☰
青岛市shp数据解压与转换全攻略:从shp/shx/json到GIS实战
2026/10/14 14:35:47 网站建设 项目流程

简介:这份资源是面向GIS初学者、地理信息专业学生及城市规划从业者的青岛市区域划分地理数据包,可用于地图制作、空间分析与规划决策等场景。压缩包共5个文件,约43KB,包含shp主数据文件(存储几何形状)、dbf属性表(记录行政区域名称等信息)、prj投影文件(定义空间参考系统)、shx索引文件(加速数据读取)以及json格式数据(便于网络传输与程序交互),各文件配套使用可完整描述青岛地理对象及其属性。目前已有689人学习下载。读者可借助ArcGIS、QGIS等软件直接打开处理,开展人口分布、交通网络、环境变化等叠加分析,也可结合json数据与Web应用交互,展示动态地图服务,是理解GIS多格式协作与空间数据组织方式的实用入门素材。

1. 青岛市 shp 数据、json 格式数据、shx 格式数据等.zip:拿到压缩包之后先别急着解压

你从某个渠道拿到一个名为「青岛市shp数据、json格式数据、shx格式数据等.zip」的压缩包,双击之后大概率会看到一堆同名不同后缀的文件:.shp、.shx、.dbf、.prj,可能还混着.json、.cpg。很多人第一反应是「shp 文件下载到手了,直接拖进 ArcGIS 打开就行」,结果要么提示缺少投影、要么属性表全是乱码、要么干脆打不开。问题不在数据本身,而在于 shp 从来不是单个文件,它是一组必须成套出现的文件集合,zip 只是把它们打包在一起。这篇笔记就围绕这个压缩包讲清楚三件事:shp/shx/json 各自是什么、怎么正确解压和校验、怎么在 ArcGIS Pro、QGIS 和代码里把它跑通,以及那些让人翻车的坑。适合刚接触 GIS 矢量数据、需要把青岛市行政边界或 POI 落到地图上的从业者。

2. 先搞懂 shp、shx、json 到底谁是谁:拆开压缩包看文件家族

2.1 shp 不是「一个文件」,而是一套必须成套的矢量格式

Shapefile 是 ESRI 在上世纪 90 年代定的一套格式,它的设计思路是「一个几何文件配一堆辅助文件」。你解压后看到的.shp只存几何形状(点、线、面),它自己单独存在时是残缺的。真正让一份数据能用的,是下面这套组合:

后缀作用缺失后果
.shp存储几何图形(坐标串)没有几何,什么都画不出来
.shx几何索引,记录每个要素在 shp 中的偏移部分软件能靠重建索引打开,但大文件会报错
.dbf属性表,存字段和记录打开后没有属性,只剩空壳图形
.prj投影坐标系定义(WKT 文本)坐标数值还在,但不知道是什么坐标系,叠加会错位
.cpg属性表字符编码(如 UTF-8、GBK)中文属性乱码

所以标题里单独点出「shx 格式数据」是有道理的——.shx缺失是 shp 打不开的高频原因之一。判断一份 shp 是否完整,最直接的办法是看同名文件是否齐全。青岛市这种市级行政边界数据,通常还会带.sbn、.sbx空间索引,有更好,没有也能用。

2.2 json 格式数据在 GIS 里通常指 GeoJSON,别和普通 json 搞混

压缩包里如果带.json,在 GIS 语境下大概率是 GeoJSON——一种用文本描述地理要素的格式,结构上就是标准 JSON,只是遵循了 GeoJSON 规范。它和 shp 的核心差别在于:GeoJSON 把几何和属性写在同一个文件里,天然自包含,不需要配套文件,坐标系默认是 WGS84(EPSG:4326)。这也是为什么热词里「json转shp网站」「shp转json」搜索量一直很高——两者互转是日常操作。

一个最小的 GeoJSON 长这样:

{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "name": "市南区", "code": "370202" }, "geometry": { "type": "Polygon", "coordinates": [[[120.38, 36.06], [120.40, 36.06], [120.40, 36.08], [120.38, 36.08], [120.38, 36.06]]] } } ] }

FeatureCollection是要素集合,features数组里每个Feature由properties(属性)和geometry(几何)组成。注意坐标顺序是「经度, 纬度」,和很多人直觉相反,写反了图形会跑到南极去。

2.3 为什么青岛市这类数据会同时给 shp 和 json 两种格式

这不是冗余,而是面向不同使用场景。shp 是桌面 GIS(ArcGIS、QGIS)和很多规划、国土系统的通用交换格式,字段类型严格、体积小;json/GeoJSON 是 Web 地图(Leaflet、Mapbox、ECharts)和前后端接口的常用格式,浏览器和 JavaScript 直接能读。同一份青岛市边界,做桌面制图用 shp,做网页可视化用 GeoJSON,各取所需。理解了这一点,你就知道解压后不该只留 shp 而把 json 删掉。

3. 解压与完整性校验:从 zip 到能打开的 shp 只差这几步

3.1 用命令行解压并检查文件是否成套

Windows 上很多人用「压缩为 zip」右键菜单,但遇到中文文件名或加密包容易出问题。稳妥做法是用命令行。Linux/macOS 下:

# 解压到指定目录,-O 指定编码,避免中文文件名乱码 unzip -O GBK "青岛市shp数据、json格式数据、shx格式数据等.zip" -d qingdao_data # 列出解压结果,确认 shp/shx/dbf/prj 是否同名成套 ls -l qingdao_data

Windows 的 PowerShell 里可以用:

Expand-Archive -Path "青岛市shp数据.zip" -DestinationPath "qingdao_data" -Force Get-ChildItem qingdao_data | Select-Object Name, Length

-O GBK是关键参数,很多国内数据包用 GBK 编码打包,不加这个参数解压出来的中文文件名会变成乱码。解压后重点看:同名.shp和.shx、.dbf是否都在,.prj是否存在。如果只有.shp没有.shx,先别删,后面有补救办法。

3.2 用 ogrinfo 快速体检,比打开 ArcGIS 快十倍

装好 GDAL 之后,ogrinfo是检查矢量数据最省事的工具,不用启动笨重的桌面软件:

# 查看数据概览:图层名、几何类型、要素数量、坐标系 ogrinfo -so -al qingdao_data/qingdao.shp # 只看坐标系 ogrinfo -so qingdao_data/qingdao.shp qingdao | grep -i "PROJCRS\|GEOGCRS\|EPSG"

-so表示只输出摘要不输出要素,-al表示所有图层。输出里重点看三行:Geometry(是 Polygon 还是 Point)、Feature Count(要素数量对不对)、Layer SRS(坐标系是什么)。如果Layer SRS显示unknown,说明.prj缺失或损坏,需要手动指定坐标系,青岛市数据一般是 CGCS2000 或 WGS84。

3.3 缺失 shx 时的重建办法

如果压缩包里真的只有.shp没有.shx,别慌,QGIS 和 GDAL 都能重建索引。用 QGIS 打开时它会提示「缺少 shx,是否重建」,点确认即可。命令行下可以用:

# 用 ogr2ogr 重新导出一次,会自动生成配套的 shx ogr2ogr -f "ESRI Shapefile" qingdao_fixed.shp qingdao_data/qingdao.shp

ogr2ogr读原文件、写新文件,写的过程中会补齐.shx、.dbf、.prj。这是处理残缺 shp 最通用的手段,比手动找文件靠谱。注意如果原.dbf也缺失,导出的就只有几何没有属性,需要另找属性数据。

4. 在 ArcGIS Pro、QGIS 和 Python 里把青岛市数据跑起来

4.1 ArcGIS Pro 里加载 shp 并处理坐标系

ArcGIS Pro 加载 shp 很直接:Catalog 面板里定位到解压目录,把.shp拖进地图即可。但有两个高频问题。第一,如果.prj缺失,Pro 会按地图当前坐标系强行显示,图形位置可能偏到几千公里外。解决办法是右键图层 → Properties → Source,看坐标系是否为 Unknown,然后用 Define Projection 工具手动指定。第二,热词里「arcgispro shp合并」很常见——青岛市下辖多个区市,如果数据是按区拆分的多个 shp,用 Merge 工具合并:

Geoprocessing → Merge Input Datasets: 选中所有区市 shp Output Dataset: qingdao_merged.shp Field Map: 确认各区字段能对齐,字段名不一致的会丢属性

Merge 之前务必检查各文件的字段结构是否一致,字段名不同会导致合并后属性错位,这是血泪经验。

4.2 QGIS 里做投影转换和格式导出

QGIS 免费且对坐标系处理更宽容。加载后如果发现图形位置不对,右键图层 → Export → Save Features As,在 CRS 下拉里选目标坐标系,比如从 CGCS2000 转到 WGS84:

Layer → Save As Format: ESRI Shapefile 或 GeoJSON CRS: EPSG:4326 - WGS 84 File name: qingdao_wgs84.geojson

导出成 GeoJSON 后,就能直接喂给前端地图库。QGIS 的「另存为」本质上就是一次重投影加格式转换,比在 ArcGIS 里找 Project 工具更顺手。注意导出 GeoJSON 时如果属性里有中文,编码选 UTF-8,否则网页端会乱码。

4.3 用 Python 读取 shp 和 json 并做互转

代码里处理矢量数据,主流是geopandas,底层依赖 GDAL。读取和转换:

import geopandas as gpd # 读取 shp,注意指定编码,中文属性常用 GBK 或 UTF-8 gdf = gpd.read_file("qingdao_data/qingdao.shp", encoding="utf-8") # 查看坐标系和字段 print(gdf.crs) print(gdf.columns.tolist()) print(gdf.head()) # 如果坐标系缺失,手动指定(青岛市常用 CGCS2000,EPSG:4490) if gdf.crs is None: gdf = gdf.set_crs(epsg=4490) # 转成 WGS84 并导出 GeoJSON gdf_wgs84 = gdf.to_crs(epsg=4326) gdf_wgs84.to_file("qingdao.geojson", driver="GeoJSON", encoding="utf-8")

read_file的encoding参数决定属性表中文是否乱码,读出来乱码就换gbk再试。set_crs是「声明」坐标系,to_crs是「转换」坐标系,两者别搞反——对没有.prj的数据用to_crs会直接报错,必须先set_crs声明再转。导出 GeoJSON 时driver="GeoJSON"固定写法,encoding="utf-8"保证网页端正常显示。

4.4 用 json 转 shp 的两种路径

热词里「json转shp网站」搜索很多,但线上转换工具对数据量和隐私都不友好,本地做更稳。如果 json 是 GeoJSON,直接用 geopandas:

import geopandas as gpd # GeoJSON 转 shp gdf = gpd.read_file("qingdao.geojson") gdf.to_file("qingdao_from_json.shp", driver="ESRI Shapefile", encoding="utf-8")

如果 json 不是标准 GeoJSON,而是自定义结构(比如坐标存在lng/lat字段里),需要先构造几何:

import geopandas as gpd import pandas as pd from shapely.geometry import Point df = pd.read_json("points.json") # 假设字段是 lng 和 lat geometry = [Point(xy) for xy in zip(df["lng"], df["lat"])] gdf = gpd.GeoDataFrame(df, geometry=geometry, crs="EPSG:4326") gdf.to_file("points.shp", driver="ESRI Shapefile", encoding="utf-8")

关键点是crs="EPSG:4326"必须显式指定,否则导出的 shp 没有.prj,别人拿到又得猜坐标系。这一步是很多人转完发现「位置对不上」的根源。

5. 避坑与排查:青岛市 shp 数据最常见的 5 个翻车现场

5.1 打开后图形跑到国外或空白

现象:把 shp 拖进 ArcGIS 或 QGIS,地图上什么都看不到,或者图形出现在非洲西海岸附近。原因:坐标系缺失或错误,软件按默认坐标系解释坐标数值。解决:先用ogrinfo -so看Layer SRS,如果是 unknown,用 Define Projection 指定为 CGCS2000(EPSG:4490)或 WGS84(EPSG:4326),再重新加载。青岛市经度约 120°、纬度约 36°,如果图形出现在 0° 附近,基本就是坐标系没定义。

5.2 属性表中文全是问号或方块

现象:打开属性表,name字段显示成????或乱码。原因:.dbf的编码和软件读取时用的编码不一致,国内数据常见 GBK 被当成 UTF-8 读。解决:在 QGIS 里右键图层 → Properties → Source → Data Source Encoding,改成 GBK 或 UTF-8 试;代码里read_file加encoding="gbk"。如果.cpg文件存在,打开看里面写的是什么编码,以它为准。

5.3 只有 shp 没有 shx,软件报「无法打开」

现象:ArcGIS 提示「Could not open the specified file」或「缺少索引文件」。原因:.shx缺失,软件无法定位几何记录。解决:用 QGIS 打开触发自动重建,或用ogr2ogr重新导出一次生成配套文件。如果连.dbf都没有,导出的只有几何,属性需要另找来源。

5.4 多个区市 shp 合并后属性错位

现象:Merge 之后,某些要素的name变成了别的区的名字。原因:各 shp 字段顺序或字段名不一致,Merge 按位置匹配字段。解决:合并前用ogrinfo -so逐个检查字段列表,字段名统一后再合并;或者在 geopandas 里用pd.concat手动对齐列名:

import geopandas as gpd import pandas as pd files = ["shinan.shp", "shibei.shp", "laoshan.shp"] gdfs = [gpd.read_file(f, encoding="utf-8") for f in files] merged = gpd.GeoDataFrame(pd.concat(gdfs, ignore_index=True), crs=gdfs[0].crs) merged.to_file("qingdao_merged.shp", driver="ESRI Shapefile", encoding="utf-8")

pd.concat按列名对齐,比 Merge 工具更可控,字段名不一致时会自动补 NaN,方便你发现哪份数据缺字段。

5.5 从 zip 直接读数据导致失败

现象:不解压,直接用代码读xxx.zip里的 shp,报错或读出来是空。原因:GDAL 虽然支持/vsizip/虚拟路径读 zip,但要求 zip 内部文件成套且路径正确,中文文件名还容易出问题。解决:老老实实先解压到本地目录再读。虚拟路径写法是/vsizip/路径/包.zip/内部文件名.shp,但兼容性不稳定,生产环境不建议用。

6. 进阶:把青岛市数据做成可复用的自动化处理脚本

前面都是单次操作,实际项目里你往往需要反复处理同类数据。我一般会写一个脚本,把「解压 → 校验 → 重投影 → 导出 GeoJSON」串起来,下次拿到新的城市数据直接改路径就能跑:

import os import zipfile import geopandas as gpd def process_city_zip(zip_path, out_dir, target_epsg=4326, src_epsg=4490): # 1. 解压 os.makedirs(out_dir, exist_ok=True) with zipfile.ZipFile(zip_path, "r") as z: z.extractall(out_dir) # 2. 找到所有 shp shp_files = [f for f in os.listdir(out_dir) if f.endswith(".shp")] if not shp_files: raise FileNotFoundError("压缩包里没有 shp 文件") results = [] for shp in shp_files: path = os.path.join(out_dir, shp) gdf = gpd.read_file(path, encoding="utf-8") # 3. 坐标系兜底:没有 prj 就按源坐标系声明 if gdf.crs is None: gdf = gdf.set_crs(epsg=src_epsg) # 4. 统一转到目标坐标系 gdf = gdf.to_crs(epsg=target_epsg) # 5. 导出 GeoJSON out_name = os.path.splitext(shp)[0] + ".geojson" gdf.to_file(os.path.join(out_dir, out_name), driver="GeoJSON", encoding="utf-8") results.append((shp, len(gdf), gdf.crs)) return results if __name__ == "__main__": info = process_city_zip("青岛市shp数据.zip", "output") for name, count, crs in info: print(f"{name}: {count} 个要素, 坐标系 {crs}")

这个脚本的价值在于把「坐标系兜底」和「统一重投影」固化成流程。src_epsg=4490是青岛市数据的常见源坐标系,target_epsg=4326是 Web 地图通用坐标系,两个参数按实际数据改。set_crs只在gdf.crs is None时触发,避免对已有正确坐标系的数据做多余声明。跑完打印每个文件的要素数和坐标系,一眼就能看出哪份数据有问题。

验证脚本是否跑对,最直接的办法是把导出的 GeoJSON 拖进 geojson.io 或 QGIS,看图形是否落在青岛位置、属性是否完整。我自己的习惯是每次处理完新数据,先随机抽一个区,用ogrinfo看要素数,再和官方公布的行政区划数量对一下,对不上就说明数据有缺失或重复。这个习惯帮我拦下过好几次「看起来正常、实际少了一半要素」的坑。

处理这类打包数据,最省心的做法永远是先解压、再校验、后转换,别指望一步到位。希望帮到你。

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

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

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

立即咨询