All, no clean code
This commit is contained in:
137
BasicShapes.js
Normal file
137
BasicShapes.js
Normal file
@@ -0,0 +1,137 @@
|
||||
const distancePerDegreeLongitude = 111.320; // 2π×6378.1km/360
|
||||
const distancePerDegreeLatitude = 110.574; // 2π×6356.75km/360
|
||||
|
||||
import * as turf from "@turf/turf";
|
||||
import { toMercator, toWgs84 } from '@turf/projection';
|
||||
|
||||
/**
|
||||
* @param {Object} center - The center point of the circle.
|
||||
* @param {number} center.x
|
||||
* @param {number} center.y
|
||||
* @param {number} radius - The radius of the circle.
|
||||
* @param {number} density - The number of points used to approximate the circle.
|
||||
*
|
||||
* @returns {Object} GeoJSON Feature representing the circle polygon.
|
||||
*/
|
||||
export function getCirclePolygon(center, radius, density = 64) {
|
||||
const points = [];
|
||||
|
||||
const coords = {
|
||||
latitude: center[1], // Latitude
|
||||
longitude: center[0] // Longitude
|
||||
};
|
||||
|
||||
const distanceX = radius / (distancePerDegreeLongitude * Math.cos(coords.latitude * Math.PI / 180));
|
||||
const distanceY = radius / distancePerDegreeLatitude;
|
||||
|
||||
for (let i = 0; i < density; i++) {
|
||||
const angle = (i / density) * Math.PI * 2;
|
||||
const x = distanceX * Math.cos(angle);
|
||||
const y = distanceY * Math.sin(angle);
|
||||
points.push([coords.longitude + x, coords.latitude + y]);
|
||||
}
|
||||
|
||||
// Close the circle by adding the first point again
|
||||
points.push(points[0]);
|
||||
|
||||
return {
|
||||
type: "Feature",
|
||||
geometry: {
|
||||
type: "Polygon",
|
||||
coordinates: [points]
|
||||
},
|
||||
properties: {}
|
||||
};
|
||||
}
|
||||
|
||||
function getDistancePerDegreeLongitude(latitude) {
|
||||
return 111.320 * Math.cos(latitude * Math.PI / 180);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} center - The center point of the rectangle.
|
||||
* @param {number} center.x
|
||||
* @param {number} center.y
|
||||
* @param {number} sideA - The length of the first side of the rectangle.
|
||||
* @param {number} sideB - The length of the second side of the rectangle.
|
||||
* @param {number} rotation - The angle (in radians) by which to rotate the rectangle.
|
||||
*
|
||||
* @returns {Object} GeoJSON Feature representing the rectangle polygon.
|
||||
*/
|
||||
export function getRectanglePolygon(center, width, height, rotation = 0) {
|
||||
const widthMeters = width * 1000 ;
|
||||
const heightMeters = height * 1000;
|
||||
|
||||
// 1. Střed převedeme do metrického systému (Web Mercator)
|
||||
const centerMerc = toMercator(turf.point(center)).geometry.coordinates;
|
||||
|
||||
// 2. Vypočítáme rohy čtverce v metrech
|
||||
const halfWidth = widthMeters / 2;
|
||||
const halfHeight = heightMeters / 2;
|
||||
|
||||
let corners = [
|
||||
[centerMerc[0] - halfWidth, centerMerc[1] + halfHeight], // topLeft
|
||||
[centerMerc[0] + halfWidth, centerMerc[1] + halfHeight], // topRight
|
||||
[centerMerc[0] + halfWidth, centerMerc[1] - halfHeight], // bottomRight
|
||||
[centerMerc[0] - halfWidth, centerMerc[1] - halfHeight], // bottomLeft
|
||||
];
|
||||
|
||||
// 3. Otočení (volitelně)
|
||||
if (rotation !== 0) {
|
||||
const rad = (rotation * Math.PI) / 180;
|
||||
corners = corners.map(([x, y]) => rotateXY(x, y, centerMerc[0], centerMerc[1], rad));
|
||||
}
|
||||
|
||||
// 4. Uzavřeme polygon a převedeme zpět do WGS84
|
||||
corners.push(corners[0]);
|
||||
const wgsCoords = corners.map(([x, y]) => toWgs84([x, y]));
|
||||
|
||||
return turf.polygon([wgsCoords]);
|
||||
}
|
||||
|
||||
function rotateXY(x, y, cx, cy, angleRad) {
|
||||
const dx = x - cx;
|
||||
const dy = y - cy;
|
||||
const cos = Math.cos(angleRad);
|
||||
const sin = Math.sin(angleRad);
|
||||
const rx = cx + dx * cos - dy * sin;
|
||||
const ry = cy + dx * sin + dy * cos;
|
||||
return [rx, ry];
|
||||
}
|
||||
/*
|
||||
const [lon, lat] = center;
|
||||
|
||||
// Přepočet metrů na stupně:
|
||||
const degLat = height / distancePerDegreeLatitude / 2;
|
||||
const degLon = width / (distancePerDegreeLongitude * Math.cos(lat * Math.PI / 180)) / 2;
|
||||
|
||||
// Rohy bez rotace (v relative souřadnicích)
|
||||
const corners = [
|
||||
[-degLon, -degLat],
|
||||
[ degLon, -degLat],
|
||||
[ degLon, degLat],
|
||||
[-degLon, degLat]
|
||||
];
|
||||
|
||||
// Rotace a posun
|
||||
const rotated = corners.map(([dx, dy]) => {
|
||||
const x = dx;
|
||||
const y = dy;
|
||||
|
||||
const rotatedX = x * Math.cos(rotation) - y * Math.sin(rotation);
|
||||
const rotatedY = x * Math.sin(rotation) + y * Math.cos(rotation);
|
||||
|
||||
return [lon + rotatedX, lat + rotatedY];
|
||||
});
|
||||
|
||||
// Uzavření polygonu
|
||||
rotated.push(rotated[0]);
|
||||
|
||||
return {
|
||||
type: "Feature",
|
||||
geometry: {
|
||||
type: "Polygon",
|
||||
coordinates: [rotated]
|
||||
},
|
||||
properties: {}
|
||||
};*/
|
||||
Reference in New Issue
Block a user