feat: create new base template for public occupation authorization requests
This commit is contained in:
parent
c90ee9ece5
commit
cb9e8a1c8b
1 changed files with 124 additions and 51 deletions
|
|
@ -219,9 +219,6 @@
|
||||||
<button type="button" id="poly-draw-btn" class="btn btn-sm btn-outline-success">
|
<button type="button" id="poly-draw-btn" class="btn btn-sm btn-outline-success">
|
||||||
<i class="bi bi-pentagon"></i> {% translate "Dessiner un polygone" %}
|
<i class="bi bi-pentagon"></i> {% translate "Dessiner un polygone" %}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" id="poly-finish-btn" class="btn btn-sm btn-success d-none">
|
|
||||||
<i class="bi bi-check-circle"></i> {% translate "Terminer" %}
|
|
||||||
</button>
|
|
||||||
<button type="button" id="poly-clear-btn" class="btn btn-sm btn-outline-danger">
|
<button type="button" id="poly-clear-btn" class="btn btn-sm btn-outline-danger">
|
||||||
<i class="bi bi-x-circle"></i> {% translate "Effacer" %}
|
<i class="bi bi-x-circle"></i> {% translate "Effacer" %}
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -478,52 +475,118 @@
|
||||||
if (!drawing) return;
|
if (!drawing) return;
|
||||||
addVertex(e.lngLat.lng, e.lngLat.lat);
|
addVertex(e.lngLat.lng, e.lngLat.lat);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
map.on('dblclick', function (e) {
|
||||||
|
if (!drawing) return;
|
||||||
|
e.preventDefault();
|
||||||
|
handleDoubleClick();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function addVertex(lng, lat) {
|
function addVertex(lng, lat) {
|
||||||
vertices.push([lng, lat]);
|
vertices.push([lng, lat]);
|
||||||
|
const isFirst = markers.length === 0;
|
||||||
|
|
||||||
const el = document.createElement('div');
|
const el = document.createElement('div');
|
||||||
el.style.cssText = 'width:10px;height:10px;border-radius:50%;background:#0d6efd;border:2px solid #fff;box-shadow:0 0 3px rgba(0,0,0,.4);cursor:pointer;';
|
if (isFirst) {
|
||||||
|
el.className = 'poly-marker poly-marker-first';
|
||||||
|
el.style.cssText = 'width:14px;height:14px;border-radius:50%;background:#198754;border:2px solid #fff;box-shadow:0 0 4px rgba(0,0,0,.5);cursor:pointer;transition:transform 0.15s;';
|
||||||
|
el.title = '{% translate "Cliquer pour fermer le polygone" %}';
|
||||||
|
el.addEventListener('mouseenter', function () {
|
||||||
|
if (vertices.length >= 3) el.style.transform = 'scale(1.3)';
|
||||||
|
});
|
||||||
|
el.addEventListener('mouseleave', function () {
|
||||||
|
el.style.transform = 'scale(1)';
|
||||||
|
});
|
||||||
|
el.addEventListener('click', function (ev) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
if (vertices.length >= 3) {
|
||||||
|
finishPolygon();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
el.className = 'poly-marker';
|
||||||
|
el.style.cssText = 'width:10px;height:10px;border-radius:50%;background:#0d6efd;border:2px solid #fff;box-shadow:0 0 3px rgba(0,0,0,.4);cursor:default;';
|
||||||
|
}
|
||||||
|
|
||||||
const marker = new maplibregl.Marker({ element: el }).setLngLat([lng, lat]).addTo(map);
|
const marker = new maplibregl.Marker({ element: el }).setLngLat([lng, lat]).addTo(map);
|
||||||
markers.push(marker);
|
markers.push(marker);
|
||||||
|
|
||||||
// Clicking the first vertex closes the polygon
|
|
||||||
if (markers.length === 1) {
|
|
||||||
el.title = '{% translate "Cliquer pour fermer le polygone" %}';
|
|
||||||
el.addEventListener('click', function (ev) {
|
|
||||||
ev.stopPropagation();
|
|
||||||
finishPolygon();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
renderPreview();
|
renderPreview();
|
||||||
|
updateGeoJSON();
|
||||||
|
updateHint();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDoubleClick() {
|
||||||
|
if (!drawing) return;
|
||||||
|
// In MapLibre, dblclick triggers two click events first.
|
||||||
|
// Remove the duplicated last vertex if close to the preceding one.
|
||||||
|
if (vertices.length >= 2) {
|
||||||
|
const last = vertices[vertices.length - 1];
|
||||||
|
const prev = vertices[vertices.length - 2];
|
||||||
|
if (Math.hypot(last[0] - prev[0], last[1] - prev[1]) < 0.0001) {
|
||||||
|
vertices.pop();
|
||||||
|
const lastMarker = markers.pop();
|
||||||
|
if (lastMarker) lastMarker.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (vertices.length >= 3) {
|
||||||
|
finishPolygon();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateGeoJSON() {
|
||||||
|
if (vertices.length >= 3) {
|
||||||
|
const coords = [vertices.concat([vertices[0]])];
|
||||||
|
const geojson = JSON.stringify({ type: 'Polygon', coordinates: coords });
|
||||||
|
document.getElementById('id_geom_geojson').value = geojson;
|
||||||
|
} else {
|
||||||
|
document.getElementById('id_geom_geojson').value = '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderPreview() {
|
function renderPreview() {
|
||||||
if (!map.getSource('poly-preview')) return;
|
if (!map.getSource('poly-preview')) return;
|
||||||
const coords = vertices.length >= 3
|
if (vertices.length >= 3) {
|
||||||
? [vertices.concat([vertices[0]])]
|
const coords = [vertices.concat([vertices[0]])];
|
||||||
: [];
|
map.getSource('poly-preview').setData({
|
||||||
const geojson = coords.length ? {
|
type: 'Feature',
|
||||||
type: 'Feature',
|
geometry: { type: 'Polygon', coordinates: coords },
|
||||||
geometry: { type: 'Polygon', coordinates: coords },
|
});
|
||||||
} : { type: 'FeatureCollection', features: [] };
|
} else if (vertices.length === 2) {
|
||||||
map.getSource('poly-preview').setData(geojson);
|
map.getSource('poly-preview').setData({
|
||||||
|
type: 'Feature',
|
||||||
|
geometry: { type: 'LineString', coordinates: vertices },
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
map.getSource('poly-preview').setData({
|
||||||
|
type: 'FeatureCollection',
|
||||||
|
features: [],
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function finishPolygon() {
|
function updateHint() {
|
||||||
if (vertices.length < 3) return;
|
const hintEl = document.getElementById('poly-hint');
|
||||||
drawing = false;
|
if (!hintEl) return;
|
||||||
const geojson = JSON.stringify({ type: 'Polygon', coordinates: [vertices.concat([vertices[0]])] });
|
if (!drawing) {
|
||||||
document.getElementById('id_geom_geojson').value = geojson;
|
if (vertices.length >= 3 || document.getElementById('id_geom_geojson').value) {
|
||||||
renderPreview();
|
hintEl.textContent = '{% translate "Polygone enregistré. Cliquez sur « Dessiner » pour le redessiner." %}';
|
||||||
updateUI(false);
|
} else {
|
||||||
document.getElementById('poly-hint').textContent =
|
hintEl.textContent = '{% translate "Cliquez sur « Dessiner un polygone » puis cliquez sur la carte pour ajouter des sommets. Cliquez sur le premier sommet pour fermer le polygone." %}';
|
||||||
'{% translate "Polygone enregistré. Cliquez sur « Dessiner » pour le redessiner." %}';
|
}
|
||||||
map.getCanvas().style.cursor = 'default';
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vertices.length <= 1) {
|
||||||
|
hintEl.textContent = '{% translate "Cliquez sur la carte pour ajouter des sommets." %}';
|
||||||
|
} else {
|
||||||
|
hintEl.textContent = '{% translate "Cliquez sur la carte pour ajouter des sommets. Cliquez sur le premier sommet pour fermer le polygone." %}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearPolygon() {
|
function startDrawing() {
|
||||||
drawing = false;
|
drawing = true;
|
||||||
vertices = [];
|
vertices = [];
|
||||||
markers.forEach(m => m.remove());
|
markers.forEach(m => m.remove());
|
||||||
markers = [];
|
markers = [];
|
||||||
|
|
@ -531,35 +594,45 @@
|
||||||
if (map.getSource('poly-preview')) {
|
if (map.getSource('poly-preview')) {
|
||||||
map.getSource('poly-preview').setData({ type: 'FeatureCollection', features: [] });
|
map.getSource('poly-preview').setData({ type: 'FeatureCollection', features: [] });
|
||||||
}
|
}
|
||||||
updateUI(false);
|
map.doubleClickZoom.disable();
|
||||||
document.getElementById('poly-hint').textContent =
|
map.getCanvas().style.cursor = 'crosshair';
|
||||||
'{% translate "Cliquez sur « Dessiner un polygone » puis cliquez sur la carte pour ajouter des sommets." %}';
|
document.getElementById('poly-draw-btn').classList.add('active');
|
||||||
map.getCanvas().style.cursor = 'default';
|
updateHint();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateUI(isDrawing) {
|
function finishPolygon() {
|
||||||
document.getElementById('poly-draw-btn').classList.toggle('d-none', isDrawing);
|
if (vertices.length < 3) return;
|
||||||
document.getElementById('poly-finish-btn').classList.toggle('d-none', !isDrawing);
|
drawing = false;
|
||||||
map.getCanvas().style.cursor = isDrawing ? 'crosshair' : 'default';
|
map.doubleClickZoom.enable();
|
||||||
|
map.getCanvas().style.cursor = 'default';
|
||||||
|
updateGeoJSON();
|
||||||
|
renderPreview();
|
||||||
|
document.getElementById('poly-draw-btn').classList.remove('active');
|
||||||
|
updateHint();
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearPolygon() {
|
||||||
|
drawing = false;
|
||||||
|
map.doubleClickZoom.enable();
|
||||||
|
map.getCanvas().style.cursor = 'default';
|
||||||
|
vertices = [];
|
||||||
|
markers.forEach(m => m.remove());
|
||||||
|
markers = [];
|
||||||
|
document.getElementById('id_geom_geojson').value = '';
|
||||||
|
if (map.getSource('poly-preview')) {
|
||||||
|
map.getSource('poly-preview').setData({ type: 'FeatureCollection', features: [] });
|
||||||
|
}
|
||||||
|
document.getElementById('poly-draw-btn').classList.remove('active');
|
||||||
|
updateHint();
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
initMap();
|
initMap();
|
||||||
|
|
||||||
document.getElementById('poly-draw-btn').addEventListener('click', function () {
|
document.getElementById('poly-draw-btn').addEventListener('click', function () {
|
||||||
drawing = true;
|
startDrawing();
|
||||||
vertices = [];
|
|
||||||
markers.forEach(m => m.remove());
|
|
||||||
markers = [];
|
|
||||||
if (map.getSource('poly-preview')) {
|
|
||||||
map.getSource('poly-preview').setData({ type: 'FeatureCollection', features: [] });
|
|
||||||
}
|
|
||||||
updateUI(true);
|
|
||||||
document.getElementById('poly-hint').textContent =
|
|
||||||
'{% translate "Cliquez sur la carte pour ajouter des sommets. Cliquez sur le premier sommet pour fermer le polygone." %}';
|
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('poly-finish-btn').addEventListener('click', finishPolygon);
|
|
||||||
document.getElementById('poly-clear-btn').addEventListener('click', clearPolygon);
|
document.getElementById('poly-clear-btn').addEventListener('click', clearPolygon);
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue