简介本资源面向需要在 GeoServer 中发布 ArcGIS 瓦片服务的 GIS 开发者与运维人员尤其适合已有基础、希望打通切片发布与地图服务链路的中高级用户。压缩包共 1571 个文件约 137.36MB以 png 瓦片图片、jar 依赖库、xml 配置、prj 投影文件、sld 样式、shp/dbf/shx 矢量数据及 pgw 坐标文件为主另含 properties、bat 启动脚本、tif 影像与少量 html、md 说明覆盖服务部署、样式配置与数据组织所需的核心组件。目前已有 1090 人学习下载。资源内含完整的 GeoServer 运行目录与日志、切片缓存及示例数据可帮助读者快速搭建可发布 ArcGIS 瓦片的服务环境理解切片目录结构、投影与样式配置方式并借助启动脚本与日志排查常见发布问题适合作为服务部署与瓦片发布实践的参考包。1. 为什么我宁愿多装一个 GeoServer也不用 ArcGIS Server 发瓦片去年帮某实验室做一套内网 GIS 演示系统底图数据全是 ArcGIS 格式的切片包但甲方环境里没有 ArcGIS Server 授权也不打算买。摆在面前的路只有两条要么把切片包拆成散列图片自己写个静态服务要么找一个能直接读 ArcGIS 瓦片目录、按标准 WMTS/TMS 协议吐出去的开源方案。前者我试过切片层级一多缓存目录能到几十万个文件Nginx 的目录索引直接跪而且坐标系和瓦片矩阵对不上前端 Leaflet 加载出来全是错位。后来换成 GeoServer 挂载 ArcGIS 切片缓存目录问题一次性解决。它本质上是一个 Java 写的 OGC 服务容器支持 WMS、WMTS、TMS、WFS 等一堆标准协议关键是它的 GeoWebCache 模块能直接识别 ArcGIS 的_alllayers目录结构把已有的瓦片当成缓存源发布出去不需要重新切图。适合谁手里有 ArcGIS 切片包、但不想被商业授权绑死、又需要标准 OGC 接口对接前端地图库的开发者。这篇就把我踩过的配置流程和参数坑一次讲清楚。2. 搞懂 GeoServer 读 ArcGIS 瓦片的底层逻辑2.1 ArcGIS 切片目录到底长什么样ArcGIS 的瓦片缓存目录有一套固定命名规则通常长这样缓存根目录/ _alllayers/ L00/ R00000000/ C00000000.png C00000001.png L01/ R00000000/ C00000000.pngL后面跟两位数字表示缩放层级R是行号C是列号都是八位十六进制。每个层级目录下还有一个conf.xml或conf.cdi文件记录了该缓存的空间参考、瓦片原点、分辨率等元数据。GeoServer 的 GeoWebCache 在挂载时会去读这些配置文件来推断瓦片矩阵集如果元数据缺失或格式不对后面发布出来的服务就会偏移或者 404。常见做法是先用gdalinfo或者直接打开conf.xml确认几个关键字段SpatialReference里的 WKID、TileOrigin、TileCols和TileRows。这些值决定了你在 GeoServer 里建网格集时填什么参数。2.2 GeoWebCache 的瓦片匹配机制GeoWebCache 本身是一个独立的瓦片缓存组件集成在 GeoServer 里之后它对外暴露的接口是/gwc/service/wmts和/gwc/service/tms。当你把一个 ArcGIS 缓存目录配置成ArcGISCache类型的瓦片源时GWC 不会去重新渲染地图而是直接根据请求的层级、行、列号拼出文件路径去磁盘上找对应的 PNG 或 JPEG。这里有个关键点GWC 默认的瓦片矩阵集GridSet和 ArcGIS 的矩阵集在原点位置和 Y 轴方向上可能不一致。ArcGIS 的瓦片原点通常在左上角Y 轴向下而 GWC 默认的 EPSG:3857 网格集原点在左下角Y 轴向上。如果直接套用默认网格集瓦片行号会上下颠倒。解决办法是在 GeoServer 里新建一个 GridSet手动指定原点为左上角并设置对应的分辨率数组。2.3 为什么不用 GeoServer 重新切图有人会问既然 GeoServer 能读原始影像为什么不直接发布影像服务让它自己切原因很简单——原始影像可能几百 GB重新切一遍全金字塔要跑几个小时甚至几天而 ArcGIS 切片包已经是切好的成品直接复用能省掉大量计算资源和时间。尤其在内网环境数据导入导出本身就麻烦能不动原始数据就不动。另一个场景是切片包可能是别人给的你手里根本没有原始影像只有瓦片目录。这时候 GeoWebCache 的 ArcGISCache 模式就是唯一选择。3. 从零配置一个可用的 ArcGIS 瓦片服务3.1 环境准备与 GeoServer 安装我一般用 Tomcat 部署 GeoServer 的 war 包比独立安装包灵活方便调 JVM 参数。假设你已经装好了 JDK 8 或 11Tomcat 9 解压在/opt/tomcat步骤如下# 下载 GeoServer war 包放到 Tomcat 的 webapps 目录 cd /opt/tomcat/webapps # 假设已经下载了 geoserver.war ls -lh geoserver.war # 启动 Tomcat /opt/tomcat/bin/startup.sh # 查看日志确认启动成功 tail -f /opt/tomcat/logs/catalina.out启动后访问http://你的IP:8080/geoserver默认账号admin密码geoserver。第一次登录后立刻改密码这是血泪经验——内网虽然相对安全但默认密码被扫到就是裸奔。JVM 内存参数在/opt/tomcat/bin/setenv.sh里加export CATALINA_OPTS-Xms1024m -Xmx2048m -XX:MaxPermSize512m-Xmx根据你的瓦片数据量调整如果切片包很大GWC 在扫描目录时会占用较多内存建议不低于 2GB。3.2 在 GeoServer 中创建 ArcGIS 缓存数据存储登录 GeoServer 管理界面左侧菜单找到「数据存储」→「新建数据存储」→ 选择「ArcGIS 缓存」类型。这个选项在部分版本里叫「ArcGIS Cache」如果找不到说明你的 GeoServer 版本太老建议用 2.20 以上。关键参数填写参数名填写内容说明工作区新建或选已有工作区建议单独建一个方便权限隔离数据存储名称自定义如arcgis_tiles不要用中文和空格缓存目录ArcGIS 切片根目录的绝对路径指向_alllayers的上一级坐标系根据 conf.xml 里的 WKID 填常见是 EPSG:3857 或 EPSG:4326瓦片格式PNG 或 JPEG看目录里实际文件后缀填完后点击「保存」GeoServer 会去扫描目录结构。如果目录层级不对或者 conf.xml 缺失这一步会报错日志里能看到具体原因。3.3 发布图层并配置瓦片矩阵集数据存储建好后新建图层选择刚才的存储GeoServer 会自动列出可用的图层名称。发布时重点在「瓦片缓存」选项卡!-- 这是一个 GridSet 配置的示意实际在界面里填 -- gridSet nameEPSG:3857_ArcGIS/name srsEPSG:3857/srs tileOrigin左上角坐标/tileOrigin resolution分辨率数组/resolution /gridSet在 GeoServer 界面里操作路径是「网格集」→「新建网格集」→ 基于 EPSG:3857 修改。关键是把「定义网格集」的方式从「自动」改成「手动」然后填入从 ArcGIS conf.xml 里读到的分辨率和原点坐标。分辨率数组的算法是第一层分辨率 初始比例尺分母 × 0.0254 / 96后续每层除以 2。如果你不确定可以直接从 conf.xml 里的LodInfos节点抄。配置完成后在图层预览里选 WMTS 或 TMS 协议应该能看到瓦片正常加载。如果出现空白或者错位先检查网格集的原点是否和 ArcGIS 一致。3.4 用 Leaflet 验证服务是否可用前端验证是最直观的。写一个简单的 HTML!DOCTYPE html html head link relstylesheet hrefhttps://unpkg.com/leaflet1.9.4/dist/leaflet.css / script srchttps://unpkg.com/leaflet1.9.4/dist/leaflet.js/script style#map { height: 600px; }/style /head body div idmap/div script var map L.map(map).setView([30.0, 120.0], 10); // 注意WMTS 的 URL 模板要根据 GeoServer 实际地址替换 L.tileLayer(http://你的IP:8080/geoserver/gwc/service/wmts?layer工作区:图层名tilematrixsetEPSG:3857_ArcGISServiceWMTSRequestGetTileVersion1.0.0Formatimage/pngTileMatrixEPSG:3857_ArcGIS:{z}TileRow{y}TileCol{x}, { maxZoom: 18, minZoom: 0 }).addTo(map); /script /body /html把你的IP、工作区名、图层名替换成实际值。如果地图上能看到瓦片说明服务通了。如果控制台报 404检查TileMatrix参数是否和网格集名称完全一致大小写敏感。提示WMTS 的 KVP 参数里TileMatrix的值必须是网格集的名称不是EPSG:3857这种通用写法。很多人在这里翻车。4. 避坑指南ArcGIS 瓦片发布常见的五个坑4.1 瓦片上下颠倒或偏移现象前端加载出来的地图上下颠倒或者整体偏移几百米。原因GeoServer 默认网格集的原点在左下角而 ArcGIS 切片原点在左上角。Y 轴方向相反导致行号映射错误。解决在网格集配置里手动把原点改成左上角坐标并确保分辨率数组和 ArcGIS 的LodInfos完全一致。改完后清空 GWC 缓存再试。4.2 部分层级 404低层级正常现象缩放级别小的时候瓦片正常放大到某一级之后全部 404。原因ArcGIS 切片包可能只切到了第 15 级但 GeoServer 的网格集默认配到了 18 级。请求超出范围的层级时磁盘上找不到对应目录。解决在图层发布设置里限制最大缩放级别或者在网格集里把分辨率数组截断到实际存在的层级。前端也要设置maxZoom对应。4.3 中文路径导致扫描失败现象数据存储保存时报错日志提示FileNotFoundException或乱码。原因ArcGIS 切片目录的路径里包含中文或空格GeoServer 在拼接文件路径时编码处理有问题。解决把切片目录移到纯英文、无空格的路径下比如/data/arcgis_cache/。这是最省事的办法不要试图去改 GeoServer 的编码配置。4.4 内存溢出导致服务卡死现象GeoServer 运行一段时间后无响应日志里出现OutOfMemoryError。原因GWC 在扫描大目录时会缓存文件列表如果切片数量几十万默认 JVM 内存不够。解决调大-Xmx到 4GB 或更高同时在 GWC 配置里关闭「自动扫描」或加大扫描间隔。另外可以启用磁盘配额避免缓存无限增长。4.5 WMTS 的 TileMatrix 名称不匹配现象浏览器控制台报 400 或 404但直接在浏览器里打开瓦片 URL 又能看到图。原因前端代码里TileMatrix参数写的是EPSG:3857但 GeoServer 里网格集名称是EPSG:3857_ArcGIS两者不一致。解决打开 GeoServer 的「网格集」列表复制实际的名称粘贴到前端代码里。注意 URL 编码冒号要写成%3A。5. 进阶技巧用 REST API 批量发布和缓存调优手动在界面点虽然直观但如果你有几十个切片包要发布一个个点就是折磨。GeoServer 提供了 REST API可以用脚本批量操作。我一般用 Python 的requests库写个循环import requests from requests.auth import HTTPBasicAuth GEOSERVER_URL http://127.0.0.1:8080/geoserver AUTH HTTPBasicAuth(admin, 你的密码) HEADERS {Content-Type: application/json} # 创建工作区的 payload workspace_payload { workspace: { name: arcgis_ws } } # 创建 ArcGIS 缓存存储的 payload store_payload { dataStore: { name: arcgis_cache_store, type: ArcGISCache, enabled: True, workspace: {name: arcgis_ws}, connectionParameters: { entry: [ {key: cacheDirectory, $: /data/arcgis_cache/_alllayers}, {key: srs, $: EPSG:3857} ] } } } # 发送请求创建工作区 r requests.post(f{GEOSERVER_URL}/rest/workspaces, jsonworkspace_payload, authAUTH, headersHEADERS) print(创建工作区:, r.status_code) # 创建数据存储 r requests.post(f{GEOSERVER_URL}/rest/workspaces/arcgis_ws/datastores, jsonstore_payload, authAUTH, headersHEADERS) print(创建存储:, r.status_code)这段代码的逻辑是先通过/rest/workspaces接口创建工作区再通过/rest/workspaces/{ws}/datastores创建 ArcGISCache 类型的数据存储。connectionParameters里的cacheDirectory要指向_alllayers目录本身而不是它的上级。srs填 ArcGIS 切片使用的坐标系。发布图层用/rest/workspaces/{ws}/datastores/{ds}/featuretypes接口但 ArcGISCache 类型的数据存储发布的是覆盖层coverage所以要用/rest/workspaces/{ws}/coveragestores。这个细节在官方文档里写得比较绕我当初在这里卡了半天。缓存调优方面GWC 的配置文件在geoserver_data/gwc/目录下可以调整gwc-gmaps.xml或自定义的geowebcache.xml。关键参数参数建议值作用cacheSize根据磁盘空间定磁盘缓存最大字节数metatiling4x4 或 8x8元瓦片合并请求减少 IOblobStoreFileBlobStore大文件用文件存储小文件可考虑内存backendTimeout120 秒后端超时内网可适当调大我一般会把metatiling设成 4x4这样前端一次请求 16 个瓦片GWC 合并成一次磁盘读取响应速度明显提升。但注意如果切片包本身已经是按单瓦片存储的metatiling 不会改变磁盘结构只是请求层面的合并。最后说一个验证技巧配置完成后用curl直接请求一个已知存在的瓦片看返回的 HTTP 状态码和 Content-Typecurl -I http://127.0.0.1:8080/geoserver/gwc/service/tms/1.0.0/arcgis_ws:图层名EPSG:3857png/10/100/200.png如果返回200 OK且Content-Type: image/png说明服务正常。如果返回404检查路径里的图层名和网格集名称是否匹配。这个命令我每次部署完都会跑一遍比在浏览器里点快得多。从那以后我每次发布 ArcGIS 瓦片都强制先跑一遍 REST API 脚本建存储再用 curl 验证瓦片最后才开前端。这套流程走下来基本不会再出现配置遗漏。希望帮到你。本文还有配套的精品资源点击获取