Polyline starts disappearing after zoom out - ios

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

Related

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)
}`

Move Multiple marker with their live location at my end

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()
}

Removing Polyline for Google Map

I want to remove d polyline in google map , but it remain I have try everything as you can see from the code also I check the debug area and the rectangle.map is nil?? but it still appear on the map and I do not want to user the clear method is work correct but I have other element on the map that I dint want to remove
DispatchQueue.main.async {
let path = GMSMutablePath()
path.add(CLLocationCoordinate2D(latitude: 37.36, longitude: -122.0))
path.add(CLLocationCoordinate2D(latitude: 37.45, longitude: -122.0))
path.add(CLLocationCoordinate2D(latitude: 37.45, longitude: -122.2))
path.add(CLLocationCoordinate2D(latitude: 37.36, longitude: -122.2))
path.add(CLLocationCoordinate2D(latitude: 37.36, longitude: -122.0))
let rectangle = GMSPolyline(path: path)
var oldPolylineArr = [GMSPolyline]()
oldPolylineArr.append(rectangle)
if self.count == 0 {
rectangle.map = self.googelMap
print("count \(self.count)")
self.count = 1
}
else if self.count == 1 {
//rectangle.map = nil
//path.removeAllCoordinates()
self.count = 0
for p in (0 ..< oldPolylineArr.count) {
oldPolylineArr[p].map = nil
}
}
}
}
This is local variable ( Inside the function )
var oldPolylineArr = [GMSPolyline]()
oldPolylineArr.append(rectangle)
you need to make it an instance var , as it holds the last one , so get this line out
var oldPolylineArr = [GMSPolyline]()
Then to clear all do
oldPolylineArr.forEach { $0.map = nil }
after that set your new created polyline
rectangle.map = self.googelMap
This will add a polyline and remove the old
class ViewController:UIViewController {
var oldPolylineArr = [GMSPolyline]()
override func viewDidLoad() {
super.viewDidLoad()
}
func addPolyAndRemoveOld() {
DispatchQueue.main.async {
// remove here
oldPolylineArr.forEach { $0.map = nil }
// add new
let path = GMSMutablePath()
path.add(CLLocationCoordinate2D(latitude: 37.36, longitude: -122.0))
path.add(CLLocationCoordinate2D(latitude: 37.45, longitude: -122.0))
path.add(CLLocationCoordinate2D(latitude: 37.45, longitude: -122.2))
path.add(CLLocationCoordinate2D(latitude: 37.36, longitude: -122.2))
path.add(CLLocationCoordinate2D(latitude: 37.36, longitude: -122.0))
let rectangle = GMSPolyline(path: path)
oldPolylineArr.append(rectangle)
rectangle.map = self.googelMap
}
}
}

Fetching data using firebase but UI freezes on simulator

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
}
}

GoogleMaps : How to draw dash line to connect with starting point of direction path on google map ios

I am using google map in the my project for direction & show route. I had done all things but I am not able to draw the dash line to connect with starting point of route from my location or building.
See my app screenshot screenshot 1
Now I want to draw dash line like google-maps screenshot 2
Any advice and suggestions will be greatly appreciated
For add dash line to connect with starting & end point you have to do little more stuffs in direction path json response, I have drawn straight dash polyline somewhere, if you got code related curved line then update your answer also,
Russell suggested link will little helpful to you,
Drawing Route Between Two Places on GMSMapView in iOS
You have to do following stuffs,
func drawRoute(coordinate: CLLocationCoordinate2D) {
// let directionURL = "https://maps.googleapis.com/maps/api/directions/json?" +
// "origin=\(19.0760),\(72.8777)&destination=\(18.520),\(72.9781)&" +
// "key=AIzaSyBdzgSm8g6w3daxTQvtlG9pqBxrj3lkaN0"
//
var directionURL = "https://maps.googleapis.com/maps/api/directions/json?origin=\(coordinate.latitude),\(coordinate.longitude)&destination=\(18.5767),\(73.6881)&key=AIzaSyARoB09HGFjDy3IKfLpZq-ZQd3YwUT-3_E"
//AIzaSyDxSgGQX6jrn4iq6dyIWAKEOTneZ3Z8PtU
directionURL += "&mode=" + "walking"
print("drawRoute")
Alamofire.request(directionURL).responseJSON
{ response in
if let JSON = response.result.value {
let mapResponse: [String: AnyObject] = JSON as! [String : AnyObject]
let routesArray = (mapResponse["routes"] as? Array) ?? []
let routes = (routesArray.first as? Dictionary<String, AnyObject>) ?? [:]
//print("routes : \(routes)")
//--------Dash line lat-long for starting point ----------\\
let dictArray = (routes["legs"] as? Array) ?? []
let dict = (dictArray.first as? Dictionary<String, AnyObject>) ?? [:]
let steps = (dict["steps"] as? Array) ?? []
let stepsDict = (steps.first as? Dictionary<String, AnyObject>) ?? [:]
let startLocation = stepsDict["start_location"]
let lat = startLocation!["lat"] as! NSNumber
let lng = startLocation!["lng"] as! NSNumber
print("lat : \(lat) lng : \(lng)")
let dotCoordinate = CLLocationCoordinate2D(latitude: CLLocationDegrees(lat), longitude: CLLocationDegrees(lng))
//--------Route polypoints----------\\
let overviewPolyline = (routes["overview_polyline"] as? Dictionary<String,AnyObject>) ?? [:]
let polypoints = (overviewPolyline["points"] as? String) ?? ""
let line = polypoints
self.addPolyLine(encodedString: line, coordinate:coordinate , dotCoordinate:dotCoordinate)
}
}
}
Now draw route polyline & dash line like following way,
func addPolyLine(encodedString: String, coordinate: CLLocationCoordinate2D ,dotCoordinate : CLLocationCoordinate2D) {
//--------Dash line to connect starting point---------\\
let dotPath :GMSMutablePath = GMSMutablePath()
// add coordinate to your path
dotPath.add(CLLocationCoordinate2DMake(coordinate.latitude, coordinate.longitude))
dotPath.add(CLLocationCoordinate2DMake(dotCoordinate.latitude, dotCoordinate.longitude))
let dottedPolyline = GMSPolyline(path: dotPath)
dottedPolyline?.map = self.viewMap
dottedPolyline?.strokeWidth = 3.0
let styles: [Any] = [GMSStrokeStyle.solidColor(UIColor.green), GMSStrokeStyle.solidColor(UIColor.clear)]
let lengths: [Any] = [10, 5]
dottedPolyline?.spans = GMSStyleSpans(dottedPolyline?.path!, styles as! [GMSStrokeStyle], lengths as! [NSNumber], kGMSLengthRhumb)
//---------Route Polyline---------\\
let path = GMSMutablePath(fromEncodedPath: encodedString)
let polyline = GMSPolyline(path: path)
polyline?.strokeWidth = 5
polyline?.strokeColor = .blue
polyline?.map = self.viewMap
}
See output:
create a MKPolyLine like this
var pointsToUse: [CLLocationCoordinate2D] = []
pointsToUse += [CLLocationCoordinate2DMake(55.4, -3.2)] // current location
pointsToUse += [CLLocationCoordinate2DMake(55.6, -3.4)] // lat lon of starting point
let polyline = MKPolyline(coordinates: &pointsToUse, count: pointsToUse.count)
mapView.add(polyline, level: MKOverlayLevel.aboveRoads)
and then update the MapView renderer like this
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer
{
if (overlay is MKPolyline)
{
let pr = MKPolylineRenderer(overlay: overlay)
pr.strokeColor = UIColor.blue.withAlphaComponent(0.5)
pr.lineWidth = 2
pr.lineDashPattern = [10, 10]
return pr
}
}

Resources