Add interactive Base 4 track map with Leaflet.js
- Created new track-map page with aerial image and SVG overlay - Implemented custom rotated square markers with obstacle numbers - Added admin edit mode for placing and repositioning markers - Database migration for track_obstacles table - Modal form for adding new obstacles (replaces browser alerts) - Drag-to-reposition functionality with auto-save - Color-coded markers (green/red/black/split) for difficulty levels - Clickable popups showing obstacle details - Added track-map to navigation menu and sitemap - URL rewrite rule for clean /track-map URL
This commit is contained in:
Binary file not shown.
BIN
assets/images/obstacles/01_03.png
Normal file
BIN
assets/images/obstacles/01_03.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.6 MiB |
BIN
assets/images/track-aerial.jpg
Normal file
BIN
assets/images/track-aerial.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 MiB |
115
assets/images/track-route.svg
Normal file
115
assets/images/track-route.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 24 KiB |
13126
assets/images/track-route2.svg
Normal file
13126
assets/images/track-route2.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 2.6 MiB |
66
assets/js/map.js
Normal file
66
assets/js/map.js
Normal file
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* TRACK MAP WITH LEAFLET.JS
|
||||
*
|
||||
* Basic Leaflet map test
|
||||
*/
|
||||
|
||||
console.log('Track map script loaded2');
|
||||
|
||||
// Check if Leaflet is available
|
||||
if (typeof L === 'undefined') {
|
||||
console.error('Leaflet library not loaded!');
|
||||
} else {
|
||||
console.log('Leaflet library is available, version:', L.version);
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
console.log('DOM loaded, initializing map...');
|
||||
|
||||
const mapElement = document.getElementById('map');
|
||||
console.log('Map element:', mapElement);
|
||||
|
||||
if (!mapElement) {
|
||||
console.error('Map element not found!');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Map element dimensions:', mapElement.offsetWidth, 'x', mapElement.offsetHeight);
|
||||
|
||||
try {
|
||||
// Image dimensions: 2876 x 2035 pixels
|
||||
const imageWidth = 2876;
|
||||
const imageHeight = 2035;
|
||||
|
||||
// Create map with simple CRS (pixel coordinates)
|
||||
// Note: Leaflet uses [y, x] format, so bounds are [[0, 0], [height, width]]
|
||||
const bounds = [[0, 0], [imageHeight, imageWidth]];
|
||||
const map = L.map('map', {
|
||||
crs: L.CRS.Simple,
|
||||
minZoom: -2,
|
||||
maxZoom: 2,
|
||||
center: [imageHeight / 2, imageWidth / 2],
|
||||
zoom: -1
|
||||
});
|
||||
console.log('Map object created with CRS.Simple:', map);
|
||||
|
||||
// Add aerial image overlay
|
||||
const imageUrl = '/assets/images/track-aerial.jpg';
|
||||
L.imageOverlay(imageUrl, bounds).addTo(map);
|
||||
console.log('Aerial image overlay added');
|
||||
|
||||
// Add SVG overlay
|
||||
const svgUrl = '/assets/images/track-route.svg';
|
||||
L.imageOverlay(svgUrl, bounds, {
|
||||
opacity: 0.8,
|
||||
interactive: false
|
||||
}).addTo(map);
|
||||
console.log('SVG route overlay added');
|
||||
|
||||
// Fit map to image bounds
|
||||
map.fitBounds(bounds);
|
||||
|
||||
console.log('Map initialized successfully');
|
||||
} catch (error) {
|
||||
console.error('Error initializing map:', error);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user