SharpMap学习(1)

最近公司想在一个产品上加一个电子地图的功能,让我有机会接触到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

 

在这段代码中,
   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,我只是对其中一些代码进行了说明,有需要的可以去下载。

下次我们将自己做一些更好玩的东西,当我们点击地图上某个对象,显示出这个对象的若干信息,怎么样,酷吧?

希望大家继续关注哦。也希望对sharpmap了解的同志多多上来拍砖。

 

 

 

 

 

 


 

posted @ 2009-02-27 00:04  GodSpeed  阅读(6750)  评论(14编辑  收藏  举报