ARTICLE DETAIL

资讯详情

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

全国地貌分布SHP矢量数据:坐标系、裁剪与格式转换实战指南

全国地貌分布SHP矢量数据:坐标系、裁剪与格式转换实战指南 简介全国地貌分布shp矢量图层数据包面向GIS、地理信息科学、城乡规划及地学科研人员解决在地貌专题制图中缺少统一基础底图的问题适用于地貌分类、空间制图与区域对比分析等场景。资源共10个文件包括shp主文件、dbf属性表、shx几何索引、prj投影文件以及sbn/sbx空间索引与mxd地图文档并附带说明文档可帮助快速理解地貌代码与类型的字段含义也可用mxd直接打开工程视图。压缩包整体约6.17MB结构完整可在ArcGIS、QGIS等主流平台加载使用无需额外数据预处理。目前已有396人学习下载。数据以全国为范围包含地貌代码、地貌类型等关键属性支持按类型符号化渲染、属性查询与面积统计能支撑全国尺度的地貌专题图制作与定量分析对需要基础底图数据的学生、工程师与科研人员较为实用作为教学演示或科研底图都较为便捷。1. 全国地貌分布shp矢量图层数据先搞清楚它是什么再想怎么用做全国尺度的地貌分析最怕的往往不是算法写不出来而是数据从哪来。手里有一套“全国地貌分布shp矢量图层数据”意味着什么它意味着全国的山地、丘陵、平原、台地这些基本地貌类型已经按统一的分类体系勾好了边界、编好了属性代码放进了一套标准的shp矢量图层里。拿到它可以直接做生态区划、土地适宜性评价、流域提取结果验证、地貌专题制图省掉从遥感影像里重新解释地貌的大半年时间。适合GIS数据处理工程师、规划院数据岗和做区域研究的同学。但它不是拿来就能用坐标对不对、字段怎么读、裁剪后属性还准不准都是接下来要过的坎。2. 读懂全国地貌shp的内部结构坐标系、字段与几何类型2.1 shp不是“一个文件”而是一组配套文件很多刚接触的人以为shp就是一个后缀为.shp的文件拷走时只拿了一个.shp结果在别人电脑上打开显示一堆乱码或完全加载不出来。shp全称是Shapefile是ESRI定义的一种矢量数据存储格式它以一组文件共同描述一份空间数据缺一个都不完整。文件后缀作用缺失后果.shp存储几何形状点、线、面数据无法显示.shx几何索引加速读取部分软件打不开.dbf属性表存储每个要素的字段值属性全丢只剩图形.prj坐标系描述文本WKT格式软件把坐标当成未知或经纬度.cpg属性表字符编码声明中文属性乱码补一个常被忽略的点全国地貌数据里的几何类型大多是Polygon但遇到群岛、跨区域碎斑时一个要素可能被记录为MultiPolygon。显示上没有任何区别计算面积和导出时会带来额外分支判断。另外如果要在ArcGIS里新建shp文件记得在创建时把几何类型选为面坐标系选择和后续分析数据保持一致否则后面所有叠加都会出现“套不准”的问题。2.2 地貌分类字段怎么从属性表里认出地貌类型全国地貌数据的分类体系常见做法是参考《中国1:100万数字地貌制图规范试行》这类技术文件把地貌按“基本地貌类型、成因、形态、物质组成、坡度、切割程度”等维度组合编码。生产数据时通常会把类型名称和编码写进属性表。以下是我在实际项目里见过的比较有代表性的字段设计不同来源字段名略有差异以官方元数据为准字段名示例值含义FID0,1,2…要素编号ShapePolygon几何类型为面Code211地貌类型代码可细分到六级Name中起伏山地地貌类型名称Area12345.6面积平方米或公顷以元数据为准Level1山地一级大类光有字段还不算完要看懂Code的判读规则。比如Code211这种编码习惯上第一位是基本地貌类型2代表山地第二位是成因类型1代表构造第三位再细分形态。拿到数据时如果只有Code没有Name就要根据编码表做一次字段映射。这种情况我一般直接生成一个字典用Python的replace方法把Code翻译成Name避免在属性表里手工一个个改。2.3 坐标系先看.prj别靠猜全国范围的地貌shp坐标系一般在CGCS2000、西安80、WGS84这三类里选。判断依据就是.prj文件里写的坐标系统文本。常见情况如果.prj写的是GCS_WGS_1984坐标值在73~135之间十进制度属于经纬度存储适合全图预览不适合量面积。如果写CGCS2000 / 3 Degree GK Zone 或 Gauss-Kruger坐标值会是几百上千万的米制数值适合按投影带做精确计算。如果文件历史较老可能是Xian 1980西安80和CGCS2000之间有两套椭球参数差异直接叠加会有几十到上百米的偏差。在选择投影时全国尺度和区域尺度的结论完全不同。做全国范围的分析建议用Albers等积投影做淮河流域的汇水分析用UTM 50N或CGCS2000高斯投影如果只是预览直接用WGS84也行。重要的是用途决定投影不是哪种更“高级”。很多翻车现场是别人给了一份标注为CGCS2000_3_Degree_GK_Zone_39的shp但用户拿它去和华东地区的高斯投影数据叠加分带不一致横向错位几百米。所以每次拿到分带投影数据先确认带号和中央经线。2.4 用Python快速体检shp配套文件与坐标系在没有ArcGIS的机器上也可以用Python脚本做一次快速体检判断这份数据是否完整。下面的脚本会列出配套文件并读出.prj里的坐标系文本。import os from pathlib import Path shp_path rD:\gis_data\national_landform\landform.shp # 1. 检查配套文件是否齐全 base Path(shp_path) required_suffixes [.shp, .shx, .dbf, .prj, .cpg] print(配套文件检查) for suffix in required_suffixes: f Path(str(base) suffix) print(f{suffix:6s} {存在 if f.exists() else 缺失}) # 2. 打印.prj里的坐标系描述 prj_path Path(str(base) .prj) if prj_path.exists(): with open(prj_path, r, encodingutf-8, errorsignore) as fp: print(\n坐标系描述\n, fp.read()[:500])逻辑说明脚本第一步遍历shp必须配套的后缀逐个判断文件是否存在第二步读取.prj文件的前500个字符并打印。如果缺.prj打印为空后续加载时就要做好“定义投影”的补救。参数说明shp_path要改成你本机实际路径。有些数据带.qpjQGIS专用投影文件而没有.cpg这也是正常的核心是.shp/.shx/.dbf不缺.prj没有则要靠元数据来补。读取.prj时用errorsignore是因为某些老数据里会带BOM或局部编码字符硬解码会影响读取出错。如果体检时发现.prj缺失还有一个补救方法是读dbf里的坐标范围判断是经纬度还是投影坐标。比如X在73~135、Y在18~53基本可以推断是WGS84或CGCS2000地理坐标系如果X是十几万到几十万或X是几百到几百万说明是投影坐标。这样可以靠经验在软件里做“定义投影”但带号无法精确获知必须结合元数据或原始来源信息。所以拿到数据时一定要保留README或元数据记录这是后悔药。3. 用geopandas把全国地貌shp读起来快速预览、投影与裁剪这部分的实操目标是拿到全国地貌shp后在本地快速读起来把坐标系搞清楚然后按研究区范围做裁剪。我用的工具是Python的geopandas跨平台、免费、脚本可复用比在ArcGIS里点鼠标更适合需要重复执行的数据预处理。3.1 安装与第一次读取先保证环境里有geopandas及其依赖。常见一条命令安装pip install geopandas matplotlib安装完成后用下面的脚本读取全国地貌shp并检查几项最关键的元信息import geopandas as gpd shp_path rD:\gis_data\national_landform\landform.shp gdf gpd.read_file(shp_path) print(要素数量, len(gdf)) print(几何类型, gdf.geom_type.unique()) print(坐标系, gdf.crs) print(字段列表, list(gdf.columns)) print(前5行) print(gdf.head())逻辑说明gpd.read_file是geopandas读取矢量数据的统一入口shp、GeoJSON、gpkg都能读。gdf.geom_type.unique()能看到几何类型是否全为面。gdf.crs打印的是CRS对象如果显示为None说明缺少坐标系定义。参数说明如果read_file报错Unable to open ...先看路径里有没有中文或空格个别Windows环境下默认编码会出问题建议把数据放到全英文路径下再试。读取后如果geom_type里混进了MultiPolygon和Polygon这是正常的全国地貌数据里跨边界的要素往往被拆成多个多面后续处理时需要先统一。3.2 先投影再算面积两个常用坐标系的选择全国尺度的面积统计有一个经典翻车点直接用WGS84经纬度坐标计算面积得到的结果严重偏小或失真。正确做法是先投影到等积投影再算面积。我个人常用两种投影全国整体面积统计用Albers等积投影常用中央经线105°E标准纬线25°N、47°N适合全国范围做面积分区统计。省级或流域级用该区域的UTM投影带例如淮河流域主要在12N~13N带塔里木河流域在45N带附近。代码示意import geopandas as gpd gdf gpd.read_file(rD:\gis_data\national_landform\landform.shp) # 全国范围用Albers等积投影中央经线105E双标准纬线25N/47N albers_crs ESRI:102025 # Albers Equal Area Conic gdf_albers gdf.to_crs(albers_crs) # 计算面积单位平方米 gdf_albers[area_m2] gdf_albers.geometry.area gdf_albers[area_km2] gdf_albers[area_m2] / 1_000_000 print(总面积平方千米, gdf_albers[area_km2].sum()) print(gdf_albers[[Name, area_km2]].head(10))逻辑说明to_crs是geopandas的坐标转换接口传入目标EPSG或ESRI代码即可。geometry.area在所有要素为Polygon/MultiPolygon时直接返回平面面积单位取决于目标投影的计量单位。Albers投影后得到的是米制单位除以1,000,000就是平方千米。参数说明ESRI:102025是ArcGIS里Albers等积投影的常用代码如果使用的geopandas版本不支持ESRI代码也可以改成projaea lat_125 lat_247 lat_00 lon_0105 datumWGS84的Proj4字符串效果一致。不确定性最大的是投影参数是否与研究区匹配。全国尺度下上述参数没问题如果只做某个省建议换用省级的CGCS2000高斯投影或UTM带号避免边缘形变。3.3 按省界或流域裁剪把全国数据切成研究区拿到全国地貌shp不可能直接全量分析通常要按省级行政区或流域边界裁剪。下面以“淮河流域边界shp”和“塔里木河流域矢量shp”这两类典型研究区为例说明裁剪流程。城市尺度也一样比如手里有一份北京 shp裁剪逻辑完全一致像南盘江流域边界shp这类小型流域数据同样流程直接套用。import geopandas as gpd landform gpd.read_file(rD:\gis_data\national_landform\landform.shp) region gpd.read_file(rD:\gis_data\basins\huaihe.shp) # 两个图层必须坐标系一致才能裁剪不一致时统一到region的坐标系 if landform.crs ! region.crs: landform landform.to_crs(region.crs) # 空间裁剪clip会把研究区外的要素裁掉保留下来的部分重新生成几何 clipped gpd.clip(landform, region) print(裁剪前要素数, len(landform)) print(裁剪后要素数, len(clipped)) # 裁剪结果导出为新shp clipped.to_file(rD:\gis_data\national_landform\landform_huaihe.shp, encodingutf-8)逻辑说明gpd.clip是geopandas里的标准裁剪函数裁剪几何用的是region的整体范围。裁剪后的要素可能被切成多个碎片但属性字段会原样保留。导出时encodingutf-8保证中文属性在QGIS和ArcGIS里不乱码。参数说明如果region里包含的是省界和国界且是线文件而非面文件需要先region.geometry.buffer(0)或做面化处理否则clip会报错或产生空结果。裁剪前务必确保两个数据是同一坐标系否则会出现“明明研究区在安徽裁剪结果却跑到海里”的尴尬情况这也是为什么第2章要先检查.prj坐标系问题会一路传导到裁剪环节。3.4 QGIS里的对应操作不习惯写Python的在QGIS里也能完成上述全流程。把全国地貌shp拖进QGIS后图层右键 → Properties → Source可以看CRS工具箱里搜Clip输入图层选地貌shp叠加图层选流域边界shp输出为GeoPackage或shp即可。符号化则在Symbology里按Name字段选择Categorized分类选一个合适的色带。这里的坑是QGIS默认不读.cpg时中文属性会显示成乱码编码里改成GBK或UTF-8重新加载就行。4. 格式转换与投影落地从dwg到shp、shp到kml、shp到3dtiles一份地貌数据在不同项目里要交付成不同格式这是一线工程里躲不掉的需求。常见路径包括CAD的dwg转shp、shp转kml给谷歌地球或在线地图用、shp转3dtiles给Cesium三维场景用以及偶尔遇到的json转shp、excel点转shp、shp转txt。下面把每一类的可落地做法和注意事项拆开说。4.1 转换场景对照先选路线再动手转换需求常用工具输出用途dwg转shpArcGIS Pro的“CAD转地理数据库”将CAD线划地貌草图落库shp转kmlQGIS“导出为KML”或ogr2ogr谷歌地球、在线浏览shp转3dtilesCesiumLab转换工具Cesium三维地球叠加展示json转shpGeoJSON导入GeoDataFrame再导出从在线服务取回的矢量数据excel点转shpgeopandas csv读取或ArcGIS的XY转点把样点、观测点落成坐标点shp转txt用pyshp或geopandas读取后写文本给非GIS系统做数据交换4.2 dwg转shpCAD草图入库的血泪经验很多规划院交过来的地貌边界草图是dwg格式dwg转shp在ArcGIS里最常见的做法是“CAD至地理数据库CAD to Geodatabase”工具而不是直接另存为shp。原因是dwg里的点、线、面、注记全混在图层里直接转shp会得到一堆拥堵的点线要素。操作步骤新建一个文件地理数据库右键 → Import → CAD to Geodatabase选择dwg文件。转换完成后地理数据库里会按CAD图层生成Polyline、Polygon等要素类。打开要素类的属性表按Layer或EntityHandle字段筛选出真正的地貌边界线。清理碎线和重复线使用“修复几何Repair Geometry”和“删除重复要素”然后再用“面化Feature To Polygon”把闭合线转成地貌面。这一套里最花时间的往往是“面化”之前的历史遗留碎线。CAD制图习惯里存在大量首尾未捕捉的断线面化后会出现缺失的镂空或重叠面。我的习惯是先做一次拓扑检查用shapechk这类的shp修复工具先处理自相交线再做面化质量会稳很多。4.3 shp转kmlQGIS导出与ogr2ogr两种做法全国地貌shp转kml核心是确认坐标系。KML强制使用WGS84经纬度所以如果源数据是CGCS2000或西安80投影必须先做重投影再导出。在QGIS中图层右键 → Export → Save Features As…格式选KMLCRS选WGS 84 EPSG:4326。注意字段里不要选太多KML的属性如果全部带上会变得很大建议只保留Name和Code。在ArcGIS中使用“Layer To KML”工具先把图层复制一份并定义为WGS84再传入工具。命令行方式用GDAL的ogr2ogr更稳定ogr2ogr -f KML landform.kml landform.shp -t_srs EPSG:4326 -dsco NameFieldName逻辑说明-t_srs EPSG:4326强制输出坐标系为WGS84这一步不做生成的KML在谷歌地球里会偏移或无法定位。-dsco NameFieldName把Name字段设为KML要素名称便于在谷歌地球里直接看到地貌类型名。参数说明如果shp里有大量中文字段建议在命令后追加-lco ENCODINGUTF-8避免KML打开时中文变成问号。kml生成后建议用文本编辑器打开确认name标签里的内容可读再放到谷歌地球验证。反过来kml转shp也是一样的逻辑。QGIS导入kml后另存shp即可注意KML的坐标天然是WGS84导出时如果下游需要投影坐标系在另存时选目标CRS再转换一次。网上常见的“json转shp网站”这类在线工具处理小文件方便全国地貌这种大文件上传并不稳妥我一般还是离线转。4.4 shp转3dtiles给Cesium的三维地貌场景地貌shp通常是二维面数据要用到三维场景里就得转成3dtiles。推荐CesiumLab这类桌面转换工具或者使用开源的3dtiles库在Python里完成切分。流程大致是把shp按类别字段如Level1提取面要素设置高度范围后生成带拉伸体块的三维模型再切为3dtiles。常见的参数设置是每个地貌类型按分类字段做拉伸拉伸高度给一个足够表现特征的固定值比如山地给500m平原给10m或者从属性表里挂接一个高程字段。贴图用半透明色块叠加在高精度地形上浏览。坑在于全国地貌shp要素数量巨大直接全量转换会导致3dtiles文件非常庞大。我的做法是先按省或流域裁剪再分段转换这样加载速度和内存占用都可控。4.5 json转shp、excel点转shp、shp转txt三个小型常见处理把GeoJSON转成shp最简单是读入geopandas后直接to_file输出。注意如果json是投影坐标系要先保留其crs元数据否则导出后会丢投影。excel点转shp则是典型“属性表变空间数据”操作用pandas读Excel里的经纬度列构造geopandas的GeoDataFrame再指定CRS为EPSG:4326导出。ArcGIS里也有对应的“XY转点”工具流程一样。shp转txt常见于和其他业务系统对接直接用geopandas读取后遍历每条要素的坐标串写成WKT格式文本输出即可。这些转换本身不复杂容易出问题的几乎都集中在三步坐标系设置是否明确、编码是否统一、几何是否有自相交。把这三步在每个转换流程前固定检查一遍翻车概率会大幅下降。5. 地貌shp使用避坑五个常见问题与排查方法5.1 要素几何自相交面化后出现错误镂空现象做面化或空间分析时生成的面要素内部出现不应该存在的空洞或面积统计结果异常。原因源数据在原始矢量化时边界线自相交常见于手工勾绘的复杂地貌边界。shp格式本身不强制拓扑规则自相交不会在加载时报错但会在后续几何处理中引爆。这种问题在1:100万地貌数据里尤其多发因为复杂的山脊线在人工数字化时容易形成回折一旦回折点自交面化工具就不知道该把哪里当内部。解决用shapechk一类的shp修复工具跑一遍也可在ArcGIS里用“修复几何”工具批量处理再对要素重新构建。Python里可以用gdf.geometry gdf.geometry.buffer(0)把自相交面修正这个trick在很多拓扑问题上都管用但要注意buffer会给边界带来微小的形状变化对分析精度要求高的场景要谨慎。处理完后再跑一次面积统计对比修复前后的总量差异是否在合理范围内。5.2 属性表中文变问号现象在ArcGIS里打开属性表Name字段显示成“????”或乱码图例也跟着出错。原因dbf文件的字符编码没被正确识别。老数据的cpg文件缺失或编码为GBK在UTF-8环境下读出来就是乱码。如果数据来源不明甚至可能连dbf的编码标准都混着来一个文件夹里不同字段的乱码情况还不一样。解决如果cpg存在先查看里面的编码声明通常是UTF-8或GBK。没有cpg时可在QGIS里指定编码重新加载Layer Properties → Source → Data Source Encoding。确认编码正确后另存一份UTF-8编码的新shp后续分析都基于新文件。在导出时记得在to_file里显式传encodingutf-8并生成对应的.cpg文件避免问题转移给下游。在ArcGIS里直接改dbf编码比较麻烦我一般用QGIS中转一道Angenehmer。5.3 坐标系错误图形跑到海里去或偏移几十到上百米现象要素能显示但位置和底图套不准有的跑到印度洋有的和全国边界错开很大一段距离。原因缺少.prj导致的坐标系未知、坐标被误判为EPSG:4326、或源数据是西安80而底图是CGCS2000。网上从公开渠道下载的行政区划shp版本很多常见到“省界线文件省1和省2的shp文件”这种命名本质就是不同来源、不同精度版本的数据。省1和省2可能在边界形状上几乎一样但坐标系或拓扑质量有明显差异叠加后总是有缝隙。解决先用第2章的方法查.prj内容确认源坐标系用ArcGIS的“定义投影”工具纠正不存在的CRS识别再通过“投影”工具做坐标转换。如果是从西安80转到CGCS2000需要用到七参数或三参数不能只改坐标系标签。做省界套合时优先用带元数据的官方版本来历不明的数据一定要先做偏差检查。5.4 裁剪后面积字段不更新现象用省界裁剪后属性表里Area字段还是全国范围的旧值和裁剪后的几何面积对不上。原因面积字段是生产方计算后固化在dbf里的静态值裁剪操作不会自动重算它。另一个常见问题是字段名是Area但单位到底是平方米还是公顷常常不标拿过来直接用统计结果和真实值差好几个量级。解决裁剪后在字段计算器里重新计算面积。代码里就是先做裁剪再执行clipped[area_m2] clipped.geometry.area并更新字段。更重要的是报告里使用的面积一定要以重新计算后的值为准不能拿原字段直接出图。拿不准单位时可以先拿全国总面积做一次反推如果算出来的面积和官方陆域面积差几倍单位肯定有问题。5.5 全国数据加载卡顿地图操作不流畅现象把整个全国地貌shp拖进地图软件后缩放平移明显卡顿甚至直接无响应。原因全量要素数据量过大且没有建立空间索引。一次加载全国几十万甚至上百万个面要素普通办公电脑扛不住。解决在ArcGIS里给数据构建空间索引或生成金字塔另一个更常见的做法是直接按区域拆分数据——把全国数据按省界切成多个分省shp工作时只加载当前需要的部分。需要做规则分幅时可以用“创建渔网”工具把全国切成规则网格再按网格切割shp每个网格单独出图或单独转3dtiles。这种“切小再干活”的做法在项目交付里几乎是标配也方便后续把分省成果发给不同地市使用。6. 进阶验证数据质量并做一张全国地貌分区制图把全国地貌shp拿来做正式图件之前先跑一遍质量验证可以避免图做出来才发现统计口径错误。我习惯用脚本快速计算各类地貌的面积占比并和统计数据做比对import geopandas as gpd gdf gpd.read_file(rD:\gis_data\national_landform\landform.shp) gdf gdf.to_crs(ESRI:102025) gdf[area_km2] gdf.geometry.area / 1_000_000 # 按一级类统计面积占比 summary gdf.groupby(Level1)[area_km2].sum().sort_values(ascendingFalse) summary_percent (summary / summary.sum() * 100).round(2) print(summary_percent)判读方法如果山区占比过高或平原占比过低先排查投影、再排查裁剪记录最后才考虑数据本身是否有类型字段错填。在ArcGIS Pro里我还会顺手做一个按Level1的分类符号化用“Categorized”渲染色带选地形色系再叠加一个省界shp数据作为参考线然后导出地图布局输出PDF或300dpi图片作为最终图件。最后的习惯是每次处理完一份地貌shp我会把“原始坐标系、目标投影、裁剪范围、编码、修复工具、处理日期”记录在一个txt文本里和数据文件放在同一个文件夹。下次回过头来用数据不用再重新猜一遍坐标和字段这比记在脑内可靠得多。希望这个工作流对你有帮助。本文还有配套的精品资源点击获取
返回列表