第03章-核心架构与类库设计
第03章:核心架构与类库设计
3.1 SharpMap 整体架构
3.1.1 架构概览
SharpMap 采用分层架构设计,各层职责明确,耦合度低:
┌─────────────────────────────────────────────────────────────────────────┐
│ 表现层 (Presentation Layer) │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ MapBox │ │ MapImage │ │ Custom Control │ │
│ │ (WinForms) │ │ (WinForms) │ │ (WPF) │ │
│ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │
└───────────┼─────────────────────┼────────────────────┼──────────────────┘
│ │ │
└──────────────┬──────┴────────────────────┘
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ 核心层 (Core Layer) │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Map │──│ Layers │──│ Styles │ │
│ │ (地图对象) │ │ (图层集合) │ │ (样式系统) │ │
│ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │
│ │ │ │ │
│ ┌────────┴────────┐ ┌────────┴────────┐ ┌────────┴────────┐ │
│ │ Rendering │ │ Thematics │ │ Transformations│ │
│ │ (渲染器) │ │ (主题渲染) │ │ (坐标变换) │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ 数据层 (Data Layer) │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ IProvider │ │ FeatureDataSet │ │ Geometry │ │
│ │ (数据提供者) │ │ (要素数据) │ │ (几何对象) │ │
│ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │
│ │ │ │ │
│ ┌────────┴────────────────────┴────────────────────┴────────┐ │
│ │ Provider 实现 │ │
│ │ ShapeFile │ PostGIS │ Ogr │ WMS │ MsSql │ GeoJSON │ ... │ │
│ └───────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
3.1.2 核心命名空间
SharpMap 的主要命名空间及其功能:
| 命名空间 | 功能描述 |
|---|---|
SharpMap |
核心类型,包含 Map 类 |
SharpMap.Layers |
图层类型定义 |
SharpMap.Data |
数据模型和数据集 |
SharpMap.Data.Providers |
数据提供者实现 |
SharpMap.Styles |
样式和符号定义 |
SharpMap.Rendering |
渲染器和渲染逻辑 |
SharpMap.Rendering.Thematics |
主题渲染 |
SharpMap.CoordinateSystems |
坐标系统 |
SharpMap.Utilities |
工具类 |
SharpMap.Forms |
WinForms 控件 |
3.1.3 类图概览
┌─────────────────┐
│ Map │
│ (地图容器) │
└────────┬────────┘
│
┌───────────────┼───────────────┐
│ │ │
▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌────────────┐
│ Layers │ │ Background │ │ Variable │
│ Collection │ │ Layers │ │ Layers │
└─────┬──────┘ └─────┬──────┘ └─────┬──────┘
│ │ │
└───────────────┼───────────────┘
│
┌────────────┴────────────┐
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Layer │ │ IProvider │
│ (抽象基类) │ │ (数据接口) │
└──────┬──────┘ └──────┬──────┘
│ │
┌──────────────┼──────────────┐ │
│ │ │ │
▼ ▼ ▼ ▼
┌─────────┐ ┌───────────┐ ┌─────────┐ ┌─────────┐
│Vector │ │ Label │ │ Tile │ │ShapeFile│
│Layer │ │ Layer │ │ Layer │ │Provider │
└─────────┘ └───────────┘ └─────────┘ └─────────┘
3.2 Map 类详解
3.2.1 Map 类定义
Map 类是 SharpMap 的核心类,负责管理地图的所有组件:
namespace SharpMap
{
public class Map : IDisposable
{
// 构造函数
public Map();
public Map(Size size);
// 主要属性
public Size Size { get; set; }
public Color BackColor { get; set; }
public int SRID { get; set; }
public Envelope Envelope { get; set; }
public double Zoom { get; set; }
public Coordinate Center { get; set; }
public double MinimumZoom { get; set; }
public double MaximumZoom { get; set; }
public double PixelSize { get; }
public double PixelWidth { get; }
public double PixelHeight { get; }
public double MapScale { get; }
// 图层集合
public LayerCollection Layers { get; }
public LayerCollection BackgroundLayer { get; }
public LayerCollection VariableLayers { get; }
// 主要方法
public Image GetMap();
public void ZoomToExtents();
public void ZoomToBox(Envelope envelope);
public Coordinate ImageToWorld(PointF point);
public PointF WorldToImage(Coordinate point);
// 坐标转换
public ICoordinateTransformation CoordinateTransformation { get; set; }
// 资源释放
public void Dispose();
}
}
3.2.2 Map 属性详解
尺寸和外观属性:
// 创建地图
var map = new Map(new Size(800, 600));
// 设置背景颜色
map.BackColor = Color.LightBlue;
// 获取/设置地图大小
map.Size = new Size(1024, 768);
// 获取像素大小(地图单位/像素)
double pixelSize = map.PixelSize;
double pixelWidth = map.PixelWidth;
double pixelHeight = map.PixelHeight;
空间属性:
// 设置空间参考
map.SRID = 4326; // WGS84
// 获取/设置地图范围
Envelope extent = map.Envelope;
map.Envelope = new Envelope(-180, 180, -90, 90);
// 获取/设置中心点
Coordinate center = map.Center;
map.Center = new Coordinate(116.4, 39.9);
// 获取/设置缩放级别
double zoom = map.Zoom;
map.Zoom = 10000; // 地图单位
// 缩放限制
map.MinimumZoom = 0.1;
map.MaximumZoom = 1000000;
比例尺:
// 获取当前地图比例尺
double scale = map.MapScale;
Console.WriteLine($"当前比例尺:1:{scale:N0}");
// 设置特定比例尺
map.Zoom = map.GetMapHeight(scale);
3.2.3 图层集合管理
// 普通图层集合(按添加顺序渲染)
map.Layers.Add(vectorLayer);
map.Layers.Insert(0, baseLayer);
map.Layers.Remove(layer);
map.Layers.Clear();
// 背景图层集合(先渲染)
map.BackgroundLayer.Add(tileLayer);
// 动态图层集合(每次重绘都重新获取数据)
map.VariableLayers.Add(realtimeLayer);
// 遍历图层
foreach (ILayer layer in map.Layers)
{
Console.WriteLine($"图层:{layer.LayerName}");
}
// 按名称获取图层
var layer = map.Layers.FirstOrDefault(l => l.LayerName == "States");
3.2.4 坐标转换方法
// 像素坐标转地理坐标
PointF screenPoint = new PointF(400, 300);
Coordinate worldPoint = map.ImageToWorld(screenPoint);
Console.WriteLine($"地理坐标:{worldPoint.X}, {worldPoint.Y}");
// 地理坐标转像素坐标
Coordinate geoPoint = new Coordinate(116.4, 39.9);
PointF pixelPoint = map.WorldToImage(geoPoint);
Console.WriteLine($"像素坐标:{pixelPoint.X}, {pixelPoint.Y}");
3.2.5 渲染方法
// 渲染地图到 Image
Image mapImage = map.GetMap();
// 保存为文件
mapImage.Save("output.png", ImageFormat.Png);
mapImage.Save("output.jpg", ImageFormat.Jpeg);
// 渲染到 Graphics
using (var bitmap = new Bitmap(800, 600))
using (var graphics = Graphics.FromImage(bitmap))
{
map.RenderMap(graphics);
bitmap.Save("output.png");
}
3.3 图层类体系
3.3.1 ILayer 接口
namespace SharpMap.Layers
{
public interface ILayer : ICloneable
{
// 基本属性
string LayerName { get; set; }
bool Enabled { get; set; }
int SRID { get; set; }
Envelope Envelope { get; }
// 可见性
double MinVisible { get; set; }
double MaxVisible { get; set; }
// 坐标转换
ICoordinateTransformation CoordinateTransformation { get; set; }
// 渲染
void Render(Graphics g, Map map);
}
}
3.3.2 Layer 抽象基类
namespace SharpMap.Layers
{
public abstract class Layer : ILayer, IDisposable
{
// 构造函数
protected Layer(string layerName);
// 属性
public virtual string LayerName { get; set; }
public virtual bool Enabled { get; set; }
public virtual int SRID { get; set; }
public abstract Envelope Envelope { get; }
public virtual double MinVisible { get; set; }
public virtual double MaxVisible { get; set; }
public virtual double VisibilityUnits { get; set; }
// 坐标转换
public ICoordinateTransformation CoordinateTransformation { get; set; }
public ICoordinateTransformation ReverseCoordinateTransformation { get; set; }
// 抽象方法
public abstract void Render(Graphics g, Map map);
// 释放资源
public virtual void Dispose();
}
}
3.3.3 VectorLayer 类
VectorLayer 是最常用的图层类型,用于渲染矢量数据:
namespace SharpMap.Layers
{
public class VectorLayer : Layer
{
// 构造函数
public VectorLayer(string layerName);
public VectorLayer(string layerName, IProvider dataSource);
// 数据源
public IProvider DataSource { get; set; }
// 样式
public VectorStyle Style { get; set; }
// 主题渲染
public ITheme Theme { get; set; }
// 平滑模式
public SmoothingMode SmoothingMode { get; set; }
// 剪裁
public bool ClippingEnabled { get; set; }
// 重写方法
public override Envelope Envelope { get; }
public override void Render(Graphics g, Map map);
// 执行点击查询
public FeatureDataSet ExecuteIntersectionQuery(Envelope envelope);
public FeatureDataSet ExecuteIntersectionQuery(Geometry geometry);
}
}
VectorLayer 使用示例:
// 创建矢量图层
var vectorLayer = new VectorLayer("Countries");
// 设置数据源
vectorLayer.DataSource = new ShapeFile("countries.shp", true);
// 设置样式
vectorLayer.Style = new VectorStyle
{
Fill = new SolidBrush(Color.LightGreen),
Outline = new Pen(Color.DarkGreen, 1),
EnableOutline = true,
PointColor = Brushes.Red,
PointSize = 10
};
// 设置平滑模式
vectorLayer.SmoothingMode = SmoothingMode.AntiAlias;
// 启用剪裁
vectorLayer.ClippingEnabled = true;
// 设置可见比例尺范围
vectorLayer.MinVisible = 1000;
vectorLayer.MaxVisible = 10000000;
// 添加到地图
map.Layers.Add(vectorLayer);
3.3.4 LabelLayer 类
LabelLayer 用于在地图上渲染文字标注:
namespace SharpMap.Layers
{
public class LabelLayer : Layer
{
// 构造函数
public LabelLayer(string layerName);
// 数据源
public IProvider DataSource { get; set; }
// 标注列
public string LabelColumn { get; set; }
// 样式
public LabelStyle Style { get; set; }
// 主题
public ITheme Theme { get; set; }
// 标注委托(动态生成标注文本)
public GetLabelMethod LabelStringDelegate { get; set; }
// 优先级列(用于标注冲突解决)
public string PriorityColumn { get; set; }
// 旋转列
public string RotationColumn { get; set; }
// 多行标注
public MultipartGeometryBehaviourEnum MultipartGeometryBehaviour { get; set; }
// 平滑模式
public SmoothingMode SmoothingMode { get; set; }
public TextRenderingHint TextRenderingHint { get; set; }
}
// 标注委托类型
public delegate string GetLabelMethod(FeatureDataRow row);
}
LabelLayer 使用示例:
// 创建标注图层
var labelLayer = new LabelLayer("Country Labels");
// 设置数据源(通常与矢量图层相同)
labelLayer.DataSource = vectorLayer.DataSource;
// 设置标注字段
labelLayer.LabelColumn = "NAME";
// 设置样式
labelLayer.Style = new LabelStyle
{
Font = new Font("Arial", 12, FontStyle.Bold),
ForeColor = Color.Black,
BackColor = new SolidBrush(Color.FromArgb(200, 255, 255, 255)),
HorizontalAlignment = LabelStyle.HorizontalAlignmentEnum.Center,
VerticalAlignment = LabelStyle.VerticalAlignmentEnum.Middle,
Offset = new PointF(0, 0),
Halo = new Pen(Color.White, 2),
CollisionDetection = true,
CollisionBuffer = new SizeF(5, 5)
};
// 使用委托动态生成标注文本
labelLayer.LabelStringDelegate = (row) =>
{
string name = row["NAME"].ToString();
double area = Convert.ToDouble(row["AREA"]);
return $"{name}\n({area:N0} km²)";
};
// 设置优先级(高优先级的标注更容易显示)
labelLayer.PriorityColumn = "POPULATION";
// 添加到地图
map.Layers.Add(labelLayer);
3.3.5 TileLayer 类
TileLayer 用于显示瓦片地图服务:
// 需要安装 SharpMap.Layers.BruTile 包
using SharpMap.Layers;
using BruTile;
using BruTile.Web;
// 创建 OpenStreetMap 瓦片源
var osmTileSource = new HttpTileSource(
new GlobalSphericalMercator(),
"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
new[] { "a", "b", "c" },
"OSM");
// 创建瓦片图层
var tileLayer = new TileLayer(osmTileSource, "OpenStreetMap");
// 添加到背景图层
map.BackgroundLayer.Add(tileLayer);
3.3.6 GdalRasterLayer 类
GdalRasterLayer 用于显示栅格数据(需要 SharpMap.Extensions):
using SharpMap.Layers;
// 创建栅格图层
var rasterLayer = new GdalRasterLayer("Satellite", "satellite.tif");
// 设置透明度
rasterLayer.Transparency = 0.5f;
// 设置透明色
rasterLayer.TransparentColor = Color.Black;
// 添加到地图
map.Layers.Add(rasterLayer);
3.4 数据提供者体系
3.4.1 IProvider 接口
namespace SharpMap.Data.Providers
{
public interface IProvider : IDisposable
{
// 连接状态
string ConnectionID { get; }
bool IsOpen { get; }
void Open();
void Close();
// 空间参考
int SRID { get; set; }
// 数据范围
Envelope GetExtents();
// 查询方法
Collection<Geometry> GetGeometriesInView(Envelope envelope);
Collection<uint> GetObjectIDsInView(Envelope envelope);
Geometry GetGeometryByID(uint oid);
// 要素查询
void ExecuteIntersectionQuery(Envelope envelope, FeatureDataSet ds);
void ExecuteIntersectionQuery(Geometry geometry, FeatureDataSet ds);
FeatureDataRow GetFeature(uint oid);
// 要素数量
int GetFeatureCount();
}
}
3.4.2 常用数据提供者
ShapeFile 提供者:
using SharpMap.Data.Providers;
// 创建 ShapeFile 提供者
var provider = new ShapeFile("data.shp");
var provider2 = new ShapeFile("data.shp", true); // 使用文件索引
var provider3 = new ShapeFile("data.shp", true, true); // 使用空间索引
// 检查属性
Console.WriteLine($"文件路径:{provider.Filename}");
Console.WriteLine($"要素数量:{provider.GetFeatureCount()}");
Console.WriteLine($"数据范围:{provider.GetExtents()}");
// 获取属性表结构
provider.Open();
var table = provider.GetSchemaTable();
foreach (DataColumn column in table.Columns)
{
Console.WriteLine($"字段:{column.ColumnName} ({column.DataType})");
}
provider.Close();
PostGIS 提供者:
using SharpMap.Data.Providers;
// 创建 PostGIS 提供者
string connectionString = "Host=localhost;Database=gisdb;Username=user;Password=pass";
var provider = new PostGIS(connectionString, "tablename", "geom", "gid");
// 设置 SRID
provider.SRID = 4326;
// 设置要查询的字段
provider.DefinitionQuery = "status = 'active'";
// 使用
var layer = new VectorLayer("PostGIS Data", provider);
OGR 提供者(需要 GDAL):
using SharpMap.Data.Providers;
// 创建 OGR 提供者
var provider = new Ogr("data.geojson");
var provider2 = new Ogr("data.kml", 0); // 指定图层索引
// 支持的格式包括:GeoJSON, KML, GML, GPX, CSV 等
3.4.3 自定义数据提供者
using System.Collections.ObjectModel;
using SharpMap.Data;
using SharpMap.Data.Providers;
using NetTopologySuite.Geometries;
public class CustomProvider : IProvider
{
private bool _isOpen;
private List<Geometry> _geometries;
private List<Dictionary<string, object>> _attributes;
public CustomProvider()
{
_geometries = new List<Geometry>();
_attributes = new List<Dictionary<string, object>>();
}
public string ConnectionID => "Custom";
public bool IsOpen => _isOpen;
public int SRID { get; set; } = 4326;
public void Open()
{
_isOpen = true;
}
public void Close()
{
_isOpen = false;
}
public void AddFeature(Geometry geometry, Dictionary<string, object> attributes)
{
_geometries.Add(geometry);
_attributes.Add(attributes);
}
public Envelope GetExtents()
{
if (_geometries.Count == 0)
return new Envelope();
var env = new Envelope();
foreach (var geom in _geometries)
{
env.ExpandToInclude(geom.EnvelopeInternal);
}
return env;
}
public Collection<Geometry> GetGeometriesInView(Envelope envelope)
{
var result = new Collection<Geometry>();
foreach (var geom in _geometries)
{
if (envelope.Intersects(geom.EnvelopeInternal))
{
result.Add(geom);
}
}
return result;
}
public Collection<uint> GetObjectIDsInView(Envelope envelope)
{
var result = new Collection<uint>();
for (int i = 0; i < _geometries.Count; i++)
{
if (envelope.Intersects(_geometries[i].EnvelopeInternal))
{
result.Add((uint)i);
}
}
return result;
}
public Geometry GetGeometryByID(uint oid)
{
if (oid < _geometries.Count)
return _geometries[(int)oid];
return null;
}
public void ExecuteIntersectionQuery(Envelope envelope, FeatureDataSet ds)
{
var table = new FeatureDataTable();
// 添加字段
if (_attributes.Count > 0)
{
foreach (var key in _attributes[0].Keys)
{
table.Columns.Add(key);
}
}
// 添加要素
for (int i = 0; i < _geometries.Count; i++)
{
if (envelope.Intersects(_geometries[i].EnvelopeInternal))
{
var row = table.NewRow();
row.Geometry = _geometries[i];
if (i < _attributes.Count)
{
foreach (var kvp in _attributes[i])
{
row[kvp.Key] = kvp.Value;
}
}
table.AddRow(row);
}
}
ds.Tables.Add(table);
}
public void ExecuteIntersectionQuery(Geometry geometry, FeatureDataSet ds)
{
ExecuteIntersectionQuery(geometry.EnvelopeInternal, ds);
}
public FeatureDataRow GetFeature(uint oid)
{
// 实现获取单个要素
throw new NotImplementedException();
}
public int GetFeatureCount()
{
return _geometries.Count;
}
public void Dispose()
{
_geometries.Clear();
_attributes.Clear();
}
}
// 使用自定义提供者
var customProvider = new CustomProvider();
// 添加一些测试数据
var factory = new GeometryFactory();
customProvider.AddFeature(
factory.CreatePoint(new Coordinate(116.4, 39.9)),
new Dictionary<string, object> { { "Name", "Beijing" }, { "Population", 21540000 } }
);
customProvider.AddFeature(
factory.CreatePoint(new Coordinate(121.5, 31.2)),
new Dictionary<string, object> { { "Name", "Shanghai" }, { "Population", 24280000 } }
);
// 使用提供者创建图层
var layer = new VectorLayer("Custom Data", customProvider);
3.5 样式系统
3.5.1 VectorStyle 类
namespace SharpMap.Styles
{
public class VectorStyle : Style
{
// 填充
public Brush Fill { get; set; }
// 边框
public Pen Outline { get; set; }
public bool EnableOutline { get; set; }
// 线
public Pen Line { get; set; }
// 点
public Brush PointColor { get; set; }
public float PointSize { get; set; }
public PointSymbolizer Symbol { get; set; }
// 默认样式
public static VectorStyle Default { get; }
public static VectorStyle CreateRandomStyle();
}
}
样式示例:
// 多边形样式
var polygonStyle = new VectorStyle
{
Fill = new SolidBrush(Color.FromArgb(150, 100, 200, 100)),
Outline = new Pen(Color.DarkGreen, 2),
EnableOutline = true
};
// 渐变填充
var gradientStyle = new VectorStyle
{
Fill = new LinearGradientBrush(
new Rectangle(0, 0, 100, 100),
Color.LightBlue,
Color.DarkBlue,
45f),
Outline = new Pen(Color.Navy, 1),
EnableOutline = true
};
// 线样式
var lineStyle = new VectorStyle
{
Line = new Pen(Color.Red, 3)
{
DashStyle = DashStyle.Dash,
StartCap = LineCap.Round,
EndCap = LineCap.ArrowAnchor
}
};
// 点样式
var pointStyle = new VectorStyle
{
PointColor = Brushes.Red,
PointSize = 12
};
// 使用图标符号
var symbolStyle = new VectorStyle
{
Symbol = new ImageSymbol(Image.FromFile("marker.png"))
};
3.5.2 LabelStyle 类
namespace SharpMap.Styles
{
public class LabelStyle : Style
{
// 字体
public Font Font { get; set; }
// 颜色
public Color ForeColor { get; set; }
public Brush BackColor { get; set; }
// 光晕效果
public Pen Halo { get; set; }
// 对齐方式
public HorizontalAlignmentEnum HorizontalAlignment { get; set; }
public VerticalAlignmentEnum VerticalAlignment { get; set; }
// 偏移
public PointF Offset { get; set; }
// 旋转
public float Rotation { get; set; }
// 碰撞检测
public bool CollisionDetection { get; set; }
public SizeF CollisionBuffer { get; set; }
// 对齐枚举
public enum HorizontalAlignmentEnum { Left, Center, Right }
public enum VerticalAlignmentEnum { Top, Middle, Bottom }
}
}
标注样式示例:
var labelStyle = new LabelStyle
{
// 字体设置
Font = new Font("Microsoft YaHei", 10, FontStyle.Regular),
ForeColor = Color.Black,
// 背景
BackColor = new SolidBrush(Color.FromArgb(200, 255, 255, 200)),
// 光晕效果(提高可读性)
Halo = new Pen(Color.White, 3),
// 对齐
HorizontalAlignment = LabelStyle.HorizontalAlignmentEnum.Center,
VerticalAlignment = LabelStyle.VerticalAlignmentEnum.Bottom,
// 偏移
Offset = new PointF(0, -10),
// 碰撞检测
CollisionDetection = true,
CollisionBuffer = new SizeF(10, 10)
};
3.6 渲染器体系
3.6.1 渲染流程
Map.GetMap()
│
▼
遍历 BackgroundLayer
│
▼
遍历 Layers
│
├──► VectorLayer.Render()
│ │
│ ▼
│ 获取可视范围内的几何
│ │
│ ▼
│ 应用样式/主题
│ │
│ ▼
│ 渲染几何到 Graphics
│
├──► LabelLayer.Render()
│ │
│ ▼
│ 获取标注数据
│ │
│ ▼
│ 碰撞检测
│ │
│ ▼
│ 渲染标注文本
│
└──► TileLayer.Render()
│
▼
计算需要的瓦片
│
▼
获取/缓存瓦片
│
▼
渲染瓦片到 Graphics
│
▼
遍历 VariableLayers
│
▼
返回 Image
3.6.2 自定义渲染
public class CustomVectorLayer : VectorLayer
{
public CustomVectorLayer(string layerName) : base(layerName)
{
}
public override void Render(Graphics g, Map map)
{
// 设置渲染质量
g.SmoothingMode = SmoothingMode.AntiAlias;
g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
// 获取可视范围
var envelope = map.Envelope;
// 获取数据
var geometries = DataSource.GetGeometriesInView(envelope);
// 自定义渲染逻辑
foreach (var geometry in geometries)
{
RenderGeometry(g, map, geometry);
}
}
private void RenderGeometry(Graphics g, Map map, Geometry geometry)
{
if (geometry is Point point)
{
var screenPoint = map.WorldToImage(point.Coordinate);
// 绘制自定义符号
DrawCustomMarker(g, screenPoint);
}
else if (geometry is LineString line)
{
// 绘制线
var points = line.Coordinates.Select(c =>
map.WorldToImage(c)).ToArray();
using (var pen = new Pen(Color.Blue, 2))
{
g.DrawLines(pen, points);
}
}
else if (geometry is Polygon polygon)
{
// 绘制多边形
var points = polygon.ExteriorRing.Coordinates.Select(c =>
map.WorldToImage(c)).ToArray();
using (var brush = new SolidBrush(Color.FromArgb(100, 0, 100, 200)))
using (var pen = new Pen(Color.DarkBlue, 1))
{
g.FillPolygon(brush, points);
g.DrawPolygon(pen, points);
}
}
}
private void DrawCustomMarker(Graphics g, PointF point)
{
float size = 20;
var rect = new RectangleF(
point.X - size / 2,
point.Y - size / 2,
size,
size);
using (var brush = new SolidBrush(Color.Red))
{
g.FillEllipse(brush, rect);
}
using (var pen = new Pen(Color.White, 2))
{
g.DrawEllipse(pen, rect);
}
}
}
3.7 本章小结
本章详细介绍了 SharpMap 的核心架构和类库设计:
- 整体架构:了解了 SharpMap 的分层架构设计
- Map 类:深入学习了 Map 类的属性、方法和使用方式
- 图层体系:掌握了 VectorLayer、LabelLayer、TileLayer 等图层类型
- 数据提供者:学习了 IProvider 接口和常用数据提供者
- 样式系统:了解了 VectorStyle 和 LabelStyle 的配置方法
- 渲染流程:理解了 SharpMap 的渲染机制
3.8 参考资源
下一章预告:第04章将深入讲解 Map 对象的高级用法,包括地图导航、视图控制、事件处理等内容。

浙公网安备 33010602011771号