0

I'm sharing and retrieving coordinates with Firebase, but when I print them in my console..I get same coordinates 3-4 time. Which creates an odd effect on my custom marker image file. How can I get the coordinates from Firebase only once?

Here is my code:

var posts=[postStruct]()
var mapView : GMSMapView? = nil
var friendLocator : [Locator] = [Locator]() 

struct Locator {
    let name: String
    let long: CLLocationDegrees
    let lat: CLLocationDegrees
}

var latPass: Double!
var longPass: Double!
var fetchLat: Double!
var fetchLong: Double!

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
    var location=locations[0]
    let span:MKCoordinateSpan=MKCoordinateSpanMake(0.01, 0.01)
    var myLocation:CLLocationCoordinate2D=CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
    let region:MKCoordinateRegion=MKCoordinateRegionMake(myLocation, span)
    latPass=28.3217378
    longPass=75.6895935

    post()
    self.configureMapView()

    let dataBaseRef=FIRDatabase.database().reference()
    dataBaseRef.child("Raunak Trikha").queryOrderedByKey().observeSingleEvent(of: .childAdded, with: {(snapshot) in

        let postDict = snapshot.value as? [String : AnyObject] ?? [:]
        var fetchLat = postDict["lat"] as! Double
        var fetchLong = postDict["long"] as! Double

        let locator = Locator(name: "Raunak Trikha", long: fetchLong, lat: fetchLat)
        self.friendLocator.append(locator)
        self.locateFriend()
        print(fetchLat)
        print(fetchLong)
    })       
    manager.stopUpdatingLocation()

    self.view = mapView

}

func locateFriend() {
    for friend in friendLocator{
        let friendMarker = GMSMarker()
        friendMarker.position=CLLocationCoordinate2D(latitude: friend.lat, longitude: friend.long)
        friendMarker.title=friend.name
        friendMarker.map=mapView
        mapView?.selectedMarker=friendMarker
        if friend.name=="Virat Singh"{

            friendMarker.icon=UIImage(named: "ViratPin.png")
        }

        else if friend.name=="Raunak Trikha"{

            friendMarker.icon=UIImage(named: "currentLocation.png")
        }
    }
    do {
        mapView?.mapStyle = try GMSMapStyle(jsonString: kMapStyle)
    } catch {
        NSLog("One or more of the map styles failed to load. \(error)")
    }
}


func configureMapView(){
    let camera = GMSCameraPosition.camera(withLatitude: latPass, longitude: longPass, zoom: 10)
    self.mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
    view = mapView
    mapView?.settings.scrollGestures = true
    mapView?.settings.zoomGestures = true
    mapView?.settings.myLocationButton = true
    //mapView?.addSubview(searchBar)
    //mapView?.addSubview(searchSupporter)
    //mapView?.bringSubview(toFront: searchBar)

    for gesture in (mapView?.gestureRecognizers!)! {

        mapView?.removeGestureRecognizer(gesture)

    }

}

when I print fetchLat & fetchLong I get the same coordinates 4 time, which overlaps my custom marker image that creates the weird effect.

2 Answers2

1

Since your code that adds a particular Locator struct is called multiple times, check your array to make sure it doesn't already contain the exact same struct before adding it to the array locally.

This will evaluate your array of structs and determine if there is no value for it. But it also assumes that name property of the struct is a unique identifier for each struct, which may not be your case. You can alternatively compare any value within the filter closure that you want to make sure isn't duplictated, i. e. lat and long.

    let locator = Locator(name: "Raunak Trikha", long: fetchLong, lat: fetchLat)
    if self.friendLocator.filter({ $0.name == locator.name }).count == 0 {
       self.friendLocator.append(locator)  
    }
    self.locateFriend()
NSGangster
  • 2,397
  • 12
  • 22
0

This function func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) will get called whenever your location changes/updates or until the GPS settles (Warms up) on your location.

I notice you are using the firebase single event obeserver function for database updates using .observeSingleEvent() which is correct however since you have defined the call in the above didUpdateLocations function it will be called multiple times.

Either move the call to Firebase out of the function or supply some conditional to call firebase only once. I.e only update if the location has changed more than X range/distance etc.

Alex McPherson
  • 3,185
  • 3
  • 30
  • 41
  • Move this function dataBaseRef.child("Raunak Trikha").queryOrderedByKey().observeSingleEvent(of: .childAdded, with: {(snapshot) out of the didUpdateLocations. If you need the last reported lat and lng store it in a var you can retrieve and initialise your locator struct also outiside of the didUpdateLocaitons function. – Alex McPherson Sep 18 '17 at 14:26
  • I'm sorry I'm new to maps and Location, can you explain it with code ? Thanks – Naveen Saini Sep 18 '17 at 14:29
  • https://developer.apple.com/documentation/corelocation/cllocationmanagerdelegate/1423615-locationmanager – Alex McPherson Sep 18 '17 at 14:35
  • This may help you. https://stackoverflow.com/questions/22292835/how-to-stop-multiple-times-method-calling-of-didupdatelocations-in-ios although its OBJ-C however you should get the idea of setting a flag or setting a distance filter etc. – Alex McPherson Sep 18 '17 at 14:47