| name | mapsui |
| description | Use when embedding interactive 2D maps in .NET desktop (WinForms/WPF) or mobile (MAUI) applications — tile layers, vector features, map controls. Mapsui: cross-platform .NET map component library. |
| tags | ["dotnet","csharp","map","wpf","maui","avalonia","blazor","skia","wms","tiles"] |
项目地址: https://github.com/Mapsui/Mapsui
官方文档: https://mapsui.com/documentation/
许可证: LGPL-2.1+
概述
- 跨 UI 框架:WPF / WinUI / MAUI / Avalonia / Uno / Blazor / WinForms
- SkiaSharp 渲染,性能优于 GDI+
- 数据源:OSM / WMS / WMTS / TMS / XYZ / Shapefile / GeoJSON / MBTiles / PostGIS
- 几何基于 NetTopologySuite
- 投影:
ProjNet / Mapsui.Projections
- 内置交互:拖动、缩放、旋转、捏合、命中
安装
dotnet add package Mapsui.Wpf
dotnet add package Mapsui.Tiling
dotnet add package Mapsui.Nts
WPF 入门
<Window xmlns:mapsui="clr-namespace:Mapsui.UI.Wpf;assembly=Mapsui.UI.Wpf">
<mapsui:MapControl x:Name="MapControl"/>
</Window>
using Mapsui;
using Mapsui.Tiling;
using Mapsui.Projections;
var map = new Map();
map.Layers.Add(OpenStreetMap.CreateTileLayer());
var pt = SphericalMercator.FromLonLat(116.397, 39.908).ToMPoint();
map.Navigator.CenterOnAndZoomTo(pt, map.Navigator.Resolutions[10]);
MapControl.Map = map;
核心概念
| 类型 | 说明 |
|---|
Map | 地图 |
Layer / MemoryLayer / ImageLayer / TileLayer | 图层 |
IProvider | 数据提供者 |
IFeature / GeometryFeature | 要素(NTS 几何) |
IStyle / VectorStyle / LabelStyle / SymbolStyle | 样式 |
Navigator | 视图操作 |
矢量图层
using Mapsui.Nts;
using Mapsui.Styles;
var features = new List<IFeature>();
foreach (var f in geoJsonFeatures)
features.Add(new GeometryFeature(f.Geometry) {
Styles = { new VectorStyle {
Fill = new Brush(Color.Red),
Outline = new Pen(Color.Black, 1)
}}
});
map.Layers.Add(new MemoryLayer("Roads") { Features = features, Style = null });
Shapefile
using Mapsui.Nts.Providers.Shapefile;
var prov = new ShapeFile("china.shp", true);
map.Layers.Add(new Layer("China") { DataSource = prov });
瓦片图层
map.Layers.Add(OpenStreetMap.CreateTileLayer());
var src = new HttpTileSource(
new GlobalSphericalMercator(0, 18),
"https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
name: "AMap");
map.Layers.Add(new TileLayer(src) { Name = "AMap" });
var mb = new MbTilesTileSource(new SQLiteConnectionString("city.mbtiles", false));
map.Layers.Add(new TileLayer(mb));
WMS
using Mapsui.Providers.Wms;
var wms = new WmsProvider("https://demo.mapserver.org/cgi-bin/wms?",
new[] { "continents" });
map.Layers.Add(new ImageLayer("WMS") { DataSource = wms });
样式
new SymbolStyle { SymbolScale = 0.7, Fill = new Brush(Color.Red) };
new LabelStyle {
Text = "{name}",
Font = new Font { Size = 14 },
BackColor = new Brush(Color.WhiteSmoke),
Halo = new Pen(Color.White, 2)
};
主题样式
public class PopulationStyle : IThemeStyle {
public IStyle? GetStyle(IFeature f) {
var pop = (int)f["population"];
return new VectorStyle { Fill = new Brush(pop > 1_000_000 ? Color.Red : Color.Blue) };
}
}
layer.Style = new PopulationStyle();
交互
MapControl.Info += (s, e) => {
if (e.MapInfo?.Feature is GeometryFeature gf)
Debug.WriteLine($"clicked {gf["name"]}");
};
性能优化
- 海量点 →
RasterizingTileLayer 包一层(按瓦片预渲染)
- 优先
MemoryLayer + 缓存 Feature
- 异步加载 +
await Layer.WaitForFinishedRefresh()
- 共享 Brush/Pen/Style 实例
- SkiaSharp 关闭抗锯齿对极小符号有性能提升
常见问题
| 问题 | 解决 |
|---|
| WPF 无图 | NuGet 缺 Mapsui.Wpf 或没设置 MapControl.Map |
| 投影错误 | SphericalMercator.FromLonLat 转换 |
| MAUI 空白 | MauiProgram 中 UseSkiaSharp() + UseMapsui() |
| Shapefile 中文乱码 | 指定 Encoding |
典型工作流
工作流 1:加载底图 + GeoJSON 矢量数据
using Mapsui;
using Mapsui.Tiling;
using Mapsui.Nts;
using Mapsui.Styles;
using NetTopologySuite.IO;
var map = new Map();
map.Layers.Add(OpenStreetMap.CreateTileLayer());
var gjReader = new GeoJsonReader();
var features = new List<IFeature>();
foreach (var f in geojsonFeatures)
{
features.Add(new GeometryFeature(f.Geometry)
{
Styles = { new VectorStyle { Fill = new Brush(Color.Red) } }
});
}
map.Layers.Add(new MemoryLayer("Data") { Features = features });
var center = SphericalMercator.FromLonLat(116.4, 39.9).ToMPoint();
map.Navigator.CenterOnAndZoomTo(center, map.Navigator.Resolutions[10]);
MapControl.Map = map;
工作流 2:Shapefile + WMS 叠加
var shpProvider = new ShapeFile("china.shp", true);
map.Layers.Add(new Layer("China") { DataSource = shpProvider });
var wmsProvider = new WmsProvider("https://geo.example.com/wms?", new[] { "rivers" });
map.Layers.Add(new ImageLayer("Rivers") { DataSource = wmsProvider });
map.ZoomToExtents();
AI 使用建议
推荐工作流
- 选择 UI 框架:Mapsui 支持 WPF/WinUI/MAUI/Avalonia/Uno/Blazor/WinForms,根据需要选择对应的 NuGet 包
- 创建 Map:实例化
Map,添加图层(TileLayer 作为底图 + MemoryLayer 作为矢量覆盖层)
- 数据转换:通过
SphericalMercator.FromLonLat() 将经纬度转为 Web Mercator 坐标
- 绑定控件:将
MapControl.Map 设置为创建的 Map 对象
- 添加交互:通过
MapControl.Info 事件处理点击拾取,Navigator 控制视图
关键注意事项
- NuGet 包完整:确保安装了
Mapsui.<UI框架>、Mapsui.Tiling、Mapsui.Nts 三个包
- 投影转换:WGS84 经纬度必须通过
SphericalMercator.FromLonLat() 转换后才能用于 Mapsui 定位
- Shapefile 编码:中文 Shapefile 需指定
Encoding(如 Encoding.UTF8 或 Encoding.GetEncoding("GBK"))
- 样式共享:共享
Brush/Pen/VectorStyle 实例可提升性能
- 海量点优化:使用
RasterizingTileLayer 包装海量点图层,按瓦片预渲染
相关技能
参考资源