Mam tabelę PostgreSQL 9.1 z setkami tysięcy PUNKTÓW PostGIS. Dla każdego z nich chciałbym znaleźć najbliższy punkt w innej tabeli PUNKTÓW. Punkty w drugiej tabeli reprezentują siatkę na całym świecie, więc wiem, że zawsze będzie dopasowanie w zakresie 1 stopnia. To pytanie, którego używam do tej pory, które korzysta z indeksów GIST, więc jest dość szybkie (łącznie około 30 sekund).
SELECT DISTINCT ON (p.id)
p.id, ST_AsText(p.pos)
, ST_AsText(first_value(g.location) OVER (PARTITION BY p.id ORDER BY ST_Distance(p.pos, g.location::geography)))
FROM point p
JOIN grid g ON ST_DWithin(p.pos::geometry, g.location, 1)
Jedynym problemem jest linia danych. Punkty siatki mają szerokość 180, a nie -180. W przypadku korzystania z wersji geometrii ST_Distance nie zwraca punktów po drugiej stronie linii danych. Na przykład. jeśli p.pos jest POINT(-179.88056 -16.68833)
najbliższym punktem siatki POINT(180 -16.25)
, ale powyższe zapytanie go nie zwraca. Jak najlepiej to naprawić?
Tak naprawdę nie chcę mieć dwóch współrzędnych dla jednego punktu siatki (-180 i +180). Próbowałem dodać własną funkcję, która sprawdza ten konkretny przypadek, ale wtedy zapytanie nie zwraca się w ciągu 5 minut, prawdopodobnie dlatego, że nie może już korzystać z indeksu. Próbowałem także użyć wersji geograficznej ST_DWithin i to zapytanie również nie powróciło po 5 minutach.