【IT168 技术文档】
使用 Microsoft SQL Server 2008 空间数据类型与Virtual Earth的集成
目录
准备工作 1
练习 1: 以GML 格式返回空间数据 3
练习 2: 创建一个GeoRSS 订阅源 6
练习 3: 使用Virtual Earth VEMap 控件 10
准备工作
预计完成本实验所需的时间
60 分钟
目标
在完成本实验后,您将可以:
创建存储过程,以GML格式返回空间数据;
创建一个HTPP的 Handler返回一个空间数据的GeoRSS订阅源;
创建一个Web页面,将Microsoft SQL Server 2008 的空间数据类型与Microsoft Virtual Earth™ VEMap 控件进行集成。
先决条件
在完成本实验前,您必须:
具有编写Transact-SQL 脚本与使用SQL Server Management Studio的相关经验。
熟悉SQL Server 2008当中的空间数据类型。
具有使用Microsoft Visual Studio开发Microsoft ASP.NET 应用程序的相关经验。
具有使用Microsoft JScript进行客户端Web开发的相关经验。
实验场景
Adventure Works Cycles 为遍布美国的许多商店提供自行车产品。您被命令开发一个Web页面,使得客户可以使用这个页面来定位所有销售Adventure Works产品的商店。另外,用户必须能够找到一个特定地点100公里范围内的所有商店。有关商店位置的地里信息数据被存储在一个SQL Server 2008 数据库中,而且您必须将这些搜索结果显示在页面中的一个Virtual Earth 地图当中。
虚拟机环境
从开始菜单或桌面上启用Microsoft Virtual PC 。如果Virtual PC 控制台没有启用,请查看系统托盘,然后双击系统托盘当中的Microsoft Virtual PC 。
选择Sql08 然后点击Start。
在虚拟机运行起来后,可以通过点击右Alt+Del 来向虚拟机发送一个Ctrl+Alt+Del 命令。
在登录窗口中,输入以下信息:
User name: administrator
Password: password01!
注意: 本实验要求虚拟机可以连接到Internet。
练习 1: 以GML 格式返回空间数据
在本练习中,您将创建一个存储过程,并以地理标记语言(GML)格式返回空间数据。GML是由Open Geospatial Consortium (OGC) 为在不同应用程序与系统之间交换空间数据信息所定义的标准。SQL Server支持的空间数据类型支持作为空间数据类型实例的源,并支持作为空间数据传递的格式。这种对于GML的支持,使得在SQL Server和其它地理信息系统(如Microsoft Virtual Earth)之间进行数据交换非常容易。
创建一个包含空间数据的数据库
启动SQL Server Management Studio。当出现提示时,使用Windows Authentication连接到 (local) 数据库实例。
在C:\SQLHOLs\Spatial and VE\Starter 目录中,打开Create DB.sql 查询文件。
查看这个脚本当中的Transact-SQL 代码,注意,这个脚本执行了下面一些任务:
删除并重新创建一个叫做StoreData的数据库。
创建一个叫做Stores 的数据表,包含一个类型为geography 名为StoreLocation的数据列。
在刚刚创建的StoreLocation 数据列上创建一个空间数据索引。
向Stores 表中插入一些数据行。每条记录都包含一个StoreLocation 值,它表示一个由经度和纬度坐标定义商店的地理位置。
点击Execute ,运行脚本。如果已经存在了StoreData 数据库,则可能会出现一些错误,忽略这些错误。
保持SQL Server Management Studio 打开,后面的步骤中要继续使用。
创建一个存储过程返回所有商店
点击 New Query 创建一个新的查询。如果出现提示,使用Windows Authentication连接到 (local) 数据库引擎。
在查询编辑器中输入下面的Transact-SQL 代码。
GO
CREATE PROCEDURE GetStoresGML
AS
-- Return the store location geography data as GML
SELECT StoreName,
StoreAddress + ', Tel:' + StorePhone AS ContactDetails,
StoreLocation.AsGml() As StoreGML
FROM Stores
GO
注意: 在这段代码当中,使用了geography 数据类型的AsGml 方法来以GML格式返回地理信息数据。
点击Execute 运行脚本。
在CREATE PROCEDURE 语句后面,添加下面的代码,测试存储过程。
EXECUTE GetStoresGML
选中刚刚输入的EXECUTE 语句,然后点击Execute 运行选中的代码。
在结果面板中,点击任意StoreGML 值,来在XML查看器中查看空间数据的GML 表示形式。
关闭XML查看器,然后返回查询编辑器中。
创建一个存储过程来返回指定位置附近的商店
在上面的过程中输入的EXECUTE 语句下面,添加下面的Transact-SQL 代码:
AS
-- Create a point geography instance based on the supplied location
DECLARE @SearchPoint geography
SET @SearchPoint = geography::Point(@Lat, @Long, 4326)
-- Create a polygon geography instance by adding a 100km buffer to the point
DECLARE @SearchArea geography
SET @SearchArea = @SearchPoint.STBuffer(100000)
--Return the search area and all store locations that intersect it
SELECT 'Search Area', '100 KM radius', @SearchArea.AsGml()
UNION ALL
SELECT StoreName,
StoreAddress + ', Tel:' + StorePhone AS ContactDetails,
StoreLocation.AsGml() As StoreGML
FROM Stores
WHERE StoreLocation.STIntersects(@SearchArea) = 1
GO
注意: 这段代码创建一个geography 实例,它包含了一个基于经度和纬度的地理坐标,这个坐标将作为参数传递到存储过程当中。它使用geography 数据类型的STBuffer方法来创建了一个geography多边形实例,用来表示一个以待搜索点为圆心100公里为半径的圆。最后,这段代码返回了一个geography实例的GML表示,它使用geography数据类型的STIntersects 方法,返回了所有与搜
索区域相交的商店位置。
选择刚刚创建的CREATE PROCEDURE 语句,然后点击Execute 运行选中的脚本。
在CREATE PROCEDURE 语句下面,添加下面的代码测试存储过程:
EXECUTE GetNearbyStoresGML '34.000000', '-118.000000'
选择刚刚添加的EXECUTE 语句,然后点击Execute 运行选中的代码。
在结果面板中,点击第一个XML值,在XML查看器中查看搜索区域的GML表示形式。
关闭XML查看器,返回查询编辑器。
将查询脚本保存为C:\SQLHOLs\Spatial and VE\Starter\StoredProcs.sql,,然后关闭SQL Server Management Studio。
练习 2: 创建一个GeoRSS 订阅源
在本练习中,您将在ASP.NET Web应用程序当中实现一个HTTP Handler,并用它来返回一个GeoRSS订阅源。GeoRSS 是一种包含地理信息数据的RSS订阅标准格式,它定义一个特定的格式,叫做GeoRSS GML,用来在订阅中包含GML格式的数据。客户端应用程序可以以普通的RSS源的方式来订阅GeoRSS源。而以GeoRSS格式返回的数据则可以被轻松的导入到Microsoft Virtual Earth VEMap控件当中。
实现一个HTTP Handler
启用 Microsoft Visual Studio 2008。
打开File 菜单,点击Open,点击Web Site,然后打开C:\SQLHOLs\Spatial and VE\Starter\StoreFinderSite Web 站点。
在Solution Explorer中,展开App_Code目录,然后双击GeoRSSHandler.vb 在代码编辑器中打开它。
注意: HTTP Handler 是一个代码模块,它可以处理到Web应用程序的HTTP 请求。通常,到一个Web应用程序的HTTP请求是由一些默认的ASP.NET 请求处理器所处理的,但是您可以为特定的扩展名创建自定义的处理器。这时,您将实现一个请求处理器,它将会返回.georss为扩展名为的处理结果。
查看现有的代码。用来处理请求的函数叫做ProcessRequest。注意,这段代码还没有完成,有些代码需要继续填充完整。
在Build the GeoRSS feed注释下面,添加下面代码开始构建由HTTP Handler返回的GeoRSS 源。
rssOutput.AppendLine("xmlns:georss='http://www.georss.org/georss'")
rssOutput.AppendLine("xmlns:gml='http://www.opengis.net/gml'>")
rssOutput.AppendLine("<title>Stores</title>")
rssOutput.AppendLine("<subtitle>Store Locations</subtitle>")
rssOutput.AppendLine("<link href='http://localhost/storefindersite/'/>")
rssOutput.AppendLine("<updated>" + System.DateTime.Now + "</updated>")
rssOutput.AppendLine("<author>")
rssOutput.AppendLine("<name>SQL Server</name>")
rssOutput.AppendLine("</author>")
在Open a connection to the database注释下面,添加下面的代码。
sqlConn.Open()
在Use the GetStoresGML stored proc to get all stores by default注释下面,添加下面的代码。
spName = "GetStoresGML"
注意: 默认情况下, 到这个HTTP Handler的请求处理将会调用GetStoresGML 存储过程,并将返回包所有商店的GeoRSS 源。
在 If a searchFrom parameter is provided, use GetNearbyStores and add the provided lat and lon coordinates as parameters注释下面,添加下面的代码。
If Not searchFrom Is Nothing Then
spName = "GetNearbyStoresGML"
Dim latLong() As String = Split(searchFrom, ",", 2)
cmd.Parameters.Add(New SqlParameter("Lat", latLong(0)))
cmd.Parameters.Add(New SqlParameter("Long", latLong(1)))
End If
注意: 如果请求包含一个参数,叫做SearchFrom(它将会包含一个用逗号分隔的经度和纬度的对),处理器将会从参数中提取其中的经度和纬度值,并使用GetNearbyStoresGML 存储过程返回一个GeoRSS源,它将包含请求搜索点100公里附近的商店。
在Specify the stored procedure name as the command text注释下面,添加下面的代码。
cmd.CommandText = spName
在Create an <entry> element for this row注释下面,添加下面的代码,来为存储过程返回的结果的每行数据创建一个<entry> 标签。
rssOutput.AppendLine("<entry>")
在Use columns 0 and 1 for the title and description注释下面,添加下面的代码来为存储过程返回的数据创建<title> 和<description> 元素。
rssOutput.AppendLine(String.Format("<description>{0}</description>", _
geomRdr.GetValue(1)))
在Add a <georss:where> element注释下面,添加下面的代码来为这个GML数据节点创建一个<where> 元素。
rssOutput.AppendLine("<georss:where>")
在Get the geography instance GML from column 2注释下面,添加下面的代码,来从存储过程结果中获取GML数据。
gml = geomRdr.GetValue(2).ToString()
在Add the <gml:> elements to the output XML注释下面,添加下面的代码,来向GeoRSS 源添加GML数据。
rssOutput.AppendLine(gml)
在Close <georss:where> and <entry> elements注释下面,添加下面的代码。
rssOutput.AppendLine("</georss:where>")
rssOutput.AppendLine("</entry>")
在Close the <feed> document and send it as the response注释下面,添加下面的代码来完成GeoRSS 源,并将它发送回请求方。
rssOutput.Append("</feed>")
context.Response.Write(rssOutput.ToString())
保存 GeoRSSHandler.vb。
注册HTTP Handler
在 Solution Explorer中,双击web.config ,在编辑器中打开它。
在<httpHandlers> 节点中,在Register the GeoRSSHandler for .georss requests注释下面,添加下面的XML代码。
<add verb="*" path="*.georss" type="GeoRSSHandler" validate="false"/>
注意: 您必须注册这个HTTP Handlers,用来指定某个特定的文件扩展名,从而让Internet Information Services 可以将这种特定的请求发送给适当的处理器来处理这种文件。
保存 web.config。
添加HTTP Handler
在 Solution Explorer中,点击位于树状图根结点的Web 站点项目文件然后点击F4 查看它的属性。
注意Port number 属性。
在Website 菜单中,点击Start Options。
选择Start URL,输入下面的URL (将<port> 修改为Web站点的Port number 属性),然后点击OK。
http://localhost:<port>/storefindersite/test.georss
在Debug 菜单中,点击Start Debugging。
当 Microsoft Internet Explorer 打开后,查看包含商店名称的RSS源的页面。
在Internet Explorer中,在Web 页面中,右键单击任意位置,然后点击View Source 在Notepad中查看页面的源代码。注意,页面的源是由HTTP Handler所生成的GeoRSS 源。
关闭 Notepad。
在 Internet Explorer中,在地址栏(Address bar)中,在上面的网址后面输入下面的查询字符串,点击键盘上的回车键:
?SearchFrom=34.000000,-118.000000
确认返回的GeoRSS源中包含了一个搜索区域,以及其中的任意商店。
关闭Internet Explorer。
保持Visual Studio 打开,以备下个练习使用。
练习 3: 使用Virtual Earth VEMap 控件
在本练习中,您将向页面中添加一些客户端代码,来将从上面的GeoRSS源中获得的地理信息数据显示在Virtual Earth VEMap 控件当中。VEMap 控件是一个客户端控件,您可以使用JavaScript 代码来对它进行编程。使用客户端代码来编辑VEMap控件的优势在于,您可以简单的构建一个mash-up Web 应用程序,它可以与来自于Internet上多种不同数据源的数据进行集成。
添加代码以显示地图
在 Solution Explorer中,双击Default.aspx ,在设计器中打开它进行编辑。
如果它已经被打开,点击设计器左下方的Source 选项卡,从而查看页面的HTML源代码。
在add a reference to the Virtual Earth map control注释下方,添加下面的HTML代码。
</script>
在GetMap 函数当中,在Display the map control注释下方,添加下面的代码。
map.LoadMap();
保存 Default.aspx。
在Solution Explorer中,右击Default.aspx,然后点击Set as Start Page。
在Debug 菜单中,点击Start Debugging。
当Internet Explorer 打开后,确认地图已经被显示出来。
使用地图中内置的控件来进行移动浏览,放大,缩小,以及更改视图。
关闭Internet Explorer。
添加代码并在地图中显示所有商店
在 Default.aspx中,在ShowAllStores 函数中,在Import GeoRSS feed of store data, and call onAllStoreLoad function when the data is loaded注释下方,添加下面的代码。
"./Stores.georss");
map.ImportShapeLayerData(veLayerSpec, onAllStoreLoad, true);
注意: 这段代码将会把Stores.georss页面的请求结果发送到Web页面当中。这个请求将会使用HTTP Handler 进行处理,它使用前面练习中输入的代码来实现,并返回包含所有商店的GeoRSS源。然后,该代码将GeoRSS数据加载为一个新的层,并显示在地图控件当中,并且当数据被成功加载到地图当中后,调用onAllStoreLoad 函数。
在onAllStoreLoad 函数当中,在Count the shapes returned 注释下面,添加下面的代码。
document.getElementById("Info").innerHTML =
'There are ' + storecount + ' stores.';
保存 Default.aspx。
在Debug 菜单中,点击Start Debugging。
在Internet Explorer 打开后,点击Show All Stores ,然后确认所有的商店都被显示在地图中,并用一些“别针”来显示。
关闭Internet Explorer。
添加代码并在地图中显示特定位置附近的商店
在 Default.aspx中,在ShowNearbyStores 函数中,在Use the VEMap.Find method to find the location entered by the user and call the onFind function to process the results注释下方,添加下面的代码。
document.getElementById("SearchLocation").value,
null, null,null, 1, false, false, false, true,
onFind)
注意: 这段代码使用Virtual Earth 来查找一个基于用户输入的文本查找的特定位置。当一个或多个位置被查找到后,代码会调用OnFind 函数。
在onFind 函数当中,在define the search point as the latitude and longitude of the first place in the results注释下面,添加下面的代码。
注意: 这段代码处理结果中发现的第一个位置,并将这个用逗号分隔的字符串提取出经度和纬度值。
在onFind 函数当中,在Import GeoRSS feed of stores near the search point, and call onNearbyStoresLoad function when the data is loaded注释下面,添加下面的代码。
"./Stores.georss?SearchFrom=" + SearchFromPoint);
map.ImportShapeLayerData(veLayerSpec, onNearbyStoresLoad, true);
注意: 这段代码将发送请求到Stores.georss 页面,并在请求中添加SearchFrom 参数,这个参数中包含了搜索区域的经度和纬度值。这个请求由上面我们实现的HTTP Handler 进行处理,并返回包含搜索区域及其中所有商店位置的GeoRSS源。这段代码的后面将GeoRSS数据加载到到地图控件中,显示为一个新的层,然后在加载完成后调用onNearbyStoresLoad 函数。
在 onNearbyStoresLoad 函数中,在Don't count or show the first shape (the search location)注释下面,添加下面的代码。
feed.GetShapeByIndex(0).HideIcon();
document.getElementById("Info").innerHTML =
'There are ' + storecount + ' stores.';
在 onNearbyStoresLoad 函数中,在Show the info for the search area when the results first load注释下面,添加下面的代码。
注意: 这段代码显示了搜索区域的信息提示气泡。
保存 Default.aspx。
在Debug 菜单中,点击Start Debugging。
在Internet Explorer 打开后,输入Seattle ,然后点击Show Stores Near ,然后确认所有搜索出来的商店将会在地图上显示为一些别针,并会使用一个圆形显示搜索区域。
重复搜索过程,输入San Francisco 和90210。
关闭Internet Explorer。
关闭Visual Studio。
关闭Virtual PC 并不要保存任何更改。