0

我正在尝试使用一种方法来确定经纬度坐标是否在数据库中存储的任何多边形内,并返回它所在的多边形列表(如果有的话)。

我有一个纬度/经度:

50.120578, -103.535156

我创建了一个地理围栏并将其存储在数据库中,

CREATE TABLE [dbo].[GeoFences] (
    [Id]           INT               IDENTITY (1, 1) NOT NULL,
    [GeoPoints]    [sys].[geography] NULL,
    CONSTRAINT [PK_dbo.GeoFences] PRIMARY KEY CLUSTERED ([Id] ASC)
);

这些是 GeoPoints 的值。

POLYGON ((-129.63729858398437 57.279042764977774, -92.899017333984375 56.8970039212726, -93.865814208984375 48.922499263758255, -122.86972045898437 48.806863461085172, -129.37362670898437 57.088515327886505, -129.63729858398437 57.279042764977774))

使用这种方法,我希望它在多边形围绕该点时返回该行。

public IEnumerable<GeoFence> SearchGeoPoint(DbGeography geoPoint)
        {
            try
            {
                return _geoLocationRepository.Get.Where(obj => obj.GeoPoints.Intersects(geoPoint));
            }
            catch (Exception)
            {
                return null;
            }
        }

但是我一直没有返回任何行。我没有收到任何异常或错误,只有 0 行。

4

2 回答 2

0

您的坐标以错误的顺序定义,因此您的多边形实际上代表了带有“小”洞的地球。

SqlGeography 应该“走”坐标,始终保持左侧的内部区域。这意味着您的多边形中定义的任何孔都应该以“相反”的方式行走(实际上仍然将多边形的内部区域保持在您的左侧)。本质上,你是在定义地球上的那个洞。

简而言之,您需要颠倒坐标顺序才能获得正确的结果(以及您正在寻找的结果)。如果您使用的是 SQL Server 2012,请尝试以下ReorientObject()方法:

DECLARE @geog GEOGRAPHY = (SELECT [GeoPoints].ReorientObject() FROM [dbo].[GeoFences] WHERE [Id] = <an id>);
SELECT @geog;

但是,我会建议ReorientObject()在这种情况下,这实际上只是一个临时解决方案。您需要永久“重新定向”所有存储的多边形 - 如果它们是使用正确的顺序定义的。

于 2014-03-17T08:49:28.913 回答
0

发现这实际上是这里的一些问题,希望遇到此问题的人会发现这很有帮助。

第一个问题是我在 LINQ 查询中一起使用了 .Get.Where 。当我删除 .Get 并直接使用数据库上下文(我使用的是通用存储库)时,它返回了我期望的行。

我换了

return _geoLocationRepository.Get.Where(obj => obj.GeoPoints.Intersects(geoPoint));

using(var context as DatabaseContext())
{
  var results = new List<GeoFence>();
  var query = context.GeoFences.Where(obj => obj.GeoPoints.Intersects(geoPoint));

  //Have to iterate through the results (Only way I've found to access the data)
  foreach(var fence in query)
{
   results.Add(fence);
}

return results;
}

另一件需要注意的是,您需要使用 Long/Lat 来创建 POINT 而不是 Lat/Long(如果您使用 Lat/Long,则会出现异常)。

于 2014-03-17T16:57:15.923 回答