简介全国矢量地图shp格式压缩包面向GIS学习者、规划师、测绘地信从业者提供可直接使用的全国基础地理底图。包内共85个文件以28套shp、shx、dbf三件套为主附带一个xml元数据文件其中shp保存点、线、面几何对象shx用于建立空间索引dbf存储行政区划名称、道路等级、水体类型等属性信息覆盖省级到县级行政区划、各级道路网络、河流湖泊水系、地形地貌、建筑物及生态保护区等常见图层。压缩包整体34.27MB文件按目录组织可单独加载任一图层也能统一导入ArcGIS、QGIS等平台进行投影转换、缓冲区分析、专题出图。目前已有543人学习浏览使用这份数据可以省去地图数据的收集、格式转换与初步配准工作直接聚焦于空间分析和成果表达适用于城市体检、资源环境评价、交通可达性分析等具体业务场景。1. 全国矢量地图 shp 数据到底解决什么问题三个高频场景干 GIS 这行最不缺的就是“自己画”最缺的是“现成的全国底图”。不管是做规划分析、出专题图还是给前端项目导一份省界临时去爬高德矢量、东拼西凑边界最后多半会栽在坐标系不一致、属性字段千奇百怪、图层压盖这些问题上。全国矢量地图 shp 格式这份打包资源就是把“全国行政区划边界常用基础图层”整理成一个开箱即用的数据集省去到处找边界描边的过程。它适合这样的读者要么是刚开始接触 arcgis/QGIS 的新手需要一个现成 shp 来练手要么是需要做全国尺度分析、出图、做数据二次开发的从业者。下面按我自己的使用流程把它拆开讲。2. 解压后的第一遍体检图层、坐标系与编码验证别急着用2.1 压缩包里的 shp 文件完整形态与识别shp 不是单文件而是一组同名文件。很多人第一次拿到 rar 解压后只看到.shp直接拖进 arcgis结果提示缺少投影文件或打不开属性表问题往往出在配套文件没解压干净。一个完整的 shapefile 至少要有.shp几何、.shx索引、.dbf属性表常常还带.prj投影、.cpg编码、.sbn/.sbx空间索引。这个压缩包里如果每个图层都是这么一组文件那才算真的“建好了库”。拿到压缩包后我的习惯是先列一遍目录不急着加载。用命令行做一次结构体检比用 arcgis 手工点一遍快得多也更容易发现漏文件ls -lh 全国矢量地图/ find 全国矢量地图/ -name *.shp | wc -l find 全国矢量地图/ -name *.prj | wc -l第一条命令看每个图层大小第二条统计 shp 数量第三条统计投影文件数量。如果 shp 数量和 prj 数量差了太多说明一部分图层缺投影参数后面做叠加分析时会被不同坐标系搞得晕头转向。常见的全国图层包里有省级面、市级面、县级点、国界线、省界线、主要河流、高速路网这类要素每个图层的几何类型和属性字段各有差异所以体检时不光看文件齐不齐还要看几何类型对不对。2.2 用 ogrinfo 与 geopandas 检查坐标系和范围在不知道数据坐标系之前任何空间操作都是危险的。全国尺度数据常见的坐标系有 CGCS2000 经纬度、WGS84 经纬度也有被投影成 Albers 等面积投影的版本。如果图层没有.prj或者 prj 里写的是“GCS_Beijing_1954”你却以为它是 WGS84叠加底图时就会整整偏移几百米到几公里。用 GDAL 自带的 ogrinfo 做摘要检查ogrinfo -so 全国省级行政区.shp 全国省级行政区-so表示只输出摘要信息。它会列出图层名、要素数量、几何类型、坐标范围最重要的是输出 Spatial Reference 那一行直接确认投影是什么。如果显示的是GEOGCS[WGS 84...]说明是经纬度如果出现PROJCS那就是投影坐标系后面做面积计算或转瓦片时要留意。用 Python 再做一次更细的检查适合要写批处理脚本的情况import geopandas as gpd gdf gpd.read_file(全国省级行政区.shp, encodingutf-8) print(坐标系:, gdf.crs) print(范围:, gdf.total_bounds) # 输出左下角和右上角经纬度 print(要素数:, len(gdf)) print(几何类型分布:) print(gdf.geom_type.value_counts())这段代码有四个输出点作用分别是指认坐标系、看数据覆盖范围、确认要素数量、排查是否存在杂混几何类型。比如一个“全国面图层”里混进了两条线要素用geom_type.value_counts()一眼就能发现后续做空间连接时不会因为几何类型不一致而静默出错。2.3 属性表中文乱码与字段名截断问题全国 shp 数据的属性表通常存省市名称、行政区划代码 PAC、面积等字段。老数据来源复杂编码常常不统一有的是 GBK有的是 GB18030少数是 UTF-8。arcgis 默认按系统区域猜编码遇到.cpg文件缺失或内容不对中文名就会变成一坨问号、乱码。QGIS 在打开时如果检测不到编码也会让你手选这时去乱猜就浪费时间了。最快的办法是看.cpg文件内容再去确认.dbf的编码头xxd 全国省级行政区.dbf | head -3 file 全国省级行政区.dbffile命令会输出类似 “dBase III DBase” 的信息而xxd查看前几个字节能看到字段名区域是 ASCII 还是高位中文经验上中文高位字节出现时基本就是 GBK。确认后在 QGIS 里按“图层属性 → 数据源 → 编码手动设为 GBK”即可恢复用 Python 读的时候则把encodingutf-8改成encodinggbkgdf gpd.read_file(全国省级行政区.shp, encodinggbk)这里必须强调一个容易误判的点乱码不一定是文件坏了多半是读法不对。数据本身还在换编码重读一遍通常就恢复。平时我自己维护这类数据集时会顺手统一做一次编码转换把 dbf 转成 UTF-8避免每次打开都手动指定。具体做法是先把属性导出为 CSV再重新生成 shp也可以直接用ogr2ogr配合-lco ENCODINGUTF-8重写一份。重写前先备份毕竟 re-encode 这种事翻车率不低字段长度和特殊符号都可能被截断。3. 提取目标区域行政区划过滤与矢量裁剪的实用参数3.1 按属性字段精确提取省市范围全国图层范围大动辄几十万到上百万个面要素直接拿来做局部城市分析非常臃肿。最常见的需求就是“我要北京市的范围”或者“我要河北省所有县级行政区”。这种提取用属性查询比空间裁剪稳定因为属性过滤不会产生新几何速度也快得多。在 arcgis 里是先按属性选择再导出数据命令行里用 ogr2ogr 一步完成ogr2ogr -f ESRI Shapefile 北京市.shp 全国省级行政区.shp \ -where NAME北京市-where是 SQL 表达式这里用的是字段名NAME具体字段以图层属性为准可能是省、NAME、PAC等。如果字段值是中文注意终端能正确传 UTF-8 参数在 Windows cmd 下建议先确认代码页或者把 SQL 写进.sql文件用-sql参数引用避免编码踩坑。提取出来的北京市.shp 会保留原属性字段但不会保留原图层的符号化配置。如果你接下来要拿去出图需要重新配置一遍样式如果只是做数据裁剪和计算那就直接可用。按多个省提取时IN语法比多个OR更清晰ogr2ogr -f ESRI Shapefile 京津冀.shp 全国省级行政区.shp \ -where NAME IN (北京市,天津市,河北省)这段命令的逻辑是从全国图层筛选出三个省级行政区合并写入一个新的 shp。注意这里的合并只是把要素拷到一起没有做拓扑融合如果三块边界紧密相连仍会保留公共边面之间没有真正融合。3.2 用矩形范围裁剪把大图层切成工作区域没有属性字段可选时就要靠坐标范围来做空间筛选。比如做水文分析只关心塔里木河流域或者做项目只想要某个经纬度范围内的路网矩形裁剪是最省力气的方式。GDAL 的-spat参数直接按空间范围过滤ogr2ogr -f ESRI Shapefile 南盘江流域.shp 全国河流.shp \ -spat 103.5 24.5 106.5 26.5-spat后面依次是左下角 X、左下角 Y、右上角 X、右上角 Y单位随源数据坐标系。如果源数据是经纬度这里就是经纬度如果源数据是投影坐标一定要用投影坐标值否则会裁出一个空图层。拿不准源坐标系时先回第 2 章用ogrinfo -so确认。这种裁剪的坑在于它只按要素范围是否与外框相交来判断所以落在边界上的线、面会有部分残留在结果里导出的要素几何没有被真正“切开”。想做标准裁剪比如只保留河流完全进入流域内的部分必须用真正的几何裁剪函数。用 geopandas 做真正的几何相交裁剪import geopandas as gpd from shapely.geometry import box river gpd.read_file(全国河流.shp, encodingutf-8) aoi box(103.5, 24.5, 106.5, 26.5) # 左、下、右、上 river_crs river.to_crs(aoi.crs if hasattr(aoi, crs) else river.crs) clipped gpd.clip(river, gpd.GeoDataFrame(geometry[aoi], crsriver.crs)) clipped.to_file(南盘江流域.shp, encodingutf-8)这里用gpd.clip会把每个要素与aoi做真正的几何相交切割后的边界干净面积量算也更准。如果只是筛要素而不切割直接用索引river.cx[103.5:106.5, 24.5:26.5]就能得到候选要素但结果几何不保证都在框内。3.3 如何在 shp 图中去掉一部分矢量反向选择与擦除日常需求里还有一种相反操作不要某个区域保留其余部分。比如做全国专题图时想去掉台湾省以外的海域界线或者在省级图上挖掉某个县做“空白区”展示。术语上叫“擦除”或“反向裁剪”。ogr2ogr 没有直接的擦除参数常见做法是先选中要排除的要素再反选导出。用 arcgis 是“按属性选择 → 切换选择 → 导出数据”命令行里可以用 SQL 的NOT INogr2ogr -f ESRI Shapefile 全国除北京.shp 全国省级行政区.shp \ -where NAME NOT IN (北京市)逻辑上可以对比 SQL 条件做排除但要注意字段值里可能带空格或全角字符比如 “北京市 ” 后面多了一个空格导致排除失败。排查时要先用属性表看真实字段值必要时用TRIM(NAME)或者在 SQL 里加LIKE %北京%ogr2ogr -f ESRI Shapefile 全国除北京.shp 全国省级行政区.shp \ -where NAME NOT LIKE %北京%这种写法会连“北京市”“北京首都机场边界”一类都排掉如果只想排除一个市务必确认字段取值唯一。空间上的擦除则需要用overlay_difference或 arcgis 的 Erase 工具它按几何区域删除而不是按属性行删除。4. 格式转换实战shp 与 kml、geojson、dwg、3dtiles 互转的边界场景4.1 shp 转 GeoJSON 与 KML线上可视化最常用目录服务、Web 地图、给前端同事传数据几乎都绕不开 GeoJSON。shp 转 GeoJSON 的核心不是格式本身而是坐标系的转换。源数据如果是投影坐标系要先转为 WGS84 经纬度否则浏览器里的地图会把要素画到海里。一条命令搞定转换和投影ogr2ogr -f GeoJSON 全国省级行政区.geojson 全国省级行政区.shp \ -t_srs EPSG:4326 \ -lco WRITE_BBOXYES-t_srs EPSG:4326强制输出 WGS84 经纬度WRITE_BBOXYES会在每个要素的 properties 里带上包围盒这个属性对前端做视野裁剪很有用。如果源数据字段名很长GeoJSON 里一般不受限但注意 shp 的 dbf 字段名最长 10 字节所以中文字段名基本都会出问题建议转换前就把字段重命名为拼音或英文。KML 是 Google Earth 系和无人机航测软件常用的格式。shp 转 KML 时最容易丢的是属性字段Google Earth 默认只显示名称其他字段得写进扩展数据里才能显示ogr2ogr -f KML 输出.kml 全国省级行政区.shp \ -dsco NameFieldNAME \ -dsco DescriptionFieldFULLNAMENameField和DescriptionField用来指定 KML 里弹出气泡的名称和描述字段。如果省略这两个参数KML 里可能只剩一个空名字到了 Google Earth 中所有省份都显示为“未命名”又得重新编辑费时费力。4.2 dwg 转 shp先过 dxf 中转站dwg 转 shp 是很多规划、土木背景用户的高频需求因为原始 CAD 图纸是 dwg而分析软件只认 shp。GDAL 官方并没有稳定读 dwg 的驱动这类转换的常规路径是先另存为 dxf再由 ogr2ogr 读取 dxf 转 shp。# 核对 dxf 能被识别 ogrinfo -so 规划用地.dxf # dxf 转 shp按图层提取 ogr2ogr -f ESRI Shapefile 规划用地.shp 规划用地.dxf \ -where LayerJMD \ -nlt MULTILINESTRING关键点是-where LayerJMDdxf 文件里不同 CAD 图层对应不同业务语义路面、用地面、建筑轮廓全挤在一个 dxf 文件里不按 Layer 过滤会全混在一起。-nlt MULTILINESTRING是为了防止 CAD 里大量短线要素被揉成多部件线后续清理更麻烦。转完后的 shp 往往会带着一堆零碎短线、重复线这是在 CAD 里画图不规范的后果不是格式转换本身造成的。我一般会在转换后用v.cleanGrass GIS 工具或 QGIS 的“修复几何”跑一遍把重复线段、微小缝隙清掉再进入下一步分析。4.3 shp 转 3dtiles 与瓦片精度、层级与性能取舍全国底图直接转 3dtiles 会卡到怀疑人生。这个转换的本质是把矢量面覆盖到地形上做切片不是简单换个后缀。我见过有人拿着百度爬下来的全国 shp 直接去导 3dtiles数据动辄几十万个面生成到一半内存就爆了。常用工具是 CesiumLab 和国产的 Model Lab 系列它们把 shp 作为数据源设定最大层级和高度模式后输出。决定成败的更多是准备工作而不是工具先把属性表压缩到只剩必要字段3dtiles 的每个要素都会携带属性字段越多包越大坐标系必须转成 EPSG:4326 或 EPSG:4978Cesium 不支持任意投影如果面要素数量超过一万个建议先做简化比如用Simplify工具抽稀边界点保留层级低时不需要的细节面数据的“高度”模式要决定是贴地还是拉伸贴地时一定要关掉默认的height拉伸值否则整个城市像起了个高台从瓦片角度讲shp 本身不适合发布层级过多的瓦片。数据分辨率只有 1:100 万级别时切到第 12 级已经能明显看到边界锯齿再往上切只会放大噪声不如在切瓦片前先按比例尺做一层综合简化。4.4 反方向geojson、kml 转回 shp 时的属性保障现在越来越多的开源数据以 GeoJSON 发布但 arcgis 老版本和多数测绘软件仍要求 shp。从 GeoJSON 转回 shp 时JSON 里的嵌套属性在 dbf 里存不下会被直接丢掉。这是因为 dbf 是扁平表结构GeoJSON 的 properties 可以是任意嵌套对象。处理方式是先把嵌套属性摊平再转出去ogr2ogr -f ESRI Shapefile 输出.shp 输入.geojson \ -lco ENCODINGUTF-8 \ -nlt PROMOTE_TO_MULTIPROMOTE_TO_MULTI是另一个预防措施。GeoJSON 里的单个 Polygon 和 MultiPolygon 可以混在同一文件里而 shp 不推荐混合几何类型PROMOTE_TO_MULTI会把 Polygon 提升成 MultiPolygon保证整个图层几何类型统一。KML 转 shp 要注意的还有KML 的坐标是经纬度和海拔shp 里没有 Z 值时会丢弃海拔线状地物还好如果是地形剖面类数据转完后高程信息会消失。遇到这种需求我会改用 GeoPackage 或 FileGDB 作为目标格式以保留三维信息。5. shp 文件使用避坑五个高频翻车现象与修复记录5.1 打开图层时属性表中文全是乱码现象arcgis 打开全国 shp 属性表省市名称变成“锟斤拷”“烫烫烫”一类乱码QGIS 里则是“”符号。原因绝大多数是全国数据在制作时按 GB2312/GBK 保存 dbf而读取方默认按 UTF-8 或系统区域码解析。.cpg文件要么缺失要么内容写错了编码名。解决先查看.cpg内容例如cat 图层.cpg显示 “OEM” 或 “936” 即 GBK然后在 QGIS 图层属性里把编码手工改成 GBK 重新加载。如果用 Python 读把 encoding 参数改为gbk。代码上可以把 shp 重新导出一次让新的.cpg写上UTF-8以后再开就不会有问题。5.2 dbf 字段名被截断成 10 个字符现象属性表里字段名明明叫POPULATION_2024导出的 shp 却显示成POPULATIO_2甚至变成POP_2024。原因shapefile 的 dbf 第三版规范里字段名最多 10 字节。中文一个字符占 2 字节或 3 字节更容易被截断。GeoJSON 转 shp、arcgis 导出时都会遇到。解决建字段时用 10 字节的英文名比如POP24而不是人口_2024。如果已经截断了在 arcgis 里用“字段计算器”另建一个新字段把截断字段的值复制过去。命令行里提前重命名字段最省事用ogr2ogr -sql重建字段序列。5.3 shp 转 KML 后 Google Earth 里只剩轮廓没有名称现象所有省界、区界都显示成了多边形但点击要素看不到任何属性名称显示的都是“未命名”或空白。原因KML 的显示名称和描述字段是单独定义的ogr2ogr 不会自动猜哪个属性当名称需要-dsco NameField显式指定。很多教程里不带这个参数总以为属性会自动带过去。解决转换命令里加ogr2ogr -f KML 输出.kml 全国省级行政区.shp -dsco NameFieldNAME如果字段名不是 NAME换成实际字段名。一次转换里只能指定一个名称字段多个字段可以在DescriptionField里拼。5.4 省界线文件“省1”“省2”到底有什么区别接边时对不上现象资料包里有两个 shp一个叫“省界线_省1”一个叫“省界线_省2”看起来都是边界线叠到一起却有一边缝隙、一边重叠。再做拓扑查错边对不齐。原因常见命名里“省1”多数是省级行政单位的面边界线即 polygon 转成的线“省2”可能是国界线含海岸线或另一种数据比例的边线两者的精度、抽取规则、拓扑容差都不同。一个严格贴着省界面一个则按国界测绘成果单独整理所以天然有差异。解决当作数据源时先确认用途。做省级统计用面图层就够了不需要线图层做国界专题图时要把国界线图层与省界线做一次“对齐”处理先叠加以高精度图层为准用snap或v.clean处理缝隙。千万不要把“省1”“省2”随意合并它们不一定出自同一版本数据库。5.5 几何损坏arcgis 报“无法读取 shapefile”或 shapechk 报错现象某个 shp 加载时 arcgis 提示“不能读取 shapefile”但 QGIS 却能勉强打开一部分重复执行某次裁剪后输出 shp 打开时要素数量对不上。原因shp 文件因为网络传输中断、解压软件强制中止、或者程序异常退出导致.shx索引与.shp里的几何记录不一致。最常见是.shx没写完而形状记录本身还在。QGIS 容错性稍强arcgis 对索引完整度更敏感。解决先用 shapechk 工具诊断和修复。shapechk 是开源修复工具它会扫描几何记录并重建索引。用法是shapechk 全国省级行政区.shp /a/a表示在修复前先做分析并输出报告报告会指出哪一段几何数据损坏。修复前一定要把原文件备份shapechk 有时会把损坏处直接标记为无效并去掉某些要素如果原文件还有更优恢复手段被它先改了反而麻烦。修复完成后用ogrinfo -so再跑一遍确认要素数符合预期再继续分析。日常避免这种问题的习惯也很重要rar 解压时不勾选“后台解压”解压过程中不要开其他大软件传输 shp 前最好打成 zip 而不是单独发.shp避免邮箱或聊天工具吞掉.shx。6. 进阶技巧用渔网分割全国图层做空间统计的关键参数拿到全国面图层却不做统计分析等于只用了它 30% 的价值。我常做的一个操作是把全国按经纬度或投影坐标切成渔网网格再统计每个网格覆盖的县级行政区数量或河流长度。这类需求在热词里总被叫“渔网分割 shp”但这里有个概念要澄清渔网任务其实是“生成渔网并叠加”不是把 shp 本身切开。用 QGIS 生成渔网非常直观“矢量 → 研究工具 → 创建渔网”。关键参数是网格间距和范围。如果全国图层是经纬度坐标1 度网格大约相当于 111 公里适合做省级对比如果是投影坐标或者你要做县域统计网格间距用 100000 米至 500000 米100 至 500 公里更合理。网格范围建议直接选择“全国省级行政区”图层的范围不用手动填最小坐标避免渔网覆盖区域和图层范围出现偏差。网格生成后做空间连接统计每个网格与省级面的交集面积占比才能算出“该网格主要属于哪个省”import geopandas as gpd grid gpd.read_file(渔网_100km.shp, encodingutf-8) prov gpd.read_file(全国省级行政区.shp, encodingutf-8) joined gpd.overlay(grid, prov, howintersection) joined[area] joined.geometry.area result joined.groupby(grid_id).apply( lambda g: g.loc[g[area].idxmax(), 省份] )这段代码的精髓是先用 overlay 求每个网格与省份的相交面再按grid_id分组保留面积最大那个省份作为归属。如果不做面积比较网格只要擦到省界边缘就会被统计成跨省结果里会冒出来一堆“既是河南又是山东”的噪声网格。同样逻辑可以做“每个网格内河流长度”把线要素与网格相交后统计线段长度总和river gpd.read_file(全国河流.shp, encodingutf-8) river[len] river.geometry.length grid_len gpd.overlay(river, grid, howintersection) grid_len[seg_len] grid_len.geometry.length summary grid_len.groupby(grid_id)[seg_len].sum()注意这里必须先求相交再按网格 id 汇总长度不能直接对原始river的 length 做分组因为一条河流会跨多个网格原始 length 是整条河的长度与网格没有关系。初次做这个统计时我没意识到这一点结果一个网格的河长等于整条黄河的长度图表上出现巨大异常值从那以后我每次做渔网统计都强制走一遍“先相交、再分组汇总”的流程宁可多算一步也不让脏统计混进结果。希望这一节的操作细节能帮你少走同样弯路。本文还有配套的精品资源点击获取
