-
Notifications
You must be signed in to change notification settings - Fork 312
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add location manager for free drive #2410
Changes from 18 commits
9dc5c09
51552d8
cf42a6f
89e5140
317db52
418d660
1af466a
65d097c
090af33
3a7f158
ffba189
b331078
9fe0fcc
7f04812
3d0f2d3
bf63eea
a531299
fa62b32
e74abeb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,10 +17,15 @@ class ViewController: UIViewController { | |
@IBOutlet weak var clearMap: UIButton! | ||
@IBOutlet weak var bottomBarBackground: UIView! | ||
|
||
var trackPolyline: MGLPolyline? | ||
var rawTrackPolyline: MGLPolyline? | ||
|
||
// MARK: Properties | ||
var mapView: NavigationMapView? { | ||
didSet { | ||
oldValue?.removeFromSuperview() | ||
if let mapView = oldValue { | ||
uninstall(mapView) | ||
} | ||
if let mapView = mapView { | ||
configureMapView(mapView) | ||
view.insertSubview(mapView, belowSubview: longPressHintView) | ||
|
@@ -85,6 +90,12 @@ class ViewController: UIViewController { | |
} | ||
} | ||
|
||
deinit { | ||
if let mapView = mapView { | ||
uninstall(mapView) | ||
} | ||
} | ||
|
||
// MARK: - Lifecycle Methods | ||
|
||
override func viewDidLoad() { | ||
|
@@ -343,7 +354,6 @@ class ViewController: UIViewController { | |
present(navigationViewController, animated: true) { [weak self] in | ||
completion?() | ||
|
||
self?.mapView?.removeFromSuperview() | ||
self?.mapView = nil | ||
} | ||
} | ||
|
@@ -375,12 +385,20 @@ class ViewController: UIViewController { | |
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight] | ||
mapView.delegate = self | ||
mapView.navigationMapViewDelegate = self | ||
mapView.userTrackingMode = .follow | ||
mapView.logoView.isHidden = true | ||
|
||
let singleTap = UILongPressGestureRecognizer(target: self, action: #selector(didLongPress(tap:))) | ||
mapView.gestureRecognizers?.filter({ $0 is UILongPressGestureRecognizer }).forEach(singleTap.require(toFail:)) | ||
mapView.addGestureRecognizer(singleTap) | ||
|
||
trackLocations(mapView: mapView) | ||
mapView.showsUserLocation = true | ||
mapView.userTrackingMode = .followWithHeading | ||
} | ||
|
||
func uninstall(_ mapView: NavigationMapView) { | ||
NotificationCenter.default.removeObserver(self, name: .passiveLocationDataSourceDidUpdate, object: nil) | ||
mapView.removeFromSuperview() | ||
} | ||
} | ||
|
||
|
@@ -398,6 +416,20 @@ extension ViewController: MGLMapViewDelegate { | |
self.mapView?.showWaypoints(on: currentRoute) | ||
} | ||
} | ||
|
||
func mapView(_ mapView: MGLMapView, strokeColorForShapeAnnotation annotation: MGLShape) -> UIColor { | ||
if annotation == trackPolyline { | ||
return .darkGray | ||
} | ||
if annotation == rawTrackPolyline { | ||
return .lightGray | ||
} | ||
return .black | ||
} | ||
|
||
func mapView(_ mapView: MGLMapView, lineWidthForPolylineAnnotation annotation: MGLPolyline) -> CGFloat { | ||
return annotation == trackPolyline || annotation == rawTrackPolyline ? 4 : 1 | ||
} | ||
} | ||
|
||
// MARK: - NavigationMapViewDelegate | ||
|
@@ -529,7 +561,7 @@ extension ViewController: NavigationViewControllerDelegate { | |
} | ||
} | ||
|
||
// Mark: VisualInstructionDelegate | ||
// MARK: VisualInstructionDelegate | ||
extension ViewController: VisualInstructionDelegate { | ||
func label(_ label: InstructionLabel, willPresent instruction: VisualInstruction, as presented: NSAttributedString) -> NSAttributedString? { | ||
// Uncomment to mutate the instruction shown in the top instruction banner | ||
|
@@ -541,3 +573,43 @@ extension ViewController: VisualInstructionDelegate { | |
return presented | ||
} | ||
} | ||
|
||
// MARK: Free driving | ||
extension ViewController { | ||
func trackLocations(mapView: NavigationMapView) { | ||
let dataSource = PassiveLocationDataSource(directions: Settings.directions) | ||
let locationManager = PassiveLocationManager(dataSource: dataSource) | ||
mapView.locationManager = locationManager | ||
Comment on lines
+580
to
+582
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the bare minimum necessary to integrate free-driving localization into an application’s pre-navigation map view. The rest of the changes in this file are related to a nifty but inessential feature that plots the user’s raw and idealized path on the map. (You don’t need to pass in a custom Directions object if the default is OK.) |
||
|
||
NotificationCenter.default.addObserver(self, selector: #selector(didUpdatePassiveLocation), name: .passiveLocationDataSourceDidUpdate, object: dataSource) | ||
|
||
trackPolyline = nil | ||
rawTrackPolyline = nil | ||
} | ||
|
||
@objc func didUpdatePassiveLocation(_ notification: Notification) { | ||
if let roadName = notification.userInfo?[PassiveLocationDataSource.NotificationUserInfoKey.roadNameKey] as? String { | ||
title = roadName | ||
} | ||
|
||
if let location = notification.userInfo?[PassiveLocationDataSource.NotificationUserInfoKey.locationKey] as? CLLocation { | ||
if trackPolyline == nil { | ||
trackPolyline = MGLPolyline() | ||
} | ||
|
||
var coordinates: [CLLocationCoordinate2D] = [location.coordinate] | ||
trackPolyline?.appendCoordinates(&coordinates, count: UInt(coordinates.count)) | ||
} | ||
|
||
if let rawLocation = notification.userInfo?[PassiveLocationDataSource.NotificationUserInfoKey.rawLocationKey] as? CLLocation { | ||
if rawTrackPolyline == nil { | ||
rawTrackPolyline = MGLPolyline() | ||
} | ||
|
||
var coordinates: [CLLocationCoordinate2D] = [rawLocation.coordinate] | ||
rawTrackPolyline?.appendCoordinates(&coordinates, count: UInt(coordinates.count)) | ||
} | ||
|
||
mapView?.addAnnotations([rawTrackPolyline!, trackPolyline!]) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,17 @@ extension Bundle { | |
return Bundle(for: RouteController.self) | ||
} | ||
|
||
/** | ||
The Mapbox Navigation framework bundle, if installed. | ||
*/ | ||
public class var mapboxNavigation: Bundle? { | ||
// Assumption: MapboxNavigation.framework includes NavigationViewController and exposes it to the Objective-C runtime as MapboxNavigation.NavigationViewController. | ||
guard let NavigationViewController = NSClassFromString("MapboxNavigation.NavigationViewController") else { | ||
Comment on lines
+43
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We’ve been making this assumption since #2221. This change just moves it somewhere more accessible to non-events-related code. |
||
return nil | ||
} | ||
return Bundle(for: NavigationViewController) | ||
} | ||
|
||
public func ensureSuggestedTileURLExists() -> Bool { | ||
guard let tilePath = suggestedTileURL else { return false } | ||
try? FileManager.default.createDirectory(at: tilePath, withIntermediateDirectories: true, attributes: nil) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#import <Foundation/Foundation.h> | ||
|
||
@interface MBXPeerWrapper | ||
|
||
@end | ||
1ec5 marked this conversation as resolved.
Show resolved
Hide resolved
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The map view isn’t showing the heading indicator for some reason. I think it has to do with the location manager only delivering location updates and not heading updates. In any case, I don’t think we want the map view to rotate with the user’s heading or course, because frequent rotation makes the map much less useful for choosing a destination.