简介西咸新区电子地图地理数据采用GeoJSON与JSON格式封装面向Web前端开发、可视化大屏搭建和GIS应用场景主要解决国家级新区地图边界获取难、数据格式不统一、厂商工具适配繁琐等问题可直接在ECharts、DataV、geojson.io等常用工具中导入展示。数据覆盖西咸新区整体轮廓并细化到沣东、沣西、空港、泾河、秦汉五个城区既有完整组合文件也有独立拆分的城区地图支持点击下钻、单独调用任意城区适用于政企大屏、区域分析和项目演示等场景。资源包共8个文件含5个GeoJSON地图文件与3个JSON层级配套文件整包仅55KB轻量易用导入主流地图制作工具即可预览效果省去自行转换与校准坐标的流程。数据中还包含轮廓与层级结构便于在页面中实现区域高亮、联动筛选、下钻回退等交互。目前已有2236人学习下载适合需要快速建立国家级新区地图可视化能力的前端与GIS开发者直接复用。1. 西咸新区GeoJSON是什么一张能直接喂给ECharts的“边界文件”做政务大屏或城市数据面板时经常需要把西咸新区下辖的空港、沣东、沣西、秦汉、泾河五个新城画出来。标题里说的“geojsonjson文件包含各个城区”本质上就是一份描述行政功能边界的地理数据文件里面存的是经纬度坐标、城区名称和边界拓扑关系ECharts不少人搜成echars、Leaflet、Mapbox 这类前端地图库都能直接消费它。这篇文章不卖文件也不讨论某一份具体数据的出处而是告诉你怎么拿到任何一份西咸新区GeoJSON之后完成校验、清洗、本地部署、加载到ECharts并避开那些让边界错位、城区名对不上的坑。适合正在做国家级新区可视化项目、需要把地图数据落到自己服务器上的开发者和GIS工程师。2. 拿到JSON文件之后先做这3步校验再谈“直接使用”标题敢写“可直接使用”但实际项目里从网上下载的GeoJSON十个里至少有四个有问题坐标系不是你要的、边界不闭合、properties里的城区名和业务数据对不上这些都会让ECharts画出来一团糟。所以我拿到一个json文件后的第一件事不是急着写代码而是做三步校验先查坐标系和属性结构再在GIS工具里预览边界最后统一字段名和编码。这三步做完后面的“直接使用”才有底气。2.1 用Python检查GeoJSON的坐标系和属性表GeoJSON规范默认坐标是WGS-84经纬度也就是EPSG:4326。但很多地图厂商导出的数据是GCJ-02火星坐标系甚至百度BD-09三者之间经纬度能差几百米到几公里。直接拿来在ECharts上画边界会整体偏移和底图对不上。另外还要确认坐标顺序GeoJSON里一个点写作[经度, 纬度]如果写反了整个地图会像镜像翻转一样左右颠倒。我一般用Python的json和标准库快速检查不需要装额外依赖import json with open(xixian_new_area.geojson, r, encodingutf-8) as f: data json.load(f) # 看顶层结构标准GeoJSON是 FeatureCollection print(data[type]) print(len(data[features])) # 有多少个面要素 # 看第一个要素的geometry类型和坐标范围 feat data[features][0] geom_type feat[geometry][type] print(geom_type) # Polygon 或 MultiPolygon coords feat[geometry][coordinates] lons [] lats [] # 递归提取所有坐标点兼容 Polygon 和 MultiPolygon def walk(c): if isinstance(c[0], (int, float)): lons.append(c[0]) lats.append(c[1]) else: for sub in c: walk(sub) walk(coords) print(经度范围:, min(lons), max(lons)) print(纬度范围:, min(lats), max(lats))这段代码会打印出整个文件里所有点的经纬度范围。西咸新区的大致位置在东经108.5到109.0、北纬34.2到34.5之间。如果你打印出来的经度是114开头像武汉、长沙或者纬度变成二十多度像广州那坐标系肯定不对或者坐标是被投影工具重投影过的。还有一个极容易忽略的点如果经度范围是负值说明数据用了西半球坐标或者坐标顺序反了需要把每对经纬度调换。另外一定要看properties里有没有name字段。ECharts的map组件默认用name来匹配数据如果这份JSON的城区名是拼音比如Konggang或代码编号比如XX002后面做tooltip和数据映射时就得写一堆alias别名。我见过一份号称“最详细”的西咸新区数据城区名用的是高德地图的adcode四个数字页面里完全没法展示最后只能手动映射。2.2 在QGIS里预览边界和城区图层代码检查只能判断数值逻辑边界闭不闭合、有没有自相交的多边形、相邻城区之间有没有缝隙必须用图形工具看。QGIS免费开源直接把GeoJSON拖进去就能显示。我用它主要做三件事。第一打开属性表确认每个要素各有一条记录并且有一个能识别的名称字段。没有名称的要素会在后续合并或下钻时变成“孤儿”多边形。第二缩放西咸新区全境看五个新城的边界是否粘连、有没有交叠。第三检查边界线是不是闭合的——一个完整的Polygon外环首尾坐标必须相同如果文件是从CAD转换来的很多环是断开的ECharts画出来会缺一块。有个很关键的结构问题西咸新区下面的“五个新城”不是标准行政区划而是功能区划。不同地图厂商的画法差别很大有的把五个新城画成五个独立Feature有的画成一个大的整体边界里再分块还有的把两个不相邻的区域合并成一个MultiPolygon。这两种结构对ECharts来说差别很大独立Feature可以直接做下钻和点击MultiPolygon在ECharts里会被当成一个region点击tooltip只显示一个名字没法区分内部块。如果是MultiPolygon结构可以用QGIS的“矢量”菜单里的“多部分转单部分”工具拆开。拆完以后注意每个子要素会继承原要素的全部属性但name字段是相同的需要你再按位置手动改。如果你懒得手动改也可以把拆出来的图层和一份已知城区名的点图层用“按位置连接”关联把点所在区域的名称赋给多边形。这个方法在五个新城边界特别碎的情况下非常省力。2.3 确认文件编码和字段命名为ECharts做准备很多从网盘或GitHub下载的JSON文件是UTF-8带BOM的或者干脆是GBK编码。用记事本打开看着没问题但用fetch加载后会出现乱码ECharts里城区名变成一串问号或方框。另外还有字段名不一致的问题有的文件里写“name”有的写“NAME”有的写“区县名”这些都影响绘制。检查编码最快的方式是用VS Code打开文件看右下角显示的编码。如果是GBK就别想着在代码里动态转码了直接用编辑器另存为UTF-8。如果是UTF-8带BOM在HTTP环境下有时候会在JSON解析时报错最好去掉BOM。命令行处理最稳# 去掉文件头部的 BOM sed -i 1s/^\xEF\xBB\xBF// xixian_new_area.geojson字段统一这个问题我习惯写一段一次性脚本处理而不是在ECharts里配置别名。因为配置别名只解决显示问题解决不了你的业务数据里可能也用这个字段做关联的问题。python -c import json with open(xixian_new_area.geojson, encodingutf-8) as f: d json.load(f) for feat in d[features]: props feat[properties] # 把常见字段名统一为 name if name not in props or not props[name]: props[name] props.get(乡镇名) or props.get(NAME) or props.get(区县名) with open(xixian_new_area_fixed.geojson, w, encodingutf-8) as f: json.dump(d, f, ensure_asciiFalse) 这段脚本有两个关键点一是ensure_asciiFalse必须加否则json.dump会把中文写成\uXXXX转义序列文件看着没问题但ECharts显示中文时偶尔会有兼容问题二是or连写法处理了字段缺失的情况避免KeyError。跑完再用VS Code打开确认一遍字段变成统一的name编码是UTF-8无BOM这份文件才真正算“能给ECharts直接使用”。3. 把西咸新区GeoJSON装进ECharts从本地部署到地图下钻校验完JSON文件下一步就是让它出现在浏览器里。标题里说“echars和其他地图厂商可直接使用”最常见的场景是本地部署一个可视化页面用fetch加载这份geojson然后注册成ECharts地图。这一章我把完整流程拆开每一步都给可跑通的代码和参数说明。3.1 用fetch加载本地JSON文件注意本地部署的跨域问题ECharts官方推荐使用地图JSON文件时要么用script标签直接引入要么用fetch registerMap。在本地部署也就是文件放在服务器上时fetch是最灵活的方式因为你可以动态加载不同精度、不同年份的边界文件。如果只是静态演示也可以把GeoJSON作为JavaScript变量直接写入页面但那样会失去按需加载的灵活性。!DOCTYPE html html head meta charsetutf-8 title西咸新区电子地图/title script srchttps://cdn.jsdelivr.net/npm/echarts5/dist/echarts.min.js/script /head body div idmap stylewidth:100%;height:600px;/div script async function init() { const response await fetch(./xixian_new_area.geojson); const geoJson await response.json(); echarts.registerMap(xixian, geoJson); const chart echarts.init(document.getElementById(map)); chart.setOption({ geo: { map: xixian, roam: true } }); } init(); /script /body /html这里最关键的坑是fetch的路径。如果你只是双击打开这个HTML文件file://协议fetch会被浏览器的跨域策略拦下来控制台报错“Access to fetch at file:///... has been blocked by CORS policy”。这就是“如何本地部署geojson”这个问题最常见的翻车点。很多人以为是代码错了其实是协议问题。我的做法是装一个本地静态服务器VS Code的Live Server插件最省事或者用Python自带的cd 你的项目目录 python -m http.server 8080然后在浏览器访问http://localhost:8080/你的页面.html。注意端口号别被占用如果8080冲突就换8081。还有一个小细节fetch的URL最好用相对路径./xixian_new_area.geojson不要写成/xixian_new_area.geojson因为部署到子目录时绝对路径会404。3.2 注册地图并用geo/map组件显示上面的代码只展示了geo组件的基础用法但实际项目里更多人用series-map因为map类型的series能更方便地绑定业务数据、做颜色分级。geo组件适合只展示边界底图不绑定数据series-map适合展示统计值比如各新城的企业数量、人口密度。两者也可以同时用底图用series-map再叠加一个geo做背景装饰。注册地图的代码是一样的差别在setOption里的配置chart.setOption({ tooltip: { trigger: item, formatter: function(params) { return params.name br/ (params.value || 暂无数据); } }, visualMap: { min: 0, max: 100, left: 20, bottom: 20, calculable: true, inRange: { color: [#e0f3f8, #ffffbf, #fee08b, #d73027] } }, series: [{ type: map, map: xixian, roam: true, label: { show: true, fontSize: 10 }, data: [ { name: 空港新城, value: 32 }, { name: 沣东新城, value: 58 }, { name: 沣西新城, value: 45 }, { name: 秦汉新城, value: 20 }, { name: 泾河新城, value: 12 } ] }] });series里的data的name必须和GeoJSON里feature.properties.name完全一致包括空格和缩写。比如“沣西新城”不能写成“沣西”更不能写成“FX”。如果对不上这个城区会显示在地图上但不上色tooltip也拿不到值。visualMap的min和max要根据你的业务数据范围调整如果数据里有异常值比如某个新城value是500而max设成100整个地图就全是深红色看不出差异。3.3 给各个城区做点击下钻和tooltip标题强调“包含各个城区”说明读者很可能需要下钻交互点击某个新城放大显示该区域或者跳转到详情页。ECharts的click事件可以拿到点击区域的name然后你可以用它来更新图表或切换视角。chart.on(click, function(params) { if (params.componentType series params.seriesType map) { console.log(点击了, params.name); // 方案一用 dispatchAction 缩放 chart.dispatchAction({ type: geoRoam, zoom: 1.8, target: params.name }); // 方案二跳转到详情页 // window.location.href /detail?city encodeURIComponent(params.name); } });注意geoRoam是ECharts 5的APIECharts 4里的写法不同。如果你想兼容旧版本用setOption里的geo.center和zoom来控制视角chart.setOption({ geo: { center: [108.8, 34.3], zoom: 6 } });center需要传入一个经纬度坐标。怎么得到某个城区的中心点可以先用geojson.io打开文件点击对应多边形看它的坐标范围然后取中间值。或者用Python脚本计算所有坐标的平均值这样定位更精准。import json with open(xixian_new_area.geojson, encodingutf-8) as f: data json.load(f) def get_polygon_center(coords): lons [c[0] for c in coords] lats [c[1] for c in coords] return (sum(lons) / len(lons), sum(lats) / len(lats)) for feat in data[features]: name feat[properties].get(name) geom feat[geometry] if geom[type] Polygon: center get_polygon_center(geom[coordinates][0]) else: # MultiPolygon # 取第一个子多边形的外环 center get_polygon_center(geom[coordinates][0][0]) print(name, round(center[0], 5), round(center[1], 5))这个脚本输出的经纬度可以直接填到center里。注意MultiPolygon取的是第一个子区块的中心如果某个城区的区块分散很开这样的中心点可能落在空白处。更准确的做法是计算所有子区块的加权质心但作为地图缩放定位这个精度已经足够。4. 从“能用”到“好用”属性字段、坐标系与子区域合并的3个必调参数很多人拿到一份号称“最详细”的GeoJSON后直接在ECharts里一画地图出来了但总感觉差口气——要么边界粗糙像锯齿要么底图和数据对不上要么点击某个区域时tooltip里显示的是拼音。这一章讲三个必调参数把一份能跑的地图调成能展示、能交互、能让用户愿意看的地图。4.1 属性字段name与ECharts的映射关系ECharts的registerMap会把GeoJSON的feature要素转成地图的region区域region的name取的是properties.name。如果你的业务数据里的行政区名和JSON里的name不一致有两条路一是改业务数据二是给ECharts配别名。改JSON字段最直接但有些情况JSON来自公司内部GIS平台每次更新都会覆盖你改完也会丢。这时候用aliasMap最合适。它是registerMap的第三个参数不污染原始文件还能把拼音、旧名称、带行政区后缀的名字一次性映射成你想要的展示名echarts.registerMap(xixian, geoJson, { aliasMap: { 空港: 空港新城, fengdong: 沣东新城, 秦汉新城管委会: 秦汉新城 } });aliasMap的key是JSON里的原始namevalue是页面里要显示的名字。注意这个配置生效的前提是registerMap的第三个参数传了对象忘了传就不会生效。另外aliasMap的匹配是精确匹配不要想着模糊匹配如果原始name里有不可见字符比如BOM或零宽空格直接写“空港”是匹配不上的。遇到这种情况先用2.3节的脚本把不可见字符清掉。还有个细节如果业务数据里有一批name在GeoJSON里不存在ECharts会自动创建一个只有名字、没有边界的regiontooltip能触发但地图上没有形状。这会导致地图上出现一个个悬空的tooltip看着很诡异。解决办法是做个差集把地图里没有的name过滤掉或者补数据。4.2 坐标系GCJ-02与WGS-84的偏移坑西咸新区范围内的底图如果你用的是高德、百度这类国内地图厂商的底图它们默认是GCJ-02或BD-09坐标系。而很多开放GeoJSON数据是从OSM或国家地理信息公共服务平台拿的用的是WGS-84。这两个坐标系之间相差约300到500米反映在屏幕上就是几个街道级别的偏移。ECharts本身不做坐标转换它只是把GeoJSON里的坐标按经纬度画到canvas上。如果你拿WGS-84的边界去叠加高德底图边界会飘到相邻区域看起来“出界”。解决方案有两个。方案一统一坐标系。如果你的页面只展示ECharts自己画的地图不叠加任何影像底图那么WGS-84完全没问题因为所有要素都在同一个坐标系里相对位置是对的。你在地图上叠加GPS采集的POI点GPS也是WGS-84那也对得上。方案二把GeoJSON转成GCJ-02和你用的高德底图保持一致。Python里可以用网上流传的coord转换脚本核心是一个带国家偏移的算法。这里给出一个可运行的简化版本import math def transform_lat(x, y): ret -100.0 2.0 * x 3.0 * y 0.2 * y * y 0.1 * x * y 0.2 * math.sqrt(abs(x)) ret (20.0 * math.sin(6.0 * x * math.pi) 20.0 * math.sin(2.0 * x * math.pi)) * 2.0 / 3.0 ret (20.0 * math.sin(y * math.pi) 40.0 * math.sin(y / 3.0 * math.pi)) * 2.0 / 3.0 ret (160.0 * math.sin(y / 12.0 * math.pi) 320 * math.sin(y * math.pi / 30.0)) * 2.0 / 3.0 return ret def transform_lng(x, y): ret 300.0 x 2.0 * y 0.1 * x * x 0.1 * x * y 0.1 * math.sqrt(abs(x)) ret (20.0 * math.sin(6.0 * x * math.pi) 20.0 * math.sin(2.0 * x * math.pi)) * 2.0 / 3.0 ret (20.0 * math.sin(x * math.pi) 40.0 * math.sin(x / 3.0 * math.pi)) * 2.0 / 3.0 ret (150.0 * math.sin(x / 12.0 * math.pi) 300.0 * math.sin(x / 30.0 * math.pi)) * 2.0 / 3.0 return ret def wgs84_to_gcj02(lng, lat): a 6378245.0 ee 0.006693421622965943 dlat transform_lat(lng - 105.0, lat - 35.0) dlng transform_lng(lng - 105.0, lat - 35.0) radlat lat / 180.0 * math.pi magic math.sin(radlat) magic 1 - ee * magic * magic sqrtmagic math.sqrt(magic) dlat (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * math.pi) dlng (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * math.pi) return lng dlng, lat dlat把这段逻辑作用到GeoJSON的每个坐标点上再输出成新JSON。但我要提醒你如果你的GeoJSON本身就是别人做好的“火星坐标”版本你再转一次就等于把数据推出了国界。判断方法很简单在geojson.io里拖入文件看边界是否和底图上的河岸线、主干道吻合。如果整个区域往西北飞了几百米说明坐标已经是GCJ-02不能再转。4.3 合并城区边界用MapShaper或QGIS简化几何“最详细的国家级新区地图”往往意味着多边形顶点特别密坐标点可能上万级。ECharts在浏览器里绘制的时候如果多边形有几千个点每次缩放都要重新计算顶点页面会卡顿。解决办法是简化几何也就是在保证边界轮廓可辨认的情况下去掉多余顶点。MapShaper是一个常用的在线/命令行工具它能把GeoJSON的顶点数量压缩到原来的5%到10%。我一般在命令行里批量处理保留一份原始详细版再生成一份简化版用于线上加载# 全局安装 npm install -g mapshaper # 保留 10% 的顶点数量输出新文件 mapshaper xixian_new_area.geojson -simplify dp 10% -o formatgeojson xixian_simplified.geojsondp表示Douglas-Peucker算法10%是保留的顶点比例。比例越低边界越粗糙。对于西咸新区这种面积级别10%通常看不出明显变化如果数据集里有特别复杂的弯折可以用15%。简化完一定要在QGIS或geojson.io里看一眼有些区域边界会变成直线比如沣河拐弯处。如果某个新城边界需要保持精度可以让MapShaper按属性字段设置不同权重mapshaper xixian.geojson -simplify dp 10% keep-shapes -o xixian_simplified.geojsonkeep-shapes这个参数很关键它可以防止简化后碎小的多边形消失。如果不加单块面积太小的Flying斑块可能会被直接删掉导致地图上出现空洞。另外还有一个细节ECharts的map组件默认给每个多边形加一层描边stroke如果描边太粗边界会看起来糊成一团。在series.map里设置itemStyle的borderWidth和borderColorseries: [{ type: map, map: xixian, itemStyle: { areaColor: #f0f0f0, borderColor: #666, borderWidth: 1 }, emphasis: { label: { show: true, color: #333 }, itemStyle: { areaColor: #ffd666 } } }]这三个参数改完地图的可用性会提升一大截名称对得上、位置不偏移、渲染不卡顿。后面你在这个基础上叠加任何业务数据画面都会干净很多。5. 避坑指南西咸新区GeoJSON最常见的5个翻车现场这一章专门记录我帮别人排查这类地图问题时遇到的真实案例每条按现象、原因、解决来写方便你对照处理。这些坑不是理论推演基本都是会真实让你调试到怀疑人生的玄学问题。5.1 现象ECharts画出来是空白只有背景色什么图形都没有原因GeoJSON的结构不是标准的FeatureCollection。最常见的两种一是文件顶层type是GeometryCollection里面没有features数组二是feature对象缺少geometry属性只有properties。ECharts的registerMap只认FeatureCollection其他结构一概解析失败但不会报错只是静默地画不出来。解决用文本编辑器打开JSON看最外层结构。标准GeoJSON长这样{ type: FeatureCollection, features: [ { type: Feature, properties: { name: 空港新城 }, geometry: { type: Polygon, coordinates: [ [ [108.7, 34.4], [108.8, 34.3] ] ] } } ] }如果你的文件是别的厂商导出的比如某些GIS软件导出的JSON是整个要素集数组外包一个{layers:[...]}那必须先剥离出features。用Python处理import json with open(bad.geojson, encodingutf-8) as f: data json.load(f) if elements in data: features data[elements] elif layers in data: features [] for layer in data[layers]: features.extend(layer.get(features, [])) else: raise ValueError(无法识别的结构) output {type: FeatureCollection, features: features} with open(fixed.geojson, w, encodingutf-8) as f: json.dump(output, f, ensure_asciiFalse)跑完以后再在QGIS里加载一次如果能显示才拿给ECharts。空白的另一个隐性原因是文件路径不对导致fetch返回404fetch失败后registerMap没执行但是setOption还是跑了此时ECharts会抛一个“There is no map container”的错而不是空白。所以遇到空白先看控制台有没有报错没有报错基本就是结构问题。5.2 现象地图显示出来了但边界错位到别的城市或者在南极/海上原因坐标系不统一。有的顶点是经纬度有的顶点是投影坐标比如Web墨卡托的米制坐标。典型例子一份JSON里西咸新区的坐标范围如果是(12000000, 3000000)这种量级那它很可能是EPSG:3857投影坐标必须重投影回EPSG:4326经纬度才能用。还有一种情况是坐标顺序反了GeoJSON必须是[经度, 纬度]但如果文件来源是某个只输出[纬度, 经度]的工具地图会上下左右翻转。解决用QGIS重投影最方便。打开图层右键“导出要素另存为”坐标系选EPSG:4326格式GeoJSON。重投影后检查坐标范围。如果是坐标顺序反了写一段Python脚本把所有坐标对调import json with open(reversed.geojson, encodingutf-8) as f: data json.load(f) def swap_coords(coords): if isinstance(coords[0], (int, float)): return [coords[1], coords[0]] return [swap_coords(c) for c in coords] for feat in data[features]: geom feat[geometry] if geom[type] Polygon: geom[coordinates] swap_coords(geom[coordinates]) elif geom[type] MultiPolygon: geom[coordinates] swap_coords(geom[coordinates]) with open(swapped.geojson, w, encodingutf-8) as f: json.dump(data, f, ensure_asciiFalse)这个递归函数对嵌套层级都有效因为Polygon的coordinates是四层嵌套MultiPolygon是五层。注意swap_coords里判断isinstance(coords[0], (int, float))如果坐标值是字符串要先转成float否则判断失效。5.3 现象所有城区都在地图上但tooltip里显示undefined原因properties里没有name字段或者有的feature有name有的没有。ECharts的tooltip默认读取region.name而region.name来源于properties.name。没有name的region在事件回调里就显示undefined。解决在registerMap之前遍历所有feature把缺失name的补上。但补的名字不能随便乱造否则会影响下钻逻辑。我常用的办法是先用脚本生成一个栅格图或者点图层把每个多边形的地理中心点坐标导出配合已知城区名的表格去做空间连接或者干脆手动对照地图填写。for i, feat in enumerate(data[features]): props feat.get(properties, {}) if not props.get(name): # 这里可以用一个映射字典按索引指定名称 props[name] f未命名片区{i}如果你确定所有feature都有name但ECharts还是显示undefined那问题很可能出在字段名不是name而是Name或NAME。上面这个脚本可以改成把Name/NAME/乡镇名都读出来赋给name。还有最后一个隐蔽点某些GeoJSON文件里properties本身是null不是对象这种情况下feat.get(properties, {})不会生效会直接抛异常。需要先判断if feat.get(properties) is None: feat[properties] {}5.4 现象页面加载后卡顿缩放地图非常迟钝原因GeoJSON文件太大。一份“最详细”的边界文件可能有几十MB包含数万个坐标点浏览器绘制这么多顶点每次重绘都是巨大的计算量。解决用4.3节的MapShaper简化。另外检查文件中是否包含大量冗余属性比如每个feature都带一串很长的历史描述文本这些属性在ECharts绘制时用不到但会增加fetch的解析时间。把不需要的字段全删掉只保留name和可能用到的数据字段with open(xixian.geojson, encodingutf-8) as f: data json.load(f) KEYS [name, value, adcode] for feat in data[features]: props feat[properties] for k in list(props.keys()): if k not in KEYS: del props[k] with open(xixian_light.geojson, w, encodingutf-8) as f: json.dump(data, f, ensure_asciiFalse)还有一种情况文件本身不大但地图上每个城区的边界线条非常复杂缩放时ECharts实时重绘所有polygon导致帧率低。这时候可以给series-map开启animation: false关掉过渡动画虽然少了丝滑感但交互响应会快很多。如果还卡就把地图切成五个单城区JSON在点击某个新城时再按需加载对应精细边界。5.5 现象ECharts报错“There is no map container named xixian”原因执行setOption时registerMap还没完成或者registerMap的地图名和setOption里的map名字拼写不一致。这个报错在ECharts 5里很常见因为registerMap是同步的但fetch是异步的如果fetch失败或路径错误registerMap不会执行接着setOption就找不到地图容器。解决确保fetch成功后再注册地图注册成功后再初始化。3.1节的async函数已经体现了这个顺序。但你可能会踩一个更深的坑同一页面多次调用registerMapECharts会使用最后一次注册的结果。比如你为了做下钻先注册了xixian后来又注册了一次xixian但用的是简化版JSON第二次就把第一次覆盖了地图上只剩轮廓。这时候要去代码里排查有没有重复的registerMap调用。另外如果你把GeoJSON直接写在script标签里作为全局变量要注册的名字必须和文件内容完全对应。还有个小细节echarts.registerMap(xixian, geoJson)里的名字是任意的但一旦用了这个名字后续所有setOption的map字段、geo的map字段都得同一个名字。别在一处用xixian_new_area另一处用xixian这种拼写不一致的坑我见得太多了。6. 进阶把这份GeoJSON变成你自己的数据可视化基础层到这里你已经能把一份西咸新区GeoJSON在ECharts里跑起来。最后这个进阶部分讲两个日常高频动作用geojson.io快速编辑以及让同一份JSON文件在ECharts折线图中联合使用的思路。6.1 用geojson.io快速编辑和导出geojson.io是一个在线编辑器直接把文件拖进去就能看到地图右侧是JSON代码。我常用它做两件事一是检查坐标顺序拖进去后看边界是否和底图吻合不吻合就立刻在代码里调换二是快速给某个要素改名比如把“空港”改成“空港新城”改完直接导出。导出时注意选GeoJSON格式不要选TopoJSON。TopoJSON体积更小但ECharts原生不支持需要额外的前端转换库不推荐在这个场景里折腾。6.2 在ECharts折线图里复用同一份地理数据很多人以为GeoJSON只能画地图其实ECharts的折线图line里也可以把地图作为背景。比如做一个各新城月度人口流入的折线图左边是地图右边是折线点击地图上的城区折线图切换成对应新城的月度数据。这不算什么新技术只是把geo和line组件放在同一个图表实例里chart.setOption({ geo: { map: xixian, left: 10, top: 10, width: 40% }, grid: { left: 55%, top: 50, width: 40% }, xAxis: { type: category, data: [1月, 2月, 3月, 4月] }, yAxis: { type: value }, series: [{ type: line, data: [10, 22, 28, 30] }] });点击地图时用chart.on(click)拿到城区名再更新series里的data就完成了图表联动。这里的核心思路地理边界数据是基础层业务数据放在另一个JSON数组里两者用name字段关联。同一份GeoJSON可以被地图、折线、散点图多个组件引用不用重复加载。6.3 打包发布时的文件组织建议最后留一个习惯项目目录里放一份带_raw后缀的原始GeoJSON再放一份简化版用于线上版本号写进文件名比如xixian_2025_v1_simplified.geojson。发布到nginx时确认JSON文件的Content-Type是application/json避免有些浏览器把.geojson当二进制文件处理。如果你要部署到CDN把GeoJSON传到CDN页面里用全量URL引用就没有跨域问题了。地理数据这种东西边界迟早会变行政区划调整一次地图文件就得换。所以别把JSON路径写死在代码里做一个版本管理接口让后端可以动态切换。我自己的做法是封装一个loadMapData(version)函数版本号作为参数每次更新只改配置不改代码这样换数据就像换皮肤一样轻松。希望帮到你。本文还有配套的精品资源点击获取
企业数字化 ERP 产品动态
相关推荐
室内人头检测数据集:927张带标签图像训练YOLOv8全流程解析 简介:这是一套面向YOLO系列算法研究与工程落地的室内人头检测数据集,适合目标检测初学者快速上手,也适合算法工程师做模型调优与验证。资源包含927张已标注图像,提供YOLO格式txt与VOC格式xml双套标签,分别存放… · 2026/9/26 19:13:41
江南为什么出才子?——从东晋南渡到明清科举 公元317年,建康城(今南京)的乌衣巷口,一群身着宽袍大袖的士人正匆匆走过。他们刚刚从洛阳、长安一路南逃,脚下是泥泞的江东小道,身后是沦陷的中原故土。人群中有一位名叫王导的琅琊王氏子弟,他不… · 2026/9/26 19:13:41
佛山口碑好的抬老人上下楼服务企业,广受信赖的靠谱商家汇总 老人上下楼出行难,广州本土专业服务商如何破局
老小区无电梯,老人出行到底有多难广州老城区里,不少建于上世纪八九十年代的住宅楼都没有安装电梯,对于行动不便的老人来说,上下楼成了生活里的头等难题。如果老人只是走路… · 2026/9/26 19:57:29
北京污水厂膜结构节能膜结构供应商推荐:靠谱商家测评排名 Q1:北京采购污水厂膜结构加盖,选供应商的时候最容易踩哪些坑?很多污水处理厂运营单位、市政水务采购人员第一次选膜结构加盖供应商,很容易只看报价不看工艺细节,最后出了问题找不到明确的责任方。市面上不少小商家会转包工程&… · 2026/9/26 19:57:29
告别套壳与适配:2026年开发者主流LLM聚合网关选型指南 在代码里分别引入OpenAI、Anthropic、Google的SDK,请求格式各异,光适配层就可能写数千行代码;换模型或加通道还要重构与回归测试——这是每个接过多家大模型的开发者都熬过的夜。聚合网关的方案优雅:统一接口地址与API Key&#x… · 2026/9/26 19:57:29
Atlas 300V 24G推理加速卡详解:从硬件定位到YOLO部署实战 “Atlas 300V 24G是运算加速卡吗?”——这个热搜问题我最近被问过不下十次,每次都是刚接触AI推理硬件的新人。既然标题就叫“atlas”,我今天就借着这波热度,把这台卡和它背后那套部署体系一次讲透。先说结论:Atlas 300… · 2026/9/26 19:57:29
15-03-工具-dotMemory与PerfView-生产环境内存分析 dotMemory 与 PerfView:生产环境内存分析 系列:C# 与常用数据结构源码剖析 实战工具篇 阅读时间:约 90 分钟 版本口径:dotMemory 2024.1、PerfView 3.1.x、.NET 8。界面菜单、命令行参数与 EventPipe 支持会变化,执行… · 2026/9/26 19:56:58
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍 简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践 一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46