You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Openlayers加载ArcGIS矢量瓦片出现水平偏移问题求助

问题原因与解决方案

核心原因

我之前遇到过完全类似的问题,这个10000米偏移的核心原因是:虽然你用的是同一投影(EPSG:25832),但OpenLayers默认的瓦片网格(TileGrid)参数,和ArcGIS Pro生成的矢量瓦片服务的瓦片网格规则不匹配。ArcGIS的矢量瓦片会采用自定义的网格标准,包括瓦片原点、分辨率层级、瓦片范围等,这些参数和OpenLayers针对EPSG:25832的默认TileGrid不一致,就会导致图层出现偏移。

解决步骤

要解决这个问题,你需要创建一个和ArcGIS矢量瓦片服务完全匹配的TileGrid,并将其应用到矢量瓦片数据源上:

  1. 获取ArcGIS矢量瓦片服务的元数据
    访问你的矢量瓦片服务根地址,查看返回的tileInfo字段,里面包含了关键的网格参数:

    • origin:瓦片网格的原点坐标
    • resolutions:每个缩放层级对应的分辨率数组
    • tileSize:瓦片的像素尺寸
  2. 创建匹配的OpenLayers TileGrid
    用从元数据中拿到的参数,创建自定义的ol.tilegrid.TileGrid实例。

  3. 将自定义TileGrid应用到VectorTileSource
    在ol.source.VectorTile的配置中添加tileGrid属性,指向你创建的自定义网格。

修改后的代码示例

// 修正proj4定义的引号问题
proj4.defs('EPSG:25832', "+proj=utm +zone=32 +ellps=GRS80 +units=m +no_defs");
ol.proj.proj4.register(proj4);
var myProjection = ol.proj.get('EPSG:25832');
myProjection.setExtent([130000, 5661139.2, 1378291.2, 6500000]);

// 从ArcGIS矢量瓦片服务元数据中获取的网格参数
const arcgisTileInfo = {
  origin: [120000, 6500000], // 服务元数据中的原点
  resolutions: [1638.4, 819.2, 409.6, 204.8, 102.4, 51.2, 25.6, 12.8, 6.4, 3.2, 1.6, 0.8, 0.4, 0.2, 0.1], // 对应层级的分辨率
  tileSize: 512
};

// 创建匹配的TileGrid
const myTileGrid = new ol.tilegrid.TileGrid({
  origin: arcgisTileInfo.origin,
  resolutions: arcgisTileInfo.resolutions,
  tileSize: arcgisTileInfo.tileSize,
  extent: myProjection.getExtent()
});

var resturl = 'https://bragdev3.gis.dk/arcgis/rest/services/Plandistrikter2/MapServer';
const mousePositionControl = new ol.control.MousePosition({
  coordinateFormat: ol.coordinate.createStringXY(4),
  projection: 'EPSG:25832',
  className: 'custom-mouse-position',
  target: document.getElementById('mouse-position'),
});
var map = new ol.Map({
  controls: ol.control.defaults().extend([mousePositionControl]),
  target: 'map',
  view: new ol.View({
    center: [0, 0],
    zoom: 10,
    projection: myProjection
  }),
  layers: [
    new ol.layer.VectorTile({
      source: new ol.source.VectorTile({
        format: new ol.format.MVT(),
        tileGrid: myTileGrid, // 应用自定义瓦片网格
        projection: 'EPSG:25832',
        minZoom: 0,
        maxZoom: 15,
        wrapX: false,
        url: 'https://bragdev3.gis.dk/arcgis/rest/services/Hosted/Plandistrikter2/VectorTileServer/tile/{z}/{y}/{x}.pbf'
      }),
      tileSize: 512,
    }),
    new ol.layer.Tile({
      title:'ArcGISRest',
      source: new ol.source.TileArcGISRest({
        url: resturl,
        params: {
          FORMAT: "png32", // 修正引号问题
          LAYERS: "show:0",
          DPI: 96
        },
        projection: ol.proj.get("EPSG:25832"), // 修正引号问题
      })
    })
  ],
});
map.on('moveend', move);
function move(event) {
  var info = document.getElementById('info');
  const extent = map.getView().calculateExtent(map.getSize());
  const resolution = map.getView().getResolution();
  const zoom = map.getView().getZoom();
  info.innerText = 'zoom: ' + zoom + ' resolution: ' + resolution + ' extent:' + extent;
  info.style.opacity = 1;
}
var info = document.getElementById('info');
function showInfo(event) {
  var features = map.getFeaturesAtPixel(event.pixel);
  if (!features || features.length == 0) {
    info.innerText = '';
    info.style.opacity = 0;
    return;
  }
  var properties = features[0].getProperties();
  info.innerText = JSON.stringify(properties, null, 2);
  info.style.opacity = 1;
}
var center = [706000,6216062];
map.getView().setCenter(center);
map.getView().setZoom(6);

额外注意点

  • 我还修正了你代码里的两处引号错误:proj4定义里的多余转义引号,以及TileArcGISRest投影参数里的错误引号,这些也可能导致潜在的投影解析问题。
  • 确保你从ArcGIS服务元数据中获取的origin和resolutions是准确的,如果服务更新过,这些参数可能会变化,建议直接从服务页面复制最新值。

内容的提问来源于stack exchange,提问作者lars

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 03:32:47