SQL Server 2008中的空间:找到多边形点(SQL Server 2008 Spatial

2019-06-25 12:38发布

我使用SQL Server 2008中的空间数据类型。 我与所有国家的表(如多边形)数据类型的几何体。 现在我要检查,如果一个点的坐标(纬度,经度)的数据类型,地理,是国家内部或没有。

使用新的空间数据类型我找不到任何例子。 目前,我有这是很多年前实施的解决办法,但它也有一些缺点。

我有两个SQL Server 2008和2012年如果新版本有一些改进,我就可以开始在它的工作了。

谢谢。

更新1:

我增加了代码示例了一点更加清晰。

declare @s geometry  --GeomCol is of this type too.
declare @z geography --GeogCol is of this type too.

select @s = GeomCol
from AllStates
where STATE_ABBR = 'NY'

select @z = GeogCol
from AllZipCodes
where ZipCode = 10101

Answer 1:

我认为地理学方法STIntersects()会做你想要什么:

DECLARE @g geography;
DECLARE @h geography;
SET @g = geography::STGeomFromText('POLYGON((-122.358 47.653, -122.348 47.649, -122.348 47.658, -122.358 47.658, -122.358 47.653))', 4326);
SET @h = geography::Point(47.653, -122.358, 4326)

SELECT @g.STIntersects(@h)


Answer 2:

如果你不能改变数据类型存储的多边形GEOGRAPHY ,那么你可以将输入经纬度GEOMETRY和使用STContainsSTIntersects对转换后的值。

DECLARE @PointGeography GEOGRAPHY = geography::Point(43.365267, -80.971974, 4326)
DECLARE @PointGeometry GEOMETRY = geometry::STGeomFromWKB(@PointGeography.STAsBinary(), 4326);

SELECT @PolygonGeometry.STContains(@PointGeometry);

走向相反的方向-试图将转换GEOMETRY多边形GEOGRPAHY -是容易出错,而且可能从我的经验失败。

请注意,如果您尝试创建GEOMETRY直接从纬度和经度值点,则STContains (或STIntersects )将无法正常工作(即当他们应该不会放弃比赛)。



Answer 3:

declare @g geometry
set @g=geometry::STGeomFromText('POLYGON((-33.229869 -70.891988, -33.251124 -70.476616, -33.703094 -70.508045, -33.693931 -70.891052,-33.229869 -70.891988))',0)

DECLARE @h geometry;

SET @h = geometry::STGeomFromText('POINT(-33.3906300 -70.5725020)', 0);
SELECT @g.STContains(@h);


Answer 4:

  1. 你不应该混合几何学和地理学。 几何是平坦面,地理学是球体(如地球)。
  2. 你“应该”调和SRIDs来处理这个问题。 每个SRID(例如2913 = NZG2000)描述了一种转换关系。 每个SRID可用于映射到/从一个统一的球,这是你如何从一个到另一个获得。
  3. 直到你得到一个“同” SRID两个值,多为.STxXX函数将返回NULL(你可能在这两种情况下默认为0)
  4. 如果他们是不一样的,但是你假装他们是,你可能对边缘情况的错误。
  5. 如果你花一些“precalc”的时候,你可以决定所涉及的边界rects顶部/左,下/右点(并存储它们),并使用索引这些值来限制记录进行检查。 除非AT / L <BB / R和AB / R> BT / L它们不能重叠,这意味着在您的WHERE会限制你STWithin检查简单的4和数字校验

下面是我在SRID 2193.所有道路使用的特定点的半径10公里以内的例子,一个特定的学校区内

DECLARE @g geometry

SELECT @g = GEO2193 FROM dbo.schoolzones WHERE schoolID = 319

SELECT DD.full_road_name, MIN(convert(int,  dd.address_number)), MAX(convert(int,  dd.address_number))
FROM (

select A.* from dbo.[street-address] A

WHERE (((A.Shape_X - 1566027.50505) * (A.Shape_X - 1566027.50505)) + ((A.Shape_Y - 5181211.81675) * (A.Shape_Y - 5181211.81675))) < 9250000

and a.shape_y > 5181076.1943481788

and a.shape_y < 5185097.2169968253

and a.shape_x < 1568020.2202472512

and a.shape_x > 1562740.328937705

and a.geo2193.STWithin(@g) = 1
) DD
GROUP BY DD.full_road_name
ORDER BY DD.full_road_name


Answer 5:

如果你有表(例如:SubsriberGeo),其中的一列(例如:位置)具有地理点的值,你想找到该表是内部多边形这里是一个办法做到这一点的所有点:

 WITH polygons
 AS (SELECT 'p1' id, 
            geography::STGeomFromText('polygon ((-113.754429 52.471834 , 1 5, 5 5, -113.754429 52.471834))', 4326) poly
),
 points
 AS (SELECT [SubscriberId],[Location] as p FROM [DatabaseName].[dbo].[SubscriberGeo])
 SELECT DISTINCT 
        points.SubscriberId, 
        points.p.STAsText() as Location
 FROM polygons
      RIGHT JOIN points ON polygons.poly.STIntersects(points.p) = 1
 WHERE polygons.id IS NOT NULL;


文章来源: SQL Server 2008 Spatial: find a point in polygon