简介:这份全国矢量地图shp格式资源面向GIS从业者、城市规划人员及地理信息相关专业师生,提供一套完整的中国地理空间框架数据,可用于行政区划制图、空间分析与专题地图制作。压缩包共116个文件,约35.76MB,以30个shp主体文件为核心,配套30个dbf属性表、30个shx索引文件,并含prj投影定义、sbn与sbx空间索引及xml元数据,覆盖河流、行政界线、区域面与点位等多类地理要素,数据经整理验证,可直接加载使用。目前已有2443人学习下载,适合需要快速获取基础底图、开展叠加分析与出图的用户。借助ArcGIS、QGIS等软件,读者可完成数据浏览、编辑、查询与空间关系分析,并将成果导出为图像或发布至Web GIS,为城市规划、环境研究、交通与灾害管理等场景提供可靠的地理信息支撑。
1. 全国矢量地图shp格式:从数据分层到坐标纠偏的落地笔记
做GIS开发或者空间数据可视化的朋友,大概率都经历过这样的场景:项目需要一份全国范围的行政边界底图,翻遍各种开放平台,要么是切片瓦片没法做空间分析,要么是坐标偏移对不上业务数据,要么是属性字段缺胳膊少腿。全国矢量地图shp格式的资源包,解决的正是这个痛点——它把省、市、县甚至乡镇级别的行政边界,以Shapefile这种GIS领域最通用的矢量格式打包好,拿来就能在ArcGIS、QGIS、PostGIS或者GeoPandas里直接加载。这份资源适合做区域统计、专题制图、路径规划底图、空间叠加分析的从业者,也适合刚接触空间数据、想跳过数据采集直接进入分析环节的新手。但别急着双击打开,shp格式的坑,比想象中要多。
2. 拆开shp文件包:图层结构、属性表与坐标系选择
2.1 Shapefile不是单个文件,而是一组文件
很多人第一次拿到shp数据,看到文件夹里一堆同名不同后缀的文件就懵了。Shapefile本质上是一种基于文件系统的矢量数据格式,至少由三个文件组成:.shp存储几何形状,.shx存储索引,.dbf存储属性表。缺了任何一个,数据都打不开。全国矢量地图资源包通常还会附带.prj文件,用来定义坐标系;如果这个文件丢了,软件就不知道你的经纬度是WGS84还是其他基准,后续叠加分析必然错位。
我一般拿到数据后,先不急着加载,而是用命令行快速扫一眼文件完整性:
# 列出目录下所有shp相关文件,确认三件套是否齐全 ls -lh *.shp *.shx *.dbf *.prj 2>/dev/null # 用ogrinfo查看图层元信息(需安装GDAL) ogrinfo -so -al china_boundary.shpogrinfo输出的信息里,重点看Geometry类型(是Polygon还是MultiPolygon)、Feature Count(要素数量是否符合预期)、Extent(范围是否覆盖全国)以及Layer SRS(空间参考系统)。如果Layer SRS显示unknown,说明.prj缺失或无效,这时候千万别直接拿去做面积计算,否则结果会离谱到让你怀疑人生。
2.2 行政层级拆分与字段设计
全国矢量地图资源包通常按行政层级拆成多个shp文件,常见命名如province.shp、city.shp、county.shp。每个文件的属性表字段设计直接决定了后续能不能做关联分析。一个合格的资源包,属性表至少应该包含:行政区划代码、名称、上级代码、几何面积、中心点坐标。有些粗糙的版本只有名称和代码,做分级统计时还得自己补字段。
用Python的GeoPandas可以快速检查字段结构:
import geopandas as gpd # 读取省级边界 gdf = gpd.read_file('province.shp') # 查看字段名、数据类型、非空值数量 print(gdf.dtypes) print(gdf.isnull().sum()) # 检查几何有效性,无效几何会导致后续空间操作报错 invalid = gdf[~gdf.geometry.is_valid] print(f"无效几何数量: {len(invalid)}") # 查看坐标系 print(gdf.crs)这段代码里,gdf.dtypes帮你确认字段类型是否正确,比如行政区划代码应该是字符串而不是整数(避免前导零丢失)。is_valid检查几何自相交、环方向错误等问题,全国范围数据合并时尤其容易出这类毛病。gdf.crs返回坐标系信息,如果是EPSG:4326表示WGS84经纬度,如果是EPSG:4490则是CGCS2000,两者在国内场景下差异不大,但和业务数据叠加前必须统一。
2.3 坐标系选择:WGS84、CGCS2000与投影坐标系
坐标系是shp数据最容易翻车的地方。全国矢量地图资源包一般提供两种版本:地理坐标系(经纬度)和投影坐标系(平面米制)。地理坐标系适合做全国范围的可视化,但直接算面积会得到平方度这种没有物理意义的单位。投影坐标系常用Albers等面积投影,适合做面积统计和分级渲染。
常见做法是:如果只是画图展示,用WGS84或CGCS2000地理坐标系就够了;如果要算各省面积、做缓冲区分析,必须转到投影坐标系。用GeoPandas做转换:
# 从地理坐标系转到Albers等面积投影(以中国为例) gdf_projected = gdf.to_crs('+proj=aea +lat_1=25 +lat_2=47 +lat_0=0 +lon_0=105 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs') # 计算面积(平方千米) gdf_projected['area_km2'] = gdf_projected.geometry.area / 1e6 print(gdf_projected[['name', 'area_km2']].head())参数说明:lat_1和lat_2是标准纬线,中国常用25°N和47°N;lon_0是中央经线,取105°E;units=m确保输出单位是米。这套参数不是唯一的,但国内做全国尺度面积统计时比较通用。转完之后再算面积,结果才靠谱。
3. 加载与可视化:QGIS、GeoPandas与PostGIS三条路线
3.1 QGIS快速出图与样式配置
QGIS是查看shp数据最直观的工具。拖拽.shp文件到画布,右键图层属性可以配置填充色、边框、标注。全国矢量地图数据量大,县级边界动辄几千个要素,直接渲染会卡。我一般先加载省级做底图,需要细化时再叠加市级或县级。
QGIS里有个实用技巧:用Categorized分类渲染,按行政区划代码前两位分组,可以快速看出各省分布。如果要做分级统计图,把业务数据通过字段连接(Join)挂到属性表上,再按数值字段做渐变渲染。注意连接字段的类型要一致,字符串对字符串,整数对整数,否则连接结果为空。
3.2 GeoPandas做空间叠加与筛选
做数据分析时,GeoPandas比QGIS更灵活。比如要筛选出某个流域范围内的所有县,或者统计每个省内的城市数量,用空间操作几行代码就能搞定:
import geopandas as gpd from shapely.geometry import Point # 读取县界和城市点位 counties = gpd.read_file('county.shp') cities = gpd.read_file('city_points.shp') # 空间连接:把城市点位挂到所在县 joined = gpd.sjoin(cities, counties, how='left', predicate='within') # 统计每个县的城市数量 city_count = joined.groupby('county_name').size().reset_index(name='city_num') # 筛选特定省份的县 target_province = counties[counties['province_name'] == '某省'] print(f"某省县级单元数量: {len(target_province)}")sjoin的predicate参数支持within、intersects、contains等,做点面关联时用within最准确。groupby统计后可以再合并回原图层做专题图。注意GeoPandas的空间连接默认用几何列,如果两个图层坐标系不一致,先to_crs统一。
3.3 PostGIS入库与空间查询
数据量特别大或者需要多人协作时,把shp导入PostGIS是更稳妥的选择。用shp2pgsql命令行工具:
# 将省级边界导入PostGIS,指定SRID为4326 shp2pgsql -s 4326 -I -D province.shp public.province | psql -h localhost -U postgres -d gisdb # 导入后建立空间索引 psql -h localhost -U postgres -d gisdb -c "CREATE INDEX idx_province_geom ON province USING GIST (geom);"-s 4326指定SRID,-I创建空间索引,-D使用dump格式提升导入速度。入库后可以用SQL做空间查询,比如查某个点落在哪个省:
SELECT name FROM province WHERE ST_Contains(geom, ST_SetSRID(ST_MakePoint(116.4, 39.9), 4326));这种查询在业务系统里很常见,比如根据用户上报的经纬度反查行政区划。PostGIS的ST_Contains要求几何有效且坐标系一致,否则会返回空结果。
4. 避坑与排查:坐标偏移、几何无效与属性乱码
4.1 现象:叠加后边界整体偏移几百米
原因:业务数据用的是GCJ-02(火星坐标系),而shp数据是WGS84,两者在国内存在非线性偏移。解决:统一转到同一坐标系。如果业务数据是GCJ-02,需要先做坐标纠偏再叠加;如果只是可视化,可以在前端用偏移算法处理。常见做法是保留WGS84原始数据,在应用层做转换,不要直接修改源文件。
4.2 现象:面积计算结果为0或负数
原因:几何环方向错误,外环顺时针、内环逆时针是Shapefile的规范,但有些数据生成时搞反了。解决:用shapely的orient函数修正:
from shapely.geometry import polygon from shapely.ops import orient gdf['geometry'] = gdf['geometry'].apply(lambda x: orient(x, sign=1.0))sign=1.0表示外环逆时针,这是GeoPandas和大多数空间库的预期方向。
4.3 现象:属性表中文显示为乱码
原因:.dbf文件的字符编码没有统一,有些是GBK,有些是UTF-8,而软件默认按系统编码读取。解决:用ogrinfo指定编码重新导出,或者在GeoPandas里指定encoding参数:
gdf = gpd.read_file('county.shp', encoding='gbk')如果还是乱码,用QGIS打开后另存为UTF-8编码的GeoJSON,再转回shp。
4.4 现象:合并多个shp后要素丢失
原因:不同文件的字段结构不一致,pd.concat时列不对齐,或者几何类型不匹配(Polygon和MultiPolygon混用)。解决:合并前统一字段名和几何类型:
import pandas as pd gdfs = [gpd.read_file(f) for f in ['province.shp', 'city.shp']] # 统一几何类型为MultiPolygon gdfs = [gdf.to_crs('EPSG:4326') for gdf in gdfs] merged = pd.concat(gdfs, ignore_index=True) merged = merged[merged.geometry.notnull()]4.5 现象:QGIS加载后标注重叠看不清
原因:全国范围小比例尺下,县级名称标注必然重叠。解决:用QGIS的标注引擎设置Placement为Around centroid,开启Discourage labels from covering features,或者按比例尺分级显示——大比例尺只显示省名,放大后再显示市名和县名。
5. 进阶技巧:用空间索引加速全国范围查询
全国矢量地图数据做空间查询时,如果不建索引,每次遍历几千个多边形,响应时间会从毫秒级退化到秒级。GeoPandas底层用R-tree做空间索引,但需要手动触发。一个实用习惯是:加载数据后先检查gdf.sindex是否存在,如果为None就手动构建。
# 构建空间索引 gdf.sindex # 用索引做快速范围查询 from shapely.geometry import box bounds = box(115, 39, 117, 41) # 某区域范围 possible_matches = gdf.sindex.query(bounds, predicate='intersects') result = gdf.iloc[possible_matches]sindex.query返回的是可能相交的要素索引,再用intersects精确过滤。这套流程比全量遍历快一个数量级。PostGIS里对应的是GIST索引,建表后记得CREATE INDEX ... USING GIST,否则ST_Contains会走全表扫描。
另一个技巧是数据分块。全国县级数据一次性加载到内存可能占用几百MB,如果只做局部分析,用bbox参数按范围读取:
gdf = gpd.read_file('county.shp', bbox=(115, 39, 117, 41))bbox参数在文件级别过滤,比读入后再筛选省内存。做全国逐省统计时,可以按省循环读取,每次只加载当前省的范围,处理完释放内存。
从那以后我每次拿到新的shp数据,都强制走一遍流程:先ogrinfo看元信息,再is_valid查几何,然后to_crs统一坐标系,最后建空间索引。这套动作花不了五分钟,但能省下后面几个小时的排查时间。希望帮到你。
本文还有配套的精品资源,点击获取