Измените масштаб и размер в соответствии с проекцией в openlayer5

Я создаю карту на основе фрагментов изображений, используя 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, чтобы скорректировать масштаб, что, кажется, было взломом, или я не совсем понимаю, как экстент используется для расчета масштаба. И в чем на самом деле разница между extent и globalExtent

Обновление: 27 мая

Мне удалось кое-что выяснить, размеры не нужны для масштабирования. Установка разрешений и установка правильного getPointResolution для просмотра гарантирует правильность измерений вместе с масштабом. Это также исправило мою изменяющуюся шкалу при движении по вертикали. Однако сейчас View не запрашивает изображения. Есть идеи, почему?

Обновленный код

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 браузера.


person dementor    schedule 21.05.2019    source источник


Ответы (1)


После долгих экспериментов я решил свою проблему. Вот некоторые идеи, которые я узнал и которые отсутствуют / трудны для понимания в документации:
1. Экстент imgHeight и imgWidth должен быть размером с изображение с полным разрешением, то есть в X-изображениях самого увеличенного уровня * Tile-X-Width и Y-изображения * Tile-Y-Width.
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
      })
    });
person dementor    schedule 29.05.2019