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

Display shields for destinations in turn banner #353

Merged
merged 2 commits into from
Jul 10, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
66 changes: 65 additions & 1 deletion MapboxNavigation/RouteManeuverViewController.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import UIKit
import MapboxDirections
import MapboxCoreNavigation

import SDWebImage

class RouteManeuverViewController: UIViewController {
@IBOutlet var separatorViews: [SeparatorView]!
Expand All @@ -19,6 +19,7 @@ class RouteManeuverViewController: UIViewController {
weak var step: RouteStep! {
didSet {
if isViewLoaded {
roadCode = step.codes?.first ?? step.destinationCodes?.first ?? step.destinations?.first
updateStreetNameForStep()
}
}
Expand All @@ -42,13 +43,36 @@ class RouteManeuverViewController: UIViewController {
return distance != nil ? 1 : 2
}

var roadCode: String? {
didSet {
guard roadCode != oldValue, let components = roadCode?.components(separatedBy: " ") else {
return
}

if components.count > 1 {
shieldAPIDataTask = dataTaskForShieldImage(network: components[0], number: components[1], height: 32 * UIScreen.main.scale) { [weak self] (image) in
self?.shieldImage = image
}
shieldAPIDataTask?.resume()
if shieldAPIDataTask == nil {
shieldImage = nil
}
} else {
shieldImage = nil
}
}
}
var shieldImage: UIImage? {
didSet {
shieldImageView.image = shieldImage
updateStreetNameForStep()
}
}

var shieldAPIDataTask: URLSessionDataTask?
var shieldImageDownloadToken: SDWebImageDownloadToken?
let webImageManager = SDWebImageManager.shared()

var availableStreetLabelBounds: CGRect {
return CGRect(origin: .zero, size: maximumAvailableStreetLabelSize)
}
Expand Down Expand Up @@ -80,6 +104,7 @@ class RouteManeuverViewController: UIViewController {

deinit {
suspendNotifications()
webImageManager.cancelAll()
}

func resumeNotifications() {
Expand All @@ -106,6 +131,45 @@ class RouteManeuverViewController: UIViewController {

turnArrowView.step = routeProgress.currentLegProgress.upComingStep
}

func dataTaskForShieldImage(network: String, number: String, height: CGFloat, completion: @escaping (UIImage?) -> Void) -> URLSessionDataTask? {
guard let imageNamePattern = ShieldImageNamesByPrefix[network] else {
return nil
}

let imageName = imageNamePattern.replacingOccurrences(of: " ", with: "_").replacingOccurrences(of: "{ref}", with: number)
let apiURL = URL(string: "https://commons.wikimedia.org/w/api.php?action=query&format=json&maxage=86400&prop=imageinfo&titles=File%3A\(imageName)&iiprop=url%7Csize&iiurlheight=\(Int(round(height)))")!

shieldAPIDataTask?.cancel()
return URLSession.shared.dataTask(with: apiURL) { [weak self] (data, response, error) in
var json: [String: Any] = [:]
if let data = data, response?.mimeType == "application/json" {
do {
json = try JSONSerialization.jsonObject(with: data, options: []) as! [String: Any]
} catch {
assert(false, "Invalid data")
}
}

guard data != nil && error == nil else {
return
}

guard let query = json["query"] as? [String: Any],
let pages = query["pages"] as? [String: Any], let page = pages.first?.1 as? [String: Any],
let imageInfos = page["imageinfo"] as? [[String: Any]], let imageInfo = imageInfos.first,
let thumbURLString = imageInfo["thumburl"] as? String, let thumbURL = URL(string: thumbURLString) else {
return
}

if thumbURL != self?.shieldImageDownloadToken?.url {
self?.webImageManager.imageDownloader?.cancel(self?.shieldImageDownloadToken)
}
self?.shieldImageDownloadToken = self?.webImageManager.imageDownloader?.downloadImage(with: thumbURL, options: .scaleDownLargeImages, progress: nil) { (image, data, error, isFinished) in
completion(image)
}
}
}

func updateStreetNameForStep() {
if let name = step?.names?.first {
Expand Down
85 changes: 9 additions & 76 deletions MapboxNavigation/RouteMapViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import Pulley
import Mapbox
import MapboxDirections
import MapboxCoreNavigation
import SDWebImage


class ArrowFillPolyline: MGLPolylineFeature {}
class ArrowStrokePolyline: ArrowFillPolyline {}
Expand Down Expand Up @@ -52,9 +50,6 @@ class RouteMapViewController: UIViewController {

var resetTrackingModeTimer: Timer?

let webImageManager = SDWebImageManager.shared()
var shieldAPIDataTask: URLSessionDataTask?
var shieldImageDownloadToken: SDWebImageDownloadToken?
var arrowCurrentStep: RouteStep?
var isInOverviewMode = false

Expand Down Expand Up @@ -105,11 +100,6 @@ class RouteMapViewController: UIViewController {
mapView.setContentInset(contentInsets, animated: false)
}

override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
webImageManager.cancelAll()
}

@IBAction func recenter(_ sender: AnyObject) {
mapView.setCamera(tiltedCamera, animated: false)
mapView.userTrackingMode = .followWithCourse
Expand Down Expand Up @@ -214,7 +204,7 @@ class RouteMapViewController: UIViewController {
guard step == controller.step else { return }

controller.notifyDidChange(routeProgress: routeProgress, secondsRemaining: secondsRemaining)
updateShield(for: controller)
controller.roadCode = step.codes?.first ?? step.destinationCodes?.first ?? step.destinations?.first

// Move the overview button if the lane views become visible
if !controller.isPagingThroughStepList {
Expand All @@ -235,45 +225,6 @@ class RouteMapViewController: UIViewController {
let slicedLine = polyline(along: routeProgress.route.coordinates!, from: userLocation, to: routeProgress.route.coordinates!.last)
updateVisibleBounds(coordinates: slicedLine)
}

func dataTaskForShieldImage(network: String, number: String, height: CGFloat, completion: @escaping (UIImage?) -> Void) -> URLSessionDataTask? {
guard let imageNamePattern = ShieldImageNamesByPrefix[network] else {
return nil
}

let imageName = imageNamePattern.replacingOccurrences(of: " ", with: "_").replacingOccurrences(of: "{ref}", with: number)
let apiURL = URL(string: "https://commons.wikimedia.org/w/api.php?action=query&format=json&maxage=86400&prop=imageinfo&titles=File%3A\(imageName)&iiprop=url%7Csize&iiurlheight=\(Int(round(height)))")!

shieldAPIDataTask?.cancel()
return URLSession.shared.dataTask(with: apiURL) { [weak self] (data, response, error) in
var json: [String: Any] = [:]
if let data = data, response?.mimeType == "application/json" {
do {
json = try JSONSerialization.jsonObject(with: data, options: []) as! [String: Any]
} catch {
assert(false, "Invalid data")
}
}

guard data != nil && error == nil else {
return
}

guard let query = json["query"] as? [String: Any],
let pages = query["pages"] as? [String: Any], let page = pages.first?.1 as? [String: Any],
let imageInfos = page["imageinfo"] as? [[String: Any]], let imageInfo = imageInfos.first,
let thumbURLString = imageInfo["thumburl"] as? String, let thumbURL = URL(string: thumbURLString) else {
return
}

if thumbURL != self?.shieldImageDownloadToken?.url {
self?.webImageManager.imageDownloader?.cancel(self?.shieldImageDownloadToken)
}
self?.shieldImageDownloadToken = self?.webImageManager.imageDownloader?.downloadImage(with: thumbURL, options: .scaleDownLargeImages, progress: nil) { (image, data, error, isFinished) in
completion(image)
}
}
}

var contentInsets: UIEdgeInsets {
guard let tableViewController = routeTableViewController else { return .zero }
Expand Down Expand Up @@ -499,43 +450,25 @@ extension RouteMapViewController: MGLMapViewDelegate {
func mapView(_ mapView: MGLMapView, didDeselect annotation: MGLAnnotation) {
mapView.userTrackingMode = .followWithCourse
}

func updateShield(for controller: RouteManeuverViewController) {
guard let ref = controller.step.codes?.first, controller.shieldImage == nil else { return }

let components = ref.components(separatedBy: " ")

if components.count > 1 {
shieldAPIDataTask = dataTaskForShieldImage(network: components[0], number: components[1], height: 32 * UIScreen.main.scale) { (image) in
controller.shieldImage = image
}
shieldAPIDataTask?.resume()
} else {
controller.shieldImage = nil
}
}
}

// MARK: RouteManeuverPageViewControllerDelegate

extension RouteMapViewController: RoutePageViewControllerDelegate {
internal func routePageViewController(_ controller: RoutePageViewController, willTransitionTo maneuverViewController: RouteManeuverViewController) {
let step = maneuverViewController.step
let step = maneuverViewController.step!

maneuverViewController.turnArrowView.step = step
maneuverViewController.shieldImage = nil
maneuverViewController.distance = step!.distance > 0 ? step!.distance : nil
maneuverViewController.distance = step.distance > 0 ? step.distance : nil
maneuverViewController.roadCode = step.codes?.first ?? step.destinationCodes?.first ?? step.destinations?.first
maneuverViewController.updateStreetNameForStep()

updateShield(for: maneuverViewController)
maneuverViewController.showLaneView(step: step)

if let step = step {
maneuverViewController.showLaneView(step: step)

let initialPaddingForOverviewButton:CGFloat = maneuverViewController.stackViewContainer.isHidden ? -30 : -20 + maneuverViewController.laneViews.first!.frame.maxY
UIView.animate(withDuration: 0.5, animations: {
self.overviewButtonTopConstraint.constant = initialPaddingForOverviewButton + maneuverViewController.stackViewContainer.frame.maxY
})
let initialPaddingForOverviewButton:CGFloat = maneuverViewController.stackViewContainer.isHidden ? -30 : -20 + maneuverViewController.laneViews.first!.frame.maxY
UIView.animate(withDuration: 0.5) {
self.overviewButtonTopConstraint.constant = initialPaddingForOverviewButton + maneuverViewController.stackViewContainer.frame.maxY
}

maneuverViewController.isPagingThroughStepList = true
Expand All @@ -544,7 +477,7 @@ extension RouteMapViewController: RoutePageViewControllerDelegate {
if step == routeController.routeProgress.currentLegProgress.upComingStep {
mapView.userTrackingMode = .followWithCourse
} else {
mapView.setCenter(step!.maneuverLocation, zoomLevel: mapView.zoomLevel, direction: step!.initialHeading!, animated: true, completionHandler: nil)
mapView.setCenter(step.maneuverLocation, zoomLevel: mapView.zoomLevel, direction: step.initialHeading!, animated: true, completionHandler: nil)
}
}
}
Expand Down