Запрос PostGIS радиуса дает мне странные результаты - PullRequest
0 голосов
/ 24 октября 2018

Я новичок в PostGIS и пытаюсь создать запрос радиуса.У меня есть таблица с полем geometry (позиция), а также значения широты и долготы в отдельных полях.

Я пытаюсь найти точки в радиусе 10 км от широты: 40.753777, lon:-73,981568.

с:

SELECT postcode, lat, lon, st_asgeojson(position) geojson, ST_Distance(ST_MakePoint(lat, lon), ST_MakePoint(40.753777, -73.981568)) distance FROM addresses WHERE ST_DWithin(ST_MakePoint(lat, lon), ST_MakePoint(40.753777, -73.981568), 10000) order by id limit 10;

Результаты дают мне очень далекие очки.Тот же самый запрос с расстоянием до Земли с использованием широты и долготы дает мне гораздо более близкие результаты.

SELECT postcode, lat, lon, st_asgeojson(position) geojson FROM addresses WHERE earth_box(ll_to_earth(40.753777, -73.981568), 10000) @> ll_to_earth(addresses.lat, addresses.lon) order by id limit 10;

Но я действительно не знаю, правильно ли это тоже, что не так с запросом PostGIS?

1 Ответ

0 голосов
/ 29 июня 2019

Несколько примечаний:

  1. Я думаю, что вы поменяли местами широту и долготу, когда указали точку, ваша строка говорит ST_MakePoint (40.753777, -73.981568), но определение таково:
geometry ST_MakePoint(double precision x, double precision y);
Note: x is longitude and y is latitude

Таким образом, это должен был быть ST_MakePoint (-73.981568, 40.753777).

В качестве простого решения вы можете использовать функцию ST_Distance_Spheroid (http://www.postgis.org/docs/ST_Distance_Spheroid.html):
SELECT
    postcode, lat, lon, st_asgeojson(position) AS geojson,
    ST_Distance_Spheroid(
        position,
        ST_GeomFromText('POINT(-73.981568 40.753777)',
        4326), 'SPHEROID["WGS 84",6378137,298.257223563]'
    ) as distance
FROM addresses 
WHERE distance < 10000 LIMIT 10;
Для более точных расстояний добавьте новый столбец географии типа из существующего столбца position геометрии типа:
ALTER TABLE addresses ADD COLUMN position_geog geography(Point,4326);
UPDATE addresses SET position_geog = position::geography;
CREATE INDEX ON addresses USING gist(position_geog);
-- and now you can use ST_DWITHIN with meters...
...