DbGeography - select polygons/linestrings 包含在多边形内
DbGeography - select polygons/linestrings contained inside polygon
我有一个案例,我想加载位于用户视口内的地图对象。
这是我创建用户视口矩形的方式:
DbGeography viewport_rectangle = DbGeography.FromText(string.Format("POLYGON(({0} {1}, {0} {2}, {3} {2}, {3} {1}, {0} {1}))", lon_min, lat_min, lat_max, lon_max));
然后我想 select 所有对象(点、折线、多边形,位于该矩形内):
var objects = db.mapobjects.Where(x => !x.LocationGeographic.Intersects(viewport_rectangle));
到这里为止一切正常。如果 PolyLine/Polygon 没有完全包含在视口多边形内,就会出现问题。在这种情况下,它被忽略,我得到 "no objects" 而不是对象,其中一些 points/edges 不在视口中。
除了"Intersects"还有其他选择吗?我想要 select 个对象包含在视口矩形中,无论它们是否在内部,或者只有一小部分在视口矩形内。
viewport_rectangle = {SRID=4326;POLYGON ((15.693584159016611
46.532346466357438, 15.693584159016611 46.532770863495614, 15.695530101656916 46.532770863495614, 15.695530101656916 46.532346466357438, 15.693584159016611 46.532346466357438))}
仅部分位于 viewport_rectangle 内且应作为结果返回的对象:
LINESTRING (15.694189164787527 46.532622094224166, 15.694309193640944
46.532614944062828, 15.694392677396532 46.5326121762582, 15.694401059299702 46.532662919320614, 15.694536175578829 46.532621632923423, 15.694564338773485 46.532659690218026, 15.694584455341097 46.532614944062828, 15.694570373743769 46.532578039989573, 15.694489236921068 46.53258611275777, 15.694502312690016 46.532539290685662, 15.694723930209872 46.53252614359414, 15.69474438205361 46.532575041532539, 15.694786962121723 46.532516225610692, 15.694763492792843 46.532481858630774, 15.694699790328738 46.532507922181281, 15.694884862750767 46.532493852478581, 15.694849658757446 46.53254505695287)
LINQ 生成查询的一部分:
SELECT
[Filter1].[ObjectId] AS [ObjectId],
[Filter1].[LocationGeographic] AS [LocationGeographic],
FROM (SELECT [Extent1].[ObjectId] AS [ObjectId], [Extent1].[LocationGeographic] AS [LocationGeographic]
FROM [dbo].[mapobjects] AS [Extent1]
WHERE (([Filter1].[LocationGeographic].STIntersects(@p__linq__0)) <> cast(1
as bit))
) AS [Project1]
已编辑:
viewport_rectangle 的正确顺序应该是:
DbGeography viewport_rectangle = DbGeography.FromText(string.Format("POLYGON(({0} {1}, {2} {1}, {2} {3}, {0} {3}, {0} {1}))", lon_min, lat_min, lon_max, lat_max));
您的多边形似乎存在环方向问题。您指定要点的顺序很重要。正如您定义的那样,多边形是整个地球减去一个非常小的正方形(大概是您想要的视口)。我是如何确定的?
declare @line geography = geography::STGeomFromText('LINESTRING (15.694189164787527 46.532622094224166, 15.694309193640944 46.532614944062828, 15.694392677396532 46.5326121762582, 15.694401059299702 46.532662919320614, 15.694536175578829 46.532621632923423, 15.694564338773485 46.532659690218026, 15.694584455341097 46.532614944062828, 15.694570373743769 46.532578039989573, 15.694489236921068 46.53258611275777, 15.694502312690016 46.532539290685662, 15.694723930209872 46.53252614359414, 15.69474438205361 46.532575041532539, 15.694786962121723 46.532516225610692, 15.694763492792843 46.532481858630774, 15.694699790328738 46.532507922181281, 15.694884862750767 46.532493852478581, 15.694849658757446 46.53254505695287)', 4236),
@poly geography = geography::STGeomFromText('POLYGON ((15.693584159016611 46.532346466357438, 15.693584159016611 46.532770863495614, 15.695530101656916 46.532770863495614, 15.695530101656916 46.532346466357438, 15.693584159016611 46.532346466357438))', 4236);
select @poly.EnvelopeAngle(); --returns 180
select @poly.ReorientObject().STIntersects(@line); --returns 1
您最好自己阅读 EnvelopeAngle()
方法。但我会这样说 - 我将它用作快速启发式方法来检测您在这里遇到的环方向问题。总是,如果多边形有这个问题,包络角将是 180(这几乎不是你想要的)。
我还在上面的代码中给出了关于如何修复它的妙语;在多边形上调用 ReorientObject()
顺时针变为逆时针(反之亦然)。
最后,您的线串似乎完全包含在您的视口中;我用 STContains()
测试过。这解释了为什么之前您认为视口就是一切 但 视口!
我有一个案例,我想加载位于用户视口内的地图对象。
这是我创建用户视口矩形的方式:
DbGeography viewport_rectangle = DbGeography.FromText(string.Format("POLYGON(({0} {1}, {0} {2}, {3} {2}, {3} {1}, {0} {1}))", lon_min, lat_min, lat_max, lon_max));
然后我想 select 所有对象(点、折线、多边形,位于该矩形内):
var objects = db.mapobjects.Where(x => !x.LocationGeographic.Intersects(viewport_rectangle));
到这里为止一切正常。如果 PolyLine/Polygon 没有完全包含在视口多边形内,就会出现问题。在这种情况下,它被忽略,我得到 "no objects" 而不是对象,其中一些 points/edges 不在视口中。
除了"Intersects"还有其他选择吗?我想要 select 个对象包含在视口矩形中,无论它们是否在内部,或者只有一小部分在视口矩形内。
viewport_rectangle = {SRID=4326;POLYGON ((15.693584159016611 46.532346466357438, 15.693584159016611 46.532770863495614, 15.695530101656916 46.532770863495614, 15.695530101656916 46.532346466357438, 15.693584159016611 46.532346466357438))}
仅部分位于 viewport_rectangle 内且应作为结果返回的对象:
LINESTRING (15.694189164787527 46.532622094224166, 15.694309193640944 46.532614944062828, 15.694392677396532 46.5326121762582, 15.694401059299702 46.532662919320614, 15.694536175578829 46.532621632923423, 15.694564338773485 46.532659690218026, 15.694584455341097 46.532614944062828, 15.694570373743769 46.532578039989573, 15.694489236921068 46.53258611275777, 15.694502312690016 46.532539290685662, 15.694723930209872 46.53252614359414, 15.69474438205361 46.532575041532539, 15.694786962121723 46.532516225610692, 15.694763492792843 46.532481858630774, 15.694699790328738 46.532507922181281, 15.694884862750767 46.532493852478581, 15.694849658757446 46.53254505695287)
LINQ 生成查询的一部分:
SELECT [Filter1].[ObjectId] AS [ObjectId], [Filter1].[LocationGeographic] AS [LocationGeographic], FROM (SELECT [Extent1].[ObjectId] AS [ObjectId], [Extent1].[LocationGeographic] AS [LocationGeographic] FROM [dbo].[mapobjects] AS [Extent1] WHERE (([Filter1].[LocationGeographic].STIntersects(@p__linq__0)) <> cast(1 as bit)) ) AS [Project1]
已编辑: viewport_rectangle 的正确顺序应该是:
DbGeography viewport_rectangle = DbGeography.FromText(string.Format("POLYGON(({0} {1}, {2} {1}, {2} {3}, {0} {3}, {0} {1}))", lon_min, lat_min, lon_max, lat_max));
您的多边形似乎存在环方向问题。您指定要点的顺序很重要。正如您定义的那样,多边形是整个地球减去一个非常小的正方形(大概是您想要的视口)。我是如何确定的?
declare @line geography = geography::STGeomFromText('LINESTRING (15.694189164787527 46.532622094224166, 15.694309193640944 46.532614944062828, 15.694392677396532 46.5326121762582, 15.694401059299702 46.532662919320614, 15.694536175578829 46.532621632923423, 15.694564338773485 46.532659690218026, 15.694584455341097 46.532614944062828, 15.694570373743769 46.532578039989573, 15.694489236921068 46.53258611275777, 15.694502312690016 46.532539290685662, 15.694723930209872 46.53252614359414, 15.69474438205361 46.532575041532539, 15.694786962121723 46.532516225610692, 15.694763492792843 46.532481858630774, 15.694699790328738 46.532507922181281, 15.694884862750767 46.532493852478581, 15.694849658757446 46.53254505695287)', 4236),
@poly geography = geography::STGeomFromText('POLYGON ((15.693584159016611 46.532346466357438, 15.693584159016611 46.532770863495614, 15.695530101656916 46.532770863495614, 15.695530101656916 46.532346466357438, 15.693584159016611 46.532346466357438))', 4236);
select @poly.EnvelopeAngle(); --returns 180
select @poly.ReorientObject().STIntersects(@line); --returns 1
您最好自己阅读 EnvelopeAngle()
方法。但我会这样说 - 我将它用作快速启发式方法来检测您在这里遇到的环方向问题。总是,如果多边形有这个问题,包络角将是 180(这几乎不是你想要的)。
我还在上面的代码中给出了关于如何修复它的妙语;在多边形上调用 ReorientObject()
顺时针变为逆时针(反之亦然)。
最后,您的线串似乎完全包含在您的视口中;我用 STContains()
测试过。这解释了为什么之前您认为视口就是一切 但 视口!