我正在开发一个 iOS 应用程序。在那个应用程序中,我有 2 个从和到的字段。我使用谷歌自动完成 API 输入地址。我还能够获取 2 个地方的纬度和经度,并能够在GMSMapView
.
现在我想在这两个地方之间画出路线。当我们使用MKMapView
. 但我无法找到解决方案GMSMapView
。请帮我画出这两个点之间的路线GMSMapView
。
如果可能的话,请给我一些重要的链接。
谢谢。
我正在开发一个 iOS 应用程序。在那个应用程序中,我有 2 个从和到的字段。我使用谷歌自动完成 API 输入地址。我还能够获取 2 个地方的纬度和经度,并能够在GMSMapView
.
现在我想在这两个地方之间画出路线。当我们使用MKMapView
. 但我无法找到解决方案GMSMapView
。请帮我画出这两个点之间的路线GMSMapView
。
如果可能的话,请给我一些重要的链接。
谢谢。
`first get all points coordinates which are coming in route then add these points latitude and longitude in path in will draw path according to that`
GMSCameraPosition *cameraPosition=[GMSCameraPosition cameraWithLatitude:18.5203 longitude:73.8567 zoom:12];
_mapView =[GMSMapView mapWithFrame:CGRectZero camera:cameraPosition];
_mapView.myLocationEnabled=YES;
GMSMarker *marker=[[GMSMarker alloc]init];
marker.position=CLLocationCoordinate2DMake(18.5203, 73.8567);
marker.icon=[UIImage imageNamed:@"aaa.png"] ;
marker.groundAnchor=CGPointMake(0.5,0.5);
marker.map=_mapView;
GMSMutablePath *path = [GMSMutablePath path];
[path addCoordinate:CLLocationCoordinate2DMake(@(18.520).doubleValue,@(73.856).doubleValue)];
[path addCoordinate:CLLocationCoordinate2DMake(@(16.7).doubleValue,@(73.8567).doubleValue)];
GMSPolyline *rectangle = [GMSPolyline polylineWithPath:path];
rectangle.strokeWidth = 2.f;
rectangle.map = _mapView;
self.view=_mapView;
我编写了以下代码,应该可以为您解决问题:
- (void)drawRoute
{
[self fetchPolylineWithOrigin:myOrigin destination:myDestination completionHandler:^(GMSPolyline *polyline)
{
if(polyline)
polyline.map = self.myMap;
}];
}
- (void)fetchPolylineWithOrigin:(CLLocation *)origin destination:(CLLocation *)destination completionHandler:(void (^)(GMSPolyline *))completionHandler
{
NSString *originString = [NSString stringWithFormat:@"%f,%f", origin.coordinate.latitude, origin.coordinate.longitude];
NSString *destinationString = [NSString stringWithFormat:@"%f,%f", destination.coordinate.latitude, destination.coordinate.longitude];
NSString *directionsAPI = @"https://maps.googleapis.com/maps/api/directions/json?";
NSString *directionsUrlString = [NSString stringWithFormat:@"%@&origin=%@&destination=%@&mode=driving", directionsAPI, originString, destinationString];
NSURL *directionsUrl = [NSURL URLWithString:directionsUrlString];
NSURLSessionDataTask *fetchDirectionsTask = [[NSURLSession sharedSession] dataTaskWithURL:directionsUrl completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error)
{
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
if(error)
{
if(completionHandler)
completionHandler(nil);
return;
}
NSArray *routesArray = [json objectForKey:@"routes"];
GMSPolyline *polyline = nil;
if ([routesArray count] > 0)
{
NSDictionary *routeDict = [routesArray objectAtIndex:0];
NSDictionary *routeOverviewPolyline = [routeDict objectForKey:@"overview_polyline"];
NSString *points = [routeOverviewPolyline objectForKey:@"points"];
GMSPath *path = [GMSPath pathFromEncodedPath:points];
polyline = [GMSPolyline polylineWithPath:path];
}
// run completionHandler on main thread
dispatch_sync(dispatch_get_main_queue(), ^{
if(completionHandler)
completionHandler(polyline);
});
}];
[fetchDirectionsTask resume];
}
用于 swift 3 绘制折线
func getPolylineRoute(from source: CLLocationCoordinate2D, to destination: CLLocationCoordinate2D){
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let url = URL(string: "https://maps.googleapis.com/maps/api/directions/json?origin=\(source.latitude),\(source.longitude)&destination=\(destination.latitude),\(destination.longitude)&sensor=true&mode=driving&key=YOURKEY")!
let task = session.dataTask(with: url, completionHandler: {
(data, response, error) in
if error != nil {
print(error!.localizedDescription)
self.activityIndicator.stopAnimating()
}
else {
do {
if let json : [String:Any] = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any]{
guard let routes = json["routes"] as? NSArray else {
DispatchQueue.main.async {
self.activityIndicator.stopAnimating()
}
return
}
if (routes.count > 0) {
let overview_polyline = routes[0] as? NSDictionary
let dictPolyline = overview_polyline?["overview_polyline"] as? NSDictionary
let points = dictPolyline?.object(forKey: "points") as? String
self.showPath(polyStr: points!)
DispatchQueue.main.async {
self.activityIndicator.stopAnimating()
let bounds = GMSCoordinateBounds(coordinate: source, coordinate: destination)
let update = GMSCameraUpdate.fit(bounds, with: UIEdgeInsetsMake(170, 30, 30, 30))
self.mapView!.moveCamera(update)
}
}
else {
DispatchQueue.main.async {
self.activityIndicator.stopAnimating()
}
}
}
}
catch {
print("error in JSONSerialization")
DispatchQueue.main.async {
self.activityIndicator.stopAnimating()
}
}
}
})
task.resume()
}
func showPath(polyStr :String){
let path = GMSPath(fromEncodedPath: polyStr)
let polyline = GMSPolyline(path: path)
polyline.strokeWidth = 3.0
polyline.strokeColor = UIColor.red
polyline.map = mapView // Your map view
}
注意:您需要将 googleDirection API 密钥放在 URL 中。
如果有人正在为@Tarek 的答案寻找Swift 3.0 ,您可以使用它。这也使用Alamofire和SwiftyJSON。
func drawPath()
{
let origin = "\(currentLocation.latitude),\(currentLocation.longitude)"
let destination = "\(destinationLoc.latitude),\(destinationLoc.longitude)"
let url = "https://maps.googleapis.com/maps/api/directions/json?origin=\(origin)&destination=\(destination)&mode=driving&key=YOURKEY"
Alamofire.request(url).responseJSON { response in
print(response.request) // original URL request
print(response.response) // HTTP URL response
print(response.data) // server data
print(response.result) // result of response serialization
let json = JSON(data: response.data!)
let routes = json["routes"].arrayValue
for route in routes
{
let routeOverviewPolyline = route["overview_polyline"].dictionary
let points = routeOverviewPolyline?["points"]?.stringValue
let path = GMSPath.init(fromEncodedPath: points!)
let polyline = GMSPolyline.init(path: path)
polyline.map = self.mapView
}
}
}
这是 johny kumar 答案的 Swift 翻译。
let cameraPositionCoordinates = CLLocationCoordinate2D(latitude: 18.5203, longitude: 73.8567)
let cameraPosition = GMSCameraPosition.cameraWithTarget(cameraPositionCoordinates, zoom: 12)
let mapView = GMSMapView.mapWithFrame(CGRectZero, camera: cameraPosition)
mapView.myLocationEnabled = true
let marker = GMSMarker()
marker.position = CLLocationCoordinate2DMake(18.5203, 73.8567)
marker.groundAnchor = CGPointMake(0.5, 0.5)
marker.map = mapView
let path = GMSMutablePath()
path.addCoordinate(CLLocationCoordinate2DMake(18.520, 73.856))
path.addCoordinate(CLLocationCoordinate2DMake(16.7, 73.8567))
let rectangle = GMSPolyline(path: path)
rectangle.strokeWidth = 2.0
rectangle.map = mapView
self.view = mapView
- Swift 3.0 & XCode 8.0 Staright Line :(
let cameraPosition = GMSCameraPosition.camera(withLatitude: 18.5203, longitude: 73.8567, zoom: 12)
self.mapView = GMSMapView.map(withFrame: CGRect.zero, camera: cameraPosition)
self.mapView.isMyLocationEnabled = true
let marker = GMSMarker()
marker.position = CLLocationCoordinate2DMake(18.5203, 73.8567)
// marker.icon = UIImage(named: "aaa.png")!
marker.groundAnchor = CGPoint(x: 0.5, y: 0.5)
marker.map = mapView
let path = GMSMutablePath()
path.add(CLLocationCoordinate2DMake(CDouble((18.520)), CDouble((73.856))))
path.add(CLLocationCoordinate2DMake(CDouble((16.7)), CDouble((73.8567))))
let rectangle = GMSPolyline.init(path: path)
rectangle.strokeWidth = 2.0
rectangle.map = mapView
self.view = mapView
向 Google Directions API 发出 URL 请求,当您收到 JSON 文件时,请执行所有步骤并解码点对象。
我在 xCode 8.3.3 和 Swift 3.1 中使用 AlamoFire 和 SwiftyJson 做到了。将路径的绘制放在一个只需要两个参数的函数中
一个字符串源示例“48.7788,9.22222”和一个字符串目标示例“49.3212232,8.334151”
func drawPath (origin: String, destination: String) {
/* set the parameters needed */
String prefTravel = "walking" /* options are driving, walking, bicycling */
String gmapKey = "Ask Google"
/* Make the url */
let url = URL(string: "https://maps.googleapis.com/maps/api/directions/json?origin=\(origin)&destination=\(destination)&mode=\(prefTravel)&key=" + gmapKey)
/* Fire the request */
Alamofire.request(url!).responseJSON{(responseData) -> Void in
if((responseData.result.value) != nil) {
/* read the result value */
let swiftyJsonVar = JSON(responseData.result.value!)
/* only get the routes object */
if let resData = swiftyJsonVar["routes"].arrayObject {
let routes = resData as! [[String: AnyObject]]
/* loop the routes */
if routes.count > 0 {
for rts in routes {
/* get the point */
let overViewPolyLine = rts["overview_polyline"]?["points"]
let path = GMSMutablePath(fromEncodedPath: overViewPolyLine as! String)
/* set up poly line */
let polyline = GMSPolyline.init(path: path)
polyline.strokeWidth = 2
polyline.map = self.mapView
}
}
}
}
}
}
嗨您可以使用“LRouteController”,这是显示两点之间的道路路线的最佳方式,例如:
[_routeController getPolyline With Locations: (Array of first and last location)]
试试看,希望能解决你的问题。
来自Google Directions API的 DirectionResponse NSLogs 对于查看您正在使用的内容很有用。
[[GMDirectionService sharedInstance] getDirectionsFrom:origin to:destination succeeded:^(GMDirection *directionResponse) {
if ([directionResponse statusOK]){
NSLog(@"Duration : %@", [directionResponse durationHumanized]);
NSLog(@"Distance : %@", [directionResponse distanceHumanized]);
NSArray *routes = [[directionResponse directionResponse] objectForKey:@"routes"];
// NSLog(@"Route : %@", [[directionResponse directionResponse] objectForKey:@"routes"]);
GMSPath *path = [GMSPath pathFromEncodedPath:routes[0][@"overview_polyline"] [@"points"]];
GMSPolyline *polyline = [GMSPolyline polylineWithPath:path];
polyline.strokeColor = [UIColor redColor];
polyline.strokeWidth = 5.f;
polyline.map = mapView;
}
} failed:^(NSError *error) {
NSLog(@"Can't reach the server")
}];
如您所知,从谷歌获取路线和路线不是免费的,去年谷歌改变了他们的 api 调用价格!所以它可能并不适合所有人。因此,如果您拥有所有关键坐标并且只想将它们连接在一起,则可以使用以下内容。
用坐标制作路径:
extension GMSMutablePath {
convenience init(coordinates: [CLLocationCoordinate2D]) {
self.init()
for coordinate in coordinates {
add(coordinate)
}
}
}
添加地图路径:
extension GMSMapView {
func addPath(_ path: GMSPath, strokeColor: UIColor? = nil, strokeWidth: CGFloat? = nil, geodesic: Bool? = nil, spans: [GMSStyleSpan]? = nil) {
let line = GMSPolyline(path: path)
line.strokeColor = strokeColor ?? line.strokeColor
line.strokeWidth = strokeWidth ?? line.strokeWidth
line.geodesic = geodesic ?? line.geodesic
line.spans = spans ?? line.spans
line.map = self
}
}
用法:
let path = GMSMutablePath(coordinates: [<#Coordinates#>])
mapView.addPath(path)
Swift 5 它对我来说工作正常
View will appear
self.drawMap(SourceCordinate: CLLocationCoordinate2D(latitude: lat, longitude: long), destinationcordinate: CLLocationCoordinate2D(latitude: latitude, longitude: longitude))
func drawMap(SourceCordinate : CLLocationCoordinate2D, destinationcordinate :CLLocationCoordinate2D)
{
self.mapView.clear()
let str = String(format:"https://maps.googleapis.com/maps/api/directions/json?origin=\(SourceCordinate.latitude),\(SourceCordinate.longitude)&destination=\(destinationcordinate.latitude),\(destinationcordinate.longitude)&key=\(googleServiceKey)")
print(str)
Alamofire.request(str).responseJSON { (responseObject) -> Void in
let resJson = JSON(responseObject.result.value!)
print(resJson)
let routes : NSArray = resJson["routes"].rawValue as! NSArray
if(resJson["status"].rawString()! == "ZERO_RESULTS"){}
else if(resJson["status"].rawString()! == "NOT_FOUND"){}
else if routes.count == 0{}
else{
let routes : NSArray = resJson["routes"].rawValue as! NSArray
// let position = CLLocationCoordinate2D(latitude: SourceCordinate.latitude, longitude: SourceCordinate.longitude)
let markerEnd = GMSMarker()
markerEnd.position = CLLocationCoordinate2D(latitude: self.latitude, longitude: self.longitude)
markerEnd.map = self.mapView
let pathv : NSArray = routes.value(forKey: "overview_polyline") as! NSArray
let paths : NSArray = pathv.value(forKey: "points") as! NSArray
let newPath = GMSPath.init(fromEncodedPath: paths[0] as! String)
let polyLine = GMSPolyline(path: newPath)
polyLine.strokeWidth = 5
polyLine.strokeColor = .black
let ThemeOrange = GMSStrokeStyle.solidColor( .blue)
let OrangeToBlue = GMSStrokeStyle.gradient(from: .blue, to: .blue)
polyLine.spans = [GMSStyleSpan(style: ThemeOrange),
GMSStyleSpan(style: ThemeOrange),
GMSStyleSpan(style: OrangeToBlue)]
polyLine.map = self.mapView
}
}
}