- posizione attuale GPS
- salvataggio ultima posizione in mappa - visualizzazione prima icona con fas
This commit is contained in:
@@ -2,10 +2,11 @@
|
||||
<div v-if="tools.isDebugOn()"></div>
|
||||
<div :class="$q.screen.lt.sm ? `` : `q-pa-xs`" v-if="isfinishLoading">
|
||||
<q-toggle
|
||||
v-if="tools.isManager()"
|
||||
v-if="tools.isManager() && !showMap"
|
||||
v-model="editOn"
|
||||
color="green"
|
||||
icon="fas fa-pencil-alt"
|
||||
class="fixed-toggle"
|
||||
>
|
||||
</q-toggle>
|
||||
<div
|
||||
@@ -26,15 +27,15 @@
|
||||
|
||||
<div
|
||||
v-if="butt_modif_new || mytitle"
|
||||
:class="$q.screen.lt.sm ? `` : `q-gutter-md q-ma-xs` + ` row`"
|
||||
:class="$q.screen.lt.sm ? `` : `q-ma-xs` + ` `"
|
||||
>
|
||||
<div class="q-table__title" style="min-width: 150px">
|
||||
{{ mytitle }}
|
||||
</div>
|
||||
<q-space></q-space>
|
||||
<div v-if="butt_modif_new">
|
||||
<div v-if="butt_modif_new" class="row justify-center">
|
||||
<q-btn
|
||||
v-if="mytable && !shared_consts.TABLES_FINDER.includes(mytable)"
|
||||
v-if="mytable && !shared_consts.TABLES_FINDER.includes(mytable) && !showMap"
|
||||
rounded
|
||||
dense
|
||||
size="sm"
|
||||
@@ -53,7 +54,7 @@
|
||||
outline
|
||||
size="md"
|
||||
color="primary"
|
||||
class="centermydiv q-mb-sm"
|
||||
class="q-mb-sm"
|
||||
:label="labelBtnAddExtra"
|
||||
:disable="startsearch"
|
||||
icon="fas fa-plus"
|
||||
@@ -74,15 +75,6 @@
|
||||
>
|
||||
</CTitleBanner>
|
||||
|
||||
<q-btn
|
||||
v-if="!showMap"
|
||||
dense
|
||||
:label="t('grid.showmap')"
|
||||
color="primary"
|
||||
icon="fas fa-map-marked-alt"
|
||||
@click="showMap = !showMap"
|
||||
>
|
||||
</q-btn>
|
||||
<div v-if="shared_consts.VERTIC_SHOW_GRID.includes(myvertical)">
|
||||
<div v-if="(prop_search || canEdit) && finder" class="q-my-xs text-right">
|
||||
<!--<q-btn
|
||||
@@ -253,7 +245,7 @@
|
||||
>
|
||||
<q-btn
|
||||
dense
|
||||
:label="!showfilter ? 'Apri Filtri' : 'Chiudi Filtri'"
|
||||
:label="!showfilter ? $t('grid.openfilter') : $t('grid.closefilter')"
|
||||
color="positive"
|
||||
icon="fas fa-filter"
|
||||
@click="showfilter = !showfilter"
|
||||
@@ -274,7 +266,8 @@
|
||||
@click="showNotification = !showNotification"
|
||||
></q-btn>
|
||||
</div>
|
||||
<div v-if="prop_search" class="q-mr-sm full-width">
|
||||
|
||||
<div v-if="prop_search" :class="'q-mr-sm ' + ($q.screen.lt.sm ? ' full-width ' : '')">
|
||||
<q-input
|
||||
v-model="search"
|
||||
filled
|
||||
@@ -369,16 +362,21 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="showMap">
|
||||
<q-btn
|
||||
dense
|
||||
:label="t('grid.showlist')"
|
||||
color="primary"
|
||||
icon="fas fa-list-alt"
|
||||
@click="showMap = !showMap"
|
||||
>
|
||||
</q-btn>
|
||||
<div v-if="shared_consts.TABLES_VISU_MAP.includes(mytable)" class="row justify-center q-ma-sm">
|
||||
<q-btn-toggle
|
||||
v-model="showMap"
|
||||
push
|
||||
glossy
|
||||
dense
|
||||
toggle-color="primary"
|
||||
:options="[
|
||||
{label: t('grid.showmap'), value: true, icon: 'fas fa-map-marked-alt'},
|
||||
{label: t('grid.showlist'), value: false, icon: 'fas fa-list-alt'},
|
||||
]"
|
||||
/>
|
||||
|
||||
</div>
|
||||
<div v-if="showMap">
|
||||
<CMapByTable
|
||||
v-if="serverData && serverData.length > 0"
|
||||
mytable=""
|
||||
@@ -1164,12 +1162,13 @@
|
||||
<q-dialog
|
||||
v-model="visupagedialog"
|
||||
transition-show="slide-up"
|
||||
transition-hide="slide-down"
|
||||
transition-hide="slide-down"
|
||||
@hide="hidewindow"
|
||||
:maximized="$q.screen.lt.sm"
|
||||
:persistent="false"
|
||||
:class="
|
||||
'dialog_annunci ' + ($q.screen.lt.md ? 'bottom-dialog' : ' right-align-dialog')
|
||||
'dialog_annunci ' +
|
||||
($q.screen.lt.sm ? 'bottom-dialog' : ' right-align-dialog')
|
||||
"
|
||||
>
|
||||
<CMyCardGrpPopup
|
||||
@@ -1195,7 +1194,7 @@
|
||||
:table="mytable"
|
||||
:prop_myrec="myrecdialog"
|
||||
:idRec="myIdRecDialog"
|
||||
:showAnteprima="$q.screen.gt.sm ? false : showMap"
|
||||
:showAnteprima="!$q.screen.lt.sm ? false : showMap"
|
||||
>
|
||||
</CMyCardService>
|
||||
<CMyCardPopup v-else :table="mytable" :prop_myrec="myrecdialog">
|
||||
|
||||
@@ -1,3 +1,36 @@
|
||||
.map-container {
|
||||
height: 400px;
|
||||
}
|
||||
}
|
||||
|
||||
.custom-icon {
|
||||
position: relative; /* Rendi il contenitore relativo */
|
||||
width: 40px; /* Larghezza del marker */
|
||||
height: 40px; /* Altezza del marker */
|
||||
}
|
||||
|
||||
.custom-icon .material-icons {
|
||||
position: absolute; /* Posizionamento assoluto per centrare */
|
||||
top: 50%; /* Posizionamento verticale */
|
||||
left: 50%; /* Posizionamento orizzontale */
|
||||
transform: translate(-50%, -50%); /* Centra l'icona */
|
||||
font-size: 20px; /* Dimensione dell'icona 20x20 */
|
||||
color: #000; /* Colore dell'icona (puoi cambiarlo) */
|
||||
}
|
||||
|
||||
.marker-wrapper {
|
||||
position: relative; /* Necessario per posizionare l'icona interna */
|
||||
text-align: center; /* Centro il contenuto */
|
||||
}
|
||||
|
||||
.marker-label {
|
||||
margin-top: 5px; /* Spaziatura sopra l'etichetta */
|
||||
font-size: 12px; /* Dimensione del testo per l'etichetta */
|
||||
}
|
||||
|
||||
/* Stili per il pulsante di localizzazione */
|
||||
.locate-button {
|
||||
position: absolute; /* Assicurati che il pulsante sia posizionato sopra la mappa */
|
||||
top: 20px; /* Posizione dall'alto */
|
||||
right: 20px; /* Distanza dal lato destro */
|
||||
z-index: 1000; /* Assicurati che sia visibile sopra la mappa */
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import 'leaflet.markercluster/dist/MarkerCluster.Default.css'
|
||||
import 'leaflet.markercluster'
|
||||
|
||||
import { useUserStore } from '@src/store/UserStore'
|
||||
import { useGlobalStore } from '@src/store/globalStore'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'CMapByTable',
|
||||
@@ -27,16 +28,36 @@ export default defineComponent({
|
||||
setup(props, { emit }) {
|
||||
const $q = useQuasar()
|
||||
const userStore = useUserStore()
|
||||
const globalStore = useGlobalStore()
|
||||
|
||||
const iconWidth = ref(25)
|
||||
const iconHeight = ref(40)
|
||||
const map = ref(<any>null)
|
||||
const zoom = ref(6)
|
||||
const zoom = ref(8)
|
||||
|
||||
const initialMap = ref(<any>null);
|
||||
const map = ref(<any>null);
|
||||
|
||||
const visiblePosition = ref(false)
|
||||
|
||||
const markers = ref(<any>null);
|
||||
|
||||
const isTrackingLocation = ref(false)
|
||||
|
||||
const currentMarker = ref<L.Marker | null>(null)
|
||||
|
||||
const centerCoordinates = ref<{ lat: number; lng: number }>({ lat: 0, lng: 0 }); //
|
||||
|
||||
const mapOptions = ref(<any>{
|
||||
zoomControl: true,
|
||||
zoomAnimation: true,
|
||||
fadeAnimation: true,
|
||||
markerZoomAnimation: false, //true
|
||||
})
|
||||
|
||||
const tileLayerOptions = {
|
||||
maxZoom: 17,
|
||||
minZoom: 3,
|
||||
}
|
||||
|
||||
const myIcon = L.icon({
|
||||
iconUrl: 'images/icon.png',
|
||||
iconSize: [30, 30],
|
||||
@@ -47,8 +68,42 @@ export default defineComponent({
|
||||
shadowAnchor: [22, 35]
|
||||
});
|
||||
|
||||
|
||||
const myIconPosAtt = L.icon({
|
||||
iconUrl: 'images/icon.png',
|
||||
iconSize: [30, 30],
|
||||
iconAnchor: [22, 35],
|
||||
popupAnchor: [-6, -36],
|
||||
shadowUrl: 'images/marker-shadow.png',
|
||||
shadowSize: [60, 30],
|
||||
shadowAnchor: [22, 35]
|
||||
});
|
||||
|
||||
const iconPosition = L.divIcon({
|
||||
className: 'custom-marker', // Classe CSS personalizzata
|
||||
html: '<span class="material-icons">location_on</span>',
|
||||
iconSize: [40, 40],
|
||||
iconAnchor: [22, 35],
|
||||
popupAnchor: [-6, -36],
|
||||
});
|
||||
|
||||
const currentLocationIcon = L.divIcon({
|
||||
className: 'current-location-icon',
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10]
|
||||
});
|
||||
|
||||
|
||||
const arrcord = toRef(props, 'arrcord')
|
||||
|
||||
watch(() => visiblePosition.value, () => {
|
||||
if (visiblePosition.value === true) {
|
||||
getCurrentPosition()
|
||||
} else {
|
||||
removeCurrentMarker()
|
||||
}
|
||||
})
|
||||
|
||||
function mywidth() {
|
||||
return tools.getwidth($q) - 20
|
||||
}
|
||||
@@ -99,27 +154,9 @@ export default defineComponent({
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
// Ottengo la lista degli utenti con i lat e long
|
||||
// arrcord.value = await userStore.getProvincesForMap()
|
||||
|
||||
// @ts-ignore
|
||||
markers.value = L.markerClusterGroup()
|
||||
initMap()
|
||||
|
||||
initialMap.value = L.map('map',
|
||||
{
|
||||
zoomControl: true, zoom: zoom.value, zoomAnimation: true,
|
||||
fadeAnimation: true, markerZoomAnimation: true,
|
||||
center: [42.71, 12.934],
|
||||
}
|
||||
);
|
||||
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
maxZoom: 15,
|
||||
attribution: ''
|
||||
}).addTo(initialMap.value);
|
||||
|
||||
updateMap()
|
||||
|
||||
// @ts-ignore
|
||||
});
|
||||
|
||||
function log(str: string) {
|
||||
@@ -135,28 +172,185 @@ export default defineComponent({
|
||||
console.log(`Latitudine: ${lat}, Longitudine: ${lng}`)
|
||||
}
|
||||
|
||||
function getIconName(myrec: any) {
|
||||
const myarrSectors = myrec.sector
|
||||
if (!myarrSectors) return 'mdi-map-marker-outline'
|
||||
|
||||
let sectId = myarrSectors[0]._id
|
||||
return globalStore.getIconBySector(sectId)
|
||||
}
|
||||
|
||||
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,
|
||||
zoom: zoom.value,
|
||||
center: getLastCoord
|
||||
}
|
||||
map.value = L.map('map', newmapopt);
|
||||
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', tileLayerOptions).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);
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
markers.value = L.markerClusterGroup();
|
||||
|
||||
map.value.addLayer(markers.value);
|
||||
|
||||
// Assicuriamoci che la mappa sia completamente caricata prima di procedere
|
||||
map.value.whenReady(() => {
|
||||
console.log('Mappa inizializzata e pronta');
|
||||
updateMap();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function updateMap() {
|
||||
if (initialMap.value) {
|
||||
if (!map.value || !markers.value) return;
|
||||
|
||||
if (map.value) {
|
||||
markers.value.clearLayers();
|
||||
|
||||
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 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: myIcon })
|
||||
.bindPopup(`<strong>${rec.descr}</strong>`)
|
||||
.on('click', () => markerClick(rec._id)); // Collega il click al bottone
|
||||
[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
|
||||
initialMap.value.addLayer(markers.value);
|
||||
map.value.addLayer(markers.value);
|
||||
}
|
||||
}
|
||||
|
||||
function markerClick(id: any) {
|
||||
emit('clickMarker', id)
|
||||
// emit('clickMarker', id)
|
||||
}
|
||||
function ApriScheda(id: any) {
|
||||
emit('clickMarker', id)
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
isTrackingLocation.value = false; // Resetta lo stato di tracciamento
|
||||
}
|
||||
);
|
||||
} else {
|
||||
console.error('Geolocalizzazione non supportata dal browser.');
|
||||
}
|
||||
}
|
||||
|
||||
const removeCurrentMarker = () => {
|
||||
if (currentMarker.value) {
|
||||
map.value.removeLayer(currentMarker.value); // Rimuovi il marker dalla mappa
|
||||
currentMarker.value = null; // Resetta il riferimento
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -172,6 +366,9 @@ export default defineComponent({
|
||||
log,
|
||||
getCoordinates,
|
||||
arrcord,
|
||||
getCurrentPosition,
|
||||
isTrackingLocation,
|
||||
visiblePosition,
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
<template>
|
||||
<div>
|
||||
<div id="map" :style="`height:${myheight()}px; width:99%`">
|
||||
<q-btn
|
||||
@click="getCurrentPosition"
|
||||
color="primary"
|
||||
:disable="isTrackingLocation"
|
||||
:push="visiblePosition"
|
||||
/>
|
||||
<q-toggle
|
||||
class="locate-button"
|
||||
icon="fas fa-map-marker-alt"
|
||||
round
|
||||
v-model="visiblePosition"
|
||||
color="primary"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user