Skip to content
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

Building extrusion highlights #2535

Merged
merged 52 commits into from
Aug 15, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
2bdd7d3
WIP Building extrusions
d-prukop Aug 7, 2020
fdacf3d
Add BuildingExtrusionStyler to NavigationMapView with hardcoded coord…
MaximAlien Aug 7, 2020
2bd12e0
Working example
d-prukop Aug 8, 2020
ae101cf
Extract BuildingExtrusionStyler to be part of NavigationMapView. Remo…
MaximAlien Aug 8, 2020
6e06440
Remove code which is not used anywhere.
MaximAlien Aug 8, 2020
e948b1b
Remove duplicated logic in extrude method. Replace removeHighlights w…
MaximAlien Aug 8, 2020
ce0478a
Add ability to show extrusion layer for specific building and all bui…
MaximAlien Aug 8, 2020
4f6f1ed
Add ability to highlight building after arrival to final destination.…
MaximAlien Aug 8, 2020
eace9bf
Add ability to unhighlight buildings
d-prukop Aug 8, 2020
e366636
Added example of highlighting buildings during route selection. Clear…
d-prukop Aug 9, 2020
d35027a
Removed references to "buildingsPlus"
d-prukop Aug 10, 2020
02c05cc
Remove vanishing route line related layers in case of arrival to fina…
MaximAlien Aug 10, 2020
733854b
Add ability to filter out features based on attributes required for b…
MaximAlien Aug 11, 2020
a2f57cb
Public API signatures. Style hooks
d-prukop Aug 11, 2020
1a169e1
Simplified the API. Removed MGLMapViewDelegate from NavigationViewCon…
d-prukop Aug 11, 2020
7a108e6
Removed TODO
d-prukop Aug 11, 2020
30be497
Moved `highlightDestinationBuildings` function to NavigationMapView
d-prukop Aug 11, 2020
29be01e
Added flag for showing all buildings
d-prukop Aug 11, 2020
8c606f5
API updates
d-prukop Aug 11, 2020
b33d97b
highlightBuildings can accept nil for buildings
d-prukop Aug 12, 2020
6db0a48
Implement ability to zoom in to building after arriving to destination.
MaximAlien Aug 12, 2020
01ad5ef
Fixed issue in the example app where querying for buildings stops wor…
d-prukop Aug 12, 2020
9f4e8cc
Adjustments for cross-platform feature parity
d-prukop Aug 12, 2020
093b124
Removed boolean for 3d buildings to an argument in the highlightBuild…
d-prukop Aug 12, 2020
c5d5ca1
Changed name of building highlighting flag to be more generic
d-prukop Aug 12, 2020
ea1f86f
Reset opacity when unhighlighting buildings
d-prukop Aug 12, 2020
f0ca04e
Added a flag to NavigationViewController for 2d vs 3d building highli…
d-prukop Aug 12, 2020
d7b3aee
Documentation for building highlight feature
d-prukop Aug 12, 2020
1d44e55
Added documentation for `NavigationViewController.highlightBuildingsI…
d-prukop Aug 12, 2020
c526a38
Update comments to follow code-style and remove unused properties.
MaximAlien Aug 12, 2020
c43d7f5
Response to comments
d-prukop Aug 13, 2020
f9b1914
Remove buildingHighlightingEnabled and use public API methods directly.
MaximAlien Aug 13, 2020
71bb9e8
Updated changelog
d-prukop Aug 13, 2020
5a294ff
Improve logic to create highlighted buildings only in case of request…
MaximAlien Aug 13, 2020
3a77af2
Fix crash when adding highlight on the same building more than once. …
MaximAlien Aug 13, 2020
94bcbfb
Fix opacity level when using `extrudeAll` set to true option.
MaximAlien Aug 13, 2020
1ec73fc
Fix crash when removing waypoint by switching to alert instead of act…
MaximAlien Aug 13, 2020
509e583
Fix issue which prevents from removing waypoints and highlighted buil…
MaximAlien Aug 13, 2020
38248af
Set default styleURL to navigationDayStyleURL to prevent inconsistenc…
MaximAlien Aug 13, 2020
e039289
Remove deprecated methods which were incorrectly added after rebase.
MaximAlien Aug 13, 2020
4628347
Add code review suggestions.
MaximAlien Aug 14, 2020
9c22780
Use identifiers instead of IDs
MaximAlien Aug 14, 2020
a5ff400
Add code review related changes.
MaximAlien Aug 14, 2020
e18afe5
Fix crash in deinit when removing styleObservation.
MaximAlien Aug 14, 2020
256bbd8
Minor improvement in comments.
MaximAlien Aug 14, 2020
7b1449f
Add code review improvements. Use new `DestinationBuildingHighlightTy…
MaximAlien Aug 14, 2020
b75f340
Improve public API comments.
MaximAlien Aug 14, 2020
44a765d
Rename DestinationBuildingHighlightType to WaypointStyle.
MaximAlien Aug 14, 2020
23a8fdd
Move WaypointStyle to separate file and add it to Jazzy.
MaximAlien Aug 14, 2020
108adca
Remove WaypointStyle from NavigationViewController.
MaximAlien Aug 14, 2020
44acbe2
Improve expressions used by highlightedBuildingsLayer.
MaximAlien Aug 14, 2020
be3c97d
Attempt to make extrusion more reliable by removing type = 'building'…
MaximAlien Aug 14, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
* `NavigationMapViewDelegate.navigationMapView(_:alternativeRouteStyleLayerWithIdentifier:source:)` to style alternative routes.
* `NavigationMapViewDelegate.navigationMapView(_:alternativeRouteCasingStyleLayerWithIdentifier:source:)` to style the casing of alternative routes.
* Fixed an issue where the casing for the main route would not overlap alternative routes. ([#2377](https://github.com/mapbox/mapbox-navigation-ios/pull/2377))
* Added the NavigationViewController.highlightsDestinationBuildings property and NavigationMapView.highlightBuildings(at:in3D:) method to highlight the destination building in UIColor.defaultBuildingHighlightColor as the user approaches it.
* Added the NavigationViewController.highlightsBuilidngsIn3D property to additionally extrude the destination building in 3D.
* Added `NavigationViewController.DestinationBuildingHighlightType` enum to control building highlighting. ([#2535](https://github.com/mapbox/mapbox-navigation-ios/pull/2535))
* Added `NavigationMapView.highlightBuildings(at:in3D:)` method to highlight the destination building in `UIColor.defaultBuildingHighlightColor` as the user approaches it. Added `NavigationMapView.unhighlightBuildings` to give the ability to unhighlight buildings. ([#2535](https://github.com/mapbox/mapbox-navigation-ios/pull/2535))

### Feedback

Expand Down
11 changes: 4 additions & 7 deletions Example/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,8 @@ class ViewController: UIViewController {
// Render part of the route that has been traversed with full transparency, to give the illusion of a disappearing route.
navigationViewController.mapView?.routeLineTracksTraversal = true

// Example of building highlighting using the NavigationViewController.
navigationViewController.highlightsDestinationBuildings = true
// Example of building highlighting in 3D.
navigationViewController.destinationBuildingHighlightType = .highlightIn3D

presentAndRemoveMapview(navigationViewController, completion: beginCarPlayNavigation)
}
Expand All @@ -262,11 +262,8 @@ class ViewController: UIViewController {
let navigationViewController = NavigationViewController(for: route, routeOptions: routeOptions, navigationOptions: options)
navigationViewController.delegate = self

// Example of building highlighting using the NavigationViewController.
navigationViewController.highlightsDestinationBuildings = true

// Extrude buildings in 2D.
navigationViewController.highlightBuildingsIn3D = false
// Example of building highlighting in 2D.
navigationViewController.destinationBuildingHighlightType = .highlightIn2D

presentAndRemoveMapview(navigationViewController, completion: beginCarPlayNavigation)
}
Expand Down
30 changes: 12 additions & 18 deletions MapboxNavigation/NavigationMapView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,6 @@ open class NavigationMapView: MGLMapView, UIGestureRecognizerDelegate {
addGestureRecognizer(mapTapGesture)

installUserCourseView()

styleURL = MGLStyle.navigationDayStyleURL
}

open override func layoutMarginsDidChange() {
Expand Down Expand Up @@ -295,11 +293,6 @@ open class NavigationMapView: MGLMapView, UIGestureRecognizerDelegate {
if (tracksUserCourse) {
updateCourseTracking(location: userLocationForCourseTracking, camera:self.camera, animated: false)
}

// TODO: Add style observation to be able to re-add highlighted building whenever it happens.

// FIXME: Since building might be already highlighted and we do not have any info
// regarding its identification after style change such highlighted building will be lost.
}

open override func anchorPoint(forGesture gesture: UIGestureRecognizer) -> CGPoint {
Expand Down Expand Up @@ -1359,16 +1352,17 @@ open class NavigationMapView: MGLMapView, UIGestureRecognizerDelegate {
extension NavigationMapView {

/**
Receives coordinates for searching the map for buildings. If buildings are found, they will be highlighted in 2d or 3d depending on the `in3D` value.
`in3D` defaults to true
`buildingHighlightingEnabled` must be set to true before this function will work.
Receives coordinates for searching the map for buildings. If buildings are found, they will be highlighted in 2D or 3D depending on the `in3D` value.

- parameter coordinates: Coordinates which represent buildings locations.
- parameter extrudesBuildings: Switch which allows to highlight buildings in either 2D or 3D. Defaults to true.
*/
public func highlightBuildings(at coordinates: [CLLocationCoordinate2D], in3D extrudesBuildings: Bool = true) {
MaximAlien marked this conversation as resolved.
Show resolved Hide resolved
highlightBuildings(Set(coordinates.compactMap({ buildingIdentifier(at: $0) })), in3D: extrudesBuildings, extrudeAll: false)
highlightBuildings(with: Set(coordinates.compactMap({ buildingIdentifier(at: $0) })), in3D: extrudesBuildings, extrudeAll: false)
}

/**
Removes the highlight from all buildings highlighted by `highlightBuildings(for coordinates:, in3D:)`.
Removes the highlight from all buildings highlighted by `highlightBuildings(at:in3D:)`.
*/
public func unhighlightBuildings() {
guard let highlightedBuildingsLayer = style?.layer(withIdentifier: StyleLayerIdentifier.buildingExtrusion) else { return }
Expand Down Expand Up @@ -1410,23 +1404,23 @@ extension NavigationMapView {
return nil
}

private func highlightBuildings(_ buildingIdentifiers: Set<Int64>, in3D: Bool = false, extrudeAll: Bool = false) {
private func highlightBuildings(with identifiers: Set<Int64>, in3D: Bool = false, extrudeAll: Bool = false) {
// In case if set with highlighted building identifiers is empty - do nothing.
if buildingIdentifiers.isEmpty { return }
if identifiers.isEmpty { return }
// Add layer which will be used to highlight buildings if it wasn't added yet.
guard let highlightedBuildingsLayer = addBuildingsLayer() else { return }

if extrudeAll {
highlightedBuildingsLayer.predicate = NSPredicate(format: "extrude = 'true' AND type = 'building' AND underground = 'false'")
} else {
// Form a predicate to filter out the other buildings from the datasource so only the desired ones are included.
highlightedBuildingsLayer.predicate = NSPredicate(format: "extrude = 'true' AND type = 'building' AND underground = 'false' AND $featureIdentifier IN %@", buildingIdentifiers.map { $0 })
highlightedBuildingsLayer.predicate = NSPredicate(format: "extrude = 'true' AND type = 'building' AND underground = 'false' AND $featureIdentifier IN %@", identifiers.map { $0 })
}

// Buildings with identifiers will be highlighted with provided color. Rest of the buildings will be highlighted, but kept at a uniform color.
let highlightedBuildingHeightExpression = "MGL_MATCH($featureIdentifier, \(buildingIdentifiers.map { "\($0), \(in3D ? "height" : "0"), " }.joined(separator: ""))\(extrudeAll ? "height" : "0"))"
let highlightedBuildingColorExpression = "MGL_MATCH($featureIdentifier, \(buildingIdentifiers.map { "\($0), %@, " }.joined(separator: ""))%@)"
var colorsList = buildingIdentifiers.map { _ in buildingHighlightColor }
let highlightedBuildingHeightExpression = "MGL_MATCH($featureIdentifier, \(identifiers.map { "\($0), \(in3D ? "height" : "0"), " }.joined(separator: ""))\(extrudeAll ? "height" : "0"))"
let highlightedBuildingColorExpression = "MGL_MATCH($featureIdentifier, \(identifiers.map { "\($0), %@, " }.joined(separator: ""))%@)"
var colorsList = identifiers.map { _ in buildingHighlightColor }

colorsList.append(buildingDefaultColor)

Expand Down
29 changes: 21 additions & 8 deletions MapboxNavigation/NavigationViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -148,16 +148,29 @@ open class NavigationViewController: UIViewController, NavigationStatusPresenter
public var shouldManageApplicationIdleTimer = true

/**
Enables highlighting of the destination building when arriving.
Enum denoting the types of the destination building highlighting on arrival.
*/
public var highlightsDestinationBuildings: Bool = false
public enum DestinationBuildingHighlightType: Int {
MaximAlien marked this conversation as resolved.
Show resolved Hide resolved
/**
Do not highlight destination building on arrival.
MaximAlien marked this conversation as resolved.
Show resolved Hide resolved
*/
case noHighlight

/**
Highlight destination building on arrival in 2D.
*/
case highlightIn2D

/**
Highlight destination building on arrival in 3D.
*/
case highlightIn3D
}

/**
When destination building highlighting is enabled, this option controls whether the building will be presented in 3d or 2d.

The default value of this property is `true`.
Allows to control highlighting of the destination building on arrival. By default destination buildings will not be highlighted.
*/
public var highlightBuildingsIn3D: Bool = true
public var destinationBuildingHighlightType: DestinationBuildingHighlightType = .noHighlight

var isConnectedToCarPlay: Bool {
if #available(iOS 12.0, *) {
Expand Down Expand Up @@ -593,7 +606,7 @@ extension NavigationViewController: NavigationServiceDelegate {
}

private func zoomInAndHighlightBuilding(for location: CLLocation?) {
if !highlightsDestinationBuildings { return }
if destinationBuildingHighlightType == .noHighlight { return }
guard let mapViewController = self.mapViewController else { return }
guard let location = location else { return }

Expand All @@ -613,7 +626,7 @@ extension NavigationViewController: NavigationServiceDelegate {
animated: true,
completionHandler: {
// Highlight buildings which were marked as target destination coordinate in waypoint.
mapView.highlightBuildings(at: self.routeOptions.waypoints.compactMap({ $0.targetCoordinate }), in3D: self.highlightBuildingsIn3D)
mapView.highlightBuildings(at: self.routeOptions.waypoints.compactMap({ $0.targetCoordinate }), in3D: self.destinationBuildingHighlightType == .highlightIn3D ? true : false)

// Update insets to be able to correctly center map view after presenting end of route view.
mapViewController.updateMapViewContentInsets()
Expand Down
3 changes: 3 additions & 0 deletions MapboxNavigation/RouteMapViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ class RouteMapViewController: UIViewController {
self?.showRouteIfNeeded()
mapView.localizeLabels()
mapView.showsTraffic = false

// FIXME: In case when building highlighting feature is enabled due to style changes and no info currently being stored
// regarding building identification such highlighted building will disappear.
}

makeGestureRecognizersResetFrameRate()
Expand Down