Oracle Spatial的空間資料應用和微軟SQL Server 2008的大同小異,SQL Server 2008提供了基於SQLCLR的編程支援,Oracle Spatial暫時還沒有比較完善的組件支援。在實際開發應用中我們可以選擇折中的解決方案,比如將空間資料讀取為通用的空間資料表達格式(如:WKT),利用開源的WKT讀取組件便可將WKT資料解析為對應的空間資料座標點或座標集合。
下面以一個實際的案例來介紹如何讀取Oracle Spatial資料為WKT,並通過WKT組件解析資料,最終在Bing Maps中進行渲染。現要實現將資料庫中地市表配置的全國地市資料中四川省的資料讀取出來在地圖中進行渲染,Oracle Spatial的sdo_geometry資料類型則可以直接使用函數(get_wkt())進行轉換為clob資料類型資料。
select t.areacode,t.areaname, (t.area.get_wkt()) wkt from areainfo t where areacode like '8623%'
為了方便用戶端的使用,服務端可以通過WCF服務封裝資料為數組返回,以下為地市實體物件資料結構和WCF服務的定義。
namespace OracleSpatial.DataService.Models
{
[DataContract]
public class AreaInfo
{
[DataMember]
public string AreaCode { get; set; }
[DataMember]
public string AreaName { get; set; }
[DataMember]
public string WKT { get; set; }
}
}
namespace OracleSpatial.DataService
{
[ServiceContract]
public interface IGeometryService
{
[OperationContract]
List<AreaInfo> GetAreaInfo();
}
}
Bing Maps的Silverlight用戶端調用WCF服務以擷取資料庫中的資料,這裡就不做詳細介紹。在這裡需要特別介紹的是幾個開源應用:
1、SharpMap開源的GeoAPI.
2、NetTopologySuite.
這兩個開源庫分別定義好了不同GIS座標系的空間標準,以及基於地理空間的空間對象、空間計算和空間分析介面,在應用開發中可以非常方便的完成空間資料的讀寫、驗證、計算和分析功能。本文使用到了WKT讀取組件(WKTReader),可以實現將WKT格式的字串解析為符合GIS座標系標準的通用空間對象(Geometry),此空間對象中就包含了完整的WKT資料的描述,如WKT所表示的座標點,座標點集合,內部座標點,空間面積等等。
public MainPage()
{
InitializeComponent();
this.Loaded += (sender, e) =>
{
LoadChinaMap();
GeometryServiceClient service = new GeometryServiceClient();
service.GetAreaInfoCompleted += service_GetAreaInfoCompleted;
service.GetAreaInfoAsync();
};
}
private void service_GetAreaInfoCompleted(object sender, GetAreaInfoCompletedEventArgs e)
{
if (e.Error == null)
{
ObservableCollection<AreaInfo> result = e.Result;
WKTReader reader = reader = new WKTReader();
IGeometry geometry = reader.Read(result[0].WKT);
}
}
通過WKTReader將WKT格式的空間資料解析為IGeometry介面的空間對象,就可以非常方便的擷取WKT空間資料中的各種座標值。如果上面所擷取到的資料,我們就可以通過繪製多邊形以及通過自訂標註將資料渲染在地圖中。
private void service_GetAreaInfoCompleted(object sender, GetAreaInfoCompletedEventArgs e)
{
if (e.Error == null)
{
ObservableCollection<AreaInfo> result = e.Result;
WKTReader reader = null;
foreach (var item in result)
{
reader = new WKTReader();
IGeometry geometry = reader.Read(item.WKT);
//邊界
MapPolygon line = new MapPolygon();
line.Locations = CoordinateConvertor.CoordinatesToLocationCollection(geometry.Coordinates);
line.Fill = new SolidColorBrush(Colors.Gray);
line.BorderBrush = new SolidColorBrush(Colors.Green);
line.BorderThickness = new Thickness(2);
line.MouseEnter += new MouseEventHandler(line_MouseEnter);
line.MouseLeave += new MouseEventHandler(line_MouseLeave);
this.mlayer.Children.Add(line);
//名稱標註
this.mlayer.AddChild(new PointControl(item.AreaName),
new Microsoft.Maps.MapControl.Location(geometry.InteriorPoint.Y, geometry.InteriorPoint.X));
}
}
}
private void line_MouseLeave(object sender, MouseEventArgs e)
{
MapPolygon mp = sender as MapPolygon;
mp.Fill = new SolidColorBrush(Colors.Gray);
}
private void line_MouseEnter(object sender, MouseEventArgs e)
{
MapPolygon mp = sender as MapPolygon;
mp.Fill = new SolidColorBrush(Colors.Yellow);
}
相關資源:
[1]、SharpMap:http://sharpmap.codeplex.com
[2]、NetTopologySuite:http://code.google.com/p/nettopologysuite
[3]、WKT:http://www.opengis.org/techno/specs.htm
著作權說明
本文屬原創文章,歡迎轉載且註明文章出處,其著作權歸作者和部落格園共有。為了儲存作者的創作熱情,請在轉載後的明顯位置標記本文出處。
作 者:Beniao
文章出處:http://beniao.cnblogs.com/ 或 http://www.cnblogs.com/