freealberta/map/app/public/js/admin-map.js

250 lines
8.5 KiB
JavaScript

/**
* Admin Map Management Module
* Handles map initialization, start location management, and coordinate operations
*/
// Map state
let adminMap = null;
let startMarker = null;
// Initialize the admin map
function initializeAdminMap() {
adminMap = L.map('admin-map').setView([53.5461, -113.4938], 11);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
maxZoom: 19,
minZoom: 2
}).addTo(adminMap);
// Add crosshair to center of map
const crosshairIcon = L.divIcon({
className: 'crosshair',
iconSize: [20, 20],
html: '<div style="width: 20px; height: 20px; position: relative;"><div style="position: absolute; top: 9px; left: 0; width: 20px; height: 2px; background: #333; box-shadow: 0 0 3px rgba(255,255,255,0.8);"></div><div style="position: absolute; top: 0; left: 9px; width: 2px; height: 20px; background: #333; box-shadow: 0 0 3px rgba(255,255,255,0.8);"></div></div>'
});
const crosshair = L.marker(adminMap.getCenter(), {
icon: crosshairIcon,
interactive: false,
zIndexOffset: 1000
}).addTo(adminMap);
// Update crosshair position when map moves
adminMap.on('move', function() {
crosshair.setLatLng(adminMap.getCenter());
});
// Add click handler to set location
adminMap.on('click', handleMapClick);
// Update coordinates when map moves
adminMap.on('moveend', updateCoordinatesFromMap);
}
// Load current start location
async function loadCurrentStartLocation() {
try {
const response = await fetch('/api/admin/start-location');
const data = await response.json();
if (data.success) {
const { latitude, longitude, zoom } = data.location;
// Update form fields
const latInput = document.getElementById('start-lat');
const lngInput = document.getElementById('start-lng');
const zoomInput = document.getElementById('start-zoom');
if (latInput) latInput.value = latitude;
if (lngInput) lngInput.value = longitude;
if (zoomInput) zoomInput.value = zoom;
// Update map
if (adminMap) {
adminMap.setView([latitude, longitude], zoom);
updateStartMarker(latitude, longitude);
}
// Show source info
if (data.source) {
const sourceText = data.source === 'database' ? 'Loaded from database' :
data.source === 'environment' ? 'Using environment defaults' :
'Using system defaults';
window.adminCore.showStatus(sourceText, 'info');
}
}
} catch (error) {
console.error('Failed to load start location:', error);
window.adminCore.showStatus('Failed to load current start location', 'error');
}
}
// Handle map click
function handleMapClick(e) {
const { lat, lng } = e.latlng;
const latInput = document.getElementById('start-lat');
const lngInput = document.getElementById('start-lng');
if (latInput) latInput.value = lat.toFixed(6);
if (lngInput) lngInput.value = lng.toFixed(6);
updateStartMarker(lat, lng);
}
// Update marker position
function updateStartMarker(lat, lng) {
if (startMarker) {
startMarker.setLatLng([lat, lng]);
} else {
startMarker = L.marker([lat, lng], {
draggable: true,
title: 'Start Location'
}).addTo(adminMap);
// Update coordinates when marker is dragged
startMarker.on('dragend', (e) => {
const position = e.target.getLatLng();
const latInput = document.getElementById('start-lat');
const lngInput = document.getElementById('start-lng');
if (latInput) latInput.value = position.lat.toFixed(6);
if (lngInput) lngInput.value = position.lng.toFixed(6);
});
}
}
// Update coordinates from current map view
function updateCoordinatesFromMap() {
const center = adminMap.getCenter();
const zoom = adminMap.getZoom();
const zoomInput = document.getElementById('start-zoom');
if (zoomInput) {
zoomInput.value = zoom;
}
}
// Update map from input fields
function updateMapFromInputs() {
const latInput = document.getElementById('start-lat');
const lngInput = document.getElementById('start-lng');
const zoomInput = document.getElementById('start-zoom');
const lat = parseFloat(latInput?.value);
const lng = parseFloat(lngInput?.value);
const zoom = parseInt(zoomInput?.value);
if (!isNaN(lat) && !isNaN(lng) && !isNaN(zoom) && adminMap) {
adminMap.setView([lat, lng], zoom);
updateStartMarker(lat, lng);
}
}
// Save start location
async function saveStartLocation() {
const latInput = document.getElementById('start-lat');
const lngInput = document.getElementById('start-lng');
const zoomInput = document.getElementById('start-zoom');
const lat = parseFloat(latInput?.value);
const lng = parseFloat(lngInput?.value);
const zoom = parseInt(zoomInput?.value);
// Validate
if (isNaN(lat) || isNaN(lng) || isNaN(zoom)) {
window.adminCore.showStatus('Please enter valid coordinates and zoom level', 'error');
return;
}
if (lat < -90 || lat > 90 || lng < -180 || lng > 180) {
window.adminCore.showStatus('Coordinates out of valid range', 'error');
return;
}
if (zoom < 2 || zoom > 19) {
window.adminCore.showStatus('Zoom level must be between 2 and 19', 'error');
return;
}
try {
const response = await fetch('/api/admin/start-location', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
latitude: lat,
longitude: lng,
zoom: zoom
})
});
const data = await response.json();
if (data.success) {
window.adminCore.showStatus('Start location saved successfully!', 'success');
} else {
throw new Error(data.error || 'Failed to save');
}
} catch (error) {
console.error('Save error:', error);
window.adminCore.showStatus(error.message || 'Failed to save start location', 'error');
}
}
// Setup map-related event listeners
function setupMapEventListeners() {
// Use current view button
const useCurrentViewBtn = document.getElementById('use-current-view');
if (useCurrentViewBtn) {
useCurrentViewBtn.addEventListener('click', () => {
if (!adminMap) return;
const center = adminMap.getCenter();
const zoom = adminMap.getZoom();
const latInput = document.getElementById('start-lat');
const lngInput = document.getElementById('start-lng');
const zoomInput = document.getElementById('start-zoom');
if (latInput) latInput.value = center.lat.toFixed(6);
if (lngInput) lngInput.value = center.lng.toFixed(6);
if (zoomInput) zoomInput.value = zoom;
updateStartMarker(center.lat, center.lng);
window.adminCore.showStatus('Captured current map view', 'success');
});
}
// Save button
const saveLocationBtn = document.getElementById('save-start-location');
if (saveLocationBtn) {
saveLocationBtn.addEventListener('click', saveStartLocation);
}
// Coordinate input changes
const startLatInput = document.getElementById('start-lat');
const startLngInput = document.getElementById('start-lng');
const startZoomInput = document.getElementById('start-zoom');
if (startLatInput) startLatInput.addEventListener('change', updateMapFromInputs);
if (startLngInput) startLngInput.addEventListener('change', updateMapFromInputs);
if (startZoomInput) startZoomInput.addEventListener('change', updateMapFromInputs);
}
// Export map management functions
window.adminMap = {
initializeAdminMap,
loadCurrentStartLocation,
setupMapEventListeners,
saveStartLocation,
updateMapFromInputs,
handleMapClick,
updateStartMarker,
getAdminMap: () => adminMap
};