カスタムUIViewでGoogleマップを使用して2つの場所間にルートを描画しようとしていますが、正しく実装することができません。私のカスタムビューはmapViewXです。ポッド「GoogleMaps」とポッド「GooglePlaces」を含むポッドを使用して、Google SDKをインストールしました。カスタムビュークラスを「GMSMapView」として作成しました。私のコードは:
@IBOutlet weak var mapViewX: GMSMapView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let path = GMSMutablePath()
path.add(CLLocationCoordinate2D(latitude: 37.778483, longitude: -122.513960))
path.add(CLLocationCoordinate2D(latitude: 37.706753, longitude: -122.418677))
let polyline = GMSPolyline(path: path)
polyline.strokeColor = .black
polyline.strokeWidth = 10.0
polyline.map = mapViewX
}
助けてください!
ここでは問題なく動作します。 GMSCameraPosition
の正しい座標を設定していることを確認してください。
[〜#〜]編集[〜#〜]
2つの座標間のルートを描画するには、Google Maps Direction API
を使用します
何かのようなもの :
let Origin = "\(37.778483),\(-122.513960)"
let destination = "\(37.706753),\(-122.418677)"
let url = "https://maps.googleapis.com/maps/api/directions/json?origin=\(Origin)&destination=\(destination)&mode=driving&key=[YOUR-API-KEY]"
Alamofire.request(url).responseJSON { response in
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(path: path)
polyline.strokeColor = .black
polyline.strokeWidth = 10.0
polyline.map = mapViewX
}
}
詳細情報- Directions API開発者ガイド
2つの座標間のルートを描画するには、Google Maps Directions APIにリクエストを送信し、そのレスポンスを解析する必要があります。したがって、最初にリクエストのAPIキーを取得する必要があります。プロジェクトを作成し、このプロジェクトでGoogle Maps Directions APIを有効にすることで、1つ here を取得できます。
Google Maps SDKがインストールされていると仮定すると、Directions APIにリクエストを送信し、そのレスポンスを解析する必要があります。応答JSONを解析したら、GMSPathオブジェクトを作成できます。 CLLocationCoordinate2Dオブジェクトの開始と終了の2つの入力があり、成功した場合はGMSPathを返し、何かが失敗した場合はエラーを返す関数を使用することをお勧めします。以下のコードはSwift 3。
私のクラスとその機能は次のようになります:
import Foundation
import CoreLocation
import GoogleMaps
class SessionManager {
let GOOGLE_DIRECTIONS_API_KEY = "INSERT_YOUR_API_KEY_HERE"
func requestDirections(from start: CLLocationCoordinate2D, to end: CLLocationCoordinate2D, completionHandler: @escaping ((_ response: GMSPath?, _ error: Error?) -> Void)) {
guard let url = URL(string: "https://maps.googleapis.com/maps/api/directions/json?origin=\(start.latitude),\(start.longitude)&destination=\(end.latitude),\(end.longitude)&key=\(GOOGLE_DIRECTIONS_API_KEY)") else {
let error = NSError(domain: "LocalDomain", code: 0, userInfo: [NSLocalizedDescriptionKey: "Failed to create object URL"])
print("Error: \(error)")
completionHandler(nil, error)
return
}
// Set up the session
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let task = session.dataTask(with: url) { (data, response, error) in
// Check if there is an error.
guard error == nil else {
DispatchQueue.main.async {
print("Google Directions Request Error: \((error!)).")
completionHandler(nil, error)
}
return
}
// Make sure data was received.
guard let data = data else {
DispatchQueue.main.async {
let error = NSError(domain: "GoogleDirectionsRequest", code: 0, userInfo: [NSLocalizedDescriptionKey: "Failed to receive data"])
print("Error: \(error).")
completionHandler(nil, error)
}
return
}
do {
// Convert data to dictionary.
guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
DispatchQueue.main.async {
let error = NSError(domain: "GoogleDirectionsRequest", code: 2, userInfo: [NSLocalizedDescriptionKey: "Failed to convert JSON to Dictionary"])
print("Error: \(error).")
completionHandler(nil, error)
}
return
}
// Check if the the Google Direction API returned a status OK response.
guard let status: String = json["status"] as? String, status == "OK" else {
DispatchQueue.main.async {
let error = NSError(domain: "GoogleDirectionsRequest", code: 3, userInfo: [NSLocalizedDescriptionKey: "Google Direction API did not return status OK"])
print("Error: \(error).")
completionHandler(nil, error)
}
return
}
print("Google Direction API response:\n\(json)")
// We only need the 'points' key of the json dictionary that resides within.
if let routes: [Any] = json["routes"] as? [Any], routes.count > 0, let routes0: [String: Any] = routes[0] as? [String: Any], let overviewPolyline: [String: Any] = routes0["overview_polyline"] as? [String: Any], let points: String = overviewPolyline["points"] as? String {
// We need the get the first object of the routes array (route0), then route0's overview_polyline and finally overview_polyline's points object.
if let path: GMSPath = GMSPath(fromEncodedPath: points) {
DispatchQueue.main.async {
completionHandler(path, nil)
}
return
} else {
DispatchQueue.main.async {
let error = NSError(domain: "GoogleDirections", code: 5, userInfo: [NSLocalizedDescriptionKey: "Failed to create GMSPath from encoded points string."])
completionHandler(nil, error)
}
return
}
} else {
DispatchQueue.main.async {
let error = NSError(domain: "GoogleDirections", code: 4, userInfo: [NSLocalizedDescriptionKey: "Failed to parse overview polyline's points"])
completionHandler(nil, error)
}
return
}
} catch let error as NSError {
DispatchQueue.main.async {
completionHandler(nil, error)
}
return
}
}
task.resume()
}
}
次に、それをviewDidLoad
で次のように使用できます。
@IBOutlet weak var mapView: GMSMapView!
override func viewDidLoad() {
super.viewDidLoad()
let sessionManager = SessionManager()
let start = CLLocationCoordinate2D(latitude: 37.778483, longitude: -122.513960)
let end = CLLocationCoordinate2D(latitude: 37.706753, longitude: -122.418677)
sessionManager.requestDirections(from: start, to: end, completionHandler: { (path, error) in
if let error = error {
print("Something went wrong, abort drawing!\nError: \(error)")
} else {
// Create a GMSPolyline object from the GMSPath
let polyline = GMSPolyline(path: path!)
// Add the GMSPolyline object to the mapView
polyline.map = self.mapView
// Move the camera to the polyline
let bounds = GMSCoordinateBounds(path: path!)
let cameraUpdate = GMSCameraUpdate.fit(bounds, with: UIEdgeInsets(top: 40, left: 15, bottom: 10, right: 15))
self.mapView.animate(with: cameraUpdate)
}
})
}
お役に立てば幸いです。
Swift 4
グローバル変数を作成します。
var sourceLat = 0.0
var sourceLong = 0.0
var DestinationLat = 0.0
var DestinationLong = 0.0
var startLOC = CLLocation()
var endLOC = CLLocation()
Pod AlamofireとSwiftJSONをインストールします。
pod 'Alamofire', '~> 4.5'
pod 'SwiftyJSON'
ソースと宛先の間のルートを描くための関数を作成します。
func drawPath(startLocation: CLLocation, endLocation: CLLocation)
{
let Origin = "\(startLocation.coordinate.latitude),\(startLocation.coordinate.longitude)"
let destination = "\(endLocation.coordinate.latitude),\(endLocation.coordinate.longitude)"
let url = "https://maps.googleapis.com/maps/api/directions/json?origin=\(Origin)&destination=\(destination)&mode=driving"
Alamofire.request(url).responseJSON { response in
//print(response.request as Any) // original URL request
//print(response.response as Any) // HTTP URL response
//print(response.data as Any) // server data
//print(response.result as Any) // result of response serialization
let json = JSON(data: response.data!)
let routes = json["routes"].arrayValue
print(json)
// print route using Polyline
DispatchQueue.global(qos: .default).async(execute: {() -> Void in
// Do something...
DispatchQueue.main.async(execute: {() -> Void in
// self.hideHUD()
})
})
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.strokeWidth = 4
polyline.strokeColor = UIColor.black
polyline.map = self.mapViewBus
}
}
}
作成ボタンアクションは、ソースルートと宛先ルートを提供します。緯度と経度を与える。その後、コードを貼り付けます。
// Route Source & Destination
self.startLOC = CLLocation(latitude: sourceLat, longitude: sourceLong)
self.endLOC = CLLocation(latitude: DestinationLat, longitude: DestinationLong)
drawPath(startLocation: startLOC, endLocation: endLOC)
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: sourceLat, longitude: sourceLong)
// marker.icon = userImage.af_imageScaled(to: CGSize(width: 50, height: 50)).af_imageRoundedIntoCircle()
marker.title = "Source"
marker.map = mapViewBus
let markerr = GMSMarker()
markerr.position = CLLocationCoordinate2D(latitude: DestinationLat, longitude: DestinationLong)
// markerr.icon = washerImage.af_imageScaled(to: CGSize(width: 50, height: 50)).af_imageRoundedIntoCircle()
markerr.title = "Desintation"
markerr.map = mapViewBus
let camera = GMSCameraPosition.camera(withLatitude: sourceLat, longitude: sourceLong, zoom: 14.0)
self.mapViewBus.camera = camera
self.mapViewBus.animate(to: camera)