简介这份资源提供了一套可发布 ArcGIS 瓦片的 GeoServer 部署包面向需要将 ArcGIS 切片服务迁移或发布到开源 GIS 平台的开发者与运维人员尤其适合具备一定 GIS 基础、希望摆脱商业软件依赖的技术人员。压缩包共 1571 个文件约 137.36MB以 310 个 jar 依赖库、250 个 xml 配置、731 个 png 切片图片为主同时包含 sld 样式、prj 投影、shp/dbf/shx 矢量数据、pgw 坐标文件及 bat/sh 启动脚本覆盖服务运行所需的完整组件。资源中附带日志、配置与示例数据可帮助读者快速理解 GeoServer 发布 ArcGIS 瓦片的目录组织与参数设置对照排查切片路径、坐标系与样式匹配等常见问题。目前已有 1089 人学习下载适合作为搭建瓦片服务、迁移切片方案时的参考包。1. 发布 ArcGIS 瓦片这件事GeoServer 到底能不能接住手里有一套 ArcGIS 切好的瓦片散在_alllayers目录里或者干脆是别人丢过来一个几百 GB 的切片包业务侧又要求走标准 OGC 服务对外发布——这个场景在国内做 GIS 集成的团队里太常见了。GeoServer 本身不直接吃 ArcGIS 的松散瓦片目录但它提供了 GeoWebCache 这套缓存与瓦片服务框架配合GeoServerTileLayer的配置能力可以把预切好的瓦片挂进来以 WMTS 或 TMS 的形式对外发布。核心思路不是“让 GeoServer 重新切一遍”而是“让 GeoServer 认识你已有的瓦片目录结构并把它当成自己的缓存来用”。这条路适合两类人一类是手上有历史 ArcGIS 切片资产、不想重新跑一遍切图任务的运维和集成工程师另一类是需要在同一套 GeoServer 里同时发布矢量 WMS 和已有栅格瓦片、做统一服务出口的开发者。它解决的是资产复用问题不是切图性能问题。下面按“先搞懂瓦片目录结构 → 再配 GeoServer 挂载 → 再排坑 → 最后做验证和进阶”的顺序讲透。2. 先搞懂 ArcGIS 瓦片目录结构对不上后面全白搭2.1 ArcGIS 切片目录的两种常见形态ArcGIS 切出来的瓦片落地形态主要有两种。第一种是松散型目录典型结构是根目录下有一个conf.xml或conf.cdi然后按级别分文件夹每个级别下再按行列号分子目录L00/ R00000000/ C00000000.png C00000001.png L01/ R00000000/ C00000000.png第二种是打包型瓦片被塞进.bundle文件里配合.bundlx索引文件。GeoServer 的 GeoWebCache 对松散型目录支持最直接打包型需要先解包或者借助额外转换步骤。我一般建议先确认目录形态再决定后续路线因为打包型直接挂载基本走不通。判断方法很简单进到瓦片根目录看有没有L00这种级别目录以及级别目录下是R开头的行目录还是.bundle文件。松散型目录里行列号的位数是固定的常见是 8 位比如R0000000a、C0000000f这里用的是十六进制。这个细节很关键因为 GeoWebCache 在挂载时对行列号的解析方式和你目录里的命名规则必须对齐否则会出现“服务起来了但瓦片全是空白”的经典翻车现场。2.2 瓦片方案参数分辨率、范围、坐标系三件套ArcGIS 切片时选定的切片方案Tiling Scheme决定了瓦片的层级分辨率、坐标范围和空间参考。这三项如果和 GeoServer 侧配置不一致瓦片就对不上位置。常见方案是 Web MercatorEPSG:3857和地理坐标系EPSG:4326两种国内项目里 3857 占多数。你需要从 ArcGIS 侧的切片方案文件里拿到几个关键值每级分辨率Resolution、瓦片尺寸通常是 256×256、原点坐标Origin、以及全范围Full Extent。这些值在conf.xml里通常能找到或者从切片时的.xml方案文件里读。GeoServer 挂载时GridSet 的配置必须和这些值逐项对齐差一个小数点都会导致瓦片偏移。提示如果拿不到原始切片方案文件可以从瓦片目录反推。级别目录的数量对应缩放级数行列号的最大值结合瓦片尺寸可以反推范围但分辨率需要结合原点推算容易出错优先找原始方案文件。2.3 为什么不能直接把瓦片目录丢进 GeoServer 数据目录有人会想GeoServer 的 GeoWebCache 缓存目录也是按级别和行列号存的直接把 ArcGIS 瓦片拷进去不就行了。这个思路方向对但格式细节对不上。GeoWebCache 自己的缓存目录结构是EPSG_3857_级别/行列号.png这种扁平或两级结构而 ArcGIS 是L级别/R行/C列.png命名规则、层级组织、行列号进制都不同。直接拷贝的结果是 GeoServer 认不出这些文件服务返回 404 或者空白瓦片。正确做法是通过 GeoWebCache 的GeoServerTileLayer机制配置一个指向外部瓦片目录的瓦片层让 GeoWebCache 按 ArcGIS 的目录规则去读取。这需要在 GeoServer 的配置里显式声明瓦片目录位置和命名模板而不是靠文件系统层面的拷贝。3. 在 GeoServer 里挂载 ArcGIS 瓦片配置步骤与参数逐项拆解3.1 准备 GridSet把 ArcGIS 的切片方案翻译成 GeoServer 能懂的语言GridSet 是 GeoWebCache 里定义瓦片网格的核心配置。你要做的是新建一个 GridSet把 ArcGIS 切片方案里的分辨率、范围、坐标系填进去。操作路径是 GeoServer 管理界面 → Tile Caching → Gridsets → 新建。关键参数逐项说明参数项含义填写依据Coordinate Reference System瓦片坐标系ArcGIS 切片方案里的 SR常见 EPSG:3857Tile Size瓦片像素尺寸通常 256×256少数项目用 512Extent全范围切片方案里的 Full Extent注意坐标系单位Resolutions每级分辨率从切片方案逐级抄单位是地图单位/像素Tile Origin原点通常是左上角注意 X 和 Y 的取值分辨率这一项最容易出错。ArcGIS 的切片方案里分辨率通常以米/像素或度/像素给出而 GeoServer 的 GridSet 要求的分辨率列表是从第 0 级到最高级依次排列。如果你抄错了顺序或者漏了一级瓦片层级就会整体错位。!-- GridSet 配置片段示例实际通过管理界面填写 -- gridSet namearcgis_3857/name srsEPSG:3857/srs tileSize256/tileSize extent-20037508.34 -20037508.34 20037508.34 20037508.34/extent resolutions 156543.03392804097 78271.51696402048 39135.75848201024 !-- 后续级别依次减半直到与 ArcGIS 切片方案一致 -- /resolutions /gridSet上面这段配置里extent是 Web Mercator 的标准全范围resolutions从第 0 级开始逐级减半。如果你的 ArcGIS 切片方案不是从第 0 级开始切的比如只切了第 5 到第 12 级那 GridSet 里的分辨率列表也要对应调整不能直接从标准方案抄全量。3.2 配置 GeoServerTileLayer 指向外部瓦片目录GridSet 建好后下一步是让 GeoWebCache 知道去哪里读瓦片。GeoServer 里可以通过 REST API 或者直接改配置文件来添加一个指向外部目录的瓦片层。常见做法是在 GeoServer 数据目录下的gwc文件夹里操作但更稳妥的方式是通过 REST 接口。# 通过 REST API 创建一个指向外部瓦片目录的 GeoServerTileLayer # 注意URL 中的工作区和图层名需要替换为实际值 curl -u admin:geoserver -X PUT \ -H Content-Type: application/json \ -d { geoServerTileLayer: { name: workspace:arcgis_tiles, enabled: true, gridSetId: arcgis_3857, blobStoreId: arcgisBlobStore, mimeFormats: [image/png], metaTilingFactors: [1, 1] } } \ http://localhost:8080/geoserver/gwc/rest/layers/workspace:arcgis_tiles.json这段命令的作用是在 GeoWebCache 里注册一个瓦片层gridSetId指向刚才建的 GridSetblobStoreId指向一个 BlobStore——BlobStore 才是真正定义瓦片文件读取路径的地方。metaTilingFactors设为[1,1]是因为外部瓦片已经是切好的不需要再做元瓦片合并。BlobStore 的配置需要单独创建它定义了瓦片目录的根路径和文件命名模板。ArcGIS 的目录结构是L级别/R行/C列.png所以 BlobStore 的命名模板要写成类似L%02d/R%08x/C%08x.png的形式具体取决于你目录里的实际命名规则。这一步如果模板写错GeoServer 就找不到文件服务会返回空白瓦片。3.3 行列号进制与补位最容易翻车的一环ArcGIS 瓦片的行列号用的是十六进制而且位数固定。比如R0000000a表示第 10 行C0000000f表示第 15 列。GeoWebCache 在读取时如果 BlobStore 的命名模板没有正确声明十六进制格式和补位宽度就会按十进制去拼路径结果就是文件找不到。# BlobStore 配置中命名模板的关键写法 # %08x 表示 8 位十六进制不足补零 # 如果 ArcGIS 目录用的是大写十六进制模板里也要对应大写 # 实际配置通过 GeoServer 管理界面或 REST 完成我一般会先手动拼一个路径验证拿一个已知存在的瓦片比如第 3 级第 5 行第 7 列按模板拼出路径去文件系统里确认这个文件确实存在。如果手动拼的路径对不上那模板肯定有问题。这个验证步骤花两分钟能省掉后面半小时的排查。注意不同版本的 ArcGIS 在切图时行列号的补位宽度可能不同有的是 8 位有的是 6 位。一定要以实际目录里的文件名为准不要凭经验假设。4. 避坑与排查挂载 ArcGIS 瓦片时最常见的五个问题4.1 服务返回空白瓦片日志里没有明显报错现象WMTS 服务能访问但返回的瓦片全是透明或空白GeoServer 日志里没有 ERROR 级别信息。原因最常见的是 GridSet 的分辨率或范围与 ArcGIS 切片方案不一致导致 GeoWebCache 计算出的瓦片行列号和你目录里的文件对不上。另一种可能是 BlobStore 的命名模板写错GeoWebCache 去找了一个不存在的路径但因为没有抛异常只是返回空瓦片。解决先手动按当前 GridSet 参数计算一个瓦片请求对应的行列号然后去瓦片目录里确认这个行列号的文件是否存在。如果不存在逐项对比 GridSet 的分辨率、原点、范围和 ArcGIS 切片方案的值。重点检查分辨率的顺序和原点坐标的正负号。4.2 瓦片位置整体偏移但层级和行列号看起来都对现象瓦片能读出来但位置整体偏移了几百米的距离或者缩放级别越高偏移越明显。原因原点坐标或分辨率精度不够。ArcGIS 切片方案里的原点通常是精确到小数点后多位的浮点数如果 GridSet 里填的是四舍五入后的值累积到高层级就会产生明显偏移。解决从切片方案文件里直接复制原始精度值不要手动截断。如果拿不到原始文件可以从瓦片目录反推原点但反推值需要和已知地物做比对验证。4.3 高层级瓦片正常低层级瓦片 404现象第 10 级以上的瓦片能正常访问第 5 级以下的瓦片全部 404。原因ArcGIS 切片时可能只切了部分级别低层级根本没有生成瓦片文件。而 GeoServer 的 GridSet 里声明了全量级别GeoWebCache 去读低层级时找不到文件。解决确认 ArcGIS 实际切了哪些级别在 GridSet 里只声明这些级别对应的分辨率。或者在 GeoWebCache 配置里设置enabled级别范围把没有瓦片的级别禁掉。4.4 并发访问时瓦片读取超时现象单个请求正常并发一上来就大量超时日志里出现文件读取等待。原因外部瓦片目录如果是机械硬盘或者网络存储随机读取性能跟不上并发请求。GeoWebCache 默认会去磁盘读瓦片没有内存缓存层。解决在 GeoWebCache 配置里开启内存缓存inMemoryCache或者把瓦片目录放到 SSD 上。如果瓦片总量不大可以考虑把常用级别的瓦片预加载到内存缓存里。4.5 坐标系对不上导致瓦片完全错位现象瓦片能读出来但位置完全不对甚至跑到地球另一侧。原因ArcGIS 切片方案用的是 EPSG:4326而 GridSet 配的是 EPSG:3857或者反过来。坐标系不匹配时GeoWebCache 计算的行列号会完全错乱。解决确认 ArcGIS 切片时用的坐标系GridSet 里必须用同一个。如果不确定看瓦片目录的级别数和分辨率——3857 的第 0 级分辨率约 1565434326 的第 0 级分辨率约 0.703数量级差很多一眼能分辨。5. 验证挂载结果与进阶技巧让这套方案真正跑稳5.1 用 GetCapabilities 和 GetTile 做最小验证配置完成后不要急着上业务系统先用最直接的方式验证。第一步请求 WMTS 的 GetCapabilities确认瓦片层出现在能力文档里并且 GridSet 的标识符和你的配置一致# 获取 WMTS 能力文档检查瓦片层是否注册成功 curl http://localhost:8080/geoserver/gwc/service/wmts?REQUESTGetCapabilities \ | grep -A 5 arcgis_tiles第二步手动构造一个 GetTile 请求拿一个你确定存在的瓦片看返回的图片是不是和文件系统里的原图一致# 请求指定层级、行、列的瓦片 # TileMatrix 的值对应 GridSet 里的级别标识 curl -o test_tile.png \ http://localhost:8080/geoserver/gwc/service/wmts?REQUESTGetTileSERVICEWMTSVERSION1.0.0LAYERworkspace:arcgis_tilesSTYLETILEMATRIXEPSG:3857:5TILEROW10TILECOL15FORMATimage/png下载下来的test_tile.png和瓦片目录里对应位置的文件做二进制比对如果一致说明整条链路是通的。如果不一致看是返回了空白瓦片还是返回了错误信息再回到上一章的排查清单里逐项检查。5.2 用 TMS 服务做兼容性兜底有些客户端只认 TMS 不认 WMTSGeoServer 的 GeoWebCache 同时提供 TMS 服务。TMS 的 URL 结构和 WMTS 不同行列号的起始值也有差异——TMS 的行号是从下往上数的而 ArcGIS 和 WMTS 是从上往下。这个差异在挂载外部瓦片时特别容易踩坑因为 GeoWebCache 在 TMS 模式下会对行号做翻转如果你的 BlobStore 命名模板没有考虑这一点TMS 请求就会读到错误的瓦片。我一般会在 GridSet 配置里同时启用 WMTS 和 TMS然后用同一个瓦片分别通过两个服务请求比对返回结果。如果 TMS 返回的瓦片和 WMTS 不一致检查 GeoWebCache 的tms相关配置里行号翻转逻辑是否和你的瓦片目录匹配。5.3 瓦片目录更新后的缓存刷新策略ArcGIS 侧的瓦片如果重新切了或者增补了级别GeoServer 这边不会自动感知。GeoWebCache 有自己的缓存索引外部瓦片目录变化后需要手动触发缓存重新加载。常见做法是通过 GeoWebCache 的 REST 接口 truncate 掉对应图层的缓存然后重新请求时 GeoWebCache 会重新去读外部目录# 截断指定图层的 GeoWebCache 缓存强制重新读取外部瓦片 curl -u admin:geoserver -X POST \ http://localhost:8080/geoserver/gwc/rest/seed/workspace:arcgis_tiles.json \ -H Content-Type: application/json \ -d {truncate: [EPSG:3857], threadCount: 1}这个操作不会删除外部瓦片目录里的文件只是清掉 GeoWebCache 内部的索引和缓存副本。执行后第一次请求会稍慢之后恢复正常。5.4 一个我踩过的坑别在 GridSet 里用“标准方案”偷懒早期做这个方案时我图省事GridSet 直接用了 GeoServer 内置的 EPSG:3857 标准方案没有按 ArcGIS 切片方案逐项填。结果瓦片在低层级看起来正常到第 12 级以上就开始出现半米左右的偏移。排查了半天才意识到ArcGIS 切片时用的原点坐标和标准方案有微小差异低层级看不出来高层级被放大后就明显了。后来老老实实从切片方案文件里逐项抄参数问题消失。这个教训是外部瓦片挂载这件事参数必须逐项对齐没有“差不多就行”的空间。希望帮到你。本文还有配套的精品资源点击获取