前阵子处理了一个挺典型的Web GIS问题数据在ArcGIS Pro里配好图标注清清晰晰发布成VTPK矢量切片包挂到Web端一看面、线、点都在偏偏那一层层的文字标注全没了。业务方第一反应是“你数据不对”一查数据没问题问题出在整个VTPK链路中的某一个环节上。这个坑其实很常见而且往往不是单一原因涉及Pro制图配置、VTPK产物结构、Server发布状态和前端渲染四个层面。这次把这套排查思路和实操方法完整整理出来给后面做矢量切片标注的人留一份参考。1. 先搞清楚VTPK的标注链路问题到底断在哪里1.1 标注在矢量切片里到底变成了什么很多人对VTPK有误解以为它就是把瓦片图片切出来前端拿到图片直接贴上去。实际上矢量切片传输的是压缩后的矢量要素数据和属性字段渲染完全在前端完成。标注在VTPK里并不是一串独立的文字而是被处理成带文本属性的要素层每个标注点/线/面会携带文本内容、字号、字体、锚点偏移、最大宽度等字段前端渲染引擎读取这些字段后动态画出文字。换句话说VTPK的STYLE里必须有一个类型为symbol、并且配置了text-field的图层前端才能显示标注。这个机制被很多人忽略所以排查总在CSS、接口、权限上打转绕了大半天才发现VTPK本身就没什么可显示的。要解决标注不显示问题第一要务是建立一条清晰的链路观念Pro客户端里的标注配置通过什么方式进入VTPK又通过什么方式被Web端读取。1.2 四个环节的排查顺序我的习惯是把整个链条切成四段来看数据源制图阶段、VTPK打包阶段、Server发布阶段、Web端渲染阶段。标注最终不显示一定是这四个环节中至少有一个断了。常见的断点很典型要么Pro里的Label Class没配好或没勾选“包含标注”要么VTPK里压根没有text层要么Server端的style.json是旧缓存要么前端把有标注的图层压到了底图下面。排查顺序我建议从源头往末端走也就是先确认VTPK是不是真的有标注要素再去看Server返回的style对不对最后才怀疑前端代码。因为越靠上游的问题影响面越大你前端调了一晚上代码结果发现包里没有标注层那就白折腾了。从实用角度讲最直接的手段是解压VTPK验证内部结构这一步能过滤掉90%的低级问题。另外要注意一点VTPK在Pro里生成时标注的放置几何是“烤”进切片里的它不像动态图层一样能重新计算。所以Pro里看到的标注和Web端未必完全一样因为Pro的标注引擎尤其是Maplex在充分的屏幕上能排布得很好而Web端还要经过Mapbox GL等引擎的碰撞检测。如果只是“部分标注缺失”而不是“全部都不显示”那大概率就是这种渲染差异后面我会专门讲。2. 源头排查异常出在ArcGIS Pro制作阶段2.1 第一步确认是否勾选了“标注此图层中的要素”听起来像废话但实际项目中次数最多的翻车原因就是这里。数据在ArcGIS Pro里套了个很酷的符号系统图层名也起得挺漂亮但右键图层时“Label”选项卡没有打勾标注根本没启用。VTPK打包工具可聪明得很你没启用标注它就压根不会把标注生成到切片里也不报错。还有一个类似的坑用的是“注记Annotation”而不是“标注Label”。ArcMap时代很多人习惯把注记转出来存在要素类里到了Pro里继续沿用这套思路。VTPK对动态标注Label的原生转换做得比较好对于注记要素层如果你没有特意把注记作为要素图层勾选进切片包它就很可能被漏掉。即便勾进去了注记的字体符号样式在Web端也容易因为字体缺失而变成乱码或消失。所以排查时先到Pro里做两件事看图层是否启用了标注看是否有未被包含的注记子图层。这一步5分钟就能排除掉最大的可能性。2.2 Label Class的可见比例范围不敢随便设这是很多人知道但不够重视的配置项。Pro里的每条Label Class都带一个Scale Range默认是“Auto”也就是和图层本身的可见范围联动。但有些人为了出图美观手动把标注的可见范围锁定在一个很窄的比例尺区间比如只在1:500到1:2000之间显示道路名。这个设置会被原封不动写进VTPK你在Web端如果缩放到1:1万级别标注铁定看不到用户还以为是丢了。我遇到过最经典的一个案例一个地块权属项目图层只有标注范围设在1:500以内业务方在Web端打开后第一屏是全县视图标题栏空荡荡的点开地块信息又能看到属性里有名称就是图上没字。最后在Pro里打开标注属性发现Scale Range里清清楚楚写着最小1:500最大1:2000。把范围改成按图层可见范围联动后问题直接消失。这里要提醒一点改Scale Range后必须重新生成VTPK并重新发布因为标注可见范围是烘焙进切片包里的不是在Server端运行时过滤的。2.3 导出VTPK时最容易忽略的“包含标注”选项很多新手用“共享为Web图层”或者“创建矢量切片包”工具时一路点根到底根本不知道界面上还有个标注选项。在ArcGIS Pro的“创建矢量切片包”工具里输入地图、切片方案、参考比例、最大切片级别这几个参数好找但要不要把标注一起压进去往往藏在图层级别的设置中。如果用的是“共享为Web图层”向导里通常会有一步列出“图层和标注”的面板每个图层右侧有一个包含标注的开关默认是开的但如果你中途某些图层没加载出来或者人为关掉了那个开关发布出来就是没有标注的包。参考比例Reference Scale也是个关键角色。它决定标注在各缩放级别下的尺寸换算关系直接影响了字在屏幕上看起来多大。我见过有人把参考比例设成了1:50Web端放大到16级才能勉强看到芝麻大的字客户以为没标注。通常的建议是参考比例接近业务主要使用的比例尺例如道路标注用1:5000建筑注记用1:1000或1:2000做完先在本级预览一下再往下走。如果在Pro里做完这些检查重新打包发布Web端还是没标注那就进入下一步直接解剖VTPK本身。3. 发布端验证VTPK内部结构说了算3.1 把VTPK解压直接看style.json里的文字图层VTPK本质上是一个zip压缩包别被它的扩展名唬住。你完全可以用7-Zip或任意压缩软件把它解开看里面的目录结构。常见结构大致是这样的包名.vtpk ├─ pth/ ├─ resources/ │ ├─ styles/ │ │ └─ root.json │ ├─ fonts/ │ └─ sprites/ └─ tiles/最关键的文件是resources/styles/root.json它就是Web端矢量图层渲染的样式定义。用文本编辑器打开搜索text-field或者text这类的关键字如果有对应图层说明标注已经成功打进了包。如果搜不到说明Pro那边压根没生成标注层回到第二章继续排查就对了。我经常在Windows上这么做7z x 道路标注.vtpk -oD:/temp/vtpk_extract解压完直接打开root.jsonCtrlF搜索“text-field”。如果能看到类似{ id: RoadLabel, type: symbol, source-layer: RoadLabel, layout: { text-field: {Name}, text-size: 12 } }那我就可以放心地告诉业务方标注已经进包了问题在前端或发布端。这个检查方法特别适合“数据一堆、说明不清、锅到处飞”的扯皮现场谁都不用争文件摆在那一看就知道谁背锅。3.2 通过REST端检查Server返回的样式如果VTPK已经成功发布到ArcGIS Server你可以直接在浏览器里访问服务REST端点把resources/styles/root.json这个地址拉出来看看。这一步对比解压文件更有意义因为它看到的是Server实际提供给前端的内容。例如服务的完整URL是http://你的服务器:6080/arcgis/rest/services/Test/VTPK/VectorTileServer/resources/styles/root.json在浏览器里打开或者用IDEA、VS Code的HTTP工具去拉检查里面的layers数组。特别注意有时VTPK文件没问题但发布过程走的是旧缓存或者Server端使用旧的样式文件也会造成Web端不显示。遇到这种事我会在Server管理控制台下停止服务清理切片缓存再启动服务让VTPK重新解析一次。此外要检查Server的Sharing——如果服务被限制为私有只有内网用户可以访问外部环境加载不到资源同样等于不显示。这一层虽然不算纯技术故障但我在现场是真遇到过测试机器能打开客户笔记本却白屏一查是服务未被共享、跨域访问没配置前端请求被浏览器CORS拦掉了。所以发布后别急着写代码先用浏览器直接访问style.json确认能正常返回JSON再往下做。3.3 图层叠加顺序和样式覆盖的坑发布端的问题不全在样式文件本身还涉及图层叠加顺序。矢量切片包里的样式会按root.json里定义的图层顺序渲染先画的在底层后画的上层。如果标注层被定义在不透明填充层之前文字就会被填色图层压住看起来像没有标注。我在实际项目中见过一个很隐蔽的例子切包的时候地块面的填充色是纯色不透明标注层的顺序恰好排在它后面。在Pro里因为标注是动态绘制在最上面的看不出问题发布成VTPK后前端严格按样式顺序渲染标注就被底下的地块填色整个盖住了悲惨的是用户看到的还是一整块地没什么异常就是没文字。排查方法很简单在root.json里调整标注层的order让它排到需要压盖的图层后面。如果你用的是ArcGIS JS API也可以通过VectorTileLayer的loadStyle方法重写style手动调整图层顺序。4. Web端渲染前端代码和抓包工具怎么查4.1 用ArcGIS JS API写一个最小验证实例后端查完了包也确认有标注层接下来才轮到前端。我强烈建议先写一个最朴素的加载demo不带任何业务逻辑、不叠加业务图层、不做高级控制直接加载这个矢量切片服务看标注显示不显示。require([ esri/Map, esri/views/MapView, esri/layers/VectorTileLayer ], function (Map, MapView, VectorTileLayer) { const layer new VectorTileLayer({ url: http://你的服务器:6080/arcgis/rest/services/Test/VTPK/VectorTileServer }); const map new Map({ basemap: gray-vector, layers: [layer] }); const view new MapView({ container: viewDiv, map: map, center: [116.39, 39.92], zoom: 14 }); });这段代码如果标注能出现说明服务和数据都没问题问题100%出在生产环境的业务代码里。如果这段代码都不显示那就要回到第三章去确认style.json是否真的返回了带text-field的图层。这种“最小复现”的思路在GIS前端排错中非常高效它能把问题的责任范围一下子砍到只剩两个变量数据和渲染。还有个小细节如果你用的是Mapbox GL JS而不是ArcGIS JS API加载VTPK服务一般会用ArcGIS的style URL初始化map。这时要注意ArcGIS生成的style中某些写法在Mapbox GL的老版本里解析异常导致symbol图层被悄悄跳过。建议至少用Mapbox GL JS v2以上的版本或者直接用ArcGIS JS API 4.x系列对VTPK的标准样式兼容性更稳。4.2 网络抓包定位数据是否返回了文本字段有些时候服务端确实返回了带标注的样式和切片但标注还是不显示这就发生在数据传输或请求环节。利用浏览器开发者工具的Network面板筛选出.pbf或者vector-tile请求点击查看响应内容确认返回的数据里有没有标注元素。如果响应里根本没有对应的文本要素那么问题很可能出在切片包的某一层没有被正确请求或者前端请求的layer ID与服务端定义的source-layer不一致。这里顺便说一句抓包工具的选择。浏览器F12已经完全够用我大多数时候只靠Network面板就能定位问题。如果非要上代理抓包工具比如Fiddler、Charles这类也能做到同样的效果但对GIS从业者来说日常排查用不上那么重的东西反而多一道代理配置的坑。当你发现Web端请求量异常少比如打开地图时一个pbf都没发那就要考虑是不是底色裁剪范围设错了前端View里加载的extent和服务默认切图范围重叠区域为零这种情况下标注自然一个都出不来。如果别人机器能显示、你机器不显示优先考虑浏览器缓存。F12里勾选Disable cache强制刷新一遍大概率能救回来。VTPK的style.json会被很多浏览器当作静态资源缓存服务端更新了旧样式但本地还是拿着几小时前的老json在渲染。4.3 图层顺序与过滤条件导致的“看不见”业务代码里的图层顺序对标注可见度影响巨大。ArcGIS JS API中Map实例的layers是一个有序集合后添加的图层渲染在上层。如果标注图层先被添加随后又添加了一个全屏半透明遮罩面图层那标注就被压在下面了。遇到这种情况不要怀疑数据和包用view.goTo去看一眼源码把业务图层normalize一下就解决。还有一种情况是图层过滤条件。有人使用MapImageLayer或者FeatureLayer叠加其中某些查询条件把文本属性给滤掉了。比如前端代码里用了layer.definitionExpression NAME IS NOT NULL;结果数据源里头NAME字段在小比例尺下本来就是空值等到放大到17级才有名称用户当然觉得标注不显示。这种问题我称之为“等级化消失”——不是标注没了是某个级别下属性为空。解决方法是前端表达式放宽条件或者调整VTPK的标注配置让它在所有级别都有兜底文本值。还有一个很常见的分歧点地图软件在低缩放级别时会为了性能或清晰度主动隐藏部分标注例如三级标题只有在16级以上才显示。这在Mapbox GL里叫collision detection一旦文本发生重叠后面的标注就让位给前面的。如果你发现Web端缩放放大后标注逐渐出现而缩小后大片标注消失属于正常的消隐行为。但如果业务要求无论怎么缩放都显示那就得手动改style给symbol图层加layout: { text-allow-overlap: true, symbol-placement: point }这种处理虽然会让画面略显拥挤但至少解决了“一个不显示”的抱怨。5. 实战速查表与避坑心得5.1 高频故障对照表下面这张表是我这些年处理这类问题总结的高频故障速查表不一定100%覆盖所有环境但针对ArcGIS体系下的VTPK基本够用现象可能根因快速验证解决办法所有标注完全不显示VTPK未包含标注层解压查root.json无text-fieldPro中勾选包含标注重新打包发布大级别能看到小级别无文字Label Class的Scale Range限制过小Pro中查看标注属性范围的设置把范围设为“自动”或按层级放宽文字变成了方块/乱码字体未嵌入或字体缺失看Server端fonts资源里是否有字体文件改用常见系统字体如宋体、微软雅黑部分标注始终不出现Maplex冲突消隐或前端碰撞检测放大缩放观察文字是否出现调整参考比例或允许文字重叠标注被一块颜色压住图层顺序不对检查root.json和前端layers顺序调整图层顺序或给填充层加透明度预览正常外部打不开服务未共享或CORS配置缺失浏览器直接访问style.json发布为共享服务配置跨域规则一直显示旧数据浏览器缓存 / Server缓存F12禁用缓存刷新清理浏览器缓存Server端重启清缓存这张表要怎么用建议第一列先对照现象第二列锁定嫌疑环节再用第三列的快速验证手段去确认。不要跳过验证直接改配置很多时候你改了半天发现根本不是那个原因。5.2 几条实操建议参考比例别乱填。我在做道路方案时参考比例就设1:5000字写在图上看起来舒服发布到Web端用14级能看放到16级也不失真。如果你对着一个1:500地块分户图做切片参考比例设1:5000放大到顶后字会偏小小到你以为没标注。参考比例和标注显示有着直接关系它本质上告诉前端字号应该按照哪个比例尺来缩放。字体选择要稳重。ArcGIS Pro里可以随便配字体包括你刚下载的炫酷第三方字体但VTPK打包时不是所有字体都能合法嵌入。一旦字体无法嵌入Web端会静默降级或干脆不渲染。做标注时一句话能用系统字体就别用自定义字体。我项目中用微软雅黑和黑体从没出过问题宋体偶尔遇到字重变化但也比第三方字体稳定。标识是否“全量显示”要提前设计好。如果业务方坚持所有标注都要显示哪怕重叠也要显示那么在Pro里就要设置Maplex的“冲突解决”和“允许压盖”。如果你不做这个设置Maplex已经悄悄把400条标注里的150条认为“放不下”而不生成到切片里前端再怎么调collision detection也救不回来。因为那些标注根本没有进入VTPK前端拿到的是缺漏后的数据。这一点经常被误解成前端问题但实际上数据从源端就已经缺了。最后再分享一个小技巧每一次改完Pro配置后别急着发布到正式服务器。先在本地导出VTPK解压看一次root.json确认text层存在并且source-layer名称和预期的图层能对上然后再走发布流程。发现标注不见了就用“解压看包”“浏览器开style.json”“最小demo加载”这三板斧依次验证。只要按这个顺序走一遍大多数标注消失案都能在一个小时内定位到真正的断点不会在没有任何产出证据的情况下反复试错。
