189 lines
5.3 KiB
JavaScript
189 lines
5.3 KiB
JavaScript
let map;
|
|
let journeys = [];
|
|
let currentJourney = {
|
|
id: Date.now(),
|
|
name: "Untitled Journey",
|
|
description: "",
|
|
markers: [],
|
|
path: null
|
|
};
|
|
let currentMarkerBeingEdited = null;
|
|
let isCreatingJourney = true;
|
|
|
|
function saveJourneyToLocalStorage() {
|
|
journeys.push({
|
|
id: currentJourney.id,
|
|
name: currentJourney.name,
|
|
description: currentJourney.description,
|
|
markers: currentJourney.markers.map(marker => ({
|
|
id: marker.id,
|
|
lngLat: marker.getLngLat(),
|
|
content: marker.content
|
|
}))
|
|
});
|
|
localStorage.setItem('journeys', JSON.stringify(journeys));
|
|
}
|
|
|
|
function loadJourneysFromLocalStorage() {
|
|
const stored = localStorage.getItem('journeyMapper_journeys');
|
|
if (stored) {
|
|
journeys = JSON.parse(stored);
|
|
}
|
|
}
|
|
|
|
// Function to create a marker at a lngLat and add to the map
|
|
function createMarker(lngLat) {
|
|
const markerElement = document.createElement('div');
|
|
markerElement.className = 'marker';
|
|
markerElement.innerHTML = '<i class="fas fa-map-marker"></i>';
|
|
|
|
const marker = new maplibregl.Marker(markerElement)
|
|
.setLngLat(lngLat)
|
|
.addTo(map);
|
|
|
|
marker.id = Date.now();
|
|
marker.content = {
|
|
title: '',
|
|
date: '',
|
|
text: '',
|
|
images: [],
|
|
videoUrl: ''
|
|
};
|
|
|
|
// Add a popup
|
|
const popup = new maplibregl.Popup({ offset: 25 })
|
|
.setHTML('<strong>New Marker</strong>');
|
|
marker.setPopup(popup);
|
|
|
|
// When the marker is clicked, open the editor
|
|
markerElement.addEventListener('click', () => {
|
|
openMarkerEditor(marker);
|
|
});
|
|
|
|
return marker;
|
|
}
|
|
|
|
function openMarkerEditor(marker) {
|
|
currentMarkerBeingEdited = marker;
|
|
document.getElementById('marker-title').value = marker.content.title || '';
|
|
document.getElementById('marker-date').value = marker.content.date || '';
|
|
document.getElementById('marker-text').value = marker.content.text || '';
|
|
document.getElementById('video-url').value = marker.content.videoUrl || '';
|
|
document.getElementById('marker-coords').textContent =
|
|
`${marker.getLngLat().lng.toFixed(4)}, ${marker.getLngLat().lat.toFixed(4)}`;
|
|
|
|
// Update imagine review
|
|
const imagePreview = document.getElementById('image-preview');
|
|
imagePreview.innerHTML = '';
|
|
学生学习 if (marker.content.images && marker.content.images.length > 0) {
|
|
marker.content.images.forEach(img => {
|
|
const imgEl = document.createElement('img');
|
|
imgEl.src = img;
|
|
imagePreview.appendChild(imgEl);
|
|
});
|
|
}
|
|
|
|
document.getElementById('marker-modal').style.display = 'block';
|
|
}
|
|
|
|
function closeMarkerEditor() {
|
|
document.getElementById('marker-modal').style.display = 'none';
|
|
currentMarkerBeingEdited = null;
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
map = new maplibregl.Map({
|
|
container: 'map',
|
|
style: 'https://demotiles.maplibre.org/style.json',
|
|
center: [0, 20],
|
|
zoom: 2
|
|
});
|
|
|
|
// Add journey path layer
|
|
map.on('load', function() {
|
|
map.addSource('journey-path', {
|
|
type: 'geojson',
|
|
data: {
|
|
type: 'Feature',
|
|
properties: {},
|
|
geometry: {
|
|
type: 'LineString',
|
|
coordinates: []
|
|
}
|
|
}
|
|
});
|
|
|
|
map.addLayer({
|
|
id: 'journey-path',
|
|
type: 'line',
|
|
source: 'journey-path',
|
|
layout: {
|
|
'line-join': 'round',
|
|
'line-cap': 'round'
|
|
},
|
|
paint: {
|
|
'line-color': '#3887be',
|
|
'line-width': 5
|
|
}
|
|
});
|
|
});
|
|
|
|
// Close editor events
|
|
document.getElementById('close-modal').addEventListener('click', closeMarkerEditor);
|
|
document.getElementById('cancel-marker').addEventListener('click', closeMarkerEditor);
|
|
|
|
// Save marker event
|
|
document.getElementById('save-marker').addEventListener('click', function() {
|
|
if (!currentMarkerBeingEdited) return;
|
|
|
|
// Update marker content
|
|
currentMarkerBeingEdited.content.title = document.getElementById('marker-title').value;
|
|
currentMarkerBeingEdited.content.date = document.getElementById('marker-date').value;
|
|
currentMarkerBeingEdited.content.text = document.getElementById('marker-text').value;
|
|
currentMarkerBeingEdited.content.videoUrl = document.getElementById('video-url').value;
|
|
|
|
// Update the popup
|
|
currentMarkerBeingEdited.getPopup().setHTML(
|
|
`<strong>${currentMarkerBeingEdited.content.title || 'Untitled'}</strong>`
|
|
);
|
|
|
|
closeMarkerEditor();
|
|
});
|
|
|
|
// Delete marker event
|
|
document.getElementById('delete-marker').addEventListener('click', function() {
|
|
if (!currentMarkerBeingEdited) return;
|
|
|
|
// Remove from map
|
|
currentMarkerBeingEdited.remove();
|
|
|
|
// Remove from currentJourney.markers
|
|
const index = currentJourney.markers.findIndex(m => m.id === currentMarkerBeingEdited.id);
|
|
if (index !== -1) {
|
|
currentJourney.markers.splice(index, 1);
|
|
}
|
|
|
|
closeMarkerEditor();
|
|
});
|
|
|
|
// Add marker on map click
|
|
map.on('click', (e) => {
|
|
if (isCreatingJourney) {
|
|
const marker = createMarker(e.lngLat);
|
|
currentJourney.markers.push(marker);
|
|
updateJourneyPath();
|
|
}
|
|
});
|
|
|
|
// Save journey button
|
|
document.getElementById('save-journey-btn').addEventListener('click', function() {
|
|
currentJourney.name = document.getElementById('journey-name').value;
|
|
currentJourney.description = document.getElementById('journey-description').value;
|
|
saveJourneyToLocalStorage();
|
|
alert('Journey saved!');
|
|
});
|
|
|
|
// Load journeys on start
|
|
loadJourneysFromLocalStorage();
|
|
});
|