我使用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
和使用STContains
或STIntersects
对转换后的值。
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:
- 你不应该混合几何学和地理学。 几何是平坦面,地理学是球体(如地球)。
- 你“应该”调和SRIDs来处理这个问题。 每个SRID(例如2913 = NZG2000)描述了一种转换关系。 每个SRID可用于映射到/从一个统一的球,这是你如何从一个到另一个获得。
- 直到你得到一个“同” SRID两个值,多为.STxXX函数将返回NULL(你可能在这两种情况下默认为0)
- 如果他们是不一样的,但是你假装他们是,你可能对边缘情况的错误。
- 如果你花一些“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