How do i remove this default red marker from google maps iOS Swift - ios

I want to remove this red pins. I am adding custom pins to source (yellow pin) and destination (blue pin, but I still not understand why this red pins also show ?
Here is Code :-
func reDrawRoute(pickupCoordinate : CLLocationCoordinate2D, destinationCoordinate :CLLocationCoordinate2D, type: String) {
// func setMapMarkersRoute(vLoc: CLLocationCoordinate2D, toLoc: CLLocationCoordinate2D) {
self.sourceMarker.map = nil
self.destMarker.map = nil
//add the markers for the 2 locations
if type == "S2D" {
self.sourceMarker = GMSMarker.init(position: pickupCoordinate)
self.sourceMarker.icon = UIImage(named: "source")
self.sourceMarker.map = gMapView
self.destMarker = GMSMarker.init(position: destinationCoordinate)
self.destMarker.icon = UIImage(named: "destination")
self.destMarker.map = gMapView
} else if type == "C2S" {
self.carMarker.position = pickupCoordinate
self.carMarker.icon = UIImage(named: "pin-car")
self.carMarker.map = gMapView
self.destMarker = GMSMarker.init(position: destinationCoordinate)
self.destMarker.icon = UIImage(named: "source")
self.destMarker.map = gMapView
} else if type == "C2D" {
self.carMarker.position = pickupCoordinate
self.carMarker.icon = UIImage(named: "pin-car")
self.carMarker.map = gMapView
self.destMarker = GMSMarker.init(position: destinationCoordinate)
self.destMarker.icon = UIImage(named: "destination")
self.destMarker.map = gMapView
}
//zoom the map to show the desired area
var bounds = GMSCoordinateBounds()
bounds = bounds.includingCoordinate(pickupCoordinate)
bounds = bounds.includingCoordinate(destinationCoordinate)
self.gMapView.moveCamera(GMSCameraUpdate.fit(bounds))
//finally get the route
getRoute(from: pickupCoordinate, to: destinationCoordinate)
}
This is for getting route coordinates between source and destination.
func getRoute(from: CLLocationCoordinate2D, to: CLLocationCoordinate2D) {
let source = MKMapItem(placemark: MKPlacemark(coordinate: from))
let destination = MKMapItem(placemark: MKPlacemark(coordinate: to))
let request = MKDirections.Request()
request.source = source
request.destination = destination
request.requestsAlternateRoutes = false
let directions = MKDirections(request: request)
directions.calculate(completionHandler: { (response, error) in
if let res = response {
//the function to convert the result and show
self.show(polyline: self.googlePolylines(from: res))
}
})
}
This code is for showing route.
private func googlePolylines(from response: MKDirections.Response) -> GMSPolyline {
let route = response.routes[0]
var coordinates = [CLLocationCoordinate2D](
repeating: kCLLocationCoordinate2DInvalid,
count: route.polyline.pointCount)
route.polyline.getCoordinates(
&coordinates,
range: NSRange(location: 0, length: route.polyline.pointCount))
let polyline = Polyline(coordinates: coordinates)
let encodedPolyline: String = polyline.encodedPolyline
let path = GMSPath(fromEncodedPath: encodedPolyline)
return GMSPolyline(path: path)
}
I am using this method for adding custom markers..

Related

How can I draw a polyline in ARKit using latitude and longitude?

Currently I can render the spheres using latitude and longitude in ARKit Geolocation Tracking , can anyone please guide me how can I draw polyline between 2 CLLocation in ARKit .
here is a full code to create poly line between two points and also set a width and color of that poly line
var locManager = CLLocationManager()
var currentLocation: CLLocation!
let annotation = MKPointAnnotation()
let annotation2 = MKPointAnnotation()
// MARK:- DRIVER -
var driverLatitute:String!
var driverLongitude:String!
// MARK:- RESTAURANT -
var restaurantLatitude:String!
var restaurantLongitude:String!
IN VIEW DID LOAD
// MARK:- 1 ( MAP ) -
self.locManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
self.locManager.delegate = self
self.locManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
self.locManager.startUpdatingLocation()
print("UPDATE UPDATE")
}
if (CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedWhenInUse ||
CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedAlways) {
print("")
}
DELEGATE METHODS
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
//print("**********************")
//print("Long \(manager.location!.coordinate.longitude)")
//print("Lati \(manager.location!.coordinate.latitude)")
//print("Alt \(manager.location!.altitude)")
//print("Speed \(manager.location!.speed)")
//print("Accu \(manager.location!.horizontalAccuracy)")
//print("**********************")
//print(Double((vendorLatitute as NSString).doubleValue))
//print(Double((vendorLongitute as NSString).doubleValue))
/*
// restaurant
self.restaurantLatitude = (dict["deliveryLat"] as! String)
self.restaurantLongitude = (dict["deliveryLong"] as! String)
// driver
self.driverLatitute = (dict["resturentLatitude"] as! String)
self.driverLongitude = (dict["resturentLongitude"] as! String)
*/
let restaurantLatitudeDouble = Double(self.restaurantLatitude)
let restaurantLongitudeDouble = Double(self.restaurantLongitude)
let driverLatitudeDouble = Double("\(manager.location!.coordinate.latitude)") //Double(self.driverLatitute)
let driverLongitudeDouble = Double("\(manager.location!.coordinate.longitude)") // Double(self.driverLongitude)
let coordinate₀ = CLLocation(latitude: restaurantLatitudeDouble!, longitude: restaurantLongitudeDouble!)
let coordinate₁ = CLLocation(latitude: driverLatitudeDouble!, longitude: driverLongitudeDouble!)
/************************************** RESTAURANT LATITUTDE AND LONGITUDE ********************************/
// first location
let sourceLocation = CLLocationCoordinate2D(latitude: restaurantLatitudeDouble!, longitude: restaurantLongitudeDouble!)
/********************************************************************************************************************/
/************************************* DRIVER LATITUTDE AND LINGITUDE ******************************************/
// second location
let destinationLocation = CLLocationCoordinate2D(latitude: driverLatitudeDouble!, longitude: driverLongitudeDouble!)
/********************************************************************************************************************/
//print(sourceLocation)
//print(destinationLocation)
let sourcePin = customPin(pinTitle: "You", pinSubTitle: "", location: sourceLocation)
let destinationPin = customPin(pinTitle: "Driver", pinSubTitle: "", location: destinationLocation)
/***************** REMOVE PREVIUOS ANNOTATION TO GENERATE NEW ANNOTATION *******************************************/
self.mapView.removeAnnotations(self.mapView.annotations)
/********************************************************************************************************************/
self.mapView.addAnnotation(sourcePin)
self.mapView.addAnnotation(destinationPin)
let sourcePlaceMark = MKPlacemark(coordinate: sourceLocation)
let destinationPlaceMark = MKPlacemark(coordinate: destinationLocation)
let directionRequest = MKDirections.Request()
directionRequest.source = MKMapItem(placemark: sourcePlaceMark)
directionRequest.destination = MKMapItem(placemark: destinationPlaceMark)
directionRequest.transportType = .automobile
let directions = MKDirections(request: directionRequest)
directions.calculate { [self] (response, error) in
guard let directionResonse = response else {
if let error = error {
print("we have error getting directions==\(error.localizedDescription)")
}
return
}
/***************** REMOVE PREVIUOS POLYLINE TO GENERATE NEW POLYLINE *******************************/
let overlays = self.mapView.overlays
self.mapView.removeOverlays(overlays)
/************************************************************************************/
/***************** GET DISTANCE BETWEEN TWO CORDINATES *******************************/
let distanceInMeters = coordinate₀.distance(from: coordinate₁)
// print(distanceInMeters as Any)
// remove decimal
let distanceFloat: Double = (distanceInMeters as Any as! Double)
// print(distanceFloat as Any)
// self.lblDistance.text = (String(format: "Distance : %.0f Miles away", distanceFloat/1609.344))
self.lblTotalDistance.text = (String(format: "Distance : %.0f Miles away", distanceFloat/1609.344))
// print(distanceFloat/1609.344)
// print(String(format: "Distance : %.0f Miles away", distanceFloat/1609.344))
let s:String = String(format: "%.0f",distanceFloat/1609.344)
// print(s as Any)
/************************************************************************************/
/***************** GENERATE NEW POLYLINE *******************************/
let route = directionResonse.routes[0]
self.mapView.addOverlay(route.polyline, level: .aboveRoads)
let rect = route.polyline.boundingMapRect
self.mapView.setRegion(MKCoordinateRegion(rect), animated: true)
/************************************************************************************/
}
self.mapView.delegate = self
print("update location after 5 sec")
// self.locManager.stopUpdatingLocation()
// speed = distance / time
}
// line width of poly line
//MARK:- MapKit delegates -
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = UIColor.blue
renderer.lineWidth = 4.0
return renderer
}

draw polyline in parallel with animation marker in google maps

I am using google maps in my application wherein I have to draw the polyline parallel along with the animation marker.Both should move simultaneous.,
Right now, my solution works like this ., First polyline is drawn with new coordinates, then animation marker is moved after.
I have tried few links in the stack overflow.. wherein the solution wasn't there.
This is the solution i'm looking for in swift iOS... the below link is for android.. which works perfectly
How to move marker along polyline using google map
Thanks if you can help me out in these..`
#objc func pocDrawPolyline() {
if poclastShownIndex < (vehicleLocationArray.count) {
let dict = vehicleLocationArray[poclastShownIndex]
if let lati = dict["latitude"], let logi = dict["longitude"] {
let lat = Double(lati as! String)
let log = Double(logi as! String)
let location = dict["location"] as? String
pocCreateVehicleMarkerWith(address: location ?? "School Bus", latitude: lat!, and: log!)
pocPath.add(CLLocationCoordinate2DMake(lat!, log!))
}
polyline.path = pocPath
polyline.strokeWidth = 3.0
polyline.strokeColor = UIColor.red
polyline.map = googleMapView
poclastShownIndex += 1
} else {
//No update from "NOW" API call
}
}
func pocCreateVehicleMarkerWith(address: String, latitude: Double, and Longitude: Double) {
// Creates a marker for Vehicle.
if vechicleMarker.map == nil {
vechicleMarker.position = CLLocationCoordinate2D(latitude: latitude, longitude: Longitude)
vechicleMarker.title = address
vechicleMarker.icon = UIImage(named: "bus1")
vechicleMarker.map = googleMapView
} else {
CATransaction.begin()
CATransaction.setAnimationDuration(0.5)
vechicleMarker.position = CLLocationCoordinate2D(latitude: latitude, longitude: Longitude)
vechicleMarker.title = address
vechicleMarker.icon = UIImage(named: "bus1")
CATransaction.commit()
if poclastShownIndex > 0 {
if let oldLatitude = vehicleLocationArray[poclastShownIndex-1]["latitude"],
let oldLongitude = vehicleLocationArray[poclastShownIndex-1]["longitude"],
let newLatitude = vehicleLocationArray[poclastShownIndex]["latitude"],
let newLongitude = vehicleLocationArray[poclastShownIndex]["longitude"] {
let oldLat = Double(oldLatitude as! String)
let oldLon = Double(oldLongitude as! String)
let newLat = Double(newLatitude as! String)
let newLon = Double(newLongitude as! String)
let oldloc = CLLocationCoordinate2D(latitude: oldLat!, longitude: oldLon!)
let newloc = CLLocationCoordinate2D(latitude: newLat!, longitude: newLon!)
let distanceInMeters = distance(from: oldloc, to: newloc)
if distanceInMeters > 0 {
print("Rotation Degree ------ \(CLLocationDegrees(getHeadingForDirection(fromCoordinate: oldloc, toCoordinate: newloc)))")
vechicleMarker.groundAnchor = CGPoint(x: CGFloat(0.5), y: CGFloat(0.5))
vechicleMarker.rotation = CLLocationDegrees(getHeadingForDirection(fromCoordinate: oldloc, toCoordinate: newloc))
googleMapView.animate(toLocation: newloc)
}
}
}
}
}func timerMethod() {
pocTimer = Timer.scheduledTimer(timeInterval: 10.0, target: self, selector: #selector(pocDrawPolyline), userInfo: nil, repeats: true)
}`

NMACoreRouter calculateRouteWithStops no callback (swift)

I'm trying to create a route using Here API in Swift but I'm having some issues because the completion block is never called so I cannot know exactly what is the problem.
Here is my code:
let coreRoute = NMACoreRouter()
let startPoint = NMAGeoCoordinates(latitude: latitude1, longitude: longitude1)
let waypoint1 = NMAWaypoint(geoCoordinates: startPoint)
let middlePoint = NMAGeoCoordinates(latitude: latitude2, longitude: longitude2)
let waypoint2 = NMAWaypoint(geoCoordinates: middlePoint, waypointType: NMAWaypointType.ViaWaypoint)
let endPoint = NMAGeoCoordinates(latitude: latitude3, longitude: longitude3)
let waypoint3 = NMAWaypoint(geoCoordinates: endPoint, waypointType: NMAWaypointType.StopWaypoint)
let stopList = [waypoint1, waypoint2, waypoint3] // I have also tried adding the NMAGeoCoordinates to array but still no callback
let routingMode = NMARoutingMode(routingType: NMARoutingType.Fastest, transportMode: NMATransportMode.Car, routingOptions: 0)
coreRoute.calculateRouteWithStops(stopList, routingMode: routingMode) { (routeResult: NMARouteResult?, error: NMARoutingError?) in
if error == nil && routeResult != nil && routeResult!.routes.count > 0 {
let route = routeResult!.routes.first as! NMARoute
let mapRoute = NMAMapRoute(route: route)
self.mapView.addMapObject(mapRoute)
} else {
// Handle error
}
}
Does anyone have any idea about this problem?
P.S. There is no problem with the app id, app code and license key. The NMAApplicationContext is successfully set in AppDelegate
Found the solution!
You need to declare NMACoreRouter object as a class variable.
class <Class_Name> {
var coreRouter: NMACoreRouter!
func <Your_Function>() {
coreRoute = NMACoreRouter()
let startPoint = NMAGeoCoordinates(latitude: latitude1, longitude: longitude1)
let waypoint1 = NMAWaypoint(geoCoordinates: startPoint)
let middlePoint = NMAGeoCoordinates(latitude: latitude2, longitude: longitude2)
let waypoint2 = NMAWaypoint(geoCoordinates: middlePoint, waypointType: NMAWaypointType.ViaWaypoint)
let endPoint = NMAGeoCoordinates(latitude: latitude3, longitude: longitude3)
let waypoint3 = NMAWaypoint(geoCoordinates: endPoint, waypointType: NMAWaypointType.StopWaypoint)
let stopList = [waypoint1, waypoint2, waypoint3] // I have also tried adding the NMAGeoCoordinates to array but still no callback
let routingMode = NMARoutingMode(routingType: NMARoutingType.Fastest, transportMode: NMATransportMode.Car, routingOptions: 0)
coreRoute.calculateRouteWithStops(stopList, routingMode: routingMode) { (routeResult: NMARouteResult?, error: NMARoutingError?) in
if error == nil && routeResult != nil && routeResult!.routes.count > 0 {
let route = routeResult!.routes.first as! NMARoute
let mapRoute = NMAMapRoute(route: route)
self.mapView.addMapObject(mapRoute)
} else {
// Handle error
}
}
}
}
EDIT: Navigation Code
let navigationManager = NMANavigationManager.sharedNavigationManager()
navigationManager.delegate = self
navigationManager.map = mapView
navigationManager.startTurnByTurnNavigationWithRoute(route)
navigationManager.startTrackingWithTransportMode(.Car)
//Simulation
sharedPositioningManager.dataSource = NMARoutePositionSource(route: route)

How to display time on route as google maps

I have created route with multiple annotations.
I want to display text between annotations which exactly as attached screen shot.
Can any one help please?
Thanks
I tried something which will show the distance between two annotation but not when you tap on the MKPolylineOverlay. One more important thing I am not maintaining any standards.
Here is my controller structure.
import UIKit
import MapKit
class RouteViewController: UIViewController, MKMapViewDelegate {
#IBOutlet weak var mapView: MKMapView!
//Rest of the code see below
}
First of all I'll add some annotation to map in the viewDidLoad delegate method as below.
override func viewDidLoad() {
super.viewDidLoad()
self.mapView.delegate = self
let annotation1 = MKPointAnnotation()
annotation1.title = "Times Square"
annotation1.coordinate = CLLocationCoordinate2D(latitude: 40.759011, longitude: -73.984472)
let annotation2 = MKPointAnnotation()
annotation2.title = "Empire State Building"
annotation2.coordinate = CLLocationCoordinate2D(latitude: 40.748441, longitude: -73.985564)
let annotation3 = MKPointAnnotation()
annotation3.title = "Some Point"
annotation3.coordinate = CLLocationCoordinate2D(latitude: 40.7484, longitude: -73.97)
let arrayOfPoints = [ annotation1, annotation2, annotation3]
self.mapView.addAnnotations(arrayOfPoints)
self.mapView.centerCoordinate = annotation2.coordinate
for (index, annotation) in arrayOfPoints.enumerate() {
if index < (arrayOfPoints.count-1) {
//I am taking the two consecutive annotation and performing the routing operation.
self.directionHandlerMethod(annotation.coordinate, ePoint: arrayOfPoints[index+1].coordinate)
}
}
}
In the directionHandlerMethod, I am performing the actual request for direction as below,
func directionHandlerMethod(sPoint: CLLocationCoordinate2D, ePoint: CLLocationCoordinate2D) {
let sourcePlacemark = MKPlacemark(coordinate: sPoint, addressDictionary: nil)
let destinationPlacemark = MKPlacemark(coordinate: ePoint, addressDictionary: nil)
let sourceMapItem = MKMapItem(placemark: sourcePlacemark)
let destinationMapItem = MKMapItem(placemark: destinationPlacemark)
let directionRequest = MKDirectionsRequest()
directionRequest.source = sourceMapItem
directionRequest.destination = destinationMapItem
directionRequest.transportType = .Automobile
let directions = MKDirections(request: directionRequest)
directions.calculateDirectionsWithCompletionHandler {
(response, error) -> Void in
guard let response = response else {
if let error = error {
print("Error: \(error)")
}
return
}
//I am assuming that it will contain one and only one result so I am taking that one passing to addRoute method
self.addRoute(response.routes[0])
}
}
Next I am adding the polyline route on map in the addRoute method as below,
func addRoute(route: MKRoute) {
let polyline = route.polyline
//Here I am taking the centre point on the polyline and placing an annotation by giving the title as 'Route' and the distance in the subtitle
let annoatation = MKPointAnnotation()
annoatation.coordinate = MKCoordinateForMapPoint(polyline.points()[polyline.pointCount/2])
annoatation.title = "Route"
let timeInMinute = route.expectedTravelTime / 60
let distanceString = String.localizedStringWithFormat("%.2f %#", timeInMinute, timeInMinute>1 ? "minutes" : "minute")
annoatation.subtitle = distanceString
self.mapView.addAnnotation(annoatation)
self.mapView.addOverlay(polyline)
}
Next I am implementing the rendererForOverlay delegate method as below,
func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = UIColor.blueColor()
renderer.lineWidth = 2
renderer.lineCap = .Butt
renderer.lineJoin = .Round
return renderer
}
Next one is the important one delegate method which is viewForAnnotation. Here I am doing some things like placing the label instead of the annotation as below,
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if annotation.title != nil && annotation.title!! == "Route" {
let label = UILabel()
label.adjustsFontSizeToFitWidth = true
label.backgroundColor = UIColor.whiteColor()
label.minimumScaleFactor = 0.5
label.frame = CGRect(x: 0, y: 0, width: 100, height: 30)
label.text = annotation.subtitle ?? ""
let view = MKAnnotationView()
view.addSubview(label)
return view
}
return nil
}

How do I iterate through JSON co-ordinates and build annotations as one function?

I am struggling to get the annotations being placed using JSON data. I have tried iterating the coordinates from the JSON into a new array but when I try pass an array to where I need the coordinates it fails because it cannot take arrays. How can I fix this?
Can anyone help?
Alamofire.request(.GET, "https://demo1991046.mockable.io/score/locations").responseJSON { (responseData) -> Void in
let swiftyJsonVar = JSON(responseData.result.value!)
if let resData = swiftyJsonVar["users"].arrayObject as? [NSArray] {
self.newArray = (resData as? [NSArray])
}
print("\([self.newArray])")
for var i = 0; i < self.newArray!.count; ++i {
self.longitude.append(self.newArray[i]["lon"] as! String!)
print("longitude: \(self.longitude)")
self.latitude.append(self.newArray[i]["lat"] as! String!)
print("latitude: \(self.latitude)")
}
let doubleLat = self.latitude.map {
Double(($0 as NSString).doubleValue)
}
let doubleLon = self.longitude.map {
Double(($0 as NSString).doubleValue)
}
print("doublelat: \(doubleLat)")
print("doubleLon: \(doubleLon)")
// 1
self.locationManager.delegate = self
// 2
self.locationManager.requestAlwaysAuthorization()
// 3
let theSpan:MKCoordinateSpan = MKCoordinateSpanMake(0.01 , 0.01)
let location:CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: doubleLat, longitude: doubleLon) // <- here is where I get an error: "Cannot convert value of type '[Double]' to expect argument type 'CLLocationDegrees' (aka 'Double")"
// print("lat: \((locationManager.location?.coordinate.latitude)!)")
// print("lon: \((locationManager.location?.coordinate.longitude)!)")
let theRegion:MKCoordinateRegion = MKCoordinateRegionMake(location, theSpan)
self.mapView.setRegion(theRegion, animated: true)
let anotation = MKPointAnnotation()
anotation.coordinate = location
anotation.title = "The Location"
anotation.subtitle = "This is the location !!!"
self.mapView.addAnnotation(anotation)
}
}
I have done soem modifies below to your code
Didn't convert the json to NSArray (by using .array instead of .arrayObject)
moved adding anotation to the map inside the for loop to add all of them.
Moved setting a region to the map out side the for loop and left it to you to set the location you like.
Alamofire.request(.GET, "https://demo1991046.mockable.io/score/locations").responseJSON { (responseData) -> Void in
let swiftyJsonVar = JSON(responseData.result.value!)
// get the users from the json var, no need to convert it to Array
guard let usersJsonArray = swiftyJsonVar["users"].array else {
// users not found in the json
return
}
// the usersJsonArray is array of json which will be much easier for work with.
// No need for 1,2 and 3 to be in the for loop.
// 1
self.locationManager.delegate = self
// 2
self.locationManager.requestAlwaysAuthorization()
// 3
let theSpan:MKCoordinateSpan = MKCoordinateSpanMake(0.01 , 0.01)
for userJson in usersJsonArray {
let longitudeString = userJson["lon"].stringValue
print("longitude: \(longitudeString)")
let latitudeString = userJson["lat"].stringValue
print("latitude: \(latitudeString)")
let doubleLat = Double(latitudeString)
let doubleLon = Double(longitudeString)
print("doublelat: \(doubleLat)")
print("doubleLon: \(doubleLon)")
// by having the next code block inside the for loop you will be able to add all the user locations to the map as anotations.
let location:CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: doubleLat, longitude: doubleLon) // Now should work fine
let anotation = MKPointAnnotation()
anotation.coordinate = location
anotation.title = "The Location"
anotation.subtitle = "This is the location !!!"
self.mapView.addAnnotation(anotation)
} // for usersJson
// you need to figure out the loaction you will set for the mapView region.
let location = .... // set the location you like.
let theRegion:MKCoordinateRegion = MKCoordinateRegionMake(location, theSpan)
self.mapView.setRegion(theRegion, animated: true)
}

Resources