Frontline polygon merge

This commit is contained in:
Tomas Richtar 2025-06-08 11:51:22 +02:00
parent 355fdd0c09
commit 18bcab0a38
2 changed files with 90 additions and 62 deletions

View File

@ -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;

View File

@ -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