问题
I'm using swift on iOS and using MKMapView. I've been working on giving a user a from - to textfield and letting the user have a form of route between the from and to locations. I've got that working on mkmapview using the built in directions and geocoding api calls for Apple. However after using it for a while a realized that a lot of countries are not supported by Apple Apple - Supported Countries For Directions
So is there a way to get routes from the google maps SDK and translate them to a MKPolyline or MKOverlay? I haven't worked with google maps so keep that in mind. I saw this question iPhone: Using Google to get directions it has an answer, but the newest solution is 4 years old and its in objective-C. Although I do understand how to convert objective-C code to swift, I'd rather not have to go through a whole project. Keep in mind that this a part of a bigger project, so I can't switch the whole thing over to google maps.
回答1:
I think this Stackoverflow answer can convert the encoded polyline to MKPolyline.
The answer is an Objective-C version, so I tried to convert it to Swift, sample code:
func polyLineWithEncodedString(encodedString: String) -> MKPolyline {
let bytes = (encodedString as NSString).UTF8String
let length = encodedString.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)
var idx: Int = 0
var count = length / 4
var coords = UnsafeMutablePointer<CLLocationCoordinate2D>.alloc(count)
var coordIdx: Int = 0
var latitude: Double = 0
var longitude: Double = 0
while (idx < length) {
var byte = 0
var res = 0
var shift = 0
do {
byte = bytes[idx++] - 0x3F
res |= (byte & 0x1F) << shift
shift += 5
} while (byte >= 0x20)
let deltaLat = ((res & 1) != 0x0 ? ~(res >> 1) : (res >> 1))
latitude += Double(deltaLat)
shift = 0
res = 0
do {
byte = bytes[idx++] - 0x3F
res |= (byte & 0x1F) << shift
shift += 5
} while (byte >= 0x20)
let deltaLon = ((res & 1) != 0x0 ? ~(res >> 1) : (res >> 1))
longitude += Double(deltaLon)
let finalLat: Double = latitude * 1E-5
let finalLon: Double = longitude * 1E-5
let coord = CLLocationCoordinate2DMake(finalLat, finalLon)
coords[coordIdx++] = coord
if coordIdx == count {
let newCount = count + 10
let temp = coords
coords.dealloc(count)
coords = UnsafeMutablePointer<CLLocationCoordinate2D>.alloc(newCount)
for index in 0..<count {
coords[index] = temp[index]
}
temp.destroy()
count = newCount
}
}
let polyLine = MKPolyline(coordinates: coords, count: coordIdx)
coords.destroy()
return polyLine
}
You can try the sample project from this GitHub link.
Below is the image of using Google Direction API web service to render a route on MKMapView from San Francisco to San Jose.
回答2:
Using google api to find directions between origin and destination.
Required parameters:
origin : lat + long current location or place ID .
destination : lat + long destination location or place ID .
Key: to create new google api key .
Optional parameters:
- mode (defaults to driving) driving give you more options, or set
walking, bicycling, transit. - alternatives : false give u just one route, option true give all directions between origin and destinations, then you can choose which route u want deponent on duration, or distance inside legs.
then convert points (inside overview_polyline) to list of CLLocationCoordinate2D using Polyline library https://github.com/raphaelmor/Polyline
Like this:
func convertPointToCoordinates() -> [CLLocationCoordinate2D]? {
let polyline = Polyline(encodedPolyline: overviewPolyline.points ?? "")
return polyline.coordinates
}
let coordinates = convertPointToCoordinates()
let polyLine = MKPolyline(coordinates: coordinates ?? [], count: (coordinates?.count ?? 0))
to add polyline on map view:
self.mapView.add(polyLine)
to focus on polyline region:
self.mapView.setVisibleMapRect(polyLine.boundingMapRect, edgePadding: UIEdgeInsets.init(top: 60, left: 60, bottom: 60, right: 60), animated: true)
回答3:
Swift 3 version, slightly condensed, thanks to ztan.
If you want to use Googles geo polylines in iOS without Google SDK.
func polyLineWithEncodedString(encodedString: String) -> [CLLocationCoordinate2D] {
var myRoutePoints=[CLLocationCoordinate2D]()
let bytes = (encodedString as NSString).utf8String
var idx: Int = 0
var latitude: Double = 0
var longitude: Double = 0
while (idx < encodedString.lengthOfBytes(using: String.Encoding.utf8)) {
var byte = 0
var res = 0
var shift = 0
repeat {
byte = bytes![idx] - 63
idx += 1
res |= (byte & 0x1F) << shift
shift += 5
} while (byte >= 0x20)
let deltaLat = ((res & 1) != 0x0 ? ~(res >> 1) : (res >> 1))
latitude += Double(deltaLat)
shift = 0
res = 0
repeat {
byte = bytes![idx] - 63
idx += 1
res |= (byte & 0x1F) << shift
shift += 5
} while (byte >= 0x20)
let deltaLon = ((res & 1) != 0x0 ? ~(res >> 1) : (res >> 1))
longitude += Double(deltaLon)
myRoutePoints.append(CLLocation(latitude: Double(latitude * 1E-5), longitude: Double(longitude * 1E-5)).coordinate)
}
return myRoutePoints
}
来源:https://stackoverflow.com/questions/31332277/is-there-a-way-to-get-directionsjust-routes-using-google-for-mkmapview