粟卫民ID:suen
127359次访问,排名603好友26人,关注者70
suen的文章
原创 35 篇
翻译 5 篇
转载 41 篇
评论 59 篇
小粟的公告
终于完成GeoWeb开源社区(http://www.gisdev.cn)的搭建和初步测试,请大家注册用户,测试,并提出宝贵意见。
最近评论
quzhoushijie:
杭州百度推广
杭州网站优化
杭州百度代理
再推荐两篇不错的参考文献:
(1) ASP.NET 2.0 Callback实例讲解,http://blog.csdn.net/lxjhb/archive/2007/11/09/1875968.aspx
(2)深度解析Asp.Net2.0中的Callback机制,http://www.cnblogs.com/orin-chan/archive/2005/12/13/296……
phdbrianlee:on the fly--怎么能翻译成“飞行时”?
它在这里是“实时、即时、在线”的意思,在英文中常对应offline。
wf0522:不错,很适合初学者
momolulu:域名和空间已经开通,www.helpwenchuan.com
基于google map 来做,现在需要有热情,有爱心的能够一起合作的志愿者.
文章分类
收藏
    相册
    我的照片
    GIS
    .NET开源GIS翻译WiKi
    GeoWeb开源社区
    GIS空间站
    GIS论坛
    中科院地理所
    国家测绘局
    我的旧BLOG归档
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 基于.NET 2.0的GIS开源项目SharpMap分析手记(三):地图渲染分析收藏

    新一篇: 基于.NET 2.0的GIS开源项目SharpMap分析手记(四):地图数据访问机制分析 | 旧一篇: 基于.NET 2.0的GIS开源项目SharpMap分析手记(二):源代码总体结构分析

     
    1 运行过程
    我们通过实例来讲述SharpMap的运行过程和渲染(绘制)机制。首先打开Simple.aspx,可知此页面有一组单选框(3个,分别是放大、缩小和漫游)和一个图像按钮,用于显示地图。它的代码在Simple.aspx.cs中。
    打开Simple.aspx.cs,在Page_Load函数中是页面初始化代码。可知地图生成分两步:
    1.1 初始化地图
    //Set up the map. We use the method in the App_Code folder for initializing the map
    myMap = MapHelper.InitializeMap(new
     System.Drawing.Size((int)imgMap.Width.Value,(int)imgMap.Height.Value));
    我们找到MapHelper.InitializeMap函数,发现地图的初始化分为以下几步:
    (1)创建地图,创建图层
    //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);
     
    (2)基本的图层显示设置
    //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;
     
    (3)加入图层到地图
    //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);
     
    (4)地图放缩、背景、中心等设置
    //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);
     
    1.2 绘制并生成地图
    我们回到Simple.aspx.cs的Page_Load函数,发现下一步调用GenerateMap();
    //This is the initial view of the map. Zoom to the extents of the map:
    //myMap.ZoomToExtents();
    //or center on 0,0 and zoom to full earth (360 degrees)
    //myMap.Center = new SharpMap.Geometries.Point(0,0);
    //myMap.Zoom = 360;
    //Create the map
    GenerateMap();
    在同一文件中,GenerateMap()包含以下两步:
    (1)保存当前地图状态
    //Save the current mapcenter and zoom in the viewstate
    ViewState.Add("mapCenter", myMap.Center);
    ViewState.Add("mapZoom", myMap.Zoom);
    (2)渲染地图
    //Render map
    System.Drawing.Image img = myMap.GetMap();
    string imgID = SharpMap.Web.Caching.InsertIntoCache(1, img);
    imgMap.ImageUrl = "getmap.aspx?ID=" + HttpUtility.UrlEncode(imgID);
    它的核心就是通过myMap.GetMap()创建了一个地图图片。我们来看看这个GetMap()函数。
    在Map.cs文件中找到GetMap()函数,它分为以下几步:
    ①创建图像,得到图像绘制环境参数
    System.Drawing.Image img = new System.Drawing.Bitmap(this.Size.Width, this.Size.Height);
    System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(img);
    g.Transform = this.MapTransform;
    g.Clear(this.BackColor);
    g.PageUnit = System.Drawing.GraphicsUnit.Pixel;
    ②绘制图层
    int SRID = (Layers.Count > 0 ? Layers[0].SRID : -1); //Get the SRID of the first layer
    for (int i = 0; i < _Layers.Count; i++)
    {
    if (_Layers[i].Enabled && _Layers[i].MaxVisible >= this.Zoom && _Layers[i].MinVisible < this.Zoom)
    _Layers[i].Render(g, this);
    }
    关键在于_Layers[i].Render(g, this),它是ILayer接口的一个函数,我们找VectorLayer的实现来看看,它分为两种,一种是专题地图,一种是非专题地图绘制。
    对于专题地图,它针对SharpMap.Data.FeatureDataTable的每一个feature进行绘制,先绘制其外框,再绘制内部几何体。对于非专题地图,它针对this.DataSource.GetGeometriesInView(envelope)得到的几何体进行绘制,也是先绘制其外框,再绘制内部几何体。最后的绘制工作都调用SharpMap.Rendering.VectorRenderer类的函数完成。SharpMap.Rendering.VectorRenderer类包含绘制注记、线串、多线串、多点、多多边形、点、多边形等。
    绘制好图层后将激发LayerRendered事件:
    if(LayerRendered!=null) LayerRendered(this, g); //Fire event
    绘制好地图后将激发Map类的MapRendered 事件:
    if (MapRendered != null) MapRendered(g); //Fire render event
    2 SharpMap.Rendering.VectorRenderer的各个函数具体分析
    现在我们对渲染地图的全过程已经有了个总体概念和初步理解,下面来具体看一下SharpMap.Rendering.VectorRenderer的各个函数:
    2.1 DrawLabel
            /// <summary>
            /// Renders a label to the map.
            /// </summary>
            /// <param name="g">Graphics reference</param>
            /// <param name="LabelPoint">Label placement</param>
            /// <param name="Offset">Offset of label in screen coordinates</param>
            /// <param name="font">Font used for rendering</param>
            /// <param name="forecolor">Font forecolor</param>
            /// <param name="backcolor">Background color</param>
            /// <param name="halo">Color of halo</param>
            /// <param name="rotation">Text rotation in degrees</param>
            /// <param name="text">Text to render</param>
            /// <param name="map">Map reference</param>
    public static void DrawLabel(System.Drawing.Graphics g, System.Drawing.PointF LabelPoint, System.Drawing.PointF Offset, System.Drawing.Font font, System.Drawing.Color forecolor, System.Drawing.Brush backcolor, System.Drawing.Pen halo, float rotation, string text, SharpMap.Map map)
    这里面要注意的是这是绘制使用的函数是DrawPath和FillPath,而且是作者从DrawString改进的,可能是为了绘制过程的统一,因为其它几何体的具体绘制也使用DrawPath。
    if (halo != null)
    g.DrawPath(halo, path);
    g.FillPath(new System.Drawing.SolidBrush(forecolor), path);
    //g.DrawString(text, font, new System.Drawing.SolidBrush(forecolor), LabelPoint.X, LabelPoint.Y);
    2.2 DrawLineString
    /// <summary>
    /// Renders a LineString to the map.
    /// </summary>
    /// <param name="g">Graphics reference</param>
    /// <param name="line">LineString to render</param>
    /// <param name="pen">Pen style used for rendering</param>
    /// <param name="map">Map reference</param>
    public static void DrawLineString(System.Drawing.Graphics g, Geometries.LineString line, System.Drawing.Pen pen, SharpMap.Map map)
    这个函数很简单,也是采用DrawPath进行具体绘制。
    2.3 DrawMultiLineString
    /// <summary>
    /// Renders a MultiLineString to the map.
    /// </summary>
    /// <param name="g">Graphics reference</param>
    /// <param name="lines">MultiLineString to be rendered</param>
    /// <param name="pen">Pen style used for rendering</param>
    /// <param name="map">Map reference</param>
    public static void DrawMultiLineString(System.Drawing.Graphics g,
    Geometries.MultiLineString lines, System.Drawing.Pen pen, SharpMap.Map map)
    它通过循环调用DrawLineString来进行绘制。
    2.4 DrawMultiPoint
    /// <summary>
    /// Renders a <see cref="SharpMap.Geometries.MultiPoint"/> to the map.
    /// </summary>
    /// <param name="g">Graphics reference</param>
    /// <param name="points">MultiPoint to render</param>
    /// <param name="symbol">Symbol to place over point</param>
    /// <param name="symbolscale">The amount that the symbol should be scaled. A scale of '1' equals to no scaling</param>
    /// <param name="offset">Symbol offset af scale=1</param>
    /// <param name="rotation">Symbol rotation in degrees</param>
    /// <param name="map">Map reference</param>
    public static void DrawMultiPoint(System.Drawing.Graphics g, Geometries.MultiPoint points, System.Drawing.Bitmap symbol, float symbolscale, System.Drawing.PointF offset, float rotation, SharpMap.Map map)
    它通过循环调用DrawPoint来进行绘制。
    2.5 DrawMultiPolygon
    /// <summary>
    /// Renders a multipolygon byt rendering each polygon in the collection by calling DrawPolygon.
    /// </summary>
    /// <param name="g">Graphics reference</param>
    /// <param name="pols">MultiPolygon to render</param>
    /// <param name="brush">Brush used for filling (null or transparent for no filling)</param>
    /// <param name="pen">Outline pen style (null if no outline)</param>
    /// <param name="clip">Specifies whether polygon clipping should be applied</param>
    /// <param name="map">Map reference</param>
    public static void DrawMultiPolygon(System.Drawing.Graphics g, Geometries.MultiPolygon pols, System.Drawing.Brush brush, System.Drawing.Pen pen, bool clip, SharpMap.Map map)
    它通过循环调用DrawPolygon来进行绘制。
    2.6 DrawPoint
    /// <summary>
    /// Renders a point to the map.
    /// </summary>
    /// <param name="g">Graphics reference</param>
    /// <param name="point">Point to render</param>
    /// <param name="symbol">Symbol to place over point</param>
    /// <param name="symbolscale">The amount that the symbol should be scaled. A scale of '1' equals to no scaling</param>
    /// <param name="offset">Symbol offset af scale=1</param>
    /// <param name="rotation">Symbol rotation in degrees</param>
    /// <param name="map">Map reference</param>
    public static void DrawPoint(System.Drawing.Graphics g, SharpMap.Geometries.Point point, System.Drawing.Bitmap symbol, float symbolscale, System.Drawing.PointF offset, float rotation, SharpMap.Map map)
    其中,symbol参数为一个位图,代表点的符号,这说明SharpMap暂时只支持位图符号,不支持矢量符号绘制。最终绘制调用DrawImage。
    2.7 DrawPolygon
    /// <summary>
    /// Renders a polygon to the map.
    /// </summary>
    /// <param name="g">Graphics reference</param>
    /// <param name="pol">Polygon to render</param>
    /// <param name="brush">Brush used for filling (null or transparent for no filling)</param>
    /// <param name="pen">Outline pen style (null if no outline)</param>
    /// <param name="clip">Specifies whether polygon clipping should be applied</param>
    /// <param name="map">Map reference</param>
    public static void DrawPolygon(System.Drawing.Graphics g, SharpMap.Geometries.Polygon pol, System.Drawing.Brush brush, System.Drawing.Pen pen, bool clip, SharpMap.Map map)
    它只支持用不同的画刷和画笔来绘制多边形,也是采用DrawPath进行具体绘制。
    3 总结
    结合源代码,本文对SharpMap的渲染机制进行了初步探讨。现阶段SharpMap(0.9版)只支持位图点符号和基本的线和多边形风格,对于矢量符号还没有什么支持。这对于网上电子地图还是可以的,但如果要用于打印出版就略嫌不足,希望以后能扩充这方面。另外,对于XAML渲染地图和分级图(Gradient Map)等,也将放在以后做进一步讨论。

    发表于 @ 2006年12月07日 08:40:00|评论(loading...)|编辑

    新一篇: 基于.NET 2.0的GIS开源项目SharpMap分析手记(四):地图数据访问机制分析 | 旧一篇: 基于.NET 2.0的GIS开源项目SharpMap分析手记(二):源代码总体结构分析

    评论:没有评论。

    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © 小粟