程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> SharpMap學習(1)

SharpMap學習(1)

編輯:關於.NET

最近公司想在一個產品上加一個電子地圖的功能,讓我有機會接觸到Gis領域。這幾年國內的GIS技術 也發展的很快,但是相關的技術文檔還是很缺乏,都是英文的。我的文筆不好,寫的東西也很淺顯,但是 希望能給看文章的一點點幫助,我就心滿意足了。

我用的 SharpMap是一個開源的Gis項目,功能還可以,最大的特點就是簡單易用,適合剛剛接觸GIS技 術的朋友。同時還使用了MapWindow GIS來幫助畫地圖,使用NetTopologySuite來完善一些sharpmap沒有 提供或者功能不全的地方。MapWindow GIS使用起來不是很方便,熟悉了就容易了。關於軟件的使用我就 不再贅述,大家有問題可以跟帖,我會及時回復。

這次我們根據demo先了解一下如何show一個地圖。這是最基本的步驟,也比較簡單,希望能對剛入門 的同學有所幫助。

我們使用SharpMap.UI.dll中的ajax控件 

 <smap:AjaxMapControl width="1600px" Height="600px" id="ajaxMap" runat="server" 

 OnClickEvent="MapClicked" onmouseout="toolTip();"; OnViewChange="ViewChanged" 

CssClass="Ly"    UseCache="false"

                        OnViewChanging="ViewChanging" ZoomSpeed="1" 

/>

來展示地圖,主要代碼分析如下:

首先,初始化地圖

Initialize Map

public static SharpMap.Map InitializeMap(System.Drawing.Size size)
    {
            HttpContext.Current.Trace.Write("Initializing map");
            //Initialize a new map of size 'imagesize'
            SharpMap.Map map = new SharpMap.Map(size);
            //Set up the countries layer
            SharpMap.Layers.VectorLayer layCountries = new SharpMap.Layers.VectorLayer

("Countries");
            //Set the datasource to a shapefile in the App_data folder
            layCountries.DataSource = new SharpMap.Data.Providers.ShapeFile

(HttpContext.Current.Server.MapPath(@"~\App_data\countries.shp"), true);
            //Set fill-style to green
            layCountries.Style.Fill = new SolidBrush(Color.Green);
            //Set the polygons to have a black outline
            layCountries.Style.Outline = System.Drawing.Pens.Black;
            layCountries.Style.EnableOutline = true;
            layCountries.SRID = 4326;
            //Set up a river layer
            SharpMap.Layers.VectorLayer layRivers = new SharpMap.Layers.VectorLayer

("Rivers");
            //Set the datasource to a shapefile in the App_data folder
            layRivers.DataSource = new SharpMap.Data.Providers.ShapeFile

(HttpContext.Current.Server.MapPath(@"~\App_data\rivers.shp"), true);
            //Define a blue 1px wide pen
            layRivers.Style.Line = new Pen(Color.Blue,1);
            layRivers.SRID = 4326;
            //Set up a river layer
            SharpMap.Layers.VectorLayer layCities = new SharpMap.Layers.VectorLayer

("Cities");
            //Set the datasource to a shapefile in the App_data folder
            layCities.DataSource = new SharpMap.Data.Providers.ShapeFile

(HttpContext.Current.Server.MapPath(@"~\App_data\cities.shp"), true);
            //Define a blue 1px wide pen
            //layCities.Style.Symbol = new Bitmap(HttpContext.Current.Server.MapPath

(@"~\App_data\icon.png"));
            layCities.Style.SymbolScale = 0.8f;
            layCities.MaxVisible = 40;
            layCities.SRID = 4326;
            //Set up a country label layer
            SharpMap.Layers.LabelLayer layLabel = new SharpMap.Layers.LabelLayer

("Country labels");
            layLabel.DataSource = layCountries.DataSource;
            layLabel.Enabled = true;
            layLabel.LabelColumn = "Name";
            layLabel.Style = new SharpMap.Styles.LabelStyle();
            layLabel.Style.ForeColor = Color.White;
            layLabel.Style.Font = new Font(FontFamily.GenericSerif, 12);
            layLabel.Style.BackColor = new System.Drawing.SolidBrush(Color.FromArgb

(128,255,0,0));
            layLabel.MaxVisible = 90;
            layLabel.MinVisible = 30;
            layLabel.Style.HorizontalAlignment = 

SharpMap.Styles.LabelStyle.HorizontalAlignmentEnum.Center;
            layLabel.SRID = 4326;
            layLabel.MultipartGeometryBehaviour = 

SharpMap.Layers.LabelLayer.MultipartGeometryBehaviourEnum.Largest;
            //Set up a city label layer
            SharpMap.Layers.LabelLayer layCityLabel = new SharpMap.Layers.LabelLayer

("City labels");
            layCityLabel.DataSource = layCities.DataSource;
            layCityLabel.Enabled = true;
            layCityLabel.LabelColumn = "Name";
            layCityLabel.Style = new SharpMap.Styles.LabelStyle();
            layCityLabel.Style.ForeColor = Color.Black;
            layCityLabel.Style.Font = new Font(FontFamily.GenericSerif, 11);
            layCityLabel.MaxVisible = layLabel.MinVisible;
            layCityLabel.Style.HorizontalAlignment = 

SharpMap.Styles.LabelStyle.HorizontalAlignmentEnum.Left;
            layCityLabel.Style.VerticalAlignment = 

SharpMap.Styles.LabelStyle.VerticalAlignmentEnum.Bottom;
            layCityLabel.Style.Offset = new PointF(3, 3);
            layCityLabel.Style.Halo = new Pen(Color.Yellow, 2);
            layCityLabel.TextRenderingHint = 

System.Drawing.Text.TextRenderingHint.AntiAlias;
            layCityLabel.SmoothingMode = SmoothingMode.AntiAlias;
            layCityLabel.SRID = 4326;
            layCityLabel.LabelFilter = 

SharpMap.Rendering.LabelCollisionDetection.ThoroughCollisionDetection;
            layCityLabel.Style.CollisionDetection = true;
            //Add the layers to the map object.
            //The order we add them in are the order they are drawn, so we add the rivers 

last to put them on top
            map.Layers.Add(layCountries);
            map.Layers.Add(layRivers);
            map.Layers.Add(layCities);
            map.Layers.Add(layLabel);
            map.Layers.Add(layCityLabel);
            //limit the zoom to 360 degrees width
            map.MaximumZoom = 360;
            map.BackColor = Color.LightBlue;
            map.Zoom = 360;
            map.Center = new SharpMap.Geometries.Point(0,0);
            HttpContext.Current.Trace.Write("Map initialized");
            return map;
    }

在這段代碼中,

SharpMap.Layers.VectorLayer layCountries = new SharpMap.Layers.VectorLayer

("Countries");

layCountries.DataSource = new SharpMap.Data.Providers.ShapeFile

(HttpContext.Current.Server.MapPath(@"~\App_data\countries.shp"), true);

這兩句話定義並初始化了一個map的一個層。一個map可能包含多個層,我們對map進行操作,其實就是 對map的各個層進行操作,比如說道路層,建築層等等。根據業務的復雜程度,可能有很多個層。一般來 說,每個層都有各自的抽象特征(一類對象),可以進行一樣的操作。各個層組合起來,就是一個 map.

好,接著說初始化。這裡為VectorLayer的構造函數提供了一個層的名稱,然受設置了數據源。一個層 的Datasource是一個IProvider類型的數據,而ShapeFile類正是實現了Iprovider接口的類。(這點很重要 ,以後有很多機會需要把一個datasource轉換成ShapeFile)。

接下來是對這個層進行著色,呵呵 就是這個層上的對象如何填充顏色。這裡因為是剛剛開始,我們就 用最簡單的辦法,設置了一個

layCountries.Style.Fill = new SolidBrush(Color.Green);

這樣,就把層上的對象都填充成了綠色。在以後的講解中,我們會讓大家了解到如何自定義theme,這 樣我們能根據實現設置的對象的類型填充不同的顏色,以實現自定義的樣式,讓地圖多彩多姿。

然後我們看到label層。每一個map的layer都有自己的label層。

SharpMap.Layers.LabelLayer layLabel = new SharpMap.Layers.LabelLayer("Country labels");

   layLabel.DataSource = layCountries.DataSource;

   layLabel.Enabled = true;

   layLabel.LabelColumn = "Name";

這裡我們首先定義了一個label層,然後把countries層的datasource直接賦給label層的datasource就 OK了。這樣,這個新定義的label層就屬於countries層了。然後我們給它制定一個labelColumn,這個是必 須指定的。它表示countries層的每個對象應該顯示什麼內容。這個內容在ShapeFile(我們在MapWindow GIS中建立的shapefile文件)的attribute中進行增加和更新。

我想有必要說一下地圖的對象。

地圖上有很多點,線和多邊形。這些都是對象。我們都可以對他們進行操作。每個對象有相應的屬性 ,這些屬性我們也可以添加,修改和刪除。而上述的label的LabelColumn就是這些屬性中的一個。我們在 這裡可以指定一個,也可以通過LabelStringDelegate來委托一個方法返回一個字符串(這個將在以後進 行詳細講解)。

OK,在設置了label的字體顏色,大小和背景色之後,有兩個個屬性是特別值得我們注意的。

layLabel.MaxVisible = 90;

ayLabel.MinVisible = 30;

這兩個值說明了我們在多大/多小的比例尺下可以看到這個label層。我就經常會忽略這個問題,以至 於在放大或縮小比例尺的時候看不到label,也找不到原因。

在初始化的最後,我們把所有的層都加到地圖中來,在設置一下最大的比例尺,背景色和中心點,就 可以了

map.Layers.Add(layCountries);

   map.Layers.Add(layRivers);

   map.Layers.Add(layCities);

   map.Layers.Add(layLabel);

   map.Layers.Add(layCityLabel);

   //limit the zoom to 360 degrees width

   map.MaximumZoom = 360;

   map.BackColor = Color.LightBlue;

最後,我們通過一個maphandler(ashx)把地圖輸出到頁面上。

System.Drawing.Bitmap img = (System.Drawing.Bitmap)map.GetMap();

context.Response.ContentType = "image/png";


  System.IO.MemoryStream MS = new System.IO.MemoryStream();

  img.Save(MS, System.Drawing.Imaging.ImageFormat.Png);

  // tidy up  

  img.Dispose();

  byte[] buffer = MS.ToArray();

  context.Response.OutputStream.Write(buffer, 0, buffer.Length);

這樣,簡單的地圖就出來了。怎麼樣,有成就感嗎?呵呵 

這裡的代碼都來自www.codeplex.com/sharpmap的demo,我只是對其中一些代碼進行了說明,有需要的 可以去下載。

下次我們將自己做一些更好玩的東西,當我們點擊地圖上某個對象,顯示出這個對象的若干信息,怎 麼樣,酷吧?

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved