Получить метрическое расстояние между двумя точками с помощью запроса PostgreSQL/PostGIS
У меня есть вопрос об использовании postgreSQL/postGIS.
Я хотел бы отобразить маркеры на карте (хранящиеся в базе данных), которые находятся на некотором расстоянии от пользователя (координаты, заданные в запросе).
Тип поля маркеров - POINT (я храню lat/long). Положение пользователя определяется API Google Map.
Вот актуальный запрос:
SELECT * FROM geo_points WHERE ST_distance(ST_SetSRID(geo_points.coords::geometry,4326),ST_GeomFromEWKT('SRID=4326;POINT(45.0653944 4.859764599999996)')) > 65
Я знаю (после некоторых исследований в Интернете), что функция ST_distance дает мне расстояние в градусах между маркерами и положением пользователя, и что я проверяю расстояние в км.
Я думаю, что я должен использовать функцию ST_tranform для преобразования точек в метрических координатах.
Итак, мои вопросы: - что такое SRID для Франции - как я могу сделать это динамически для всего мира в соответствии с позицией пользователя?
Я также знаю, что функция ST_within существует и может это сделать. Но я предвижу тот факт, что позже мне может понадобиться расстояние.
Любая помощь будет принята с благодарностью
ps: возможно, есть решения в другом посте, но все ответы, которые я нашел во время моих исследований, не соответствовали моим потребностям.
1 ответ
Во-первых, обратите внимание на порядок координат, используемый PostGIS, он должен быть long/lat. В настоящее время вы ищете в Сомали. Сменив координаты, вы будете искать во Франции.
Вы можете использовать геодезический расчет с типом географии или использовать геодезические функции, такие как ST_Distance_Spheroid. С типом geography вы можете использовать ST_DWithin для более высокой производительности.
Вот geo_points
65 м или менее от достопримечательности Франции (не Сомали):
SELECT * FROM geo_points
WHERE ST_Distance_Spheroid(
ST_Transform(geo_points.coords::geometry, 4326),
ST_SetSRID(ST_MakePoint(4.859764599999996, 45.0653944), 4326),
'SPHEROID["WGS 84",6378137,298.257223563]') < 65.0;
Однако он будет очень медленным, поскольку ему нужно найти расстояние до каждой точки geo_points, поэтому делайте это только в том случае, если вам не нужна производительность и у вас меньше нескольких тысяч точек.
Если вы измените и преобразуете geo_points.coords
хранить лон / лат (WGS84) как geography
тип:
SELECT * FROM geo_points
WHERE ST_DWithin(
geo_points::geography,
ST_SetSRID(ST_MakePoint(4.859764599999996, 45.0653944), 4326)::geography,
65.0);