I'm super excited about the new geo query feature available in Firebase. I'm trying out the 'GeoFire/Utils' pod recently made available. I set up a test iOS app and here is the repo . I left the rules open if anyone wants to clone and try. My Firestore document looks like this.
date : January 29, 2021 at 1:29:00 PM UTC-8
geohash:"9mupwu3mkc"
id:"13101C7F-D7FF-4141-BC5A-76602173C096"
lat:33.6863622
lng:-117.8264411
ownerAddress:"1 Civic Center Plaza, Irvine CA 92606"
I am using the samplecode from firebase. Here is the call to firebase
func getallDocs(radius: Double) {
// Find pickups within 50km of Basecamp
let center = CLLocationCoordinate2D(latitude: 33.9742268, longitude: -118.3947792)
let radiusInKilometers: Double = radius
// Each item in 'bounds' represents a startAt/endAt pair. We have to issue
// a separate query for each pair. There can be up to 9 pairs of bounds
// depending on overlap, but in most cases there are 4.
let queryBounds = GFUtils.queryBounds(forLocation: center,
withRadius: radiusInKilometers)
let queries = queryBounds.compactMap { (any) -> Query? in
guard let bound = any as? GFGeoQueryBounds else { return nil }
return db.collection("pickups")
.order(by: "geohash")
.start(at: [bound.startValue])
.end(at: [bound.endValue])
}
var matchingDocs = [QueryDocumentSnapshot]()
// Collect all the query results together into a single list
func getDocumentsCompletion(snapshot: QuerySnapshot?, error: Error?) -> () {
guard let documents = snapshot?.documents else {
print("Unable to fetch snapshot data. \(String(describing: error))")
return
}
print("\nDocs: Count \(documents.count)")
for document in documents {
let lat = document.data()["lat"] as? Double ?? 0
let lng = document.data()["lng"] as? Double ?? 0
let ownerAddress = document.data()["ownerAddress"] as? String ?? "no address"
let coordinates = CLLocation(latitude: lat, longitude: lng)
let centerPoint = CLLocation(latitude: center.latitude, longitude: center.longitude)
// We have to filter out a few false positives due to GeoHash accuracy, but
// most will match
let distance = GFUtils.distance(from: centerPoint, to: coordinates)
print("ownerAddress: \(ownerAddress), distance: \(distance) \tlat: \(lat), \(lng)")
if distance <= radiusInKilometers {
matchingDocs.append(document)
}
}
}
// After all callbacks have executed, matchingDocs contains the result. Note that this
// sample does not demonstrate how to wait on all callbacks to complete.
for query in queries {
query.getDocuments(completion: getDocumentsCompletion)
}
print("Docs: \(matchingDocs.count)")
}
My distances are way off. Here is an example of my output, the top one is my query center. And with a query radius of 100,000 km I still don't get all of my addresses in California.
Home Base: 7401 Sepluveda, Los Angeles CA 90045, distance: 0.0 lat: 33.9742268, -118.3947792
ownerAddress: 1204 Mira Mar Ave, Long Beach CA 90301, distance: 31295.135631869747 lat: 33.781846, -118.1473443
ownerAddress: 625 Fair Oaks, Pasadena CA 91030, distance: 27608.75410615904 lat: 34.1181627, -118.1510438
My question is why is my distance so much greater than what google maps / reality is?
firebaser here
From our chat in the comments it seems that the withRadius:
value is actually in meters, despite what the documentation says.
This is clearly not working as documented, so I filed a to update the docs. That change is coming in here .
I'm super excited about the new geo query feature available in Firebase. I'm trying out the 'GeoFire/Utils' pod recently made available. I set up a test iOS app and here is the repo . I left the rules open if anyone wants to clone and try. My Firestore document looks like this.
date : January 29, 2021 at 1:29:00 PM UTC-8
geohash:"9mupwu3mkc"
id:"13101C7F-D7FF-4141-BC5A-76602173C096"
lat:33.6863622
lng:-117.8264411
ownerAddress:"1 Civic Center Plaza, Irvine CA 92606"
I am using the samplecode from firebase. Here is the call to firebase
func getallDocs(radius: Double) {
// Find pickups within 50km of Basecamp
let center = CLLocationCoordinate2D(latitude: 33.9742268, longitude: -118.3947792)
let radiusInKilometers: Double = radius
// Each item in 'bounds' represents a startAt/endAt pair. We have to issue
// a separate query for each pair. There can be up to 9 pairs of bounds
// depending on overlap, but in most cases there are 4.
let queryBounds = GFUtils.queryBounds(forLocation: center,
withRadius: radiusInKilometers)
let queries = queryBounds.compactMap { (any) -> Query? in
guard let bound = any as? GFGeoQueryBounds else { return nil }
return db.collection("pickups")
.order(by: "geohash")
.start(at: [bound.startValue])
.end(at: [bound.endValue])
}
var matchingDocs = [QueryDocumentSnapshot]()
// Collect all the query results together into a single list
func getDocumentsCompletion(snapshot: QuerySnapshot?, error: Error?) -> () {
guard let documents = snapshot?.documents else {
print("Unable to fetch snapshot data. \(String(describing: error))")
return
}
print("\nDocs: Count \(documents.count)")
for document in documents {
let lat = document.data()["lat"] as? Double ?? 0
let lng = document.data()["lng"] as? Double ?? 0
let ownerAddress = document.data()["ownerAddress"] as? String ?? "no address"
let coordinates = CLLocation(latitude: lat, longitude: lng)
let centerPoint = CLLocation(latitude: center.latitude, longitude: center.longitude)
// We have to filter out a few false positives due to GeoHash accuracy, but
// most will match
let distance = GFUtils.distance(from: centerPoint, to: coordinates)
print("ownerAddress: \(ownerAddress), distance: \(distance) \tlat: \(lat), \(lng)")
if distance <= radiusInKilometers {
matchingDocs.append(document)
}
}
}
// After all callbacks have executed, matchingDocs contains the result. Note that this
// sample does not demonstrate how to wait on all callbacks to complete.
for query in queries {
query.getDocuments(completion: getDocumentsCompletion)
}
print("Docs: \(matchingDocs.count)")
}
My distances are way off. Here is an example of my output, the top one is my query center. And with a query radius of 100,000 km I still don't get all of my addresses in California.
Home Base: 7401 Sepluveda, Los Angeles CA 90045, distance: 0.0 lat: 33.9742268, -118.3947792
ownerAddress: 1204 Mira Mar Ave, Long Beach CA 90301, distance: 31295.135631869747 lat: 33.781846, -118.1473443
ownerAddress: 625 Fair Oaks, Pasadena CA 91030, distance: 27608.75410615904 lat: 34.1181627, -118.1510438
My question is why is my distance so much greater than what google maps / reality is?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.