简介:2024年甘肃省10类地理与人文空间数据以Shapefile格式整合打包,面向GIS开发者、城乡规划师与区域研究人员,解决甘肃省级多尺度空间底图分散、格式不一、难以直接使用的问题。包内提供省、市、县区、乡镇街道四级行政区划,以及水系(面+线)、道路、大学、景点、高程、土壤类型等图层;属性表包含标准行政区编码、名称、类别、地址和坐标信息,全部统一至WGS 1984坐标系,可直接加载进ArcGIS、QGIS开展制图、叠加分析、缓冲区分析等工作。压缩包共53个文件,大小115.17MB,以shp、dbf、prj、shx等空间数据文件为主体,附带全国范围TIF高程、土壤分类xlsx说明文档及投影定义文件,分专题目录存放,便于按需调用。目前已有58人学习/下载,适合需要快速获取甘肃基础底图、开展教育资源分布、旅游文化地理、交通可达性或农业适宜性评估等空间应用场景的读者。
1. 2024年甘肃省10类【地理+人文】shp文件这套组合,先按“底图、分析、专题”来用
做GIS的人都知道,翻遍各种shp文件下载站点,仍找不到一套能覆盖省、市、县、乡四级又带水系道路高程的数据,有多浪费时间。2024年甘肃10类【地理+人文】shp数据把省、市、县区、乡镇街道四级行政区划,水系、道路、高程三组地理要素,以及大学、景点、土壤类型三组专题数据收进一套矢量包里。它适合的范围很明确:区域规划、应急制图、旅游线路分析、土壤适宜性评价这类带空间分析的项目,起步阶段不需要再去拼碎片数据。这篇文章就顺着这套文件讲清楚三件事:怎么给10类数据分组、开工前怎么统一坐标系和检查文件完整性、实际处理里最容易翻车的环节在哪。
2. 10类甘肃shp文件先拆成三组,再决定投影和字段策略
拿到一套shp,第一件事不是急着双击打开,而是先按“几何类型、坐标系、属性字段”拆成底图、地理、专题三组。不同组的处理方式完全不同:线状水系不能和面状县区直接做相交,点状大学不能和乡镇面共用同一套拓扑规则。只要这一步想清楚,后续的裁切、融合、叠加都只是按套路执行。
2.1 省、市、县区、乡镇街道四级行政区划shp,分层粒度决定了工作量
这四层是同一份行政区划数据按行政级别拆开的,正常情况下面边界保持严格一致。做整张甘肃挂图,用省层就够;做兰州都市圈规划,切市界;做到村一级的公共服务设施可达性分析,必须用乡镇街道面。粒度选错,后面所有统计都得返工。
拿到数据之后我一般先开属性表,看行政区名称字段到底叫XZQMC还是town,再看行政代码是6位还是9位。6位代码只到县,9位代码到乡镇。如果只有6位代码,乡镇层就做不了唯一值匹配,聚合统计时会出现字段缺失。2024年的新数据大多用9位行政区划代码,但字段命名在不同打包版本里差异很大;建议首先把名称类字段统一改成name,代码字段统一改成code,后面做dissolve和join时才不用反复查字段名。
判断数据层级还有一个实用方法:全选属性表后查看要素数量。甘肃省14个市州、86个县区、1200多个乡镇街道,数量级差距一眼能看出来。如果某乡镇层只有几十个要素,说明打包时已经合并过,不满足村级分析需求。
2.2 水系、道路、高程三组地理shp:线层、面层、栅格不要混在一个工程里
水系通常至少分成两个文件:河流线、湖泊水库面;道路是线层;高程可能以等高线shp或DEM栅格出现。在甘肃做项目时,这三类的性质差异特别突出:河西走廊的河流多是内陆河,需要区分人工渠与自然河流;甘南和陇南山区的道路受地形约束大,道路shp中的等级字段直接决定可达性建模结果;高程若是DEM栅格,就不能和矢量shp做相交计算,而要先做“按掩膜提取”切成研究区范围。
我建议在一个GIS工程里创建三个图层组:第一组放行政边界、道路、水系面;第二组放水系线、道路中心线、等高线;第三组放栅格。这样在做叠加分析时,不会因为图层组混乱而误把点层和线层当成面层去统计面积。GIS软件不会拦你,计算出来的结果也没有语法错误,但从地理意义上讲,河流长度和湖泊面积本来就不可比。
2.3 大学、景点两个点图层与土壤类型面图层:坐标漂移是最常见的坑
大学与景点属于人文POI,网上常见的打包数据常来自互联网地图服务商。很多服务商对外提供的是加密坐标,而行政区划shp用的是CGCS2000或WGS84,两者直接叠加会出现几十到几百米偏移。判断方法很简单:把兰州大学榆中校区的实际坐标和大学.shp里的坐标对比,偏差大于200米就要做坐标纠偏。土壤类型面图层则要警惕坐标系标注错误,历史资料常混用北京54、西安80和CGCS2000,直接当CGCS2000使用会在面积测量上产生不可接受误差。
纠偏思路是用QGIS或ArcGIS里的“空间校正”做相似变换,再叠加官方控制点核对。不要“想当然统一到CGCS2000”,要先看原始坐标到底属于哪个基准面。土壤类型图层最好对照全国第二次土壤普查的图斑编号,逐条核对县级边界是否吻合,否则做种植适宜性评价时结果不可信。
3. 开工前把10个shp文件统一到EPSG:4547,并做一次数据完整性检查
甘肃东西跨度约1600公里,跨3度投影带的多个分带。如果全项目统一用WGS84经纬度做面积统计,面积会偏大,线长度也会失真。常见做法是使用CGCS2000 / 3-degree Gauss-Kruger CM 105E,也就是EPSG:4547。下面几步能把10类shp一次性统一到这个坐标系,同时把损坏文件暴露出来。
3.1 用ArcGIS Python批量读取所有shp的投影信息,先找出没有.prj的文件
用ArcCatalog逐个右键查看属性太慢,可以直接用arcpy批处理遍历目录。打开ArcGIS Pro的Python窗口,改好工作路径后运行下面脚本:
import arcpy arcpy.env.workspace = r"D:\gansu_shp_2024" for fc in arcpy.ListFeatureClasses(): desc = arcpy.Describe(fc) sr = desc.spatialReference print(fc, "|", sr.name, "|", sr.factoryCode)这段代码做的事情很简单:ListFeatureClasses罗列目录下所有shp,Describe提取每个要素类的空间参考信息。sr.name显示坐标系名称,sr.factoryCode显示EPSG代码。运行后如果某个文件只显示Unknown或 None,说明缺少.prj文件,后续加载会被默认当成WGS84处理。参数上要注意arcpy.env.workspace只能指向一个目录,如果shp分散在多个子文件夹,需要先遍历子目录。
没有.prj的shp并不代表数据本身损坏,可以手动指定投影。但必须确认来源单位当初用的投影,不能凭文件名猜测。甘肃的省、市两级文件最常见的是CGCS2000,县级以下有时混着西安80,在重投影前要单独挑出来。
3.2 用shapechk修复shp文件结构,给坏文件一颗后悔药
shp文件在传输中经常丢伴生文件。一个完整的shapefile至少包含.shp、.shx、.dbf三个文件,.prj和.cpg可有可无。ArcGIS打不开某个shp时提示“无法读取”,绝大多数情况是.shx索引损坏或丢失。这种情况下不要直接放弃,先用shapechk这类修复工具重建索引。
shapechk的用法不复杂:打开软件后选择shp文件,工具会扫描几何记录和索引之间的对应关系,找出坏记录并自动重建。修复完成后建议把结果另存为一个新的shp,命名加_fixed后缀,不要在原文件上直接覆盖,避免修复失败后连原始数据都丢了。这个习惯很值得养成,尤其是从网盘下载的行政区划数据,打包压缩时经常把.shx漏掉。
如果在QGIS环境下,也可以用更轻量的办法:直接把shp拖进QGIS,右键图层执行“导出另存为”,让软件从.shp中重建索引并生成新文件。QGIS在读取容错上比ArcGIS更宽松,但这不代表数据没问题,导出后再用拓扑检查扫一遍才算安心。
3.3 检查着字段名和编码,中文乱码问题一次说清
shp文件的属性表存储在.dbf中,这个格式理论上不支持UTF-8,早期数据普遍是GBK编码。到了QGIS里,如果图层编码识别错误,看到的字段名会是乱码,比如XZQMC变成一串不可读字符。解决方法是在导入时手动指定编码,或者用脚本批量修正:
import geopandas as gpd gdf = gpd.read_file("D:/gansu_shp_2024/大学.shp", encoding="gbk") gdf.to_file("D:/gansu_shp_2024/大学_utf8.shp", encoding="utf-8")这段代码用encoding="gbk"读取原始文件,再用encoding="utf-8"写出新shp。encoding参数的选择取决于.cpg文件标注的字符集;如果没有.cpg文件,最稳妥的做法是分别试gbk、utf-8、gb18030三种编码,看哪个不乱码就用哪个。写完新文件后,再用3.1节的Describe脚本重新验证一遍字段名,避免字段编号被软件截断。
在字段层面还容易遇到一个问题:同一乡镇街道层里,部分记录的名称字段是空值。这通常来自原始乡镇合并数据未同步更新。解决办法是按行政代码code关联到县区表,把名称带出来;不要只靠名称字段做聚合,因为甘肃有不少乡镇名称是重名的。
3.4 省界线文件省1和省2的shp有什么区别,该用哪一层
很多从平台下载的行政区划包里有“省1”和“省2”两个界线文件,经常让人一头雾水。我的理解是:这两个文件在数据组织上经常是一个是面状行政区层,一个是线状边界层;或者一个是完整版省级面,一个是不含争议标注、只做制图用的简化线层。
区分方法还是看属性表和几何类型。面状层可以直接做面积统计,线状层只能用来制图或做线缓冲。甘肃的单个省级项目,我一般直接用县区层融合出省面,不再去依赖省界线文件。原因是省1和省2在使用边界规则上存在差异,一旦把线级省界参与县区融合,容易出现细缝和重合问题。要判断该用哪一层,先看要素类型和要素数量,再看属性表里有没有国界代码字段;如果只有名称和长度字段,通常就是线状层,只能当背景网格使用。
4. 把10类shp组合起来做项目:从甘肃分市分幅到kml、3dtiles输出
分组检查全部通过后,数据就可以进入实际生产了。这里列四条最常用的操作路径:按市州聚合、导出KML、转3DTiles、以及用Excel点转shp生成临时点位。每一步都尽量给可复制参数,项目不同时改路径和字段名就能直接用。
4.1 用geopandas把乡镇街道聚合到市州,得到一张可统计的市级底图
省市县乡四级边界分开存放时,最常见的需求是把乡镇面按市级代码聚合,生成一张市级统计底图。用ArcGIS的Dissolve工具可以做,但批量处理时geopandas脚本更直观:
import geopandas as gpd town = gpd.read_file("D:/gansu_shp_2024/乡镇街道.shp", encoding="gbk") town = town.to_crs("EPSG:4547") city = town.dissolve(by="市代码", aggfunc="first") city.to_file("D:/gansu_shp_2024/市州_聚合.shp", encoding="utf-8")先读取乡镇层,统一转到EPSG:4547,再按市代码字段溶解。by指定聚合字段,这里必须是9位行政代码中代表市州的前4位,如果在乡镇层里只有6位县代码,需要先用string slicing截取出市代码。aggfunc="first"表示非聚合字段只取第一条记录,防止名称字段出现过多重复。
溶解完成后要检查一下输出面层有没有碎面。常见结果是武威、张掖这类面积较大的市州产生很多细长多边形,原因来自源数据乡镇边界存在微小缝隙。遇到这种情况返回第5章第1条,先拓扑修复再溶解。
4.2 arcgis shp转kml时,为什么先要转成EPSG:4326
在ArcGIS Pro里把shp转成kml,很多人直接选“导出KML”按钮,结果在Google Earth中图层错位。原因是KML规范要求使用WGS84经纬度坐标,如果shp是CGCS2000投影坐标,就必须先重投影。常用命令是:
import arcpy arcpy.env.workspace = r"D:\gansu_shp_2024" arcpy.conversion.LayerToKML( "景点.shp", "D:/gansu_shp_2024/甘肃景点.kml", "1", "true", "false" )LayerToKML的参数含义分别是输入图层、输出KML、图层输出比例尺、是否复合要素、是否地面叠加。第三个参数里的“1”代表按原比例输出,不需要缩小时填写更大的数。重点提醒:输出KML时属性字段会有压缩,长字段名会被截断甚至丢失,建议在转换前先把要保留的字段复制为name、desc这种短名称。
QGIS里另存为KML更灵活,在导出选项里可以勾选“COORDINATE_PRECISION”控制坐标精度,建议设置为7,保证十进制度数的亚米级精度。导出的KML可以再转回shp,但此时必须注意字段类型已经转换为文本类型,数字字段需要重新转换。
4.3 shp转3dtiles与json转shp,两条最常见的格式转换路线
现在做三维可视化的项目越来越多,shp转3dtiles成了高频需求。完整的shp并不能直接转成3dtiles,常见做法是先把shp转成GeoJSON,再用CesiumLab或3d-tiles-tools切片。GDAL提供了一条最稳定的转换命令:
ogr2ogr -f "GeoJSON" 甘肃景点.geojson 甘肃景点.shp这条命令把shp直接转成GeoJSON。-f指定输出格式,输入文件放在最后。要反向操作,也就是把GeoJSON转回shp,命令换成:
ogr2ogr -f "ESRI Shapefile" 甘肃景点_new.shp 甘肃景点.geojsonGeoJSON不具备shp的多部件复杂几何类型,如果源shp里存在MultiPatch或Z值,转出来的结果可能丢失高程信息。针对甘肃地形项目,高程信息最好保留在属性表字段里,而不是依赖几何Z值,这样的数据更容易在三维平台间流转。不要轻信网上随手找的json转shp网站,上传原始shp到不明站点本身就有数据安全风险;用本地GDAL转换是更专业的选择。
4.4 用Excel点转shp,快速把调研坐标组装成可用图层
很多没有经过GIS训练的同事会用Excel记录采样点,包含经度、纬度、名称三列。把这些数据转成shp不需要手工在ArcGIS里“添加XY数据”,用Python脚本处理更高效:
import pandas as pd import geopandas as gpd from shapely.geometry import Point df = pd.read_excel("D:/gansu_shp_2024/甘肃调研点.xlsx") df["geometry"] = df.apply(lambda row: Point(row["经度"], row["纬度"]), axis=1) gdf = gpd.GeoDataFrame(df, geometry="geometry", crs="EPSG:4326") gdf.to_file("D:/gansu_shp_2024/调研点.shp", encoding="utf-8")这里要求Excel里的经度、纬度是十进制度数,如果源文件里是度分秒格式,必须先统一换算。Point(row["经度"], row["纬度"])的顺序不能写反,shp和大多数空间库都是先x后y,也就是先经度后纬度。crs="EPSG:4326"表示这批坐标是WGS84经纬度,如果调研用的是手机GPS默认输出,这个设置是对的;如果是手绘地图量出来的坐标,还要先确认底图坐标系,否则点位会整体偏移。
批量生成shp后,再和已有的县区面做空间连接,把乡镇名称和县区代码挂到点上。这样一份普通的调研表就能参与行政区域的各类统计,比手动一个个填属性值可靠得多。
5. 甘肃省shp数据处理避坑:5个高频问题,现象原因解决一次说清
处理shp文件时间久了,我形成一套固定排查套路:先看几何一致性,再看投影,然后查字段。下面五条基本覆盖了甘肃10类shp最常翻车的场景,每一条都是“现象、原因、解决”三步走。
5.1 县区与乡镇边界接缝,面积统计一加就对不上
现象:把某市下的乡镇shp做面积求和,结果比统计年鉴上的县区面积少很多。再把乡镇融合成县区面,跟县区shp边界叠不上,出现细长缝隙。
原因:相邻乡镇在数字化时公共边没有完全重合,或者在投影转换时产生了微小偏移;乡镇层和县区层来自不同比例尺底图,只要源头不一,边界线就不会完全重叠。
解决:先把乡镇层按县区代码dissolve成临时县界面,和原始县界面做拓扑叠加,用1米容差把公共边咬合起来。在ArcGIS里使用“拓扑”工具集下的“Integrate”,在QGIS里使用“修复几何”算法。做完这步再融合省、市层面,不要在最终阶段反复修边界。
5.2 将甘肃shp转成Web墨卡托后,河流和道路发生了几十米偏移
现象:把10类shp整体转成EPSG:3857用于在线发布,结果叠加天地图或谷歌地图时,兰州城区的道路和河流整体向西偏移,越往东越明显。
原因:Web墨卡托是球面投影,适合在线浏览但不适合做精确分析;甘肃跨越多个3度带,直接用3857计算距离、面积会失真。
解决:分析阶段统一用EPSG:4547,只出图时再转3857。专题图需要底图瓦片时,把瓦片作为背景,shp保持在CGCS2000。两者叠加时,只有发布端做动态投影,原始数据不做任何坐标系改动,偏差才会降到最小。
5.3 kml转shp后出现一堆无属性的零散要素,景点数量莫名其妙翻倍
现象:在Google Earth里标了20个景点,导出kml后用在线工具转shp,打开ArcGIS变出30多个要素,不少要素没有名称字段,位置还跑到陇南的山沟里。
原因:KML里除了地标,还有文件夹、样式符号等结构,部分工具把<Folder>、<Style>也解析成了要素;另一方面KML坐标顺序是经度、纬度,自定义脚本解析容易颠倒。
解决:用GDAL直接转换:ogr2ogr -f "ESRI Shapefile" out.shp in.kml,不要用网页工具。转换后先用“修复几何”处理一次,再按属性条件筛选掉空名称要素。如果KML里有Z值,导出的shp会带高程字段,做二维分析时要留意是否过滤。
5.4 dwg转shp后线要素的宽度和高程属性丢失,道路分析没法继续
现象:拿到设计院CAD总图,转成shp后发现所有道路线统一变成细线,属性表里没有道路等级、宽度、车速字段,原来在CAD里设置的颜色和线宽都消失了。
原因:CAD的道路属性存在图层名、线宽、扩展数据里,不是shp标准的属性字段。dwg转shp时转换工具只保留几何坐标,并不能自动生成道路等级字段;线宽属于样式信息,shp本身不存储样式,因此全部丢失。
解决:转换前在CAD里把图块“炸开”,删除重复线,再用ArcGIS“CAD转地理数据库”工具导入。导入后按图层名生成RoadClass字段,例如图层名含“主干道”就赋值为城市主干路,然后手动补齐缺失属性。如果目标平台是MapGIS,不要直接转线文件,先把shp导出为DXF再进MapGIS编辑,否则曲线节点信息容易丢失。
5.5 用渔网分割甘肃景点shp,碎点太多且属性被平均化
现象:做景点密度分析,用渔网工具把甘肃切割成若干格网,生成结果后景点全部落在网格边界上,属性表还出现大量重复统计。
原因:直接用了“裁剪”而不是“空间连接”,渔网范围超出甘肃边界,省外的空网格也被保留;点落在网格边界时,裁剪会把每个点切出多个副本。
解决:先用甘肃省界裁剪渔网,再做“空间连接”,匹配选项选“相交”,连接操作选“一对一”。这样每个景点只归属一个网格,网格外的空图斑也一并删除。记住一个原则:点数据与面网格关联用空间连接,不要用裁剪。
6. 最后一招:用GeoPandas把甘肃10类shp统一整理成GeoJSON,交付给任何前端
项目到了交付环节,最常见的要求不是交付shp,而是让前端网页直接读取GeoJSON。与其在GIS软件里一个一个导出,不如写一个批量脚本,把整个目录下的shp统一整理成标准GeoJSON。
下面这段脚本可以放在gis_tools.py里反复使用:
import glob import geopandas as gpd for file in glob.glob("D:/gansu_shp_2024/*.shp"): gdf = gpd.read_file(file, encoding="gbk") if gdf.crs is None: gdf = gdf.set_crs("EPSG:4547") gdf_wgs84 = gdf.to_crs("EPSG:4326") out_name = file.replace(".shp", ".geojson") gdf_wgs84.to_file(out_name, driver="GeoJSON", encoding="utf-8") print("已转换:", out_name)这段脚本的工作流程是:遍历目录下所有shp,用GBK编码读取,如果缺少投影信息则手动指定为EPSG:4547,再统一转换到EPSG:4326,最后写出GeoJSON。driver="GeoJSON"说明输出格式;encoding="utf-8"保证前端不会乱码。
转换完成后至少要验证三件事:第一,要素数量是否和源shp一致;第二,字段名是否保留;第三,叠加到在线底图时,乡镇边界是否和天地图影像对齐。验证时我用QGIS新建一个工程,把原始shp和转换后的GeoJSON同时加载,开启“识别”工具随机抽查五个要素位置,再做一次字段统计。这个习惯让交付过程少了很多返工。
我自己的习惯是,把所有shp处理脚本都放在同一个gis_tools.py里,包括投影检查、编码修复、KML转换和GeoJSON导出。这样下一次遇到甘肃或其他省份的同类数据,不用临时找在线工具,也不会因为忘了某个参数而重新踩坑。希望这篇笔记里的流程和避坑经验能帮到你。
本文还有配套的精品资源,点击获取