diff --git a/public/js/components/ConfigManager.js b/public/js/components/ConfigManager.js
index 04d3718..d823d62 100644
--- a/public/js/components/ConfigManager.js
+++ b/public/js/components/ConfigManager.js
@@ -709,120 +709,62 @@ class ConfigManager {
if (e.target === mapModal) closeMap();
});
- // Load transit stops - search for common Stockholm areas
- const loadSitesOnMap = async () => {
+ // Load nearby transit stops based on map center
+ const markersLayer = L.layerGroup().addTo(map);
+ const loadedSiteIds = new Set();
+
+ const loadNearbySites = async () => {
+ const center = map.getCenter();
+ const zoom = map.getZoom();
+ // Scale radius based on zoom: wider view = larger radius
+ const radius = zoom >= 15 ? 500 : zoom >= 13 ? 1500 : zoom >= 11 ? 4000 : 8000;
+
try {
- // Start with focused search to avoid too many markers
- const searchTerms = ['Ambassaderna'];
- const allSites = new Map();
-
- for (const term of searchTerms) {
- try {
- const response = await fetch(`/api/sites/search?q=${encodeURIComponent(term)}`);
- const data = await response.json();
- console.log(`Search "${term}" returned:`, data);
- if (data.sites) {
- data.sites.forEach(site => {
- // Only add sites with valid coordinates from API
- const lat = site.lat || site.latitude;
- const lon = site.lon || site.longitude;
-
- if (lat && lon && !isNaN(parseFloat(lat)) && !isNaN(parseFloat(lon))) {
- if (!allSites.has(site.id)) {
- allSites.set(site.id, {
- id: site.id,
- name: site.name,
- lat: parseFloat(lat),
- lon: parseFloat(lon)
- });
- }
- } else {
- console.log(`Site ${site.id} (${site.name}) missing coordinates, skipping`);
- }
- });
- }
- } catch (err) {
- console.error(`Error searching for ${term}:`, err);
- }
- }
-
- // Add known site with coordinates as fallback
- const knownSites = [
- { id: '1411', name: 'Ambassaderna', lat: 59.3293, lon: 18.0686 }
- ];
-
- knownSites.forEach(site => {
- if (!allSites.has(site.id)) {
- allSites.set(site.id, site);
- }
- });
-
- const sitesArray = Array.from(allSites.values());
- console.log(`Loading ${sitesArray.length} sites on map with coordinates:`, sitesArray);
-
- if (sitesArray.length > 0) {
- const markers = [];
- sitesArray.forEach(site => {
- const lat = site.lat;
- const lon = site.lon;
-
- if (!lat || !lon || isNaN(lat) || isNaN(lon)) {
- console.warn(`Invalid coordinates for site ${site.id}, skipping`);
- return;
- }
-
- // Create custom icon
+ const response = await fetch(`/api/sites/nearby?lat=${center.lat}&lon=${center.lng}&radius=${radius}`);
+ const data = await response.json();
+
+ if (data.sites) {
+ data.sites.forEach(site => {
+ if (loadedSiteIds.has(site.id)) return;
+ const lat = parseFloat(site.lat);
+ const lon = parseFloat(site.lon);
+ if (!lat || !lon || isNaN(lat) || isNaN(lon)) return;
+
+ loadedSiteIds.add(site.id);
+
const customIcon = L.divIcon({
className: 'custom-marker',
- html: `
🚌
`,
+ html: '🚌
',
iconSize: [30, 30],
iconAnchor: [15, 15]
});
-
- const marker = L.marker([lat, lon], { icon: customIcon }).addTo(map);
-
+
+ const marker = L.marker([lat, lon], { icon: customIcon });
+
const popupContent = `
${site.name}
ID: ${site.id}
-
`;
-
+
marker.bindPopup(popupContent);
- markers.push(marker);
-
- // Make marker clickable to open popup
- marker.on('click', function() {
- this.openPopup();
- });
+ markersLayer.addLayer(marker);
});
-
- // Fit map to show all markers, or center on first marker
- if (markers.length > 0) {
- if (markers.length === 1) {
- map.setView(markers[0].getLatLng(), 15);
- } else {
- const group = new L.featureGroup(markers);
- map.fitBounds(group.getBounds().pad(0.1));
- }
- } else {
- // If no markers, show message
- console.log('No sites with coordinates found');
- }
+ console.log(`Loaded ${data.sites.length} nearby sites (${loadedSiteIds.size} total on map)`);
}
} catch (error) {
- console.error('Error loading sites on map:', error);
+ console.error('Error loading nearby sites:', error);
}
};
-
- // Load sites after map is initialized
- setTimeout(() => {
- loadSitesOnMap();
- }, 500);
+
+ // Load sites on init and when map is panned/zoomed
+ setTimeout(() => loadNearbySites(), 300);
+ map.on('moveend', loadNearbySites);
// Handle site selection from map popup - use event delegation on the modal
mapModal.addEventListener('click', (e) => {
@@ -874,73 +816,42 @@ class ConfigManager {
const data = await response.json();
if (data.sites && data.sites.length > 0) {
- // Clear existing markers
- map.eachLayer((layer) => {
- if (layer instanceof L.Marker) {
- map.removeLayer(layer);
- }
- });
-
- // Clear existing markers
- map.eachLayer((layer) => {
- if (layer instanceof L.Marker) {
- map.removeLayer(layer);
- }
- });
-
- // Add markers for search results
- const markers = [];
+ // Clear existing markers and reset tracking
+ markersLayer.clearLayers();
+ loadedSiteIds.clear();
+
+ const searchMarkers = [];
data.sites.forEach(site => {
- let lat = site.lat || site.latitude;
- let lon = site.lon || site.longitude;
-
- // If no coordinates, use approximate location based on map center
- if (!lat || !lon) {
- const center = map.getCenter();
- lat = center.lat + (Math.random() - 0.5) * 0.05;
- lon = center.lon + (Math.random() - 0.5) * 0.05;
- }
-
- // Create custom icon
+ const lat = parseFloat(site.lat);
+ const lon = parseFloat(site.lon);
+ if (!lat || !lon || isNaN(lat) || isNaN(lon)) return;
+
+ loadedSiteIds.add(site.id);
+
const customIcon = L.divIcon({
- className: 'custom-transit-marker',
- html: `🚌
`,
+ className: 'custom-marker',
+ html: '🚌
',
iconSize: [32, 32],
- iconAnchor: [16, 16],
- popupAnchor: [0, -16]
+ iconAnchor: [16, 16]
});
-
- const marker = L.marker([lat, lon], {
- icon: customIcon,
- title: site.name
- }).addTo(map);
-
- const popupContent = document.createElement('div');
- popupContent.style.minWidth = '220px';
- popupContent.innerHTML = `
-
-
${site.name}
-
ID: ${site.id}
+
+ const marker = L.marker([lat, lon], { icon: customIcon });
+ marker.bindPopup(`
+
+ ${site.name}
+ ID: ${site.id}
+
-
- `;
-
- marker.bindPopup(popupContent);
- markers.push(marker);
-
- marker.on('click', function() {
- this.openPopup();
- });
+ `);
+ markersLayer.addLayer(marker);
+ searchMarkers.push(marker);
});
-
- // Fit map to show results
- if (markers.length > 0) {
- const group = new L.featureGroup(markers);
+
+ if (searchMarkers.length > 0) {
+ const group = new L.featureGroup(searchMarkers);
map.fitBounds(group.getBounds().pad(0.1));
}
}