SQL Server Geography与DbGeography

时间:2017-05-18 12:52:14

标签: c# .net sql-server entity-framework geospatial

我有两个GPS坐标,我想计算它们之间的距离,但SQL服务器上的结果与c#中的结果完全不同,我用Google搜索,发现两种方法都以米为单位返回距离,但这种差异让我发疯。

SQL SERVER查询

OtherTable

Result of above sql query

Web API

SELECT
    T.number5, T.year, T.[A1], T.[A1-1], T.[B1], T.[B1-1]
  , OT1.FileName, OT1.Value, OT1.Brand
  , OT2.FileName, OT2.Value, OT2.Brand
  , OT3.FileName, OT3.Value, OT3.Brand
  , OT4.FileName, OT4.Value, OT4.Brand
FROM #temp AS T
LEFT JOIN OtherTable AS OT1 ON OT1.FileName = T.[A1]
LEFT JOIN OtherTable AS OT2 ON OT2.FileName = T.[A1-1]
LEFT JOIN OtherTable AS OT3 ON OT3.FileName = T.[B1]
LEFT JOIN OtherTable AS OT4 ON OT4.FileName = T.[B1-1]

响应

select geography::Point(25.3132666, 55.2994054 ,4326)
                         .STDistance(geography::Point(25.25434, 55.32820,4326)) as Distance;

提前致谢。

3 个答案:

答案 0 :(得分:14)

在定义点时,检查SQL中点的WKT表示中的纬度和经度顺序,它们如下GEOGRAPHY::POINT(Latitude, Longitude, srid)

SELECT GEOGRAPHY::Point(25.3132666,55.2994054 ,4326)
                    .STDistance(GEOGRAPHY::Point(25.25434, 55.32820,4326)) as distance;
//distance: 7142.94965953253

但在C#代码中定义DBGeography时,顺序不同:"POINT(Longitude Latitude)"

String format = "POINT(55.32820 25.25434)";
DbGeography myLocation = DbGeography.PointFromText(format, 4326);
var users = context.Users.Select(u => new
{
    fullName = u.name,
    lat = u.location.Latitude,
    lng = u.location.Longitude,
    distance = myLocation.Distance(u.location)
}).ToList();

//distance: 7142.949659532529

另外,您应该检查Users表中插入的位置。确保插入时已正确插入。否则,他们将在其他地方而不是Users

的位置

更多

SELECT GEOGRAPHY::Point(25, 55 ,4326).Lat                       //25

DbGeography.PointFromText("POINT(25  55)", 4326).Latitude.Value //55

Microsoft.SqlServer.Types.SqlGeography.STPointFromText(
            new System.Data.SqlTypes.SqlChars("POINT(25 55)"), 4326).Lat.Value;
                                                                //55

什么是WKT?它来自哪里? 它是由{OGC在Simple Feature Access引入的不同几何类型的 W ell- K nown T ext表示建议规范和所有软件供应商在兼容性方面遵循它。该规范向我们展示了如何将点,线(线串),多边形和一些其他几何类型定义为文本(WKT)和二进制(WKB)。

SQL Server没有完全遵循此规范,我们看到不遵循标准的结果,甚至导致同一公司的不同组件出现此类问题。

答案 1 :(得分:4)

在API版本中切换Lat / Lng。在API中,它应该是Lng Lat

select geography::Point(25.3132666, 55.2994054 ,4326).STDistance(geography::Point(25.25434, 55.32820,4326))  as Distance

<强>返回

7142.94965953253

这是我翻转一个Lat / Lng usinq我的UDF

的地方
Select [dbo].[udf-Geo-Meters](55.2994054,25.3132666  ,25.25434,55.32820)

<强>返回

4135883.9028193

答案 2 :(得分:2)

这个问题很小但很棘手

SQL SERVER查询

geography::Point(25.3132666, 55.2994054 ,4326)

SQL Server定义一个点,使得第一个值是纬度,第二个值是经度。

Web API

String format = "POINT(25.25434 55.32820)";
DbGeography myLocation = DbGeography.FromText(format);

C#从上面的格式定义一个点,第一个值是经度,第二个值是纬度