diff --git a/app/components/Map.tsx b/app/components/Map.tsx
index a26779c..3c3ce3c 100644
--- a/app/components/Map.tsx
+++ b/app/components/Map.tsx
@@ -7,10 +7,14 @@ import {
LayerGroup,
useMap,
} from 'react-leaflet';
-import L from 'leaflet';
-// import L, { LatLngExpression } from 'leaflet';
+// import L from 'leaflet';
+import L, { LatLngExpression } from 'leaflet';
import 'leaflet/dist/leaflet.css';
+import { intersect } from '@turf/intersect';
+import { polygon } from '@turf/helpers';
+import { Position } from 'geojson';
+
import Antennas from './Antennas';
import SectorLobes from './SectorLobes';
import AntennaInfo from './AntennaInfo';
@@ -22,7 +26,7 @@ import { Device } from '../accessPointTypes';
import { useAppSelector, useAppDispatch, useAppStore } from '../../lib/hooks';
// import { AccessPoint, Antenna } from '../types';
-import { AccessPoint } from '../types';
+import { AccessPoint, SectorlobeData } from '../types';
import { initializeActual } from '../../lib/features/actual/actualSlice';
@@ -37,6 +41,45 @@ import {
changeCurrent,
} from '../../lib/features/currentAntennas/currentAntennasSlice';
+import { initializeSectorlobes } from '../../lib/features/sectorlobes/sectorlobesSlice';
+
+function IntersectionInfo({
+ intersections,
+ setPanToCoords,
+}: {
+ intersections: SectorlobeData[][][];
+ setPanToCoords: (coords: L.LatLngExpression) => void;
+}) {
+ return (
+
+ {intersections.map((intersection, index) => {
+ return (
+
+ {intersection.map((pair: SectorlobeData[], index: number) => {
+ const lobe1 = pair[0];
+ const lobe2 = pair[1];
+ return (
+
+
Frequency {lobe1.frequency} intersection between lobes
+
+ {lobe1.id} and {lobe2.id}
+
+
+
+ );
+ })}
+
+ );
+ })}
+
+ );
+}
+
function DynamicCircleRadius() {
const map = useMap();
@@ -69,8 +112,17 @@ function DynamicCircleRadius() {
return null;
}
+function RecenterMap({ panToCoords }: { panToCoords: LatLngExpression }) {
+ const map = useMap();
+ map.setView(panToCoords, map.getZoom());
+ return null;
+}
+
export default function Map() {
const [toggleInfo, setToggleInfo] = useState(false);
+ const [intersections, setIntersections] = useState([]);
+ const [panToCoords, setPanToCoords] = useState(null);
+ const [intersectionToggle, setIntersectionToggle] = useState(false);
const [currentAntenna, setCurrentAntenna] = useState(
null
@@ -83,6 +135,9 @@ export default function Map() {
const actualData = useAppSelector((state) => state.actual.value);
const oldPlaygroundData = useAppSelector((state) => state.playground.old);
+ const sectorlobesData: SectorlobeData[] = useAppSelector(
+ (state) => state.sectorlobes.value
+ );
const antennasData = useAppSelector((state) => state.currentAntennas.value);
const dispatch = useAppDispatch();
@@ -128,10 +183,68 @@ export default function Map() {
})
);
+ const sectorlobeData: SectorlobeData[] = antennasData.map((ap) => {
+ const center: L.LatLngTuple = [
+ parseFloat(ap.lat.trim()),
+ parseFloat(ap.lon.trim()),
+ ];
+ const heading = ap.azimuth;
+ const radiusInMeters = 100;
+ const sectorWidth = 45;
+ let radius: number = 0;
+
+ if (heading < 45) {
+ // 0-45
+ radius = radiusInMeters;
+ } else if (heading < 135) {
+ // 45-135
+ radius = radiusInMeters - (radiusInMeters / 100) * 20;
+ } else if (heading < 225) {
+ // 135-225
+ radius = radiusInMeters;
+ } else if (heading < 315) {
+ // 225-315
+ radius = radiusInMeters - (radiusInMeters / 100) * 20;
+ } else if (heading <= 360) {
+ // 315-360
+ radius = radiusInMeters;
+ }
+ const numberOfVertices: number = 100;
+ const earthCircumferenceAtLatitude =
+ 40008000 * Math.cos((center[0] * Math.PI) / 180);
+
+ const scaleFactor = (radius / earthCircumferenceAtLatitude) * 360;
+ const sectorVertices: LatLngExpression[] = Array.from(
+ { length: numberOfVertices + 1 },
+ (_, index) => {
+ const angle: number =
+ (90 +
+ heading -
+ sectorWidth / 2 +
+ (sectorWidth * index) / numberOfVertices) *
+ (Math.PI / 180);
+
+ const lat: number = center[0] + scaleFactor * Math.sin(angle);
+ // const lng: number = center[1] + scaleFactor * Math.cos(angle) * 0.3;
+ const lng: number = center[1] + scaleFactor * Math.cos(angle);
+
+ return [lat, lng];
+ }
+ );
+ sectorVertices.push(center);
+ return {
+ id: ap.id,
+ center,
+ sectorVertices,
+ frequency: ap.frequency,
+ };
+ });
+
if (!initialized.current) {
store.dispatch(initializeActual(antennasData));
store.dispatch(initializePlayground(antennasData));
store.dispatch(initializeCurrent(antennasData));
+ store.dispatch(initializeSectorlobes(sectorlobeData));
initialized.current = true;
}
}
@@ -161,41 +274,97 @@ export default function Map() {
fetchDataAndSetAntennasData();
}, [store]);
- // function getSectorVertices(
- // center: [number, number],
- // radius: number,
- // heading: number,
- // sectorWidth: number,
- // numberOfVertices: number
- // ): LatLngExpression[] {
- // const earthCircumferenceAtLatitude =
- // 40008000 * Math.cos((center[0] * Math.PI) / 180);
-
- // const scaleFactor = (radius / earthCircumferenceAtLatitude) * 360;
-
- // const sectorVertices: LatLngExpression[] = Array.from(
- // { length: 2 },
- // (_, index) => {
- // const angle: number =
- // (90 +
- // heading -
- // sectorWidth / 2 +
- // (sectorWidth * index) / numberOfVertices) *
- // (Math.PI / 180);
-
- // const lat: number = center[0] + scaleFactor * Math.sin(angle);
- // // const lng: number = center[1] + scaleFactor * Math.cos(angle) * 0.3;
- // const lng: number = center[1] + scaleFactor * Math.cos(angle);
-
- // return [lat, lng];
- // }
- // );
-
- // return sectorVertices;
- // }
+ useEffect(() => {
+ // gather lobes into clusters by frequency
+ if (sectorlobesData.length > 0) {
+ const clusters: { [key: string]: SectorlobeData[] } = {};
+ const foundIntersections: { [key: string]: SectorlobeData[][] } = {};
+ for (const lobe of sectorlobesData) {
+ const key = lobe.frequency.toString();
+ if (!(key in clusters)) {
+ clusters[key] = [];
+ }
+ clusters[key].push(lobe);
+ }
+
+ // for each cluster, find if any lobes overlap
+ for (const key in clusters) {
+ const cluster = clusters[key];
+ for (let i = 0; i < cluster.length; i++) {
+ const lobe1 = cluster[i];
+ for (let j = i + 1; j < cluster.length; j++) {
+ const lobe2 = cluster[j];
+
+ // Convert the LatLngExpression[] to a Position[] for turf.js
+ const lobe1Positions: Position[] = lobe1.sectorVertices.map(
+ (vertex) => {
+ if (Array.isArray(vertex)) {
+ return [vertex[1], vertex[0]];
+ } else {
+ return [vertex.lng, vertex.lat];
+ }
+ }
+ );
+
+ const lobe2Positions: Position[] = lobe2.sectorVertices.map(
+ (vertex) => {
+ if (Array.isArray(vertex)) {
+ return [vertex[1], vertex[0]];
+ } else {
+ return [vertex.lng, vertex.lat];
+ }
+ }
+ );
+
+ const center1: Position = [lobe1.center[1], lobe1.center[0]];
+
+ const center2: Position = [lobe2.center[1], lobe2.center[0]];
+
+ lobe1Positions.unshift(center1);
+ lobe2Positions.unshift(center2);
+
+ const poly1 = polygon([lobe1Positions]);
+ const poly2 = polygon([lobe2Positions]);
+ const intersection = intersect({
+ type: 'FeatureCollection',
+ features: [poly1, poly2],
+ });
+ if (intersection) {
+ if (!(key in foundIntersections)) {
+ foundIntersections[key] = [];
+ }
+ foundIntersections[key].push([lobe1, lobe2]);
+ }
+ }
+ }
+ }
+ setIntersections(Object.values(foundIntersections));
+ }
+ }, [sectorlobesData]);
return (
<>
+
+ {intersections.length > 0 ? (
+
+ Found {intersections.length} intersection
+ {intersections.length > 1 ? 's' : ''}.
+
+ ) : (
+
No intersections found.
+ )}
+ {intersectionToggle && intersections.length > 0 ? (
+
+ setPanToCoords(coords)
+ }
+ />
+ ) : null}
+
+
{toggleInfo ? (
+ {panToCoords ? : null}
{/* Call anything you want to add to the map here. */}
diff --git a/app/components/SectorLobe.tsx b/app/components/SectorLobe.tsx
index 4000b7a..6cbf532 100644
--- a/app/components/SectorLobe.tsx
+++ b/app/components/SectorLobe.tsx
@@ -9,6 +9,7 @@ import { SectorLobeProps } from '../types';
import { useAppSelector, useAppDispatch } from '../../lib/hooks';
import { updateCurrent } from '@/lib/features/currentAntennas/currentAntennasSlice';
+import { updateSectorlobes } from '@/lib/features/sectorlobes/sectorlobesSlice';
export default function SectorLobe({
key_path,
@@ -152,9 +153,18 @@ export default function SectorLobe({
const newAp = { ...currentAp };
newAp.azimuth = tempHeading;
newAp.frequency = tempFreq;
+
+ const newSectorLobe = {
+ id: ap.id,
+ center: center,
+ sectorVertices: sectorVertices,
+ frequency: tempFreq,
+ };
+
setCurrentAp(newAp);
if (currentMode === 'playground') {
dispatch(updateCurrent(newAp));
+ dispatch(updateSectorlobes(newSectorLobe));
}
}
diff --git a/app/components/SectorLobes.tsx b/app/components/SectorLobes.tsx
index da21a6a..b0768fc 100644
--- a/app/components/SectorLobes.tsx
+++ b/app/components/SectorLobes.tsx
@@ -3,13 +3,12 @@ import 'leaflet/dist/leaflet.css';
import SectorLobe from './SectorLobe';
-// ! Current known issues:
+// ! Current known issues/map quirks:
// ! 1. The sectorlobes, when tuned to different headings, the look of the width changes.
// ! This is because the way shapes are warped due to the projection of the map.
// ! 2. The sectorLobes do not represent the actual shape of the sectorLobe.
// ! This is because the sectorLobe is not a cone. It is an ellipse.
// ! So their needs to be a specific algorithm which will aid in the creation of the sectorLobe based on the model of the antenna.
-// ! 3. The sectorlobes do not appear if heading is at 360 degrees
import { useAppSelector } from '../../lib/hooks';
diff --git a/app/types.ts b/app/types.ts
index 689ad08..80295d7 100644
--- a/app/types.ts
+++ b/app/types.ts
@@ -1,3 +1,5 @@
+import { LatLngExpression, LatLngTuple } from 'leaflet';
+
// Interfaces
export type Antenna = {
@@ -38,6 +40,13 @@ export interface ReducedPoints {
[key: string]: ReducedContent;
}
+export interface SectorlobeData {
+ id: string;
+ center: LatLngTuple;
+ sectorVertices: LatLngExpression[];
+ frequency: number;
+}
+
// Props
export interface InfoProps {
diff --git a/lib/features/sectorlobes/sectorlobesSlice.ts b/lib/features/sectorlobes/sectorlobesSlice.ts
new file mode 100644
index 0000000..b5e1612
--- /dev/null
+++ b/lib/features/sectorlobes/sectorlobesSlice.ts
@@ -0,0 +1,50 @@
+import { PayloadAction, createSlice } from '@reduxjs/toolkit';
+
+import { SectorlobeData } from '../../../app/types';
+
+type SectorlobesState = { value: SectorlobeData[] };
+
+export const sectorlobesSlice = createSlice({
+ name: 'sectorlobes',
+ initialState: {
+ value: [],
+ } satisfies SectorlobesState as SectorlobesState,
+ reducers: {
+ initializeSectorlobes: (state, action: PayloadAction) => {
+ return { ...state, value: action.payload, old: action.payload };
+ },
+ replaceSectorlobes: (state, action: PayloadAction) => {
+ return { ...state, value: action.payload };
+ },
+ addSectorlobes: (state, action: PayloadAction) => {
+ return { ...state, value: [...state.value, action.payload] };
+ },
+ removeSectorlobes: (state, action: PayloadAction) => {
+ return {
+ ...state,
+ value: state.value.filter((item) => item.id !== action.payload.id),
+ };
+ },
+ updateSectorlobes: (state, action: PayloadAction) => {
+ const newArray = state.value.map((item) => {
+ if (item.id === action.payload.id) {
+ return action.payload;
+ }
+ return item;
+ });
+ state = { ...state, value: newArray };
+ },
+ },
+});
+
+export const {
+ initializeSectorlobes,
+ replaceSectorlobes,
+ addSectorlobes,
+ removeSectorlobes,
+ updateSectorlobes,
+} = sectorlobesSlice.actions;
+
+export default sectorlobesSlice.reducer;
+
+// https://redux-toolkit.js.org/usage/usage-with-typescript
diff --git a/lib/store.ts b/lib/store.ts
index 1410478..af7d34e 100644
--- a/lib/store.ts
+++ b/lib/store.ts
@@ -2,6 +2,7 @@ import { configureStore } from '@reduxjs/toolkit';
import playgroundReducer from './features/playground/playgroundSlice';
import actualReducer from './features/actual/actualSlice';
import currentAntennasReducer from './features/currentAntennas/currentAntennasSlice';
+import sectorlobesReducer from './features/sectorlobes/sectorlobesSlice';
export const makeStore = () => {
return configureStore({
@@ -9,6 +10,7 @@ export const makeStore = () => {
playground: playgroundReducer,
actual: actualReducer,
currentAntennas: currentAntennasReducer,
+ sectorlobes: sectorlobesReducer,
},
});
};
diff --git a/package-lock.json b/package-lock.json
index 1b4fc41..8ac827a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,8 @@
"version": "0.1.0",
"dependencies": {
"@reduxjs/toolkit": "^2.2.1",
+ "@turf/helpers": "^7.0.0-alpha.114",
+ "@turf/intersect": "^7.0.0-alpha.114",
"cors": "^2.8.5",
"cypress": "^13.6.4",
"dotenv": "^16.4.2",
@@ -3331,6 +3333,43 @@
"node": ">= 10"
}
},
+ "node_modules/@turf/helpers": {
+ "version": "7.0.0-alpha.114",
+ "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-7.0.0-alpha.114.tgz",
+ "integrity": "sha512-hqoARkwAaFMK/8wOWDQhmvIxjUL2l9jUhn1GUzW3fsumImPxuHoJZbIZhiHjE7ceQngveCeUCtkiKw89lekN8w==",
+ "dependencies": {
+ "deep-equal": "^2.2.3",
+ "tslib": "^2.6.2"
+ },
+ "funding": {
+ "url": "https://opencollective.com/turf"
+ }
+ },
+ "node_modules/@turf/intersect": {
+ "version": "7.0.0-alpha.114",
+ "resolved": "https://registry.npmjs.org/@turf/intersect/-/intersect-7.0.0-alpha.114.tgz",
+ "integrity": "sha512-YQ99CzN4atud30pY9brGxECWibOs9S9v5ztsnKUxDdOlqi2+zgP5LHOrKwrydZrDX6qsi0O6RE+w+0/a/cnX+A==",
+ "dependencies": {
+ "@turf/helpers": "^7.0.0-alpha.114+e0bdd0add",
+ "@turf/meta": "^7.0.0-alpha.114+e0bdd0add",
+ "polygon-clipping": "^0.15.3",
+ "tslib": "^2.6.2"
+ },
+ "funding": {
+ "url": "https://opencollective.com/turf"
+ }
+ },
+ "node_modules/@turf/meta": {
+ "version": "7.0.0-alpha.114",
+ "resolved": "https://registry.npmjs.org/@turf/meta/-/meta-7.0.0-alpha.114.tgz",
+ "integrity": "sha512-R/VHKBLqVnPcXaawR7PlXSfgLSPvMUBwe04m2riTPhOrUCrh5/UW3+NTshAg9tjIMk1njsnlpqgUcrG0OYu9OQ==",
+ "dependencies": {
+ "@turf/helpers": "^7.0.0-alpha.114+e0bdd0add"
+ },
+ "funding": {
+ "url": "https://opencollective.com/turf"
+ }
+ },
"node_modules/@types/aria-query": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.3.tgz",
@@ -4304,7 +4343,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz",
"integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==",
- "dev": true,
"dependencies": {
"call-bind": "^1.0.2",
"is-array-buffer": "^3.0.1"
@@ -4528,7 +4566,6 @@
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
"integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
- "dev": true,
"engines": {
"node": ">= 0.4"
},
@@ -5714,15 +5751,14 @@
}
},
"node_modules/deep-equal": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.2.tgz",
- "integrity": "sha512-xjVyBf0w5vH0I42jdAZzOKVldmPgSulmiyPRywoyq7HXC9qdgo17kxJE+rdnif5Tz6+pIrpJI8dCpMNLIGkUiA==",
- "dev": true,
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz",
+ "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==",
"dependencies": {
"array-buffer-byte-length": "^1.0.0",
- "call-bind": "^1.0.2",
+ "call-bind": "^1.0.5",
"es-get-iterator": "^1.1.3",
- "get-intrinsic": "^1.2.1",
+ "get-intrinsic": "^1.2.2",
"is-arguments": "^1.1.1",
"is-array-buffer": "^3.0.2",
"is-date-object": "^1.0.5",
@@ -5732,11 +5768,14 @@
"object-is": "^1.1.5",
"object-keys": "^1.1.1",
"object.assign": "^4.1.4",
- "regexp.prototype.flags": "^1.5.0",
+ "regexp.prototype.flags": "^1.5.1",
"side-channel": "^1.0.4",
"which-boxed-primitive": "^1.0.2",
"which-collection": "^1.0.1",
- "which-typed-array": "^1.1.9"
+ "which-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -5942,7 +5981,6 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
- "dev": true,
"dependencies": {
"define-data-property": "^1.0.1",
"has-property-descriptors": "^1.0.0",
@@ -6212,7 +6250,6 @@
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz",
"integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==",
- "dev": true,
"dependencies": {
"call-bind": "^1.0.2",
"get-intrinsic": "^1.1.3",
@@ -7215,7 +7252,6 @@
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
"integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
- "dev": true,
"dependencies": {
"is-callable": "^1.1.3"
}
@@ -7326,7 +7362,6 @@
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
"integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
- "dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -7551,7 +7586,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
"integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
- "dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -7601,7 +7635,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
"integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
- "dev": true,
"dependencies": {
"has-symbols": "^1.0.2"
},
@@ -7861,7 +7894,6 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz",
"integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==",
- "dev": true,
"dependencies": {
"get-intrinsic": "^1.2.2",
"hasown": "^2.0.0",
@@ -7875,7 +7907,6 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
"integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
- "dev": true,
"dependencies": {
"call-bind": "^1.0.2",
"has-tostringtag": "^1.0.0"
@@ -7891,7 +7922,6 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz",
"integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==",
- "dev": true,
"dependencies": {
"call-bind": "^1.0.2",
"get-intrinsic": "^1.2.0",
@@ -7926,7 +7956,6 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
"integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
- "dev": true,
"dependencies": {
"has-bigints": "^1.0.1"
},
@@ -7950,7 +7979,6 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
"integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
- "dev": true,
"dependencies": {
"call-bind": "^1.0.2",
"has-tostringtag": "^1.0.0"
@@ -7966,7 +7994,6 @@
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
"integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
- "dev": true,
"engines": {
"node": ">= 0.4"
},
@@ -8001,7 +8028,6 @@
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
"integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
- "dev": true,
"dependencies": {
"has-tostringtag": "^1.0.0"
},
@@ -8129,7 +8155,6 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz",
"integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==",
- "dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -8158,7 +8183,6 @@
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
"integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
- "dev": true,
"dependencies": {
"has-tostringtag": "^1.0.0"
},
@@ -8187,7 +8211,6 @@
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
"integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
- "dev": true,
"dependencies": {
"call-bind": "^1.0.2",
"has-tostringtag": "^1.0.0"
@@ -8203,7 +8226,6 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz",
"integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==",
- "dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -8212,7 +8234,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
"integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
- "dev": true,
"dependencies": {
"call-bind": "^1.0.2"
},
@@ -8235,7 +8256,6 @@
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
"integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
- "dev": true,
"dependencies": {
"has-tostringtag": "^1.0.0"
},
@@ -8250,7 +8270,6 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
"integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
- "dev": true,
"dependencies": {
"has-symbols": "^1.0.2"
},
@@ -8265,7 +8284,6 @@
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz",
"integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==",
- "dev": true,
"dependencies": {
"which-typed-array": "^1.1.11"
},
@@ -8296,7 +8314,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz",
"integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==",
- "dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -8317,7 +8334,6 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz",
"integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==",
- "dev": true,
"dependencies": {
"call-bind": "^1.0.2",
"get-intrinsic": "^1.1.1"
@@ -8356,8 +8372,7 @@
"node_modules/isarray": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
- "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
- "dev": true
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
},
"node_modules/isexe": {
"version": "2.0.0",
@@ -14685,7 +14700,6 @@
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz",
"integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==",
- "dev": true,
"dependencies": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.3"
@@ -14701,7 +14715,6 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
- "dev": true,
"engines": {
"node": ">= 0.4"
}
@@ -14710,7 +14723,6 @@
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
"integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
- "dev": true,
"dependencies": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.4",
@@ -15281,6 +15293,15 @@
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
+ "node_modules/polygon-clipping": {
+ "version": "0.15.7",
+ "resolved": "https://registry.npmjs.org/polygon-clipping/-/polygon-clipping-0.15.7.tgz",
+ "integrity": "sha512-nhfdr83ECBg6xtqOAJab1tbksbBAOMUltN60bU+llHVOL0e5Onm1WpAXXWXVB39L8AJFssoIhEVuy/S90MmotA==",
+ "dependencies": {
+ "robust-predicates": "^3.0.2",
+ "splaytree": "^3.1.0"
+ }
+ },
"node_modules/postcss": {
"version": "8.4.32",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz",
@@ -15830,7 +15851,6 @@
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz",
"integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==",
- "dev": true,
"dependencies": {
"call-bind": "^1.0.2",
"define-properties": "^1.2.0",
@@ -16005,6 +16025,11 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/robust-predicates": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz",
+ "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg=="
+ },
"node_modules/run-applescript": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz",
@@ -16198,7 +16223,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz",
"integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==",
- "dev": true,
"dependencies": {
"define-data-property": "^1.0.1",
"functions-have-names": "^1.2.3",
@@ -16329,6 +16353,11 @@
"source-map": "^0.6.0"
}
},
+ "node_modules/splaytree": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/splaytree/-/splaytree-3.1.2.tgz",
+ "integrity": "sha512-4OM2BJgC5UzrhVnnJA4BkHKGtjXNzzUfpQjCO8I05xYPsfS/VuQDwjCGGMi8rYQilHEV4j8NBqTFbls/PZEE7A=="
+ },
"node_modules/split2": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
@@ -16390,7 +16419,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz",
"integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==",
- "dev": true,
"dependencies": {
"internal-slot": "^1.0.4"
},
@@ -17393,7 +17421,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
"integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
- "dev": true,
"dependencies": {
"is-bigint": "^1.0.1",
"is-boolean-object": "^1.1.0",
@@ -17435,7 +17462,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz",
"integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==",
- "dev": true,
"dependencies": {
"is-map": "^2.0.1",
"is-set": "^2.0.1",
@@ -17450,7 +17476,6 @@
"version": "1.1.13",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz",
"integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==",
- "dev": true,
"dependencies": {
"available-typed-arrays": "^1.0.5",
"call-bind": "^1.0.4",
diff --git a/package.json b/package.json
index 0786af7..2521c96 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,8 @@
},
"dependencies": {
"@reduxjs/toolkit": "^2.2.1",
+ "@turf/helpers": "^7.0.0-alpha.114",
+ "@turf/intersect": "^7.0.0-alpha.114",
"cors": "^2.8.5",
"cypress": "^13.6.4",
"dotenv": "^16.4.2",