脱谷为糠,其髓斯存,神之渭也。山骞不崩,唯百为镇,骨之谓也。 一身精神,具乎两目;一身骨相,具乎面部。
   ::  ::  :: 联系 :: 订阅 订阅 :: 管理

sqlserver2k5中利用CLR-UDF实现空间查询

Posted on 2005-12-05 22:16 microsoft001 阅读(520) 评论(5) 编辑 收藏
今天晚上比较闲,写点东西。我已经在实际项目中使用sqlserver2005来构建空间数据库并完成空间查询的功能。


这里仅给出一个利用sqlserver2k5中CLR UDF实现空间查询的简单示例,具体算法实现不详表。

1。在VS2005中创建一个SQL Server Project。
2。新增一个User-Defined Function。编写如下函数PointQuery
[SqlFunction]
public static SqlBoolean PointQuery(SqlDouble x, SqlDouble y, SqlDouble tolerance, SqlBytes binary)
{
//这里进行空间计算,返回是否命中的布尔值
}

参数x, y为点坐标,tolerance为容限,binary为二进制空间数据。
在函数体中把binary还原为geometry对象,与点对象进行几何计算后返回一个布值表示是否命中。
(事实上可看做一个圆查询)
3。编译后deploy这个assembly到sqlserver2k5上。


下面给出一个在空间表中实现空间查询的例子:
例如有个空间表world_contry的结构like this

column name data type
id int
minx float
miny float
maxx float
maxy float
property1  
...  
propertyN  
geometry image

T-SQL实现这个空间表的点选查询,小括号中为实际数据
SELECT * FROM 
(
--这里先进行一次MBR过滤,得到一个表A
SELECT * 
FROM [world_contry]
WHERE
[minx]<(MBR.maxx)
[miny]<(MBR.maxy)
[maxx]>(MBR.minx)
[maxy]>(MBR.miny)
) A
WHERE
[dbo].[PointQuery]  --CLR UDF
(
(point.x),
(point.y),
(point.tolerance)
[A].[geometry]
)
=1     

如果做属性关联则在其后追加,例如

AND
[name]
LIKE '%国%'


这是一个点查询的简单例子,其他诸如多边形,折线等查询以此类推。

简单测试了一下,我的PC是P4 2.8G, 1G RAM。
在一个面类型的世界国家表(未做数据库方面的任何优化)中,将其记录反复复制至8万条
在这个单表中随意加入一个点数据,执行一个点查询后命中48条记录,完成时间在600ms左右。
这48条记录就是这个点查询对象查询出来的feature。




(评论功能已被博主禁用)