地图Map有各种不同的图层Layer组成,图层可以是不同类型(点线面),相关联的图层可以形成图层组LayerGroup,例如一级道路,二级道路,普通道路这三个图层可以组成一个交通道路图层组。
分层的想法最早可追溯到20世纪60年代的景观建筑与环境敏感性规划领域,这也是GIS的第三个学科来源。每个层代表地表环境的的特定组成。这些层可以包括地下水,自然植被或土壤。
那么看下ILayer接口
这个接口包括一个方法:渲染图层Render
和若干属性:名字LayerName,唯一标识SRID,是否渲染Enabled,最小可见缩放级MinVisible和最大可见缩放级MaxVisible,如果地图缩放级别在此区间之外,则不可见(对于配置地图效果尤为重要),最后还有此图层的所有数据最小外接矩形Envelope
抽象类Layer具有IClone接口,表明具有复制功能(PS:微软不建议使用此接口,因为无法确定此接口的实现的是浅复制还是深复制,建议用两个方法代替)。
同时多了一个坐标转换属性CoordinateTransformation,此属性包括一个源坐标系SourceCS和一个目标坐标系TargetCS以及两坐标系之间的数学转换对象MapTransform,源坐标系SourceCS即为地图数据的坐标系,目标坐标系TargetCS则为用户想要渲染的地图坐标系,前面Map的Zoom,Center,Envlope等等包括MapToWorld转换方法返回的地理坐标均是此坐标系下地理坐标。对于矢量图层VectorLayer和标注图层LabelLayer来说,如果设置此属性,此图层被渲染时则使用数学转换对象MapTransform对原始数据进行坐标转换,然后根据转换后的数据进行渲染。若没有设置(为null),则目标坐标系TargetCS=SourceCS即为图层数据的实际坐标系
if (this.CoordinateTransformation != null) for (int i = 0; i < features.Count; i++) features[i].Geometry = SharpMap.CoordinateSystems.Transformations.GeometryTransform.TransformGeometry(features[i].Geometry, this.CoordinateTransformation.MathTransform);
另外抽象类Layer具有一个LayerRenderedEventHandler类型事件用于扩展与图层渲染相关的行为
实际的图层类型有VectorLayer,LabelLayer,LayerGroup和WmsLayer
先看VectorLayer 首先其实现了ILayer接口的render方法
Render方法根据专题Theme(有的话)或默认Style依次调用私有方法RenderGeometry渲染每个几何对象,RenderGeometry根据每个几何对象类型分别调用VectorRender的不同方法完成渲染。前面关注的渲染流程里图层的渲染方法其实就是矢量图层的这个染Render方法。
同时VectorLayer实现Envelope属性。先通过数据源的GetExtents方法得到数据实际坐标下所有数据最小外接矩形,如果设置坐标转换则转换为目标坐标下最小外接矩形,如果不需要转换,则直接返回。
public override BoundingBox Envelope { get { if (this.DataSource == null) throw (new ApplicationException("DataSource property not set on layer '" + this.LayerName + "'")); bool wasOpen = this.DataSource.IsOpen; if (!wasOpen) this.DataSource.Open(); SharpMap.Geometries.BoundingBox box = this.DataSource.GetExtents(); if (!wasOpen) //Restore state this.DataSource.Close(); if (this.CoordinateTransformation != null) return SharpMap.CoordinateSystems.Transformations.GeometryTransform.TransformBox(box, this.CoordinateTransformation.MathTransform); return box; } }
图层的数据由成员DataSource提供,DataSource是SharpMap.Data.Providers.IProvider类型(这里使用Provider模式便于扩展)
此接口提供ExecuteIntersectionQuery和GetExtents等等方法获取数据。性能的瓶颈就在这儿了,一般需要有空间索引支持快速的数据访问。
Style属性用于指定渲染样式
如果需要生成专题图则设置Theme属性
如果需要支持多边形裁剪则设置ClippingEnabled为True,默认为False
另外VectorLayer还支持GDI+的抗锯齿效果,设置SmoothingMode属性即可
总结:Layer主要保存所有数据最小外接矩形,标识符,名字,坐标转换,可见性等;
VectorLayer主要保存对图层数据的访问接口(DataSource),负责渲染实现(Render)和渲染效果(Theme,Style,SmoothingMode)