如何基于图案从地图图像提取数据并生成SHP多边形做叠加分析
解决方案
一、QGIS 可视化+手动/自动化流程
1. 图像地理配准
- 把地图JPG拖进QGIS图层面板,打开「地理参考」工具(菜单栏:
Raster > Georeferencer)加载该图像。如果没有真实地理坐标,就用像素坐标当临时坐标系(比如选EPSG:3857),添加几个对角控制点完成配准,导出带地理信息的TIFF替换原图层。 - 对图案模板JPG重复上述操作,确保和地图的坐标系、像素对齐一致。
2. 提取图案多边形
- 先对图案模板做二值化处理:用「栅格计算器」(
Raster > Raster Calculator)输入类似("pattern@1" > 200)的公式(根据背景色明暗调整阈值),把图案和背景彻底分离。 - 用「光栅转矢量」工具(
Raster > Conversion > Polygonize (Raster to Vector)),选择处理后的二值化栅格,设置输出字段(比如pattern_id),导出为SHP文件,每个图案对应一个多边形要素。
3. 叠加筛选
- 导入你的叠加多边形SHP(没有的话用QGIS的「添加多边形要素」工具手动绘制)。
- 用「空间连接」工具(
Vector > Data Management Tools > Join attributes by location):目标图层选图案多边形,连接图层选叠加多边形,匹配规则选intersects,导出连接后的图层就是位于叠加范围内的图案集合。
二、纯Python 自动化方案
1. 先装依赖
pip install gdal opencv-python geopandas shapely
2. 核心代码示例
(1)提取图案轮廓并转多边形
import cv2 import numpy as np from geopandas import GeoDataFrame from shapely.geometry import Polygon # 读取图案模板,转灰度图 img = cv2.imread('pattern_template.jpg', cv2.IMREAD_GRAYSCALE) # 二值化,分离图案和背景(阈值根据实际调整) _, binary_img = cv2.threshold(img, 200, 255, cv2.THRESH_BINARY_INV) # 提取外轮廓 contours, _ = cv2.findContours(binary_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 转换为Shapely多边形,过滤小杂点 polygons = [] for cnt in contours: if cv2.contourArea(cnt) > 100: # 过滤面积过小的轮廓 coords = cnt.reshape(-1, 2) polygons.append(Polygon(coords))
(2)导出SHP文件
# 创建GeoDataFrame,指定坐标系(无真实坐标就用EPSG:3857) gdf = GeoDataFrame({'geometry': polygons}, crs='EPSG:3857') # 导出为SHP gdf.to_file('pattern_polygons.shp')
(3)叠加筛选
# 加载叠加多边形 overlay_gdf = GeoDataFrame.from_file('overlay_polygon.shp') # 筛选和叠加多边形相交的图案 filtered_patterns = gdf[gdf.intersects(overlay_gdf.unary_union)] # 导出结果 filtered_patterns.to_file('filtered_patterns.shp')
三、关键注意点
- 图案提取的精度取决于二值化阈值,多试几个数值(比如180、220)找到最合适的;如果图案有复杂边缘,用
cv2.CHAIN_APPROX_TC89_L1参数优化轮廓。 - 地理配准必须对齐:如果地图和图案模板的像素尺寸不一样,要先统一分辨率再配准,否则提取的多边形位置会偏移。
- QGIS适合需要手动修正的小批量场景,Python适合大规模自动化处理。
内容的提问来源于stack exchange,提问作者BananaMaster
相关产品推荐
相关产品推荐

