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)
}`
Related
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..
I have encountered a strange problem, when i zoom out the my polyline of custom coordinates starts disappearing, following is my code
func setTrackerLines(currentLoc: String, destinationLoc: String) {
let str1 = currentLoc
let LocArray1 = str1.components(separatedBy: ",")
let str2 = destinationLoc
let LocArray2 = str2.components(separatedBy: ",")
let path = GMSMutablePath()
path.add(CLLocationCoordinate2D(latitude: (LocArray1[0] as NSString).doubleValue, longitude: (LocArray1[1] as NSString).doubleValue))
path.add(CLLocationCoordinate2D(latitude: (LocArray2[0] as NSString).doubleValue, longitude: (LocArray2[1] as NSString).doubleValue))
let rectangle = GMSPolyline(path: path)
rectangle.strokeColor = UIColor.blue
rectangle.strokeWidth = 1
rectangle.map = self.myMapView
}
}
have call this method on viewdidload(), This is how i am using the code
for i in 0 ..< pointArray.count {
print("Delta: \(delta)")
if pointArray.count != (i + 1) {
self.setTrackerLines(currentLoc: pointArray[i], destinationLoc: pointArray[i + 1])
}
The result is showing in pictures. Kindly help please
I am building an application where I have to move multiple marker. These markers will be visible at my end according to the multiple user's live locations. I am able to update only a single marker. but the rest are not updating. I stored these data in firebase and I am getting their data from there.
override func viewDidLoad() {
super.viewDidLoad()
Database.database().reference().child("users").observe(.childChanged, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject]
{
self.hideHUD()
self.latitudeFloatValue = (dictionary["lat"] as! Double)
self.longitudeFloatValue = (dictionary["long"] as! Double)
self.moveMent.delegate = self
//set old coordinate
self.oldCoordinate = CLLocationCoordinate2DMake(self.latitudeFloatValue, self.longitudeFloatValue)
print(self.oldCoordinate)
// Create a GMSCameraPosition that tells the map to display the marker
let camera = GMSCameraPosition.camera(withLatitude: self.latitudeFloatValue, longitude: self.longitudeFloatValue , zoom: 14)
self.mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
self.mapView.isMyLocationEnabled = true
self.mapView.delegate = self
self.view = self.mapView
// Creates a marker in the center of the map.
self.driverMarker = GMSMarker()
self.driverMarker.position = self.oldCoordinate!
self.driverMarker.icon = UIImage(named: "car")
self.driverMarker.map = self.mapView
self.copyCordinates = self.cordinates
print(self.copyCordinates)
print(self.cordinates)
self.cordinates = ["lattitude":self.latitudeFloatValue,"longitude":self.longitudeFloatValue]
print("self.cordinates",self.cordinates)
print(self.oldCordinates)
print(self.newCordinates)
if(self.oldCordinates["lattitude"] == nil)
{
self.oldCordinates = self.cordinates
self.newCordinates = self.cordinates
}
self.newCordinates = self.cordinates
self.oldCordinates = self.copyCordinates
print("oldCordinates",self.oldCordinates)
print("newCordinates",self.newCordinates)
self.movinfMarker()
}
}, withCancel: nil)
//for use in background
self.locman.requestAlwaysAuthorization()
locman.requestWhenInUseAuthorization()
if (CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedWhenInUse || CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedAlways){
guard let currentLocation = locman.location else {
return
}
stringLatitude = currentLocation.coordinate.latitude
stringLongitude = currentLocation.coordinate.longitude
print(currentLocation.coordinate.latitude)
print(currentLocation.coordinate.longitude)
}
// Create a GMSCameraPosition that tells the map to display the marker
let camera = GMSCameraPosition.camera(withLatitude: stringLatitude, longitude: stringLongitude , zoom: 7)
self.mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
self.mapView.isMyLocationEnabled = true
self.mapView.delegate = self
self.view = self.mapView
Database.database().reference().child("users").observe(.childAdded, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject]
{
self.latitudeFloatValue = (dictionary["lat"] as! Double)
self.longitudeFloatValue = (dictionary["long"] as! Double)
self.titleMarker = (dictionary["username"] as! String)
self.uuidValue = (dictionary["uuid"] as! String)
self.states = [
State(name: self.titleMarker, uuid: self.uuidValue, long: self.longitudeFloatValue, lat: self.latitudeFloatValue),
]
}
for state in self.states {
// Creates a marker in the center of the map.
let state_marker = GMSMarker()
state_marker.position = CLLocationCoordinate2D(latitude: state.lat, longitude: state.long)
state_marker.icon = UIImage(named: "car")
state_marker.title = state.name
state_marker.userData = state.uuid//zIndex = Int32(state.uuid)!
state_marker.snippet = "Hey, this is \(state.name)"
state_marker.map = self.mapView
self.markerDict[state.name] = state_marker
}
}, withCancel: nil)
}
func movinfMarker(){
driverMarker.map = nil
let oldCoodinate: CLLocationCoordinate2D? = CLLocationCoordinate2D(latitude: self.oldCordinates["lattitude"] ?? 0.0 , longitude: self.oldCordinates["longitude"] ?? 0.0)
let newCoodinate: CLLocationCoordinate2D? = CLLocationCoordinate2D(latitude: self.newCordinates["lattitude"] ?? 0.0 , longitude: self.newCordinates["longitude"] ?? 0.0)
print("oldCordinatesNewWala",oldCoodinate as Any)
print("newCordinatesNewWala",newCoodinate as Any)
driverMarker.icon = UIImage(named: "car")
mapView.camera = GMSCameraPosition.camera(withTarget: newCoodinate!, zoom: 17)
driverMarker.groundAnchor = CGPoint(x: CGFloat(0.5), y: CGFloat(0.5))
driverMarker.position = oldCoodinate ?? CLLocationCoordinate2D(latitude: 0.0,longitude: 0.0)
//this can be old position to make car movement to new position
driverMarker.map = mapView
//marker movement animation
CATransaction.begin()
CATransaction.setValue(Int(2.0), forKey: kCATransactionAnimationDuration)
CATransaction.setCompletionBlock({() -> Void in
self.driverMarker.groundAnchor = CGPoint(x: CGFloat(0.5), y: CGFloat(0.5))
//New bearing value from backend after car movement is done
})
driverMarker.position = newCoodinate ?? CLLocationCoordinate2D(latitude: 0.0,longitude: 0.0)
//this can be new position after car moved from old position to new position with animation
driverMarker.map = mapView
driverMarker.groundAnchor = CGPoint(x: CGFloat(0.5), y: CGFloat(0.5))
//found bearing value by calculation
CATransaction.commit()
}
I am new to using firebase, I am trying to fetch data from firebase.
I get the latitude and longitudes of driver from firebase and append them in latitude array and longitude array and then create the polyline on google map.
When I run the code on simulator UI freezes, zoom in and zoom out takes time, but on real device, iPhone 4s, map does not open.
My database Structure:
func API()
{
let rootReference = FIRDatabase.database().reference()
let DriverId = String(Driver_id)
print("DriverId = \(DriverId)")
let currentDatePath = rootReference.child("gogoapp_driver/\(DriverId)/\(dateFormatForDriverLocation!)")
currentDatePath.observeEventType(.Value, withBlock: { snapshot in
for item in snapshot.children {
let child = item as! FIRDataSnapshot
let latitude = child.value!["latitude"] as! String
let latitudeValue = Double(latitude)
self.latitudeArray.append(latitudeValue!)
let longitude = child.value!["longitude"] as! String
let longitudeValue = Double(longitude)
self.longitudeArray.append(longitudeValue!)
}
self.createPolyline()
})
}
func createPolyline()
{
if latitudeArray.count > 0
{
let lastLat = latitudeArray.last
let lastLong = longitudeArray.last
let coordinatesForCamera : CLLocation = CLLocation(latitude: lastLat!, longitude: lastLong!)
let camera = GMSCameraPosition.cameraWithLatitude(lastLat!, longitude: lastLong!, zoom: 12)
self.googleMapsView.camera = camera
let path = GMSMutablePath()
var line = GMSPolyline()
for( var i = 0; i < latitudeArray.count; i++)
{
let currentLocation : CLLocation = CLLocation(latitude: latitudeArray[i], longitude: longitudeArray[i])
let longitude :CLLocationDegrees = longitudeArray[i]
let latitude :CLLocationDegrees = latitudeArray[i]
let c1 = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
path.addCoordinate(c1)
line = GMSPolyline(path: path)
line.strokeWidth = 5.0
line.map = googleMapsView
marker.position = c1
marker.map = googleMapsView
marker.title = "\(ChildName)"
}
line = GMSPolyline(path: path)
line.strokeWidth = 5.0
line.map = googleMapsView
}
}
I use MapBox api swift 2.3 and reading geojson. But after swift 3 dont work began to upgrade.
Swift 2.3 examples; its work
for location in locations {
nate2D(latitude: location[1].doubleValue, longitude: location[0].doubleValue)
coordinates.append(coordinate)
}
Swift 3.0 dont work
if let feature = feature as? NSDictionary {
if let geometry = feature["geometry"] as? NSDictionary {
if geometry["type"] as? String == "Polygon" {
var coordinates: [CLLocationCoordinate2D] = []
if let locations = geometry["coordinates"] as? NSArray {
for location in locations {
for i in (0 ..< (location as AnyObject).count)
{
let coordinate = CLLocationCoordinate2D(latitude: ???, longitude: ???)
coordinates.append(coordinate)
}
}
}
let shape = MGLPolygon(coordinates: &coordinates, count: UInt(coordinates.count))
DispatchQueue.main.async(execute: {
[unowned self] in
self.mapView.addAnnotation(shape)
})
}
}
}
enter image description here
It ' s correct answer
for location in locations {
for i in (0 ..< (location as AnyObject).count)
{
let a = locations[0] as? NSArray
let b = a?[i] as? NSArray
var c = b?[0]
print(c);
let coordinate = CLLocationCoordinate2D(latitude: b?[1] as! CLLocationDegrees, longitude: b?[0] as! CLLocationDegrees)
coordinates.append(coordinate)
}
}