Shp文件实战:从世界底图到主要城市点位全流程解析
2026/9/8 4:24:21 网站建设 项目流程

简介:面向地理信息系统学习者、数据分析师与地图应用开发者,这是一套以Shapefile格式存储的世界地图及主要城市矢量数据集,可帮助用户直接获得规范化的全球国家边界和城市点位数据,用于地图制图、空间查询、区域分析以及各类地图应用开发。资源包共包含15个文件,大小仅1.06MB,除了核心的.shp几何文件外,还同步提供.dbf属性表、.shx空间索引、.prj投影定义等配套文件,数据组织清晰,能够被ArcGIS、QGIS等主流GIS软件和geopandas、sf等地理数据处理库直接识别与读取。目前已有1218人浏览学习。借助这套数据,使用者可快速完成世界范围的可视化底图搭建,也可按国家或城市字段进行筛选、计算距离、统计分布等空间操作,省去从公开网站逐一下载或手动裁剪底图的重复劳动;无论是课堂教学、论文配图,还是WebGIS原型验证和桌面端项目开发,都能以该数据集为起点进一步扩展。整套资源轻量完整,是地理信息相关从业者练习和项目实践中的实用基础数据。 做GIS的人,谁没为“世界地图配主要城市”这点事折腾过几回。项目汇报要一张世界底图,领导随口加一句“把主要城市标出来”,听起来就是加个点图层的小事,真动手才发现:要么国家边界精度差得没法看,要么城市点位散在几十个图层里不会挑,要么好不容易打开Shp,坐标系全乱,线不闭合、属性对不上。这篇文章我就把这套东西完整拆一遍,从Shp文件的基本常识、数据源选择,到下载、筛选、导出、转换,一直到各种高频问题排查,尽量用一次“世界地图+主要城市”的实战过程串起来。不管你是刚入行的实习生,还是被临时抓壮丁做底图的后端,照着走都能拿到一份能直接用的成果。

1. 基础认知:一份能用的Shp“世界地图+城市”到底由什么构成

很多新手第一次接触Shp文件,直接从网盘里拖一个“世界地图.shp”出来,双击打不开,就开始怀疑软件坏了。其实Shp压根不是一个文件,而是一组文件的组合。搞明白这个底层逻辑,后面很多问题都能迎刃而解。

1.1 Shp从不是“单个文件”,别漏了它的三个基础件

Shp格式本质上是ESRI公司在几十年前定义的一套矢量数据存储规范,它把一个完整的地理要素拆成了至少三个文件存:

  • .shp:真正的几何坐标信息,点、线、面都在这。
  • .shx:形状索引文件,相当于书的目录,让软件能快速定位某个要素。
  • .dbf:属性表,每一行对应一个要素,列就是各种字段(比如城市名、人口、所属国家)。

有些刚接触的朋友只拷贝了一个.shp到别的电脑,结果打开就是“无效文件”。实际上这三个文件必须放在同一个目录下、保持同名,缺一个都不行。除此之外还有一堆辅助文件,比如.prj(坐标系描述)、.cpg(字符编码)、.sbn/.sbx(空间索引)、.qix(四叉索引)等。.prj尤其重要,没有它,软件只能“猜”这个数据在地球的什么位置。

提示:从一个项目拷贝Shp到另一个项目,最好连同所有同名文件一起复制。保险做法是打包成zip,QGIS和ArcGIS都支持直接读zip内的shp,不会漏文件。

1.2 “主要城市”筛选口径:用属性字段,而不是肉眼挑点

“主要城市”这个词其实很模糊。有人觉得是各国首都,有人觉得是人口超过100万的大城市,还有人想要的是“国际知名度高”的城市。如果直接在地图上肉眼挑几个点,成果很难复现,换个人结果就不一样了。正确做法是让数据自己说话,用属性字段去筛。

Natural Earth提供的居民点数据集里,每个城市点都带了不少有用的字段:

  • NAME:城市名称
  • POP_MAX:最大人口估算值
  • ADM0CAP:是否为国家首都(1表示是,0表示否)
  • SOV0NAME:所属主权国家名称
  • TIMEZONE:时区

实际项目里我常用的筛选逻辑是:"POP_MAX" >= 1000000 OR "ADM0CAP" = 1。这样既能拿到全球所有百万人口以上的大城市,又不会漏掉像华盛顿、堪培拉这种人口不算顶级但行政地位重要的首都。这种基于字段的筛选,别人拿到你的成果一看就懂,自己也方便后续调整。

2. 数据获取:零成本搞定全球底图与城市点位

数据源是整个任务的基石。别一上来就百度“世界地图shp下载”,然后点进某个下载站,下下来一解压,要么图层乱得没法用,要么符号化之后丑到不想多看一眼。我在实际项目里,全球尺度的底图和城市点位,几乎都是从一个数据源里解决——Natural Earth。

2.1 首选数据源:Natural Earth

Natural Earth是全球最常用的公共领域地图数据集,它的优势很直接:

  • 完全免费,不用注册,没有使用限制,做项目出图都能用。
  • 提供了 1:10m、1:50m、1:110m 三种比例尺。110m的适合做小比例尺全球总览,文件小、加载快;10m的能放大到省级城市尺度,细节丰富。
  • 分类清晰,文化类(Cultural)里有国家面、居民点、道路、铁路,物理类(Physical)里有海岸线、河流、湖泊、地形等。

以“世界地图+主要城市”这个需求为例,只需要下载两个数据包:Cultural里的Admin 0 – Countries(国家面)和Populated Places(居民点)。前者当底图,后者提取城市点。整套流程下来,数据质量统一,符号化也不费劲。

2.2 城市边界、路网和补充数据的获取思路

如果项目还需要城市边界或路网,那就得换数据源了。城市边界的常见选择是GADM,它提供全球各级行政区划多边形,从国家到区县都有,字段里带有行政区划代码,用来做城市级筛选非常方便。路网的话,OpenStreetMap是绕不开的,它分道路等级、有类型属性,能导出整个大区的道路网,也可以按城市提取。

国内城市尺度的路网,OpenStreetMap的覆盖度和属性质量通常够用。但如果要那种带车道数、限速信息的高精度路网,就得找专业的图商或行业数据集了。这个看具体项目需求来定,不是“世界地图+主要城市”这个任务的必需项。

注意:不管从哪下载数据,第一时间记录数据来源、版本、下载日期。我以前吃过亏,用了某份路网数据做分析,后来发现原始数据已经更新过,版本对不上,结果全部重来。现在所有原始数据我都单独放一个目录,随手放一个说明文件,写清楚来源和时间。

2.3 下载后第一件事:确认坐标系

坐标系这个概念,新手很容易忽略,但它几乎是所有“坐标对不上”问题的根源。全球底图数据一般默认使用WGS 84经纬度坐标系,对应的EPSG编码是4326。也就是说,拿到Natural Earth的数据,不用做任何投影转换,直接叠加Global底图、在线瓦片地图,位置就是准的。

但如果后续要做距离量算、面积统计,或者要把数据切成网格、做缓冲区分析,就必须转换到投影坐标系。具体选哪个投影,取决于项目所在区域——全球范围可以用Web Mercator(EPSG:3857)或等距圆柱投影,区域范围建议选当地的高斯-克吕格投影。我的习惯是:

  1. 原始数据永远保留一份,不动坐标系。
  2. 做分析时复制一份,再转换到目标坐标系。
  3. 输出成果时根据下游需求再导出一份对应坐标系的副本。

这套“三副本”流程虽然啰嗦,但能避免大量返工。

3. 完整实操:从原始数据到可发布的Shp成果

理论说完了,下面进入实操。我用QGIS来做整个流程,因为它跨平台、免费,而且处理Shp这种矢量数据非常顺手。如果你用的是ArcGIS,思路完全一样,工具名称略有差异。

3.1 下载并用QGIS打开Natural Earth数据

QGIS打开Shp文件有两种常见方式。第一种是直接拖拽:把下载好的zip文件整个拖进QGIS窗口,软件会自动识别里面的Shp并加载。第二种是通过菜单“图层-添加图层-添加矢量图层”,选择文件后,文件类型过滤器选择“ESRI Shapefile”。加载之后,你会看到图层列表里出现了两个图层:一个多边形,一个点。

如果下载的是1:110m数据,可以看到国家面非常简洁,边界线很细,适合做小比例尺的底图。想要城市点,找到居民点图层,先随便缩放看看点位的分布密度。这里有个小提醒:如果图层加载出来只能看到黑乎乎一片,通常是符号样式没设置透明度和填充,把多边形图层换成浅色填充,深色细描边,底图观感立刻就不一样了。

3.2 提取主要城市并导出独立Shp

现在要把“所有居民点”筛成“主要城市”。在QGIS中,我一般用“处理工具箱”里的“按表达式提取要素”,打开的对话框里可以写表达式:

"POP_MAX" >= 1000000 OR "ADM0CAP" = 1

执行之后会生成一个新的点图层,里面就是经过筛选后的城市点。如果城市太多导致注记重叠,可以再加一个条件限制数量,比如按POP_MAX排序后取前100个。QGIS里可以用“按属性排序”工具,按人口字段降序排列,再“按表达式提取要素”限制OBJECTID范围,或者直接把排好序的图层导出后手动保留需要的数量。

筛选完成后,右键图层选择“导出-保存要素为”,格式选择“ESRI Shapefile”,文件名称建议写成world_major_cities.shp,坐标系保持WGS 84,设置好保存路径,点确定。这样,我们自己的“主要城市”Shp就正式生成了。

3.3 叠加行政区与路网,做一张可用的底图

有了国家面,有了城市点,基本底图就算齐了。如果需要路网,把之前提到的OSM路网数据导进来,调整线宽、透明度,让等级高的路更突出。这里有一个实用技巧:把国家面图层放在最底层,路网放中间,城市点放最上层,标注只给城市点打开。全球地图的城市标注很容易挤成一团,所以我通常只给“首都”字段为1的城市打开标注,文字大小设为8号字,背景颜色设半透明白色,这样既清晰又不影响底图。

导出的成果不一定非要Shp格式,如果下游要的是GeoJSON、GeoPackage或者KML,在导出的时候直接换格式就行。Shp是通用交换格式,GeoPackage则更适合作为中间存储格式,一个文件包含多图层、还能存样式,我现在习惯用GeoPackage做工作文件,需要交付给别人的时候再导出Shp。

4. 高频需求实战:格式转换与数据清理

做完了底图,后面往往跟着一堆格式转换的需求。这里把论坛和群里最高频的几个问题集中整理一下,直接给方案。

4.1 Shp转Txt:给程序和三维引擎的坐标文本

“Shp转Txt”这个需求,大多出现在程序对接和三维可视化场景。比如Unity、UE项目加载坐标点位,或者数据中台只需要城市点的经纬度列表。这时候所谓“Txt”,其实就是带分隔符的文本文件,每行一个要素,列是经纬度和属性字段。

QGIS里操作很简单:右键图层,导出-保存要素为,格式选择“Delimited Text File”(分隔文本),可以自定义字段分隔符,常见的有逗号、制表符、分号。导出的时候注意编码选择UTF-8,否则中文字段名会产生乱码。另外,如果导出的是点图层,QGIS会自动带上X和Y坐标字段;如果是面图层,想导出边界坐标,建议用程序脚本处理,把面要素的每个顶点坐标循环写入Txt,或者用PostGIS的ST_AsText()输出WKT格式再落地成文本。

4.2 Shp转Kml:批量操作与坐标设置

KML是Google Earth和其他很多地图客户端都支持的格式。QGIS导出KML时,右键图层选择“另存为”,格式选“Keyhole Markup Line层 [KML]”即可。需要说明的是,KML规范要求坐标系统必须是WGS 84经纬度,如果你的Shp是投影坐标系,QGIS导出时勾选“将坐标转换为WGS 84”即可。

批量转多个Shp算是常见痛点。QGIS处理工具箱里的“转换格式”提供了批量模式:右键工具选择“作为批处理过程执行”,一次把多个文件添加进来,设置输出路径,一键搞定。如果要用脚本,循环调用ogr2ogr是最轻量的方案,在命令行里写一个for循环就好,不依赖图形界面。

4.3 Shp转3DTiles与白模加载

“Shp转3DTiles”和“图新地球加载城市白模Shp”这两条热词,其实是同一个问题的两边。所谓“白模”,一般是指没有纹理贴图的建筑模型——建筑轮廓是面,高度字段被拉伸成立方体。Shp里的建筑面加上一个高度字段,比如层数FLOORS,手动或按楼层数估算高度后,再用CesiumLab这类工具设置“拉伸高度”,就能把Shp批量转成带高度的三维模型,再导出3DTiles格式。

用图新地球加载这种Shp白模,本质上是软件读取了Shp里的面要素和高度字段,自动做了拉伸显示。和CesiumLab转3DTiles的原理一致,区别只是实时渲染还是预烘焙。所以遇到这类需求,核心还是保证Shp的属性表里有一个可信的“高度”字段,否则拉伸出来的白模高度全是0,加载起来就是一片贴地的平面。

4.4 FME的DWG转Shp思路

FME Workbench里,DWG转Shp的需求,特别强调“带属性”三个字。CAD文件里的几何本身不带业务属性,但它的图层名、颜色、线宽、扩展字典数据都是潜在的属性来源。FME处理这类转换的核心思路是:读模块用DWG格式器,把CAD实体的图层、颜色等读取出来;转换中间用AttributeCreator把图层名映射成Shp的字段;写模块里预先定义好属性结构。

我之前处理过一个地下管线项目,DWG里的管线用不同颜色区分管径,楼层地面用图层名区分功能。FME里写了几个字符串条件判断,把颜色号转成管径数字,把图层名转成房间功能类型,输出到Shp的属性表里,下游做GIS分析就顺了。如果你第一次用FME处理DWG转Shp,建议先打开“数据检查器”查看DWG的要素类和属性,搞清楚属性存在哪个字段里,再动手搭流程,能省不少调试时间。

5. 踩坑排查:Shp常见问题与解决技巧

最后这部分,集中回答一批论坛里翻来覆去被问的问题。我把典型的几个场景列出来,直接给操作路径。

5.1 图层打开缺属性或位置漂移

Shp打开后发现要素全在一个角落,或者跟底图重叠不上,最常见的原因是坐标系信息丢失或错误。如果原始数据没有.prj文件,QGIS会弹窗让你选择坐标系,这时候随便选一个,位置肯定对不上。正确的处理方式:

  • 如果数据本身是WGS 84经纬度,但缺.prj,在图层属性里手动设置坐标系为EPSG:4326,然后导出时选择“覆盖数据集CRS”写回。
  • 如果数据原来是投影坐标,被误设置成了经纬度,位置会偏移得很离谱,这时候需要知道它原来的坐标系,重新指定后再用“重投影图层”转换到目标坐标系。

还有种情况是有.prj但坐标值本身已经是经纬度,却写成了投影坐标系,这时候不能简单重新指定,要根据数据范围判断原始坐标系,再做变换。

5.2 属性表中文乱码

Shp的.dbf文件有自己的一套字符编码,老版本常用GBK或ANSI,新软件默认读UTF-8,结果就是中文属性全变成“锟斤拷”。QGIS处理起来相对简单:加载Shp时,“图层-添加图层”对话框中有一个“编码”选项,选GBK或GB18030,就能正确显示中文。ArcGIS里则是在ArcCatalog中右击Shp,选择“属性-常规”,修改字符编码。更彻底的办法是把所有属性统一成UTF-8编码重新导出一份,避免持续踩坑。

5.3 “让Shp里的线消失”到底怎么操作

“如何让一个Shp里面的线取消掉”,这个问题在不同场景下有完全不同的操作。如果你是不想看到线要素,只是想视觉上隐藏,那直接改图层符号系统,设置线宽为0或透明度100%就解决了,数据本身不受影响。如果你想彻底删除线要素,进入属性表,用条件筛选选中所有线要素,然后切换编辑模式删除,或者反选后在导出时排除,生成一个不含线的新图层。

再补充一种情况:如果你遇到的是“线断成很多段想合并”,那就不是删除操作,而是用“融合”(Dissolve)按某个字段合并,或者用“消除线段”工具把短小的线清理掉。分清“隐藏”、“删除”、“合并”这三个需求,才不会把数据越改越乱。

5.4 渔网分割Shp:一次标准操作

“渔网分割Shp”在很多行业叫“网格化切分”,常用于把一个大范围数据切分成规则小格子,再分区域做统计或出图。ArcGIS里有现成的“创建渔网”(Create Fishnet)工具,QGIS里对应“矢量-研究工具-矢量网格”。操作时注意两点:

  • 网格范围设置成研究范围Shp的包络范围,或者直接选择“复制研究范围Shp的坐标”。
  • 网格的大小根据实际需求设置。比如全国路网数据要分省切分,网格范围设置成路网整体范围,行列数按需要的网格密度计算。

网格生成后,用“裁剪”(Clip)工具,用网格做裁剪要素,路网做被裁剪图层,输出就是切分后的路网Shp,每个网格一个文件。这里有个贴心做法:把裁剪输出的路径用网格编号字段动态命名,比如grid_01.shpgrid_02.shp,后续按编号拼接回去也很方便。

最后再分享一点个人的实操体会

做了这么多年地理数据,最大的感触是:别迷信“完美数据源”,关键是建立一套自己的数据处理流程。每次拿数据,先在脑子里过一遍:这份数据坐标系是什么,字段含义是什么,精度能不能满足项目要求,给别人用还是自己用。把这些想清楚,操作层面的事其实都是水磨工夫。还有一个习惯我保留到现在:所有原始下载包单独归档,文件名前面加上日期和来源,处理后的工作文件用GeoPackage统一存,最终交付再导出对应格式。这套习惯前期看着繁琐,遇到“换个人做就要返工”的项目时,你会发现它能帮你省下大量时间。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询