我寫的東西內容淺顯,希望能給初學者一些幫助。至於深入研究sharpmap和GIS技術的大牛,請不吝賜 教,給我們這些菜鳥多一些指導。
今天我們接著來聊sharpmap的基本使用技巧,根據attribute來填充地圖對象的顏色,讓用戶更清晰的 看到重點的業務對象對應在地圖上的表示,以及如何自定義label層的顯示內容,字體的大小等。所以,今 天的主題主要是自定義:自定義theme,自定義label以及label字體。
首先,我們要為地圖填充上不同的色彩,讓他們看起來五顏六色,容易分辨。比如河流和湖泊要填成 藍色,草地要填充上綠色,房子要填充上白色,道路要填充上青色等等。怎麼做呢?很簡單,先看下代碼 :
SharpMap.Rendering.Thematics.CustomTheme iTheme = new SharpMap.Rendering.Thematics.CustomTheme(GetMyStyle);
在初始化Map的時候,加上上面的一行代碼。它定義了一個自定義的Theme對象,這個對象的構造函數 需要傳入一個我們自己寫的方法(委托),這個方法裡面具體說明了這個 theme是如何定義的,方法代碼 如下:
private static SharpMap.Styles.VectorStyle GetMyStyle(SharpMap.Data.FeatureDataRow
row)
{
SharpMap.Styles.VectorStyle style = new
SharpMap.Styles.VectorStyle();
switch (row["Status"].ToString().ToLower())
{
case "available": //If status is interred, fill it
with yellow
style.Fill = Brushes.Yellow;
return style;
default:
style.Fill = Brushes.Green;
return style;
}
}
這段簡單代碼大家都看得懂,這個委托定義需要傳入一個FeatureDataRow,它的作用就是在初始化地圖 的過程中,每處理一個對象,都要到這個方法中來考察一下feature的值是多少以決定具體要填充哪些顏 色。在這裡,當status為available時,就填充黃色,否則就填充綠色。定義的VectorStyle用來返回給地 圖。是不是很簡單呢?
![]()
地圖填充完了,我們要在上面顯示出到底他們是什麼。在第一篇中,我們已經可以把對象的一個屬性 顯示出來,但是當地圖擴大到一定比例時,僅僅顯示名字這一種信息已經不足以滿足用戶的需要了。比如 說一棟房子,在很遠處看它時,我們只需要看到他的顏色就行了。但是當我們離的很近的時候,難道看到 的是全白色嗎?顯然不是,我們還可以看到門牌號,窗戶上的貼紙以及其它詳細信息。地圖也一樣,當比 例尺改變以後,應該有更詳細的信息被列出來。老規矩,先貼代碼:
SharpMap.Layers.LabelLayer myLabel = new SharpMap.Layers.LabelLayer("labels");
myLabel .DataSource = myLayer.DataSource;
myLabel.LabelStringDelegate= new SharpMap.Layers.LabelLayer.GetLabelMethod
(GetLabelString);
在這裡,首先定義了一個label(就像在初始化地圖裡一樣,或者就在初始化地圖裡做),然後把你所 要顯示的圖層的數據源賦值給這個label的數據源,接著為label層的LabelStringDelegate指定一個方法 (這個方法傳入一個FeatureDataRow,返回一個字符串),最後去實現這個方法,代碼如下:
public static string GetLabelString(FeatureDataRow dr)
{
string field1= string.Empty;
string field2= string.Empty;
string field13= string.Empty;
if (dr["HouseNumber"] != null)
{
field1= dr["HouseNumber"].ToString();
}
if (dr["HostName"] != null)
{
field2= dr["HostName"].ToString();
}
if (dr["Memo"] != null)
{
field3= dr["Memo"].ToString();
}
StringBuilder sb = new StringBuilder();
sb.Append(field1);
sb.Append(": ");
sb.Append(field2);
sb.Append("\r\n" + field3);
return sb.ToString();
}
代碼簡單的要死,不再詳述,值得注意的是:如果要換行,請使用“\r\n”, 這裡不支持html拼的字 符串。哈,又解決一個問題。爽吧?
然後,新的問題又來了,字體一直都是那麼大,或者一直都是那麼小,這可怎麼辦呢?看起來也相當 不舒服啊。如果字體能隨著比例尺的變化而變化就好了。這個沒問題,我們馬上就搞定它。看代碼:
public void ChangeFontSize(double Zoom, SharpMap.Layers.ILayer iLayer)
{
SharpMap.Layers.LabelLayer labelLayer =
(SharpMap.Layers.LabelLayer)iLayer;
if (Zoom < 800 && Zoom > 400)
{
((SharpMap.Layers.LabelLayer)labelLayer).Style.Font = new
System.Drawing.Font(System.Drawing.FontFamily.GenericSerif, 6);
}
else if (Zoom < 400 && Zoom > 140)
{
((SharpMap.Layers.LabelLayer)labelLayer).Style.Font = new
System.Drawing.Font(System.Drawing.FontFamily.GenericSerif, 8);
}
else if (Zoom < 140.00 && Zoom > 20)
{
((SharpMap.Layers.LabelLayer)labelLayer).Style.Font = new
System.Drawing.Font(System.Drawing.FontFamily.GenericSerif, 16);
}
else if (Zoom < 20.00)
{
((SharpMap.Layers.LabelLayer)labelLayer).Style.Font = new
System.Drawing.Font(System.Drawing.FontFamily.GenericSerif, 48);
}
else
{
((SharpMap.Layers.LabelLayer)labelLayer).Style.Font = new
System.Drawing.Font(System.Drawing.FontFamily.GenericSerif, 70);
}
}
這個方法傳入了一個Zoom值和一個ILayer,沒有返回值,直接修改ILayer就可以了。
相信大家都看得懂吧?值得注意的問題是:AjaxMap上面的map對象有個屬性叫做zoomAmount,這是個 javascript的屬性需要在前台指定,它說明了地圖放大或縮小的比例尺倍數。Demo中是在 RadioButtonList的ListItem中指定的。這個過程是這樣的:當點擊Zoom In這個button,自動執行了一段 javascript:
ajaxMapObj.disableClickEvent(); ajaxMapObj.zoomAmount = 3;
然後當我們點擊地圖,click事件已經被禁止,系統刷新地圖,此時在handler裡接受到了地圖的新的 參數(zoom等),然後重新繪制了地圖。所以,我們在handler裡取得zoom參數,並且使用 GetLayerByName(“”)方法來取得label層
ChangeFontSize(Zoom, map.GetLayerByName("mylabels"));
這樣,就實現了字體隨著比例尺變化兒變化。有同學可能問:那如何讓label的內容隨著比例尺變化而 變化呢?只需要把剛才那句話
myLabel.LabelStringDelegate= new SharpMap.Layers.LabelLayer.GetLabelMethod (GetLabelString);
放到相應的if。。else語句裡就行了。簡單吧?