self.view
as GMSMapView
in viewDidLload
This is clustering approach I am using
//method to detect when user scrolls map
@objc(mapView:didChangeCameraPosition:) func mapView(_: GMSMapView, didChange _: GMSCameraPosition) {
self.counter = self.counter + 1
self.requestForMap(counter: self.counter)
}
//if user did nothing for 0.2 seconds request data from server
fileprivate func requestForMap(counter: Int) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { [weak self] in
guard let `self` = self else {
return
}
if counter == self.counter {
self.sessionManager.session.invalidateAndCancel()
self.requestData()
}
}
}
to get pins in area I do this on client
// get coordinates of visible area
extension GMSMapView {
func boundings() -> [String: Any] {
let screenBounds = UIScreen.main.bounds
let topPoint = CGPoint(x: 15, y: 60)
let bottomPoint = CGPoint(x: screenBounds.width - 15, y: screenBounds.height)
let shoudBeFull = self.camera.zoom > 15 //if user is zoomed in a lot request all data in area
let bouding = [
"top": [
"lat": self.projection.coordinate(for: topPoint).latitude,
"lon": self.projection.coordinate(for: topPoint).longitude,
],
"bottom": [
"lat": self.projection.coordinate(for: bottomPoint).latitude,
"lon": self.projection.coordinate(for: bottomPoint).longitude,
],
"full": shoudBeFull,
] as [String: Any]
return bouding
}
}
then this data as JSON
is passed to the server and the server gets pins' data for objects, coordinates of which are inside this bounding. We are using node.js, not sure how it works there.
Then I have an array of currently displayed pins like var pins = [GMSMarker]
, after I get an array of objects from server I go through this array, remove those, which are not in new data and add those, which are new