我写的东西内容浅显,希望能给初学者一些帮助。至于深入研究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学习(3)

  地图填充完了,我们要在上面显示出到底他们是什么。在第一篇中,我们已经可以把对象的一个属性显示出来,但是当地图扩大到一定比例时,仅仅显示名字这一种信息已经不足以满足用户的需要了。比如说一栋房子,在很远处看它时,我们只需要看到他的颜色就行了。但是当我们离的很近的时候,难道看到的是全白色吗?显然不是,我们还可以看到门牌号,窗户上的贴纸以及其它详细信息。地图也一样,当比例尺改变以后,应该有更详细的信息被列出来。老规矩,先贴代码:

  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("rn" + field3);

            return sb.ToString();
        }

  代码简单的要死,不再详述,值得注意的是:如果要换行,请使用“rn”, 这里不支持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语句里就行了。简单吧?

posted on 2012-12-18 16:31  骑牛射雕  阅读(325)  评论(0编辑  收藏  举报