Is there a way to get directions(just routes) using google for mkmapview?

时光总嘲笑我的痴心妄想 提交于 2019-12-01 07:41:09

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!