开发者

Geohashing - recursively find neighbors of neighbors

开发者 https://www.devze.com 2023-01-03 05:53 出处:网络
I am now looking for an elegant algorithm to recursively find neighbors of neighbors with the geohashing algorithm (http://www.geohash.org).

I am now looking for an elegant algorithm to recursively find neighbors of neighbors with the geohashing algorithm (http://www.geohash.org).

Basically take a central geohash, and then get the first 'ring' of same-size hashes around it (8 elements), then, in the next step, get the next ring around the first etc. etc. Have you heard of an elegant way to do so?

Brute force could be to take each neighbor and get their neighbors simply ignoring the massive overlap. Neighbors around one central geohash has been solved many times (here e.g. in Ruby: http://github.com/masuidrive/pr_geohash/blob/master/lib/pr_geohash.rb)

Edit for clarification: Current solution, with 开发者_C百科passing in a center key and a direction, like this (with corresponding lookup-tables):

  def adjacent(geohash, dir)
    base, lastChr = geohash[0..-2], geohash[-1,1]
    type = (geohash.length % 2)==1 ? :odd : :even
    if BORDERS[dir][type].include?(lastChr)
      base = adjacent(base, dir)
    end
    base + BASE32[NEIGHBORS[dir][type].index(lastChr),1]
  end

(extract from Yuichiro MASUI's lib)

I say this approach will get ugly soon, because directions gets ugly once we are in ring two or three. The algorithm would ideally simply take two parameters, the center area and the distance from 0 being the center geohash only (["u0m"] and 1 being the first ring made of 8 geohashes of the same size around it (=> [["u0t", "u0w"], ["u0q", "u0n"], ["u0j", "u0h"], ["u0k", "u0s"]]). two being the second ring with 16 areas around the first ring etc.

Do you see any way to deduce the 'rings' from the bits in an elegant way?


That depends on what you mean by Neighbor. I'm assuming this is being used in the context of a proximity search. In that case I would think that your best bet would be to search from the outermost ring inward.

Assume you can find the outermost set (longest proximity) in the searchable Universe. Store that as the new Universe and then find the next inner set in that Universe. This search should subtract that inner set from the Universe. Store the old Universe (the outermost ring) and repeat this process until you hit the center. Each search after the first one will reduce your search area and give you a ring.


Start by constructing the sides immediately around the central geohash i.e. top, right, bottom and left, initially each of these will only comprise a single geohash and a corner. Then recursively iterate the sides using the adjacent function with direction as corresponds that side (i.e. expand left for the left side) whilst maintaining an appropriate result set and the sides for the next iteration. You also need to handle the diagonal/corner geohash for each side (e.g. left-top for left, top-right for top, if using a clockwise association). For an example of the procedure see this implementation I did in Lua or Javascript (but with additional functionality), which start with a call to Grid().

0

精彩评论

暂无评论...
验证码 换一张
取 消