环境: sql2008, 数据5万左右(场所地址带经纬度)
需求: 在地图上画出多边形,取得多边形数据(各点经纬度), 从数据库中查询出该多边形区域内的所有场所。
场所表设计:
IF OBJECT_ID ( 'dbo.SpatialTable', 'U' ) IS NOT NULL DROP TABLE dbo.SpatialTable; GO CREATE TABLE SpatialTable ( id int IDENTITY (1,1), Lng VARCHAR(12),Lat VARCHAR(12) , geom geometry, adress varchar ); GO
数据示例:
INSERT INTO SpatialTable (Lng,lat)VALUES ('116.307672','40.055678'); INSERT INTO SpatialTable (Lng,lat)VALUES ('116.307672','40.054546');
存储过程:
/****** Object: StoredProcedure [dbo].[aa] Script Date: 05/26/2015 09:55:31 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO --------------------------------- --用途:根据多边线数据查询区域内的场所 --说明: -- 2015-05-26 ------------------------------------ create PROCEDURE [dbo].SP_QueryLatLng @geometry VARCHAR(500) --传入值(多边形geometry类型), 如:POLYGON ((116.304834 40.05543, 116.305373 40.051923, 116.312631 40.054712, 116.309577 40.057749, 116.304834 40.05543)) AS DECLARE @g GEOMETRY SET @g = geometry::STGeomFromText(@geometry, 0) --转换 DECLARE @n INT DECLARE @rowcount INT DECLARE @id INT DECLARE @h GEOMETRY DECLARE @lng VARCHAR(12) --经度 DECLARE @lat VARCHAR(12) --纬度 IF OBJECT_ID('Tempdb..#temp') IS NOT NULL DROP TABLE #temp IF OBJECT_ID('Tempdb..#Resultset') IS NOT NULL DROP TABLE #temp CREATE TABLE #temp --根据这个临时表进行遍历 ( id INT IDENTITY(1, 1) , lng VARCHAR(12) , lat VARCHAR(12) , adress VARCHAR(200) ) CREATE TABLE #Resultset --输出的临时表结果集 ( id INT , lng VARCHAR(12) , lat VARCHAR(12) , adress VARCHAR(200) ) INSERT INTO #temp SELECT Lng , Lat , adress FROM SpatialTable --将符合条件的场所信息插入临时表准备遍历 SET @rowcount = @@rowcount SET @n = 1 WHILE @n < @rowcount BEGIN SELECT @lng = lng , @lat = lat FROM #temp WHERE id = @n; SET @h = geometry::STGeomFromText('POINT(' + @lng + ' ' + @lat + ')', 0); IF @g.STContains(@h) = 1 BEGIN INSERT INTO #Resultset ( id, lng, lat, adress ) SELECT * FROM #temp WHERE id = @n END SET @n = @n + 1 END SELECT * FROM #Resultset
调用存储过程示例:
EXEC dbo.SP_QueryLatLng @geometry = 'POLYGON ((116.304834 40.05543, 116.305373 40.051923, 116.312631 40.054712, 116.309577 40.057749, 116.304834 40.05543))'
我刚学数据库不久,写的存储过程,用了两个临时表(没有用游标),数据现在是5万左右,还在不断增加, 项目经理说可以用嵌套查询, 循环都不需要用, 我没写出来(报语法错误)。有没有做过数据库几何图形数据查询的大神, 帮忙看下.
我表结构示例数据都给了, 能直接在sql中运行, 希望大神帮忙看看, 哪些不足。
这个难应该是难在怎么判断点在多边形内。如果是矩形到是很容易啊
select * from tb where x between x1 and x2 and y between y1 and y2.
这个主要是算法。你先得把点在多边形内的算法整出来的。我感觉还是不好整。多边形还分凸多边形,凹多边形,特别是凹多边形这个难判断。
sql 08以上已经支持空间查询了, 这个算法不劳费心, 主要是我写的那个过程, 能否简化
@奋奋奋: 按你有算法支持那就很简单了。一句查询就可以了啊。
select * from spatialtable where @g.STContains(geometry::STGeomFromText('POINT('+lng+' '+lat+')',0))=1
@gw2010:
3Q,
select * from spatialtable where geometry::STGeomFromText('POLYGON ((116.304834 40.05543, 116.305373 40.051923, 116.312631 40.054712, 116.309577 40.057749, 116.304834 40.05543))', 0).STContains(geometry::STGeomFromText('POINT('+lng+' '+lat+')',0))=1
.STContains(这个位置不知道能否嵌套查询不)。 如果是这样就可以省去自己写遍历了。
mark