技术开发 频道

SQLServer2008空间数据与Virtual Earth

  【IT168 技术文档】摘要:通过这个动手实验室,您可以了解到:创建返回 GML 格式的空间数据的存储过程;创建 HTTP 处理程序以返回空间数据的 GeoRSS 订阅源;创建将 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 向美国各地的大量商店供给自行车。该公司请您开发一个网页,从中可以找到所有销售 Adventure Works 产品的商店。此外,必须允许用户能在指定位置处方圆 100 km 范围内查找商店。商店位置的地理数据要存储在 SQL Server 2008 数据库中,您必须将搜索操作的结果显示在该网页中的 Virtual Earth 地图

  实验室操作脚本

  1. 检索 GML 格式的空间数据

  在此练习中,您将创建返回以地理标记语言 (GML) 表示的空间数据的存储过程。GML 是一个由开放地理空间联盟 (OGC) 定义的标准,用于在应用程序和系统之间交换地理数据。SQL Server 中的空间数据类型支持 GML 作为空间数据类型实例的数据源,也支持 GML 作为表示空间数据值的格式。借助对 GML 的这种支持,可以轻松地在 SQL Server 中的空间数据和其他地理空间系统(如 Microsoft Virtual Earth)之间进行集成。

  注意:您可以从 C:\SQLHOLS\Spatial and VE\Solution\StoredProcs.sql 复制此练习中使用的代码

  创建包含空间数据的数据库

  1. 从开始菜单中的 Microsoft SQL Server 2008 程序组中启动 SQL Server Management Studio。收到提示时,使用 Windows 身份验证连接到数据库引擎的 (local) 实例。

  2. 打开 C:\SQLHOLs\Spatial and VE\Starter 文件夹中的 Create DB.sql 查询文件。

  3. 检查此脚本中的 Transact-SQL 代码。请注意,此代码执行下列任务:

  • 删除名为 StoreData的数据库并重新创建它。

  • 创建一个名为 Stores 表,其中包含名为 StoreLocation 的 geography列。

  • 在 StoreLocation 列上创建一个空间索引。

  • 在 Stores 表中插入大量记录。每个记录都包含一个由纬度和经度坐标定义的表示地理点的 StoreLocation 值。

  4. 单击执行运行此脚本。如果尚不存在 StoreData 数据库,请忽略任何有关无法删除该数据库的错误。

  5. 保持 SQL Server Management Studio 打开,下一个过程还要使用此程序。

  创建检索所有商店的存储过程

  1. 单击新建查询创建新查询。如果收到提示,请使用 Windows 身份验证连接到 (local) 数据库引擎实例。

  2. 在查询编辑器中键入以下 Transact-SQL 代码。

  USE StoreData

  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

  注意:此代码使用地理数据类型的 AsGml 方法返回 GML 格式的空间数据值。

  3. 单击执行运行此脚本。

  4. 在 CREATE PROCEDURE 语句下,添加下面的代码以测试存储过程。

  EXECUTE GetStoresGML

  5. 选择刚刚添加的 EXECUTE 语句,然后单击执行运行所选的代码。

  6. 在结果窗格中,单击任意 StoreGML 值在 XML 查看器中查看空间数据的 GML 表示形式。

  7. 关闭 XML 查看器并返回到查询编辑器。

  创建查找指定位置附近的商店的存储过程

  1. 在您在上一过程中添加的 EXECUTE 语句下,添加以下 Transact-SQL 代码。

  CREATE PROCEDURE GetNearbyStoresGML @Lat nvarchar(10), @Long nvarchar(10)

  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 方法创建表示搜索点周围方圆 100km 范围内的多边形 geography 实例。最后,此代码返回定义搜索区域的 geography 实例的 GML 表示形式以及搜索区域中的所有商店,通过使用 geography 数据类型的 STIntersects 方法可以找到这些商店。

  2. 选择刚刚添加的 CREATE PROCEDURE 语句,然后单击执行运行所选的代码。

  3. 在 CREATE PROCEDURE 语句下,添加下面的代码以测试存储过程。

  EXECUTE GetNearbyStoresGML '34.000000', '-118.000000'

  4. 选择刚刚添加的 EXECUTE 语句,然后单击执行运行所选的代码。

  5. 在结果窗格中,单击第一个 XML 值,以在 XML 查看器中查看搜索区域的 GML 表示形式。

  6. 关闭 XML 查看器并返回到查询编辑器。

  7. 将查询脚本文件另存为 C:\SQLHOLs\Spatial and VE\Starter\StoredProcs.sql,然后关闭 SQL Server Management Studio。

  2. 创建GeoRSS 订阅源

  在此练习中,您将在 ASP.NET Web 应用程序中实现 HTTP 处理程序以返回 GeoRSS 订阅源。GeoRSS 是在 RSS 订阅源中包含地理空间数据时所用的一个标准,它定义了一种名为 GeoRSS GML 的特定格式,用来在订阅源中包含 GML 格式的数据。客户端应用程序可以订阅 GeoRSS 订阅源,订阅方式与订阅常规 RSS 订阅源相同。可以轻松地将 GeoRSS 格式的数据导入 Microsoft Virtual Earth VEMap 控件中。

  注意:您可以从 C:\SQLHOLS\Spatial and VE\Solution\StoreFinderSite 中的完成的网站页面复制此练习中所用的代码。

  实现 HTTP 处理程序

  1. 启动 Microsoft Visual Studio 2008。

  2. 在文件菜单中,单击打开网站,然后打开 C:\SQLHOLs\Spatial and VE\Starter\StoreFinderSite 网站。

  3. 在解决方案资源管理器中,展开 App_Code,然后双击 GeoRSSHandler.vb 在代码编辑器中打开它。

  注意:HTTP 处理程序是一个代码模块,用于处理对 Web 应用程序的 HTTP 请求。通常由默认 ASP.NET 请求处理程序处理对 ASP.NET Web 应用程序的请求,但是您可以针对特定文件扩展名创建自定义处理程序。在本例中,您将实现一个将用于处理扩展名为 .georss 的文件的请求的处理程序。

  4. 检查现有的代码。处理传入请求的过程名为 ProcessRequest。请注意,此过程不完整,包含大量必须添加代码的注释。

  5. 在注释 Build the GeoRSS feed下,添加以下代码,以开始构建将由 HTTP 处理程序返回的 GeoRSS 订阅源。

rssOutput.AppendLine("<feed xmlns='http://www.w3.org/2005/Atom'")
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>")

  6. 在注释 Open a connection to the database下,添加以下代码。

  sqlConn.Open()

  7. 在注释 Use the GetStoresGML stored proc to get all stores by default下,添加以下代码。

  spName = "GetStoresGML"

  注意:默认情况下,对此 HTTP 处理程序的请求将调用 GetStoresGML 存储过程,并返回包含所有商店的 GeoRSS 订阅源。

  8. 在注释If a searchFrom parameter is provided, use GetNearbyStores and add the provided lat and lon coordinates as parameters下,添加以下代码。

  Dim searchFrom As String = context.Request.QueryString("SearchFrom")

  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 km 范围内的商店。

  9. 在注释 Specify the stored procedure name as the command text(将存储过程名称指定为命令文本)下,添加以下代码。

  cmd.CommandText = spName

  10. 在注释 Create an element for this row下,添加以下代码来为存储过程的结果中的每一行都创建一个<entry>标记。

  rssOutput.AppendLine("<entry>")

  11. 在注释 Use columns 0 and 1 for the title and description下,添加以下代码以根据存储过程返回的数据创建<title>元素和<description>元素。

rssOutput.AppendLine(String.Format("<title>{0}</title>", geomRdr.GetValue(0)))

rssOutput.AppendLine(String.Format("<description>{0}</description>", _

   geomRdr.GetValue(1)))

  12. 在注释 Add a<georss:where> element下,添加以下代码来为此条目创建<where> 元素。

  rssOutput.AppendLine("<georss:where>")

  13. 在注释 Get the geography instance GML from column 2下,添加以下代码,以从存储过程结果中检索 GML 数据。

  gml = geomRdr.GetValue(2).ToString()

  14. 在注释 Add the <gml:>elements to the output XML下,添加以下代码以向 GeoRSS 订阅源添加 GML 数据。

  rssOutput.AppendLine(gml)

  15. 在注释 Close <georss:where>and <entry>elements下,添加以下代码。

  rssOutput.AppendLine("</georss:where>")

  rssOutput.AppendLine("</entry>")

  16. 在注释 Close the<feed> document and send it as the response下,添加以下代码以完成 GeoRSS 订阅源并将其发送给请求人。

  rssOutput.Append("</feed>")

  context.Response.Write(rssOutput.ToString())

  17. 保存 GeoRSSHandler.vb。

  注册HTTP处理程序

  1. 在解决方案资源管理器中,双击 web.config 在编辑器中打开它。

  2. 在<httpHandlers> 部分中,在注释 Register the GeoRSSHandler for .georss requests下,添加以下 XML。

<add verb="*" path="*.georss" type="GeoRSSHandler" validate="false"/>

  注意:您必须为特定文件扩展名注册 HTTP 处理程序,以便 Internet Information Services 将针对这些文件的请求转发到正确的处理程序。

  3. 保存 web.config。

  测试 HTTP 处理程序

  1. 在解决方案资源管理器中,单击位于树的根目录下的网站项目文件,然后按 F4 查看其属性。

  2. 请注意观察端口号属性。

  3. 在网站菜单上,单击启动选项。

  4. 选择启动 URL,输入以下 URL(将 port 替换为网站的端口号属性的值),然后单击确定。

  http://localhost:/storefindersite/test.georss

  5. 在调试菜单上,单击开始执行(不调试)。

  6. 当 Microsoft Internet Explorer ® 打开时,查看包含商店名称的 RSS 订阅源的页面。

  7. 在 Internet Explorer 中,右键单击该网页的任意位置,然后单击查看源文件以在记事本中打开该页的源文件。请注意,该页的源是您前面创建的 HTTP 处理程序生成的 GeoRSS 订阅源。

  8. 关闭记事本。

  9. 在 Internet Explorer 中的地址栏中,将以下查询字符串附加到 URL 后,然后按 Enter。

  ?SearchFrom=34.000000,-118.000000

  10. 验证生成的 GeoRSS 订阅源包含搜索区域及其中的所有商店。

  11. 关闭 Internet Explorer。

  12. 保持 Visual Studio 打开,下一个练习还要使用此程序。

  3. 使用 Virtual Earth VEMap 控件

  在此练习中,您将向一个网页添加客户端代码,以在Virtual Earth VEMap 控件中显示从GeoRSS 订阅源检索到的空间数据。VEMap 控件是可以使用 JavaScript 代码编程的客户端控件。使用客户端代码对 VEMap 控件进行编程的好处是您可以轻松构建集成 Internet 上的多个源中的数据的混合 Web 应用程序。

  注意:您可以从 C:\SQLHOLS\Spatial and VE\Solution\StoreFinderSite 中的完成的网站页面复制此练习中所用的代码。

  添加代码以显示地图

  1. 在解决方案资源管理器中,双击 Default.aspx 在设计器中打开它。

  2. 如果它还未被选中,请单击设计器左下部的源选项卡查看此页的 HTML 源文件。

  3. 在注释 add a reference to the Virtual Earth map control下,添加以下 HTML。

<script type="text/javascript"
              src
="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6">
</script>

  4. 在 GetMap JavaScript 函数中,在注释 Display the map control下,添加以下代码。

  map = new VEMap('mapDiv');

  map.LoadMap();

  5. 保存 Default.aspx。

  6. 在解决方案资源管理器中,右键单击 Default.aspx,然后单击设为起始页。

  7. 在调试菜单上,单击开始执行(不调试)。

  8. 当 Internet Explorer 打开时,验证显示了地图。

  9. 使用地图上的内置控件移动、缩放和更改视图。

  10. 关闭 Internet Explorer。

  添加代码以在地图上显示所有商店

  1. 在 Default.aspx 中的 ShowAllStores 函数中,在注释 Import GeoRSS feed of store data, and call onAllStoreLoad function when the data is loaded下,添加以下代码。

  var veLayerSpec = new VEShapeSourceSpecification(VEDataType.GeoRSS,

  "./Stores.georss");

  map.ImportShapeLayerData(veLayerSpec, onAllStoreLoad, true);

  注意:此代码向网站发送针对 Stores.georss 页的请求。此请求将由您在上一练习中实现的 HTTP 处理程序处理,并返回包含所有商店的 GeoRSS 订阅源。接着此代码将 GeoRSS 数据作为新层加载到地图控件中,并指定在将此数据加载到地图中后调用 onAllStoreLoad 函数。

  2. 在 onAllStoreLoad 函数中,在注释 Count the shapes returned下,添加以下代码。

  var storecount = feed.GetShapeCount();

  document.getElementById("Info").innerHTML =

  'There are ' + storecount + ' stores.';

  3. 保存 Default.aspx。

  4. 在调试菜单上,单击开始执行(不调试)。

  5. 当 Internet Explorer 打开时,单击 Show All Stores,并验证商店在地图上显示为图钉。

  6. 关闭 Internet Explorer。

  添加代码以显示指定位置附近的商店

  1. 在 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下,添加以下代码。

  results = map.Find( null,

  document.getElementById("SearchLocation").value,

  null, null,null, 1, false, false, false, true,

  onFind);

  注意:此代码使用 Virtual Earth 根据用户输入的文本查找位置。当找到一个或多个位置时,此代码会指定应调用 OnFind 函数。

  2. 在 onFind 函数中,在注释 define the search point as the latitude and longitude of the first place in the results下,添加以下代码。

  var SearchFromPoint = places[0].LatLong;

  注意:此代码取用在结果中找到的第一个位置,并以逗号分隔的字符串的形式提取纬度和经度。

  3. 在 onFind 函数中,在注释 Import GeoRSS feed of stores near the search point, and call onNearbyStoresLoad function when the data is loaded下,添加以下代码。

  var veLayerSpec = new VEShapeSourceSpecification(VEDataType.GeoRSS,

  "./Stores.georss?SearchFrom=" + SearchFromPoint);

  map.ImportShapeLayerData(veLayerSpec, onNearbyStoresLoad, true);

  注意:此代码向网站发送针对 Stores.georss 页的请求,该请求使用一个包含搜索位置的纬度和经度的 SearchFrom 参数。此请求将由您在上一练习中实现的 HTTP 处理程序处理,并返回包含搜索区域和其中的所有商店的 GeoRSS 订阅源。接着,此代码将 GeoRSS 数据作为新层加载到地图控件中,并指定在将此数据加载到地图中后调用 onNearbyStoresLoad 函数。

  4. 在 onNearbyStoresLoad 函数中,在注释 Don't count or show the first shape (the search location)下,添加以下代码。

  var storecount = feed.GetShapeCount()-1;

  feed.GetShapeByIndex(0).HideIcon();

  document.getElementById("Info").innerHTML =

  'There are ' + storecount + ' stores.';

  5. 在 onNearbyStoresLoad 函数中,在注释 Show the info for the search area when the results first load下,添加以下代码。

  map.ShowInfoBox(feed.GetShapeByIndex(0));

  注意:此代码将显示搜索区域的信息气球。

  6. 保存 Default.aspx。

  7. 在调试菜单上,单击开始执行(不调试)。

  8. 当 Internet Explorer 打开时,输入文本 Seattle 并单击 Show Stores Near,然后验证这些商店在地图中显示为图钉并用一个圆圈显示搜索区域。

  9. 使用位置 San Francisco 和90210 重复此搜索。

  10. 关闭 Internet Explorer。

  11. 关闭 Visual Studio。

  12. 关闭 Hyper-V,放弃更改。

0
相关文章