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
}
}
Related
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)
}`
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'm trying to retrieve the flight number, latitude & longitude from all Firestore documents and add them as Mapbox annotations to a mapView. So far the code pulls the data from Cloud Firestore and stores them as variables. Aditionally the code displays a Mapbox map with coordinates but they must be assigned manually in the array
Im having trouble with appending the variables from Firestore to the coordinates array.
I found this "Add annotation after retrieving users latitude and longitude from Firebase" which was along the correct lines but its to do with firebase and not firestore.
Any help would be greatly appreciated!
class HomeViewController: UIViewController, MGLMapViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let mapView = MGLMapView(frame: view.bounds)
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mapView.styleURL = MGLStyle.darkStyleURL
mapView.tintColor = .lightGray
mapView.centerCoordinate = CLLocationCoordinate2D(latitude: 0, longitude: 66)
mapView.zoomLevel = 2
mapView.delegate = self
view.addSubview(mapView)
var aircraftArray = [""]
let db = Firestore.firestore()
let AircraftRef = db.collection("LiveAircraftData").getDocuments { (snapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in snapshot!.documents {
let FlightNumber = document.documentID
let latitude = document.get("Latitude") as! Double
let longitude = document.get("Longitude") as! Double
print(FlightNumber, latitude, longitude)
var Coordinates = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
aircraftArray.append(Coordinates)
var pointAnnotations = [MGLPointAnnotation]()
for coordinate in Coordinates {
let point = MGLPointAnnotation()
point.coordinate = coordinate
point.title = "\(coordinate.latitude), \(coordinate.longitude)"
pointAnnotations.append(point)
}
mapView.addAnnotations(pointAnnotations)
}
}
}
}
This is what my database looks like
screenshot of code
I am encountering great difficulties in putting an integrated map based on firebase in my project, I am looking for expert knowledge to help me, even though I build run correctly at the time of running the system for, my code below:
Thanks
#IBOutlet var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
let locationsRef = Database.database().reference(withPath: "locations")
locationsRef.observe(.value, with: { snapshot in
for item in snapshot.children {
guard let locationData = item as? DataSnapshot else { continue }
var locationValue = locationData.value as! [String: Any]
var location: CLLocationCoordinate2D!
if let lat = locationValue["lat"] as? String {
let lng = Double(locationValue["lng"] as! String)!
location = CLLocationCoordinate2D(latitude: Double(lat)!, longitude: lng)
} else {
let lat = locationValue["lat"] as! Double
let lng = locationValue["lng"] as! Double
location = CLLocationCoordinate2D(latitude: lat, longitude: lng)
}
func addAnnotations(coords: [CLLocation]){
for coord in coords{
let CLLCoordType = CLLocationCoordinate2D(latitude: coord.coordinate.latitude,
longitude: coord.coordinate.longitude);
let anno = MKPointAnnotation();
anno.coordinate = CLLCoordType;
self.mapView.addAnnotation(anno);
}
}
}
})
}
I am trying to convert a String that I am retrieving from Firebase and adding it as several annotations on Google Maps. Unfortuanately, my app is crashing whenever it goes through the current code:
ref = FIRDatabase.database().reference()
ref.child("Locations").observeSingleEventOfType(.Value, withBlock: { (snapshot) in
let lat = (snapshot.value!["Latitude"] as! NSString).doubleValue
let lon = (snapshot.value!["Longitude"] as! NSString).doubleValue
let complainLoc = CLLocationCoordinate2DMake(lat, lon)
let Coordinates = CLLocationCoordinate2D(latitude: lat, longitude: lon)
})
My JSON Tree
My Code Block Which Crashes
Here is the code I used for saving data to Firebase
FIRDatabase.database().reference().child("Location").child(FIRAuth.auth()!.currentUser!.uid).setValue(["Latitude": locationManager.location!.coordinate.latitude, "Longitude": locationManager.location!.coordinate.longitude])
SWIFT 5
let dbLat = Double(latStr) // Convert String to double
let dbLong = Double(longStr)
Use latitude and longitude
let center = CLLocationCoordinate2D(latitude: dbLat! , longitude: dbLong! )
let pointAnnotation = MKPointAnnotation()
pointAnnotation.coordinate = CLLocationCoordinate2D(latitude: dbLat!, longitude:dbLong!)
Make sure when you are saving the values of lat and lon to the database you are saving them as Float or Double..
For retrieving use :
ref = FIRDatabase.database().reference()
ref.child("Locations").observeEventType(.Value, withBlock: { (snapshot) in
if snapshot.exists(){
if let locationDictionary = snapshot.value as [String : AnyObject]{
for each in locationDictionary{
//each will bring you every location dictionary in your database for your every user
let lat = each.value!["Latitude"] as! CLLocationDegrees
let lon = each.value!["Longitude"] as! CLLocationDegrees
let userId = each.key as! String
let complainLoc = CLLocationCoordinate2DMake(lat, lon)
let Coordinates = CLLocationCoordinate2D(latitude: lat, longitude: lon)
//Every time this for loop complete's itself it will generate a new set of Coordinates for each user
}
}
}
})
EDIT:
Updated code for Firebase 6 and Swift 5
let ref = self.ref.child("Locations")
ref.observeSingleEvent(of: .value, with: { snapshot in
let allLocations = snapshot.children.allObjects as! [DataSnapshot]
for location in allLocations {
let lat = location.childSnapshot(forPath: "Latitude").value as! CLLocationDegrees
let lon = location.childSnapshot(forPath: "Longitude").value as! CLLocationDegrees
let userId = location.key
let locCoord = CLLocationCoordinate2DMake(lat, lon)
let coordinates = CLLocationCoordinate2D(latitude: lat, longitude: lon)
}
})
note that self.ref points to my Firebase root ref.