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: {} };*/