友情提示,您閱讀本篇博文的先決條件如下:
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 Servr 2008空間數據應用系列七:基於Bing Maps(Silverlight) 的空間數據展現》一文中介紹瞭如何基於Bing Maps呈現SQL Server 2008中存儲的空間數據,對於標準的地理空間數據可以通過數據導入的方式將其存放到數據庫中(後續文章將詳細介紹),對於一些非標準的空間數據或者說是一個軟件產品中的業務空間數據,則需要通過人爲或其他方式將其存儲進數據庫,本篇將以如何在Bing Maps(Silverlight)中動態繪製多邊圖形然後將其存儲到SQL Server 2008的空間數據列中爲例,詳細介紹如何實現自定義圖形存儲入庫的實現方式和原理。
一、創建空間數據表
首先創建空間數據類型字段表,以存儲在Bing Maps(Silverlight)中動態繪製的多邊形圖形數據到空間數據列。
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NOT NULL,
[Polygon] [geography] NOT NULL)
GO
二、編寫入庫存儲過程
目前Linq To Sql和ASP.NET Entity Framework都不支持SQL Server 2008的空間數據類型,前臺只能通過字符串或者對象的形式將數據傳遞到後臺服務端,然後通過調用存儲過程,在存儲過程中對空間數據的字符串進行空間數據對象轉換,然後入庫。針對上面所創建的空間數據表可以創建如下存儲過程來實現多邊形空間數據的入庫存儲。
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[SavePolygon]
(
@name varchar(50),
@polytext varchar(max),
@identity int OUTPUT
)
AS
INSERT INTO dbo.DrawnPolygons
(Name,Polygon)
VALUES (@name, geography::STPolyFromText(@polytext, 4326))
SET @identity = @@Identity
RETURN
三、編寫服務接口
入庫接口可以採用WebService或者WCF技術提供,本篇採用WCF作爲數據操作接口技術,Linq To Sql做數據訪問,自定義方法調用存儲過程實現數據庫入庫操作。
在項目中添加Linq To Sql文件,然後打開對於的代碼隱藏文件,在Linq To Sql自動生產的創建數據庫連接的代碼下面添加如下自定義方法實現數據庫存儲過程的調用。
public int SavePolygon([Parameter(DbType = "VarChar(50)")] string name,
[Parameter(DbType = "VarChar(MAX)")] string polygontext,
[Parameter(DbType = "Int")] ref System.Nullable<int> identity)
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), name, polygontext, identity);
identity = ((System.Nullable<int>)(result.GetParameterValue(2)));
return ((int)(result.ReturnValue));
}
如上實現了Linq To Sql對存儲過程的調用,接下來就是創建WCF服務提供給Silverlight調用。
public interface IDrawService
{
/// <summary>
/// 保存多邊形對象到空間數據庫
/// </summary>
/// <param name="name"></param>
/// <param name="arrayOfLatLong"></param>
/// <returns></returns>
[OperationContract]
int? SavePolygon(string name, List<MapPoint> arrayOfLatLong);
}
在WCF服務的詳細實現中將Bing Maps客戶端傳遞過來的參數構造爲空間數據類型的WKT文本格式,通過上面的存儲過程就可以直接將WKT轉化爲空間數據類型直接入庫。
{
public int? SavePolygon(string name, List<MapPoint> arrayOfLatLong)
{
var sb = new StringBuilder();
sb.Append("POLYGON ((");
for (var i = arrayOfLatLong.Count; i >= 1; i--)
{
var j = i - 1;
sb.Append(arrayOfLatLong[j].Longitude.ToString());
sb.Append(" ");
sb.Append(arrayOfLatLong[j].Latitude.ToString());
sb.Append(",");
}
sb.Remove(sb.Length - 1, 1);
sb.Append("))");
int? identity = 0;
var connectionString = ConfigurationManager.ConnectionStrings["Sql08ConnectionString"].ConnectionString;
BMPTSDataContext ctx = new BMPTSDataContext(connectionString);
ctx.SavePolygon("西南大區", sb.ToString(), ref identity);
return identity;
}
}
接口中使用的數據傳輸對象MapPoint的詳細定義如下代碼塊:
/// 地圖座標點(經度,緯度)
/// </summary>
[DataContract]
public class MapPoint
{
[DataMember]
public double Latitude { get; set; }
[DataMember]
public double Longitude { get; set; }
public MapPoint() { }
public MapPoint(double lat, double lng)
{
this.Latitude = lat;
this.Longitude = lng;
}
}
四、Bing Maps客戶端的實現
客戶端的實現非常簡單,首先創建Silverlight應用程序並添加Bing Maps Silverlight Control開發組件的引用,其次在界面中添加Map對象以顯示Bing Maps原型界面,最後可以設計一個小的工具面板,以按鈕的方式驅動觸發繪製多邊形的行爲,以及保存圖形到數據庫的命令請求。如下界面效果:
對於繪製多邊形的算法這裏鑑於篇幅限制就不一一貼出來了,詳細可通過文末提供的代碼下載鏈接下載本文的示例代碼。比如限制繪製一個【成都-重慶-貴陽-昆明】這四個城市組成的西南大區多變型圖形,並將其圖形數據以空間數據的形式存儲到SQL Server 2008中。圖形如下圖所示:
通過點擊“保存數據”按鈕則將地圖界面繪製的圖形數據取出來構造爲數組傳遞到WCF服務接口,調用數據庫存儲過程實現數據入庫操作,下面是保存按鈕的代碼實現。
{
LocationCollection lc = this._drawLine.Locations;
ObservableCollection<MapPoint> polygon = new ObservableCollection<MapPoint>();
for (int i = 0; i < lc.Count; i++)
{
polygon.Add(new MapPoint { Longitude = lc[i].Longitude, Latitude = lc[i].Latitude });
}
//調用WCF接口實現數據入庫
DrawServiceClient client = new DrawServiceClient();
client.SavePolygonAsync(this.tbName.Text.Trim(), polygon);
client.SavePolygonCompleted += client_SavePolygonCompleted;
}
private void client_SavePolygonCompleted(object sender, SavePolygonCompletedEventArgs e)
{
if (e.Error != null)
{
this.tbResult.Text = e.Result.Value > 0 ? "保存成功!" : "保存失敗";
}
}
五、數據庫中的空間數據
當通過Bing Maps中動態繪製多邊形圖形對象,然後將圖形數據通過WCF服務接口入庫保存後,可以通過SQL Server Management Studio查詢並在空間數據結果中直接預覽結果。
六、相關資料
[1]、Geography數據類型:http://msdn.microsoft.com/zh-cn/library/cc280766.aspx
[2]、地域實例上的OGC方法:http://msdn.microsoft.com/zh-cn/library/bb933917.aspx
[3]、地理實例上的擴展方法:http://msdn.microsoft.com/zh-cn/library/bb933968.aspx
[4]、OGC靜態地理方法:http://msdn.microsoft.com/zh-cn/library/bb933988.aspx
[5]、擴展靜態地理方法:http://msdn.microsoft.com/zh-cn/library/bb933921.aspx
七、示例代碼下載