Длина строк в формате Google Maps и SQL Server LINESTRING несовместима

Google Maps и MSSQL, похоже, не согласны с тем, как рассчитать расстояние/длину полилинии /linestring с помощью SRID 4326.

MSSQL:

SELECT geography::STGeomFromText('LINESTRING(-98.78 39.63,2.98 27.52)', 4326).STLength()

Результат: 9030715.95721209

Затем Карты Google:

http://jsbin.com/niratiyojo/1/

Результат: 9022896.239500616

Сначала я думал, что это просто другой радиус земли, поэтому я играл с этим, и оказалось, что это больше.

Мне нужен мой JavaScript-интерфейс, чтобы он соответствовал тому, что MSSQL будет сообщать, чтобы он был последовательным и точным. Где и как я могу узнать, как MSSQL вычисляет их STLength() и может ли он быть реплицирован в JavaScript?

Update:

Я понял, что если я делаю

SELECT GEOGRAPHY::STGeomFromText('LINESTRING(-98.78 39.63,2.98 27.52)', 104001).STLength() * 6378137

Затем MSSQL возвращает 9022896.23950062

Новый SRID в MSSQL:

Новый идентификатор пространственной ссылки "Единица измерения" По умолчанию пространственная ссылка ID (SRID) в SQL Server 2012 - 4326, который использует метрическую систему как его единица измерения. Этот SRID также представляет эллипсоидальная сферическая форма земли. Хотя это представление наиболее точным, его также более сложно вычислить точные эллипсоидальные математика. SQL Server 2012 предлагает компромисс в скорости и путем добавления нового идентификатора пространственной привязки (SRID), 104001, который использует сферу радиуса 1 для представления совершенно круглой земли.

Таким образом, проблема заключается в том, что Google Maps не использует истинную эллипсоидальную сферу при расчетах. Я ищу функцию javascript, которая получает 9030715.95721209 в качестве свидетеля.

Я попробовал прямую формулу Vincenty здесь: http://jsbin.com/noveqoqepa/1/edit?html,js,console и, пока она ближе, я все еще не могу сопоставить MSSQL

Изменить 2:

Я смог найти измерения, которые он использует:

SridList._sridList.Add(4326, new SridInfo(4326, "EPSG", 4326, "GEOGCS[\"WGS 84\", DATUM[\"World Geodetic System 1984\", ELLIPSOID[\"WGS 84\", 6378137, 298.257223563]], PRIMEM[\"Greenwich\", 0], UNIT[\"Degree\", 0.0174532925199433]]", "metre", 1.0, 6378137.0,
6356752.314));

но, похоже, их включение в Винценти не приносит никакой пользы.

Ответы

Ответ 1

Пройдя через все различные варианты, лучшим вариантом является использование одной и той же функции буквально как на сервере, так и на клиенте. Это может быть достигнуто двумя способами:

Подход 1: Используйте функцию SQL на клиенте

В этом случае вы инициируете запрос AJAX на клиенте на сервер, который, в свою очередь, запрашивает базу данных для конкретного расчета и возвращает его клиенту.

Подход 2: Используйте функцию Javascript в SQL

Это может показаться совершенно невозможным, но с помощью xp_cmdshell возможно выполнить команды командной строки из sql, и вы можете запустить javascript из терминал использует что-то вроде node.js, поэтому все, что вам осталось, - это реализовать функцию Vincenty, которая будет вызываться из командной строки.

Большой вопрос здесь в том, как будет работать. Запуск и остановка экземпляра node каждые несколько секунд кажется относительно плохой идеей, поэтому было бы гораздо более оптимально закодировать службу в node для выполнения этой работы, однако я бы не знал, каким будет лучший способ для sql для взаимодействия с такой услугой. Простейший подход, вероятно, заключался бы в том, чтобы он выполнял HTTP-запрос на что-то вроде localhost:8888/?lat1=&lng1=&etc., но это стало почти таким же сложным, как и подход 1.

Заключение

Подход 1 по-прежнему представляется наиболее разумным, хотя подход 2 дает вам гораздо большую гибкость, чтобы делать именно то, что вы хотите. Для частного проекта или проекта перфекциониста я думаю, что я бы пошел с подходом 2, потому что "нам нужно закончить это, и у нас нет времени для сюрпризов или оптимизаций". Я думаю, что я бы посоветовал подход №1.

Ответ 2

Вы понимаете, что Google Maps использует веб-Меркатор, иначе EPSG: 3857, а не WGS EPSG: 4326? статья Веб-Меркатора и ее ссылки могут помочь объяснить различия.

Попробуйте выполнить JavaScript GeographicLib и/или Proj4js. Как этот вопрос/ответ на gis.stackexchange укажет, что базовые реализации конверсий пространственных данных могут быть немного отличающимися. Вы, по крайней мере, нуждаетесь в чем-то лучшем, чем Винченти.

Ответ 3

Единственный способ убедиться в том, что вы получите программиста Microsoft по телефону, разобрать код или просто отправить запрос в базу данных SQL Server и принять его результаты.

Это может вам помочь: Использование пространственных типов SQL в приложении .NET

Если вы хотите попробовать свои силы при разборке, я считаю, что этот метод находится в файле Microsoft.SqlServer.Types.dll.