Получение соседей с помощью алгоритма геохеширования?

Я смотрю на питоническую реализацию этого принятого ответа с самым высоким рейтингом в GIS SE - Используете геохеш для поиска по близости? и я не могу получить совпадения для моего запроса геохеш. Вот подход, который я пробовал до сих пор.

Чтобы запустить этот минимальный проверяемый полный пример (MVCE), вам необходимо загрузить следующие файлы: geohash int и sortedlist python и установите отсортированный список python через pip. Вам также необходимо установить последнюю версию Cython на свой компьютер, чтобы обернуть функциональность C для geohash-int (обратите внимание, что я обертываю только то, что необходимо для этого MVCE).

geohash_test.py

# GeoHash is my Cython wrapper of geohash-int C package
from geo import GeoHash
from sortedcontainers import SortedList

import numpy as np

def main():
    # Bounding coordinates of my grid.
    minLat = 27.401436
    maxLat = 62.54858
    minLo = -180.0
    maxLo = 179.95000000000002
    latGrid = np.arange(minLat,maxLat,0.05)
    lonGrid = np.arange(minLo,maxLo,0.05)
    geoHash = GeoHash()

    # Create my own data set of points with a resolution of
    # 0.05 in the latitude and longitude direction. 
    gridLon,gridLat = np.meshgrid(lonGrid,latGrid)
    grid_points = np.c_[gridLon.ravel(),gridLat.ravel()]

    sl = SortedList()

   #Store my grid points in the best resolution possible i.e. 52(First step in accepted answer)
   for grid_point in grid_points:
      lon = grid_point[0]
      lat = grid_point[1]
      geohash = geoHash.encode(lat,lon,52)
      bitsOriginal = geohash["bits"]
      sl.add(bitsOriginal)
      #Derive the minimum and maximum value for the range query from method below
   minValue,maxValue = getMinMaxForQueryGeoHash(geoHash)
   # Do the actual range query with a sorted list
   it = sl.irange(minValue,maxValue,inclusive=(False,False))
   print(len(list(it)))

def getMinMaxForQueryGeoHash(geoHash):
    lonTest = 172.76843
    latTest = 61.560745

    #Query geohash encoded at resolution 26 because my search area
    # is around 10 kms.(Step 2 and 3 in accepted answer)

    queryGeoHash = geoHash.encode(latTest,lonTest,26)

    # Step 4 is getting the neighbors for query geohash

    neighbors = geoHash.get_neighbors(queryGeoHash)
    bitsList = []
    for key,value in neighbors.items():
       bitsList.append(value["bits"])

    #Step 5 from accepted answer
    bitsList.append(queryGeoHash["bits"])

   # Step 6 We need 1 to all the neighbors 
   newList = [x+1 for x in bitsList]
   joinedList = bitsList + newList

    #Step 7 Left bit shift this to 52 
    newList2 = [x <<26 for x in joinedList]
    #Return min and max value to main method
    minValue = min(newList2)
    maxValue = max(newList2)
    return minValue,maxValue

 main()

Если бы кто-то написал это как псевдокод, вот что я делаю

  1. Учитывая мою ограничивающую рамку, которая представляет собой сетку, я сохраняю ее в максимально возможном разрешении, вычисляя геохеш для каждой широты и долготы (это происходит с глубиной 52 бита)

  2. Я добавляю геохэш в отсортированный список

  3. Затем я хотел бы выполнить запрос диапазона, указав радиус поиска 10 км для конкретной координаты запроса.

  4. Из принятого ответа для этого вам нужно минимальное и максимальное значение для геохэша запроса.

  5. Я вычисляю минимальное и максимальное значение в методе getMinMaxForQueryGeoHash

  6. Вычислите геохэш запроса на битовой глубине 26 (это радиус 10 км)

  7. Вычислите соседей геохеша запроса и создайте массив из 18 элементов.

  8. 18 элементов — это 8 соседей, возвращенных методом C, плюс исходный геохэш запроса, а остальные 9 получены путем добавления 1 к этому массиву.

  9. Затем сдвиньте этот массив влево на 26 и верните минимальное и максимальное значение в запрос irange отсортированного списка.

    Битовый сдвиг = 52 (максимальное разрешение) - точность геохэша запроса (26) = 26

Но этот запрос возвращает мне NULL. Может кто-нибудь объяснить, где я ошибаюсь?


person gansub    schedule 27.08.2019    source источник


Ответы (1)


используя ваш жаргон: для MVCE вам не нужны сложные реализации на двух языках. Существует множество простых хороших реализаций Geohash, некоторые на 100% Python (пример ). Все они используют Кривую Мортона (пример).

Вывод: попробуйте подключить и запустить реализацию на чистом Python, сначала протестировать кодирование/декодирование, затем протестировать использование функции neighbors(geohash).

person Peter Krauss    schedule 17.09.2019
comment
Спасибо за Ваш ответ. Я пытаюсь использовать геохэш, чтобы сделать то, что я называю приблизительным поиском ближайшего соседа без расчета расстояний (что в моем текущем коде очень дорого). Я бы удовлетворился приблизительными совпадениями. Отсюда необходимость в запросе диапазона. - person gansub; 17.09.2019
comment
neighbors(geohash), который я процитировал, и здесь, в приведенный пример... Но он топологический, для преобразования в вычисление расстояний вы должны оценивать по ширине ячейки или центроидам ячеек... LatLong не является метрической системой, см. более быстрые средства оценки расстояний, такие как Turf или любая географическая библиотека Python. Если требуется расстояние более 1 ячейки, необходимо использовать итерации, поэтому он неэффективен для поиска ближайшего соседа более чем на 1 или 2 ячейки (вы не точны в отношении фокуса). - person Peter Krauss; 17.09.2019
comment
Теперь я начинаю понимать это (я думаю). Вы говорите, что мою широтно-длинную сетку нельзя использовать для выполнения запросов диапазона с использованием геохэша. Но если данные являются топологическими, такими как сфера или эллипсоид, эти точки можно проиндексировать с помощью геохэша, а затем мы можем выполнять запросы диапазона. Я прав ? - person gansub; 17.09.2019
comment
Топология в данном случае связана с топологией ячеек сетки и выбором 4-connected or 8-connected... Ну, вы также можете перемотать все назад и проверить общую картину вашей реальной проблемы. Сегодня (2019 г.) для этого есть другие более быстрые индексы, лучшим, на мой взгляд, является H3 Uber, на основе шестиугольной сетки. - person Peter Krauss; 17.09.2019