Prace s mapu, zobrazeni GPX, editace kopilota, skeletony
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
<script setup>
|
||||
import {computed} from "vue";
|
||||
|
||||
const props = defineProps({
|
||||
address: {
|
||||
type: String
|
||||
},
|
||||
gpsLatitude: {
|
||||
type: Number
|
||||
},
|
||||
gpsLongitude: {
|
||||
type: Number
|
||||
},
|
||||
zoom: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 12
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: "500px"
|
||||
}
|
||||
});
|
||||
|
||||
const addressEncoded = computed(() => {
|
||||
if (!props.gpsLatitude || !props.gpsLongitude) {
|
||||
return encodeURI(props.address);
|
||||
} else {
|
||||
return `${props.gpsLatitude},${props.gpsLongitude}`
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<iframe frameborder="0" scrolling="no" marginheight="0" marginwidth="0"
|
||||
:src="`https://maps.google.com/maps?q=${addressEncoded}&t=m&z=${zoom}&output=embed&iwloc=near`"
|
||||
:style="`width: 100%; height: ${height}`"
|
||||
:aria-label="address"/>
|
||||
</template>
|
||||
@@ -0,0 +1,71 @@
|
||||
<script setup>
|
||||
import MapWrapper from "components/map/MapWrapper.vue";
|
||||
import {Marker, Polyline, InfoWindow} from "vue3-google-map";
|
||||
import {computed, onMounted, ref} from "vue";
|
||||
import {axios} from "boot/axios";
|
||||
|
||||
|
||||
const props = defineProps({
|
||||
gpxTrackUrl: {
|
||||
type: String,
|
||||
required: false,
|
||||
},
|
||||
markers: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: () => []
|
||||
},
|
||||
photos: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: () => []
|
||||
}
|
||||
})
|
||||
|
||||
const track = ref([]);
|
||||
const gpxLoading = ref(!!props.gpxTrackUrl);
|
||||
onMounted(() => {
|
||||
if (!props.gpxTrackUrl) {
|
||||
return;
|
||||
}
|
||||
gpxLoading.value = true;
|
||||
axios.get(props.gpxTrackUrl)
|
||||
.then(({data}) => (new window.DOMParser()).parseFromString(data, "text/xml"))
|
||||
.then(doc => {
|
||||
const points = [];
|
||||
const nodes = [...doc.getElementsByTagName('trkpt')];
|
||||
nodes.forEach(node => {
|
||||
const lat = parseFloat(node.getAttribute("lat"));
|
||||
const lng = parseFloat(node.getAttribute("lon"));
|
||||
points.push({lat, lng});
|
||||
})
|
||||
|
||||
track.value = points; // puvodne se bounds bralo z tohodle
|
||||
})
|
||||
.finally(() => gpxLoading.value = false);
|
||||
});
|
||||
|
||||
|
||||
const bounds = computed(() => {
|
||||
const photosTransformed = props.photos.map(p => ({position: {lat: p.gpsLatitude, lng: p.gpsLongitude}}));
|
||||
const allData = [...props.markers, ...track.value, ...photosTransformed];
|
||||
return allData.filter(i => !!i.position).map(i => i.position);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="gpxLoading" v-bind="$attrs">Loading</div>
|
||||
<MapWrapper v-bind="$attrs" :bounds="bounds" v-if="!gpxLoading">
|
||||
<Marker v-for="(marker, idx) in markers" :key="idx" :options="marker"/>
|
||||
|
||||
<Marker v-for="(photo, idx) in photos" :key="idx" :options="{icon: '/mapIcons/photo-16x16.png', position: {lat: photo.gpsLatitude, lng: photo.gpsLongitude}}">
|
||||
<InfoWindow :options="{position: {lat: photo.gpsLatitude, lng: photo.gpsLongitude}}">
|
||||
<img :src="photo.thumbnailUrl" />
|
||||
</InfoWindow>
|
||||
</Marker>
|
||||
|
||||
<template v-if="track.length > 0">
|
||||
<Polyline :options="{path: track, geodesic: true, strokeColor: '#ff0000', strokeOpacity: 0.3, strokeWeight: 5}"/>
|
||||
</template>
|
||||
</MapWrapper>
|
||||
</template>
|
||||
@@ -0,0 +1,36 @@
|
||||
<script setup>
|
||||
import {GoogleMap} from "vue3-google-map";
|
||||
import {ref, watch} from "vue";
|
||||
|
||||
const props = defineProps({
|
||||
bounds: {
|
||||
type: Array,
|
||||
required: false
|
||||
}
|
||||
});
|
||||
|
||||
const key = process.env.GOOGLE_MAPS_API_KEY;
|
||||
|
||||
|
||||
const mapRef = ref(null);
|
||||
watch(
|
||||
() => mapRef.value?.ready,
|
||||
(ready) => {
|
||||
if (!props.bounds || !ready) return;
|
||||
const map = mapRef.value.map;
|
||||
const api = mapRef.value.api;
|
||||
|
||||
const bounds = new api.LatLngBounds();
|
||||
for (let i = 0; i < props.bounds.length; i++) {
|
||||
bounds.extend(props.bounds[i]);
|
||||
}
|
||||
map.fitBounds(bounds);
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<GoogleMap :api-key="key" v-bind="$attrs" :max-zoom="13" ref="mapRef">
|
||||
<slot/>
|
||||
</GoogleMap>
|
||||
</template>
|
||||
Reference in New Issue
Block a user