javascript sql-server google-maps gis sqlgeography

javascript - La longitud de Google Maps y SQL Server LINESTRING es inconsistente



sql-server google-maps (3)

Google Maps y MSSQL parecen estar en desacuerdo sobre cómo calcular la distancia / longitud de una polilínea / cadena de líneas usando SRID 4326.

MSSQL:

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

Resultado: 9030715.95721209

Luego Google Maps:

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

Resultado: 9022896.239500616

Al principio pensé que era solo un radio diferente de la medida de la Tierra, así que jugué un poco con eso y resultó ser más.

Necesito que mi interfaz de JavaScript coincida con lo que MSSQL informaría para ser consistente y preciso. ¿Dónde o cómo puedo encontrar cómo MSSQL calcula su STLength() y puede replicarse en JavaScript?

Actualizar:

Me di cuenta si lo hago

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

Luego MSSQL devuelve 9022896.23950062

El nuevo SRID en MSSQL:

Nueva ID de referencia espacial de "esfera de unidad" La ID de referencia espacial predeterminada (SRID) en SQL Server 2012 es 4326, que utiliza el sistema métrico como su unidad de medida. Este SRID también representa la verdadera forma de esfera elipsoidal de la tierra. Si bien esta representación es más precisa, también es más complejo calcular las matemáticas elipsoidales precisas. SQL Server 2012 ofrece un compromiso en velocidad y precisión al agregar una nueva identificación de referencia espacial (SRID), 104001, que utiliza una esfera de radio 1 para representar una Tierra perfectamente redonda.

Entonces, el problema es que Google Maps no usa una verdadera esfera elipsoidal en los cálculos. Estoy buscando una función de javascript que obtiene 9030715.95721209 como atestiguado.

Intenté la fórmula directa de Vincenty aquí: http://jsbin.com/noveqoqepa/1/edit?html,js,console y, aunque está más cerca, aún no puedo encontrar MSSQL

Edición 2:

Pude encontrar las medidas que utiliza:

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));

Pero aparentemente conectarlos a Vincenty no produce suerte.


¿Se da cuenta de que Google Maps utiliza Web Mercator, también conocido como EPSG: 3857, y no WGS EPSG: 4326? El artículo de Web Mercator y sus referencias pueden ayudar a explicar las diferencias.

Pruebe la implementación de JavaScript de GeographicLib y / o Proj4js . Como lo indicará esta pregunta / respuesta en gis.stackexchange , las implementaciones subyacentes de las conversiones de datos espaciales pueden ser sutilmente diferentes. Al menos necesitas algo mejor que Vincenty Direct.


Después de pasar por todas las diferentes opciones, su mejor opción parece ser usar la misma función literal tanto en el servidor como en el cliente. Esto puede lograrse de dos formas:

Enfoque 1: usar la función SQL en el cliente

En este caso, debería activar una consulta AJAX en el cliente al servidor, que a su vez consulta la base de datos para el cálculo específico que desea y lo devuelve al cliente.

Enfoque 2: utilizar la función de Javascript en SQL

Esto puede parecer bastante imposible, pero al usar xp_cmdshell es posible ejecutar comandos de línea de comandos desde sql , y puede ejecutar javascript desde la terminal usando algo como node.js, por lo que todo lo que queda es implementar la función Vincenty desde la que se va a llamar. la linea de comando

La gran pregunta aquí es cómo será el rendimiento. Iniciar y detener una instancia de node cada pocos segundos parece ser una idea relativamente mala, por lo que sería mucho más óptimo codificar un servicio en nodo para hacer este trabajo, sin embargo, no sabría cuál sería la mejor manera para que sql interactúe con tal servicio El enfoque más simple probablemente sería hacer que realice una solicitud http a algo como localhost:8888/?lat1=&lng1=&etc. , pero eso comienza a ser casi tan complejo como el enfoque 1.

Conclusión

El Enfoque 1 todavía parece ser el más razonable, aunque el Enfoque 2 le brinda mucha más flexibilidad para hacer exactamente lo que quiere. Para un proyecto privado o un proyecto perfeccionista creo que iría con el enfoque 2, para un ''necesitamos terminar esto y no tenemos tiempo para sorpresas o proyectos de optimización'', creo que recomendaría el enfoque número 1.


La única forma de estar seguro es que el programador de Microsoft esté en el teléfono, desensamblar el código o simplemente enviar una consulta a una base de datos de SQL Server y aceptar los resultados.

Esto puede ser de ayuda para usted: usar tipos espaciales de SQL en una aplicación .NET

Si desea intentar desensamblar, creo que el método está en el archivo Microsoft.SqlServer.Types.dll.