Files
myprojplanet_vite/src/components/CMapEditAddressByCoord/CMapEditAddressByCoord.ts
Surya Paolo 8f4ff8ff9c - attivita
- gestione degli script sul server
 - creato websocket per interagire con gli script del server.
2024-08-29 23:31:54 +02:00

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,
}
}
})