根据 openlayer5 中的投影更改比例和测量
Change scale and measurement according to a projection in openlayer5
我正在使用 openlayer 构建基于图像图块的地图,我将投影更改为自定义投影而不是默认 EPSG。我需要比例尺根据我的距离与像素比显示正确的比例尺,还需要根据该比例尺进行测量。
我更改了 metersPerUnit
以满足我对比例的需求,但这似乎取决于范围。
1. extent 究竟是如何在规模上使用的?
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
});
另一件事是,我需要在 metersPerUnit
中使用 imgWidth
来更正比例,这似乎是一个 hack,或者我不太明白 extent 是如何用于比例计算的。 extent
和 globalExtent
之间到底有什么区别
更新:5 月 27 日
我想出了一些 things.Extents 不需要缩放。修复分辨率并实施正确的 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
中看到图像未被查询。
经过一番折腾,我解决了我的问题。以下是我学到的一些见解,missing/hard 需要在文档中理解:
1. 范围 imgHeight
和 imgWidth
需要是全分辨率图像的大小,即在最大缩放级别 X-images * Tile-X-Width 和 Y-Images * 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
})
});
我正在使用 openlayer 构建基于图像图块的地图,我将投影更改为自定义投影而不是默认 EPSG。我需要比例尺根据我的距离与像素比显示正确的比例尺,还需要根据该比例尺进行测量。
我更改了 metersPerUnit
以满足我对比例的需求,但这似乎取决于范围。
1. extent 究竟是如何在规模上使用的?
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
});
另一件事是,我需要在 metersPerUnit
中使用 imgWidth
来更正比例,这似乎是一个 hack,或者我不太明白 extent 是如何用于比例计算的。 extent
和 globalExtent
更新:5 月 27 日
我想出了一些 things.Extents 不需要缩放。修复分辨率并实施正确的 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
中看到图像未被查询。
经过一番折腾,我解决了我的问题。以下是我学到的一些见解,missing/hard 需要在文档中理解:
1. 范围 imgHeight
和 imgWidth
需要是全分辨率图像的大小,即在最大缩放级别 X-images * Tile-X-Width 和 Y-Images * 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
})
});