简介:面向地理信息系统制图与空间分析需求的中亚五国矢量数据集,采用Shapefile格式打包存储,涵盖哈萨克斯坦、乌兹别克斯坦、吉尔吉斯斯坦、塔吉克斯坦和土库曼斯坦的行政边界与地理要素,可直接服务于区域规划、资源调查和教学演示。压缩包内共8个文件,其中.shp主文件保存几何坐标,.dbf属性表记录国家名称及统计信息,.prj定义地理坐标系统,配套.shx索引、.xml元数据及字符编码文件,确保数据在ArcGIS、QGIS等主流软件中正确读取与投影。整个包体仅545KB,体量精简,便于传输和快速部署。目前已有186人学习下载,借助这套数据可完成专题制图、多图层叠加、空间查询与简单分析,亦可结合其他数据源扩展研究,尤其适用于中亚地区自然资源分布、交通网络与政治边界等议题,是高性价比的地理信息数据基础。
1. 中亚五国矢量图拿来做空间分析:shp格式为什么比jpg靠谱
做中亚片区基建项目前期选址时,我拿到手的往往是一张jpg底图,边界线跟国名糊在一起,没法计算面积、没法做缓冲区,更没法叠加自己的钻孔点位。后来换成一份shp格式的中亚五国矢量图——哈萨克斯坦、吉尔吉斯斯坦、塔吉克斯坦、土库曼斯坦、乌兹别克斯坦的国界都以面要素形式存着,这才算有了能落地的数据底座。这份数据适合两类人:一类是规划、环评、遥感从业者,要在ArcGIS或QGIS里做叠加分析;另一类是刚接触GIS的数据工程师,想拿真实国界练手,学shp的坐标、属性、格式转换。它能解决的核心问题很直接:把一张不能分析的图,变成能缩放、裁剪、计算面积、批量处理的数据。
2. 拆开shp看数据本质:四个文件、坐标参考与属性表
在动QGIS之前,先花两分钟认识shp的“黑匣子”。shp不是单文件格式,通常解压后你会看到4个同名不同后缀的文件。直接拖进软件可能也能用,但一旦缺了.prj或.dbf,后续的坐标系和属性问题会让人崩溃。为什么先讲这个?因为后续导出kml、转geojson、做渔网分割,底层依赖的就是这几个文件的配合。把这一层摸清楚,后面所有操作都是顺手的事。
2.1 先看文件清单:shp、shx、dbf、prj各管什么
常见做法是解压后先按文件类型查看缺失项。shp这套体系里,四个后缀各管一段,缺一个就有一种难缠的毛病:
| 后缀 | 作用 | 缺失时的影响 |
|---|---|---|
| .shp | 存储几何信息(点、线、面的坐标) | 没有它,整个图层丢失 |
| .shx | 几何索引,加速显示与检索 | 一般不影响手动打开,但部分程序会报错 |
| .dbf | 属性表,国家名、面积、编码等都存这里 | 能画图但没有属性可查,转geojson时字段为空 |
| .prj | 投影参考信息,描述坐标系 | 最常见的翻车点:图层位置漂移,叠加不上 |
我的经验是,收到别人发的shp后先不急着看,把后缀补齐再导入。实际工作中经常遇到只发一个.shp文件的情况,那时看起来能打开,等一查坐标就发现全在0,0附近——因为没有.prj,软件会默认按WGS84或当前工程坐标系去猜,猜错就漂了。这套文件结构也解释了常见的热词操作:shp转txt、shp转kml这些,本质上是把几何坐标和属性表用另一种格式封装一遍。一旦理解了shp底层是坐标集合+属性记录的组合,任何转换工具对你都是白匣子。
关于.shp里的几何类型,中亚五国国界一般用Polygon(面)存储,国界线则可以用Polyline。做面积计算、缓冲区分析时,面要素是最方便的:可以直接调用几何对象的面积属性,不需要自己再闭合线。这份数据从用途上按面要素处理即可。如果你在解压后看到还有一个.xml或.sbn文件,别慌,它们可能是QGIS或ArcGIS生成的辅助文件,不是必需项。
2.2 坐标参考:WGS84经纬度与投影坐标的选择
.prj文件里记录的是坐标参考系统。这里要分清楚两种最常见的坐标定义,因为很多人在这一步选错:
| 坐标系 | EPSG编码 | 特点 | 适用场景 |
|---|---|---|---|
| WGS84经纬度 | EPSG:4326 | 以度为单位的球面坐标 | 原始数据存储、KML/GeoJSON导出、GPS定位 |
| Web Mercator | EPSG:3857 | 米制,直接用于Web地图切片 | Leaflet、Mapbox等前端展示 |
| UTM分区投影 | 如EPSG:32643 | 米制,按经度分带 | 面积计算、精确距离量测 |
拿到这份中亚五国数据时,推荐先确认读出的crs是不是EPSG:4326。如果是4326,它在QGIS里能和在线底图直接叠;但要注意,直接拿4326算面积得到的是平方度,做报告前必须先投影到UTM。中亚主要跨多个UTM分带,哈萨克斯坦跨度大,从42N到44N都有;如果只做一个国家的面积或距离分析,选该国中央经度对应的分带即可。做全中亚范围分析时,可改用Albers等面积投影,避免分带之间的面积误差。
需要说明的是,很多用户拿到数据后问“为什么ArcGIS里显示0,0”,除了缺.prj,另一种情况是.prj存在但数据源本身坐标是经纬度,而工程坐标系设成了高斯投影,这时看起来坐标很小、国家跑到海洋里。所以第一步一定是在图层属性里查看坐标系,而不是直接叠加底图。我不会一上来就点“缩放至图层”,因为那只能帮你看到画布上有没有东西,看不出坐标系对不对。
2.3 属性表字段:NAME与ISO编码能做什么
dbf属性表是这份数据真正的价值所在。一般会包括下面这些字段:
- NAME:英文国家名或中文国家名,用于标注与检索
- ISO:ISO 3166-1 alpha-3码,如KAZ、UZB、TKM、KGZ、TJK,适合做字段关联
- AREA:面积字段,单位可能是平方米或平方千米,使用前先校验
- POP_EST:人口估算值,做人口密度图时可以用
- FID/ID:内部标识
从实践看,ISO字段最实用。例如要做中亚五国人均GDP专题图,你手头有一份Excel的ISO数据,直接按ISO做属性连接,比用中文名可靠得多——中文名经常出现“土库曼斯坦”和“土尔其”这种字形差异,而ISO码不会出错。AREA字段在很多shp里可能是旧估算值,做报告时我一般会用QGIS重新算一遍面积,而不是信任原字段。
这里给一个可直接抄作业做法:用QGIS的字段计算器重新生成面积字段。右键图层打开属性表,点“打开字段计算器”,新建字段area_km2,表达式用$area/1000000即可。前提是图层坐标系已经被定义为投影坐标系,或先在图层属性里把CRS切换到投影坐标系。参数说明:$area是Geometry函数,返回图层坐标系的面积单位;若坐标系为4326,结果会是平方度,此时需要先用“重投影图层”工具转换到3857或UTM。
3. 在QGIS里加载、修复与转换:shp导出GeoJSON、KML与3D Tiles
现在手里有了shp,第一件事是把它加载到GIS软件里验证边界。因为在不了解软件生态的情况下,直接用ArcGIS需要许可,而QGIS完全免费,对shp兼容性很好,且内置了修复几何工具。尤其对于shp新手,QGIS的对话框比ArcGIS的GeoProcessing工具更直白,错误信息也更友好,所以这章用QGIS版本来写。ArcGIS的操作路径类似,只是菜单名称不同,比如ArcMap里是右击图层→数据→导出数据。两者不冲突,你按自己手头软件选一个走通就行。
3.1 加载shp与检查几何有效性
启动QGIS后,按以下步骤加载:
- 菜单栏选择“图层→添加图层→添加矢量图层”(快捷键Ctrl+Shift+V)。
- 源类型选“文件”,点击“...”按钮选择.shp文件。
- 如果属性出现乱码,在“编码”下拉框里换GBK或UTF-8。
- 点击“添加”后,图层出现在图层面板。
加载后我一般做三步检查。第一步:右键图层→属性→信息,确认“坐标参照系统(CRS)”是否是EPSG:4326。第二步:用“矢量→几何工具→检查几何有效性”跑一次,检查多边形是否有自相交或环方向错误。第三步:属性表里统计NAME字段,确认五个国家各有一个面要素;如果数据按行政区划分,行数会超过5行,这取决于数据是按国家拆分还是按省州拆分,不影响后续使用。
几何有效性检查工具输出的参数值得解读:它会把每个无效要素列举为点要素图层,提示错误类型如“自相交环”或“重复点”。如果出现个别无效多边形,后续缓冲区和面积计算会静默出错,这就是为什么必须先跑一遍。完成后若错误不多,用“矢量→几何工具→修复几何”生成一个新图层,并保留原有属性字段。修复几何对话框里有“输出要素类型”选项,默认是自动判断,一般不用改。
3.2 格式转换:导出GeoJSON、KML与3D Tiles
shp的导出菜单在QGIS里是“图层→导出→要素另存为”,这个对话框里能选多种格式。这不是买一把锁,而是换一套钥匙:shp转kml就是把几何和属性重新封装成Google Earth认识的XML结构,shp转GeoJSON是给前端地图用的。常见目标格式、参数和坑我整理如下:
| 目标格式 | 在另存为对话框里的操作 | 关键参数 |
|---|---|---|
| GeoJSON | 格式选GeoJSON,文件后缀写.geojson | CRS建议EPSG:4326,因为GeoJSON规范要求经纬度顺序;如要和Web底图对齐,可选EPSG:3857 |
| KML | 格式选Keyhole Markup Language [KML] | 坐标系必须EPSG:4326,否则Google Earth里位置偏移 |
| CSV/TXT | 格式选Comma Separated Value [CSV] | 勾选“仅导出所选要素”或全部要素;可以导WKT几何列 |
| AutoCAD DXF | 格式选DXF | 导出后可在CAD里编辑;反向dwg转shp,则要在AutoCAD里另存为DXF或通过ArcGIS导入 |
导KML我吃过一次亏:用EPSG:3857导出的KML,在Google Earth里离真实位置偏了上百公里。后来固定成一条规矩,导出KML前先把图层重投影到4326。导GeoJSON时经常有人问“为什么导出后坐标是6位小数,精度够不够”,其实6位小数约等于0.1米精度,完全满足国界制图,不需要强行设置更高小数位。
至于shp转3dtiles,我实际用过的路径是:先导出GeoJSON,再在CesiumLab里加载GeoJSON数据,设置LOD层级并构建tileset.json。QGIS这边还有一个Qgis2threejs插件,可以把shp输出为three.js能加载的产品,但它不是严格意义的3D Tiles。如果只是把国界线做成3D体块展示,插件够用;如果要发布到CesiumJS前端,则用CesiumLab或自写脚本更合适。按需选择,不必纠结于格式本身。反向的kml转shp,在QGIS里直接打开kml,再右键另存为shp即可,GeoJSON和json转shp同理,QGIS的打开对话框都支持。
3.3 局部区域裁剪与渔网分割
拿到中亚五国全国边界,下一步往往是切局部——例如做伊犁河流域或边境缓冲带。QGIS里做法这样:
- 准备一个范围图层(shp或GeoJSON均可)作为掩膜。
- 菜单“矢量→地理处理工具→裁剪”,或在Processing工具箱里搜索“clip”。
- 输入图层选中中亚shp,掩膜图层选中你的范围,输出一个新shp。
注意,clip裁剪保留与掩膜相交的部分;如果你想要的是缓冲带,裁剪之后再用“缓冲区”工具对结果做一次Buffer,距离设为1km。很多初学者会把顺序反过来,先对全国做Buffer再Clip,结果缓冲区跨界到邻国,面积自然多了。Buffer工具的参数里要选“端点样式”为圆角,否则线段相接处会出现直切痕迹,进行学术出图时会显得很粗糙。
渔网分割是另一个常用操作:做面积统计或抽样时,要把研究区划成规则网格。Processing工具箱搜索“创建渔网”(Create Grid),参数包括:网格类型选“矩形”或“六边形”,后者适合蜂窝采样;网格范围下拉选择“使用图层范围”并选中“中亚五国”;水平/垂直间距填0.5度或50km,取决于你需要多大的格网;输出格式选shp或geojson。这一步会生成无属性的网格多边形。若需要统计每个网格内五国的面积占比,再用“矢量→地理处理工具→相交”把渔网与shp相交,属性表里会自动出现每个格子的形状面积,最后用字段计算器换算比例。这套流程在做跨境资源评估时很常用。
4. 避坑记录:打不开、漂移到海里、属性乱码的四类排查
shp这套格式已经有几十年历史,坑都是重复的。以下是我在多个项目里亲手踩过或帮人排查过的四类问题,均按现象→原因→解决的线索来写。
4.1 图层打开后空白或报“打开要素失败”
现象:QGIS里加载了.shp,图层面板有图层名,但地图画布上没有任何图形;有时报“打开要素失败”或“无法从数据源读取feature count”。
原因:多半是.shp与.shx、.dbf三者不同步。比如.shp是今天拷贝的,.shx和.dbf却是三天前的版本,或是文件被网盘同步工具截断了一半。有些系统只同步.shp,漏掉了.shx和.dbf,导致索引与几何对不上。
解决:第一优先重新拷贝一份完整的.shp/.shx/.dbf/.prj到本地目录;其次用免费工具shapechk做修复,它可以重建.shx索引,并会在同目录生成修复后的文件。注意shapechk修复前一定要备份原数据,因为修复会重写文件头。如果加载后图层面板有要素数量但画布空白,还有一种原因是坐标全都为null,打开属性表看geometry字段即可确认。如果整张图偏移到另一个洲,但坐标值不是0,0,多半是投影定义错了,不是文件损坏。
4.2 位置漂移:国家跑去了非洲或海里
现象:shp加载后,图形出现在完全错误的位置——中亚边界跑到了大西洋或非洲大陆中部,或缩成一个点靠在坐标原点附近。
原因:此类情形几乎都是坐标参考系统定义不一致。数据实际是经纬度(EPSG:4326),而工程或图层被错误指定为Web Mercator(EPSG:3857),系统会用不同的数学变换把坐标画在错位的位置;或者.prj缺失,软件按默认当前工程CRS解读。
解决:在图层属性→信息里查看当前CRS。如果是4326而工程是3857,右键图层→图层CRS→“设置图层CRS”把它改回4326(这只是重新解释,不改变数据坐标,但会影响后续叠加);也可以用“导出→要素另存为”,CRS指定为EPSG:4326生成新文件,后续叠加就一致。经验是,修改后保留原始文件,另存CRS修正版,不要覆盖原数据。遇到.prj缺失,找一个同区域的shp复制其.prj文件重命名即可,前提是两个数据的坐标参考完全一致——这条实操在网上下载的零散数据里非常管用。
4.3 属性表乱码:国家名变成一排问号
现象:打开属性表,NAME字段显示一串“???”或方块字,中文名乱码;英文名正常显示。
原因:dbf属性表用GBK编码存储,而QGIS的默认编码UTF-8读取导致解码错误;反过来也有,UTF-8被GBK读,同样乱。
解决:加载图层时在“编码”字段手动选择“GBK”或“UTF-8”。如果已经加载了,右键图层→“更改数据源编码”,在弹出的对话框里选GBK并重新加载。更持久的方法是先用QGIS另存为一个新的shp,并在另存为对话框的“编码”里强制选择UTF-8,此后属性表在中英文环境下都稳定。注意,用Notepad++直接打开.dbf是二进制,不可直接改编码,必须通过GIS软件另存。
我自己拿到数据后会先看属性表,而不是先看地图:字段值一乱,就知道来源是编码问题。还有一个隐藏祸首是用Excel直接编辑dbf——很多dbf编辑器保存后会改坏字段头编码,导致QGIS无法识别字段名。所以后面章节会讲用Python的方式操作dbf相关字段,避免人工翻车。
4.4 几何无效自查清单
现象:对shp做缓冲、相交或面积计算时,结果明显不对——面积是负数、缓冲区缺一块、输出要素数量莫名其妙翻倍。
原因:多边形存在自相交、重复节点或环方向错误。肉眼往往看不出来,但地理处理引擎在计算时会做环方向假设,一旦方向反了,面积正负就颠倒。
解决:常规操作是“矢量→几何工具→检查几何有效性”,发现错误后用“修复几何”得到一个新图层。修复后的要素一般可以直接用于计算。如果修复工具报错频繁,也可以用shapely的buffer(0)技巧:在Python里对几何对象执行buffer(0)能自动拆解自相交环,再重新写回shp。针对中亚边境线,要注意国界两侧地块共享边界线的情况,修复工具会产生重复节点,这只会影响拓扑检查,不影响面积计算,不用手工清理。
5. 用geopandas脚本批量操作:坐标点转shp、属性筛选与格式互转
如果只是用一次,QGIS点菜单就够;但如果要把五个国家分别导出、或按字段循环生成多个文件,脚本就是效率翻倍的路径。geopandas包在此基础上读取和写出shp都调用gdal/fiona后端,兼容性稳定,代码量也很小。以下是我常用的几段脚本,均以这份中亚五国数据为例。
5.1 读取shp并检查坐标系与字段
import geopandas as gpd # 读取shp;如果属性中文乱码,把encoding改成"gbk" gdf = gpd.read_file("central_asia.shp", encoding="utf-8") print(gdf.crs) # 查看坐标系,比如EPSG:4326 print(gdf.shape) # 输出(行数, 列数) print(gdf.columns) # 查看字段列表 print(gdf.geom_type) # 查看几何类型,应为polygon逻辑说明:read_file返回一个GeoDataFrame,一行是一个要素,geometry列存放面要素。如果乱码,把encoding改为gbk再读,这和QGIS加载时的编码选择是同一回事。crs属性打印出来可以看到数据实际的坐标参考;geom_type可以判断这份shp是面还是线,如果面数据里混入其它几何类型,后续裁剪可能报错,建议先执行gdf = gdf[gdf.geom_type == "Polygon"]过滤。
参数说明:encoding可选utf-8/gbk,与dbf属性表的内码一致即可。read_file支持shp、geojson、kml等,取决于本机gdal驱动是否齐全。
5.2 属性筛选与导出GeoJSON/KML/CSV
import geopandas as gpd gdf = gpd.read_file("central_asia.shp", encoding="utf-8") # 挑出哈萨克斯坦并导出GeoJSON kaz = gdf[gdf["NAME"] == "Kazakhstan"] kaz.to_file("kz.geojson", driver="GeoJSON") # 导出KML前,先统一到EPSG:4326,否则Google Earth会偏移 if gdf.crs is not None and gdf.crs.to_epsg() != 4326: gdf = gdf.to_crs(epsg=4326) gdf.to_file("central_asia.kml", driver="KML") # 导出为CSV/TXT,geometry列会保留WKT文本 gdf.to_csv("central_asia.csv", index=False)逻辑说明:to_file的driver参数决定输出格式。GeoJSON对属性字段要求少,KML会自动对属性名做长度裁剪,如果你的字段名带下划线或特殊字符,在KML里可能被截断,属于fiona的KML驱动限制,不影响几何使用。导出KML前强制转4326是个好习惯,能避开坐标轴顺序导致的东移。导CSV时直接调pandas的to_csv,geometry列默认以WKT字符串保存,后续用Excel打开时,这一列只是文本,不参与计算。
参数说明:如果只想导出五个国家中某几个,把gdf["NAME"] == "Kazakhstan"改成gdf["NAME"].isin(["Kazakhstan", "Uzbekistan"])即可。kml驱动需要gdal库带KML插件,如果报错“unable to open due to driver not recognized”,多半是gdal版本没装KML驱动,可用conda重装gdal。
5.3 把Excel里的坐标点转成shp并叠加五个国家
经常有非GIS同事发来一张Excel,里面两列longitude和latitude表示项目点位,要落到地图上。不打开QGIS也能完成:
import geopandas as gpd from shapely.geometry import Point import pandas as pd df = pd.read_excel("project_sites.xlsx") # 需要安装openpyxl df["geometry"] = df.apply(lambda r: Point(r["longitude"], r["latitude"]), axis=1) points = gpd.GeoDataFrame(df, geometry="geometry", crs="EPSG:4326") points.to_file("sites.shp", encoding="utf-8") # 统计每个国家境内有多少点:点与国界shp做空间连接 countries = gpd.read_file("central_asia.shp", encoding="utf-8") joined = gpd.sjoin(points, countries, how="left", predicate="within") print(joined.groupby("NAME").size())逻辑说明:先构造Point几何,再生成GeoDataFrame;sjoin是空间连接函数,predicate="within"判断point是否落在某个国家的面内。这里不用预判经纬度是否颠倒,只要Excel里是标准的longitude/latitude,Point(x,y)的x是经度、y是纬度即可。如果Excel里的经纬度是度分秒字符串(比如43°45′N),要先用pandas字符串操作换算成十进制度,否则数据会飞到海洋里,这个问题在Excel点转shp操作里最常见。
参数说明:how="left"表示保留所有点,即使某点不在任何国家境内,NAM会显示NaN;如果你只关心境内点,改成how="inner"即可。第2行的apply逐行遍历会把大量数据点压慢,超过10万行时建议换成gpd.points_from_xy(df["longitude"], df["latitude"]),速度能快一个量级。
6. 进阶技巧:按自定义研究区裁剪国界并重算面积
把五个国家的数据进一步做成研究区,是这类数据的典型进阶用法。比如要统计伊犁河—巴尔喀什湖流域内各国面积,就需要用流域边界去裁剪国界数据,然后按裁剪后的多边形重新计算面积。用geopandas的话,一个clip就能解决问题。
6.1 用GeoPandas做clip与面积统计
import geopandas as gpd countries = gpd.read_file("central_asia.shp", encoding="utf-8") basin = gpd.read_file("ili_basin.geojson", encoding="utf-8") # 统一坐标系后裁剪 countries = countries.to_crs(epsg=4326) basin = basin.to_crs(epsg=4326) clipped = gpd.clip(countries, basin) # 面积按UTM计算,避免用经纬度直接得平方度 clipped_utm = clipped.to_crs(epsg=32643) clipped_utm["area_km2"] = clipped_utm.geometry.area / 1e6 print(clipped_utm[["NAME", "area_km2"]])逻辑说明:gpd.clip在GeoPandas 0.7以上版本可用,是要素裁剪的简洁写法,前提是两个数据坐标参考一致。面积统计先转UTM再除以1e6得到平方千米,比直接用4326的$area稳定得多。如果研究区跨度大,也可以用Albers等积投影,方法与上面相同,只是epsg编码换成相应投影的编码就行。
这套操作里,坐标统一那一步最容易被忽略。好几次我在处理外部数据时,国界是4326,流域是从在线服务下载的3857,没统一就直接clip,结果返回空图层。从那以后,我养成了一个固定习惯:每次拿到外部shp,先检查CRS,再跑一遍几何有效性,最后才做叠加计算。这三步加起来不到两分钟,但能省一整天的返工时间。希望这套实战流程对你也有用。
本文还有配套的精品资源,点击获取