简介:这份中亚五国矢量数据集面向 GIS 制图、区域规划与地理教学等场景,提供哈萨克斯坦、乌兹别克斯坦、吉尔吉斯斯坦、塔吉克斯坦和土库曼斯坦五国的精确边界与行政要素。压缩包共 8 个文件,以 shp 主文件为核心,配套 shx 空间索引、dbf 属性表、prj 坐标系统及 cpg/sbn/sbx 等辅助文件,便于在 ArcGIS、QGIS 中直接读取和编辑。整体包体仅 545KB,轻量易部署,适合快速开展地图可视化、空间查询与属性关联分析。目前已有 186 人学习下载,资源内包含完整的 Shapefile 文件组,并附有 shp.xml 元数据描述,可帮助理解各字段含义与数据更新信息。利用这份数据集可制作专题地图、进行土地利用或交通网络分析,也能作为矢量数据格式教学的典型样例,提升对 GIS 数据结构的直观认识。
1. 中亚五国矢量图:一份shp数据能做什么,为什么先跑ogrinfo
做跨境能源管道选线、中亚棉花长势分析、丝绸之路经济带物流节点规划,第一块硬骨头都是同一件事:找到一份能用的中亚五国矢量图——哈萨克斯坦、吉尔吉斯斯坦、塔吉克斯坦、乌兹别克斯坦、土库曼斯坦的国界shp。数据并不难找,难的是“能用”。很多人把shp拖进ArcGIS,看到五个国境轮廓就以为完事,结果量面积差一倍、转KML地名全乱、叠加影像偏了几百米。这些翻车十有八九出在坐标系、属性编码和边界拓扑上。这篇文章就按一条我能复现的流程讲:先体检、再投影、清洗属性、处理共享边界、导出你需要的格式,最后列出我踩过的坑。适合刚拿到shp不知道从哪下手的从业者,也适合给团队搭数据生产规范的负责人。
2. 先做三分钟体检:shp数据包的组成与坐标系判断
拿到任何shp,第一反应不是打开GIS,而是打开命令行。因为shp不是单文件,坐标系又经常藏在.prj里,用ogrinfo三行命令能少走两小时弯路。
2.1 shp不是“一个文件”:三件套与可选扩展名
一个完整的Shapefile由三个基础文件构成:.shp存储几何坐标,.shx是几何索引,.dbf存储属性数据。三者同名同路径缺一不可。常见传输中只发了.shp,导致对方打开只有几何没有属性表,甚至图层加载失败。还有可选的.prj写投影信息,.cpg写字符编码,.sbn/.sbx是空间索引,.xml是元数据。拷数据时建议把整个文件夹一起打包,或者转成GeoPackage单文件交付。
| 扩展名 | 作用 | 缺失后果 |
|---|---|---|
| .shp | 几何坐标 | 没有数据主体 |
| .shx | 几何索引 | 无法读取要素 |
| .dbf | 属性表 | 属性丢失 |
| .prj | 投影信息 | 坐标系被误判 |
| .cpg | 字符编码 | 中文乱码 |
这张表是给团队做数据交接用的。我见过太多先把原始数据删掉、只留一个.shp的“瘦身”操作,三个月后没人知道它是什么坐标系,只能重新下载。另外要记得,shp的字段名长度限制在10个字符,这个限制源自dbf的dBASE标准。转换时如果字段名超过10字符,会被截断,重名时还会变成重复名。这一点在第二节属性清洗时还会再碰到。
2.2 三条必跑命令:ogrinfo 的 -so 与 -al 用法
检查shp最直接的工具是GDAL全家桶里的ogrinfo。在终端输入:
ogrinfo -so -al 中亚五国.shp输出会包含图层名、几何类型(Polygon或MultiPolygon)、要素数量(Feature Count: 5)、图层范围(Extent)和坐标系统(PROJCS或GEOGCS)。如果显示GEOGCS["WGS 84"],说明是经纬度坐标;如果显示PROJCS["Albers..."],说明已经是投影坐标。
再跑一条不带-so的命令,能看到每条要素的完整属性:
ogrinfo -al 中亚五国.shp这时可以观察属性字段名是ASCII还是西里尔字母,以及每个国家的名称字段内容。如果属性值有汉字但终端显示乱码,说明.dbf编码不是UTF-8,后面需要处理。
注意:ogrinfo是命令行工具,不在图形界面里。Windows用户可以在OSGeo4W Shell里运行,或者安装QGIS后使用自带的OSGeo4W Shell。Linux用户一般需要安装gdal-bin包。如果公司不让装命令行工具,用QGIS的图层属性面板也能看到同样信息,但批量处理时命令行的优势是不可替代的。
这里多写一句关于“gis怎么新建shp文件”:如果你的数据源是纸质地图或照片,想自己描一个五国边界,QGIS里图层菜单-创建图层-新建Shapefile,选择Polygon类型并指定CRS为WGS84。新建后先另存一个备份,再进编辑模式手动描摹。但我们优先推荐从公开数据源获取,手工数字化中亚五个国家边界成本很高,而且容易出拓扑错误。
2.3 坐标系分水岭:经纬度还是投影,决定面积量算对不对
中亚五国的范围大致在东经46~87度、北纬37~55度。如果是经纬度的WGS84坐标系,图层范围显示为X:46到87,Y:37到55,单位是度。这个状态下可以做视觉叠加,但不能算面积、不能算距离,因为一度的长度在赤道是111km,在55°N缩短到约64km,直接量结果没有意义。
这就是“为什么五国面积量算经常翻车”的第一根导火索。正确做法是用等积投影。对整个中亚地区,我一般用双标准纬线Albers等积圆锥:
ogr2ogr -t_srs "+proj=aea +lat_1=40 +lat_2=50 +lat_0=0 +lon_0=65 +x_0=0 +y_0=0 +ellps=WGS84 +units=m +no_defs" 中亚五国_Albers.shp 中亚五国.shp这条命令把“中亚五国.shp”重新投影成Albers等积坐标,输出文件坐标单位是米,标准纬线定在40和50度,中央经线取65度。参数里lat_1和lat_2是标准纬线,决定整个区域的变形分布;lon_0=65在中亚五国的经度中轴附近,y_0/x_0偏移量先置0。这是常见的区域级统计投影。
如果数据源本身带.prj,ogrinfo能读出来;如果.prj缺失,可用范围判断:坐标值在几十的说明不是经纬度就是米制。用ogrinfo -so看Extent最靠谱。换到国内数据也一样,处理塔里木河流域矢量shp、淮河shp、南盘江流域边界shp时,先跑这条命令,再决定是否需要投影,套路完全相同。
投影转换完成后,验证方式是把输出重新读一遍:
ogrinfo -so -al 中亚五国_Albers.shp此时Extent的坐标数量级应该从几十变成几百万。如果仍是几十,说明命令里的投影字符串没有生效,检查终端是否把加号批处理掉——Windows下部分终端会把+号吞掉,需要给整个投影参数加单引号。这一步看起来小,但每次都有人栽在这里。
另外,如果最终只需要在Google Earth里看,可以不投影,保留WGS84即可。但一旦要做面积统计,必须投影。两者最好保存成两个文件:一份原始经纬度做存档,一份投影做分析,免得回头找不到原版。实际工作中我见过不止一个人拿到数据先在ArcGIS里打开,看到范围正常就去做专题图,直到要把shp合并到全国数据里才发现坐标对不上。所以在数据生产流程里,我会要求每个shp必须配一个说明文件,写明源数据、坐标系、精度、属性字段含义。这不是多此一举,因为shp自带的元数据经常被删,三个月后连自己都会怀疑“这个文件到底是哪个投影存下来的”。
3. 让五国边界成为可分析的地理要素:属性清洗与拓扑修复
下载好的shp通常带一堆冗长字段:NAME、NAME_ISO、NAME_RU、VARNAME等。如果不做处理,做专题图时图例全是英文/俄文,出图前还得临时改。更麻烦的是共享边界不闭合,导致面积重复或gap。这一章解决两件事:属性让人看懂、边界让软件认同。
3.1 属性俄文变中文:字段计算器与编码转换
常见的五国shp中,name_ru字段是西里尔字母,比如“Казахстан”。为了让团队里的非GIS同事直接看懂,我们新增一列中文名称。QGIS里打开属性表,进入字段计算器,添加字符串字段name_cn,长度20,然后输入:
case when "NAME" = 'Kazakhstan' then '哈萨克斯坦' when "NAME" = 'Kyrgyzstan' then '吉尔吉斯斯坦' when "NAME" = 'Tajikistan' then '塔吉克斯坦' when "NAME" = 'Uzbekistan' then '乌兹别克斯坦' when "NAME" = 'Turkmenistan' then '土库曼斯坦' else '未识别' end这个表达式的逻辑是:按英文名称精确匹配,给每个国家赋中文名。如果数据源里没有"NAME"字段,可能用"admin0"或"COUNTRY",以ogrinfo输出为准。字段计算器写好后,单击“更新现有字段”,选择name_cn。注意:Shapefile的dbf对中文支持不差,但字段名必须是ASCII,因此字段叫name_cn而不是中文名。
然后加ISO代码字段iso3,方便后续做数据连接。表达式类似,把中文替换成KAZ、KGZ、TJK、UZB、TKM。有了这两个字段,后续按国家拆分、做柱状图、关联统计年鉴都直接走属性了。
如果属性表本身是乱码,先从图层属性-数据源-编码改为UTF-8或GBK,能显示正常再执行字段计算。如果改编码还是乱,用下面命令重写dbf编码:
ogr2ogr -lco ENCODING=UTF-8 中亚五国_utf8.shp 中亚五国_原始.shp这个命令把原有shp重新输出一份,dbf编码强制为UTF-8。注意,改编码不会改变属性内容,只是让软件读对字节。
3.2 共享边界缝隙怎么补:拓扑检查器与v.clean
五国边界源出多家时,相邻两国的边界线往往不是完全重合的。放大到国界线,会看到一条肉眼可辨的白色缝隙,或者一个窄重叠带。做空间查询“相邻国家”没问题,但做union或dissolve时,缝隙会变成很小的多边形,重叠部分会被重复计算面积。
我的处理顺序是:先用QGIS的Topology Checker插件,规则选“must not have gaps”和“must not have overlaps”,容差设为0.001度(约100米,取决于原始数据精度)。跑完会列出所有错误位置。右键错误可以缩放到具体位置,手动用节点编辑吸附。
如果错误上百个,纯手动修不完。用GRASS的v.clean来自动清理:
v.clean input=中亚五国@图层 output=五国_clean tool=rmdupl,break,rmarea thresh=0.01这里tool参数含义是:rmdupl删除重复几何,break在几何自相交处打断,rmarea删除小于阈值的面积碎片。thresh=0.01对应最小面积,单位取决于图层CRS。如果图层还是经纬度,thresh单位是平方度,不好控制,建议先转投影再跑。
自动清理后要回归检查一遍,因为v.clean可能会把很小的岛屿或争议区域也删掉。中亚的咸海、里海边界里有一些碎面,阈设大了会把它们抹掉。所以我一般先把阈值设到0.001,跑完看面积变化,再逐步加大。
3.3 要素数不是5?国界、省界与争议区域的层级取舍
看到网上有人抱怨“省界线文件省1和省2的shp文件有什么区别”,其实这说的是同一张地图中不同行政层级的区分。国界shp也类似,有的数据集把五国国界做成5个要素,有的只有4个(把土库曼斯坦和乌兹别克斯坦之间的边界做成一条共线),有的则把里海、咸海也画成多边形,要素数瞬间变成7个甚至更多。
建议拿到数据后先执行一条分组统计命令,看每个国家是否有唯一的admin0代码:
ogr2ogr -where "ADM0_A3 IN ('KAZ','KGZ','TJK','UZB','TKM')" 五国_filter.shp 中亚_all.shp注意:字段名“ADM0_A3”是很多公开数据源的一个命名惯例,但你的数据未必叫这个。实际操作时先用ogrinfo看字段,再改。这条命令的意义是,把要素集里所有不属于五国的碎块、邻国部分、争议区域一次性筛掉,得到一个干净的五国面板数据。
如果你的数据包含州级边界(省1)和全国边界(省2),不要把两层混在一个shp里。等值线制图时用省界,但做面积统计时一定要用国界层,否则会造成重复。同理,有人会问“北京 shp怎么这么小”,就是因为只取了北京市范围而没带全国底图。数据处理原则是:不同精度、不同层级的矢量分开存,需要叠加再通过空间关系关联。
4. 转换到常用格式:KML、GeoJSON、3DTiles 与 CAD 互转
用户搜“arcgis shp转kml”怎么弄、“dwg转shp”怎么弄,本质上是数据交换问题。本章给出可直接复用的命令和必调参数,避免格式转换后几何或属性翻车。
4.1 dwg转shp与shp转kml:两条通行命令
DWG是CAD原生格式,shp是GIS主流格式。常见做法是在QGIS中加载DWG(需要安装CAD Tools插件),但命令行控制度更高。假设有一个“中亚规划.dwg”,里面有多层,其中一层是多边形:
ogr2ogr -f "ESRI Shapefile" 中亚_cad.shp 中亚规划.dwg转出来后用ogrinfo查看几何类型。CAD里的封闭多段线会被识别为Polygon,但文字、标注、块引用会变成Point或LineString,这是固有属性,不是bug。很多人在这一步发现面积字段丢失——因为CAD并没有属性表,所有扩展数据在EATTEDIT里,转shp时默认不读取。如果想要CAD属性进dbf,需要在CAD中用EXPORT导出时勾选“属性”,或者用FME。如果只是用DWG参考,这个转换够了。
shp转kml的命令更简单:
ogr2ogr -f KML -t_srs EPSG:4326 中亚五国.kml 中亚五国.shp注意:KML规范要求坐标系必须是WGS84经纬度,所以不管源shp是Albers还是Web Mercator,都要加-t_srs EPSG:4326。不加也能转,GDAL会附加一个transform,但若源坐标系缺失,目标KML会挂在一个错误的坐标系下,Google Earth可能把它甩到海里。参数里EPSG:4326是WGS84经纬度编码。
kml转shp也是同样逻辑,ogr2ogr -f "ESRI Shapefile" 五国.shp 五国.kml,但KML里的符号和样式不会进shp,点要素的图标信息会丢。
4.2 shp转3DTiles:先分清是“边界白模”还是“数据栅格”
“shp转3dtiles”这个需求出现得很频繁,但很多人把两个完全不同的场景混在一起。场景一:把五国边界加高做成三维柱状图,用Cesium展示。场景二:把一个带栅格属性(如土地利用分类)的shp做成三维场景的底图。后者根本不转3DTiles,而是把矢量栅格化后切片。
对于边界加高的场景,最快路径是shp→GeoJSON→Cesium加载,而不是转3DTiles。shp转GeoJSON:
ogr2ogr -f GeoJSON -t_srs EPSG:4326 中亚五国.geojson 中亚五国_Albers.shp在Cesium里用GeoJsonDataSource加载,给每个Feature设置一个高度值,例如用属性字段pop_density乘以一个拉伸系数,就能看到高低起伏的边界柱体。这样的方案不需要预处理缓存,刷新即可。
如果数据量大到一个GeoJSON加载不动,才需要转3DTiles。工具选“CesiumLab”或“cesiumium-tiles”都行,核心参数是几何简化和纹理尺寸。边界数据没有纹理,主要调“最大顶点数”和“简化比例”。3DTiles切割时建议把国界先转成WGS84,因为3DTiles内部使用WGS84坐标系。转前用mapshaper简化,能减少30%以上体积。
4.3 excel点转shp和渔网分割shp:批量操作的参数陷阱
先理清这两个操作。excel点转shp是把经纬度表格变成点图层,渔网分割shp是用格网把五国切成均匀的小块。前者用于把城市点位标到国界上,后者用于把人口、气候指标按格网统计。
Excel转shp在QGIS里最稳:导入CSV时选“定制分隔符”,X字段填经度,Y字段填纬度,几何类型选Point,CRS选WGS84。导入后发现点位置在范围外,十有八九是经纬度写反了。python环境里可以这样读取:
import pandas as pd import geopandas as gpd df = pd.read_csv("cities.csv") gdf = gpd.GeoDataFrame( df, geometry=gpd.points_from_xy(df.lon, df.lat), crs="EPSG:4326", ) gdf.to_file("cities.shp", encoding="utf-8")这里points_from_xy需要传入经度在前、纬度在后。如果你把列名起成x、y,很容易在习惯上把纬度当X,实际应该按“经度在前”传参。to_file默认输出Shapefile,如果报字段名截断,试试用GeoPackage。
渔网分割shp,用QGIS的Create Grid工具做网格层,然后Intersect。注意Create Grid的网格间距单位:如果图层CRS是WGS84,间距是度;想要1千米网格就去投影一层。生产时我一般先投影到Albers,再做10km网格,然后用:
ogr2ogr -t_srs EPSG:3857 -overwrite 五国_web.shp 五国_Albers.shp这种临时转换只是为了网格叠加,分析完再转回来。渔网分割的产物要素数巨大,不要用shp保存,存GeoPackage,否则很容易触发2GB限制。
5. 避坑指南:处理五国shp最常见的五个翻车现场
这一章全是我和同行在数据生产线上踩过的坑。每条都按现象-原因-解决来写,希望能帮你少交学费。
5.1 缺文件导致打不开:shapechk 的修复时机与限制
现象:双击五国.shp,ArcCatalog提示“找不到.shx”,或者QGIS里几何要素出现大洞。排查后是文件夹里只有.shp和.dbf,.shx丢了。
原因:传输过程中某些邮箱/网盘对.shx这种罕见后缀做了拦截或改名。另外,通过Git管理shp时,.shx被.gitignore误伤也常见。
解决:如果只是.shx缺失,用shapechk修复工具重建索引。shapechk是一个ESRI提供的命令行小工具,用法是:
shapechk 中亚五国.shp它会扫描.shp并重新生成.shx。如果.dbf也丢了,shapechk救不回来,只能重新找原始数据。所以前面强调每一份shp都要保留完整三件套备份。如果连原始数据源都没留下,可以尝试用ogrinfo硬读.shp,有时能算几何但属性为空,不能作为成品数据。
5.2 面积量算失真:投影坐标系没设造成的系统性错误
现象:用QGIS字段计算器给五国图层算面积,得到的数值只有预计的四分之一甚至更小;再一看,坐标单位是度。
原因:图层CRS是EPSG:4326,$area的返回单位是平方度,不是平方米。即使你手动把图层CRS改为Albers,如果源数据里的坐标仍然是经纬度,QGIS会临时重投影返回米制结果,但前提是没有“图层CRS覆盖”。很多人顺手把“图层CRS”改成了Albers但忘了投影实际几何,结果量出来还是半吊子。
解决:必须使用ogr2ogr做实际投影转换,生成一个新文件,而不是在图层属性里改CRS。投影后检查Extent数量级,然后再算面积。在QGIS中,投影后新增字段area_km2,表达式为$area / 1e6,这样得到平方千米。
5.3 中文属性乱码:KML和GeoJSON导出时的编码坑
现象:五国shp在QGIS中文正常,导出KML后用Google Earth打开是乱码,“哈萨克斯坦”变成“е“Х∞”或问号。
原因:KML内部是XML,默认UTF-8。如果源dbf编码是GBK,GDAL在转KML时没有正确读取.cpg,导致字符串按错误编码解释。另外,QGIS导出KML时如果图层本身带有非UTF-8属性,也会出现问题。
解决:最保险的是先统一编码。用上一章的命令把dbf转成UTF-8再导出。或者在QGIS中设置图层属性-数据源-编码为“UTF-8”,然后再另存为KML。导出GeoJSON也一样,GeoJSON规范要求UTF-8。建议所有shp入库前都转成UTF-8,省得后面每个环节都出乱码。
5.4 行政边界与卫星影像不套合:坐标系基准不一致
现象:把五国边界shp叠加到同区域高分影像上,边界与河流、道路错开约几百米,在阿拉木图这种山谷城市特别明显。
原因:影像产品一般用WGS84,但某些边界数据来自旧苏联测绘成果,基准面是Pulkovo 1942或Krassovsky椭球。WGS84和Pulkovo之间的平移向量在中亚地区大约有100~300米误差。凡是原始shp没有.prj或者.prj写着“GCS_Unknown”,就要高度怀疑基准面不准确。
解决:优先选择使用单一基准的数据源,例如Natural Earth、GADM。如果必须用旧基准数据,需要用大地测量控制点做七参数转换,或至少做平移配准。在没有控制点的情况下,一个临时办法:把边界层和影像层同时加载,比较一个明显地物的偏移量,然后用QGIS的“移动图层”功能整体平移,但不保证整体精度。这只是临时救场,正式成果必须用原厂坐标定义。
5.5 shp单文件超过2GB:大网格场景改用GeoPackage
现象:做渔网分割五国边界后,输出shp到一半报错“无法写入”,或者整个shapefile文件损坏。文件管理器里看到.shp大小约2.14GB。
原因:shapefile规范限制shp和dbf的体积均不能超过2GB,这在处理高精度网格分割时很容易触碰。不是电脑磁盘问题。
解决:输出到GeoPackage。QGIS中另存为GeoPackage,或者在ogr2ogr里指定:
ogr2ogr -f GPKG 五国_grid.gpkg 五国_grid.shpGeoPackage没有2GB硬限制,也支持空间索引,属性字段名长度上限也更大。如果你的下游系统必须要shp,那就按国家拆分,一个国一个文件;或者对边界做适度简化,移除不必要的顶点。拆分命令在下一章给。
顺便说一句,有些老库里有shp转txt的需求,本质上是用ogr2ogr输出CSV,但属性中的几何信息会丢失,通常不推荐用txt存几何。
6. 进阶用法:按国家批量拆分与自动检查
最后写一个可以直接抄的脚本,把多国的五国shp按国名拆成单独文件,并做一次自动校验。用GeoPandas最顺手:
import geopandas as gpd gdf = gpd.read_file("中亚五国_Albers.shp", encoding="utf-8") for name, group in gdf.groupby("name_cn"): group.to_file(f"{name}.shp", encoding="utf-8") print(name, len(group), group.total_bounds)这段代码按name_cn字段分组,每个国家写出一个单独shp。total_bounds输出该国的范围,用于快速判断是否有几何异常(比如范围突变到非洲)。注意,写入shp时字段名被截断到10字符,但name_cn不算长,问题不大。如果你的字段名像“average_income_2023”这种超过10字符,在GeoPandas写shp前需要先用rename改短。
验证拆分后的文件,再跑一次ogrinfo:
for f in 哈萨克斯坦.shp 吉尔吉斯斯坦.shp; do echo $f; ogrinfo -so -al $f | grep "Extent"; done这是我做完任何矢量数据都会跑的“后悔药”动作——检查Extent是否符合预期。X范围应在46~87,Y在37~55。如果X跑到三位数,说明投影信息丢失或投影字符串错误,要回头检查。
另一个值得养成的习惯是保留原始下载文件不动,所有清洗另存新文件。文件名加后缀:原始、_Albers、_utf8、_topo。这样即使后面某个环节出了问题,也能从上一版重新开始。我最早处理中亚五国数据时,因为直接在原始shp上改CRS,导致整个文件夹被污染,最后只能重新下载。从那以后,“只读原始,另存过程”成了我的铁律。希望这套从体检到最后拆分的流程能帮到你。
本文还有配套的精品资源,点击获取