简介:这份资源面向GIS从业者、城市规划人员、科研人员及高校学生,提供2021年云南省路网、水网、建筑、土地利用等矢量数据与行政区划边界,采用WGS84坐标,可直接在ArcGIS等平台加载分析,适用于区域规划、交通研究、土地利用评估等场景。压缩包共40个文件,约57.53MB,以shp、shx、dbf、prj、xml为主:shp存储几何要素,shx为索引,dbf保存属性表,prj定义投影,xml记录元数据,覆盖道路、铁路、水系、建筑、土地利用与地名等图层,并附云南省整体边界。目前已有466人学习下载,数据经过整理,省去自行采集与清洗的环节,可快速用于制图、空间统计与建模,也可作为底图与其他数据叠加分析,适合需要现成云南矢量底图的中高级用户。
1. 从一份 2021 年云南省全要素矢量数据说起:路网、水网、建筑、土地利用怎么落到 shp 里
手上拿到一份「2021年云南省最新最全路网、水网、建筑、土地利用矢量数据+行政区划边界+shp数据+wgs84坐标」的时候,多数人的第一反应是打开 ArcGIS 或 QGIS 看图层能不能正常加载,第二反应才是问:这套数据到底能干什么、坐标对不对、属性字段够不够用。它本质上是把云南省域范围内的四类核心地理要素——道路线、水系线面、建筑面、土地利用面——连同行政区划边界,统一整理成 shp 格式,并采用 wgs84 地理坐标系。对做国土空间规划、交通可达性分析、洪涝淹没模拟、城市扩张研究的人来说,这是一套能直接进 GIS 流水线的基础底图,而不是只能看不能算的展示图。
热搜里反复出现的 shp、wgs84、矢量数据、行政区划边界这几个词,恰好对应了这套数据的四个命门:格式能不能被工具链吃进去、坐标系能不能和已有数据对齐、矢量拓扑能不能支撑空间运算、边界能不能用来做裁剪和统计。新手拿到手最怕的是「图层能打开但一算就错」,熟手最关心的则是字段结构、几何类型和坐标精度能不能满足自己的模型。接下来按「先认清数据构成,再跑通加载与坐标校验,然后落到具体分析场景,最后把踩过的坑摊开」这条线走,每一步都给可复现的命令和参数。
2. 拆解数据构成:路网、水网、建筑、土地利用与行政区划边界各自怎么用
2.1 五类图层的几何类型与典型字段
拿到 shp 数据先别急着做分析,用 ogrinfo 把每个图层的几何类型和字段列出来,这一步决定了后面能用什么空间运算。路网通常是 LineString,字段里会有道路等级、名称、长度;水网可能是 LineString 加 Polygon 两套,线表示河流中心线,面表示水域范围;建筑是 Polygon,字段一般带层数或面积;土地利用是 Polygon,带地类编码;行政区划边界是 Polygon,带行政区代码和名称。
# 查看 shp 文件的图层信息、几何类型和字段 ogrinfo -so -al yunnan_road.shp ogrinfo -so -al yunnan_water_line.shp ogrinfo -so -al yunnan_building.shp ogrinfo -so -al yunnan_landuse.shp ogrinfo -so -al yunnan_boundary.shp-so只输出摘要不读几何,-al列出所有图层。重点看 Geometry 那一行是 Line String 还是 Polygon,以及 Field 列表里有没有你需要的等级、编码字段。如果路网只有几何没有等级字段,做分级渲染或按等级筛选时就得自己补属性,这是后面分析前必须确认的事。
2.2 wgs84 坐标意味着什么,以及和投影坐标的换算
wgs84 是地理坐标系,单位是度,直接拿它算长度和面积会得到以度为单位的荒谬结果。做距离、面积、缓冲区分析之前,必须投影到适合云南的投影坐标系。云南跨了多个 UTM 带,常见做法是用 CGCS2000 高斯克吕格投影,按经度选择 3 度带或 6 度带。用 ogr2ogr 做转换:
# 把 wgs84 地理坐标转成 CGCS2000 3度带投影(以云南中部约102E为例,带号34) ogr2ogr -f "ESRI Shapefile" \ -t_srs "+proj=tmerc +lat_0=0 +lon_0=102 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs" \ yunnan_road_proj.shp yunnan_road.shp-t_srs指定目标投影,+lon_0=102是中央经线,+units=m保证输出单位是米。转换后面积和长度字段才有物理意义。如果只是做叠加显示不做量算,保持 wgs84 也能用,但一旦涉及 buffer、intersect、area 计算,不投影就是给自己埋雷。
2.3 行政区划边界在裁剪和统计里的角色
行政区划边界最直接的用途是裁剪:把全省的路网、建筑按某个州市或县区裁出来,减少数据量、聚焦分析范围。用 ogr2ogr 的-clipsrc参数可以一步完成:
# 用某个县边界裁剪路网,只保留县内道路 ogr2ogr -f "ESRI Shapefile" \ -clipsrc yunnan_county_boundary.shp \ road_in_county.shp yunnan_road.shp裁剪之后做统计,比如按行政区汇总建筑面积、按县统计路网密度,就需要把裁剪结果和边界做空间连接。这一步在 PostGIS 里做比在桌面软件里做更可控,后面章节会展开。边界图层本身要检查拓扑:有没有自相交、有没有缝隙、行政区代码是否唯一,这些直接决定统计结果对不对。
3. 把 shp 数据跑进分析流水线:加载、校验、裁剪与空间统计
3.1 用 Python 批量读取并做坐标与几何校验
桌面软件点几下能看,但批量校验和自动化处理得靠代码。用 geopandas 读 shp,检查坐标系、几何有效性、空几何和重复要素:
import geopandas as gpd from shapely.validation import explain_validity # 读取 shp,指定编码避免中文属性乱码 gdf = gpd.read_file("yunnan_building.shp", encoding="utf-8") # 检查坐标系 print("CRS:", gdf.crs) # 检查几何有效性,找出无效几何 invalid = gdf[~gdf.is_valid] for idx, row in invalid.iterrows(): print(idx, explain_validity(row.geometry)) # 检查空几何和重复 print("空几何数量:", gdf.geometry.is_empty.sum()) print("重复几何数量:", gdf.geometry.duplicated().sum())encoding="utf-8"很关键,shp 的 dbf 属性表中文乱码十有八九是编码没对上。is_valid会标出自我相交、环方向错误等几何问题,explain_validity告诉你具体哪里坏了。无效几何在做 intersect 或 union 时会直接报错或产生错误结果,必须先修复。
3.2 修复无效几何并统一坐标系
发现无效几何后用 buffer(0) 或 make_valid 修复,再统一投影:
from shapely.validation import make_valid # 修复无效几何 gdf["geometry"] = gdf["geometry"].apply( lambda geom: make_valid(geom) if not geom.is_valid else geom ) # 统一投影到 CGCS2000 3度带 gdf_proj = gdf.to_crs("+proj=tmerc +lat_0=0 +lon_0=102 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs") # 重新计算面积字段(单位:平方米) gdf_proj["area_m2"] = gdf_proj.geometry.area gdf_proj.to_file("yunnan_building_fixed.shp", encoding="utf-8")make_valid比 buffer(0) 更稳,buffer(0) 对某些自相交多边形会返回空几何。投影后再算面积,area属性才是平方米。这一步做完,建筑面数据才能拿去做密度分析或容积率估算。
3.3 路网与水网的叠加分析:以缓冲区统计为例
路网和水网的典型分析是缓冲区叠加,比如统计河流两侧一定范围内有多少道路,或者道路对水系的跨越情况。先对水网做缓冲区,再和路网做空间连接:
# 水网缓冲区 100 米 water_proj = gpd.read_file("yunnan_water_line_proj.shp") water_buffer = water_proj.copy() water_buffer["geometry"] = water_proj.geometry.buffer(100) # 路网与水网缓冲区相交 road_proj = gpd.read_file("yunnan_road_proj.shp") road_near_water = gpd.sjoin(road_proj, water_buffer, predicate="intersects") # 统计每条河流缓冲区内道路数量 count_by_water = road_near_water.groupby("water_id").size() print(count_by_water.describe())buffer(100)的单位是米,因为已经投影过了。sjoin的predicate="intersects"表示只要相交就匹配,也可以用within做更严格的包含判断。这一步能快速筛出跨河路段或临河路段,对防洪评估和道路选线有直接价值。
3.4 用 PostGIS 做行政区尺度的空间统计
数据量大或者要做多轮统计时,把 shp 导入 PostGIS 比在 Python 里反复读写文件高效得多。导入后用 SQL 做空间连接和汇总:
# 用 shp2pgsql 导入 PostGIS shp2pgsql -s 4326 -I -W UTF-8 yunnan_landuse.shp public.landuse | psql -d gisdb shp2pgsql -s 4326 -I -W UTF-8 yunnan_boundary.shp public.boundary | psql -d gisdb-- 按行政区统计各地类面积(先投影再算面积) SELECT b.name, l.landuse_code, SUM(ST_Area(ST_Transform(l.geom, 4526))) AS area_m2 FROM landuse l JOIN boundary b ON ST_Intersects(l.geom, b.geom) GROUP BY b.name, l.landuse_code ORDER BY b.name, area_m2 DESC;-s 4326声明源数据是 wgs84,-I建空间索引加速查询。SQL 里ST_Transform(l.geom, 4526)把几何转到 EPSG:4526(CGCS2000 3度带),再算面积。ST_Intersects做空间连接,比逐要素循环快几个数量级。这一步是土地利用结构统计的标准做法,换任何省份都通用。
4. 避坑与排查:shp 加载、坐标、属性、拓扑里最容易翻车的五件事
4.1 现象:shp 加载后位置偏移几百米甚至几公里
原因:坐标系声明错误或缺失。shp 的 .prj 文件如果丢失或写错,软件会按默认坐标系解释,导致位置漂移。wgs84 数据被当成投影坐标读,或者投影参数写错中央经线,都会偏。
解决:用 ogrinfo 确认 .prj 内容,和已知控制点比对。缺失 .prj 时手动指定坐标系重新导出,不要靠软件猜。导入 PostGIS 时-s参数必须和实际坐标系一致。
4.2 现象:中文属性字段显示为乱码
原因:dbf 文件的编码和读取时指定的编码不一致。shp 的 dbf 默认可能是 GBK、GB2312 或 UTF-8,不同来源不一样。
解决:读取时显式指定encoding,geopandas 里试utf-8、gbk、gb18030。如果已经乱码且没有原始数据,用 ogr2ogr 转编码:ogr2ogr -f "ESRI Shapefile" -lco ENCODING=UTF-8 out.shp in.shp。
4.3 现象:做 intersect 或 union 时报拓扑错误
原因:多边形自相交、环方向错误、重复节点、缝隙或重叠。这些在 shp 里很常见,尤其是从 dwg 转 shp 或从其他格式转换来的数据。
解决:先跑is_valid批量检查,用make_valid修复。修复后重新检查,必要时用buffer(0)兜底。修复前备份原始数据,修复可能改变几何形状。
4.4 现象:面积或长度计算结果明显偏小或偏大
原因:在 wgs84 地理坐标系下直接算面积或长度,单位是度,数值没有物理意义。或者投影参数选错,中央经线偏离数据范围太远,变形过大。
解决:先投影到合适的投影坐标系再算。云南用 CGCS2000 3度带,中央经线按数据所在经度选。跨带数据要分带处理或选统一的 Albers 等面积投影。
4.5 现象:按行政区统计时部分要素被重复计算或漏算
原因:边界图层有重叠或缝隙,或者空间连接的 predicate 选得不合适。intersects会把跨边界的要素同时算进两个行政区,within会漏掉边界上的要素。
解决:先检查边界拓扑,消除重叠和缝隙。统计时明确口径:跨边界要素按面积比例分摊,还是按中心点归属。用ST_Centroid判断归属比intersects更可控。
5. 从 shp 到可用成果:批量导出、格式转换与精度验证的进阶手法
5.1 批量导出为 GeoJSON、WKT 和 3D Tiles 的取舍
shp 有字段名长度限制和 2GB 大小限制,做 Web 展示或大数据量传输时通常要转格式。GeoJSON 适合 Web 地图,WKT 适合入库和文本交换,3D Tiles 适合三维场景。用 ogr2ogr 批量转:
# shp 转 GeoJSON ogr2ogr -f "GeoJSON" yunnan_road.geojson yunnan_road.shp # 导出为 WKT 文本(用 ogrinfo 配合 SQL) ogrinfo -sql "SELECT ST_AsText(geometry) FROM yunnan_road" yunnan_road.shp # shp 转 3D Tiles 需要先转成带高度的 GeoJSON 或 OBJ,再用工具切片GeoJSON 默认输出 wgs84,适合直接给前端。WKT 导出时注意坐标系,ST_AsText输出的是当前坐标系下的坐标。3D Tiles 转换链路较长,建筑数据需要先拉伸高度字段,再走切片工具,这一步对建筑层高字段的完整性要求很高。
5.2 用渔网分割 shp 做分块处理
数据量大时,按渔网分块能降低单次处理内存占用,也方便并行。用 QGIS 或 Python 生成渔网,再和目标图层做相交:
import geopandas as gpd from shapely.geometry import box # 生成覆盖范围的渔网 bounds = gdf.total_bounds cell_size = 10000 # 10km 网格 cells = [] x = bounds[0] while x < bounds[2]: y = bounds[1] while y < bounds[3]: cells.append(box(x, y, x + cell_size, y + cell_size)) y += cell_size x += cell_size grid = gpd.GeoDataFrame(geometry=cells, crs=gdf.crs) # 按网格分割 clipped = gpd.overlay(gdf, grid, how="intersection")cell_size按数据密度调整,城市建筑密集区可以小一些,路网稀疏区可以大一些。overlay的how="intersection"保留相交部分,分割后每个网格单独处理,最后合并结果。
5.3 精度验证:用已知地物和控制点交叉检查
数据精度不能只看元数据,要拿已知地物验证。常见做法是选几个有明显地标的点,比如交叉路口、桥梁、行政中心,比对 shp 坐标和实测坐标或高精度影像坐标。偏差在米级以内可以接受,超过十米就要怀疑坐标系或采集精度。
# 计算验证点与 shp 中对应要素的距离 from shapely.geometry import Point check_points = [ (102.7, 25.0, "控制点A"), (102.8, 25.1, "控制点B"), ] for lon, lat, name in check_points: pt = Point(lon, lat) nearest = gdf_proj.geometry.distance(pt) print(name, "最近距离:", nearest.min())验证点坐标要和 shp 在同一坐标系下,否则距离没有意义。这一步做完,心里对数据精度才有底,拿去投标或出图才敢签字。
5.4 我自己的习惯:先建校验脚本,再动分析
这些年做数据项目,我养成了一个习惯:拿到任何 shp 数据,先写一个校验脚本,把坐标系、几何有效性、字段完整性、空值比例、重复要素全部跑一遍,输出一份检查报告。这份报告不交给别人,就是给自己看的后悔药。很多翻车不是分析逻辑错,而是数据本身有问题没提前发现。校验脚本跑完,再决定要不要修复、怎么修复、修复到什么程度。这个习惯让我少熬了很多夜,也希望帮到你。
本文还有配套的精品资源,点击获取