인터페이스는 현지화되어 있으며, Skill 소개와 설명 문서는 선택한 언어로 AI가 자동 번역합니다. 코드·명령어·경로·전문 용어는 원문을 유지하며 원작자 문서가 우선합니다.
Skills 둘러보기
개발 및 엔지니어링 · SKILL.md

sharpmap

sharpmap

Use when rendering 2D maps in legacy .NET WinForms or ASP.NET WebForms applications. SharpMap: an older .NET 2D mapping library. For new projects, prefer Mapsui.

Independent GitHub snapshot · Automated classification · Original documentation governs

Skill 문서

GitHub

name: sharpmap description: "Use when rendering 2D maps in legacy .NET WinForms or ASP.NET WebForms applications. SharpMap: an older .NET 2D mapping library. For new projects, prefer Mapsui." tags:

  • dotnet
  • csharp
  • 2d
  • map
  • rendering
  • wms
  • shapefile
  • postgis
  • winforms

项目地址: https://github.com/SharpMap/SharpMap

官方文档: https://github.com/SharpMap/SharpMap/wiki

NuGet: SharpMap、SharpMap.UI.WinForms(SharpMap 最新稳定版 1.2.0,截至2026年)

许可证: LGPL-2.1

概述

SharpMap 提供:

  • 数据源:Shapefile、PostGIS、SQL Server Spatial、Oracle Spatial、SQLite/SpatiaLite、WMS、WFS、TileSource(OSM/Bing)
  • 图层模型:VectorLayer、LabelLayer、TileLayer、WmsLayer
  • 样式:VectorStyle、LabelStyle、按属性主题样式
  • 坐标变换:通过 ProjNet
  • 几何:基于 NetTopologySuite
  • 渲染:System.Drawing 位图 / WMS 服务输出
  • UI 控件:WinForms MapBox

注意:SharpMap 主要面向 .NET Framework / 较旧 .NET,新项目建议改用 Mapsui。


安装

dotnet add package SharpMap
dotnet add package SharpMap.UI.WinForms
dotnet add package SharpMap.Extensions
dotnet add package ProjNet

核心对象

类型说明
Map地图
ILayer / VectorLayer / LabelLayer / TileLayer图层
IProvider数据提供者
VectorStyle / LabelStyle样式

WinForms 入门

using SharpMap;
using SharpMap.Layers;
using SharpMap.Data.Providers;
using SharpMap.Styles;
using System.Drawing;

var map = new Map(new Size(800, 600));

var prov = new ShapeFile("countries.shp", true);
var layer = new VectorLayer("countries", prov)
{
    Style = new VectorStyle {
        Fill = new SolidBrush(Color.LightGreen),
        Outline = Pens.Black,
        EnableOutline = true
    }
};
map.Layers.Add(layer);

var labels = new LabelLayer("labels") {
    DataSource = prov,
    LabelColumn = "NAME",
    Style = new LabelStyle { Font = new Font("Arial", 10) }
};
map.Layers.Add(labels);

map.ZoomToExtents();
mapBox1.Map = map;
mapBox1.Refresh();

PostGIS 数据源

var conn = "Host=localhost;Database=gisdb;User Id=postgres;Password=pg";
var prov = new PostGIS(conn, "poi", "geom", "id");
map.Layers.Add(new VectorLayer("poi", prov));

OSM 瓦片底图

using BruTile.Predefined;
var src = KnownTileSources.Create(KnownTileSource.OpenStreetMap);
map.Layers.Add(new TileAsyncLayer(src, "OSM"));
map.SRID = 3857;

主题样式

using SharpMap.Rendering.Thematics;

var theme = new CustomTheme(row => {
    var pop = (int)row["POP"];
    return new VectorStyle {
        Fill = new SolidBrush(pop > 1_000_000 ? Color.Red : Color.Blue)
    };
});
layer.Theme = theme;

坐标变换

using ProjNet.CoordinateSystems;
using ProjNet.CoordinateSystems.Transformations;

var ctf = new CoordinateTransformationFactory();
layer.CoordinateTransformation = ctf.CreateFromCoordinateSystems(
    GeographicCoordinateSystem.WGS84,
    ProjectedCoordinateSystem.WebMercator);
map.SRID = 3857;

输出图像与 WMS

using var img = map.GetMap();
img.Save("map.png");

// ASP.NET WMS
public void ProcessRequest(HttpContext ctx)
{
    var map = MapHelper.InitializeMap();
    SharpMap.Web.Wms.WmsServer.ProcessRequest(ctx, map);
}

拾取与查询

mapBox1.MouseDown += (s, e) => {
    var pt = mapBox1.Map.ImageToWorld(new PointF(e.X, e.Y));
    var ds = new SharpMap.Data.FeatureDataSet();
    layer.DataSource.ExecuteIntersectionQuery(
        new NetTopologySuite.Geometries.Envelope(pt.X-1e-3, pt.X+1e-3,
                                                 pt.Y-1e-3, pt.Y+1e-3), ds);
    foreach (FeatureDataRow row in ds.Tables[0].Rows)
        Console.WriteLine(row["NAME"]);
};

性能建议

  1. 预建空间索引(Shapefile .qix、PostGIS GiST)
  2. TileAsyncLayer 用于在线底图
  3. 避免主线程加载大数据
  4. LabelLayer 启用优先级与碰撞检测
  5. 复用 Brush/Pen/VectorStyle

常见问题

问题解决
无图检查 SRID、ZoomToExtents
文字模糊设置高 DPI Aware、MapBox.MapTransform
GDI+ 内存泄漏释放 Brush/Pen/Bitmap
Shapefile 中文乱码new ShapeFile(path, true, false, Encoding.UTF8)

典型工作流

工作流 1:Shapefile 渲染 + 主题样式 + 输出图片

using SharpMap;
using SharpMap.Layers;
using SharpMap.Data.Providers;
using SharpMap.Styles;
using SharpMap.Rendering.Thematics;
using System.Drawing;

// 创建地图
var map = new Map(new Size(1024, 768));
map.SRID = 4326;

// 添加 Shapefile 图层
var prov = new ShapeFile("countries.shp", true);
var layer = new VectorLayer("Countries", prov)
{
    Style = new VectorStyle
    {
        Fill = Brushes.LightGreen,
        Outline = Pens.Black,
        EnableOutline = true
    }
};

// 按人口设置主题样式
layer.Theme = new CustomTheme(row =>
{
    var pop = (int)row["POP_EST"];
    return new VectorStyle
    {
        Fill = new SolidBrush(pop > 100_000_000 ? Color.Red : Color.LightBlue)
    };
});
map.Layers.Add(layer);

// 添加行政标注
var labels = new LabelLayer("Labels")
{
    DataSource = prov, LabelColumn = "NAME",
    Style = new LabelStyle { Font = new Font("Arial", 10) }
};
map.Layers.Add(labels);

// 渲染
map.ZoomToExtents();
using var img = map.GetMap();
img.Save("output.png");

工作流 2:PostGIS 数据 + OSM 底图 + WMS 发布

// PostGIS 数据
var pgConn = "Host=localhost;Database=gisdb;User Id=postgres;Password=pg";
var poiProvider = new PostGIS(pgConn, "poi", "geom", "id");
map.Layers.Add(new VectorLayer("POI", poiProvider)
{
    Style = new VectorStyle { Fill = Brushes.OrangeRed }
});

// OSM 底图
using BruTile.Predefined;
var tileSrc = KnownTileSources.Create(KnownTileSource.OpenStreetMap);
map.Layers.Add(new TileAsyncLayer(tileSrc, "OSM"));
map.SRID = 3857;

AI 使用建议

推荐工作流

  1. 创建 Map:new Map(new Size(width, height)) → 设置 SRID
  2. 添加数据源:ShapeFile(path) / PostGIS(conn, table, geomCol, idCol) 等方式连接数据
  3. 创建图层:VectorLayer(name, provider) 并设置 Style;按需添加 LabelLayer
  4. 添加底图:TileAsyncLayer + BruTile 加载 OSM 在线底图
  5. 渲染输出:map.GetMap() 获取 Image 对象 → 保存为 PNG 或通过 ASP.NET WMS 发布

关键注意事项

  • 新项目建议 Mapsui:SharpMap 主要面向 .NET Framework,新项目推荐使用 Mapsui(更活跃、跨平台更好)
  • SRID 一致性:图层与地图 SRID 必须一致,必要时通过 CoordinateTransformation 转换
  • 空间索引:Shapefile 需预建 .qix 索引,PostGIS 用 GiST 索引加速查询
  • 资源释放:GDI+ Brush/Pen/Bitmap 需及时释放避免内存泄漏
  • Shapefile 编码:中文数据需指定 Encoding.UTF8 或 Encoding.GetEncoding("GBK")

相关技能

参考资源

저장한 Skills