Compare commits

...

2 Commits

16 changed files with 2116 additions and 36 deletions

View File

@@ -1,6 +1,6 @@
from flask import Flask
from app.extensions import db, migrate, login_manager, mail
from config import config
from app.utils.config import config
import os
def create_app(config_name=None):

View File

@@ -143,8 +143,6 @@
<!-- 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>
</div>
@@ -162,10 +160,22 @@
// Create map
map = L.map('map', {
zoomControl: true,
scrollWheelZoom: true,
scrollWheelZoom: false, // Disable default scroll wheel zoom
doubleClickZoom: true,
touchZoom: true
}).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
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
@@ -226,7 +236,7 @@
routesData.forEach((route, index) => {
if (route.coordinates && route.coordinates.length > 0) {
const color = colors[index % colors.length];
// Create polyline
const polyline = L.polyline(route.coordinates, {
color: color,
@@ -234,7 +244,7 @@
opacity: 0.8,
smoothFactor: 1
});
// Create popup content
const popupContent = `
<div class="route-popup">
@@ -260,15 +270,43 @@
</a>
</div>
`;
polyline.bindPopup(popupContent);
// Add to route layer
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
allBounds.push(...route.coordinates);
console.log(`Added route: ${route.title} (${route.coordinates.length} points)`);
}
});
@@ -298,27 +336,7 @@
}
function setupControls() {
// Fit routes button
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;
}
});
// Only refresh map button remains
// Refresh map button
document.getElementById('refresh-map').addEventListener('click', () => {

View File

@@ -58,10 +58,28 @@ if (routeId) {
const latlngs = data.coordinates.map(pt => [pt[0], pt[1]]);
const polyline = L.polyline(latlngs, { color: '#ef4444', weight: 5, opacity: 0.9 }).addTo(map);
map.fitBounds(polyline.getBounds(), { padding: [20, 20], maxZoom: 15 });
// Start marker
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);
// End marker
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);
// Start marker (green pin)
L.marker(latlngs[0], {
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]
})
}).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 {
map.setView([45.9432, 24.9668], 6);
L.marker([45.9432, 24.9668]).addTo(map).bindPopup('No route data').openPopup();

Binary file not shown.

After

Width:  |  Height:  |  Size: 494 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 791 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB