技术开发 频道

SQL Server 2008:新位置感知数据类型

  在地图上绘制点

  现在你已经知道如何从数据库读取一个点的值,接下来可以做更有趣的事情了,如在地图上绘制该点。在web上,有许多地图服务提供商,如谷歌,微软等。

  如果你采用微软的方案,必应地图提供了一个选择,当必应显示你的地图时,它使用类似下面的URL创建图像:

 http://www.bing.com/maps/default.aspx?v=2&FORM=LMLTCC&cp=37.839179~-119.541904&style=r&lvl=8

  在这个例子中,查询字符串cp后指定了经纬度值-119.5和37.8,有了这个信息,你可以使用下面的代码构造URL: 

int id = int.Parse(pointIdTextBox.Text);

  SqlGeography geog
= ReadPointFromDatabase(id);

  string bingMapsFormat
=

  "http:
//www.bing.com/maps/default.aspx?" +

  "v
=2&FORM=LMLTCC&cp={0}~{1}&style=r&lvl=8";

  string bingMapsUrl
= string.Format(

  bingMapsFormat, geog.Lat, geog.
Long);

  webBrowser1.Navigate(bingMapsUrl);

  MessageBox.Show("Point "
+ geog.Lat +

  ", "
+ geog.Long + " plotted!");

  这里的ReadPointFromDatabase方法可以从数据库中根据id检索SqlGeography对象,接下来的代码构造了必要的URL值,然后使用一个简单的WinForms WebBrowser组件显示包含了地图的网页,如图4所示。

  当然,更好的实现应该使用真实的地图控件,并在地图顶部增加地图操作按钮,但对于许多简单的应用,能够以某点为中心显示地图已经足够了。

  多边形计算实例

  到目前为止,我们已经讨论了geometry和geography类型,但仅讨论了单点情况,虽然二维空间的点非常有用,但如果能存储一条线,或一个多边形在数据库中不是更有用吗?好消息是你可以做到!

  还是以SqlGeometry为例,使用静态Point方法,你可以将一个点存储到对象中,但同一个类中也包含创建线和多边形的方法,如图5所示。因此每个SqlGeometry对象(或一个SqlGeography对象)可以存储一到多个点,你可以使用这些点形成任何你想要的对象。

  图 5 SqlGeometry类的方法

  例如,假设你要存储一条直线,这需要两个点:起点和终点,你可以使用两个字段来分别存储起点和终点,但SQL Server 2008允许你在一个geometry数据类型中存储这两个点,你可能会开始思考在一个表字段中存储一到多个点会有什么好处,其中一个原因就是存储效率,另一个就是计算,是的,SQL Server和对应的.Net对象类型允许你执行计算。

  你可能想用存储在数据库中的多个点组成一个多边形,如一个正方形,然后你可能需要确定另一个点是否也在这个正方形范围内,解决起来也很简单,可以使用C#代码实现,也可以直接通过SQL Server的功能实现。

  除了判断点是否存在等简单应用外,SQL Server也支持更多的高级特性,例如,你可以计算区域,找出对象的中心位置,检查多边形是否闭合,或者找出多边形上的点数。这为你提供了无限可能,特别要提出的是你既可以在代码中使用SqlGeometry和SqlGeography对象实现,又可以直接在存储过程的函数中实现。

  我们还是以正方形为例,我们的目标是监测某个点是否在该正方形范围内,首先使用直角坐标系((0,0), (0,10), (10,10), (10,0))定义一个正方形,然后确定点(5,5)是否在该正方形内,如图6所示,你如何使用SqlGeometry .Net类实现这个测试呢?

  图 6 这个点在正方形内吗?

  首先你需要定义你的正方形,在.Net中你可以使用StringBuilder组件,或者使用SqlGeometryBuilder对象构建几何对象,下面是使用这个类的例子: 

SqlGeometryBuilder builder = new SqlGeometryBuilder();

  builder.SetSrid(
0);

  builder.BeginGeometry(OpenGisGeometryType.Polygon);

  builder.BeginFigure(
0, 0);

  builder.AddLine(
0, 10);

  builder.AddLine(
10, 10);

  builder.AddLine(
10, 0);

  builder.AddLine(
0,0);

  builder.EndFigure();

  builder.EndGeometry();

  在这里,SqlGeometryBuilder(Microsoft.SqlServer.Types命名空间的一部分)使用四个点构造了一个正方形,但因为你可以在多个不同的对象中存储不受数量限制的点,你必须在开始和结束时指定一个数字,在此之前,你需要指定空间参考id(SRID),以及你使用BeginGeometry方法创建的对象类型,虽然SRID的值可以忽略,但SRID必须指定,因此0是非常好的选择。

  现在已经定义好正方形,现在该检查那个点是否在正方形内了,这可以使用SqlGeometry对象的STContains方法实现,但首先需要创建一个几何对象的实例,可以使用ConstructedGeometry属性完成,如: 

SqlGeometry square = builder.ConstructedGeometry;

  SqlGeometry point
= SqlGeometry.Point(5, 5, 0);

  SqlBoolean
contains = square.STContains(point);

  
if (contains.Value)

  {

  MessageBox.Show("
Contains point!");

  }

  你可能已猜到,上面的代码会显示一条消息,显示点(5,5)在该正方形内,实际上这一点是正方形的中心点。

  小结

  SQL Server 2008支持许多有趣的新特性,其中一个就是支持空间数据,通过阅读本文,你应该已经了解了geometry和geography类型,并看到了如何在C#应用程序中使用这些类型,如如何读写数据点,以及如何利用经纬度值在地图上显示一个点。

  虽然使用浮点字段也可以存储经纬度值,但SQL Server 2008让这一切都变得更加简单了,表中的每个geometry或geography数据类型都可以存储一到多个点,因此可以形成任意复杂的多边形,这种支持让你可以在数据库表中只创建一个字段,就可以存储多个点的数据,如果利用浮点字段是很难办到的。

  新的空间数据类型另一个好处是你可以利用这些值进行计算,SQL Server 2008为各种不同的计算提供了良好的支持,相信下一个SQL Server版本会这方面进行增强。

0
相关文章