Получите расстояние в метрах вместо градусов в Spatialite

У меня есть следующий запрос:

select distance(GeomFromText('POINT(8 49)',4326),GeomFromText('LINESTRING(8.329969 49.919323,8.330181 49.919468)',4326)) 

это дает мне 0,97 градуса. Но мне нужно это в метрах и не знаю, к какому SRID нужно преобразовать.

Может ли кто-нибудь дать мне пример, как получить результат в метрах для пространственного?

Все позиции в Европе.

Просто умножьте значение в градусах на 111195 – это значение (Earth mean radius)*PI/180 – это «средняя длина одной большой степени круга в метрах на поверхности Земли».

Максимальная ошибка с использованием этого метода составляет ~ 0,1%


РЕДАКТИРОВАТЬ

Хорошо, мой ответ выше по-прежнему встает на вопрос: «Как преобразовать дуги в градусах по длинам в метрах», однако это не вопрос, который вы задали (должен был спросить).

Я не использовал Spatialite профессионально, поэтому я предположил, что ваш запрос на выбор действительно возвращает «длину в градусах». Это не правда.

К сожалению, похоже, что Spatialite не может вычислить расстояние в «географическом смысле». Несмотря на то, что ваши геометрии определены с помощью SRID 4326, он относится к ним так, как если бы они были на плоскости.

Вот простое доказательство:

 select Distance(GeomFromText('POINT(0 0)',4326),GeomFromText('POINT(3 4)',4326)); 

возвращает 5.0 .

Это позор …

Давайте посмотрим на ваш оригинальный запрос:

 select Distance( GeomFromText('POINT(8 49)',4326), GeomFromText('LINESTRING(8.329969 49.919323,8.330181 49.919468)',4326) ) 

Эквивалентный запрос в MS SQL Server:

 SELECT (geography::STGeomFromText('POINT(8 49)', 4326)).STDistance(geography::STGeomFromText('LINESTRING(8.329969 49.919323,8.330181 49.919468)', 4326)); 

сразу получает правильный результат: 105006.59673084648 , в метрах, и без лишних броухаха.

Итак, каковы ваши варианты с Spatialite?

Действительно, как вы сказали в комментариях, один из вариантов – проецировать ваши геометрии и рассчитывать на них. Использование SRID 3035 для Европы тоже имеет смысл (если ваши местоположения в основном в Германии, я бы рассмотрел SRID 25832).

 select Distance( Transform(GeomFromText('POINT(8 49)',4326),25832), Transform(GeomFromText('LINESTRING(8.329969 49.919323,8.330181 49.919468)',4326),25832) ) 

возвращает 104969.401605453 .

Что касается вашего другого образца (в комментариях):

 select distance( Transform(GeomFromText('POINT(8.328957 49.920900)',4326),3035), Transform(GeomFromText('POINT(8.339665 49.918000)',4326),3035) ) 

Существует более простой способ сделать это (если у вас есть два POINT, а не POINT и LINESTRING): создайте LINESTRING с помощью POINT и используйте функцию GeodesicLength, например:

 select GeodesicLength(GeomFromText('LINESTRING(8.328957 49.920900, 8.339665 49.918000)',4326)) 

Он возвращает 833.910006698673 , как и ожидалось.

В справочном руководстве функций SpatiaLite вы можете увидеть, что есть две версии функции Distance() . Один принимает только два аргумента и возвращает расстояние в единицах CRS, другой принимает 3 аргумента и возвращает расстояние в метрах.

Чтобы получить расстояние в метрах, просто передайте третий аргумент расстоянию:

 sqlite> select Distance(MakePoint(0, 0), MakePoint(3, 4)); 5.0 sqlite> select Distance(MakePoint(0, 0), MakePoint(3, 4), 1); 554058.923752633