- attivita
- gestione degli script sul server - creato websocket per interagire con gli script del server.
This commit is contained in:
@@ -1,19 +1,23 @@
|
||||
import { tools } from '@store/Modules/tools'
|
||||
import { useQuasar } from 'quasar'
|
||||
import { PropType, defineComponent, onMounted, ref, computed, toRef, watch } from 'vue'
|
||||
import { PropType, defineComponent, onMounted, ref, toRaw, computed, toRef, watch, shallowRef } from 'vue'
|
||||
|
||||
import 'leaflet/dist/leaflet.css'
|
||||
// @ts-ignore
|
||||
import * as L from 'leaflet'
|
||||
import '../../utils/leaflet-extensions'; // Importa le estensioni
|
||||
import 'leaflet.markercluster/dist/MarkerCluster.css'
|
||||
import 'leaflet.markercluster/dist/MarkerCluster.Default.css'
|
||||
import 'leaflet.markercluster'
|
||||
|
||||
import { useUserStore } from '@src/store/UserStore'
|
||||
import { useGlobalStore } from '@src/store/globalStore'
|
||||
import { useI18n } from '@src/boot/i18n'
|
||||
import { ICoordGPS } from '@src/model'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'CMapByTable',
|
||||
emits: ['clickMarker', 'updateMapBoundaries', 'updateMapZoomOut'],
|
||||
props: {
|
||||
mytable: {
|
||||
type: String,
|
||||
@@ -27,6 +31,7 @@ export default defineComponent({
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const $q = useQuasar()
|
||||
const { t } = useI18n()
|
||||
const userStore = useUserStore()
|
||||
const globalStore = useGlobalStore()
|
||||
|
||||
@@ -34,23 +39,31 @@ export default defineComponent({
|
||||
const iconHeight = ref(40)
|
||||
const zoom = ref(8)
|
||||
|
||||
const map = ref(<any>null);
|
||||
const map = shallowRef(<any>null);
|
||||
|
||||
const visiblePosition = ref(false)
|
||||
|
||||
const markers = ref(<any>null);
|
||||
const markers = shallowRef(<any>null);
|
||||
|
||||
const isTrackingLocation = ref(false)
|
||||
|
||||
const currentMarker = ref<L.Marker | null>(null)
|
||||
const debug = ref(tools.isDevelop())
|
||||
|
||||
const currentMarkerPositionGPS = shallowRef<L.Marker | null>(null)
|
||||
|
||||
const centerCoordinates = ref<{ lat: number; lng: number }>({ lat: 0, lng: 0 }); //
|
||||
|
||||
const arrMarkers = ref(<any>[])
|
||||
|
||||
const recordShowed = ref(<any>null)
|
||||
const markerShowed = shallowRef<any>(null)
|
||||
const markerTemporaneo = shallowRef<L.Marker | null>(null)
|
||||
|
||||
const mapOptions = ref(<any>{
|
||||
zoomControl: true,
|
||||
zoomAnimation: true,
|
||||
zoomControl: false,
|
||||
zoomAnimation: false,
|
||||
fadeAnimation: true,
|
||||
markerZoomAnimation: false, //true
|
||||
markerZoomAnimation: true,
|
||||
})
|
||||
|
||||
const tileLayerOptions = {
|
||||
@@ -96,6 +109,10 @@ export default defineComponent({
|
||||
|
||||
const arrcord = toRef(props, 'arrcord')
|
||||
|
||||
const precZoomLevel = ref(0)
|
||||
|
||||
const debounceTimer = ref(<any>null)
|
||||
|
||||
watch(() => visiblePosition.value, () => {
|
||||
if (visiblePosition.value === true) {
|
||||
getCurrentPosition()
|
||||
@@ -109,7 +126,7 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
function myheight() {
|
||||
return $q.screen.height - 150
|
||||
return $q.screen.height - 220
|
||||
}
|
||||
|
||||
const iconUrl = computed(() => {
|
||||
@@ -169,7 +186,7 @@ export default defineComponent({
|
||||
const lng = e.latlng.lng
|
||||
|
||||
// Fai qualcosa con le coordinate, ad esempio stamparle in console
|
||||
console.log(`Latitudine: ${lat}, Longitudine: ${lng}`)
|
||||
// console.log(`Latitudine: ${lat}, Longitudine: ${lng}`)
|
||||
}
|
||||
|
||||
function getIconName(myrec: any) {
|
||||
@@ -180,29 +197,107 @@ export default defineComponent({
|
||||
return globalStore.getIconBySector(sectId)
|
||||
}
|
||||
|
||||
function updateBoundaries(updatedata: boolean) {
|
||||
if (map.value) {
|
||||
// Get the boubdaries of the map showed
|
||||
const bounds = map.value.getBounds();
|
||||
|
||||
// tojson
|
||||
tools.setCookie(tools.COOK_MAPBOUNDS + 'ne', tools.objToStr(bounds.getNorthEast()))
|
||||
tools.setCookie(tools.COOK_MAPBOUNDS + 'sw', tools.objToStr(bounds.getSouthWest()))
|
||||
|
||||
// Update Map Boundaries to the Parent
|
||||
emit('updateMapBoundaries', bounds.getNorthEast(), bounds.getSouthWest(), updatedata);
|
||||
}
|
||||
}
|
||||
|
||||
function updateMapZoomOut() {
|
||||
emit('updateMapZoomOut', map.value.getZoom());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the center coordinates and zoom level of the map, and saves them in cookies.
|
||||
*
|
||||
* @return {void} This function does not return a value.
|
||||
*/
|
||||
function onMoveEnd() {
|
||||
const center = map.value.getCenter(); // Ottieni le coordinate centrali
|
||||
centerCoordinates.value = { lat: center.lat, lng: center.lng }; // Salva le coordinate
|
||||
const currentZoomLevel = map.value.getZoom();
|
||||
tools.setCookie('last_lat', center.lat)
|
||||
tools.setCookie('last_lng', center.lng)
|
||||
tools.setCookie('zoom', currentZoomLevel)
|
||||
|
||||
updateBoundaries(true)
|
||||
|
||||
precZoomLevel.value = map.value.getZoom();
|
||||
}
|
||||
|
||||
const onZoomEvent = () => {
|
||||
// Annulla il timer precedente se presente
|
||||
if (debounceTimer.value) {
|
||||
clearTimeout(debounceTimer.value);
|
||||
}
|
||||
|
||||
// Inizia un nuovo timer di 1 secondo
|
||||
debounceTimer.value = setTimeout(() => {
|
||||
const currentZoomLevel = map.value.getZoom();
|
||||
|
||||
if (currentZoomLevel < precZoomLevel.value) {
|
||||
// Aggiorna i dati della mappa
|
||||
updateMapZoomOut();
|
||||
|
||||
// Aggiorna il livello di zoom precedente
|
||||
precZoomLevel.value = currentZoomLevel;
|
||||
}
|
||||
|
||||
}, 500);
|
||||
}
|
||||
|
||||
const onCustomButtonClick = () => {
|
||||
alert("Pulsante personalizzato cliccato!");
|
||||
// Logica aggiuntiva qui
|
||||
};
|
||||
|
||||
function initMap() {
|
||||
if (true) {
|
||||
const getLastCoord = [tools.getCookie('last_lat', 42.71), tools.getCookie('last_lng', 12.934)]
|
||||
console.log('getLastCoord', getLastCoord)
|
||||
zoom.value = tools.getCookie('zoom', 8, true)
|
||||
console.log('getLastCoord', getLastCoord, 'zoom', zoom.value)
|
||||
const newmapopt = { ...mapOptions.value,
|
||||
// console.log('getLastCoord', getLastCoord, 'zoom', zoom.value)
|
||||
const newmapopt = {
|
||||
...mapOptions.value,
|
||||
zoom: zoom.value,
|
||||
center: getLastCoord
|
||||
center: getLastCoord
|
||||
}
|
||||
map.value = L.map('map', newmapopt);
|
||||
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', tileLayerOptions).addTo(map.value);
|
||||
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', tileLayerOptions)
|
||||
.addTo(map.value);
|
||||
|
||||
// Aggiunta dei controlli di zoom
|
||||
const zoomControl = L.control.zoom({
|
||||
position: "topright",
|
||||
}).addTo(map.value);
|
||||
|
||||
// Aggiunta di un pulsante personalizzato
|
||||
// @ts-ignore
|
||||
const customButton = L.control({ position: "topright" });
|
||||
|
||||
customButton.onAdd = function () {
|
||||
const button = L.DomUtil.create("button", "custom-zoom-button");
|
||||
button.innerHTML = t('grid.showlist'); // Testo del pulsante
|
||||
button.onclick = onCustomButtonClick; // Gestore evento click
|
||||
|
||||
return button;
|
||||
};
|
||||
|
||||
// customButton.addTo(map.value);
|
||||
|
||||
map.value.on('moveend', () => {
|
||||
const center = map.value.getCenter(); // Ottieni le coordinate centrali
|
||||
centerCoordinates.value = { lat: center.lat, lng: center.lng }; // Salva le coordinate
|
||||
const currentZoomLevel = map.value.getZoom();
|
||||
tools.setCookie('last_lat', center.lat)
|
||||
tools.setCookie('last_lng', center.lng)
|
||||
tools.setCookie('zoom', currentZoomLevel)
|
||||
// console.log('Coordinate centrali aggiornate:', centerCoordinates.value);
|
||||
onMoveEnd()
|
||||
});
|
||||
|
||||
map.value.on("zoomend", onZoomEvent);
|
||||
// @ts-ignore
|
||||
markers.value = L.markerClusterGroup();
|
||||
|
||||
@@ -210,88 +305,139 @@ export default defineComponent({
|
||||
|
||||
// Assicuriamoci che la mappa sia completamente caricata prima di procedere
|
||||
map.value.whenReady(() => {
|
||||
console.log('Mappa inizializzata e pronta');
|
||||
// console.log('Mappa inizializzata e pronta');
|
||||
updateMap();
|
||||
precZoomLevel.value = map.value.getZoom()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function createSingleMarkerByCoordinates(rec: any) {
|
||||
|
||||
const markerHtml = `
|
||||
<div class="marker-wrapper">
|
||||
<img src="images/marker-shadow.png" class="marker-shadow" alt="Shadow" />
|
||||
<img src="images/icon.png" class="marker-icon" alt="" />
|
||||
|
||||
<div class="marker-circle"></div>
|
||||
|
||||
<div class="marker-mini-icon ${getIconName(rec)}"></div>
|
||||
</div>`;
|
||||
|
||||
const markerIcon = L.divIcon({
|
||||
className: 'custom-marker', // Classe CSS personalizzata
|
||||
html: markerHtml,
|
||||
iconSize: [40, 40],
|
||||
iconAnchor: [22, 35],
|
||||
popupAnchor: [-6, -36],
|
||||
shadowUrl: 'images/marker-shadow.png',
|
||||
shadowSize: [60, 30],
|
||||
shadowAnchor: [22, 35]
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
let each_marker = new L.marker(
|
||||
[rec.coordinate_gps.coordinates[1], rec.coordinate_gps.coordinates[0]],
|
||||
{
|
||||
icon: markerIcon
|
||||
|
||||
}
|
||||
)
|
||||
.bindPopup(() => {
|
||||
let container = L.DomUtil.create('div');
|
||||
let strHTML = `<span class="fake-link">${rec.descr}</span>`
|
||||
|
||||
if (debug.value) {
|
||||
// strHTML += `<br> Lat: ${rec.coordinate_gps.coordinates[1]} <br> Lng: ${rec.coordinate_gps.coordinates[0]}`;
|
||||
}
|
||||
|
||||
container.innerHTML = strHTML
|
||||
|
||||
let fakeLink: any = container.querySelector('.fake-link');
|
||||
L.DomEvent.on(fakeLink, 'click', (e) => {
|
||||
L.DomEvent.stopPropagation(e);
|
||||
ApriScheda(rec._id);
|
||||
each_marker.closePopup();
|
||||
});
|
||||
|
||||
return container;
|
||||
}, { closeButton: false }) // Rimuove il pulsante di chiusura dal popup
|
||||
|
||||
.on('click', () => {
|
||||
if (!$q.screen.lt.sm) {
|
||||
markerClick(rec._id)
|
||||
}
|
||||
})
|
||||
.on('mouseover', () => {
|
||||
if (!$q.screen.lt.sm) {
|
||||
each_marker.openPopup()
|
||||
}
|
||||
})
|
||||
.on('mouseout', () => {
|
||||
if (!$q.screen.lt.sm) {
|
||||
each_marker.closePopup()
|
||||
}
|
||||
});
|
||||
|
||||
// Salva l'ID del mio record, per poi poterlo trovare
|
||||
each_marker.mytable = props.mytable
|
||||
each_marker.idRec = rec._id
|
||||
|
||||
// Aggiungi il marker all'array in memoria
|
||||
arrMarkers.value.push(each_marker)
|
||||
|
||||
return each_marker
|
||||
|
||||
}
|
||||
|
||||
function updateMap() {
|
||||
if (!map.value || !markers.value) return;
|
||||
|
||||
if (map.value) {
|
||||
markers.value.clearLayers();
|
||||
// console.log('updateMap')
|
||||
|
||||
markers.value.clearLayers()
|
||||
arrMarkers.value = []
|
||||
|
||||
for (const rec of arrcord.value) {
|
||||
if (rec.coordinate_gps.coordinates) {
|
||||
const markerHtml = `
|
||||
<div class="marker-wrapper">
|
||||
<img src="images/marker-shadow.png" class="marker-shadow" alt="Shadow" />
|
||||
<img src="images/icon.png" class="marker-icon" alt="${name}" />
|
||||
|
||||
<div class="marker-circle"></div>
|
||||
|
||||
<!-- Aggiungi l'icona aggiuntiva al centro -->
|
||||
<div class="marker-mini-icon ${getIconName(rec)}"></div>
|
||||
</div> `;
|
||||
const each_marker = createSingleMarkerByCoordinates(rec)
|
||||
|
||||
const markerIcon = L.divIcon({
|
||||
className: 'custom-marker', // Classe CSS personalizzata
|
||||
html: markerHtml,
|
||||
iconSize: [40, 40],
|
||||
iconAnchor: [22, 35],
|
||||
popupAnchor: [-6, -36],
|
||||
shadowUrl: 'images/marker-shadow.png',
|
||||
shadowSize: [60, 30],
|
||||
shadowAnchor: [22, 35]
|
||||
});
|
||||
|
||||
|
||||
// @ts-ignore
|
||||
let each_marker = new L.marker(
|
||||
[rec.coordinate_gps.coordinates[1], rec.coordinate_gps.coordinates[0]],
|
||||
{
|
||||
icon: markerIcon
|
||||
|
||||
},
|
||||
)
|
||||
.bindPopup(() => {
|
||||
let container = L.DomUtil.create('div');
|
||||
container.innerHTML = `
|
||||
<span class="fake-link">${rec.descr}</span>
|
||||
`;
|
||||
|
||||
let fakeLink: any = container.querySelector('.fake-link');
|
||||
L.DomEvent.on(fakeLink, 'click', (e) => {
|
||||
L.DomEvent.stopPropagation(e);
|
||||
ApriScheda(rec._id);
|
||||
each_marker.closePopup();
|
||||
});
|
||||
|
||||
return container;
|
||||
}, { closeButton: false }) // Rimuove il pulsante di chiusura dal popup
|
||||
|
||||
.on('click', () => {
|
||||
if (!$q.screen.lt.sm) {
|
||||
markerClick(rec._id)
|
||||
}
|
||||
})
|
||||
.on('mouseover', () => {
|
||||
if (!$q.screen.lt.sm) {
|
||||
each_marker.openPopup()
|
||||
}
|
||||
})
|
||||
.on('mouseout', () => {
|
||||
if (!$q.screen.lt.sm) {
|
||||
each_marker.closePopup()
|
||||
}
|
||||
});
|
||||
markers.value.addLayer(each_marker);
|
||||
}
|
||||
}
|
||||
|
||||
// Aggiungi il gruppo di marker cluster alla mappa
|
||||
map.value.addLayer(markers.value);
|
||||
|
||||
// console.log('markerShowed', markerShowed.value)
|
||||
if (markerShowed.value) {
|
||||
markerShowed.value.closePopup()
|
||||
const trovatomarker = arrMarkers.value.find((marker: any) => markerShowed.value && (marker.idRec === markerShowed.value.idRec))
|
||||
if (!trovatomarker) {
|
||||
// non presente, quindi lo aggiunge
|
||||
markers.value.addLayer(markerShowed.value);
|
||||
} else {
|
||||
markerShowed.value = trovatomarker
|
||||
}
|
||||
markerShowed.value.openPopup(); // Mostra il popup
|
||||
}
|
||||
|
||||
if (visiblePosition.value && currentMarkerPositionGPS.value) {
|
||||
// Aggiungi un marker per la posizione attuale, se desiderato
|
||||
/*const tempmark = L.marker(
|
||||
[currentMarkerPositionGPS.value.getLatLng().lat, currentMarkerPositionGPS.value.getLatLng().lng],
|
||||
{ icon: currentLocationIcon }
|
||||
).addTo(map.value)
|
||||
.bindPopup('Posizione attuale')
|
||||
// .openPopup();
|
||||
|
||||
currentMarkerPositionGPS.value = tempmark*/
|
||||
markers.value.addLayer(currentMarkerPositionGPS.value);
|
||||
}
|
||||
|
||||
updateBoundaries(false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,38 +449,59 @@ export default defineComponent({
|
||||
emit('clickMarker', id)
|
||||
}
|
||||
|
||||
function gotoCurrentLocation() {
|
||||
getCurrentPosition();
|
||||
}
|
||||
|
||||
function flyToCoord(lat: number, lng: number, callback: () => void) {
|
||||
try {
|
||||
map.value.off('moveend', callback)
|
||||
|
||||
if (map.value.getZoom() < 13) {
|
||||
zoom.value = 13;
|
||||
} else {
|
||||
zoom.value = map.value.getZoom()
|
||||
}
|
||||
// Centra la mappa sulla posizione attuale
|
||||
map.value.flyTo([lat, lng], zoom.value, {
|
||||
animate: true,
|
||||
duration: 0.7
|
||||
})
|
||||
// Usa l'evento 'moveend' per sapere quando l'animazione è completata
|
||||
map.value.on('moveend', callback);
|
||||
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const getCurrentPosition = () => {
|
||||
if (navigator.geolocation) {
|
||||
isTrackingLocation.value = true; // Setta lo stato a "in tracciamento"
|
||||
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
position => {
|
||||
const lat = position.coords.latitude;
|
||||
const lng = position.coords.longitude;
|
||||
const lat = position.coords.latitude
|
||||
const lng = position.coords.longitude
|
||||
|
||||
flyToCoord(lat, lng, () => {
|
||||
if (currentMarkerPositionGPS.value) {
|
||||
map.value.removeLayer(currentMarkerPositionGPS.value)
|
||||
}
|
||||
|
||||
// Aggiungi un marker per la posizione attuale, se desiderato
|
||||
currentMarkerPositionGPS.value = L.marker(
|
||||
[lat, lng],
|
||||
{ icon: currentLocationIcon }
|
||||
).addTo(map.value)
|
||||
.bindPopup('Posizione attuale')
|
||||
// .openPopup();
|
||||
|
||||
isTrackingLocation.value = false; // Resetta lo stato di tracciamento
|
||||
|
||||
|
||||
if (zoom.value < 12) {
|
||||
zoom.value = 12;
|
||||
}
|
||||
// Centra la mappa sulla posizione attuale
|
||||
map.value.flyTo([lat, lng], zoom.value, {
|
||||
animate: true,
|
||||
duration: 0.5
|
||||
})
|
||||
// setView([lat, lng], map.getZoom())
|
||||
|
||||
if (currentMarker.value) {
|
||||
map.value.removeLayer(currentMarker.value);
|
||||
}
|
||||
|
||||
// Aggiungi un marker per la posizione attuale, se desiderato
|
||||
currentMarker.value = L.marker(
|
||||
[lat, lng],
|
||||
{ icon: currentLocationIcon }
|
||||
).addTo(map.value)
|
||||
.bindPopup('Posizione attuale')
|
||||
.openPopup();
|
||||
|
||||
isTrackingLocation.value = false; // Resetta lo stato di tracciamento
|
||||
},
|
||||
error => {
|
||||
console.error('Errore nel recupero della posizione:', error);
|
||||
@@ -347,12 +514,67 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
const removeCurrentMarker = () => {
|
||||
if (currentMarker.value) {
|
||||
map.value.removeLayer(currentMarker.value); // Rimuovi il marker dalla mappa
|
||||
currentMarker.value = null; // Resetta il riferimento
|
||||
if (currentMarkerPositionGPS.value) {
|
||||
map.value.removeLayer(currentMarkerPositionGPS.value); // Rimuovi il marker dalla mappa
|
||||
currentMarkerPositionGPS.value = null; // Resetta il riferimento
|
||||
}
|
||||
}
|
||||
|
||||
function findMarkerByIdRec(id: any) {
|
||||
const marker = arrMarkers.value.find((marker: any) => {
|
||||
return marker.idRec === id;
|
||||
});
|
||||
|
||||
return marker;
|
||||
}
|
||||
|
||||
function showInMap(rec: any) {
|
||||
// console.log('showInMap', rec)
|
||||
|
||||
// Find if is already in the map
|
||||
let existingMarker = findMarkerByIdRec(rec._id)
|
||||
if (!existingMarker) {
|
||||
|
||||
if (markerTemporaneo.value) {
|
||||
// Rimuovo il marker temporaneo usato in precedenza
|
||||
map.value.removeLayer(markerTemporaneo.value)
|
||||
markerTemporaneo.value = null
|
||||
}
|
||||
|
||||
// Se non la trovo nella mappa, allora inserisco un nuovo marker temporaneo e lo aggiungo alla mappa
|
||||
existingMarker = createSingleMarkerByCoordinates(rec); // Crea un nuovo marker
|
||||
markers.value.addLayer(existingMarker);
|
||||
|
||||
// console.log('***** Added marker TEMPORANEO', existingMarker)
|
||||
|
||||
markerTemporaneo.value = existingMarker
|
||||
}
|
||||
|
||||
if (existingMarker) {
|
||||
const lat = existingMarker.getLatLng().lat
|
||||
const lng = existingMarker.getLatLng().lng
|
||||
|
||||
recordShowed.value = rec
|
||||
markerShowed.value = existingMarker
|
||||
|
||||
// console.log('flyToCoord START ... ', lat, lng)
|
||||
|
||||
// Passa una callback dopo il volo
|
||||
flyToCoord(lat, lng, () => {
|
||||
// console.log('flyToCoord END ... ', lat, lng)
|
||||
|
||||
if (markerShowed.value) {
|
||||
//console.log('openPopup markerShowed', markerShowed.value)
|
||||
if (markerShowed.value.closePopup) {
|
||||
markerShowed.value.openPopup(); // Mostra il popup
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return {
|
||||
mywidth,
|
||||
myheight,
|
||||
@@ -369,6 +591,8 @@ export default defineComponent({
|
||||
getCurrentPosition,
|
||||
isTrackingLocation,
|
||||
visiblePosition,
|
||||
gotoCurrentLocation,
|
||||
showInMap,
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user