简介:这是面向GIS开发者和地图应用场景的成都市GeoJSON数据包,涵盖高新区南区、高新西区、高新东区及天府新区等最新行政区域边界,适用于高德地图API、前端可视化或地理分析项目,可直接用于区域渲染、空间查询与城市规划参考。压缩包为RAR格式,共2个文件,包含1个ZIP压缩包和1个chengdu.json文件,整体大小仅1.6MB,结构紧凑。JSON文件内含各区域的多边形坐标与属性信息,ZIP包用于归档或提供备用数据,支持使用JavaScript、Python等常见语言及高德地图API快速读取和展示。目前已有942人学习下载,适合需要快速获取成都指定区域边界数据、进行地图定制或区域统计的开发者和研究人员,也可作为应急、选址和交通等领域的辅助数据。
1. 成都 geojson 数据为什么难搞:高新区和天府新区在行政区划里根本不存在
做成都可视化大屏的人,多半都让“成都 geojson 最新数据”这个需求坑过。你从公开渠道下载的成都区县边界,大概率只有 20 个标准行政区划单位,而高新区南区、高新西区、高新东区、天府新区这四个名字,在正式的行政区划代码里是不存在的——它们是功能区,不是行政区。于是最常见的翻车现场是:地图上高新西区那片产业区被填成了郫都区的颜色,天府新区直管区散落在双流和龙泉驿的边界里,你根本没法单独高亮它。这篇文章就是把这件事讲透:如何用公开数据自己拼一套能用于业务的成都 geojson,覆盖数据源选型、坐标系处理、功能区边界裁剪和最新版本判断,照着做就能落地。
2. 成都 geojson 数据获取:公开渠道、区划底图与坐标系选型
2.1 用行政区划代码筛选公开数据源:最靠谱的取数方式
我不建议直接找一份别人打包好的“成都全市 geojson”下载。那种一个文件里二十多个面、名字全都起好的,多半来自社区手工整理版,边界质量参差不齐,有没有把高新区处理好全凭运气。我的习惯是回到源头取数。
省市两级运维的地理信息公共服务平台,一般都会按行政区划代码提供边界下载服务。行政区划代码是判断数据权威性的关键:每个区县对应一个唯一的代码,前四位 5101 表示成都市,后六位精确到区县。下载后第一步不是看形状,而是对代码。你在接数据时,先确认字段里有没有 adcode 这类字段,有的话直接用代码匹配,比用名字匹配稳定得多——名字可能有简称、别名,代码不会。
另一个渠道是开源地理数据社区里的人工校对版本。这类版本的优点是把高新南区、高新西区、高新东区和天府新区都矢量化好了,方便省事;缺点是数据源头不一,有的区县来自官方,有的来自志愿者描边,边界一旦拼在一起,缝隙和重叠问题立刻暴露。所以我的做法是:行政区的 20 个区县以公开平台下载为主,功能区的独立边界从社区版本里取,再自己写脚本做裁剪和校验。把两套数据组合用,而不是指望某一个文件是全的。
2.2 成都 20 个行政区县的底图要求:简阳与高新东区是判断新旧的两个锚点
成都的行政区划底图,按现行区划一共是 20 个单位:12 个市辖区、3 个县、5 个县级市。这也是业务系统里最常用的基础图层。
| 类型 | 数量 | 区县 |
|---|---|---|
| 市辖区 | 12 | 锦江区、青羊区、金牛区、武侯区、成华区、龙泉驿区、青白江区、新都区、温江区、双流区、郫都区、新津区 |
| 县级市 | 5 | 都江堰市、彭州市、邛崃市、崇州市、简阳市 |
| 县 | 3 | 金堂县、大邑县、蒲江县 |
这套名单里的两个时间节点必须记牢。第一个是简阳:2016 年之前下载的成都数据大概率没有简阳,因为简阳是 2016 年才改由成都代管的。你拿这种旧数据做地图,成都的东南方向会缺一大块。第二个是新津:新津撤县设区之后,新版本数据里的名字应该是“新津区”而不是“新津县”。所以拿到数据先看这两处,比什么都快。
功能区的边界则是另一套逻辑。高新南区大致在武侯区南部与双流区交界的区域,高新西区在郫都区南部,高新东区在简阳市西部——三个片区互不相邻,中间隔着普通行政区。天府新区成都直管区则主要位于双流区中东部、局部伸入龙泉驿区一带,托管边界经过多次调整。正因为功能区边界是后来划定的,它和行政区边界天然存在交叠,空间上无法做到互斥。这一点在第 4 章还会展开。
2.3 坐标系统一:WGS84、GCJ02 与 Web 墨卡托三选一
坐标系是地理数据最容易出问题、又最容易被忽略的环节。下载到的成都 geojson 坐标系统一为 WGS84 经纬度,这是开源数据和 GPS 设备的通用标准,适合作为存储层格式。但如果你把这份数据直接叠到国内地图厂商的底图上,会发现整体偏移几百米——因为国内地图厂商的底图瓦片大多采用加密坐标系,和 WGS84 之间存在系统偏差。
前端展示层如果用 Web 墨卡托投影,那是显示标准,适合做地图渲染,但不适合拿来算面积。Web 墨卡托在高纬度地区面积严重失真,成都在北纬 30 度左右,直接用它算面积会偏大。我的建议是:存储统一用 EPSG:4326(WGS84),导出 geojson 时固定这个坐标系;算面积单独转等积投影;如果业务底图是国内地图 SDK,在数据接入层做坐标转换,转换后的数据单独存一份,不要污染原始文件。
3. 数据处理:把成都 20 个区县与高新、天府新区拼成一套可用的 geojson
3.1 批量读取区县 geojson:先用 Python 摸清字段和坐标系
确认数据源之后,第一步是批量读入。把下载好的区县文件按“区县名.geojson”的方式命名,放在同一目录下,用 GeoPandas 批量读取。注意先别急着合并,先把坐标系和字段结构打出来看一遍,确认所有文件都在同一个坐标系里。
import glob import geopandas as gpd # 假定文件按区县名命名,放在 data/chengdu_districts/ 目录下 files = sorted(glob.glob("data/chengdu_districts/*.geojson")) frames = [gpd.read_file(f) for f in files] districts = gpd.concat(frames, ignore_index=True) print(districts.crs) # 坐标系是否统一 print(districts.columns.tolist()) # 字段结构 print(districts["name"].tolist()) # 区县名单,核对是否 20 个这段代码里有两个关键点:glob按文件名模式批量抓取,sorted保证文件顺序稳定;gpd.concat把所有区县合并成一个 GeoDataFrame,ignore_index=True重置索引,避免后续操作出现索引重复。打印crs是为了确认所有文件都是 WGS84,如果有文件是其他坐标系,先在concat之前单独处理掉。打印name列表是为了肉眼核对区县名单,重点看简阳在不在、新津是“区”还是“县”。如果数据源没有adcode字段,后面自己补一列内部编码就行,不影响空间操作。
3.2 合并全市边界与功能区裁剪:overlay 的 intersection 用法
行政区底图准备好之后,两个核心操作:一是合并出成都全市边界,二是把功能区边界严格限制在行政区范围内。功能区边界是人工矢量化或从社区版本继承来的,难免有超出行政区范围的部分,直接拿来用会让功能区盖到别的市去。用overlay的intersection做裁剪是最稳妥的。
# 1. 按 city 字段合并,生成全市整体边界 city = districts.dissolve(by="city", aggfunc="first") # 2. 读取功能区独立边界(高新南/西/东区 + 天府新区成都直管区) zones = gpd.read_file("data/chengdu_functional_zones.geojson") zones = zones.to_crs(districts.crs) # 确保坐标系一致 # 3. 裁剪:只保留落在成都市范围内的部分 zones_clip = gpd.overlay(zones, districts, how="intersection") zones_clip["zone_type"] = "functional"dissolve按city字段把 20 个区县合并成一个面,aggfunc="first"表示合并且保留该组第一条记录的属性,这里我们只需要几何,属性无所谓。overlay的how="intersection"是求两个图层几何的交集,输出结果里的每个面都同时属于功能区和成都行政区,这样就能保证功能区边界不越界。如果你发现裁剪后有碎面,多半是源数据里的小缝造成的,可以按面积阈值过滤掉。
这里还有一个很容易被忽略的点:高新南区、西区、东区三个片区互不相邻,千万不要为了做一个“高新区”图层而把三个面 union 成一个。三个片区中间隔着郫都区、双流区和简阳市的辖区,强行合并会把大量非高新区区域包进来,业务统计时面积和范围全错。正确的做法就是三个片区独立成面,共享同一个名称前缀,属性里用片区名区分。
3.3 输出 FeatureCollection:字段设计决定业务系统好不好接
数据处理完,输出前的字段规整非常关键。业务系统接 geojson 时,只认固定字段名。我见过因为字段乱起导致前端无法绑定数据的案例:有人把区县名放在name里,有人放在label里,还有人放在NAME里,前端每接一个数据源就要改一次映射。这里给出我常用的字段规范。
| 字段 | 示例 | 说明 |
|---|---|---|
| name | 高新南区 | 展示名称,功能区与行政区统一 |
| adcode | 510109 | 行政区划代码;功能区可以自定义编码,如 GX01 |
| zone_type | functional / administrative | 区分功能区和行政区 |
| city | 成都市 | 便于省级聚合和过滤 |
import pandas as pd import geopandas as gpd districts["zone_type"] = "administrative" districts["city"] = "成都市" cols = ["name", "adcode", "zone_type", "city", "geometry"] merged = gpd.GeoDataFrame( pd.concat([districts[cols], zones_clip[cols]], ignore_index=True), crs="EPSG:4326", ) merged.to_file("chengdu_full.geojson", driver="GeoJSON")这段代码把行政区数据和功能区数据拼接成一份完整的 FeatureCollection。pd.concat按行拼接,ignore_index=True重新编号;crs="EPSG:4326"强制指定输出坐标系为 WGS84,防止文件自带的 crs 信息丢了导致前端乱套。to_file的driver="GeoJSON"指定输出格式。输出后我一般会再用geojson.io或 QGIS 打开看一眼,确认没有掉面。
4. 成都 geojson 避坑指南:拓扑错误、面积偏差与功能区归属冲突
4.1 相邻区县边界有缝隙或重叠:缓冲区修复的两个方向
现象:放大到街道一级,武侯区和双流区的交界处出现一条细缝,或者两个区挤进来同一个社区地块。这类问题在社区手工版数据里尤其常见,因为每个区县的边界可能是不同志愿者画的。
原因:不同来源的边界节点坐标不一致。A 区边界在某个坐标处中断,B 区边界在另一个坐标处结束,两个节点之间就差了那么零点几米。
解决:先做有效性修复,再做几何对齐。无效几何大部分是自相交造成的,buffer(0)是最经典的单行修复方案;如果修复之后缝隙还在,用snap把相邻几何吸附对齐。
from shapely.ops import snap # 先修自相交等无效几何 districts["geometry"] = districts.geometry.buffer(0) # 以第一个区县为基准,把其他区县边界吸附到容差范围内 base = districts.geometry.iloc[0] districts["geometry"] = districts.geometry.apply( lambda g: snap(g, base, tolerance=0.0001) )buffer(0)不是真的做缓冲区,而是把自相交的环拆开重建,是最常用的拓扑修复手段。snap的tolerance参数单位是度,0.0001 度大约是 10 米级别,对区县边界来说够用。两个方向的修复逻辑不一样:修缝隙用snap,治重叠靠buffer(0)之后再做 overlay 的difference清除重叠区域。
4.2 面积和官方统计对不上:算面积用错了投影
现象:用 GeoPandas 自带area属性算成都总面积,得到 1.5 万甚至 1.6 万平方公里,比官方口径偏大,某个区的面积怎么算都觉得不对劲。
原因:geometry 是经纬度坐标系时,area算出来是“度²”而不是平方公里,数值毫无意义;或者数据还在 Web 墨卡托坐标系下直接算面积,纬度越高虚胖越严重。成都地处北纬 30 度附近,墨卡托投影下面积比实际偏大不少。
解决:算面积之前先把数据投影到适合成都的等积投影。UTM 48N(EPSG:32648)覆盖成都区域,是一般项目里最简单可靠的选择。
area_gdf = districts.to_crs("EPSG:32648") districts["area_km2"] = area_gdf.geometry.area / 1e6转换到 UTM 后area的结果是平方米,除以 1e6 得到平方公里。这个值和官方公布的面积对得上,才能说明边界数据本身是靠谱的。如果对不上,先排查有没有哪个区县的边界明显越界,再排查是不是有重复面没清理干净。
4.3 预览工具正常、业务系统渲染错乱:Geometry 类型与属性污染
现象:数据在网页预览工具里打开一切正常,但一接进自研 GIS 引擎或地图组件,高新南区的边界出现破洞,天府新区的面渲染成斜线斑块。
原因:两种可能。一是几何类型不纯,数据里混着GeometryCollection,某些引擎不认这个类型;二是properties里有非法字符或超大字符串,前端 JSON 解析时性能崩了。
解决:导出前统一几何类型,强制转成MultiPolygon,顺便做一次有效性校验。
from shapely.geometry import MultiPolygon def to_multi(g): if g.geom_type == "GeometryCollection": polys = [p for p in g.geoms if p.geom_type in ("Polygon", "MultiPolygon")] return MultiPolygon([p for poly in polys for p in getattr(poly, "geoms", [poly])]) return g districts["geometry"] = districts.geometry.apply(to_multi) print(districts.geometry.is_valid.all())geom_type检查是这一段的重点:GeometryCollection在可视化工具里能显示,但在严格按 OGC 标准实现的引擎里很容易出问题。把集合里的多边形拆出来重组,统一成MultiPolygon,兼容性最好。is_valid.all()为False时,返回 False 的行用第 4.1 的buffer(0)再修一轮。
4.4 功能区归属冲突:一个点位同时属于高新和武侯怎么办
现象:一个营业网点的坐标落下来,同时匹配到高新南区和武侯区,统计报表里数据被算了两次。这不是数据 bug,是两套划分体系在空间上不能互斥的必然结果。
原因:功能区边界是从行政区里划出来的托管区域,它与行政区的空间范围天然交叠。高新南区在武侯区的地盘上,高新区和武侯区的面必然重合。你不可能让一个点只属于其中一个,除非人为设定优先级。
解决:业务系统里给功能区更高的优先级,点归属判断时先匹配功能区,匹配不到再落入行政区。空间数据处理时,把功能区和行政区作为两个独立图层,不要合并成一个互斥图层。唯一归属需求强烈时,用 overlay 把功能区和行政区的交叠部分单独切出来,做成一个带双属性的过渡图层——这样既能统计高新区的产业数据,也能统计武侯区的行政数据,两边数据都能对上。
5. 一个验证技巧:用简阳和新津字段快速判断成都 geojson 够不够新
5.1 属性列表验新旧:哪些字段缺失说明数据是老版本
拿到任何一份成都 geojson,先跑一遍区县名单比对,比对着地图看半天快得多。我常用下面这段检查脚本:
must_have = {"锦江区", "青羊区", "金牛区", "武侯区", "成华区", "龙泉驿区", "青白江区", "新都区", "温江区", "双流区", "郫都区", "新津区", "金堂县", "大邑县", "蒲江县", "都江堰市", "彭州市", "邛崃市", "崇州市", "简阳市"} names = set(districts["name"]) missing = must_have - names print("缺失区县:", missing)判断逻辑很简单:缺简阳,数据是 2016 年以前的;名字里是“新津县”而不是“新津区”,数据是撤县设区之前的;属性列表里没有高新东区,就没有覆盖 2017 年之后高新区的托管范围。这三项全部通过,这份数据才算具备“最新”的底线条件。
5.2 边界吻合度验证:功能区与行政区打架的位置重点盯
属性过了,还要验证空间。重点看三处交界:高新南区与武侯、双流交界,高新西区与郫都交界,高新东区与简阳交界。这三个位置最容易出现边界错位。做法是在 QGIS 里把功能区和行政区两个图层同时打开,设半透明叠加,放大到 1:5000 核对边界走向。如果功能区边界和行政区边界之间出现了一条明显的缝隙带,多半是坐标漂移或者手工描边误差,需要回到第 3.2 重新裁剪。
我第一次正式接入成都数据时,拿到的版本没有简阳,全市边界东南方向凭空少了一块,当时还以为是图层样式问题,排查了半天才发现是数据本身不完整。从那以后我养成了一个习惯:拿到成都 geojson 先跑名单比对,简阳、新津区、高新东区缺一个都不采用。这个习惯后来帮我避开了不少类似的坑。数据这个事,最怕的就是看着像、用着错,多一道验证工序,心里踏实得多。希望帮到你。
本文还有配套的精品资源,点击获取