[英]SQL Server 2008 Spatial: find a point in polygon
I am using SQL Server 2008 spatial data types.我正在使用 SQL Server 2008 空间数据类型。 I have a table with all States (as polygons) as data type GEOMETRY.
我有一个表,其中包含所有状态(作为多边形)作为数据类型 GEOMETRY。 Now I want to check if a point's coordinates (latitudes, longitudes) as data type GEOGRAPHY, is inside that State or not.
现在我想检查一个点的坐标(纬度、经度)作为数据类型 GEOGRAPHY 是否在该州内。
I could not find any example using the new spatial data types.我找不到任何使用新空间数据类型的示例。 Currently, I have a workaround which was implemented many years ago, but it has some drawbacks.
目前,我有一个多年前实施的解决方法,但它有一些缺点。
I've both SQL Server 2008 and 2012. If the new version has some enhancements, I can start working in it too.我有 SQL Server 2008 和 2012。如果新版本有一些改进,我也可以开始使用它。
Thanks.谢谢。
UPDATE 1:更新1:
I am adding a code sample for a bit more clarity.我正在添加一个代码示例,以便更加清晰。
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
I think the geography method STIntersects() will do what you want:我认为地理方法 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)
If you cannot change the data-type for the stored polygons to GEOGRAPHY
then you can convert the input latitude and longitude to GEOMETRY
and use the STContains
or STIntersects
against the converted value.如果您无法将存储多边形的数据类型更改为
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);
Going the opposite direction -- trying to convert the GEOMETRY
polygons to GEOGRPAHY
-- is error-prone and likely to fail from my experience.相反的方向——试图将
GEOMETRY
多边形转换为GEOGRPAHY
很容易出错,并且根据我的经验可能会失败。
And note that if you try to create the GEOMETRY
point directly from the latitude and longitude values then the STContains
(or STIntersects
) won't work (ie won't give a match when they should).请注意,如果您尝试直接从纬度和经度值创建
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);
Here's an example I used in SRID 2193. All roads within a 3km radius of a given point, and inside a specific school zone这是我在 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
In case you have table (example: SubsriberGeo) where one of the columns (example: Location) has geography Points as values and you'd like to find all Points from that table that are inside polygon here is a way to do it:如果您有表(例如: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.