关于javascript:google maps和sql server linestring长度不一致

Google Maps and SQL Server LINESTRING length inconsistent

谷歌地图和MSSQL似乎不同意如何使用SRID4326计算折线/线串的距离/长度。

MSSQL:

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

结果:9030715.95721209

然后谷歌地图:

结果:9022896.239500616

起初我以为这只是一个不同的地球半径测量,所以我玩了,结果发现更多。

我需要我的javascript接口来匹配MSSQL报告的内容,以保持一致和准确。我可以在哪里或如何找到MSSQL如何计算它们的STLength(),并且可以在javascript中复制它?

更新:

我意识到如果我这样做

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

然后mssql返回9022896.23950062

MSSQL中的新SRID:

New"Unit Sphere" Spatial Reference ID The default spatial reference
ID (SRID) in SQL Server 2012 is 4326, which uses the metric system as
its unit of measurement. This SRID also represents the true
ellipsoidal sphere shape of the earth. While this representation is
most accurate, it’s also more complex to calculate precise ellipsoidal
mathematics. SQL Server 2012 offers a compromise in speed and
accuracy, by adding a new spatial reference id (SRID), 104001, which
uses a sphere of radius 1 to represent a perfectly round earth.

所以问题是谷歌地图在计算中没有使用真正的椭圆球体。我正在寻找一个javascript函数,它可以得到9030715.95721209,正如所看到的那样。

我在这里尝试了Vincenty Direct公式:http://jsbin.com/noveqoqepa/1/edit?html,js,console,虽然它更接近,但我仍然无法匹配mssql

编辑2:

我找到了它使用的测量方法:

1
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:在客户机上使用SQL函数

在这种情况下,您将在客户机上触发一个到服务器的Ajax查询,该查询反过来查询数据库中您想要的特定计算,并将其返回给客户机。

方法2:在SQL中使用javascript函数

这听起来可能不太可能,但是使用xp_cmdshell,可以从SQL执行命令行命令,并且可以使用node.js之类的工具从终端运行javascript,所以剩下的就是实现从命令行调用的vincenty函数。

这里的大问题是表演如何。每隔几秒钟启动和停止一个node实例似乎是一个相对不好的主意,因此在节点中编写一个服务代码来完成这项工作会更为理想,但是我不知道sql与这样的服务交互的最佳方式是什么。最简单的方法可能是让它对类似于localhost:8888/?lat1=&lng1=&etc.的东西执行HTTP请求,但这开始变得和方法1一样复杂。

结论

方法1似乎仍然是最合理的方法,尽管方法2给了您更大的灵活性,使您能够准确地执行您想要的操作。对于一个私人项目或一个完美主义项目,我认为我会采用方法2,因为"我们需要完成这个,我们没有时间进行惊喜或优化",我认为我会建议方法1。


你知道谷歌地图使用的是网络墨卡托,又称epsg:3857,而不是wgs epsg:4326吗?网络墨卡托的文章及其参考可能有助于解释这些差异。

尝试使用地理库和/或proj4js的javascript实现。正如gis.stackexchange上的这个问题/答案所表明的,空间数据转换的底层实现可能会有细微的不同。你至少需要比文森蒂直接更好的东西。


唯一可以确定的方法是让Microsoft程序员打电话、反汇编代码,或者只向SQL Server数据库发送查询并接受其结果。

这可能对您有所帮助:在.NET应用程序中使用SQL空间类型

如果您想尝试进行反汇编,我相信该方法在microsoft.sqlserver.types.dll文件中。