graph avancé, coloration et complétion des marqueurs

This commit is contained in:
Tykayn 2025-07-12 13:17:41 +02:00 committed by tykayn
parent d76c06402d
commit 7166eb646a

View file

@ -262,7 +262,16 @@
<script>
const overpassQuery = `{% if overpass_query is defined %}{{ overpass_query|e('js') }}{% endif %}`;
const mapToken = '{{ maptiler_token }}';
// Liste des tags attendus pour la complétion de ce thème
const completionTags = {{ completion_tags[theme]|json_encode|raw }};
let mapInstance = null;
const basemaps = {
'streets': 'https://api.maptiler.com/maps/streets/style.json?key=' + mapToken,
// 'satellite': 'https://data.geopf.fr/annexes/ressources/vectorTiles/styles/BDORTHO/standard.json' // supprimé car non compatible
};
const IGN_RASTER_ID = 'ign-ortho';
const IGN_LAYER_ID = 'ign-ortho-layer';
const IGN_RASTER_URL = 'https://wxs.ign.fr/ortho/geoportail/wmts?layer=ORTHOIMAGERY.ORTHOPHOTOS&style=normal&tilematrixset=PM&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image/jpeg&TileMatrix={z}&TileCol={x}&TileRow={y}';
document.addEventListener('DOMContentLoaded', function() {
if (!overpassQuery) {
document.getElementById('themeMap').innerHTML = '<div class="alert alert-warning">Aucune requête Overpass disponible pour ce thème.</div>';
@ -271,11 +280,43 @@
// Initialiser la carte
mapInstance = new maplibregl.Map({
container: 'themeMap',
style: 'https://api.maptiler.com/maps/streets/style.json?key=' + mapToken,
style: basemaps['streets'],
center: [2, 48],
zoom: 13
});
mapInstance.addControl(new maplibregl.NavigationControl());
// Gestion du changement de fond de carte
const basemapSelect = document.getElementById('basemapSelect');
if (basemapSelect) {
basemapSelect.addEventListener('change', function() {
const val = basemapSelect.value;
if (val === 'streets') {
mapInstance.setStyle(basemaps['streets']);
} else if (val === 'satellite') {
// Ajout du raster IGN comme dans JOSM
if (!mapInstance.getSource(IGN_RASTER_ID)) {
mapInstance.addSource(IGN_RASTER_ID, {
'type': 'raster',
'tiles': [IGN_RASTER_URL],
'tileSize': 256,
'attribution': 'Données © IGN BD Ortho',
'scheme': 'tms',
'minzoom': 0,
'maxzoom': 19
});
}
if (!mapInstance.getLayer(IGN_LAYER_ID)) {
mapInstance.addLayer({
'id': IGN_LAYER_ID,
'type': 'raster',
'source': IGN_RASTER_ID,
'minzoom': 0,
'maxzoom': 19
});
}
}
});
}
// Requête Overpass
fetch('https://overpass-api.de/api/interpreter', {
method: 'POST',
@ -309,13 +350,49 @@
lat = e.center.lat; lon = e.center.lon;
}
if (!lat || !lon) return;
// Calcul de la complétion
let filled = 0;
let missingTags = [];
if (completionTags && completionTags.length > 0) {
completionTags.forEach(tag => {
if (e.tags && typeof e.tags[tag] !== 'undefined' && e.tags[tag] !== null && e.tags[tag] !== '') {
filled++;
} else {
missingTags.push(tag);
}
});
}
let completion = completionTags && completionTags.length > 0 ? Math.round(100 * filled / completionTags.length) : null;
// Couleur dégradée du gris au vert intense
function lerpColor(a, b, t) {
// a et b sont des couleurs hex, t entre 0 et 1
const ah = a.replace('#', '');
const bh = b.replace('#', '');
const ar = parseInt(ah.substring(0,2), 16), ag = parseInt(ah.substring(2,4), 16), ab = parseInt(ah.substring(4,6), 16);
const br = parseInt(bh.substring(0,2), 16), bg = parseInt(bh.substring(2,4), 16), bb = parseInt(bh.substring(4,6), 16);
const rr = Math.round(ar + (br-ar)*t);
const rg = Math.round(ag + (bg-ag)*t);
const rb = Math.round(ab + (bb-ab)*t);
return '#' + rr.toString(16).padStart(2,'0') + rg.toString(16).padStart(2,'0') + rb.toString(16).padStart(2,'0');
}
let color = '#cccccc'; // gris par défaut
if (completion !== null) {
color = lerpColor('#cccccc', '#008000', Math.max(0, Math.min(1, completion/100)));
}
// Affichage des tags manquants
let missingHtml = '';
if (missingTags.length > 0) {
missingHtml = `<div style='color:#b30000;font-size:0.95em;margin-top:4px;'><b>Manque :</b> ${missingTags.map(t => `<code>${t}</code>`).join(', ')}</div>`;
}
const popupHtml = `<div style='min-width:180px'>
<strong>${e.tags && e.tags.name ? e.tags.name : '(sans nom)'}</strong><br>
<span class='text-muted'>${e.type} ${e.id}</span><br>
<span style='font-size:0.95em;'>${e.tags ? Object.entries(e.tags).map(([k,v]) => `<span><b>${k}</b>: ${v}</span>`).join('<br>') : ''}</span><br>
<a href='https://www.openstreetmap.org/${e.type}/${e.id}' target='_blank'>Voir sur OSM</a>
<b>Complétion :</b> ${completion !== null ? completion + '%' : ''}
${missingHtml}
<br><a href='https://www.openstreetmap.org/${e.type}/${e.id}' target='_blank'>Voir sur OSM</a>
</div>`;
new maplibregl.Marker({ color: '#198754' })
new maplibregl.Marker({ color: color })
.setLngLat([lon, lat])
.setPopup(new maplibregl.Popup({ offset: 18 }).setHTML(popupHtml))
.addTo(mapInstance);