Skip to content

Instantly share code, notes, and snippets.

@nixta
Last active July 11, 2016 20:07
Show Gist options
  • Save nixta/9e21b3fec8e8de80057912d316b0d0c1 to your computer and use it in GitHub Desktop.
Save nixta/9e21b3fec8e8de80057912d316b0d0c1 to your computer and use it in GitHub Desktop.
Sample View Controller to do Walk Directions in the 10.2.5 ArcGIS Runtime SDK for iOS
//
// ViewController.swift
// WalkTimeTest-Swift
//
// Created by Nicholas Furness on 7/11/16.
// Copyright © 2016 Esri. All rights reserved.
//
import UIKit
import ArcGIS
class ViewController: UIViewController, AGSRouteTaskDelegate, AGSMapViewTouchDelegate {
@IBOutlet weak var mapView: AGSMapView!
lazy var defaultStops:[AGSStopGraphic] = {
let coords:[[Double]] = [
[13111.632500000298,6837513.480800003],
[12387.869442865569,6837411.963014238],
[13104.466600000858,6837991.212300003]
]
return coords.map() { (coord:[Double]) -> AGSStopGraphic in
let x = coord[0]
let y = coord[1]
let geom = AGSPoint(x: x, y: y, spatialReference: AGSSpatialReference.webMercatorSpatialReference())
let graphic = AGSStopGraphic(geometry: geom, symbol: nil, attributes: nil)
return graphic
}
}()
var routeGraphicsLayer = AGSGraphicsLayer()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Set up the Map View
let basemap = AGSTiledMapServiceLayer(URL: NSURL(string:"http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer"))
self.mapView.addMapLayer(basemap)
self.mapView.addMapLayer(self.routeGraphicsLayer)
let centerPoint = AGSPoint(x: 12793.949076875797, y: 6837702.943161963, spatialReference: AGSSpatialReference.webMercatorSpatialReference())
self.mapView.zoomToScale(25000, withCenterPoint: centerPoint, animated: true)
self.mapView.touchDelegate = self
// Set up the Route Task
self.routeTask = AGSRouteTask(URL: NSURL(string:"http://route.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World"), credential: AGSCredential(user: userName, password: password))
self.routeTask?.delegate = self
// Get some default parameters to use (could probably cache these somewhere IRL)
self.routeTask?.retrieveDefaultRouteTaskParameters()
}
func mapView(mapView: AGSMapView!, didClickAtPoint screen: CGPoint, mapPoint mappoint: AGSPoint!, features: [NSObject : AnyObject]!) {
// Calculate a route when the map is tapped
if let task = self.routeTask, params = self.defaultRouteParams {
self.routeGraphicsLayer.removeAllGraphics()
params.setStopsWithFeatures(self.defaultStops)
task.solveWithParameters(params)
}
}
var routeTask:AGSRouteTask?
var defaultRouteParams:AGSRouteTaskParameters?
// MARK: Default Parameters
func routeTask(routeTask: AGSRouteTask!, operation op: NSOperation!, didRetrieveDefaultRouteTaskParameters routeParams: AGSRouteTaskParameters!) {
self.defaultRouteParams = routeParams
self.defaultRouteParams?.outSpatialReference = self.mapView.spatialReference
self.defaultRouteParams?.returnRouteGraphics = true
self.applyWalkTimeParameters(self.defaultRouteParams)
}
func routeTask(routeTask: AGSRouteTask!, operation op: NSOperation!, didFailToRetrieveDefaultRouteTaskParametersWithError error: NSError!) {
showError("Could not retrieve default parameters!", message:error.localizedDescription)
self.routeTask = nil
}
// MARK: Walk Time Parameters
func applyWalkTimeParameters(params:AGSRouteTaskParameters?) {
// Here we override some parameters that are important for Walk Time.
// Note that these can be obtained here (use your own token):
// https://logistics.arcgis.com/arcgis/rest/services/World/Utilities/GPServer/GetTravelModes/execute?f=json&token=YOUR_TOKEN_HERE
params?.impedanceAttributeName = "WalkTime"
params?.restrictionAttributeNames = ["Avoid Roads Unsuitable for Pedestrians", "Preferred for Pedestrians", "Walking"]
params?.attributeParameterValues = [[
"parameterName": "Restriction Usage",
"attributeName": "Walking",
"value": "PROHIBITED"
], [
"parameterName": "Restriction Usage",
"attributeName": "Preferred for Pedestrians",
"value": "PREFER_LOW"
], [
"parameterName": "Walking Speed (km/h)",
"attributeName": "WalkTime",
"value": 5
], [
"parameterName": "Restriction Usage",
"attributeName": "Avoid Roads Unsuitable for Pedestrians",
"value": "AVOID_HIGH"
]] as [[String:AnyObject]]
params?.outputGeometryPrecision = 2
params?.outputGeometryPrecisionUnits = AGSUnits.Centimeters
params?.uTurns = AGSNAUTurn.AllowBacktrack
params?.useHierarchy = false
}
// MARK: Route solving
func routeTask(routeTask: AGSRouteTask!, operation op: NSOperation!, didSolveWithResult routeTaskResult: AGSRouteTaskResult!) {
print("Got route result OK")
if let route = routeTaskResult.routeResults.first as? AGSRouteResult {
print("Adding route")
route.routeGraphic.symbol = AGSSimpleLineSymbol(color: UIColor.blueColor(), width: 4.0)
self.routeGraphicsLayer.addGraphic(route.routeGraphic)
print("Added route")
print("Route takes \(route.totalMinutes) minutes to travel \(route.totalMiles) miles")
if let directionSteps = route.directions.graphics as? [AGSDirectionGraphic] {
for step in directionSteps {
print("\(step.text) (\(step.length) mi - \(step.timeMinutes) min)")
}
}
}
}
func routeTask(routeTask: AGSRouteTask!, operation op: NSOperation!, didFailSolveWithError error: NSError!) {
showError("Error getting route result", message: error.localizedDescription)
}
// MARK: Other stuff
func showError(title:String, message:String) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: { (action) -> Void in }))
self.presentViewController(alert, animated: true, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
{
"attributeParameterValues": [{
"parameterName": "Restriction Usage",
"attributeName": "Walking",
"value": "PROHIBITED"
}, {
"parameterName": "Restriction Usage",
"attributeName": "Preferred for Pedestrians",
"value": "PREFER_LOW"
}, {
"parameterName": "Walking Speed (km/h)",
"attributeName": "WalkTime",
"value": 5
}, {
"parameterName": "Restriction Usage",
"attributeName": "Avoid Roads Unsuitable for Pedestrians",
"value": "AVOID_HIGH"
}],
"description": "Follows paths and roads that allow pedestrian traffic and finds solutions that optimize travel time. The walking speed is set to 5 kilometers per hour.",
"impedanceAttributeName": "WalkTime",
"simplificationToleranceUnits": "esriMeters",
"uturnAtJunctions": "esriNFSBAllowBacktrack",
"restrictionAttributeNames": ["Avoid Roads Unsuitable for Pedestrians", "Preferred for Pedestrians", "Walking"],
"useHierarchy": false,
"simplificationTolerance": 2,
"timeAttributeName": "WalkTime",
"distanceAttributeName": "Kilometers",
"type": "WALK",
"id": "caFAgoThrvUpkFBW",
"name": "Walking Time"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment