根据openlayer5中的投影更改比例和测量

时间:2019-05-21 13:59:55

标签: openlayers openlayers-5

我正在使用openlayer构建基于图像图块的地图,其中将投影更改为自定义投影,而不是默认的EPSG。我需要根据我到像素的距离比例来显示正确的比例,还需要根据该比例进行测量。

我更改了metersPerUnit以适应规模需求,但这似乎取决于程度。 1.程度如何精确地用于规模? 2.当我在地图上垂直移动时,我可以看到比例尺值发生了变化,因为平面投影是不应该的。 (我将global设置为true,我认为应该已经解决了这个问题。我是否了解global的问题?

即使更改了metersPerUnit,测量值仍然有很大不同,我想这是因为我还需要更改getPointResolution函数吗?但我补充说,这似乎无法正常工作。测量结果仍然不同。

getPointResolution = (projection, resolution, point, opt_units) => {
        var pointResolution = resolution;
        pointResolution /= projection.getMetersPerUnit();
        return pointResolution;
    };

proj = new Projection({
      code: 'ZOOMIFY',
      units: 'pixels',
      extent: [0, 0, imgWidth, imgHeight],
      metersPerUnit: (constant_micronsperpixel * 0.000001 / imgWidth),
      global: true,
      getPointResolution: getPointProjection
    });

另一件事是,我需要在imgWidth中使用metersPerUnit来纠正似乎是hack的比例,或者我不太了解如何使用范围进行比例计算。 extentglobalExtent之间的真正区别是什么

更新:5月27日

我设法弄清楚了一些东西。固定分辨率并实施正确的getPointResolution以确保查看结果正确,并带有刻度。这也将我不断变化的规模固定为垂直移动。 但是,视图现在不查询图像。知道为什么吗?

更新代码

this.getPointResolution = (resolution, point) => {
        var pointResolution = resolution;
        return pointResolution;
    }

    this.proj = new Projection({
      code: 'MORPHLE',
      units: 'm',
      metersPerUnit: 0.000001,
      global: true,
      getPointResolution: this.getPointResolution,

    });

    this.resolutions = [this.props.slide_data.uperpixel * 128,this.props.slide_data.uperpixel * 64,this.props.slide_data.uperpixel * 32, this.props.slide_data.uperpixel * 16, this.props.slide_data.uperpixel * 8, this.props.slide_data.uperpixel * 4, this.props.slide_data.uperpixel*2, this.props.slide_data.uperpixel];

    this.viewer = new Map({
      controls: [],
      target: null,
      overlays: [this.popup],
      layers: [
        new TileLayer({
          source: new XYZ({
            url: this.props.url,
            maxZoom: this.props.max_zoom - 1,
            minZoom: 0,
            wrapX: false,
            tileSize: [500, 500],
            projection: this.proj
          }),
          minResolution: (this.props.slide_data.uperpixel),
          maxResolution: (this.props.slide_data.uperpixel * 128)

        })
      ],
      view: new View({
        projection: this.proj,
        center: this.state.center,
        resolutions: this.resolutions,
        minZoom: 0,
        zoom: this.state.zoom,
        rotation: this.slideAngle
      })
    });

尽管我现在在浏览器Network Tab中看到的图像仍未被查询。

1 个答案:

答案 0 :(得分:0)

经过很多次尝试,我解决了我的问题。以下是一些我学到的见解,在文档中缺少/难以理解:
1.范围imgHeightimgWidth必须是全分辨率图像的大小,即最大缩放级别的X图像* Tile-X-Width和Y图像* Tile-Y-Width。< br /> 2. TileGrid中添加的分辨率定义了图像URL查询,而View中的分辨率仅定义了视图分辨率。如果它们匹配(在某些缩放比例下),则图像将是查询图像,否则缩放比例本质上仅是数字形式。

因此,如果有人想使用带有自定义投影和分辨率以及正确的投影和尺寸的OpenLayer进行深度缩放-以下是代码:

this.imgWidth = this.stitched_tile_width * this.x_max;
this.imgHeight = this.tile_height * this.y_max;

this.resolutions = [];
let z_levels = this.props.slide_data.z_levels.split(",");
(z_levels).forEach((level, index) => {
      this.resolutions.push(this.distperpixel * Math.pow(2, parseInt(level)));
});

this.resolutions = this.resolutions.reverse();

this.getPointResolution = (resolution, point) => {
      var pointResolution = resolution;
      return pointResolution;
}

    this.proj = new Projection({
      code: 'CUSTOM',
      units: 'pixels',
      extent: [0, 0, this.imgWidth, this.imgHeight],
      metersPerUnit: 0.000001,
      global: true,
      getPointResolution: this.getPointResolution,
    });

    this.layer = new TileLayer({
      extent: this.proj.getExtent(),
      source: new TileImage({
        tileGrid: new TileGrid({
          extent: this.proj.getExtent(),
          origin: [0, this.imgHeight],
          resolutions: this.resolutions,
          tileSize: [this.tile_width, this.tile_height],
        }),
        projection: this.proj,
        url: this.props.url,
        wrapX: false
      }),
    });

    this.viewer = new Map({
      layers: [
        this.layer
      ],
      view: new View({
        projection: this.proj,
        extent: this.proj.getExtent(),
        center: this.state.center,
        zoom: starting_zoom,
        maxResolution: this.resolutions[0],
        maxZoom: (this.resolutions.length - 1),
        rotation: this.slideAngle
      })
    });