anovis / proximity_hash

Proximity Hash generates a set of geohashes that cover a circular area, given the center coordinates and the radius.
https://pub.dev/packages/proximity_hash
Apache License 2.0
5 stars 0 forks source link

what is the best way to get a Geohash of a location? #4

Closed yulkin2002 closed 3 years ago

yulkin2002 commented 3 years ago

I know your package is not meant for this, but I am trying to minimize the number of packages and so trying to squeeze this capability out of your code. I tried calling createGeohashes(43.6500245, -79.5290709, 0.1, 9); this one returns two: [dpz2q60xy, dpz2q60xv], which could actually be correct as this is a multi-unit building, but figured I'd check with you whether this is expected behaviour.

If it is, could you suggest of a better way to get the one geohash of a location?

anovis commented 3 years ago

In order to get a more precise geohash you will need a higher precision. If you use precision 11 such as createGeohashes(43.6500245, -79.5290709, 0.1, 11) you will get a single response of dpz2q60xy66. However higher precisions requires more computations and will slow down your code. This website has some nice visuals for how the precision works in terms of spatial distances.

In terms of this tool being able to solve for your exact problem it depends what you are using the geohashes for. I worked on another project geohashtree, which helps ingest and store lat long coordinates by their geohashes and allows you to use proximity hash on a subset of those.

yulkin2002 commented 3 years ago

@anovis thanks! I do get only one geohash from the website you recommended as well as this other website

also, if I understand geohash concept correctly, higher precision would give me the smaller quadrants within the quadrant with precision of 9, so in your example above the first 9 digits of the precision 11 geohash is dpz2q60xy. if I run createGeohashes(43.6500245, -79.5290709, 0.1, 10), I get [dpz2q60xy6, dpz2q60xy4], where the first 9 digits are also dpz2q60xy

in both scenarios with higher precision the first 9 digits match the first value returned when I use createGeohashes(43.6500245, -79.5290709, 0.1, 9).

Is it really supposed to return a second geohash dpz2q60xv? I tried reducing the radius to 0.000001 but still get two codes back. I understand that it's meant for getting the nearby geohashes, but thought reducing the radius to something minuscule would give me only one result.

What I am trying to do is to generate and save a bunch of geohashes based on street addresses (ideally one per address), so that I can then query them based on user's requested radius. So I am trying to also use createGeohashes() to get the one geohash per address but with lower precision as that should be sufficient for my purposes and to your point - would be a little faster.

I checked out your geohashtree package, but I don't think it has a capability to generate geohashes, does it?

anovis commented 3 years ago

ahh i see your problem. that is my mistake. you will want to use the package dart_geohash which will generate the hash for your address. My package uses this package to generate all hashes in a certain radius to help you search. for example you have two addresses dpz2q60xy6 and dpz2q60xy6 and a user is at 43.6500245, -79.5290709. if you want to find all addresses in a certain radius then createGeohashes will output all geohashes in radius r from that point allowing you to find nerarby addresses.

this is a similar use case that i built out the geohashtree library for. I first input a list of all addresses into the tree iterating through the tree.addLatLng(double lat, double long, V v) which converts the coordinate to a geohash behind the scenes and stores the value v in the tree based on its hash to make queries quicker. then you can search the tree using tree.getGeohashesByProximity() which will return all values in the given proximity. here is the list of api methods. I am happy to add some more examples to the documentation if that makes it clearer.

yulkin2002 commented 3 years ago

ah I see, sounds like I am trying to create a simplified version of a Geohash tree but in firebase and then query it based on user's preferred radius. So hypothetically, I would have a parent with a 5 digit geohash that would then store the children with 8 digit precision and using createGeohashes would identify which geohashes I need to pull.

I did not understand from the documentation that your geohashtree generates geohashes behind the scenes, I'm going to explore it more to see if I can apply it to my use case.

thanks again!

yulkin2002 commented 3 years ago

@anovis would you consider adding a method in this package to create a geohash from coordinates or exposing the GeoHash.fromDecimalDegrees as you mentioned you are leveraging dart_geohash?

it would be super handy :)

P.S. the only use I have for dart_geohash is this capability and if your package provided that then I don't need to use dart_geohash at all. Things tend to get out of control the more packages my code relies on so I try to only use what I must

anovis commented 3 years ago

ah in that case you can use the convertToGeohash method. this takes into consideration the Earths curvature, but you can specify x=0,y=0 and the result will the direct output of geoHasher.encode(lon, lat, precision: precision);

yulkin2002 commented 3 years ago

@anovis this is perfect, thank you so much!