Geographic Information Systems Asked on June 7, 2021
I have a XYZ layer for tiles(generated from an 1065 * 950 Image using gdal2tiles), and a vector layer for features, I want to use my own pixel transformation to set the coordinates of the features.
this.extent = [0, 0, this.imgWidth, this.imgHeight];
this.projection = new Projection({
code: "warehouse-tile-image",
units: "pixel",
extent: this.extent,
});
this.view = new View({
projection: this.projection,
center: getCenter(
this.extent
),
zoom: 2,
maxZoom: 3,
});
this.tileSource = new XYZ({
url: "assets/map/{z}/{x}/{y}.png",
minZoom: 0,
projection: this.projection,
maxZoom: 3,
tileSize: 256,
});
this.layer = new VectorLayer({
source: new VectorSource(),
});
I want to use this d3 scale function to set the pixel coordinates:
//The coordinate of data is in meter
const scale= 0.05
const max_x = scale* this.imgWidth + this.origin.x;
const max_y = scale* this.imgHeight + this.origin.y;
this.xScale = scaleLinear()
.domain([this.origin.x, max_x])
.range([0, this.imgWidth]);
this.yScale = scaleLinear()
.domain([this.origin.y, max_y])
.range([this.imgHeight, 0]);
So I can transform the custom coordinates to pixel by using
this.xScale(x) = pixel x
and
this.yScale(y) = pixel y
This is how I do in Leaflet in order to re-projection:
const denominator = Math.pow(2, this.maxZoom);
L.CRS.MySimple = L.Util.extend({}, L.CRS.Simple, {
/**
* max zoom level >= log2(max(width,height)/tilesize)
* a,c = 1 / 2^max zoom level
**/
transformation: new L.Transformation(
1 / denominator, //a
0, //b
1 / denominator, //c
0 //d
),
});
this.mapOptions = {
layers: [
L.tileLayer(this.tileUrl, {
maxZoom: this.maxZoom,
tileSize: 256,
noWrap: true,
bounds: bounds,
}),
],
zoom: this.maxZoom,
crs: L.CRS.MySimple,
maxZoom: this.maxZoom,
minZoom: 0,
maxBounds: bounds,
zoomControl: false,
center: L.latLng([this.imgWidth, this.imgHeight]),
};
private transformCoord(coordinate: { x: number; y: number }): number[] {
//This function will transform custom coordinates to pixel coordinate using d3 scale
return [this.xScale(coordinate.x), this.yScale(coordinate.y)];
}
//Feature geometry
geometry: {
type: "Point",
coordinates: this.transformCoord(data.pose.position),
},
And then I just use those scale function to transform the coordinates to pixel coordinates and feed to the data layer(Leaflet-realtime which use a Geojson layer).
However, it is different in OpenLayers which seems to do the pixel transformation automatically for me.
My problem is I don’t understand how the projections work in OpenLayers, I have no idea how to do the same as in Leaflet.
You can define reverse scale functions, where all you have to do is to exchange .domain
and .range
values:
this.xScaleReverse = scaleLinear()
.domain([0, this.imgWidth])
.range([this.origin.x, max_x]);
this.yScaleReverse = scaleLinear()
.domain([this.imgHeight, 0])
.range([this.origin.y, max_y]);
Answered by TomazicM on June 7, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP