fix popup infos

This commit is contained in:
Tykayn 2025-06-06 15:48:03 +02:00 committed by tykayn
parent ef42dba9dd
commit abdd59e8c8
3 changed files with 192 additions and 118 deletions

View file

@ -118,7 +118,8 @@
let features = [];
let maplibre;
let map;
let overpassData = {}; // Stockage des données Overpass
function getCompletionColor(completion) {
if (completion === undefined || completion === null) {
return '#808080'; // Gris pour pas d'information
@ -129,30 +130,27 @@
}
function calculateCompletion(element) {
let completed = 0;
let total = 0;
// Critères à vérifier
const criteria = [
let completionCount = 0;
let totalFields = 0;
const fieldsToCheck = [
'name',
'addr:street',
'addr:housenumber',
'addr:postcode',
'addr:city',
'contact:street',
'contact:housenumber',
'opening_hours',
'website',
'wheelchair',
'phone'
'contact:website',
'contact:phone',
'wheelchair'
];
criteria.forEach(criterion => {
if (element.tags && element.tags[criterion]) {
completed++;
fieldsToCheck.forEach(field => {
totalFields++;
if (element.tags && element.tags[field]) {
completionCount++;
}
total++;
});
return total > 0 ? (completed / total) * 100 : 0;
return (completionCount / totalFields) * 100;
}
function createPopupContent(element) {
@ -254,8 +252,8 @@
let josm_elements = [];
async function loadPlaces(map) {
map_is_loaded = false;
try {
const request = `{{query_places |raw}}`;
const response = await fetch('https://overpass-api.de/api/interpreter', {
method: 'POST',
body: request
@ -264,46 +262,113 @@
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log('Lieux chargés:', data.elements);
mapElements = data.elements;
map_is_loaded = true;
console.log('Données reçues:', data);
// Créer le graphique de distribution
createCompletionChart(data.elements);
// Stocker les données Overpass
data.elements.forEach(element => {
overpassData[element.id] = element;
});
// Mettre à jour les cercles
features = [];
josm_elements = [];
data.elements.forEach(element => {
const lat = element.lat || (element.center && element.center.lat);
const lon = element.lon || (element.center && element.center.lon);
if (lat && lon) {
const completion = calculateCompletion(element);
const color = getCompletionColor(completion);
// Créer un cercle de 20 mètres de rayon (plus petit)
const circle = turf.circle([lon, lat], 0.04, { steps: 64, units: 'kilometers' });
circle.properties = {
color: color,
completion: completion,
name: element.tags?.name || 'Sans nom',
popupContent: createPopupContent(element),
center: [lon, lat] // Stocker le centre comme un tableau [lon, lat]
console.log('Completion pour', element.tags?.name, ':', completion, '%');
const circle = {
id: `circle-${element.id}`,
type: 'Feature',
properties: {
id: element.id,
name: element.tags?.name || 'Sans nom',
completion: completion,
center: [lon, lat]
},
geometry: {
type: 'Point',
coordinates: [lon, lat]
}
};
features.push(circle);
josm_elements.push(element);
}
});
// Mettre à jour la source des cercles
map.getSource('completion-circles').setData({
'type': 'FeatureCollection',
'features': features
// Créer les cercles sur la carte
features.forEach(feature => {
const layerId = `circle-${feature.properties.id}`;
if (map.getSource(layerId)) {
map.removeSource(layerId);
}
if (map.getLayer(layerId)) {
map.removeLayer(layerId);
}
const circle = turf.circle(
feature.properties.center,
0.02, // Rayon initial en kilomètres
{ steps: 64, units: 'kilometers' }
);
map.addSource(layerId, {
'type': 'geojson',
'data': circle
});
map.addLayer({
'id': layerId,
'type': 'fill',
'source': layerId,
'paint': {
'fill-color': getCompletionColor(feature.properties.completion),
'fill-opacity': 0.7
}
});
});
// Calculer les bounds pour tous les points
// Ajouter les popups sur les cercles
map.on('click', function(e) {
const clickedFeatures = map.queryRenderedFeatures(e.point, {
layers: features.map(f => `circle-${f.properties.id}`)
});
console.log('Clicked features:', clickedFeatures);
if (clickedFeatures.length > 0) {
const feature = clickedFeatures[0];
const elementId = feature.layer.id.replace('circle-', '');
const element = overpassData[elementId];
if (element) {
const completion = calculateCompletion(element);
// Créer le contenu de la popup
const popupContent = `
<div class="popup-content">
<h5>${element.tags?.name || 'Sans nom'}</h5>
<p>Taux de complétion: ${Math.round(completion)}%</p>
<ul>
${Object.entries(element.tags || {})
.filter(([key]) => !['name'].includes(key))
.map(([key, value]) => `<li><strong>${key}:</strong> ${value}</li>`)
.join('')}
</ul>
</div>
`;
new maplibregl.Popup()
.setLngLat(e.lngLat)
.setHTML(popupContent)
.addTo(map);
}
}
});
// Ajuster la vue pour inclure tous les points
const points = features.map(f => f.properties.center);
if (points.length > 0) {
const bounds = new maplibregl.LngLatBounds(points[0], points[0]);
@ -319,33 +384,68 @@
console.warn('Bounds invalides, utilisation des coordonnées par défaut');
}
}
createCompletionChart(data.elements);
// Cacher le spinner une fois le chargement terminé
document.getElementById('maploader').style.display = 'none';
document.getElementById('maploader').classList.add('d-none');
} catch (error) {
console.error('Erreur lors du chargement des lieux:', error);
document.getElementById('maploader').classList.add('d-none');
}
}
function updateCircles(map) {
if (!map) return;
function openJOSMQuery(map, query) {
const bounds = map.getBounds();
const zoom = map.getZoom();
// Ajuster la taille de base en fonction du zoom
// Plus le zoom est faible (loin), plus le rayon est grand
const baseRadius = Math.min(100, 200 / Math.pow(1.2, zoom));
const josmUrl = `http://localhost:8111/load_object?` +
features.forEach(feature => {
const source = map.getSource(feature.id);
if (!source) return;
const completion = feature.properties.completion;
const radius = baseRadius * (1 + (completion / 100));
// Mettre à jour le rayon du cercle
const circle = turf.circle(
feature.properties.center,
0.5* radius / 1000, // Convertir en kilomètres
{ steps: 64, units: 'kilometers' }
);
// Mettre à jour la source avec le nouveau cercle
source.setData(circle);
// Mettre à jour la couleur du cercle
const layer = map.getLayer(feature.id);
if (layer) {
map.setPaintProperty(feature.id, 'fill-color', getCompletionColor(completion));
}
});
}
function openJOSMQuery(map, query) {
const bounds = map.getBounds();
const josmUrl = `http://localhost:8111/load_object?` +
`objects=${query}`;
`objects=${query}`;
// Créer un élément <a> temporaire
const tempLink = document.createElement('a');
tempLink.style.display = 'none';
document.body.appendChild(tempLink);
// Créer un élément <a> temporaire
const tempLink = document.createElement('a');
tempLink.style.display = 'none';
document.body.appendChild(tempLink);
console.log('josmUrl', josmUrl);
tempLink.href = josmUrl;
tempLink.click();
document.body.removeChild(tempLink);
}
console.log('josmUrl', josmUrl);
tempLink.href = josmUrl;
tempLink.click();
document.body.removeChild(tempLink);
}
function openInJOSM() {
if (josm_elements.length === 0) {
@ -355,8 +455,6 @@ function openJOSMQuery(map, query) {
const query = createJOSMQuery(josm_elements);
console.log('map', map);
openJOSMQuery(map, query);
}
document.addEventListener('DOMContentLoaded', function() {
@ -372,65 +470,34 @@ function openJOSMQuery(map, query) {
document.getElementById('openInJOSM').addEventListener('click', openInJOSM);
map.on('load', () => {
// Créer une source pour les cercles
map.addSource('completion-circles', {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features': []
}
});
// Ajouter une couche pour les cercles
map.addLayer({
'id': 'completion-circles',
'type': 'fill',
'source': 'completion-circles',
'paint': {
'fill-color': ['get', 'color'],
'fill-opacity': 0.6,
'fill-outline-color': '#fff'
}
});
// Ajouter une couche pour la bordure
map.addLayer({
'id': 'completion-circles-outline',
'type': 'line',
'source': 'completion-circles',
'paint': {
'line-color': 'rgba(100,100,100,0.5)',
'line-width': 2
}
});
// Ajouter les popups sur les cercles
map.on('click', 'completion-circles', (e) => {
const properties = e.features[0].properties;
new maplibregl.Popup()
.setLngLat(e.lngLat)
.setHTML(properties.popupContent)
.addTo(map);
});
// Attendre que la carte soit chargée avant d'ajouter les écouteurs d'événements
map.on('load', function() {
console.log('Map loaded');
map_is_loaded = true;
// Changer le curseur au survol des cercles
map.on('mouseenter', 'completion-circles', () => {
map.getCanvas().style.cursor = 'pointer';
map.on('mouseenter', function(e) {
const hoveredFeatures = map.queryRenderedFeatures(e.point, {
layers: features.map(f => f.id)
});
if (hoveredFeatures.length > 0) {
map.getCanvas().style.cursor = 'pointer';
}
});
map.on('mouseleave', 'completion-circles', () => {
map.getCanvas().style.cursor = '';
map.on('mouseleave', function(e) {
const hoveredFeatures = map.queryRenderedFeatures(e.point, {
layers: features.map(f => f.id)
});
if (hoveredFeatures.length === 0) {
map.getCanvas().style.cursor = '';
}
});
// Charger les lieux
loadPlaces(map);
});
sortTable();
colorHeadingTable();
});
</script>
{% endblock %}