From 18bcab0a38b7266c0f0a84f7f5e94add46323dec Mon Sep 17 00:00:00 2001 From: Tomas Richtar Date: Sun, 8 Jun 2025 11:51:22 +0200 Subject: [PATCH] Frontline polygon merge --- Frontline.js | 69 +++++++++++++++++++++++++++++++---------- MapPolygons.js | 83 ++++++++++++++++++++++---------------------------- 2 files changed, 90 insertions(+), 62 deletions(-) diff --git a/Frontline.js b/Frontline.js index 795f876..c4e71bf 100644 --- a/Frontline.js +++ b/Frontline.js @@ -73,28 +73,62 @@ export function getFrontline(frontlineData, protrusionData = null) { ...bodyPolygonRight, bodyPolygonRight[0] ]; - + const polygonCoords = [ ...bodyPolygon, bodyPolygon[0] ]; if (style === LEFT_SIDE) { - return { - body: turf.polygon([[...polygonCoords]]), - protrusions: computeProtrusion(leftSidePoints, protrusionData), + let mainPoly = turf.polygon([[...polygonCoords]]); + const protrusions = computeProtrusion(leftSidePoints, protrusionData, frontlineData.offsetDistance); + + for(let i = 0; i <= protrusions.length -1 ; i++) + { + let additionalPoly = protrusions[i]; + mainPoly = turf.union(turf.featureCollection([mainPoly, additionalPoly])); + } + + return { + rightPoly: null, + leftPoly: mainPoly, }; } else if (style === RIGHT_SIDE) { - return { - body: turf.polygon([[...polygonCoords]]), - protrusions: computeProtrusion(rightSidePoints, protrusionData) + let mainPoly = turf.polygon([[...polygonCoords]]); + const protrusions = computeProtrusion(rightSidePoints, protrusionData, frontlineData.offsetDistance); + + for(let i = 0; i <= protrusions.length -1 ; i++) + { + let additionalPoly = protrusions[i]; + mainPoly = turf.union(turf.featureCollection([mainPoly, additionalPoly])); + } + + return { + rightPoly: mainPoly, + leftPoly: null, }; } else if (style === BOTH_SIDES) { + let mainPoly = turf.polygon([[...polygonCoordsRight]]); + const protrusions = computeProtrusion(rightSidePoints, protrusionData, frontlineData.offsetDistance); + + for(let i = 0; i <= protrusions.length -1 ; i++) + { + let additionalPoly = protrusions[i]; + mainPoly = turf.union(turf.featureCollection([mainPoly, additionalPoly])); + } + + let mainPolyLeft = turf.polygon([[...polygonCoordsLeft]]); + const protrusionsLeft = computeProtrusion(leftSidePoints, protrusionData, frontlineData.offsetDistance); + + for(let i = 0; i <= protrusionsLeft.length -1 ; i++) + { + let additionalPoly = protrusionsLeft[i]; + mainPolyLeft = turf.union(turf.featureCollection([mainPolyLeft, additionalPoly])); + } + return { - bodyLeft: turf.polygon([[...polygonCoordsLeft]]), - bodyRight: turf.polygon([[...polygonCoordsRight]]), - protrusionsLeft: computeProtrusion(leftSidePoints, protrusionData), - protrusionsRight: computeProtrusion(rightSidePoints, protrusionData) + rightPoly: mainPoly, + leftPoly: mainPolyLeft, }; } } @@ -152,7 +186,7 @@ function computeSides(splinePoints, offsetDistance, style = LEFT_SIDE) { return { leftSidePoints, rightSidePoints }; } -function computeProtrusion(leftSidePoints, protrusionData) { +function computeProtrusion(leftSidePoints, protrusionData, sideOffset) { const protrusions = []; const segments = []; let totalLength = 0; @@ -170,6 +204,7 @@ function computeProtrusion(leftSidePoints, protrusionData) { for (let d = 0; d <= totalLength - (protrusionData.gap + protrusionData.startSize); d += protrusionData.gap) { positions.push(d + protrusionData.startSize); } + if (positions[positions.length - 1] < totalLength) { positions.push(totalLength - protrusionData.startSize); } @@ -186,16 +221,18 @@ function computeProtrusion(leftSidePoints, protrusionData) { if (currentSegmentIndex >= segments.length) { break; } - + const seg = segments[currentSegmentIndex]; const localDistance = distance - currentSegmentPos; const pointOnSegment = turf.along(turf.lineString([seg.p0, seg.p1]), localDistance, { units: METERS }).geometry.coordinates; + const thicknessOffset = sideOffset * 0.2; + const adjustedPoint = turf.destination(turf.point(pointOnSegment), thicknessOffset, seg.bearing + 90, { units: METERS }).geometry.coordinates; const normalBearing = seg.bearing - 90; const tangentBearing = seg.bearing; - const centerPoint = turf.destination(turf.point(pointOnSegment), protrusionData.length, normalBearing, { units: METERS }).geometry.coordinates; + const centerPoint = turf.destination(turf.point(adjustedPoint), protrusionData.length, normalBearing, { units: METERS }).geometry.coordinates; - const corner1 = turf.destination(turf.point(pointOnSegment), -protrusionData.startSize, tangentBearing, { units: METERS }).geometry.coordinates; - const corner2 = turf.destination(turf.point(pointOnSegment), protrusionData.startSize, tangentBearing, { units: METERS }).geometry.coordinates; + const corner1 = turf.destination(turf.point(adjustedPoint), -protrusionData.startSize, tangentBearing, { units: METERS }).geometry.coordinates; + const corner2 = turf.destination(turf.point(adjustedPoint), protrusionData.startSize, tangentBearing, { units: METERS }).geometry.coordinates; const corner3 = turf.destination(turf.point(centerPoint), protrusionData.endSize, tangentBearing, { units: METERS }).geometry.coordinates; const corner4 = turf.destination(turf.point(centerPoint), -protrusionData.endSize, tangentBearing, { units: METERS }).geometry.coordinates; diff --git a/MapPolygons.js b/MapPolygons.js index 408169b..37d53ea 100644 --- a/MapPolygons.js +++ b/MapPolygons.js @@ -20,39 +20,27 @@ map.on('load', () => { const rectangleBGeoJSON = getRectanglePolygon([20, 20], 2200, 2200); const frontlineGeoJSON = getFrontline(frontlineData, protrusionData); - var frontlineFeatureCollection = []; - var frontlineFeatureCollectionA = []; - - if (frontlineData.style === BOTH_SIDES) { - frontlineFeatureCollection = { - type: "FeatureCollection", - features: [ - frontlineGeoJSON.bodyLeft, - ...frontlineGeoJSON.protrusionsLeft - ] - }; - frontlineFeatureCollectionA = { - type: "FeatureCollection", - features: [ - frontlineGeoJSON.bodyRight, - ...frontlineGeoJSON.protrusionsRight - ] - }; - }else { - frontlineFeatureCollection = { - type: "FeatureCollection", - features: [ - frontlineGeoJSON.body, - ...frontlineGeoJSON.protrusions - ] - }; - }; - // FRONTLINE - map.addSource("frontlinePolygon", { - "type": "geojson", - "data": frontlineFeatureCollection - }); + if (frontlineData.style === LEFT_SIDE){ + map.addSource("frontlinePolygon", { + "type": "geojson", + "data": frontlineGeoJSON.leftPoly + }); + }else if (frontlineData.style === RIGHT_SIDE){ + map.addSource("frontlinePolygon", { + "type": "geojson", + "data": frontlineGeoJSON.rightPoly + }); + } else { + map.addSource("frontlinePolygon", { + "type": "geojson", + "data": frontlineGeoJSON.rightPoly + }); + map.addSource("frontlinePolygonSecond", { + "type": "geojson", + "data": frontlineGeoJSON.leftPoly + }); + } map.addLayer({ "id": "frontlinePolygon", @@ -76,15 +64,10 @@ map.on('load', () => { }); if (frontlineData.style === BOTH_SIDES) { - map.addSource("frontlinePolygonA", { - "type": "geojson", - "data": frontlineFeatureCollectionA - }); - map.addLayer({ - "id": "frontlinePolygonA", + "id": "frontlinePolygonSecond", "type": "fill", - "source": "frontlinePolygonA", + "source": "frontlinePolygonSecond", "layout": {}, "paint": { "fill-color": "green", @@ -92,9 +75,9 @@ map.on('load', () => { } }); map.addLayer({ - "id": "frontlinePolygonA-outline", + "id": "frontlinePolygonSecond-outline", "type": "line", - "source": "frontlinePolygonA", + "source": "frontlinePolygonSecond", "paint": { "line-color": "#000000", "line-width": 2, @@ -254,22 +237,30 @@ const arrowData = { //ARROW //FRONTLINE +/* const frontlinePoints = [ [10.42076, 40.08804], [25.42076, 80.08804], [65.42076, 75.08804] ]; + */ +const frontlinePoints = [ + [14.32076, 50.08804], + [15.42076, 51.08804], + [16.42076, 52.08804], + [18.42076, 50.08804] + ]; const frontlineData = { points: frontlinePoints, splineStep: 0.08, - offsetDistance: 20000, + offsetDistance: 10000, style: BOTH_SIDES, }; const protrusionData = { - length: 30000, - startSize: 10000, - endSize: 1000, - gap: 30000, + length: 15000, + startSize: 5000, + endSize: 500, + gap: 15000, }; //FRONTLINE