class CanvasLayer2 extends ol.layer.Layer {
constructor(options) {
super(options);
this.features = options.features;
this.canvas = document.createElement("canvas");
this.canvas.style.position = "absolute";
this.ctx = this.canvas.getContext("2d");
}
getSourceState() {
return "ready";
}
render(frameState) {
const width = frameState.size[0];
const height = frameState.size[1];
const projection = frameState.viewState.projection;
const d3Projection = d3.geoMercator().scale(1).translate([0, 0]);
let d3Path = d3.geoPath().projection(d3Projection);
const pixelBounds = d3Path.bounds(this.features);
const pixelBoundsWidth = pixelBounds[1][0] - pixelBounds[0][0];
const pixelBoundsHeight = pixelBounds[1][1] - pixelBounds[0][1];
const geoBounds = d3.geoBounds(this.features);
const geoBoundsLeftBottom = ol.proj.fromLonLat(geoBounds[0], projection);
const geoBoundsRightTop = ol.proj.fromLonLat(geoBounds[1], projection);
let geoBoundsWidth = geoBoundsRightTop[0] - geoBoundsLeftBottom[0];
if (geoBoundsWidth < 0) {
geoBoundsWidth += ol.extent.getWidth(projection.getExtent());
}
const geoBoundsHeight = geoBoundsRightTop[1] - geoBoundsLeftBottom[1];
const widthResolution = geoBoundsWidth / pixelBoundsWidth;
const heightResolution = geoBoundsHeight / pixelBoundsHeight;
const r = Math.max(widthResolution, heightResolution);
const scale = r / frameState.viewState.resolution;
const center = ol.proj.toLonLat(
ol.extent.getCenter(frameState.extent),
projection
);
const angle = (-frameState.viewState.rotation * 180) / Math.PI;
d3Projection
.scale(scale)
.center(center)
.translate([width / 2, height / 2])
.angle(angle);
d3Path = d3Path.projection(d3Projection);
this.canvas.width = width;
this.canvas.height = height;
this.ctx.clearRect(0, 0, width, height);
d3Path.context(this.ctx);
this.ctx.beginPath();
d3Path(this.features);
this.ctx.stroke();
this.ctx.fillStyle = "rgba(0, 250, 0, 0.5)";
this.ctx.fill();
return this.canvas;
}
}