长三角地级市shp文件处理指南:从rar解压到3dtiles转换
2026/9/17 1:58:43 网站建设 项目流程

简介:长三角各地级市的shp数据文件包,适合GIS从业者、城市规划研究者及地理信息课程学习者使用,可直接导入ArcGIS、QGIS等平台进行地图展示、空间查询与专题制图,解决长三角市级行政区划矢量底图缺失的常见问题。压缩包共8个文件,整体仅53KB,除了核心的shp矢量图层外,还配套了prj投影参数、dbf属性表、sbx/sbn空间索引及shp.xml元数据说明,文件结构完整,解压后无需二次整理即可加载使用。目前已有2276人学习下载,数据和配置信息都较为轻量,适合作为区域经济分析、城市群空间格局研究的快速底图。使用这份数据,用户可以省去手动拼接行政区边界的环节,直接对各地级市图层进行符号化、合并、裁剪或关联社会经济指标,能显著提升前期数据处理与出图效率,也便于开展后续空间统计与规划应用。

1. 拿到“长三角各地级市shp文件.rar”之后,第一件事不是解压

这份压缩包在GIS圈流传很广,表面上是把长三角各市行政边界装进一个rar,解压完拿QGIS一拖就能出图。但真正决定后面工作顺不顺的,是压缩包里那一条完整的数据链:shp主文件、shx索引、dbf属性、prj投影,以及属性表里的中文编码。少一个文件或者坐标系不统一,你在ArcGIS里看到的可能是一堆乱码或跑到大海里的面。

常见的处理路径有两条:一是用ArcMap/QGIS直接打开、拼接、裁剪;二是用GDAL/OGR命令行或GeoPandas做批处理,为Web地图、数据可视化、shp转3dtiles准备数据。两条路径在“解压→读入→清洗→转换”这四步上是通的。先把rar结构搞清楚,后面无论你是做城市边界提取、只保留外边界线,还是把shp转txt给后端用,都会少踩很多坑。

2. 拆开rar和shp:先看压缩包清单,再决定怎么解压

2.1 为什么长三角地级市数据喜欢用rar分卷发布

各地级市shp数据动辄几十MB起步,如果还带道路、水系、POI,压缩后能省不少空间。rar比zip对矢量数据里大量重复边界的压缩率略高,网上很多历史数据包都保留着rar格式,甚至还有分卷压缩,形如长三角.shp.part1.rar长三角.shp.part2.rar。分卷必须全部下载才能解压,缺一卷就报错。

另一个原因是中文文件名和属性编码在rar里兼容性好,压缩包在Windows上解压后文件名不乱码。但这不等于数据没问题,真正的乱码风险在dbf属性表内部,这在第3章会专门展开。

先明确一点:rar本身不是GIS概念,它只是运输工具。压缩包内容通常按“地级市/县区/道路/要素点”分目录存放,也可能把整个省合并成一个大的shp,再用字段区分城市。不同发布者习惯不同,所以第一步不是急着解压,而是看清单。

2.2 一份完整shp在压缩包里应该有哪几个文件

后缀作用缺失后果
.shp要素几何信息GIS无法识别,报缺失主文件
.shx要素几何索引读取极慢,部分软件打不开
.dbf属性表,城市名等字段有图形无属性,无法按市筛选
.prj坐标系描述文本软件会猜测坐标系,出图位置跑偏
.cpgdbf字符编码标识中文属性容易出现乱码

如果你的压缩包里只有.shp没有.dbf,很多后台统计和按城市筛选就直接断掉。常见处理是用7z或WinRAR检查压缩包完整性,发现缺文件就问来源方要完整的,不花时间自己猜。

2.3 用Python只列压缩包清单,不全量解压

在程序化流程里,可以用rarfile库读取压缩包内容,判断数据组织方式。示例代码如下:

import rarfile rarfile.UNRAR_TOOL = "unrar" # 指定unrar可执行文件,或改成7z路径 with rarfile.RarFile("长三角各地级市shp文件.rar") as rf: for info in rf.infolist(): name = info.filename.lower() if name.endswith((".shp", ".shx", ".dbf", ".prj", ".cpg")): print(f"{info.filename} {info.file_size / 1024:.1f}KB")

这段代码的用途是优先列出shp及其配套文件。文件名后缀过滤条件很窄,能过滤掉压缩包里的说明文档、图片预览和临时文件。如果发现所有shp旁边都缺.prj,就说明这份数据没有坐标系信息,后面对接Web地图时要按已知坐标系手动设置。如果所有城市的.cpg缺失,则大概率会碰到中文乱码,读取时要指定gbkutf-8逐个试。

3. 用ogrinfo和geopandas把shp读进来并做第一轮清洗

3.1 shp文件的格式边界:几何、属性、投影是三个独立文件

很多新人把shp当成一个文件,实际上它是一个“文件组”。几何在.shp,几何索引在.shx,属性在.dbf,三者缺一不可。投影信息.prj是纯文本,用记事本就能打开,内容是一段WKT描述,例如PROJCS["CGCS2000 / 3-degree Gauss-Kruger CM 120E"...]

长三角地区常见的坐标系有三种:WGS84经纬度、CGCS2000经纬度、CGCS2000高斯投影。用ArcGIS打开时不看.prj直接拖入,软件会默认按WGS84处理,结果可能偏差几百米到几公里。所以读数据的第一步永远是看投影。

3.2 用ogrinfo命令查元数据,不打开GUI也能判断数据质量

GDAL是GIS界的通用底层库,装了QGIS或gdal命令行工具后就能使用。查看shp基本信息的命令是:

ogrinfo -so -al 长三角城市.shp

输出里能看到图层名、要素数量、几何类型(Polygon还是MultiPolygon)、坐标系WKT和字段列表。-so表示仅查看概要信息,不逐要素输出,速度很快。如果要素数量和你预期的地级市数量对不上,说明shp里可能混入了县级面或者被合并过的重复面。

想确认某个城市的字段值写法,但不用完整扫描所有字段,可以加-where参数:

ogrinfo -al 长三角城市.shp -where "NAME = '苏州市'"

这里假设字段名是NAME,实际字段名以3.1节的字段列表为准。这条命令把筛选条件下的要素属性全部打出来,能快速确认城市名里是否带“市”字,以及各市在属性表中是唯一的还是多选了多次。带不带“市”会直接影响后面where条件写法,长三角数据包来源不一,有的写“苏州市”,有的写“苏州”,清洗时要对齐。

3.3 用geopandas读入,显式指定编码并检查无效几何

GeoPandas是Python里处理shp的标准方式。读入长三角城市数据时,我会显式传编码参数:

import geopandas as gpd gdf = gpd.read_file("长三角城市.shp", encoding="utf-8") print(gdf.crs) print(gdf.columns.tolist()) print(gdf["NAME"].value_counts())

三行输出分别回答三个问题:坐标系是什么、字段有哪些、每个城市有多少个面。如果print(gdf.crs)输出None,说明缺少prj文件;不要直接猜测,先按数据来源判断。如果字段名是中文乱码,把encoding="utf-8"改成encoding="gbk"重试一次。这只是属性读取编码,不会改变几何。

读入后立即检查几何有效性,避免后续求交裁切时计算出负面积或自相交:

bad = gdf[~gdf.is_valid] print(bad.shape[0])

bad.shape[0]大于0,用gdf.geometry = gdf.geometry.buffer(0)做修复。buffer(0)是把自相交的环自动重建一遍,对大多数从网上收集的shp有效,但会轻微圆滑边界,精度要求高的分析建议在原始数据上修好后再读入。

3.4 同一份rar里多个城市shp的投影统一问题

长三角各地级市shp文件的发布时间不同,有的采用CGCS2000,有的是WGS84,还有部分直接沿用西安80。混合使用时不能直接合并,需要统一坐标。用GeoPandas重投影:

gdf_4326 = gdf.to_crs("EPSG:4326")

如果后续要做面积统计或渔网分割,建议在投影坐标系下做,因为经纬度是角度单位,直接算面积会错得离谱。长三角范围适合用UTM 50N或CGCS2000高斯投影,在华东地区变形小,计算面积和边长更稳。

4. 按地级市提取边界、只保留外边界线、渔网分割

4.1 用ogr2ogr按字段值提取单个地级市

直接把整个长三角shp推给地图服务或用它裁剪道路图层,数据量没必要。常见做法是先按城市名拆开:

ogr2ogr -where "NAME = '苏州市'" 苏州.shp 长三角城市.shp -t_srs EPSG:4326

这条命令从长三角城市shp里筛出NAME字段等于“苏州市”的所有要素,写成新文件,并顺便把坐标系转成WGS84经纬度。-where用的是SQL表达式,字段名和值都区分大小写。如果之前检查发现NAME里带“市”,条件就写'苏州市',否则写'苏州'

空间范围粗筛和字段筛选经常搭配使用。两份数据无法用字段关联时,用空间范围先圈出附近区域,再精确处理:

操作方式命令参数适用场景
按属性筛-where "NAME='苏州市'"字段值明确
按矩形框选-spat 119.5 30.5 121.5 32.5快速圈定城市范围
按外部边界裁-clipsrc 苏州市界.shp精确裁剪,结果贴合边界

4.2 只保留外边界线,去掉内部区县界

很多时候你不需要县级边界,只要地级市整体轮廓。直接从市界shp里去掉内部线,可用GeoPandas取每个面的外环:

from shapely.geometry import Polygon, MultiPolygon def outer_ring(geom): if geom.geom_type == "MultiPolygon": return MultiPolygon([Polygon(p.exterior) for p in geom.geoms]) return Polygon(geom.exterior) gdf = gpd.read_file("苏州市.shp", encoding="utf-8") gdf.geometry = gdf.geometry.map(outer_ring) gdf.to_file("苏州市_外边界.shp", encoding="utf-8")

这里的逻辑是:单一面直接取exterior作为新多边形;多部件面则逐部件取外环再合成MultiPolygon。值得注意的是,如果原数据里相邻区县边界有重叠,取外环会把重叠区域也包进来,最后输出轮廓和真实边界有小误差。稳妥做法是先dissolve合并:

merged = gdf.dissolve()

dissolve()把同名城市的所有面合并成一个整体,再取外环,得到的就是城市最外缘轮廓。这样处理后再做图、做掩膜或做shp转kml,边缘不会出现锯齿状断线。

4.3 渔网分割shp:把县级面切成均等网格

需要按格网统计、发布切片或做空间索引时,会用到渔网分割。常见做法是先生成规则格网,再把目标shp和格网求交。GeoPandas代码如下:

import geopandas as gpd import numpy as np from shapely.geometry import box gdf = gpd.read_file("长三角城市.shp", encoding="utf-8") minx, miny, maxx, maxy = gdf.total_bounds step = 0.1 # 经纬度单位,约10公里 cols = int(np.ceil((maxx - minx) / step)) rows = int(np.ceil((maxy - miny) / step)) grids = [] for i in range(cols): for j in range(rows): grids.append(box(minx + i * step, miny + j * step, minx + (i + 1) * step, miny + (j + 1) * step)) grid = gpd.GeoDataFrame(geometry=grids, crs=gdf.crs) sliced = gpd.overlay(gdf, grid, how="intersection") sliced.to_file("长三角_渔网.shp", encoding="utf-8")

step的单位跟随当前坐标系。坐标系是EPSG:4326时,0.1是10公里左右的经纬度跨度;坐标系换成UTM后,step应改成10000(米)。用overlay求交的代价较高,要素量大时先按城市字段过滤,再逐市切网格,最后合并结果,能明显减少内存消耗。

4.4 用市界裁剪掉市外点线,避免跨城统计

叠加分析场景里,长三角的POI或道路数据经常超出所需城市。用空间连接过滤即可:

import geopandas as gpd city = gpd.read_file("苏州市.shp", encoding="utf-8") pois = gpd.read_file("长三角_设施点.shp", encoding="utf-8") pois_in = gpd.sjoin(pois, city, predicate="within", how="inner")

sjoin是空间连接,predicate="within"要求设施点完全落在市界内。落在市界的点按within不满足,需要保留边界点就把条件换成intersects。空间连接后结果会带上城市的属性字段,所以后续不需要再按城市名二次匹配。

5. 长三角地级市shp转换:txt、kml、3dtiles一次说清

5.1 shp转txt和CSV:把坐标和属性交给非GIS系统

后端程序不认shp,但认文本。用GDAL把shp转成带几何的CSV或txt,最稳的参数是GEOMETRY=AS_WKT

ogr2ogr -f CSV 长三角城市.csv 长三角城市.shp -lco GEOMETRY=AS_WKT -lco ENCODING=UTF-8

生成的CSV里每个要素一行,最后一列是WKT格式的多边形坐标串。这个文件可以直接交给数据分析或DBA做空间入库。如果是点数据,转成AS_XY会更紧凑:

ogr2ogr -f CSV 点位.csv 点位.shp -lco GEOMETRY=AS_XY

AS_XY把点拆成X和Y两个数字列,方便直接进表格工具。

反向操作也常用:Excel里维护了经纬度列,想生成shp。常见做法是先用pandas读Excel,再用points_from_xy生成几何:

import pandas as pd import geopandas as gpd df = pd.read_excel("POI.xlsx") gdf = gpd.GeoDataFrame(df, geometry=gpd.points_from_xy(df["经度"], df["纬度"]), crs="EPSG:4326") gdf.to_file("POI.shp", encoding="utf-8")

ArcMap里对应的操作是“添加XY数据”,原理完全一样,所以这个流程可以直接平移。

5.2 批量把地级市shp转kml,保留城市名做标注

KML是Google Earth和很多Web地图的常见交换格式。长三角城市按目录拆开后,批量转换用bash循环:

for f in *.shp; do ogr2ogr -f KML -dsco NameField=NAME "${f%.shp}.kml" "$f" done

NameField=NAME表示用属性表里的NAME字段作为KML地标名,这样地图上直接显示“苏州市”“杭州市”而不是无标签的面。KML标准要求WGS84坐标系,如果输入shp是CGCS2000或高斯投影,最好命令后面加-t_srs EPSG:4326,否则部分在线地图定位偏差明显。

5.3 shp转3dtiles:给Cesium用的数据准备

把长三角地级市和建筑物shp转3dtiles,常见方案有两条,适合不同数据规模:

工具适用数据特点
py3dtiles点云、简单白膜、城市边界开源,支持直接输入shp
Cesium ion大范围倾斜摄影、复杂模型在线转换,需要上传数据
CesiumLab本地批量处理功能全,适合Long任务

本地命令行常用py3dtiles。安装后执行类似:

py3dtiles convert 长三角建筑.shp -o 长三角_tiles

输入shp最好先转成EPSG:4326,并检查属性字段不要带中文,3dtiles的批量处理工具对中文属性支持不稳定,转之前把不必要的字段删掉能减少包体。转换完成后会生成tileset.json和若干b3dm文件,Cesium加载时指向tileset.json即可。地级市边界面转3dtiles后体积通常很小,适合做城市级的可视化和区域选择操作,比直接加载shp经过后端切片要省事。

5.4 shp文件批量压缩的回坑提醒

同一个压缩包经过多次转发后,经常出现单个shp很大、传输困难的场景。我一般按“shp+shx+dbf+prj+后缀”整套压进一个zip或rar,不单独压主文件,因为单独压缩会导致收件人只解压出.shp,其他配套文件缺失,文件打不开还白折腾。调用7z命令行可以批量处理:

for f in *.shp; do 7z a "${f%.shp}.zip" "${f%.shp}"??? done

这里的通配符写法只适合文件名规整的场景。更稳的方式是先用目录整理同名文件,再对整个目录压缩一次,保证文件组完整。

6. 用三个技巧验证长三角地级市shp,避免出图和统计时翻车

6.1 先看字段唯一值,再确认城市数量与面数量是否一致

长三角地级市shp最容易出的问题是属性表里一个城市对应多个面,比如下辖区县没有合并。用GeoPandas按城市名统计面数量:

counts = gdf.groupby("NAME").size() print(counts)

如果输出里“苏州市”对应1行,说明边界已经合并;“苏州市”出现多行,说明shp保存的是区县级面。你需要决定是做市级粒度还是区县粒度,决定后再决定要不要执行dissolve

6.2 检查相邻城市之间有缝隙还是重叠

网络收集的shp数据拓扑关系不保证正确。相邻城市边界应该完全重合,但实际常常出现重叠几米或缝隙几米。检查两两相交:

from itertools import combinations gdf = gdf.reset_index(drop=True) for i, j in combinations(range(len(gdf)), 2): left = gdf.geometry.iloc[i] right = gdf.geometry.iloc[j] if left.intersects(right): inter = left.intersection(right).area if inter > 1e-6 and i < j: print(gdf["NAME"].iloc[i], gdf["NAME"].iloc[j], inter)

打印出来的重叠面积可能是真实共边产生的,也可能是拓扑错误。面积极小且边界完全重合是正常共边,数值大则需要修复。修重叠的常用手段是取两个面的边界做stitch,重绘项目里用后处理。对绝大多数应用场景,先做一次gdf.buffer(0)再保存,能把大部分自相交和微缝隙修正掉。

6.3 保存前统一编码和坐标系,避免跨软件乱码

最后保存时,务必显式指定编码和坐标系输出:

ogr2ogr -lco ENCODING=UTF-8 final.shp 长三角城市.shp -t_srs EPSG:4326

-lco ENCODING=UTF-8是让新shp的dbf属性表保持UTF-8,不然在Linux或QGIS里中文又会变乱码。-t_srs强制转成WGS84,保证你在ArcMap、QGIS、GeoServer和在线地图里看到的坐标一致。长三角各地级市shp如果后续要接Web端渲染或做切片,这一步几乎不能省略。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询