-
-
Save nazmulkp/74a2a08cc08f0c51972c3aed51c4db19 to your computer and use it in GitHub Desktop.
| The following viewDidLoad will (1) set two locations, (2) remove all the previous annotations, and (3) call user defined helper functions (to get route points and draw the route). | |
| var loc1: CLLocationCoordinate2D | |
| loc1.latitude = 29.0167 | |
| loc1.longitude = 77.3833 | |
| var origin = Annotation(title: "loc1", subTitle: "Home1", andCoordinate: loc1) | |
| objMapView.addAnnotation(origin) | |
| // Destination Location. | |
| var loc2: CLLocationCoordinate2D | |
| loc2.latitude = 19.076000 | |
| loc2.longitude = 72.877670 | |
| var destination = Annotation(title: "loc2", subTitle: "Home2", andCoordinate: loc2) | |
| objMapView.addAnnotation(destination) | |
| if arrRoutePoints { | |
| // Remove all annotations | |
| objMapView.removeAnnotations(objMapView.annotations()) | |
| } | |
| arrRoutePoints = self.getRoutePoint(from: origin, to: destination) | |
| self.drawRoute() | |
| self.centerMap() |
The following function will get both the locations and prepare URL to get all the route points. And of course, will call stringWithURL.
func destination() {
var saddr = "(origin.coordinate.latitude),(origin.coordinate.longitude)"
var daddr = "(destination.coordinate.latitude),(destination.coordinate.longitude)"
var apiUrlStr = "http://maps.google.com/maps?output=dragdir&saddr=\(saddr)&daddr=\(daddr)"
var apiUrl = URL(string: apiUrlStr)!
var error: Error?
var apiResponse = try! String(contentsOf: apiUrl, encoding: String.Encoding.utf8)
var encodedPoints = apiResponse.matching("points:\"([^\\\"]*)\"", capture: 1)
return self.decodePolyLine(encodedPoints)
}
The following code is the real magic (decoder for the response we got from the API). I would not modify that code unless I know what I am doing :)
func encodedString() {
encodedString = encodedString.replacingOccurrences(of: "\\", with: "\")
var len = encodedString.length
var index = 0
var array = Any
var lat = 0
var lng = 0
while index < len {
var b: Int
var shift = 0
var result = 0
repeat {
b = encodedString[index += 1] - 63
result |= (b & 0x1f) << shift
shift += 5
} while b >= 0x20
var dlat = (result & 1) ? ~(result >> 1) : (result >> 1)
lat += dlat
shift = 0
result = 0
repeat {
b = encodedString[index += 1] - 63
result |= (b & 0x1f) << shift
shift += 5
} while b >= 0x20
var dlng = (result & 1) ? ~(result >> 1) : (result >> 1)
lng += dlng
var latitude = Int(value: lat * 1e-5)
var longitude = Int(value: lng * 1e-5)
printf("\n[%f,", CDouble(latitude))
printf("%f]", CDouble(longitude))
var loc = CLLocation(latitude: CFloat(latitude), longitude: CFloat(longitude))
array.append(loc)
}
return array
}
This function will draw a route and will add an overlay.
func drawRoute() {
var numPoints = arrRoutePoints.count
if numPoints > 1 {
var coords = malloc(numPoints * sizeof(CLLocationCoordinate2D))
for i in 0..<numPoints {
var current = arrRoutePoints[i]
coords[i] = current.coordinate
}
self.objPolyline = MKPolyline(coordinates: coords, count: numPoints)
free(coords)
objMapView.addOverlay(objPolyline)
objMapView.setNeedsDisplay()
}
}
The following code will center align the map.
func centerMap() {
var region: MKCoordinateRegion
var maxLat = -90
var maxLon = -180
var minLat = 90
var minLon = 180
for idx in 0..<arrRoutePoints.count {
var currentLocation = arrRoutePoints[idx]
if currentLocation.coordinate.latitude > maxLat {
maxLat = currentLocation.coordinate.latitude
}
if currentLocation.coordinate.latitude < minLat {
minLat = currentLocation.coordinate.latitude
}
if currentLocation.coordinate.longitude > maxLon {
maxLon = currentLocation.coordinate.longitude
}
if currentLocation.coordinate.longitude < minLon {
minLon = currentLocation.coordinate.longitude
}
}
region.center.latitude = (maxLat + minLat) / 2
region.center.longitude = (maxLon + minLon) / 2
region.span.latitudeDelta = maxLat - minLat
region.span.longitudeDelta = maxLon - minLon
objMapView.setRegion(region, animated: true)
}
The following is the MKMapViewDelegate method, which draws overlay (iOS 4.0 and later).
func overlay() {
var view = MKPolylineView(objPolyline)
view.fillColor = UIColor.black
view.strokeColor = UIColor.black
view.lineWidth = 4
return view
}