296 lines
11 KiB
JavaScript
296 lines
11 KiB
JavaScript
import { getArrowPolygon } from "athena-utils/shape/Arrow.js";
|
|
import { getFrontline } from "./Frontline.js";
|
|
import { LEFT_SIDE, RIGHT_SIDE, BOTH_SIDES } from "athena-utils/shape/Frontline.js";
|
|
import { handleDraw, handleClick, showArrowEditor, hideArrowEditor, showFrontlineEditor, hideFrontlineEditor, handleDelete, drawOnMap } from "./DrawingFunctions.js";
|
|
import { arrowParamsMap, frontlineParamsMap, currentFeature, setCurrentFeature} from "./DrawingFunctions.js";
|
|
|
|
export const ARROW = "arrow";
|
|
export const FRONTLINE = "frontline";
|
|
export const ADDITIONAL_SIDE = "additionalSide"; // used for Id in BOTH_SIDES style
|
|
|
|
let currentDrawStyle = ARROW;
|
|
|
|
mapboxgl.accessToken = 'pk.eyJ1Ijoib3V0ZG9vcm1hcHBpbmdjb21wYW55IiwiYSI6ImNqYmh3cDdjYzNsMnozNGxsYzlvMmk2bTYifQ.QqcZ4LVoLWnXafXdjZxnZg';
|
|
|
|
const map = new mapboxgl.Map({
|
|
container: 'map',
|
|
style: 'mapbox://styles/mapbox/streets-v12',
|
|
center: [10, 50],
|
|
zoom: 5
|
|
});
|
|
|
|
// Drawing visuals
|
|
const draw = new MapboxDraw({
|
|
displayControlsDefault: false,
|
|
controls: {
|
|
line_string: true
|
|
},
|
|
defaultMode: 'draw_line_string',
|
|
styles: [
|
|
// Main drawing line
|
|
{
|
|
id: 'gl-draw-line',
|
|
type: 'line',
|
|
filter: ['all', ['==', '$type', 'LineString'], ['==', 'active', 'true']],
|
|
layout: {
|
|
'line-cap': 'round',
|
|
'line-join': 'round'
|
|
},
|
|
paint: {
|
|
'line-color': 'rgb(0, 255, 0)',
|
|
'line-width': 4
|
|
}
|
|
},
|
|
// This makes the nonstop visible line invisible
|
|
{
|
|
id: 'gl-draw-line-inactive',
|
|
type: 'line',
|
|
filter: ['all', ['==', '$type', 'LineString'], ['==', 'deactive', 'false']],
|
|
layout: {
|
|
'line-cap': 'round',
|
|
'line-join': 'round'
|
|
},
|
|
paint: {
|
|
'line-color': 'rgba(0, 0, 0, 0)',
|
|
'line-width': 2
|
|
}
|
|
},
|
|
// Selected point
|
|
{
|
|
id: 'gl-draw-polygon-and-line-vertex-active',
|
|
type: 'circle',
|
|
filter: ['all', ['==', '$type', 'Point'], ['==', 'meta', 'vertex'], ['==', 'active', 'true']],
|
|
paint: {
|
|
'circle-radius': 6,
|
|
'circle-color': 'rgb(255, 255, 0)'
|
|
}
|
|
},
|
|
// Main points
|
|
{
|
|
id: 'gl-draw-polygon-and-line-vertex-inactive',
|
|
type: 'circle',
|
|
filter: ['all', ['==', '$type', 'Point'], ['==', 'meta', 'vertex'], ['==', 'active', 'false']],
|
|
paint: {
|
|
'circle-radius': 4,
|
|
'circle-color': 'rgb(0, 255, 0)'
|
|
}
|
|
},
|
|
// Midpoints
|
|
{
|
|
id: 'gl-draw-polygon-midpoint',
|
|
type: 'circle',
|
|
filter: ['all', ['==', '$type', 'Point'], ['==', 'meta', 'midpoint']],
|
|
paint: {
|
|
'circle-radius': 4,
|
|
'circle-color': 'rgb(0, 255, 174)'
|
|
}
|
|
}
|
|
]
|
|
});
|
|
|
|
// Map controlls
|
|
map.addControl(draw, 'top-left');
|
|
map.on('draw.create', (e) => {
|
|
handleDraw(e, map, draw, currentDrawStyle)
|
|
});
|
|
map.on('draw.update', (e) => {
|
|
handleDraw(e, map, draw, currentDrawStyle)
|
|
});
|
|
map.on('click', (e) => {
|
|
hideArrowEditor();
|
|
hideFrontlineEditor();
|
|
handleClick(e, ARROW, arrowParamsMap, showArrowEditor, map, draw, currentDrawStyle);
|
|
handleClick(e, FRONTLINE, frontlineParamsMap, showFrontlineEditor, map, draw, currentDrawStyle);
|
|
});
|
|
map.dragPan.enable();
|
|
|
|
export function updateButtonStyles(drawStyle) {
|
|
currentDrawStyle = drawStyle;
|
|
const buttonsContainer = document.getElementById('drawStyleButtons');
|
|
Array.from(buttonsContainer.querySelectorAll('button')).forEach(btn => {
|
|
const isSelected = btn.getAttribute('data-style') === drawStyle;
|
|
btn.style.backgroundColor = isSelected ? '#333' : '#f0f0f0';
|
|
btn.style.color = isSelected ? '#fff' : '#000';
|
|
});
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
document.getElementById('removeArrow').addEventListener('click', () => {
|
|
handleDelete(ARROW, map, draw);
|
|
});
|
|
|
|
document.getElementById('removeFrontline').addEventListener('click', () => {
|
|
handleDelete(FRONTLINE, map, draw);
|
|
});
|
|
|
|
document.getElementById('applyArrowChanges').addEventListener('click', () => {
|
|
if (!currentFeature) return;
|
|
|
|
const coords = currentFeature.geometry.coordinates;
|
|
const id = currentFeature.id;
|
|
|
|
const splineStep = parseFloat(document.getElementById('splineStep').value);
|
|
const offsetDistance = parseFloat(document.getElementById('offsetDistance').value);
|
|
const range = parseFloat(document.getElementById('range').value);
|
|
const minValue = parseFloat(document.getElementById('minValue').value);
|
|
const widthArrow = parseFloat(document.getElementById('widthArrow').value);
|
|
const lengthArrow = parseFloat(document.getElementById('lengthArrow').value);
|
|
const calculation = parseInt(document.getElementById('styleArrow').value);
|
|
|
|
const fillColor = document.getElementById('arrowFillColor').value;
|
|
const outlineColor = document.getElementById('arrowOutlineColor').value;
|
|
const opacity = parseFloat(document.getElementById('arrowOpacity').value);
|
|
|
|
const paintOptions = {
|
|
'fill-color': fillColor,
|
|
'fill-outline-color': outlineColor,
|
|
'fill-opacity': opacity
|
|
};
|
|
|
|
arrowParamsMap.set(id, {
|
|
splineStep,
|
|
offsetDistance,
|
|
calculation,
|
|
range,
|
|
minValue,
|
|
widthArrow,
|
|
lengthArrow,
|
|
paintOptions
|
|
});
|
|
|
|
const arrowGeoJSON = getArrowPolygon({
|
|
points: coords,
|
|
splineStep,
|
|
offsetDistance
|
|
}, {
|
|
calculation,
|
|
range,
|
|
minValue
|
|
}, {
|
|
widthArrow,
|
|
lengthArrow
|
|
});
|
|
|
|
//ARROW
|
|
const arrowLayerId = ARROW + "-" + id;
|
|
if (map.getLayer(arrowLayerId)) map.removeLayer(arrowLayerId);
|
|
if (map.getSource(arrowLayerId)) map.removeSource(arrowLayerId);
|
|
|
|
drawOnMap(arrowGeoJSON, ARROW + "-" + id, paintOptions, map);
|
|
|
|
const allFeatures = draw.getAll().features;
|
|
setCurrentFeature(allFeatures.find(f => f.id === id));
|
|
});
|
|
|
|
document.getElementById('applyFrontlineChanges').addEventListener('click', () => {
|
|
if (!currentFeature) return;
|
|
|
|
const coords = currentFeature.geometry.coordinates;
|
|
const id = currentFeature.id;
|
|
|
|
const splineStep = parseFloat(document.getElementById('splineStepFrontline').value);
|
|
const offsetDistance = parseFloat(document.getElementById('offsetDistanceFrontline').value);
|
|
const style = parseInt(document.getElementById('styleFrontline').value);
|
|
|
|
const length = parseFloat(document.getElementById('protrusionLength').value);
|
|
const startSize = parseFloat(document.getElementById('protrusionStartSize').value);
|
|
const endSize = parseFloat(document.getElementById('protrusionEndSize').value);
|
|
const gap = parseFloat(document.getElementById('protrusionGap').value);
|
|
|
|
const fillColorLeft = document.getElementById('frontlineFillColorLeft').value;
|
|
const outlineColorLeft = document.getElementById('frontlineOutlineColorLeft').value;
|
|
const opacityLeft = parseFloat(document.getElementById('frontlineOpacityLeft').value);
|
|
const paintOptionsLeft = {
|
|
'fill-color': fillColorLeft,
|
|
'fill-outline-color': outlineColorLeft,
|
|
'fill-opacity': opacityLeft
|
|
};
|
|
|
|
const fillColorRight = document.getElementById('frontlineFillColorRight').value;
|
|
const outlineColorRight = document.getElementById('frontlineOutlineColorRight').value;
|
|
const opacityRight = parseFloat(document.getElementById('frontlineOpacityRight').value);
|
|
const paintOptionsRight = {
|
|
'fill-color': fillColorRight,
|
|
'fill-outline-color': outlineColorRight,
|
|
'fill-opacity': opacityRight
|
|
};
|
|
|
|
frontlineParamsMap.set(id, {
|
|
splineStep,
|
|
offsetDistance,
|
|
style,
|
|
protrusion: {
|
|
length,
|
|
startSize,
|
|
endSize,
|
|
gap
|
|
},
|
|
paintOptionsLeft,
|
|
paintOptionsRight
|
|
});
|
|
|
|
const frontlineData = {
|
|
points: coords,
|
|
splineStep,
|
|
offsetDistance,
|
|
style
|
|
};
|
|
|
|
const protrusionData = frontlineParamsMap.get(id).protrusion;
|
|
const frontlineGeoJSON = getFrontline(frontlineData, protrusionData);
|
|
let polygonToDraw = frontlineGeoJSON;
|
|
|
|
if (frontlineGeoJSON.leftPoly || frontlineGeoJSON.rightPoly) {
|
|
polygonToDraw = frontlineGeoJSON.leftPoly || frontlineGeoJSON.rightPoly;
|
|
}
|
|
if(frontlineGeoJSON.leftPoly && frontlineGeoJSON.rightPoly){
|
|
let polygonToDrawLeft = frontlineGeoJSON.leftPoly;
|
|
let polygonToDrawRight = frontlineGeoJSON.rightPoly;
|
|
const frontlineLayerId = FRONTLINE + "-" + id;
|
|
|
|
if (map.getLayer(frontlineLayerId)) map.removeLayer(frontlineLayerId);
|
|
if (map.getSource(frontlineLayerId)) map.removeSource(frontlineLayerId);
|
|
|
|
drawOnMap(polygonToDrawLeft, FRONTLINE + "-" + id + ADDITIONAL_SIDE, paintOptionsLeft, map);
|
|
drawOnMap(polygonToDrawRight, FRONTLINE + "-" + (id), paintOptionsRight, map);
|
|
|
|
const allFeatures = draw.getAll().features;
|
|
setCurrentFeature(allFeatures.find(f => f.id === id));
|
|
|
|
return;
|
|
}
|
|
|
|
const frontlineLayerId = FRONTLINE + "-" + id;
|
|
if (map.getLayer(frontlineLayerId + ADDITIONAL_SIDE)) map.removeLayer(frontlineLayerId + ADDITIONAL_SIDE);
|
|
if (map.getSource(frontlineLayerId + ADDITIONAL_SIDE)) map.removeSource(frontlineLayerId + ADDITIONAL_SIDE);
|
|
if (map.getLayer(frontlineLayerId)) map.removeLayer(frontlineLayerId);
|
|
if (map.getSource(frontlineLayerId)) map.removeSource(frontlineLayerId);
|
|
|
|
let paintOptions;
|
|
if(frontlineData.style == LEFT_SIDE){
|
|
paintOptions = paintOptionsLeft;
|
|
}else if(frontlineData.style == RIGHT_SIDE)
|
|
{
|
|
paintOptions = paintOptionsRight;
|
|
}
|
|
|
|
drawOnMap(polygonToDraw, FRONTLINE + "-" + id, paintOptions, map);
|
|
|
|
const allFeatures = draw.getAll().features;
|
|
setCurrentFeature(allFeatures.find(f => f.id === id));
|
|
});
|
|
|
|
const buttonsContainer = document.getElementById('drawStyleButtons');
|
|
buttonsContainer.addEventListener('click', (event) => {
|
|
if (event.target.tagName !== 'BUTTON') return;
|
|
|
|
Array.from(buttonsContainer.querySelectorAll('button')).forEach(btn => btn.classList.remove('active'));
|
|
|
|
event.target.classList.add('active');
|
|
|
|
currentDrawStyle = event.target.getAttribute('data-style');
|
|
updateButtonStyles(currentDrawStyle);
|
|
});
|
|
|
|
updateButtonStyles(currentDrawStyle);
|
|
}); |