SQL Server 2005 多边形中的点
我在 sql2005 数据库中有一个多边形结构,如下所述。
CREATE TABLE [dbo].[Polygons](
[PolygonID] [int] IDENTITY(1,1) NOT NULL,
[PolygonName] [varchar](255) NOT NULL,
[PolygonColor] [varchar](7) NOT NULL,
[PolygonRuleID] [int] NOT NULL)
CREATE TABLE [dbo].[Polylines](
[LineID] [int] IDENTITY(1,1) NOT NULL,
[LineX1] [float] NOT NULL,
[LineY1] [float] NOT NULL,
[LineX2] [float] NOT NULL,
[LineY2] [float] NOT NULL,
[PolygonID] [int] NOT NULL
)
现在,我检索应用程序的整行并将所有行放入测试功能中。
public static bool PointInPolygon(float pointX, float pointY, PolylineCollection polygon)
{
int nvert = polygon.Count();
int i, j = 0;
bool c = false;
for (i = 0, j = nvert - 1; i < nvert; j = i++)
{
if (((polygon[i].LineY1 > pointY) != (polygon[j].LineY1 > pointY)) &&
(pointX < (polygon[j].LineX1 - polygon[i].LineX1) * (pointY - polygon[i].LineY1) / (polygon[j].LineY1 - polygon[i].LineY1) + polygon[i].LineX1))
c = !c;
}
return c;
}
但我需要将此功能移至sql server。 但是Sql 2005没有本机空间函数,我不想使用任何额外的空间功能库。 如何将此函数移植到 T-SQL? :) 或者有人对 PointInPolygon 检查有不同的解决方案吗?
谢谢
I have a polygon structure in an sql2005 db as described below.
CREATE TABLE [dbo].[Polygons](
[PolygonID] [int] IDENTITY(1,1) NOT NULL,
[PolygonName] [varchar](255) NOT NULL,
[PolygonColor] [varchar](7) NOT NULL,
[PolygonRuleID] [int] NOT NULL)
CREATE TABLE [dbo].[Polylines](
[LineID] [int] IDENTITY(1,1) NOT NULL,
[LineX1] [float] NOT NULL,
[LineY1] [float] NOT NULL,
[LineX2] [float] NOT NULL,
[LineY2] [float] NOT NULL,
[PolygonID] [int] NOT NULL
)
Now I retrieve whole lines to application and put all to hit testing function.
public static bool PointInPolygon(float pointX, float pointY, PolylineCollection polygon)
{
int nvert = polygon.Count();
int i, j = 0;
bool c = false;
for (i = 0, j = nvert - 1; i < nvert; j = i++)
{
if (((polygon[i].LineY1 > pointY) != (polygon[j].LineY1 > pointY)) &&
(pointX < (polygon[j].LineX1 - polygon[i].LineX1) * (pointY - polygon[i].LineY1) / (polygon[j].LineY1 - polygon[i].LineY1) + polygon[i].LineX1))
c = !c;
}
return c;
}
But I need to move this function to sql server. But Sql 2005 doesn't have native spatial functions and I dont want to use any extra spatial functionality libraries. How can I port this function to T-SQL? :) Or anyone have different solution to PointInPolygon check?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
你可以看一下这个页面,它提供了SQL代码:
SQL代码Point In Polygon< /a>
You can look at this page, it provides SQL code:
SQL code Point In Polygon
您没有排除使用内置 geospatial 的 sql 2008类型。 我还没有使用过它,所以我无法提供除此之外的任何东西。
You didn't rule out going with sql 2008 which has built-in geospatial types. I haven't used it so I can't offer anything beyond that.
SQL Server 2005 允许您为可以在服务器端执行的 CLR 编写本机函数。 您可以阅读 MSDN 简介在 SQL Server 2005 中使用 CLR 集成。 这应该允许您将您的函数作为 sql server 的补充来实现并以本机速度运行。
SQL Server 2005 allows you to write native functions for the CLR that can execute server side. You can read the MSDN intro Using CLR Integration in SQL Server 2005. This should allow you to have your function implemented as an addition to sql server and run at native speeds.
您可以使用游标将 PointInPolygon 重写为存储过程。
You could re-write PointInPolygon as a stored proc with a cursor.
我必须承认我没有完全理解你的算法来测试点命中。 无论如何,多边形的数据结构是奇数的,因为一条线的 X1/Y1 必须等于前一行的 X2/Y2 才能形成多边形。 因此,我只会存储单个点,以保证数据结构的一致性,并且最后一个点和第一个点再次互连。
至于查找点是否位于(2D)多边形内部的算法,我首先过滤候选线并创建“切割”(水平或垂直),以便获得线交点的列表并订购它们。 然后,使用排名函数,如果排名是奇数,则它在多边形内部,如果排名是偶数,则我们在多边形外部(或在“洞”中)。
I have to admit that I don't fully get your algorithm to test for point hitting. Anyways, the data structure is odd for a polygon, since X1/Y1 of a line have to be equal to X2/Y2 of the previous line in order to form a polygon. Therefore, I'd store single points only in order to make the data structure guaranteed to be consistent, and the last and the first point are interconnected again.
As for an algorithm for finding whether a point is inside the (2D) polygon or not, I'd first filter the lines which are candidates and create a "cut" (horizontal or vertical) so that I get a list of line intersection points and order them. Then, using a rank function, it is inside the polygon if the rank is odd, if it even we're outside the polygon (or in a "hole").