Map experiments
This commit is contained in:
127
client/src/components/map/mapUtils.ts
Normal file
127
client/src/components/map/mapUtils.ts
Normal file
@ -0,0 +1,127 @@
|
||||
import { Coordinate, distance, rotate } from "ol/coordinate";
|
||||
import { Extent, getCenter } from "ol/extent";
|
||||
import { addCoordinateTransforms, addProjection, get, getTransform, Projection, ProjectionLike, transform } from "ol/proj";
|
||||
import proj4 from "proj4";
|
||||
|
||||
function rotateProjection(projection: ProjectionLike, angle: number, extent: Extent) {
|
||||
function rotateCoordinate(coordinate: Coordinate, angle: number, anchor: Coordinate) {
|
||||
var coord = rotate(
|
||||
[coordinate[0] - anchor[0], coordinate[1] - anchor[1]],
|
||||
angle
|
||||
);
|
||||
return [coord[0] + anchor[0], coord[1] + anchor[1]];
|
||||
}
|
||||
|
||||
function rotateTransform(coordinate: Coordinate) {
|
||||
return rotateCoordinate(coordinate, angle, getCenter(extent));
|
||||
}
|
||||
|
||||
function normalTransform(coordinate: Coordinate) {
|
||||
return rotateCoordinate(coordinate, -angle, getCenter(extent));
|
||||
}
|
||||
|
||||
var normalProjection = get(projection);
|
||||
|
||||
if (normalProjection) {
|
||||
var rotatedProjection = new Projection({
|
||||
code: normalProjection.getCode() + ":" + angle.toString() + ":" + extent.toString(),
|
||||
units: normalProjection.getUnits(),
|
||||
extent: extent
|
||||
});
|
||||
addProjection(rotatedProjection);
|
||||
|
||||
addCoordinateTransforms(
|
||||
"EPSG:4326",
|
||||
rotatedProjection,
|
||||
function (coordinate) {
|
||||
return rotateTransform(transform(coordinate, "EPSG:4326", projection));
|
||||
},
|
||||
function (coordinate) {
|
||||
return transform(normalTransform(coordinate), projection, "EPSG:4326");
|
||||
}
|
||||
);
|
||||
|
||||
addCoordinateTransforms(
|
||||
"EPSG:3857",
|
||||
rotatedProjection,
|
||||
function (coordinate) {
|
||||
return rotateTransform(transform(coordinate, "EPSG:3857", projection));
|
||||
},
|
||||
function (coordinate) {
|
||||
return transform(normalTransform(coordinate), projection, "EPSG:3857");
|
||||
}
|
||||
);
|
||||
|
||||
// also set up transforms with any projections defined using proj4
|
||||
if (typeof proj4 !== "undefined") {
|
||||
var projCodes = Object.keys(proj4.defs);
|
||||
projCodes.forEach(function (code) {
|
||||
var proj4Projection = get(code) as Projection;
|
||||
if (proj4Projection) {
|
||||
if (!getTransform(proj4Projection, rotatedProjection)) {
|
||||
addCoordinateTransforms(
|
||||
proj4Projection,
|
||||
rotatedProjection,
|
||||
function (coordinate) {
|
||||
return rotateTransform(
|
||||
transform(coordinate, proj4Projection, projection)
|
||||
);
|
||||
},
|
||||
function (coordinate) {
|
||||
return transform(
|
||||
normalTransform(coordinate),
|
||||
projection,
|
||||
proj4Projection
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return rotatedProjection;
|
||||
}
|
||||
}
|
||||
|
||||
const calculateCentroid = (bottomLeft: Coordinate, topLeft: Coordinate, topRight: Coordinate, bottomRight: Coordinate) => {
|
||||
const x = (bottomLeft[0] + topLeft[0] + topRight[0] + bottomRight[0]) / 4;
|
||||
const y = (bottomLeft[1] + topLeft[1] + topRight[1] + bottomRight[1]) / 4;
|
||||
return [x, y];
|
||||
}
|
||||
|
||||
function calculateRotationAngle(bottomLeft: Coordinate, bottomRight: Coordinate) {
|
||||
// Calculate the difference in x and y coordinates between bottom right and bottom left
|
||||
const deltaX = bottomRight[0] - bottomLeft[0];
|
||||
const deltaY = bottomRight[1] - bottomLeft[1];
|
||||
|
||||
// Calculate the angle using atan2
|
||||
const angle = -Math.atan2(deltaY, deltaX);
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
function calculateExtent(bottomLeft: Coordinate, topLeft: Coordinate, topRight: Coordinate, bottomRight: Coordinate) {
|
||||
const width = distance(bottomLeft, bottomRight);
|
||||
const height = distance(bottomLeft, topLeft);
|
||||
|
||||
// Calculate the centroid of the polygon
|
||||
const [centerX, centerY] = calculateCentroid(bottomLeft, topLeft, topRight, bottomRight);
|
||||
|
||||
// Define the extent based on the center and dimensions
|
||||
const extent = [
|
||||
centerX - width / 2, // minX
|
||||
centerY - height / 2, // minY
|
||||
centerX + width / 2, // maxX
|
||||
centerY + height / 2 // maxY
|
||||
];
|
||||
|
||||
return extent;
|
||||
}
|
||||
|
||||
export {
|
||||
rotateProjection,
|
||||
calculateRotationAngle,
|
||||
calculateExtent,
|
||||
calculateCentroid
|
||||
}
|
Reference in New Issue
Block a user