ymgis
面向桌面 GIS 小工具的轻量组件库:画布 + 图层管理 + 图层树 + 基础绘制 + 在线地图服务预览 + 动态重投影。
不依赖 QGIS。基于 PyQt6 + rasterio + Shapely + pyproj,可发布到 PyPI,供 QuickAnno、下载器、质检工具等复用。
能力概览
| 能力 | 说明 |
|---|---|
| 地图画布 | 平移、滚轮锚定缩放(鼠标下点不动)、可配置背景色(默认白色) |
| 动态重投影 | 可叠加不同坐标系数据;视图 CRS 由第一个带 CRS 的图层决定 |
| 本地栅格 | GeoTIFF(rasterio)按视口窗口读取;跨 CRS 时 WarpedVRT 重投影 |
| 图片预览 | PNG / JPG / BMP / WebP / GIF(ImageLayer,像素坐标,无地理参考) |
| 矢量标注 | 内存 Shapely 点/线/面 + 简单样式;渲染时按需重投影 |
| 图层树 | 勾选显隐;展开图例(矢量样式;栅格为 ArcMap 拉伸高/中/低或 RGB 波段;底图符号) |
| 添加数据 | ArcGIS / YMDesktop 风格浏览对话框;可选「数据源」或「图层」,图层支持单选/多选;GDB/MDB/PostGIS |
| 绘制工具 | 平移 / 点 / 线 / 矩形 / 多边形(线、面双击结束,双击点为终点/顶点) |
| 切片底图 | 通用 XYZ/TMS;预设天地图、高德、百度、谷歌 |
| OGC WMS | GetMap 视口图像预览 |
| ArcGIS REST | MapServer / ImageServer export;亦可 XYZ tile/{z}/{y}/{x} |
| 超图 iServer | 地图 image.png 视口预览;亦可 zxyTileImage 瓦片 |
在线服务图层自身为 EPSG:3857,叠到其它视图 CRS 时会动态重投影(AABB 近似)。高德/百度存在国内加密坐标偏移,适合底图预览,不宜与精密测绘数据直接叠合量测。
安装
# 开发态(本仓库)
pip install -e .
# 发布后
pip install ymgis
快速开始
from PyQt6.QtWidgets import QApplication, QMainWindow, QSplitter
from ymgis import MapCanvas, RasterLayer, VectorLayer, LayerTreeWidget, PanTool, DrawPolygonTool
app = QApplication([])
win = QMainWindow()
canvas = MapCanvas()
tree = LayerTreeWidget(canvas.layer_manager)
# 第一个带 CRS 的图层决定视图坐标系(无需手动 set_crs)
raster = RasterLayer(r"D:\data\demo.tif")
canvas.layer_manager.add_layer(raster)
canvas.zoom_to_full_extent()
# 普通图片预览(无地理参考,像素坐标):
# from ymgis import ImageLayer
# canvas.layer_manager.add_layer(ImageLayer(r"D:\data\photo.jpg"))
# canvas.zoom_to_full_extent()
# 标注层自动继承视图 CRS;绘制坐标为画布 CRS
annos = VectorLayer("标注")
canvas.layer_manager.add_layer(annos)
tool = DrawPolygonTool()
tool.polygon_drawn.connect(
lambda g: annos.add_feature(g, {"class": "demo"}, source_crs=canvas.crs)
)
canvas.set_map_tool(tool)
split = QSplitter()
split.addWidget(tree)
split.addWidget(canvas)
win.setCentralWidget(split)
win.resize(1200, 800)
win.show()
app.exec()
多坐标系叠加
from ymgis import MapCanvas, RasterLayer, VectorLayer, create_amap
from shapely.geometry import Point
canvas = MapCanvas()
# 先加载 CGCS2000 / 任意投影影像 → 视图 CRS = 该影像 CRS
canvas.layer_manager.add_layer(RasterLayer(r"D:\data\cgcs2000.tif"))
# 再叠加 WGS84 矢量 → 渲染时自动重投影到视图 CRS
pts = VectorLayer("点", crs="EPSG:4326")
pts.add_feature(Point(116.4, 39.9))
canvas.layer_manager.add_layer(pts)
# 在线底图(EPSG:3857)也会重投影到当前视图
canvas.layer_manager.add_layer(create_amap(), to_top=False)
canvas.zoom_to_full_extent()
添加数据(数据源 / 图层)
from ymgis import AddDataMode, browse_add_data
# 只选数据源(文件夹 / GDB / MDB / PostGIS),不进入图层
src = browse_add_data(mode=AddDataMode.SOURCE, multiselect=False)
# 选图层:可双击进入 GDB/MDB,支持多选
layers = browse_add_data(mode=AddDataMode.LAYER, multiselect=True)
if layers:
for item in layers.items:
print(item.kind, item.path, item.layer_name)
在线底图 / 地图服务预览
from ymgis import (
MapCanvas,
create_amap,
create_baidu,
create_google,
create_tianditu,
WmsLayer,
ArcGisRestLayer,
SuperMapRestLayer,
)
canvas = MapCanvas()
canvas.layer_manager.add_layer(create_amap(), to_top=False)
# canvas.layer_manager.add_layer(create_baidu(), to_top=False)
# canvas.layer_manager.add_layer(create_google(), to_top=False)
# canvas.layer_manager.add_layer(create_tianditu("你的天地图tk"), to_top=False)
# WMS / ArcGIS / 超图
# canvas.layer_manager.add_layer(WmsLayer("https://host/wms", "workspace:layer"))
# canvas.layer_manager.add_layer(
# ArcGisRestLayer("https://host/arcgis/rest/services/Demo/MapServer")
# )
# canvas.layer_manager.add_layer(
# SuperMapRestLayer("http://host:8090/iserver/services/map-demo/rest/maps/Demo")
# )
canvas.zoom_to_full_extent()
自定义 XYZ:
from ymgis import XyzTileLayer
layer = XyzTileLayer(
"https://tile.example.com/{z}/{x}/{y}.png",
name="自定义瓦片",
subdomains=["a", "b", "c"], # 对应模板 {s}
)
运行示例:
pip install -e .
python examples/basic_viewer.py
# 可选传入 GeoTIFF:
python examples/basic_viewer.py D:\data\demo.tif
# 在线底图 / WMS / ArcGIS / 超图预览:
python examples/online_basemap.py
# 天地图也可:set TIANDITU_TOKEN=你的tk
模块
| 模块 | 说明 |
|---|---|
MapCanvas |
地图画布;首层定 CRS、动态重投影渲染 |
LayerManager |
图层栈;combined_extent(target_crs) |
RasterLayer |
GeoTIFF 窗口读取 + WarpedVRT 重投影 |
ImageLayer |
本地图片预览(PNG/JPG/BMP/WebP/GIF) |
VectorLayer |
内存 Shapely 要素;可指定 crs= |
ymgis.crs |
transform_xy / transform_extent / transform_geometry |
XyzTileLayer |
通用 XYZ/TMS 异步瓦片底图 |
BaiduTileLayer / create_* |
百度及天地图/高德/谷歌预设 |
WmsLayer |
OGC WMS GetMap 视口预览 |
ArcGisRestLayer |
ArcGIS REST export 预览 |
SuperMapRestLayer |
超图 iServer 地图预览 |
LayerTreeWidget |
图层树 + 图例(show_legend=True) |
AddDataDialog / browse_add_data |
添加数据;AddDataMode.SOURCE / LAYER + 单选/多选 |
ymgis.data |
GisDataItem / list_layers 等数据源类型与枚举 |
LegendItem / LegendSymbol |
图例条目与符号类型 |
PanTool / DrawPointTool / DrawLineTool / DrawRectTool / DrawPolygonTool |
交互工具 |
设计约定
- 视图 CRS:由第一个加载且带有 CRS 的图层自动设定;
canvas.set_crs(...)可显式指定并锁定。 - 动态重投影:后续图层 CRS 不同时,在渲染/
combined_extent时转换到视图 CRS(依赖 pyproj;栅格用 WarpedVRT)。 - 无 CRS 的图层(如空标注层)加入后自动继承当前视图 CRS;绘制工具产出的几何为画布 CRS。
- 图层树默认展开图例:矢量按点/线/面样式,栅格显示缩略图,在线底图/服务显示通用符号;
LayerTreeWidget(show_legend=False)可关闭。 - 在线切片/WMS 图层原生多为 EPSG:3857;瓦片异步加载并带内存缓存。
- 栅格按视口读取并缩放到控件尺寸,避免整图进内存。
与 QGIS / GeoD 的关系
- 不是 QGIS 替代品:无工程文件、无复杂符号、无拓扑规则。
- 可预览常见在线底图与 OGC/REST 地图服务,但不是 GeoD 那种批量网图下载器。
- 目标:多个内部小工具共用同一套画布/图层树,安装包体积远小于捆绑
qgis_runtime。
发布到 PyPI
推荐使用脚本(Windows PowerShell):
# 升高版本:编辑 src/ymgis/__about__.py 中的 __version__(例如 "0.1.4")
# 首次:复制并填写 token(不要提交 publish.local.ps1)
copy scripts\publish.local.ps1.example scripts\publish.local.ps1
# 编辑 scripts\publish.local.ps1,将 $PyPiToken 设为 pypi-... 开头的 API token
.\scripts\publish.ps1
# 或:.\scripts\publish.ps1 -Token "pypi-你的完整token"
# 测试库:.\scripts\publish.ps1 -TestPyPI
也可手动:
pip install -e ".[dev]"
python -m build
# Username=__token__ Password=pypi-...
twine upload dist/*
请先在 PyPI 确认包名 ymgis 可用;若冲突可改为 yima-gis 并同步修改 pyproject.toml 的 name。若已上传过同一版本,需先升高版本号(只改 src/ymgis/__about__.py 中的 __version__)。
目录
ymgis/
├── pyproject.toml
├── README.md
├── LICENSE
├── examples/
│ ├── basic_viewer.py
│ └── online_basemap.py
├── src/ymgis/
│ ├── crs.py # 动态重投影
│ ├── canvas/
│ ├── layers/
│ │ └── services/ # XYZ / WMS / ArcGIS / 超图 / 厂商预设
│ ├── tools/
│ └── widgets/
└── tests/
License
MIT
Metadata
Release files for ymgis 0.1.11
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ymgis-0.1.11.tar.gz | 49.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ymgis-0.1.11-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 112.6 kB
Release files / ymgis-0.1.11.tar.gz
| Download URL | ymgis-0.1.11.tar.gz |
|---|---|
| Size | 49.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4ffaf4aaaeb60a97d742babeef7097bc985cea8c0068bd886de25a9d7d634da9
|
|
BLAKE2b-256 checksum How to use checksums |
e98a3e9573d67b239d54b754d0894edfd42873ed3f218e3bedffdfa3c79a3aab
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.0
|
Release files / ymgis-0.1.11-py3-none-any.whl
| Download URL | ymgis-0.1.11-py3-none-any.whl |
|---|---|
| Size | 63.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
52225e546cc0e37651833768f7af77549dba6147c37e2134b76e65cf071b9b7b
|
|
BLAKE2b-256 checksum How to use checksums |
b11c1f3772764d4cdcae2c9c2e0b5b1eca44ec7ae037d6e9701557776fb75ec9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.0
|