user2931321
user2931321

Reputation: 476

How to get centre of the route map using GoogleMaps sdk

I want to display an image at the centre of the route map. Below is the code used for directions between origin and destination:

        let camera1 = GMSCameraPosition.camera(withLatitude: 45.4654, longitude:9.1859, zoom: 0.0)
        self.mapView = GMSMapView.map(withFrame: cell.mapView.bounds, camera: camera1)

 Alamofire.request(url, method: .post, parameters: nil, encoding: JSONEncoding.default, headers: nil)
        .validate()
        .responseJSON { response in
            switch response.result {
            case .success:
                print(response.result.value!)
                print("Validation Successful")
                let dictResponse = response.result.value as! NSDictionary
                print(dictResponse)
                 let aryRoutes = dictResponse .value(forKey:"routes" ) as! NSArray
                print(aryRoutes)

                var aryOverViewPolyLines :NSArray = []
                aryOverViewPolyLines = aryRoutes .value(forKey: "overview_polyline") as! NSArray
                print(aryOverViewPolyLines)
                let strPoints = (aryOverViewPolyLines.value(forKey: "points") as! NSArray).object(at: 0)
                let polygon = GMSPolygon()
                polygon.path = GMSPath(fromEncodedPath: strPoints as! String)
                print(strPoints)
                let rectangle = GMSPolyline.init(path: polygon.path)
                rectangle.strokeWidth = 2.0
                rectangle.strokeColor = .white
                rectangle.map = self.mapView

                let mapBounds = GMSCoordinateBounds(path: polygon.path!)
                self.mapView.animate(with: GMSCameraUpdate.fit(mapBounds, withPadding: 150.0))



                case .failure(let error):
                print(response.result.value!)
                print(error)
            }
    }

Any suggestions how to solve this issue.

Upvotes: 0

Views: 432

Answers (2)

Allan Spreys
Allan Spreys

Reputation: 5707

The solution from @mnabaa works by finding the middle path on the polyline. However, some paths could be a lot longer in distance than others. As a result, the point returned by Mnabaa's solution could end up somewhere a lot closer to the point A than the point B depending on the route. The extension below takes this problem into account:

extension GMSPolyline {
    var middlePoint: CLLocationCoordinate2D? {
        guard let path = path else {
            return nil
        }
        var intermediatePoints: [CLLocationCoordinate2D] = []
        for coordinateIndex in 0 ..< path.count() - 1 {
            let startCoordinate = path.coordinate(at: coordinateIndex)
            let endCoordinate = path.coordinate(at: coordinateIndex + 1)
            let startLocation = CLLocation(latitude: startCoordinate.latitude, longitude: startCoordinate.longitude)
            let endLocation = CLLocation(latitude: endCoordinate.latitude, longitude: endCoordinate.longitude)
            let pathDistance = endLocation.distance(from: startLocation)
            let intervalLatIncrement = (endLocation.coordinate.latitude - startLocation.coordinate.latitude) / pathDistance
            let intervalLngIncrement = (endLocation.coordinate.longitude - startLocation.coordinate.longitude) / pathDistance
            for intervalDistance in 0 ..< Int(pathDistance) {
                let intervalLat = startLocation.coordinate.latitude + (intervalLatIncrement * Double(intervalDistance))
                let intervalLng = startLocation.coordinate.longitude + (intervalLngIncrement * Double(intervalDistance))
                let circleCoordinate = CLLocationCoordinate2D(latitude: intervalLat, longitude: intervalLng)
                intermediatePoints.append(circleCoordinate)
            }
        }
        return intermediatePoints[intermediatePoints.count / 2]
    }
}

It's based on the article by Dylan Maryk.

Upvotes: 1

lePapa
lePapa

Reputation: 377

func mapView(_ mapView: GMSMapView, didTap overlay: GMSOverlay) {
    if let route = overlay as? GMSPolyline{

        let coordinate = route.path!.coordinate(at: (route.path!.count()-1) / 2)
        route.customMapInfoMarker!.position = CLLocationCoordinate2D(latitude: coordinate.latitude, longitude: coordinate.longitude)
        route.customMapInfoMarker.groundAnchor = CGPoint(x: 0.5, y: 0.5)
        route.customMapInfoMarker.map = mapView
        route.customMapInfoMarker.iconView = // YOUR CUSTOM IMAGEVIEW HERE
    }
}

Extend GMSPolyline

extension GMSPolyline{

    fileprivate struct AssociatedKey {
        static var infoMarker = GMSMarker()
    }
    var customMapInfoMarker: GMSMarker! {
        get {
            if let marker = objc_getAssociatedObject(self, &AssociatedKey.infoMarker) as? GMSMarker {
                return marker
            }
            return GMSMarker()
        }
        set (newValue){
            if let newValue = newValue {
                objc_setAssociatedObject(
                    self,
                    &AssociatedKey.infoMarker,
                    newValue,
                    objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            }
        }
    }
}

Upvotes: 0

Related Questions