graph avancé, coloration et complétion des marqueurs
This commit is contained in:
parent
d76c06402d
commit
7166eb646a
1 changed files with 80 additions and 3 deletions
|
@ -262,7 +262,16 @@
|
||||||
<script>
|
<script>
|
||||||
const overpassQuery = `{% if overpass_query is defined %}{{ overpass_query|e('js') }}{% endif %}`;
|
const overpassQuery = `{% if overpass_query is defined %}{{ overpass_query|e('js') }}{% endif %}`;
|
||||||
const mapToken = '{{ maptiler_token }}';
|
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;
|
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() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
if (!overpassQuery) {
|
if (!overpassQuery) {
|
||||||
document.getElementById('themeMap').innerHTML = '<div class="alert alert-warning">Aucune requête Overpass disponible pour ce thème.</div>';
|
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
|
// Initialiser la carte
|
||||||
mapInstance = new maplibregl.Map({
|
mapInstance = new maplibregl.Map({
|
||||||
container: 'themeMap',
|
container: 'themeMap',
|
||||||
style: 'https://api.maptiler.com/maps/streets/style.json?key=' + mapToken,
|
style: basemaps['streets'],
|
||||||
center: [2, 48],
|
center: [2, 48],
|
||||||
zoom: 13
|
zoom: 13
|
||||||
});
|
});
|
||||||
mapInstance.addControl(new maplibregl.NavigationControl());
|
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
|
// Requête Overpass
|
||||||
fetch('https://overpass-api.de/api/interpreter', {
|
fetch('https://overpass-api.de/api/interpreter', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
@ -309,13 +350,49 @@
|
||||||
lat = e.center.lat; lon = e.center.lon;
|
lat = e.center.lat; lon = e.center.lon;
|
||||||
}
|
}
|
||||||
if (!lat || !lon) return;
|
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'>
|
const popupHtml = `<div style='min-width:180px'>
|
||||||
<strong>${e.tags && e.tags.name ? e.tags.name : '(sans nom)'}</strong><br>
|
<strong>${e.tags && e.tags.name ? e.tags.name : '(sans nom)'}</strong><br>
|
||||||
<span class='text-muted'>${e.type} ${e.id}</span><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>
|
<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>`;
|
</div>`;
|
||||||
new maplibregl.Marker({ color: '#198754' })
|
new maplibregl.Marker({ color: color })
|
||||||
.setLngLat([lon, lat])
|
.setLngLat([lon, lat])
|
||||||
.setPopup(new maplibregl.Popup({ offset: 18 }).setHTML(popupHtml))
|
.setPopup(new maplibregl.Popup({ offset: 18 }).setHTML(popupHtml))
|
||||||
.addTo(mapInstance);
|
.addTo(mapInstance);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue