SQL 空间多边形由内而外

发布于 2024-10-07 08:20:23 字数 211 浏览 7 评论 0原文

我允许用户通过单击绘制在 Silverlight 中绘制多边形。然后我循环遍历这些点,将它们转换为经度和纬度,然后保存到 SQL(在 geography 列中)。

问题是,由于世界是圆的等等,它只有在用户顺时针绘制时才有效。否则,它会尝试使多边形环绕世界并失败。

那么我该如何正确地做到这一点呢?我是否必须弄清楚他们的绘画方式?如果是的话,该怎么做?

I am allowing users to draw a polygon in Silverlight by clicking to draw. Then I loop through the points, convert them to longitude and latitude and then save to SQL (in a geography column).

The problem is that because of the world being round and all that, it only works if the user draws clockwise. Otherwise it tries to make the polygon right round the world and fails.

So how do I do this correctly? Do I have to work out which way they are drawing, and if so how?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

開玄 2024-10-14 08:20:23

您可以检查地理的 EnvelopeAngle() 方法的结果是否为 180,然后使用 ReorientObject() 函数进行更正。

这是示例:

--A CW polygon
DECLARE @G3 GEOGRAPHY = 'POLYGON ((45 45, 44 45, 44 46, 45 46, 45 45))';    
SELECT @G3.EnvelopeAngle();                --180
SELECT @G3.ReorientObject().STAsText();    --POLYGON ((44 46, 44 45, 45 45, 45 46, 44 46))

编辑,如评论中所述,您可以使用简单的更新命令来更正当前的几何图形(如果您确定它们不正确):

UPDATE foo_table SET bar_column = bar_column.ReorientObject() 
    WHERE bar_column.EnvelopeAngle() > 90

You can check, if the result of the EnvelopeAngle() method for the geography was 180, then use the ReorientObject() function to correct it.

Here is the sample:

--A CW polygon
DECLARE @G3 GEOGRAPHY = 'POLYGON ((45 45, 44 45, 44 46, 45 46, 45 45))';    
SELECT @G3.EnvelopeAngle();                --180
SELECT @G3.ReorientObject().STAsText();    --POLYGON ((44 46, 44 45, 45 45, 45 46, 44 46))

EDIT as stated in the comments you may correct current geometries, using a simple update command (in the case you are sure they are not correct):

UPDATE foo_table SET bar_column = bar_column.ReorientObject() 
    WHERE bar_column.EnvelopeAngle() > 90
心房的律动 2024-10-14 08:20:23

我最近在 GIS StackExchange 上问了类似的问题。我相信我已经找到了一个仅 SQL 的解决方案,复制如下:

最终在 Spatial Ed 的博客

SQL 演示了转换:

DECLARE @geom GEOMETRY = 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))';
DECLARE @geog GEOGRAPHY = @geom.MakeValid().STUnion(@geom.STStartPoint()).STAsText()

以及 Ed 帖子的摘录:

此行为的关键是 STUnion() 方法。由于这是一种基于 OGC 的方法,适用于给定要素的整个几何图形,因此它会强制多边形进入该方法所需的方向 - 这恰好是用于地理类型的方向 [ ...]。所示的这种方法非常有效,可以保持较小的开销[...]。

I asked a similar question recently at the GIS StackExchange. I believe I have found a SQL-only solution, which is reproduced below:

Eventually found the answer at Spatial Ed's Blog.

SQL demonstrating the transform:

DECLARE @geom GEOMETRY = 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))';
DECLARE @geog GEOGRAPHY = @geom.MakeValid().STUnion(@geom.STStartPoint()).STAsText()

And excerpt from Ed's post:

The key to this behavior is the the STUnion() method. Since this is an OGC-based method, working on the entire geometry for a given feature, it forces polygons into the orientation required for the method - which just happens to be the one used for the Geography type [...]. This method illustrated is quite efficient, keeping overhead small [...].

固执像三岁 2024-10-14 08:20:23

如果您使用的是 SqlServer 2008 的 RTM 版本,您始终可以使用可免费分发的 codeplex 中的 sqlspatial 工具库只需使用 makevalid 方法。

如果您有时间使用 SqlServer Denali 的 CTP1,您可以选择新的空间类型,该类型可以接受大于半球的对象,并且具有 ReorientObject 方法 - 如果需要,可以重新定向对象:)

If you are tied to RTM version of SqlServer 2008 you can always use sqlspatial tools from codeplex that is freely distributable and from that library just use makevalid method.

If you have time to play with CTP1 of SqlServer Denali you can just pickup new spatial types that can accept objects larger than a hemisphere and that have ReorientObject method to - Reorient Object if needed :)

愁杀 2024-10-14 08:20:23

这是地理空间地理数据类型中的一个常见概念,多边形是由许多顶点和这些顶点之间的边定义的。但是,您必须能够区分多边形内部和外部的内容。这是由系统完成的,假设边缘的一侧始终定义内部(不同的标准使用左侧或右侧)

在一个方向上您绘制了一个小圆圈,在另一个方向上您绘制了一个包围的球体整个世界,除了一个小圈子。后者往往会打破地理限制并提出例外。

如果您考虑尝试绘制一个甜甜圈,则您有 2 个多边形,并且必须具有顺时针/逆时针图案的点,以定义中心内的“孔”。

That is a common concept within geospatial geography data types, a polygon is defined by a number of vertices and the edges between those vertices. However, you have to be able to distinguish between what is inside and outside of the polygon. This is done by the system assuming that one side of the edge will always be defining the inside (Different standards use left side or right side)

In one direction you have drawn a small circle, in the other direction you have drawn a sphere that encompasses the entire world, except for a small circle. The latter would tend to break geographic limits and raise an exception.

If you consider trying to draw a doughnut, you have 2 polygons and have to have the points in a clockwise / anti-clockwise pattern, to define the 'hole' within the centre.

≈。彩虹 2024-10-14 08:20:23

左手法则支配着这一点......当你“行走”多边形的周边时,你的左手必须始终在里面......所以事物应该“看起来”是逆时针数字化的。这也适用于甜甜圈和带孔的聚合物。

如果您将左手放在您感兴趣的多边形区域“内部”,它们将以顺时针方式数字化。

确定哪个是正确的一种简单方法是始终采用面积较小的那个...在我能想到的几乎所有工作流程中,没有任何多边形可以数字化大于世界的一半...

工作流程将如下所示:让您的用户创建他们的多边形,创建另一个具有相反方向的多边形(SQL Server 中的 ReorientObject ()),然后比较它们的面积...逻辑上,最小的是正确的。

只是解决这个问题的另一种方法。

Left hand rule governs this... as you 'walk' the perimeter of your polygon, your left hand must always be inside... so things should 'appear' to be digitized counter-clockwise. this hold true for donuts and polys with holes as well.

if you keep your left hand 'inside' the polygon area you are interested in, they will be digitized in a clockwise fashion.

A simple way to determine which one is correct is to always take the one with the SMALLER area... in just about any workflow I can thing of, there are no polygons that would be digitized that are larger than half the world...

The workflow would go like this: have your users create their polygons, create another polygon with the opposite orientation (ReorientObject () in SQL Server) and then compare their areas... Logically, the smallest is correct.

Just another way to solve this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文