谷歌地图和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)); |
但似乎把它们插进文森蒂身上不会带来好运。
- 我唯一能发现的是,半短轴倾向于表示为两个小数位,这对整体结果的影响正好为零。我真的不知道MSSQL是如何确定它的距离的。
- 利用椭球面上的Vincenty测地线解的活例子下的形式,我得到9030706.728 m,相当接近9030715.95721209(9×10^9米中的9米)。
- 是的,使用我在文章底部发布的jsbin解决方案,我也得到了相同的距离。它非常接近,但我需要更精确。
- 我不认为MapsAPI中提供的函数适用于需要极其精确的GIS应用程序。对于这些类型的应用程序,您最好找到满足您特定需求的其他库并使用它。你可以试试github.com/chrisveness/geodesy,尽管我不确定它是否能比其他人提到的库提供更精确的计算。
在经历了所有不同的选项之后,您最好的选择似乎是在服务器和客户机上使用相同的文本函数。这可以通过两种方式实现:
方法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。
- 如果精确性不是一个问题,那么谷歌地图就会在功能上建立,MS SQL SRID 104001将作为一个解决办法来完成这场比赛。在我的具体应用程序中,无论需要什么,但似乎有办法2。
你知道谷歌地图使用的是网络墨卡托,又称epsg:3857,而不是wgs epsg:4326吗?网络墨卡托的文章及其参考可能有助于解释这些差异。
尝试使用地理库和/或proj4js的javascript实现。正如gis.stackexchange上的这个问题/答案所表明的,空间数据转换的底层实现可能会有细微的不同。你至少需要比文森蒂直接更好的东西。
- Geographiclib returns 9030706.727997527 which is the same as the Vincenty formula.我开始觉得MSSQL是不合适的
- 复制这个网站码到您的网站上以设置一个投票箱在您的网站上。另一个建议是,当多线路变换时,使用客户端上的Javascript版本,并在一次或一次绘图完成后将线路的末端与后端同步。
- 告诉我我认为谷歌地图中使用的投影可能是一种误解,你可能想检查出大地线、圆圈、谷歌地图中的包裹以及相关的指示,这些指示可能有助于解释你可能为你的离散账户所作的区别。
- 我了解谷歌地图使用的投影,我使用的Javascript方法是4326的连接。Google maps geodesic option for polililine actually does not have any effect in their internal calculations for the length of a polililine(weardly).他们简单地在线上每一个长度/横点,并根据地球的一个球形模型计算。Thats why Google and MSSQL are so far off,where Vincenty uses an ellipsoid model of the earth,and muscloser to MSSQL,but I can't find the damn formula microsoft is using,I just know i t probably ellipsoidal
- 我的解决方案似乎是用一个球形地球模型将MSSQL长度函数降到MSSQL,所以它与几何图表匹配,并将它作为一个柱。另一个选择是写一个使用文森特的SQL程序。我不得不做一场他们的比赛,一种方式或另一种方式,我更喜欢最精确的方式,但这似乎是最昂贵的。
唯一可以确定的方法是让Microsoft程序员打电话、反汇编代码,或者只向SQL Server数据库发送查询并接受其结果。
这可能对您有所帮助:在.NET应用程序中使用SQL空间类型
如果您想尝试进行反汇编,我相信该方法在microsoft.sqlserver.types.dll文件中。
- 备选案文2似乎比备选案文1容易。备选案文3不可行。有人建议如何拆除它吗?我以一种明确的语言接受他的写作,这在预防分歧方面是众所周知的坏。
- 如果你想和服务器做的匹配,那么我就承认你在后面的某个地方使用了服务器。如果不你为什么在乎它是否匹配SQL服务器?如果你已经连接到一个SQL服务器,为什么不能把几何查询放在SQL服务器或Web Services上?
- 我是用一个Javascript接口创建LRS系统的,我需要知道一条聚氨酯的距离大约10次,第二次的变化,这可以很容易地与纯的Javascript(我做到了这一点)。这个服务器不能用一个后台呼叫,因为服务器的头顶上有太多的东西,而服务器的头顶上也会有太多的东西。然而,Javascript函数计算的距离必须与SQL服务器匹配,或者在视野和模型之间必须保持间隔。
- 我本来可以分解Microsoft.SqlServer.Types.dll的,但我看到它在SqlServerSpatial120.dll中提到一个功能。载荷空间DLL没有在高水平代码中产生,以致它看起来是明确的。我把它装进了IDA里,可以拿到大会,但它很难抓住。我管理好了一条弦,在那里它是指它的用法。我把它放在原始问题上,作为一个编辑
- 是可以从代码中获得C的,但它确实被忽略了。我希望能找到一个能帮我找到配方的号码。对唯一的16384号感兴趣,建议这可能不是Vincenty。这里是使用功能:帕斯泰宾