ST_D с параметром в градусах, а не в метрах, почему?
В документе ST_DWithin сказано, что третий параметр (расстояние) указан в метрах. Но когда я выполняю какой-то запрос, кажется, что он принимает третий параметр как "градус"?
Вот моя упрощенная структура таблицы:
> \d+ theuser;
Table "public.theuser"
Column | Type | Modifiers | Storage | Description
----------+------------------------+-----------+----------+-------------
id | bigint | not null | plain |
point | geometry | | main |
Indexes:
"theuser_pkey" PRIMARY KEY, btree (id)
"point_index" gist (point)
Referenced by:
...
Has OIDs: no
Все точки сохраняются с SRID=4326.
И это запрос:
> select * from theuser where ST_DWithin(point , ST_GeomFromText('POINT(120.9982 24.788)',4326) , 100 );
Он принимает третий параметр (100) как "градус", поэтому он возвращает все данные, мне нужно сузить до 0,001, чтобы найти близлежащие точки.
Но как мне напрямую передать счетчики в качестве 3-го параметра (я не хочу выполнять преобразование счетчик / градус)? Что не так с моим запросом? почему postgreSQL не воспринимает это как метры, как говорится в документе?
Среды:
> select version();
version
-----------------------------------------------------------------------------------------------------------
PostgreSQL 8.4.9 on i486-pc-linux-gnu, compiled by GCC gcc-4.4.real (Ubuntu 4.4.3-4ubuntu5) 4.4.3, 32-bit
> SELECT postgis_lib_version();
postgis_lib_version
---------------------
1.4.0
Если именно SRID вызывает эту проблему, то какой SRID напрямую использует "метр" в качестве единицы измерения? (Я попытался преобразовать в SRID=2163, но все еще в степени) Спасибо.
4 ответа
Из документов:
Для геометрий: расстояние указывается в единицах, определенных пространственной системой отсчета геометрий.
Если ваши данные в SRID=4326, то указанное вами расстояние указывается в градусах.
Вы должны либо использовать ST_Transform и систему координат на основе счетчика, либо одну из двух функций: ST_Distance_Sphere (быстрее, менее точно) или ST_Distance_Spheroid.
Если твой geometry
находится в WGS84, то есть Srid 4326, вы можете привести геометрию к geography
SELECT *
FROM theuser
WHERE ST_DWithin(
point::geography,
ST_GeomFromText('POINT(120.9982 24.788)',4326)::geography,
100 -- DISTANCE IN METERS
);
Как указано здесь, https://postgis.net/docs/ST_DWithin.html, есть две разные подписи для функции ST_DWithin.
Если кто-то хочет использовать счетчики напрямую, подойдет вторая сигнатура с логическим флагом.
В качестве примера JPA я публикую свой запрос ниже.
@Query("select f from Facility as f where dwithin(f.address.coordinates, :center, 10000, true) = TRUE")
List<Facility> findAllByDistance(@Param("center") Point point);
Я бы не рекомендовал вам преобразовывать в метры каждый раз, когда вы хотите использовать DWithin. Кстати, если вам нужны метры, вам нужна проекция равной площади, например, проекция Альберса (их много), почему бы вам не попробовать ST_Buffer(точка, градусы) и посмотреть, что он делает на Google Earth, принять меры и найти нужное вам число, обычно вам нужны предварительно определенные диапазоны, что-то вроде очень близко = 0,00008, около = 0,0005, далеко = 0,001, очень далеко = 0,01, действительно очень далеко = 0,1 и т. Д. (Все в градусах).
В предыдущем вопросе, который вы задали самым быстрым способом, вы находитесь в правильном направлении.
Попробуйте запрос ниже, он работает нормально для меня.
select * from theuser where ST_DWithin(point , ST_GeomFromText('POINT(120.9982 24.788)',4326) , 0.1/111.325 );
Здесь 0,1 = 100 метров.