友情提示,您閱讀本篇博文的先決條件如下:
1、本文示例基于Microsoft SQL Server 2008 R2調測。
2、具備 Transact-SQL 程式設計經驗和使用 SQL Server Management Studio 的經驗。
3、具有使用 Microsoft Visual Studio 進行 Microsoft .NET Framework開發的經驗。
4、具有使用WCF、Silverlight、ADO.NET開發的經驗。
5、熟悉或了解Microsoft SQL Server 2008中的空間資料類型。
6、具備相應(比如OGC)的GIS專業理論知識。
SQL Server 2008中存儲的空間資料,除了能夠直接基于SQL Server做空間查詢、空間分析外,由于SQLCLR提供了非常豐富、完善的開發API,使得空間資料可以在不同的常用空間資料類型之間轉換,同時還可以非常簡單的和地圖應用無縫內建使用。本篇博文以Bing Maps Silverlight Control為地圖應用用戶端為基礎,介紹如何實作在Bing Maps中呈現地理空間資料。
一、準備空間資料
為了示範如何基于Bing Maps Silverlight Control來呈現SQL Server 2008中存儲的空間資料,首先需要在資料庫中模拟一些資料供資料查詢使用,随意建立一個帶有空間資料類型字段的表就可以,如下SQL腳本。
CREATE TABLE DrawnPolygons(
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NOT NULL,
[Polygon] [geography] NOT NULL)
GO
對于上面腳本所建立的表格,随意的構造幾條資料,如下圖SQL Server Management Studio的空間結果中所呈現的效果。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiInBnauQWO1EGZ5cDZ4M2YxIjZwU2NhNmZ1QmYkVjNkFGOxIGOfdWbp9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.jpg)
二、編寫資料服務接口
資料結構使用WebService或者WCF提供都可以,本篇選用WCF Service提供地圖資料通路接口,實作将資料庫的空間資料讀取出來傳回到Bing Maps的地圖用戶端。由于目前的Linq To Sql和ASP.NET Entity Framewrok還不支援SQL Server 2008的空間資料類型,資料通路隻能自己編寫ADO.NET實作。如下代碼塊:
private DataTable Query(string sql)
{
string cstring = ConfigurationManager.ConnectionStrings["BingMapsDB"].ConnectionString;
SqlConnection conn = new SqlConnection(cstring);
if (conn.State == ConnectionState.Closed) conn.Open();
SqlDataAdapter adapter = new SqlDataAdapter(sql, conn);
DataSet ds = new DataSet();
adapter.Fill(ds);
return ds.Tables[0];
}
直接在WCF中對外公布一個公共方法,并将其标記為操作契約(OperationContract)就完成了服務接口的提供,該接口實作資料庫查詢并将資料庫資料資料組合為對象集合傳回到用戶端,詳細實作如下代碼塊。
[OperationContract]
public List<DrawnPolygons> QueryPolygons()
var sql = "SELECT * FROM [DrawnPolygons]";
var result = Query(sql);
List<DrawnPolygons> areas = null;
if (result != null && result.Rows.Count > 0)
{
areas = new List<DrawnPolygons>();
foreach (DataRow row in result.Rows)
{
areas.Add(new DrawnPolygons
{
ID = int.Parse(row["ID"].ToString()),
Name = row["NAME"].ToString(),
Xaml = ToXaml(row["Polygon"], row["ID"].ToString())
});
}
}
return areas;
接口使用了資料傳輸對象DrawnPolygons,其他結構如下定義:
[DataContract]
public class DrawnPolygons
[DataMember]
public int ID { get; set; }
public string Name { get; set; }
public string Xaml { get; set; }
三、構造空間資料用戶端對象
在這裡請大家講視眼轉移到本篇前面代碼片段的中加粗大紅字型處,會發現使用了一個名為“ToXaml()”的方法,此方法的主要功能就是實作将空間資料轉換為用戶端Silverlight能夠識别的xaml語言标記。該方法的詳細實作如下代碼塊所示:
private string ToXaml(object polygon,string id)
StringBuilder sb = new StringBuilder();
//将資料庫查詢出的空間資料構造為SQL Server空間資料類型對象
var geo = SqlGeography.STGeomFromText(
new SqlChars(
new SqlString(polygon.ToString())), 4326);
//将空間資料構造為Bing Maps圖形(多邊形)對象的Xaml文本,以傳回到用戶端直接解析Xaml為Silverlight程式中的對象。
for (int j = 1; j <= geo.NumRings(); j++)
if (geo.RingN(j).STNumPoints() > 1)
sb.Append("<m:MapPolygon xmlns:m=\"clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl\"");
sb.Append(" Fill=\"Red\" Locations=\"");
for (int k = 1; k <= geo.RingN(j).STNumPoints(); k++)
if (k > 1) sb.Append(" ");
sb.Append(String.Format("{0:0.#####},{1:0.#####}",
(double)geo.RingN(j).STPointN(k).Lat,
(double)geo.RingN(j).STPointN(k).Long));
}
sb.AppendLine("\"/>");
return sb.ToString();
實際上,在服務端将空間資料轉化為Xaml并非實作傳遞空間資料到用戶端并解析呈現到GIS界面的唯一選擇,還可以将資料庫空間資料處理為KML、GML等常用的其它能夠表示存儲地圖資料的任意格式傳回到用戶端使用。這裡為何選擇将空間資料解析為Xaml語言标記的目的是為了Silverlight能夠直接将Xaml語言标記解析為對應的對象,并能夠直接使用。如果選擇将空間資料解析為别的地圖資料格式,還需要額外的解析算法去實作空間資料的解析。
四、Bing Maps用戶端的實作
Bing Maps Silverlight用戶端隻需要調用上面提供的WCF Service接口,将空間資料查詢到用戶端,然後通過XamlReader的接口解析Xaml為對應的對象即可,可以在應用程式加載時就發起對接口的調用。如下代碼塊所示:
public MainPage()
InitializeComponent();
//調用WCF服務接口查詢空間資料到用戶端
DataServiceClient service = new DataServiceClient();
service.QueryPolygonsCompleted += new EventHandler<QueryPolygonsCompletedEventArgs>(service_QueryPolygonsCompleted);
service.QueryPolygonsAsync();
private void service_QueryPolygonsCompleted(object sender, QueryPolygonsCompletedEventArgs e)
if (e.Error != null) return;
for (int i = 0; i < e.Result.Count; i++)
//将空間資料所構造的Xaml語言标記解析為Bing Maps Silverlight Control中的多邊形(MapPolygon)對象。
MapPolygon polygon = (MapPolygon)XamlReader.Load(e.Result[i].Xaml);
//将多邊形對象添加到地圖中呈現。
map.Children.Add(polygon);
四、相關資料
版權說明
本文屬原創文章,歡迎轉載且注明文章出處,其版權歸作者和部落格園共有。為了儲存作者的創作熱情,請在轉載後的明顯位置标記本文出處。
作 者:Beniao