Compare commits
2 Commits
c0739f24a7
...
a64e206fc8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a64e206fc8 | ||
|
|
cee3711fd8 |
@@ -1,6 +1,6 @@
|
|||||||
from flask import Flask
|
from flask import Flask
|
||||||
from app.extensions import db, migrate, login_manager, mail
|
from app.extensions import db, migrate, login_manager, mail
|
||||||
from config import config
|
from app.utils.config import config
|
||||||
import os
|
import os
|
||||||
|
|
||||||
def create_app(config_name=None):
|
def create_app(config_name=None):
|
||||||
|
|||||||
@@ -143,8 +143,6 @@
|
|||||||
|
|
||||||
<!-- Map Controls -->
|
<!-- Map Controls -->
|
||||||
<div class="map-controls">
|
<div class="map-controls">
|
||||||
<button id="fit-routes" class="map-control-btn" title="Fit all routes">🎯</button>
|
|
||||||
<button id="toggle-routes" class="map-control-btn active" title="Toggle routes">🛣️</button>
|
|
||||||
<button id="refresh-map" class="map-control-btn" title="Refresh map">🔄</button>
|
<button id="refresh-map" class="map-control-btn" title="Refresh map">🔄</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -162,10 +160,22 @@
|
|||||||
// Create map
|
// Create map
|
||||||
map = L.map('map', {
|
map = L.map('map', {
|
||||||
zoomControl: true,
|
zoomControl: true,
|
||||||
scrollWheelZoom: true,
|
scrollWheelZoom: false, // Disable default scroll wheel zoom
|
||||||
doubleClickZoom: true,
|
doubleClickZoom: true,
|
||||||
touchZoom: true
|
touchZoom: true
|
||||||
}).setView(romaniaCenter, romaniaZoom);
|
}).setView(romaniaCenter, romaniaZoom);
|
||||||
|
|
||||||
|
// Enable zoom with Ctrl/Cmd + wheel only
|
||||||
|
map.getContainer().addEventListener('wheel', function(e) {
|
||||||
|
if ((e.ctrlKey || e.metaKey) && map.options.scrollWheelZoom !== true) {
|
||||||
|
map.options.scrollWheelZoom = true;
|
||||||
|
} else if (!(e.ctrlKey || e.metaKey) && map.options.scrollWheelZoom !== false) {
|
||||||
|
map.options.scrollWheelZoom = false;
|
||||||
|
}
|
||||||
|
if (!(e.ctrlKey || e.metaKey)) {
|
||||||
|
e.preventDefault(); // Prevent zoom if not holding Ctrl/Cmd
|
||||||
|
}
|
||||||
|
}, { passive: false });
|
||||||
|
|
||||||
// Add OpenStreetMap tiles
|
// Add OpenStreetMap tiles
|
||||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||||
@@ -226,7 +236,7 @@
|
|||||||
routesData.forEach((route, index) => {
|
routesData.forEach((route, index) => {
|
||||||
if (route.coordinates && route.coordinates.length > 0) {
|
if (route.coordinates && route.coordinates.length > 0) {
|
||||||
const color = colors[index % colors.length];
|
const color = colors[index % colors.length];
|
||||||
|
|
||||||
// Create polyline
|
// Create polyline
|
||||||
const polyline = L.polyline(route.coordinates, {
|
const polyline = L.polyline(route.coordinates, {
|
||||||
color: color,
|
color: color,
|
||||||
@@ -234,7 +244,7 @@
|
|||||||
opacity: 0.8,
|
opacity: 0.8,
|
||||||
smoothFactor: 1
|
smoothFactor: 1
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create popup content
|
// Create popup content
|
||||||
const popupContent = `
|
const popupContent = `
|
||||||
<div class="route-popup">
|
<div class="route-popup">
|
||||||
@@ -260,15 +270,43 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
polyline.bindPopup(popupContent);
|
polyline.bindPopup(popupContent);
|
||||||
|
|
||||||
// Add to route layer
|
|
||||||
routeLayer.addLayer(polyline);
|
routeLayer.addLayer(polyline);
|
||||||
|
|
||||||
|
// Add start and end markers
|
||||||
|
const startCoord = route.coordinates[0];
|
||||||
|
const endCoord = route.coordinates[route.coordinates.length - 1];
|
||||||
|
|
||||||
|
// Green start marker
|
||||||
|
const startMarker = L.marker(startCoord, {
|
||||||
|
icon: L.icon({
|
||||||
|
iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-green.png',
|
||||||
|
iconSize: [25, 41],
|
||||||
|
iconAnchor: [12, 41],
|
||||||
|
popupAnchor: [1, -34],
|
||||||
|
shadowUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png',
|
||||||
|
shadowSize: [41, 41]
|
||||||
|
})
|
||||||
|
}).bindPopup(`<b>Start of route</b><br>${route.title}`);
|
||||||
|
routeLayer.addLayer(startMarker);
|
||||||
|
|
||||||
|
// Red end marker
|
||||||
|
const endMarker = L.marker(endCoord, {
|
||||||
|
icon: L.icon({
|
||||||
|
iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-red.png',
|
||||||
|
iconSize: [25, 41],
|
||||||
|
iconAnchor: [12, 41],
|
||||||
|
popupAnchor: [1, -34],
|
||||||
|
shadowUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png',
|
||||||
|
shadowSize: [41, 41]
|
||||||
|
})
|
||||||
|
}).bindPopup(`<b>End of route</b><br>${route.title}`);
|
||||||
|
routeLayer.addLayer(endMarker);
|
||||||
|
|
||||||
// Collect bounds for fitting
|
// Collect bounds for fitting
|
||||||
allBounds.push(...route.coordinates);
|
allBounds.push(...route.coordinates);
|
||||||
|
|
||||||
console.log(`Added route: ${route.title} (${route.coordinates.length} points)`);
|
console.log(`Added route: ${route.title} (${route.coordinates.length} points)`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -298,27 +336,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setupControls() {
|
function setupControls() {
|
||||||
// Fit routes button
|
// Only refresh map button remains
|
||||||
document.getElementById('fit-routes').addEventListener('click', () => {
|
|
||||||
if (routeLayer.getLayers().length > 0) {
|
|
||||||
const group = new L.FeatureGroup();
|
|
||||||
routeLayer.eachLayer(layer => group.addLayer(layer));
|
|
||||||
map.fitBounds(group.getBounds(), { padding: [20, 20] });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Toggle routes button
|
|
||||||
document.getElementById('toggle-routes').addEventListener('click', (e) => {
|
|
||||||
if (routesVisible) {
|
|
||||||
map.removeLayer(routeLayer);
|
|
||||||
e.target.classList.remove('active');
|
|
||||||
routesVisible = false;
|
|
||||||
} else {
|
|
||||||
map.addLayer(routeLayer);
|
|
||||||
e.target.classList.add('active');
|
|
||||||
routesVisible = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Refresh map button
|
// Refresh map button
|
||||||
document.getElementById('refresh-map').addEventListener('click', () => {
|
document.getElementById('refresh-map').addEventListener('click', () => {
|
||||||
|
|||||||
@@ -58,10 +58,28 @@ if (routeId) {
|
|||||||
const latlngs = data.coordinates.map(pt => [pt[0], pt[1]]);
|
const latlngs = data.coordinates.map(pt => [pt[0], pt[1]]);
|
||||||
const polyline = L.polyline(latlngs, { color: '#ef4444', weight: 5, opacity: 0.9 }).addTo(map);
|
const polyline = L.polyline(latlngs, { color: '#ef4444', weight: 5, opacity: 0.9 }).addTo(map);
|
||||||
map.fitBounds(polyline.getBounds(), { padding: [20, 20], maxZoom: 15 });
|
map.fitBounds(polyline.getBounds(), { padding: [20, 20], maxZoom: 15 });
|
||||||
// Start marker
|
// Start marker (green pin)
|
||||||
L.marker(latlngs[0], { icon: L.divIcon({ html: '<div style="background:#22c55e;border-radius:50%;width:24px;height:24px;display:flex;align-items:center;justify-content:center;color:#fff;"><i class=\'fas fa-play\'></i></div>', className: 'custom-div-icon', iconSize: [24,24], iconAnchor: [12,12] }) }).addTo(map);
|
L.marker(latlngs[0], {
|
||||||
// End marker
|
icon: L.icon({
|
||||||
L.marker(latlngs[latlngs.length-1], { icon: L.divIcon({ html: '<div style="background:#ef4444;border-radius:50%;width:24px;height:24px;display:flex;align-items:center;justify-content:center;color:#fff;"><i class=\'fas fa-flag-checkered\'></i></div>', className: 'custom-div-icon', iconSize: [24,24], iconAnchor: [12,12] }) }).addTo(map);
|
iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-green.png',
|
||||||
|
iconSize: [25, 41],
|
||||||
|
iconAnchor: [12, 41],
|
||||||
|
popupAnchor: [1, -34],
|
||||||
|
shadowUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png',
|
||||||
|
shadowSize: [41, 41]
|
||||||
|
})
|
||||||
|
}).addTo(map);
|
||||||
|
// End marker (red pin)
|
||||||
|
L.marker(latlngs[latlngs.length-1], {
|
||||||
|
icon: L.icon({
|
||||||
|
iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-red.png',
|
||||||
|
iconSize: [25, 41],
|
||||||
|
iconAnchor: [12, 41],
|
||||||
|
popupAnchor: [1, -34],
|
||||||
|
shadowUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png',
|
||||||
|
shadowSize: [41, 41]
|
||||||
|
})
|
||||||
|
}).addTo(map);
|
||||||
} else {
|
} else {
|
||||||
map.setView([45.9432, 24.9668], 6);
|
map.setView([45.9432, 24.9668], 6);
|
||||||
L.marker([45.9432, 24.9668]).addTo(map).bindPopup('No route data').openPopup();
|
L.marker([45.9432, 24.9668]).addTo(map).bindPopup('No route data').openPopup();
|
||||||
|
|||||||
|
After Width: | Height: | Size: 494 KiB |
|
After Width: | Height: | Size: 153 KiB |
|
After Width: | Height: | Size: 308 KiB |
|
After Width: | Height: | Size: 791 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 21 KiB |