ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

长三角地级市shp文件处理指南:从rar解压到3dtiles转换

长三角地级市shp文件处理指南:从rar解压到3dtiles转换 简介长三角各地级市的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缺失则大概率会碰到中文乱码读取时要指定gbk或utf-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, encodingutf-8) print(gdf.crs) print(gdf.columns.tolist()) print(gdf[NAME].value_counts())三行输出分别回答三个问题坐标系是什么、字段有哪些、每个城市有多少个面。如果print(gdf.crs)输出None说明缺少prj文件不要直接猜测先按数据来源判断。如果字段名是中文乱码把encodingutf-8改成encodinggbk重试一次。这只是属性读取编码不会改变几何。读入后立即检查几何有效性避免后续求交裁切时计算出负面积或自相交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, encodingutf-8) gdf.geometry gdf.geometry.map(outer_ring) gdf.to_file(苏州市_外边界.shp, encodingutf-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, encodingutf-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(geometrygrids, crsgdf.crs) sliced gpd.overlay(gdf, grid, howintersection) sliced.to_file(长三角_渔网.shp, encodingutf-8)step的单位跟随当前坐标系。坐标系是EPSG:4326时0.1是10公里左右的经纬度跨度坐标系换成UTM后step应改成10000米。用overlay求交的代价较高要素量大时先按城市字段过滤再逐市切网格最后合并结果能明显减少内存消耗。4.4 用市界裁剪掉市外点线避免跨城统计叠加分析场景里长三角的POI或道路数据经常超出所需城市。用空间连接过滤即可import geopandas as gpd city gpd.read_file(苏州市.shp, encodingutf-8) pois gpd.read_file(长三角_设施点.shp, encodingutf-8) pois_in gpd.sjoin(pois, city, predicatewithin, howinner)sjoin是空间连接predicatewithin要求设施点完全落在市界内。落在市界的点按within不满足需要保留边界点就把条件换成intersects。空间连接后结果会带上城市的属性字段所以后续不需要再按城市名二次匹配。5. 长三角地级市shp转换txt、kml、3dtiles一次说清5.1 shp转txt和CSV把坐标和属性交给非GIS系统后端程序不认shp但认文本。用GDAL把shp转成带几何的CSV或txt最稳的参数是GEOMETRYAS_WKTogr2ogr -f CSV 长三角城市.csv 长三角城市.shp -lco GEOMETRYAS_WKT -lco ENCODINGUTF-8生成的CSV里每个要素一行最后一列是WKT格式的多边形坐标串。这个文件可以直接交给数据分析或DBA做空间入库。如果是点数据转成AS_XY会更紧凑ogr2ogr -f CSV 点位.csv 点位.shp -lco GEOMETRYAS_XYAS_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, geometrygpd.points_from_xy(df[经度], df[纬度]), crsEPSG:4326) gdf.to_file(POI.shp, encodingutf-8)ArcMap里对应的操作是“添加XY数据”原理完全一样所以这个流程可以直接平移。5.2 批量把地级市shp转kml保留城市名做标注KML是Google Earth和很多Web地图的常见交换格式。长三角城市按目录拆开后批量转换用bash循环for f in *.shp; do ogr2ogr -f KML -dsco NameFieldNAME ${f%.shp}.kml $f doneNameFieldNAME表示用属性表里的NAME字段作为KML地标名这样地图上直接显示“苏州市”“杭州市”而不是无标签的面。KML标准要求WGS84坐标系如果输入shp是CGCS2000或高斯投影最好命令后面加-t_srs EPSG:4326否则部分在线地图定位偏差明显。5.3 shp转3dtiles给Cesium用的数据准备把长三角地级市和建筑物shp转3dtiles常见方案有两条适合不同数据规模工具适用数据特点py3dtiles点云、简单白膜、城市边界开源支持直接输入shpCesium 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很大、传输困难的场景。我一般按“shpshxdbfprj后缀”整套压进一个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(dropTrue) 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 ENCODINGUTF-8 final.shp 长三角城市.shp -t_srs EPSG:4326-lco ENCODINGUTF-8是让新shp的dbf属性表保持UTF-8不然在Linux或QGIS里中文又会变乱码。-t_srs强制转成WGS84保证你在ArcMap、QGIS、GeoServer和在线地图里看到的坐标一致。长三角各地级市shp如果后续要接Web端渲染或做切片这一步几乎不能省略。本文还有配套的精品资源点击获取
返回列表