Redis GEO ,GEOHASH,Spatial_index
https://matt.sh/redis-geo
http://antirez.com/latest/0
http://invece.org/
https://github.com/davidmoten/geo/blob/master/src/main/java/com/github/davidmoten/geo/GeoHash.java
http://www.movable-type.co.uk/scripts/latlong-db.html
http://www.basistech.com/wp-content/uploads/2014/06/oss-2011-smiley-geospatial-search.pdf
https://github.com/mattsta/geohash-int/commits/matt
https://dzone.com/articles/designing-spacial-index#footnote-6-ref
http://www.ibm.com/developerworks/library/j-spatial/
https://en.wikipedia.org/wiki/Angular_diameter
https://en.wikipedia.org/wiki/Angular_displacement
https://github.com/yinqiwen/ardb/blob/d42503/src/geo/geohash_helper.cpp
https://github.com/yinqiwen/ardb/wiki/Spatial-Index
https://github.com/yinqiwen/geohash-int
https://en.wikipedia.org/wiki/Geohash
https://en.wikipedia.org/wiki/Z-order_curve
https://en.wikipedia.org/wiki/Geohash
https://matt.sh/redis-architecture-diagram
https://matt.sh/redis-geo#_origin-story
https://github.com/antirez/redis/blob/356a6304ec77783e7fdaf00668a09dc293b810a0/src/geo.c
http://cristian.regolo.cc/2015/07/07/introducing-the-geo-api-in-redis.html
http://redisplanet.com/redis/under-the-hood-of-redis-hash-part-2-and-list/
http://redisplanet.com/redis/under-the-hood-of-redis-hash-part-1/
http://www.basistech.com/wp-content/uploads/2014/06/oss-2011-smiley-geospatial-search.pdf
https://dzone.com/articles/designing-spacial-index
http://iamzhongyong.iteye.com/blog/1399333
http://tech.idv2.com/2011/06/17/location-search/
http://blog.sina.com.cn/s/blog_62ba0fdd0100tul4.html
https://github.com/kungfoo/geohash-java
http://101.96.10.62/geomesa.github.io/assets/outreach/SpatioTemporalIndexing_IEEEcopyright.pdf
https://www.elastic.co/guide/en/elasticsearch/reference/current/geo-shape.html
https://docs.mongodb.com/manual/core/geospatial-indexes/
https://en.wikipedia.org/wiki/Spatial_database#Spatial_index
https://en.wikipedia.org/wiki/Geographic_coordinate_system
https://en.wikipedia.org/wiki/Haversine_formula
http://geohash.org/site/tips.html
http://101.96.10.63/www.comp.nus.edu.sg/~ooibc/spatialsurvey.pdf
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.140.7080&rep=rep1&type=pdf
http://101.96.10.61/people.cs.vt.edu/~asandu/Public/Qual2005/Q2005_skjellum.pdf
http://gis.stackexchange.com/questions/108557/advantages-of-r-trees-in-comparison-to-geohashes?rq=1
http://www.movable-type.co.uk/scripts/latlong.html
https://en.wikipedia.org/wiki/Great-circle_distance
https://en.wikipedia.org/wiki/Haversine_formula
https://en.wikipedia.org/wiki/Angular_displacement
http://www.mathsisfun.com/algebra/trig-inverse-sin-cos-tan.html
http://math.rice.edu/~pcmi/sphere/drg_txt.html
http://stackoverflow.com/questions/18324524/what-are-some-efficient-geohash-bounding-box-coverage-algorithms
https://en.wikipedia.org/wiki/Image_resolution
======================================================================
Absolutely you can. And it can be quite fast. (EDIT: The intensive computation bits can ALSO be distributed)
There are several ways, but one way that I've been working with is in using an ordered list of integer-based geohashes, and finding all the nearest neighbour geohash ranges for a specific geohash resolution (the resolution approximates your distance
criteria), and then querying those geohash ranges to get a list of nearby points. I use redis and nodejs (ie. javascript) for this. Redis is super fast and can retrieve ordered ranges very quickly, but it can't do a lot of the indexing query manipulation stuff that SQL databases can do.
The method is outlined here: https://github.com/yinqiwen/ardb/blob/master/doc/spatial-index.md
But the gist of it is (to paraphrase the link):
- You store all your geohashed points in the best resolution you want (max usually 64bit integer if that's accessible, or in the case of javascript, 52bits) in an ordered set (ie. zset in redis). Most geohash libraries these days have geohash integer functions built in, and you'll need to use these instead of the more common base32 geohashes.
- Based on the radius you want to search within, you need to then find a bit depth/resolution that will match your search area and this must be less than or equal to your stored geohash bit depth. The linked site has a table that correlates the bit depth of a geohash to its bounding box area in meters.
- Then you rehash your original coordinate at this lower resolution.
- At that lower resolution also find the 8 neighbour (n, ne, e, se, s, sw, w, nw) geohash areas. The reason why you have to do the neighbour method, is because two coordinates nearly right beside each other could have completely different geohashes, so you need to do some averaging of the area covered by the search.
- Once you get all the neighbour geohashes at this lower resolution, add to the list your coordinate's geohash from step 3.
- Then you need to build a range of geohash values to search within which cover these 9 areas. The values from step 5 are your lower range limit, and if you add 1 to each of them, you'll get your upper range limit. So you should have an array of 9 ranges, each with a lower limit and and upper geohash limit (18 geohashes in total). These geohashes are still in that lower resolution from step 2.
- Then you convert all 18 of these geohashes to whatever bit depth/resolution you have stored all your geohashes in your database in. Generally you do this by bitshifting it to the desired bit depth.
- Now you can do a range query for points within these 9 ranges and you'll get all points approximately within the distance of your original point. There will be no overlap so you don't need to do any intersections, just pure range queries, very fast. (ie. in redis: ZRANGEBYSCORE zsetname lowerLimit upperLimit, over the 9 ranges produced in this step)
You can further optimize (speed wise) this by:
- Taking those 9 ranges from step 6 and finding where they lead into each other. Usually you can reduce 9 separate ranges into about 4 or 5 depending on where your coordinate is. This can reduce your query time by half.
- Once you have your final ranges, you should hold them for reuse. The calculation of these ranges can take most of the processing time, so if your original coordinate doesn't change much but you need to make the same distance query over again, you should keep that ready instead of calculating it everytime.
- If you're using redis, try to combine the queries into a MULTI/EXEC so it pipelines them for a bit better performance.
- The BEST part: You can distribute steps 2-7 on clients instead of having that computation done all in one place. This greatly reduces CPU load in situations where millions of requests would be coming in.
You can further improve accuracy by using a circle distance/haversine type function on the returned results if you care much about precision.
Here's a similar technique using ordinary base32 geohashes and a SQL query instead of redis: https://github.com/davetroy/geohash-js
I don't mean to plug my own thing, but I've written a module for nodejs&redis that makes this really easy to implement. Have a look at the code if you'd like: https://github.com/arjunmehta/node-geo-proximity
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库