GeoRSS是一种描述和查明互联网内容所在物理位置的方法。通过使用GeoRSS,搜索Web站点或者与地理位置有关的项目就成为可能。GeoRSS利用地理标识语言(GML),即利用可扩展标记语言 (Extensible Markup Language, XML)存储和传输地理数据的方法。原始的GML模型以由World Wide Web联盟(W3C)所开发的资源描述框架(RDF)为基础。GML保持着RDF的许多特性,包括智能代理和一个用于描述和查询数据的标准语法。
GeoRSS 是在 RSS 订阅源中包含地理空间数据时所用的一个标准,它定义了一种名为 GeoRSS GML 的特定格式,用来在订阅源中包含 GML 格式的数据。客户端应用程序可以订阅 GeoRSS 订阅源,订阅方式与订阅常规 RSS 订阅源相同。可以轻松地将 GeoRSS 格式的数据导入Microsoft Bing Maps、Google Maps中,同样也可以将空间数据库中的空间数据发布为GeoRss订阅后快速的在GIS中呈现,本篇将介绍如何基于微软Bing Maps for Silverlight中呈现GeoRss订阅的空间数据。
一、发布空间数据到GeoRss
前一篇文章《SQL Server 2008空间数据应用系列十:使用存储过程生成GeoRSS聚合空间信息》介绍了如何将空间数据通过存储过程+HTTP请求接口发布为GeoRss的具体实现,这里就一笔带过,详细请查阅上篇博文。
二、创建GeoRss阅读器
创建GeoRss阅读器的目的是为了动态的请求GeoRss地址,将GeoRss数据解析为自己想要的数据结构,如下便是根据自己的需求结合GeoRss定义的一种数据结构样例。 核心原理就是使用WebClient动态的发起http请求,将返回的GeoRss数据通过Linq To XML的方式解析为对象结构的数据。其实现非常简单,不做具体分析,详细代码如下所示:
using Microsoft.Maps.MapControl;
namespace GeoRss.Map.GeoRssUtils
{
public class GeoRssItem
{
public string Title { get ; set ; }
public string Description { get ; set ; }
public string Link { get ; set ; }
public string PubData { get ; set ; }
public LocationCollection Locatios { get ; set ; }
}
}
using System;
using System.Net;
using System.Xml.Linq;
using System.Linq;
using System.Windows;
using Microsoft.Maps.MapControl;
namespace GeoRss.Map.GeoRssUtils
{
public delegate void DownloadGeoRssCompletedEventHandler(List < GeoRssItem > items);
public delegate void DownloadGeoRssExceptionEventHandler(Exception e);
public class GeoRssReader
{
public GeoRssReader()
{
wc = new WebClient();
wc.DownloadStringCompleted += WebClientDownloadGeoRssCompleted;
}
public GeoRssReader(Uri uri)
: this ()
{
this .uri = uri;
}
public GeoRssReader(Uri uri, DownloadGeoRssCompletedEventHandler evh)
: this (uri)
{
DownloadGeoRssCompleted += evh;
}
public Uri uri { get ; set ; }
public event DownloadGeoRssCompletedEventHandler DownloadGeoRssCompleted;
public event DownloadGeoRssExceptionEventHandler DownloadGeoRssException;
public void ReadAsync()
{
if (DownloadGeoRssCompleted.Target != null )
{
wc.DownloadStringAsync(uri);
}
}
#region _private
private readonly WebClient wc;
private void WebClientDownloadGeoRssCompleted( object sender, DownloadStringCompletedEventArgs e)
{
try
{
XNamespace nsXml = " http://www.w3.org/2005/Atom " ;
XNamespace nsGeorss = " http://www.georss.org/georss " ;
XNamespace nsGeo = " http://www.w3.org/2003/01/geo/wgs84_pos# " ;
XNamespace nsMedia = " http://search.yahoo.com/mrss/ " ;
var items = from item in XElement.Parse(e.Result).Descendants( " item " )
select new GeoRssItem
{
Title = (item.Element( " title " ) != null ) ? item.Element( " title " ).Value : null ,
Link = (item.Element( " link " ) != null ) ? item.Element( " link " ).Value : null ,
Description = (item.Element( " description " ) != null ) ? item.Element( " description " ).Value : null ,
PubData = (item.Element( " pubDate " ) != null ) ? item.Element( " pubDate " ).Value : null ,
Locatios = ParserLocations(XElement.Parse(item.LastNode.ToString().Replace( " : " , " X " )).Value)
};
if (DownloadGeoRssCompleted.Method != null )
{
DownloadGeoRssCompleted.Invoke(items.ToList());
}
}
catch (Exception ex)
{
if (DownloadGeoRssException.Method != null )
{
DownloadGeoRssException.Invoke(ex);
}
else
{
throw ;
}
}
}
private LocationCollection ParserLocations( string points)
{
LocationCollection lc = new LocationCollection();
string [] ps = points.Split( ' ' );
for ( int i = 0 ; i < ps.Length; i += 2 )
{
lc.Add( new Location( double .Parse(ps[i]), double .Parse(ps[i + 1 ])));
}
return lc;
}
#endregion
}
}
三、基于SLBM呈现GeoRss数据
引入Bing Maps Silverlight Control的控件库,定义一个专门的MapLayer图层来呈现GeoRss数据,其Silverlight前台的代码如下。
< map:Map x:Name ="map" Margin ="0,0,0,0" CredentialsProvider =" {StaticResource MyCredentials} "
ScaleVisibility ="Visible"
CopyrightVisibility ="Collapsed" >
< map:MapLayer Name ="mlayer" ></ map:MapLayer >
</ map:Map >
</ Grid >
应用程序加载的过程中使用上面所开发完成的GeoRss阅读器进行数据读取并解析,随后将结果呈现在Bing Maps Silverlight Control的应用中。代码如下:
{
InitializeComponent();
string url = " http://localhost:32484/SHBuildingGeoHandler.ashx " ;
GeoRssReader reader = new GeoRssReader( new Uri(url, UriKind.RelativeOrAbsolute));
reader.DownloadGeoRssCompleted += new DownloadGeoRssCompletedEventHandler(reader_DownloadGeoRssCompleted);
reader.ReadAsync();
}
void reader_DownloadGeoRssCompleted(List < GeoRssItem > items)
{
// System.Diagnostics.Debug.WriteLine(items.Count);
foreach (var item in items)
{
MapPolygon mp = new MapPolygon();
mp.Locations = item.Locatios;
mp.Fill = new SolidColorBrush(Colors.Red);
this .mlayer.Children.Add(mp);
}
}