- gestione degli script sul server - creato websocket per interagire con gli script del server.
391 lines
12 KiB
TypeScript
Executable File
391 lines
12 KiB
TypeScript
Executable File
import { tools } from '@store/Modules/tools'
|
|
import { useQuasar } from 'quasar'
|
|
import { defineComponent, onMounted, onBeforeUnmount, ref, watch, computed, PropType, nextTick, shallowRef } from 'vue'
|
|
|
|
import 'leaflet/dist/leaflet.css'
|
|
import * as L from 'leaflet'
|
|
import 'leaflet.markercluster/dist/MarkerCluster.css'
|
|
import 'leaflet.markercluster/dist/MarkerCluster.Default.css'
|
|
import 'leaflet.markercluster'
|
|
import '../../utils/leaflet-extensions'; // Importa le estensioni
|
|
|
|
import { useUserStore } from '@src/store/UserStore'
|
|
|
|
// Importa le immagini dei marker
|
|
import icon from 'leaflet/dist/images/marker-icon.png'
|
|
import iconShadow from 'leaflet/dist/images/marker-shadow.png'
|
|
import { ICoordGPS, ICoordLatLng } from '@src/model'
|
|
|
|
export default defineComponent({
|
|
name: 'CMapEditAddressByCoord',
|
|
props: {
|
|
modelValue: {
|
|
type: Object as PropType<ICoordGPS>,
|
|
required: true,
|
|
},
|
|
editaddress: {
|
|
type: Boolean,
|
|
required: true,
|
|
},
|
|
visuMappa: {
|
|
type: Boolean,
|
|
required: false,
|
|
default: true,
|
|
}
|
|
},
|
|
setup(props, { emit }) {
|
|
const $q = useQuasar()
|
|
const userStore = useUserStore()
|
|
|
|
const mapContainer = ref(<any>null);
|
|
|
|
const iconWidth = ref(25)
|
|
const iconHeight = ref(41)
|
|
const map = shallowRef<L.Map | null>(null)
|
|
const marker = ref<L.Marker | null>(null)
|
|
const suggestions = ref([]);
|
|
const isMapDialogOpen = ref(false)
|
|
const mostraMappa = ref(true)
|
|
|
|
const localAddress = ref(props.modelValue.address);
|
|
const localAddressObj = ref({ label: '', value: '' });
|
|
const localCoordinates = ref(<ICoordLatLng>{ lat: props.modelValue.coordinates[1], lng: props.modelValue.coordinates[0] });
|
|
|
|
const modificato = ref(false)
|
|
|
|
const fineLoad = ref(false)
|
|
|
|
const zoomLevel = ref(17)
|
|
|
|
const updateAll = () => {
|
|
if (localAddress.value)
|
|
emit('update:modelValue',
|
|
{
|
|
address: localAddress.value,
|
|
type: 'Point',
|
|
coordinates: [localCoordinates.value.lng, localCoordinates.value.lat]
|
|
} as ICoordGPS);
|
|
};
|
|
|
|
// Funzione per aggiornare il nome
|
|
const updateAddress = () => {
|
|
if (localAddress.value)
|
|
updateAll()
|
|
};
|
|
|
|
// Funzione per aggiornare il cognome
|
|
const updateCoordinates = () => {
|
|
updateAll()
|
|
};
|
|
|
|
// Monitoraggio delle modifiche alle props
|
|
watch(() => props.modelValue.address, (newValue) => {
|
|
localAddress.value = newValue;
|
|
});
|
|
|
|
watch(() => props.modelValue.coordinates, (newValue) => {
|
|
localCoordinates.value.lat = newValue[1];
|
|
localCoordinates.value.lng = newValue[0];
|
|
});
|
|
|
|
|
|
watch(() => localCoordinates.value.lat, (newValue) => {
|
|
if (fineLoad.value) {
|
|
modificato.value = true
|
|
}
|
|
updateMarker(localCoordinates.value.lat, localCoordinates.value.lng);
|
|
getAddressFromCoordinates(localCoordinates.value.lat, localCoordinates.value.lng);
|
|
});
|
|
watch(() => localCoordinates.value.lng, (newValue) => {
|
|
if (fineLoad.value) {
|
|
modificato.value = true
|
|
}
|
|
updateMarker(localCoordinates.value.lat, localCoordinates.value.lng);
|
|
getAddressFromCoordinates(localCoordinates.value.lat, localCoordinates.value.lng);
|
|
|
|
});
|
|
|
|
const myheight = computed(() => {
|
|
return $q.screen.height - 150
|
|
})
|
|
|
|
// Funzione per ottenere e stampare il livello di zoom
|
|
function getZoomLevel() {
|
|
zoomLevel.value = map.value ? map.value.getZoom() : 17;
|
|
// console.log('Current zoom level:', zoomLevel);
|
|
}
|
|
|
|
const initMap = () => {
|
|
// Configura l'icona di default
|
|
const DefaultIcon = L.icon({
|
|
iconUrl: icon,
|
|
shadowUrl: iconShadow,
|
|
iconSize: [iconWidth.value, iconHeight.value],
|
|
iconAnchor: [iconWidth.value / 2, iconHeight.value],
|
|
popupAnchor: [1, -iconHeight.value],
|
|
shadowSize: [iconHeight.value, iconHeight.value]
|
|
})
|
|
L.Marker.prototype.options.icon = DefaultIcon
|
|
|
|
zoomLevel.value = 17
|
|
|
|
map.value = L.map(mapContainer.value,
|
|
{
|
|
zoomControl: true, zoom: zoomLevel.value, zoomAnimation: true,
|
|
fadeAnimation: true, markerZoomAnimation: true,
|
|
center: [42.71, 12.934],
|
|
}
|
|
)
|
|
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map.value)
|
|
|
|
|
|
getZoomLevel();
|
|
|
|
// Ottenere il livello di zoom quando la mappa viene ridimensionata
|
|
map.value.on('zoomend', getZoomLevel);
|
|
|
|
/*
|
|
const closeButton = L.control({ position: 'topright' });
|
|
|
|
closeButton.onAdd = function () {
|
|
const button = L.DomUtil.create('button', 'leaflet-control-button');
|
|
button.innerHTML = 'Chiudi'; // Testo del pulsante
|
|
button.style.backgroundColor = 'red';
|
|
button.style.color = 'white';
|
|
button.style.border = 'none';
|
|
button.style.borderRadius = '5px';
|
|
button.style.padding = '10px';
|
|
button.style.cursor = 'pointer';
|
|
|
|
button.onclick = () => {
|
|
mostraMappa.value = false; // Chiudi il dialog della mappa
|
|
};
|
|
|
|
return button;
|
|
};
|
|
|
|
closeButton.addTo(map.value);
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
const onResize = () => {
|
|
if (map.value) {
|
|
map.value.invalidateSize();
|
|
}
|
|
};
|
|
|
|
const updateMarker = (lat: number, lng: number) => {
|
|
// console.log('aggiorna marker', lat, lng)
|
|
if (fineLoad.value) {
|
|
modificato.value = true
|
|
}
|
|
if (marker.value) {
|
|
marker.value.setLatLng([lat, lng])
|
|
} else {
|
|
marker.value = L.marker([lat, lng], { draggable: true }).addTo(map.value!)
|
|
marker.value.on('dragend', (event: L.LeafletEvent) => {
|
|
const position = (event.target as L.Marker).getLatLng()
|
|
localCoordinates.value = {
|
|
lat: parseFloat(position.lat.toFixed(6)),
|
|
lng: parseFloat(position.lng.toFixed(6)),
|
|
};
|
|
if (fineLoad.value) {
|
|
mostraMappa.value = true
|
|
}
|
|
getAddressFromCoordinates(localCoordinates.value.lat, localCoordinates.value.lng);
|
|
// updateCoordinates()
|
|
})
|
|
}
|
|
map.value?.setView([lat, lng], zoomLevel.value)
|
|
}
|
|
|
|
function updateMap() {
|
|
|
|
map.value?.setView([localCoordinates.value.lat, localCoordinates.value.lng], zoomLevel.value)
|
|
}
|
|
|
|
const searchAddress = async () => {
|
|
try {
|
|
const response = await fetch(`https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(localAddress.value)}`)
|
|
const data = await response.json()
|
|
if (data && data.length > 0) {
|
|
localCoordinates.value = { lat: parseFloat(data[0].lat), lng: parseFloat(data[0].lon) }
|
|
localAddress.value = data[0].display_name
|
|
if (fineLoad.value) {
|
|
mostraMappa.value = true
|
|
}
|
|
isMapDialogOpen.value = true
|
|
}
|
|
} catch (error) {
|
|
console.error('Error searching address:', error)
|
|
}
|
|
}
|
|
|
|
const getAddressSuggestions = async (val: string, update: Function) => {
|
|
try {
|
|
if (val.length === 0) {
|
|
suggestions.value = [];
|
|
update();
|
|
return;
|
|
}
|
|
|
|
const response = await fetch(
|
|
`https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(val)}`
|
|
);
|
|
const data = await response.json();
|
|
suggestions.value = data.map((item: any) => ({
|
|
label: item.display_name,
|
|
value: item.display_name,
|
|
lat: item.lat,
|
|
lon: item.lon
|
|
}));
|
|
|
|
update();
|
|
} catch (error) {
|
|
console.error('Error fetching address suggestions:', error);
|
|
}
|
|
};
|
|
|
|
const getAddressFromCoordinates = async (lat: number, lon: number) => {
|
|
const url = `https://nominatim.openstreetmap.org/reverse?lat=${lat}&lon=${lon}&format=json`;
|
|
|
|
try {
|
|
const response = await fetch(url);
|
|
if (!response.ok) {
|
|
throw new Error('Errore nella richiesta di geocoding');
|
|
}
|
|
const data = await response.json();
|
|
localAddress.value = data.display_name; // Ottieni l'indirizzo
|
|
localAddressObj.value = { label: localAddress.value, value: localAddress.value }
|
|
} catch (error) {
|
|
console.error('Errore durante il geocoding:', error);
|
|
localAddress.value = ''; // In caso di errore, resetta l'indirizzo
|
|
localAddressObj.value = { label: '', value: '' }
|
|
}
|
|
};
|
|
|
|
watch(localAddressObj, (newAddress: any) => {
|
|
if (newAddress) {
|
|
const match: any = suggestions.value.find((suggestion: any) => suggestion.value === newAddress.value);
|
|
if (match && match.lat) {
|
|
localAddress.value = match.value;
|
|
localCoordinates.value = {
|
|
lat: parseFloat(parseFloat(match.lat).toFixed(6)),
|
|
lng: parseFloat(parseFloat(match.lon).toFixed(6)),
|
|
};
|
|
updateCoordinates()
|
|
updateAddress()
|
|
|
|
updateMarker(localCoordinates.value.lat, localCoordinates.value.lng);
|
|
}
|
|
}
|
|
});
|
|
|
|
function salvaCoordinate() {
|
|
updateCoordinates()
|
|
updateAddress()
|
|
$q.notify({
|
|
type: 'positive',
|
|
message: 'Coordinate modificate, Salvare per rendere effettiva la modifica',
|
|
position: 'bottom',
|
|
timeout: 2000
|
|
})
|
|
modificato.value = false
|
|
mostraMappa.value = false
|
|
}
|
|
|
|
onMounted(() => {
|
|
|
|
if (!props.modelValue.address) {
|
|
localAddress.value = ''
|
|
localAddressObj.value = { label: '', value: '' }
|
|
} else {
|
|
localAddressObj.value = { label: props.modelValue.address, value: props.modelAddress }
|
|
}
|
|
if (!props.modelValue.coordinates) {
|
|
localCoordinates.value = { lat: 0, lng: 0 }
|
|
}
|
|
|
|
initMap()
|
|
|
|
updateMap()
|
|
updateMarker(localCoordinates.value.lat, localCoordinates.value.lng);
|
|
|
|
if (!localCoordinates.value || !localCoordinates.value.lat) {
|
|
mostraMappa.value = false
|
|
}
|
|
fineLoad.value = true
|
|
window.addEventListener('resize', onResize);
|
|
|
|
nextTick(() => {
|
|
mostraMappa.value = props.visuMappa
|
|
})
|
|
})
|
|
|
|
onBeforeUnmount(() => {
|
|
window.removeEventListener('resize', onResize);
|
|
});
|
|
|
|
const getCurrentLocation = () => {
|
|
if ('geolocation' in navigator) {
|
|
navigator.geolocation.getCurrentPosition(
|
|
(position) => {
|
|
localCoordinates.value = {
|
|
lat: parseFloat(position.coords.latitude.toFixed(6)),
|
|
lng: parseFloat(position.coords.longitude.toFixed(6)),
|
|
};
|
|
if (fineLoad.value) {
|
|
mostraMappa.value = true;
|
|
}
|
|
updateCoordinates();
|
|
updateMarker(localCoordinates.value.lat, localCoordinates.value.lng);
|
|
},
|
|
(error) => {
|
|
console.error('Error getting location:', error);
|
|
$q.notify({
|
|
type: 'negative',
|
|
message: 'Errore durante il rilevamento della posizione.',
|
|
});
|
|
}
|
|
);
|
|
} else {
|
|
$q.notify({
|
|
type: 'negative',
|
|
message: 'Geolocalizzazione non supportata dal browser.',
|
|
});
|
|
}
|
|
};
|
|
|
|
function annullaSalvataggio() {
|
|
localCoordinates.value.lng = props.modelValue.coordinates[0]
|
|
localCoordinates.value.lat = props.modelValue.coordinates[1]
|
|
localAddress.value = props.modelValue.address
|
|
updateMarker(localCoordinates.value.lat, localCoordinates.value.lng);
|
|
mostraMappa.value = false
|
|
modificato.value = false
|
|
}
|
|
|
|
// evento dopo il mounting
|
|
return {
|
|
searchAddress,
|
|
myheight,
|
|
isMapDialogOpen,
|
|
suggestions,
|
|
getAddressSuggestions,
|
|
localAddress,
|
|
localCoordinates,
|
|
updateAddress,
|
|
updateCoordinates,
|
|
mostraMappa,
|
|
localAddressObj,
|
|
getCurrentLocation,
|
|
salvaCoordinate,
|
|
modificato,
|
|
annullaSalvataggio,
|
|
mapContainer,
|
|
fineLoad,
|
|
}
|
|
}
|
|
}) |