计算 sql 服务器中两个地理位置之间的距离
Calculate distance between two geographical locations in sql server
我正在尝试使用 SQL 服务器中的以下查询来计算从一点到另一点 (Polygon/Multipolygon) 的距离。
DECLARE @g geometry;
DECLARE @h geometry;
SET @g = geometry::STGeomFromText('POLYGON ((139.999722222222 40.0513888888889, 141.401111111111 40.0513888888889, 141.398333333333 39.3494444444444, 140.765 38.1005555555556, 140.766111111111 37.3333333333333, 140.314722222222 36.8161111111111, 140.316111111111 36.2841666666667, 139.050277777778 36.2847222222222, 139.049444444444 35.1669444444444, 138.499444444444 35.1669444444444, 138.499444444444 35.5852777777778, 136.816944444444 35.5830555555556, 136.034166666667 34.8980555555556, 135.732222222222 34.8997222222222, 135.732222222222 35.3827777777778, 136.431944444444 35.8013888888889, 137.365 36.5341666666667, 138.165555555556 36.9333333333333, 139.415 37.8152777777778, 140.285833333333 39.4497222222222, 140.285833333333 39.8652777777778, 139.915555555556 39.8652777777778, 139.915555555556 39.9669444444444, 139.999722222222 40.0513888888889))', 4326);
SET @h = geometry::STGeomFromText('POINT(-1.9335937499142 53.956085529457)', 4326);
SELECT @g.STDistance(@h)/1609.344 as DistanceInMiles,@h.STDistance(@g) as DistanceInMeters
以下坐标在英国,
点(-1.9335937499142 53.956085529457)
Polygon 的坐标在日本。不知何故,当我 运行 查询时,我得到的距离不正确。
您可以在以下数据库中查看结果 fiddle,
https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=d6f4e3cbfa8d836c24006f6005eefc4b
不确定我是否做错了什么?
这里有 2 个问题。当您实际使用 GPS 坐标时,第一个不是使用 GEOGRAPHY
数据类型而是使用 GEOMETRY
。地理将考虑地球的形状,并将 return 为这种情况提供更精确的值。
第二个也是最大的问题是日本多边形的环形方向。坐标放置在硬编码字符串上的顺序对于确定生成的多边形非常重要。有时 SQL 服务器无法正确确定我们点之间的边的哪一侧实际上是多边形。
您可以通过使用相同多边形的 GEOMETRY
表示形式执行 STUnion
来解决此问题:
DECLARE @g_metry GEOMETRY = GEOMETRY::STGeomFromText('POLYGON ((139.999722222222 40.0513888888889, 141.401111111111 40.0513888888889, 141.398333333333 39.3494444444444, 140.765 38.1005555555556, 140.766111111111 37.3333333333333, 140.314722222222 36.8161111111111, 140.316111111111 36.2841666666667, 139.050277777778 36.2847222222222, 139.049444444444 35.1669444444444, 138.499444444444 35.1669444444444, 138.499444444444 35.5852777777778, 136.816944444444 35.5830555555556, 136.034166666667 34.8980555555556, 135.732222222222 34.8997222222222, 135.732222222222 35.3827777777778, 136.431944444444 35.8013888888889, 137.365 36.5341666666667, 138.165555555556 36.9333333333333, 139.415 37.8152777777778, 140.285833333333 39.4497222222222, 140.285833333333 39.8652777777778, 139.915555555556 39.8652777777778, 139.915555555556 39.9669444444444, 139.999722222222 40.0513888888889))', 4326);
DECLARE @g GEOGRAPHY = @g_metry.MakeValid().STUnion(@g_metry.STStartPoint()).STAsText()
DECLARE @h GEOGRAPHY = GEOGRAPHY::STGeomFromText('POINT(-1.9335937499142 53.956085529457)', 4326);
SELECT
@g.STDistance(@h)/1609.344 as DistanceInMiles,
@h.STDistance(@g) as DistanceInMeters
结果:
DistanceInMiles DistanceInMeters
5574.53292757983 8971341.11980304
如需进一步阅读,您可以阅读 this blog post。
我正在尝试使用 SQL 服务器中的以下查询来计算从一点到另一点 (Polygon/Multipolygon) 的距离。
DECLARE @g geometry;
DECLARE @h geometry;
SET @g = geometry::STGeomFromText('POLYGON ((139.999722222222 40.0513888888889, 141.401111111111 40.0513888888889, 141.398333333333 39.3494444444444, 140.765 38.1005555555556, 140.766111111111 37.3333333333333, 140.314722222222 36.8161111111111, 140.316111111111 36.2841666666667, 139.050277777778 36.2847222222222, 139.049444444444 35.1669444444444, 138.499444444444 35.1669444444444, 138.499444444444 35.5852777777778, 136.816944444444 35.5830555555556, 136.034166666667 34.8980555555556, 135.732222222222 34.8997222222222, 135.732222222222 35.3827777777778, 136.431944444444 35.8013888888889, 137.365 36.5341666666667, 138.165555555556 36.9333333333333, 139.415 37.8152777777778, 140.285833333333 39.4497222222222, 140.285833333333 39.8652777777778, 139.915555555556 39.8652777777778, 139.915555555556 39.9669444444444, 139.999722222222 40.0513888888889))', 4326);
SET @h = geometry::STGeomFromText('POINT(-1.9335937499142 53.956085529457)', 4326);
SELECT @g.STDistance(@h)/1609.344 as DistanceInMiles,@h.STDistance(@g) as DistanceInMeters
以下坐标在英国,
点(-1.9335937499142 53.956085529457)
Polygon 的坐标在日本。不知何故,当我 运行 查询时,我得到的距离不正确。
您可以在以下数据库中查看结果 fiddle,
https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=d6f4e3cbfa8d836c24006f6005eefc4b
不确定我是否做错了什么?
这里有 2 个问题。当您实际使用 GPS 坐标时,第一个不是使用 GEOGRAPHY
数据类型而是使用 GEOMETRY
。地理将考虑地球的形状,并将 return 为这种情况提供更精确的值。
第二个也是最大的问题是日本多边形的环形方向。坐标放置在硬编码字符串上的顺序对于确定生成的多边形非常重要。有时 SQL 服务器无法正确确定我们点之间的边的哪一侧实际上是多边形。
您可以通过使用相同多边形的 GEOMETRY
表示形式执行 STUnion
来解决此问题:
DECLARE @g_metry GEOMETRY = GEOMETRY::STGeomFromText('POLYGON ((139.999722222222 40.0513888888889, 141.401111111111 40.0513888888889, 141.398333333333 39.3494444444444, 140.765 38.1005555555556, 140.766111111111 37.3333333333333, 140.314722222222 36.8161111111111, 140.316111111111 36.2841666666667, 139.050277777778 36.2847222222222, 139.049444444444 35.1669444444444, 138.499444444444 35.1669444444444, 138.499444444444 35.5852777777778, 136.816944444444 35.5830555555556, 136.034166666667 34.8980555555556, 135.732222222222 34.8997222222222, 135.732222222222 35.3827777777778, 136.431944444444 35.8013888888889, 137.365 36.5341666666667, 138.165555555556 36.9333333333333, 139.415 37.8152777777778, 140.285833333333 39.4497222222222, 140.285833333333 39.8652777777778, 139.915555555556 39.8652777777778, 139.915555555556 39.9669444444444, 139.999722222222 40.0513888888889))', 4326);
DECLARE @g GEOGRAPHY = @g_metry.MakeValid().STUnion(@g_metry.STStartPoint()).STAsText()
DECLARE @h GEOGRAPHY = GEOGRAPHY::STGeomFromText('POINT(-1.9335937499142 53.956085529457)', 4326);
SELECT
@g.STDistance(@h)/1609.344 as DistanceInMiles,
@h.STDistance(@g) as DistanceInMeters
结果:
DistanceInMiles DistanceInMeters
5574.53292757983 8971341.11980304
如需进一步阅读,您可以阅读 this blog post。