[英]SQL Server 2008 Spatial: find a point in polygon
我正在使用 SQL Server 2008 空間數據類型。 我有一個表,其中包含所有狀態(作為多邊形)作為數據類型 GEOMETRY。 現在我想檢查一個點的坐標(緯度、經度)作為數據類型 GEOGRAPHY 是否在該州內。
我找不到任何使用新空間數據類型的示例。 目前,我有一個多年前實施的解決方法,但它有一些缺點。
我有 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
我認為地理方法 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)
如果您無法將存儲多邊形的數據類型更改為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
)將不起作用(即,在應該匹配時不會提供匹配項)。
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);
這是我在 SRID 2193 中使用的示例。 給定點半徑 3 公里內和特定學區內的所有道路
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
如果您有表(例如: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;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.