360° flyover on a MKMapView 🚁

Overview

FlyoverKit Header Logo

Swift 5.0 CI Status Version Carthage Compatible Platform Documentation Twitter


FlyoverKit enables you to present stunning 360° flyover views on an MKMapView with zero effort while maintaining full configuration possibilities. FlyoverKit builds the core of STLocationRequest which enables you a way to request the user location services via a 3D 360° flyover MapView.

Example

Example Application Screenshot

The example Application is an excellent way to see FlyoverKit in action. You get a brief look of the available configuration options and how they affect the flyover behaviour. Simply open the FlyoverKit.xcodeproj and run the FlyoverKit-Example scheme. Please keep in mind that the SatelliteFlyover and HybridFlyover will only work on a real iOS device.

Installation

CocoaPods

FlyoverKit is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'FlyoverKit'

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.

To integrate FlyoverKit into your Xcode project using Carthage, specify it in your Cartfile:

github "SvenTiigi/FlyoverKit"

Run carthage update --platform iOS to build the framework and drag the built FlyoverKit.framework into your Xcode project.

On your application targets’ “Build Phases” settings tab, click the “+” icon and choose “New Run Script Phase” and add the Framework path as mentioned in Carthage Getting started Step 4, 5 and 6

Swift Package Manager

To integrate using Apple's Swift Package Manager, add the following as a dependency to your Package.swift:

dependencies: [
    .package(url: "https://github.com/SvenTiigi/FlyoverKit.git", from: "1.3.1")
]

Manually

If you prefer not to use any of the aforementioned dependency managers, you can integrate FlyoverKit into your project manually. Simply drag the Sources Folder into your Xcode project.

Usage

FlyoverKit can be implemented in three different ways. Simply choose the most suitable type for your implementation. Please see the Advanced section in order to configure the FlyoverKit to your needs.

FlyoverCamera

If you already have a MKMapView in your Controller and you want to add a flyover to this MapView, simply use the FlyoverCamera.

import FlyoverKit

// Initialize the FlyoverCamera with an already existing MKMapView
let flyoverCamera = FlyoverCamera(mapView: self.mapView)

// Initialize a location via CLLocationCoordinate2D
let eiffelTower = CLLocationCoordinate2D(latitude: 48.858370, longitude: 2.294481)

// Start flyover
flyoverCamera.start(flyover: eiffelTower)

FlyoverMapView

If you wish to show a MapView which is already preconfigured to perform a flyover on a given location, you should use the FlyoverMapView.

import FlyoverKit

// Initialize the FlyoverMapView
let flyoverMapView = FlyoverMapView()

// Initialize a location via CLLocation
let eiffelTower = CLLocation(latitude: 48.858370, longitude: 2.294481)

// Start flyover
flyoverMapView.start(flyover: eiffelTower)

FlyoverMapViewController

If you wish to present a UIViewController with an embedded FlyoverMapView to perform a flyover on a given location, FlyoverMapViewController is at your service.

import FlyoverKit

// Initialize a location via FlyoverAwesomePlace
let eiffelTower = FlyoverAwesomePlace.parisEiffelTower

// Initialize the FlyoverMapViewController with a Flyover object
let controller = FlyoverMapViewController(flyover: eiffelTower)

// Present controller
self.present(controller, animated: true)

Advanced

The FlyoverKit consists of three main components. The Flyover protocol, FlyoverCamera and FlyoverMapView


Architecture

Flyover Protocol

The flyover protocol specifies a type with a CLLocationCoordinat2D property. It is used to perform a flyover on the given coordinate.

public protocol Flyover {
    var coordinate: CLLocationCoordinate2D { get }
}

The FlyoverKit already implemented this protocol to various MapKit and CoreLocation types like CLLocationCoordinate2D, CLLocation, MKMapPoint, MKMapItem, MKCoordinateRegion and many more.

You can apply the Flyover protocol to your own models to use them for a flyover.

struct Address {
    var name: String
    var coordinate: CLLocationCoordinate2D
}
extension Address: Flyover {}

Operators

In order to compare two Flyover types you can use the following two operators.

Equatable operator (==)

self.flyover1 == self.flyover2

Checks if the two given Flyover types are exactly the same via comparison of latitude and longitude.

Rounded Equatable operator (~~)

self.flyover1 ~~ self.flyover2

Checks if the two given Flyover types are nearly the same via comparison of rounded latitude and longitude.

FlyoverAwesomePlace

The FlyoverAwesomePlace is a Flyover protocol compliant Enumeration with awesome locations and landmarks like NewYorkStatueOfLiberty, GooglePlex, SydneyOperaHouse and many more. You can use them in your own implementation or to explore different locations in the FlyoverKitExample Application.

FlyoverCamera

The FlyoverCamera is responsible for manipulating the MKMapView camera and performs a 360° flyover animation via UIViewPropertyAnimator.

In order to initialize a FlyoverCamera object you need to pass a MKMapView (which reference will be weakly stored) and a FlyoverCamera.Configuration object.

// Initialize FlyoverCamera configuration
let configuration = FlyoverCamera.Configuration(
    duration: 4.0,
    altitude: 600.0,
    pitch: 45.0,
    headingStep: 20.0
)

// Initialize FlyoverCamera
let camera = FlyoverCamera(
    mapView: mapView,
    configuration: configuration
)

// Start Flyover
camera.start(flyover: location)

Configuration

The FlyoverCamera.Configuration struct holds all specific flyover configuration values. Set the properties to get the right look and feel of the flyover as you need it to be.

Configuration Description
duration The flyover animation duration
altitude The altitude above the ground, measured in meters
pitch The viewing angle of the camera, measured in degrees
headingStep The direction step in degrees that is added to the MapViewCamera heading in each flyover iteration
regionChangeAnimation The region change animation that should be applied if a flyover has been started and the MapCamera has to change the region. Default is always .none which immediately present the place. If you wish that the region change should be performed via an animation you can set .animated(duration: 1.5, curve: .easeIn)

An excellent visualization of an MKMapCamera from TechTopia

Flyover Camera Diagram

Configuration Theme

If you don't want to set the properties yourself you can use a preconfigured configuration theme. Currently there are four themes available

Theme Description
default Default flyover configuration with configuration for a default flyover usage
lowFlying Flyover configuration with a low altitude and a high pitch. Simulates a low flying helicopter viewing angle
farAway Configuration with a high altitude and a normal pitch which results in a far away viewing angle
giddy A giddy configuration 🤢 which you shouldn't use in production. But it's fun 🤷‍♂️ 🤙
astronautView The view of an astronaut 🌎

Furthermore, you can initialize a FlyoverCamera with a given Theme.

// Initialize FlyoverCamera
let camera = FlyoverCamera(
    mapView: mapView,
    configuration: .default
)

More themes coming soon... 👨‍💻

FlyoverMapView

The FlyoverMapView is a preconfigured MKMapView with an embedded FlyoverCamera. The FlyoverMapView offers various convenience functions for example starting a flyover with a MKAnnotation object or setting a supported flyover MapType.

// Initialize with default configuration theme and standard MapType
let flyoverMapView = FlyoverMapView()

// Or initialize by setting a different theme and the satelliteFlyover MapType
let flyoverMapView = FlyoverMapView(configuration: .farAway, mapType: .satelliteFlyover)

MapType

The FlyoverMapView.MapType specifies the three supported MKMapType's.

MapType Description
standard A street map that shows the position of all roads and shows 3D buildings
satelliteFlyover A satellite image of the area with road and road name information layered on top
hybridFlyover A hybrid satellite image with flyover data where available

FlyoverMapViewController

The FlyoverMapViewController is an easy and simple way to present a UIViewController with an embedded FlyoverMapView. You can use it if you just want to present a 360° flyover on a given Flyover type.

// Initialize a location
let eiffelTower = CLLocationCoordinate2DMake(48.858370, 2.294481)

// Initialize the FlyoverMapViewController with a Flyover object
let controller = FlyoverMapViewController(flyover: eiffelTower)

// Present controller
self.present(controller, animated: true)

Additionally you can initialize the FlyoverMapViewController with your own Configuration or Configuration.Theme and a MapType

// Initialize a location
let eiffelTower = CLLocationCoordinate2DMake(48.858370, 2.294481)

// Initialize a Configuration
let configuration = FlyoverCamera.Configuration(
    duration: 4.0,
    altitude: 600.0,
    pitch: 45.0,
    headingStep: 20.0
)

// Initialize the FlyoverMapViewController
let controller = FlyoverMapViewController(
    flyover: eiffelTower, 
    configuration: configuration, 
    mapType: .satelliteFlyover
)

// Present controller
self.present(controller, animated: true)

Contributing

Contributions are very welcome 🙌 🤓

License

FlyoverKit
Copyright (c) 2020 Sven Tiigi <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
You might also like...
Simple 360 Video player for iOS using SceneKit
Simple 360 Video player for iOS using SceneKit

simple360player_iOS Simple 360 Video player for iOS using SceneKit. VR ready. Stereoscopic Ready. We generate a simple scene in which we add a sphere

iOS 360-degree video player streaming from an AVPlayer.
iOS 360-degree video player streaming from an AVPlayer.

Swifty360Player iOS 360-degree video player streaming from an AVPlayer. Demo Requirements Swifty360Player Version Minimum iOS Target Swift Version 0.2

ARVideoPortal - A Minimal iOS AR app to display 360 / video in sphere space
ARVideoPortal - A Minimal iOS AR app to display 360 / video in sphere space

AR Video Portal A minimal iOS AR app to display 360 / video in sphere space. Xco

NYT360Video plays 360-degree video streamed from an AVPlayer on iOS.
NYT360Video plays 360-degree video streamed from an AVPlayer on iOS.

NYT360Video 360º video playback from The New York Times NYT360Video plays spherical 360º video, allowing the user to explore the video via pan gesture

Comments
  • No such module 'SnapKit' Error In Demo.

    No such module 'SnapKit' Error In Demo.

    Hello, I just download the code and trying to run but it's showing Error that

    FlyoverKit-master/FlyoverKitExample/ViewController.swift:11:8: No such module 'SnapKit'

    screen shot 2018-02-26 at 11 24 41 am

    help wanted 
    opened by Premal-Khetani 5
  • How to stop/pause the flyover

    How to stop/pause the flyover

    Hi I've integrated your FlyoverKit into a SwiftUI app with UIViewControllerRepresentable and it looks beautiful. I can manipulate the configuration properties just fine but for the life of me I can't work out how to pause the flyover. I have a startStop Bool binding and have tried this: uiViewController.flyoverMapView.flyoverCamera.state = startStop ? .started : .stopped to no avail. Any pointers would be much appreciated.

    help wanted 
    opened by magnas35 2
Releases(1.3.1)
  • 1.3.1(Sep 22, 2019)

  • 1.3.0(Apr 2, 2019)

  • 1.2.2(Sep 29, 2018)

    FlyoverAwesomePlace

    Added CaseIterable to FlyoverAwesomePlace

    
    for place in FlyoverAwesomePlace.allCases {
        print(place)
    }
    
    for place in FlyoverAwesomePlace.iterate() {
        print(place)
    }
    
    
    Source code(tar.gz)
    Source code(zip)
  • 1.2.1(Sep 18, 2018)

  • 1.2.0(Apr 22, 2018)

    tvOS

    This release adds tvOS 📺 support to FlyoverKit 🙌

    ConfigurationTheme

    This release removed the ConfigurationTheme and the specific initializer. The ConfigurationThemes are now available as static property on FlyoverCamera.Configuration.

    /// No longer available
    let camera = FlyoverCamera(
        mapView: mapView,
        configurationTheme: .lowFlying
    )
    
    /// Use the configuration initializer and set static property (e.g. .lowFlying)
    let camera = FlyoverCamera(
        mapView: mapView,
        configuration: .lowFlying
    )
    
    Source code(tar.gz)
    Source code(zip)
  • 1.1.2(Mar 29, 2018)

  • 1.1.1(Feb 28, 2018)

  • 1.1.0(Feb 28, 2018)

    FlyoverCamera State

    In this release the property isStarted is completely removed and replaced with the state enum property. In order to check if the FlyoverCamera is started you can check

    // Is FlyoverCamera started?
    self.flyoverCamera.state == .started
    
    // Is FlyoverCamera stopped?
    self.flyoverCamera.state == .stopped
    

    Flyover Operators

    In order to compare two Flyover types you can use the following two operators.

    // Equatable operator (==)
    self.flyover1 == self.flyover2
    

    This checks if the two given Flyover types are exactly the same via comparison of latitude and longitude.

    // Rounded Equatable operator (~~)
    self.flyover1 ~~ self.flyover2
    

    This checks if the two given Flyover types are nearly the same via comparison of rounded latitude and longitude.

    AstronautView

    Version 1.1.0 introduces a new FlyoverCamera.Configuration.Theme named astronautView. The theme configures the FlyoverCamera to give you a view like an astronaut 🌎

    Foreground/Background behavior

    In this release we fixed an issue with foreground and background behavior of an Application running a FlyoverCamera or FlyoverMapView. The FlyoverCamera will stop as soon the Application is going into the background mode and will automatically start the flyover when the Application is in foreground

    Source code(tar.gz)
    Source code(zip)
  • 1.0.0(Feb 22, 2018)

Owner
Sven Tiigi
iOS Engineer @opwoco
Sven Tiigi
MKMapView wrapper for SwiftUI as drop-in to MapKit's SwiftUI view

MKMapView wrapper for SwiftUI as drop-in to MapKit's SwiftUI view. Easily extensible annotations and overlays, iOS 13 support and backwards compatible with MKAnnotation and MKOverlay!

Paul 73 Dec 26, 2022
Request the Location Services via a 3D 360° flyover MKMapView 🗺

STLocationRequest STLocationRequest is a simple and elegant way to request the users location services at the very first time. The STLocationRequestCo

Sven Tiigi 640 Dec 6, 2022
Use any custom view as custom callout view for MKMapView with cool animations. Use any image as annotation view.

MapViewPlus About MapViewPlus gives you the missing methods of MapKit which are: imageForAnnotation and calloutViewForAnnotationView delegate methods.

Okhan Okbay 162 Nov 16, 2022
SwiftUI wrapper for MapKit's MKMapView (UIKit).

SwiftUIMKMapView SwiftUI wrapper for MapKit's MKMapView (UIKit). ▶️ Usage Add as a dependecy to your project using Swift Package Manager. Embed map vi

Dariusz Rybicki 1 Apr 4, 2022
MKMapView wrapper for SwiftUI as drop-in to MapKit's SwiftUI view

MKMapView wrapper for SwiftUI as drop-in to MapKit's SwiftUI view. Easily extensible annotations and overlays, iOS 13 support and backwards compatible with MKAnnotation and MKOverlay!

Paul 73 Dec 26, 2022
Swifty360Player - iOS 360-degree video player streaming from an AVPlayer.

Swifty360Player iOS 360-degree video player streaming from an AVPlayer. Demo Requirements Swifty360Player Version Minimum iOS Target Swift Version 0.2

Abdullah Selek 148 Dec 18, 2022
Open Source iOS 360 Degree Panorama Video Player.

?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? The Metal with Swift 5.0 version is comming ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 360 VR Player A Open Source, Ad-free, Na

Hanton Yang 2k Dec 24, 2022
NYT360Video plays 360-degree video streamed from an AVPlayer on iOS.

NYT360Video 360º video playback from The New York Times NYT360Video plays spherical 360º video, allowing the user to explore the video via pan gesture

The New York Times 270 Nov 23, 2022
360 video player for iOS written in swift - a subset of SceneKit that works

DDDKit An open source library to support 360 videos and pictures. It's designed as a generic 3D library that you can use for much more! Example of use

Guillaume Sabran 123 Aug 9, 2022
Open Source iOS 360 Degree Panorama Video Player.

?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? The Metal with Swift 5.0 version is comming ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 360 VR Player A Open Source, Ad-free, Na

Hanton Yang 2k Jan 1, 2023