2026/10/23 4:39:14

中国标准地图 WebGIS 实战:审图号核验、配准切片与 ECharts 避坑

中国标准地图 WebGIS 实战:审图号核验、配准切片与 ECharts 避坑 简介面向地图制图、地理信息教学与空间数据分析场景带审图号GS(2022)1873号的中国标准地图提供权威国境线与全国版图数据适合需要规范底图的学生、教师及GIS从业者使用。压缩包共14个文件、约584KB涵盖shp与shx空间几何及索引、dbf属性表、prj投影定义、cpg字符编码、json配置数据和qmd地图文档等类型形成从图形、属性到显示配置的完整结构便于在常见GIS软件中加载、查询与二次制图。已有475人学习或下载在底图核对、专题图制作和教学演示中具有一定参考度。使用者可获得标准化版图边界、要素属性与投影说明并完成地图配准、符号化展示和空间分析对于需要校验行政边界或制作规划图的用户也可减少来源甄别、编码与投影不匹配带来的返工。1. 一张被退回的大屏底图把审图号 GS(2022)1873 推到了台前去年帮某公司做一个区域业务的数据大屏地图那屏做完自认为挺像样深色底、发光边界、鼠标悬浮高亮。上线前内部过会被一句问住了——“这张中国地图的审图号在哪”再往下查更尴尬底图是从素材站下的 SVG界线画法和标准地图对不上还用 clip 把图幅下半截裁了。返工两轮最后换成中国标准地图、把审图号 GS(2022)1873号 老老实实落到图面上才过。这类问题跟审美无关跟“可追溯”有关。审图号是一串能查的编号它把一张具体的图图名、比例尺、投影、图幅范围、版本日期唯一地钉住GS(2022)1873 就是其中一份公开可下载的标准地图。后面几章讲的是我自己走过一遍的路怎么核这个号、怎么把这张图配准进 WebGIS、怎么在 ECharts 里用它做省级分布图、以及上线前用脚本卡一道。适合做数据大屏、报告插图、论文配图、内部 GIS 底图的人看新手能照着做做过的人也大概率会在第 5 章找到自己翻过的车。2. 审图号 GS(2022)1873 锁定了什么图名、比例尺与三份交付物2.1 从审图号里能读出什么、读不出什么先把字符串拆开看。GS(2022)1873号这种结构里前缀表示这是标准地图类审图号括号里的年份通常对应送审/批准的年份后面的流水号只是当年的序号。也就是说光看这串字符你读不出它画的是全国还是某个区域、比例尺是 1:4000 万还是 1:6000 万、投影是什么、图幅里有没有附图、注记是几号字——这些信息全在核验页面和下载包里不在编号本身。这一步是很多人跳过的。我见过不止一个项目把“GS(2022)1873”当成万能通行证底图换了、比例尺改了、甚至行政区划调整过一版了编号还挂着旧的。核验的时候我会固定抄六项下来图名、比例尺、投影、图幅范围、审图号、版本/更新日期。抄完存成一份元数据文件别只记在脑子里三个月后设计问你“这张图哪来的”你得答得出来。提示审图号和版本日期要分开记。审图号回答“这张图有没有经过审核”版本日期回答“这张图是不是现势的”两者缺一不可。还有一个容易踩的细节同一份标准地图往往提供多个比例尺版本比例尺不同界线概括程度、注记密度、附图大小都不一样。你从 1:6000 万的图上抠下来的省界放到 1:1000 万的大屏上放大三倍看锯齿和简化痕迹一目了然。选比例尺的经验是先算你最终出图的物理尺寸或像素宽度再倒推需要的比例尺别反过来。2.2 三种交付形态JPG、EPS、自己切片同一张标准地图落地到项目里通常有三种用法代价完全不同形态典型场景好处代价JPG/PNG 栅格报告插图、静态大屏、PPT开箱即用固定分辨率审图号已经印在图面上放大糊不能改配色改一个省的颜色得整张重做EPS/AI 矢量印刷出版、需要改配色和注记字号可编辑任意缩放不失真需要设计软件文件大误删界线风险高自己配准切片交互式 WebGIS、可缩放地图支持缩放漫游能和业务数据叠加要做配准、切片、坐标系对齐工作量最大选型上我一般按“输出介质”定而不是按“哪个看起来专业”定。一份要打印在 A4 报告里的插图JPG 完全够你上矢量纯属给自己找事一个要支持鼠标悬浮、下钻、联动的地图屏那必须切片。中间的模糊地带是“静态大屏但分辨率 4K”这种情况我倾向用高分辨率栅格导出时按 1.5 倍尺寸出而不是矢量因为大屏没人放大看细节但审图号那一行必须清楚——这一点矢量反而容易翻车见 2.3。EPS 的坑集中在“可编辑”这三个字上。标准地图的 EPS 里界线、面填充、注记、审图号文本经常在同一个图层组里取消分组之后很容易把某段界线当装饰线删掉更常见的是为了适配版面整体缩放 80%审图号字号跟着缩导出印刷时低于可读阈值。我的做法是EPS 只用来改填充色和注记位置界线图层锁死不动审图号单独提出来做成一个顶层文本对象跟图幅边框一起固定。2.3 别拿搜索引擎里那张 png 当底图这条几乎是我见过最贵的省事。搜“中国地图 png”出来的图来源五花八门有的是几年前的旧版、有的把图幅下方的附图裁掉了、有的审图号被水印盖住、还有的干脆就是别人二次描摹的界线。这些图在肉眼层面“看着都差不多”但一旦进了交付物问题就没法收敛——你既证明不了它对应哪个版本也定位不了哪一段界线画错了。更麻烦的是传播链。设计给的图是从运营那里拿的运营是从上一版 PPT 里抠的PPT 是外包做的。链条一长任何一次修改都变成“谁也不敢动”。所以只要有第二个人参与我就会在项目里搭一个底图资产库一个文件配一个 sidecar 元数据# assets/basemap/china-standard-2022-1873.yaml id: china-standard-2022-1873 name: 中国标准地图按核验页面填写图名 shen_tu_hao: GS(2022)1873号 source: 标准地图服务系统公开下载 fetched_at: 2024-03-11 scale: 按核验页面填写 # 不要凭印象抄页面 projection: 按核验页面填写 files: - china-2022-1873.jpg # 栅格报告插图用 - china-2022-1873.eps # 矢量印刷改色用 sha256: 用校验命令算出来的值 # 冻结用流水线里比对 notes: 图幅要素完整未做任何裁剪这份 sidecar 就是底图的“黑匣子”出问题时能倒查来源和获取时间sha256用来冻结版本任何人替换了文件流水线里的比对会直接报错。算哈希很简单# 记录底图指纹后续任何替换都会被发现 sha256sum assets/basemap/china-2022-1873.jpg # 只留前 16 位做人工核对也够用完整值写进 yaml参数说明就一句对二进制文件做哈希任何像素级改动都会变所以一旦冻结就不能“顺手美个图再存一遍”要改就换新 id。2.4 一张图选型的判断顺序把顺序理清楚比记工具名有用得多。我的顺序是定输出介质——屏幕、印刷、还是两者都要定是否需要交互——要缩放漫游就走切片否则一律栅格定坐标系——业务数据是什么坐标系底图就往上对齐不要两头都改最后才定分辨率和瓦片层级。多数翻车是把顺序做反了先挑工具比如“我要用矢量因为高级”再回头适配介质结果印刷丢字、大屏糊图。第 3 章开始就是第 2、3 步的具体操作。3. 把标准地图接进 WebGIS配准、偏移与瓦片的最小闭环3.1 先认清三套坐标WGS84、GCJ-02、BD-09交互地图上所有“整体飘了”的问题根子上都是这里。工程里常见三套坐标坐标常见来源与 WGS84 的关系典型误用WGS84GPS 原始数据、多数国际开源数据基准直接和国内底图叠加出现几百米偏移GCJ-02国内多数在线地图服务的展示坐标非线性偏移量级几百米当成 WGS84 用点位整体往一个方向偏BD-09部分地图服务在其基础上再偏移在 GCJ-02 上二次偏移与 GCJ-02 混用偏移叠加原则只有一条展示层统一到一套坐标转换只做一次位置固定在数据入口。我一般统一到 WGS84 展示把所有来源的经纬度在入库或出图前转成 WGS84底图也按 WGS84 配准。这样多源数据叠加时只需要排查一次。WGS84 转 GCJ-02 的实现到处都有公开版本下面是 Python 版保留它是为了让你看清结构import math A 6378245.0 # 椭球长半轴 EE 0.00669342162296594323 # 偏心率平方 def _dlat(x, y): r -100.0 2.0*x 3.0*y 0.2*y*y 0.1*x*y 0.2*math.sqrt(abs(x)) r (20.0*math.sin(6.0*x*math.pi) 20.0*math.sin(2.0*x*math.pi)) * 2.0/3.0 r (20.0*math.sin(y*math.pi) 40.0*math.sin(y/3.0*math.pi)) * 2.0/3.0 r (160.0*math.sin(y/12.0*math.pi) 320*math.sin(y*math.pi/30.0)) * 2.0/3.0 return r def _dlng(x, y): r 300.0 x 2.0*y 0.1*x*x 0.1*x*y 0.1*math.sqrt(abs(x)) r (20.0*math.sin(6.0*x*math.pi) 20.0*math.sin(2.0*x*math.pi)) * 2.0/3.0 r (20.0*math.sin(x*math.pi) 40.0*math.sin(x/3.0*math.pi)) * 2.0/3.0 r (150.0*math.sin(x/12.0*math.pi) 300.0*math.sin(x/30.0*math.pi)) * 2.0/3.0 return r def wgs84_to_gcj02(lng, lat): dlat _dlat(lng - 105.0, lat - 35.0) dlng _dlng(lng - 105.0, lat - 35.0) rad lat / 180.0 * math.pi magic 1 - EE * math.sin(rad) ** 2 sqrt_magic math.sqrt(magic) dlat (dlat * 180.0) / ((A * (1 - EE)) / (magic * sqrt_magic) * math.pi) dlng (dlng * 180.0) / (A / sqrt_magic * math.cos(rad) * math.pi) return lng dlng, lat dlat逻辑说明两个辅助函数算出的是弧度意义上的偏移量再用椭球参数换算成度。参数里105.0 / 35.0是公式的参考原点A和EE决定换算尺度改动它们等于换了一套椭球不要动。实际用法上有个纪律只做正向偏移用于图面叠加。有人问我能不能“转回去对齐”我的答复一律是别在这条路上找后悔药——工程上正确的做法是从数据源头统一坐标系或者在服务端存一份带坐标系标记的原始数据展示时再按目标坐标系出图。靠反复转换“凑对齐”偏移会越凑越大排查起来就是玄学。3.2 栅格配准给 JPG 补上地理参照标准地图的 JPG 是“图”不是“带坐标的数据”。要把它挂到地图上第一步是补地理参照。GDAL 的gdal_translate就够# 给无坐标的栅格补上地理参照左上角经度 纬度 右下角经度 纬度 gdal_translate \ -a_srs EPSG:4326 \ -a_ullr $XMIN $YMAX $XMAX $YMIN \ china-2022-1873.jpg china-2022-1873-geo.tif # 看一眼结果确认尺寸和范围没有反 gdalinfo china-2022-1873-geo.tif | head -20参数说明每个都值得停一下-a_srs EPSG:4326声明这份栅格用经纬度。注意它只是“声明”不改变像素所以四角必须和声明一致否则后面全错。-a_ullr的顺序是左上角经度、左上角纬度、右下角经度、右下角纬度不是常见的 xmin/ymin/xmax/ymax。这是第一次做配准时最常见的翻车点顺序错了图会上下或左右翻转。四角值从哪来优先从矢量版EPS的地理参照或图幅角点注记里读实在没有就在图上找两三个特征明显的地物点湖岸拐点、河口、图廓交点反推再用第三个点验证。验证方法是关键一步。配准完别急着切片先把这份 tif 拖进任意一个能显示底图的工具里叠一层已知坐标的点比如几个城市的经纬度看残差。我的容忍线是在目标最大缩放层级下误差不超过 1 个像素。超过就回去查四角——八成是-a_ullr顺序错了或者图幅带了白边没裁。补一句白边的事标准地图导出时常带一圈白边或图廓装饰线这些不属于地理范围。用gdal_translate -srcwin先裁掉再配准比配准完再去修边界省事得多。3.3 用 gdal2tiles 出瓦片并用 Leaflet 挂上去配准好的 tif 可以直接切瓦片。Web Mercator 是默认选择因为绝大多数前端地图库都按它算# 切 XYZ 瓦片层级按图幅宽度估算最小层级 ≈ log2(图幅像素宽 / 256) gdal2tiles.py -p mercator -z 3-7 --xyz --tilesize256 \ china-2022-1873-geo.tif ./tiles/china1873参数说明-p mercator输出 Web Mercator前端可以直接用。-z 3-7层级范围。下限按“整幅图刚好铺满一屏”算上限按“审图号文字还清楚”算。层级开太高只会让栅格糊成一片还白占磁盘。--xyz输出 XYZ 命名y 轴从上往下。不加这个参数出来的是 TMSy 轴从下往上前端直接引用会上下颠倒——这是第 5 章要展开的一个坑。--tilesize256和前端默认瓦片尺寸对齐别乱改。前端用 Leaflet 挂载注意maxNativeZoom和 attribution 两处const map L.map(map, { minZoom: 3, maxZoom: 10, zoomControl: true, attributionControl: true }); L.tileLayer(/tiles/china1873/{z}/{x}/{y}.png, { minZoom: 3, maxZoom: 10, maxNativeZoom: 7, // 真实瓦片只到 7 级再放大是拉伸不是新数据 noWrap: true, // 禁止横向环绕避免出现重复图幅 attribution: 底图中国标准地图 审图号 GS(2022)1873号 }).addTo(map);maxNativeZoom是最容易被忽略的一个参数。不设它用户放大到 10 级时浏览器会去请求不存在的 8、9、10 级瓦片一片空白设了它Leaflet 会拿 7 级的瓦片放大显示虽然糊但连续。noWrap: true同理关掉横向循环世界地图在大屏上往左拖不会出现第二份图幅。attribution这一行不是装饰。审图号在图面上必须有位置交互地图里最省事、最不容易被后续改动弄丢的位置就是它——它跟着地图容器走不会因为某个业务图层重绘而消失。3.4 审图号在图面上的落位与最小可读尺寸不同介质对“可读”的要求差很多。下面这张表是我自己项目里在用的经验值不是条文按实际版面微调介质建议位置最小字号/高度补充网页交互图地图容器右下角 attribution12px跟随容器不随图层重绘丢失静态导出 PNG1920 宽图幅右下角内侧留 8px 边距14px导出后 100% 缩放要能辨认印刷 A4 插图图幅下方居中或右下角不小于图面短边的 1/60与图廓留白不与图例挤在一起4K 大屏右下角距边 24px20px 以上深色底上要用浅灰别用纯白晃眼两个实践细节。第一别把审图号放在图幅外面又指望它出现在导出图里——Canvas 导出只截画布区域画布外的 HTML 元素不会被带上这是第 4 章要专门处理的问题。第二深色主题下审图号的对比度要单独验一遍我吃过一次亏在 4K 屏上肉眼可见投到会议室的投影仪上就成了一条灰线。4. ECharts 省级分布图边界裁剪、registerMap 与截图里的审图号4.1 边界数据的三条来路与取舍ECharts 从 5 版起不再随包提供地图数据GeoJSON 得自己准备。常见的三条来路来路精度工作量风险从标准地图 EPS 里提取界线高与底图同源大需要矢量编辑提取时误删要素权威公开的边界数据中到高中需核对版本版本与底图不一致第三方简化/美化版低小界线画法与标准地图有出入附图常缺我的选择是第二条为主、第一条做校验用公开边界数据出图再和标准地图做一次目视比对重点看省界走向、飞地、附图要素是否完整。第一条的完整提取成本太高只在印刷级交付时才做。第三条我基本不用省下来的两小时后面返工要还回去两天。比对这件事别凭印象做个笨办法把标准地图底图铺在下面GeoJSON 描边叠在上面同一比例尺下截一张图逐段扫一遍。有出入的地方记下来别急着“修一下”——地图边界不能自己描出入大就换数据源。4.2 用 mapshaper 裁剪与瘦身原始边界数据往往几十兆直接扔给前端会拖慢首屏。mapshaper 是命令行里最好用的一个先做裁剪和简化# 1) 只保留需要的区域按属性字段过滤 mapshaper china-full.geojson \ -filter adcode 100000 \ -o precision0.0001 formatgeojson china-filtered.geojson # 2) 按矩形范围裁剪xmin,ymin,xmax,ymax做区域专题图时用 mapshaper china-filtered.geojson \ -clip bbox$XMIN,$YMIN,$XMAX,$YMAX \ -o precision0.0001 china-clip.geojson # 3) 拓扑保持的简化keep-shapes 防止小要素被抹掉 mapshaper china-clip.geojson \ -simplify 12% keep-shapes \ -o precision0.0001 formatgeojson china-slim.geojson参数说明-filter里的表达式按属性字段做布尔判断字段名要和你数据里的实际字段对齐写错不会报错只会静默输出空文件——所以每步之后都mapshaper xxx.geojson -info看一眼要素数量。-simplify 12%是保留顶点比例。12% 通常能把体积压到原来的十分之一同时省界还看得过去低于 5% 就开始出现折角。keep-shapes必须加否则面积小的要素会被整块删掉地图上出现空洞。-clip bbox的四个值是 xmin,ymin,xmax,ymax。裁剪会切开边界多边形如果要做面填充记得后面用-dissolve按目标字段合并。-o precision0.0001控制坐标保留位数约 11 米精度对省级分布图足够能再省一截体积。简化完必须做一次拓扑检查相邻省之间不能出现缝隙。mapshaper 默认保持拓扑但你一旦混用了多个来源的数据缝隙就出来了。快速检查的办法是把填充色设成半透明缝隙会以底色的细线形式暴露——这招比写脚本快。4.3 registerMap 与 option 里三个必调项数据准备好注册和配置就几行// geoJson 由 fetch 或本地 import 得到 echarts.registerMap(china-std, geoJson); const option { geo: { map: china-std, roam: true, // 允许缩放漫游 aspectScale: 0.85, // 见下方说明别用默认值瞎猜 itemStyle: { areaColor: #0e1a2b, borderColor: #3a5b8c }, emphasis: { itemStyle: { areaColor: #1b3a63 } } }, series: [{ type: map, map: china-std, geoIndex: 0, // 与上面的 geo 共用一套投影和缩放 data: valueList // [{name:某省, value:123}, ...] }], visualMap: { min: 0, max: 5000, calculable: true, inRange: { color: [#123, #2a6, #8fd] } } };三个必调项aspectScale地图的横纵比缩放系数。默认 0.75很多模板照抄不改结果整张图被压扁形状一眼不对。全国图我一般用 0.85 左右具体值以“和标准地图目视一致”为准别背数字。geoIndexseries.typemap和geo组件同时存在时靠这个把两者绑在一起不绑会出现两份重叠的地图交互事件只命中其中一份。roam允许缩放漫游时要配合zoom上限否则用户能缩到边界数据精度之外省界变成一堆折线。name字段要和 GeoJSON 里的属性名一一对应对不上就是一片空白加控制台无提示——这是 ECharts 地图最典型的静默失败。4.4 导出图片里审图号怎么保住大屏截图、报告配图基本都走toolbox.saveAsImage或直接对 canvastoDataURL。这里有个硬约束Canvas 导出只截画布内的内容。你把审图号写在地图容器外的一个div里或者写在地图下方的 HTML 说明区导出的 PNG 里就没有它。解决办法是把审图号画进画布用graphic组件定位在右下角graphic: [{ type: text, right: 14, bottom: 12, silent: true, // 不参与交互避免遮挡地图事件 style: { text: 审图号GS(2022)1873号, font: 14px sans-serif, fill: rgba(200,210,225,0.9) // 深色底用浅灰别用纯白 }, z: 100 // 压在图层之上 }]silent: true很关键不加的话这块文字会吃掉鼠标事件用户在地图右下角悬浮时高亮失效排查起来很费时间。z要给足否则在某些渲染顺序下会被 visualMap 的图例盖住。导出之后还有一步把 PNG 拉回 100% 缩放看审图号那行字是不是真的能认。我见过太多“代码里写了、图上也有、但导出后糊成一团”的案例尤其在 2 倍像素比的屏上做的图导出到 1 倍时字号直接减半。5. 避坑与排查底图上线前最常翻车的 5 个点5.1 点位整体往一个方向偏几百米现象业务点位和底图叠在一起所有点统一往东南或西北偏一段距离形状没变形只是整体平移。原因坐标系混用。底图是按 WGS84 配准的业务数据来自某个返回 GCJ-02 的接口两者直接叠加就是这个结果。偏移量随经纬度变化所以看起来“有的地方偏得多、有的地方偏得少”很像玄学其实完全可复现。解决在数据入口统一转换别在渲染层修。做法是把所有外部来源的经纬度在入库时转成 WGS84并给数据表加一列标记原始坐标系转换只在入库那一步发生。已经混了的存量数据按来源分批重跑一次转换不要写“渲染时按图层判断要不要转”这种逻辑——那个分支迟早会被人改错。5.2 瓦片上下颠倒或者整体错开一屏现象底图加载出来了但南北颠倒或者和点位错开正好一个屏幕高度。原因TMS 和 XYZ 的 y 轴方向相反。gdal2tiles.py不加--xyz输出的是 TMS 命名前端 Leaflet 默认按 XYZ 请求第 0 级就一格错不开层级一高错位量正好是一个屏幕。BD-09 那套东西如果混进来还会有额外的缩放层级偏移现象类似但成因不同。解决切瓦片时统一加--xyz如果瓦片是别人给的、改不了就在前端 URL 模板里用{-y}让 Leaflet 自己换算。判断方法很简单打开tiles/0/0/0.png看它是不是全球一张图再打开tiles/1/0/0.png和tiles/1/0/1.png谁在上面就是谁的方向。5.3 导出的大屏截图里审图号消失了现象页面上明明有审图号导出的 PNG 里没有。原因审图号写在地图 canvas 之外的 DOM 里saveAsImage和toDataURL都只截 canvas 区域。另一种情况是用了html2canvas之类整页截图但地图是 WebGL 渲染的截出来一片空白。解决审图号用graphic画进 canvas见 4.4或者导出后做二次合成——拿到 canvas 的 dataURL再用一个离屏 canvas 把审图号文字画到右下角最后一起输出。第二种更稳但要注意字体加载完成后再画否则会 fallback 成默认字体字号宽度全变。加一条自检导出图宽度小于 1920 时直接告警小图上的审图号基本不可读。5.4 EPS 转曲之后审图号既搜不到也改不了现象印刷交付前把文字转成曲线之后想改审图号——文本已经变成路径逐节点编辑做自检脚本时也检索不到这段文字。原因转曲是不可逆操作。很多排版流程默认“交付前全部转曲”但地图类图幅里的审图号属于标识信息转曲之后既失去了语义也失去了校验手段。解决流程上分两份——一份保留文本层的可编辑母版一份是转曲后的印刷稿母版永远不进交付物只用来出下一版。同时在 sidecar 元数据里记死审图号字符串自检脚本查元数据而不是查图面文字。印刷前再目视确认一次转曲稿里那行字的字重和字距没被压缩。5.5 简化过头小要素消失、省界出现缝现象地图上少了几块小区域或者两个相邻省份之间出现一条细缝放大看是底色透出来。原因-simplify比例给太低又没有keep-shapes面积小的多边形被整块删掉多个来源的数据混合简化时拓扑被破坏公共边界两侧的顶点不再重合缝隙就是这么来的。解决简化比例从 20% 起试逐步降到能接受的最小值每降一档跑一次要素数量比对永远带keep-shapes混源数据先合并再简化不要分别简化后拼接。验证用半透明填充看缝比写脚本快。这一步没有捷径只能一档一档试出来。6. 把审图号变成流水线卡口一份导出前的自检脚本上面那些坑靠人盯是盯不住的。我的做法是在出图流水线里加一步自检跑不过就不出包。脚本不长但把最容易丢的几件事都卡住了import hashlib, sys from PIL import Image def sha256(path): h hashlib.sha256() with open(path, rb) as f: for chunk in iter(lambda: f.read(1 20), b): h.update(chunk) return h.hexdigest() def check_export(png, sid, frozen_sha, min_w1920): errs [] img Image.open(png).convert(RGB) w, h img.size # 1) 尺寸太小审图号必然糊 if w min_w: errs.append(f导出宽度 {w} {min_w}) # 2) 审图号必须写进 PNG 元数据而不是只存在前端 DOM 里 if img.info.get(shen_tu_hao) ! sid: errs.append(PNG 元数据缺审图号) # 3) 右下角区域对比度粗检全白/全黑说明文字没画上或被裁掉 crop img.crop((int(w*0.72), int(h*0.88), w, h)).convert(L) lo, hi crop.getextrema() if hi - lo 40: errs.append(右下角对比度过低审图号疑似未渲染) # 4) 与冻结版本比对防止底图被悄悄换掉 if sha256(png) ! frozen_sha: errs.append(导出图与冻结版本不一致) return errs if __name__ __main__: problems check_export(sys.argv[1], GS(2022)1873号, sys.argv[2]) print(\n.join(problems) or checks passed) sys.exit(1 if problems else 0)四项检查对应四类事故尺寸检查拦“大屏糊图”元数据检查拦“审图号只写在前端”对比度粗检拦“graphic 没渲染上”哈希比对拦“底图被替换”。第三项是粗检不是 OCR它只回答“这块区域有没有东西”不回答“这行字对不对”——要精确校验文字还是得靠元数据那一条。检查项拦什么误报率出了误报怎么办导出宽度小图糊字低调阈值别关检查元数据审图号漏写字样极低检查导出时的 pnginfo 写入右下角对比度文字未渲染中有图例挡右下角时改采样区域哈希比对底图被换零换底图就更新冻结值走一次评审最后说个习惯。我现在的项目里底图目录是只读的替换底图要走一次变更更新 sidecar、重算哈希、重跑一次目视比对、把审图号写进发布说明。麻烦但换来的是任何一张出去的地图都能在三分钟内答清楚“这张图哪来的、什么版本、审图号是多少”。地图这东西画错一条线可能没人发现但一旦被发现返工的不是一张图是这一版所有的交付物。希望帮到你。本文还有配套的精品资源点击获取