- Creazione "AbitareGliIblei"
- Mappa Interattiva con i markers
This commit is contained in:
390
src/components/CMapEditAddressByCoord/CMapEditAddressByCoord.ts
Executable file
390
src/components/CMapEditAddressByCoord/CMapEditAddressByCoord.ts
Executable file
@@ -0,0 +1,390 @@
|
||||
import { tools } from '@store/Modules/tools'
|
||||
import { useQuasar } from 'quasar'
|
||||
import { defineComponent, onMounted, onBeforeUnmount, ref, watch, computed, PropType, nextTick } 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 { 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 = ref<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.lng, (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,
|
||||
}
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user