extensive changes
This commit is contained in:
@@ -1,64 +1,168 @@
|
||||
<template>
|
||||
<div style="height: 600px; width: 800px; color: #000000">
|
||||
<L-Map
|
||||
@ready="onMapReady"
|
||||
ref="mapRef"
|
||||
:zoom="zoom"
|
||||
:center="center"
|
||||
style="height: 500px; width: 100%"
|
||||
@click="updateMarker"
|
||||
<div class="q-pa-md">
|
||||
<q-layout
|
||||
view="hHh Lpr fFf"
|
||||
container
|
||||
style="height: 600px; width: 100vw"
|
||||
class="rounded-borders"
|
||||
>
|
||||
<L-Tile-Layer
|
||||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||
layer-type="base"
|
||||
name="OpenStreetMap"
|
||||
@click="updateMarker($event.latlng)"
|
||||
></L-Tile-Layer>
|
||||
<L-Marker :lat-lng="markerLatLng" @click="handleMarkerClick"></L-Marker>
|
||||
<L-Routing-Machine
|
||||
@routingstart="debugRoutingEvent"
|
||||
@routesfound="debugRoutingEvent"
|
||||
@routingerror="debugRoutingEvent"
|
||||
:waypoints="waypoints"
|
||||
/>
|
||||
</L-Map>
|
||||
<q-footer :class="$q.dark.isActive ? 'bg-primary' : 'bg-black'" style="height: 48px">
|
||||
<q-toolbar>
|
||||
<q-btn
|
||||
class="q-mr-sm"
|
||||
dense
|
||||
flat
|
||||
icon="menu"
|
||||
round
|
||||
size="sm"
|
||||
@click="qLocDrawer = !qLocDrawer"
|
||||
/>
|
||||
<q-btn-dropdown flat label="Zoom To" size="sm" stretch>
|
||||
<q-list>
|
||||
<q-item v-close-popup v-ripple clickable @click="zoomTo('fmLoc')">
|
||||
<q-item-section>
|
||||
<q-item-label>Find My Location</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item v-close-popup v-ripple clickable @click="zoomTo('simLoc')">
|
||||
<q-item-section>
|
||||
<q-item-label>Sim Location</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-btn-dropdown>
|
||||
<q-btn label="Routing" @click="routeLayer = !routeLayer" size="sm" stretch />
|
||||
</q-toolbar>
|
||||
</q-footer>
|
||||
<q-drawer
|
||||
v-model="qLocDrawer"
|
||||
show-if-above
|
||||
mini-to-overlay
|
||||
overlay
|
||||
:width="300"
|
||||
side="left"
|
||||
:breakpoint="500"
|
||||
:mini="miniState"
|
||||
@mouseenter="miniState = false"
|
||||
@mouseleave="miniState = true"
|
||||
>
|
||||
<q-scroll-area class="fit" :horizontal-thumb-style="{ opacity: 0 }">
|
||||
<q-list padding>
|
||||
<q-item-label header>Location Queue</q-item-label>
|
||||
<q-separator />
|
||||
<LocationMark
|
||||
v-for="key in locationQueueOrder"
|
||||
:key="key"
|
||||
:loc_id="key"
|
||||
:active="locationQueueData[key].loc_id === currentLocation.loc_id"
|
||||
:start="locationQueueData[key].start"
|
||||
:address="locationQueueData[key].address"
|
||||
:latitude="locationQueueData[key].latitude"
|
||||
:longitude="locationQueueData[key].longitude"
|
||||
:end="locationQueueData[key].end"
|
||||
@item-clicked="zoomToCoods"
|
||||
/>
|
||||
</q-list>
|
||||
</q-scroll-area>
|
||||
</q-drawer>
|
||||
|
||||
<q-page-container>
|
||||
<q-page>
|
||||
<div style="height: 560px; width: 90vw; color: #000000">
|
||||
<L-Map
|
||||
ref="mapRef"
|
||||
:center="center"
|
||||
:zoom="zoom"
|
||||
style="height: 550px; width: 100%"
|
||||
@click="updateMarker"
|
||||
@ready="onMapReady"
|
||||
>
|
||||
<L-Tile-Layer
|
||||
layer-type="base"
|
||||
name="OpenStreetMap"
|
||||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||
@click="updateMarker($event.latlng)"
|
||||
></L-Tile-Layer>
|
||||
<L-Layer-Group>
|
||||
<L-Marker v-if="markerLatLng" :lat-lng="markerLatLng" @click="handleMarkerClick">
|
||||
</L-Marker>
|
||||
</L-Layer-Group>
|
||||
<L-Layer-Group v-if="locationQueueOrder">
|
||||
<L-Marker
|
||||
v-for="locid in locationQueueOrder"
|
||||
:key="locid"
|
||||
:icon="getCustomIcon(locid)"
|
||||
:lat-lng="[locationQueueData[locid].latitude, locationQueueData[locid].longitude]"
|
||||
>
|
||||
</L-Marker>
|
||||
</L-Layer-Group>
|
||||
<L-Layer-Group v-if="routeLayer">
|
||||
<LRoutingMachine
|
||||
v-bind="routingOptions"
|
||||
@routingstart="debugRoutingEvent"
|
||||
@routesfound="debugRoutingEvent"
|
||||
@routingerror="debugRoutingEvent"
|
||||
/>
|
||||
</L-Layer-Group>
|
||||
<L-Layer-Group v-if="findMyUpdate">
|
||||
<L-Marker
|
||||
v-if="findMyUpdate"
|
||||
:icon="fmIcon"
|
||||
:lat-lng="[findMyUpdate.latitude, findMyUpdate.longitude]"
|
||||
></L-Marker>
|
||||
<L-Circle
|
||||
:fillOpacity="0.5"
|
||||
:lat-lng="[findMyUpdate.latitude, findMyUpdate.longitude]"
|
||||
:radius="findMyUpdate.horizontalAccuracy"
|
||||
color="firebrick"
|
||||
fillColor="indianred"
|
||||
></L-Circle>
|
||||
</L-Layer-Group>
|
||||
</L-Map>
|
||||
</div>
|
||||
</q-page>
|
||||
</q-page-container>
|
||||
</q-layout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
<script lang="ts" setup>
|
||||
import { useQuasar } from 'quasar';
|
||||
import { ref } from 'vue';
|
||||
import { computed, onMounted, reactive, ref } from 'vue';
|
||||
import { GeoSearchControl, OpenStreetMapProvider } from 'leaflet-geosearch';
|
||||
import LRoutingMachine from 'components/LRoutingMachine.vue';
|
||||
import 'leaflet-routing-machine/dist/leaflet-routing-machine.css';
|
||||
import { Icon, PinCirclePanel, PinStarPanel } from 'leaflet-extra-markers';
|
||||
import 'leaflet-geosearch/dist/geosearch.css';
|
||||
import 'leaflet/dist/leaflet.css';
|
||||
import LRoutingMachine from 'components/LRoutingMachine.vue';
|
||||
import LocationMark from 'components/LocationMark.vue';
|
||||
|
||||
import type { coords, SearchControlProps } from 'src/types';
|
||||
import type { Map, LeafletMouseEvent } from 'leaflet';
|
||||
import type { LeafletMouseEvent, Map } from 'leaflet';
|
||||
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useSocketioStore } from 'stores/socketio';
|
||||
import { useLeafletStore } from 'stores/leaflet';
|
||||
|
||||
import SetLocationDialog from 'components/SetLocationDialog.vue';
|
||||
import { LMap, LMarker, LTileLayer } from '@vue-leaflet/vue-leaflet';
|
||||
|
||||
const waypoints = [
|
||||
[ 38.7436056, -9.2304153 ],
|
||||
[ 38.7436056, -0.131281 ],
|
||||
];
|
||||
|
||||
import { LCircle, LLayerGroup, LMap, LMarker, LTileLayer } from '@vue-leaflet/vue-leaflet';
|
||||
import { favorites } from 'constants/favorites';
|
||||
|
||||
const leafletStore = useLeafletStore();
|
||||
const socketStore = useSocketioStore();
|
||||
const { zoom, center, markerLatLng } = storeToRefs(socketStore);
|
||||
const $q = useQuasar();
|
||||
const mapRef = ref(null);
|
||||
const responseMessage = ref('');
|
||||
const { zoom, center, markerLatLng, qLocDrawer } = storeToRefs(leafletStore);
|
||||
|
||||
const debugRoutingEvent = (event) => {
|
||||
console.log(`${event.type} event: `, event);
|
||||
};
|
||||
const socketStore = useSocketioStore();
|
||||
const { currentLocation, nextLocation, locationQueueData, locationQueueOrder, findMyUpdate } =
|
||||
storeToRefs(socketStore);
|
||||
|
||||
const $q = useQuasar();
|
||||
|
||||
const mapRef = ref();
|
||||
const responseMessage = ref('');
|
||||
const routeStart = ref(null);
|
||||
const routeEnd = ref(null);
|
||||
const routeLayer = ref(false);
|
||||
const miniState = ref(true);
|
||||
|
||||
const onMapReady = (map: Map) => {
|
||||
const provider = new OpenStreetMapProvider();
|
||||
@@ -81,6 +185,48 @@ const onMapReady = (map: Map) => {
|
||||
map.addControl(searchControl);
|
||||
};
|
||||
|
||||
const fmIcon = new Icon({
|
||||
color: 'indianred',
|
||||
accentColor: 'firebrick',
|
||||
content: 'FM',
|
||||
contentColor: 'white',
|
||||
scale: 1,
|
||||
svg: PinCirclePanel,
|
||||
});
|
||||
|
||||
const getCustomIcon = (locid: string) => {
|
||||
const locationIndex = locationQueueOrder.value.indexOf(locid);
|
||||
if (currentLocation.value && currentLocation.value.loc_id === locid) {
|
||||
return new Icon({
|
||||
color: 'pink',
|
||||
accentColor: 'black',
|
||||
content: '*',
|
||||
contentColor: 'black',
|
||||
scale: 1.5,
|
||||
svg: PinStarPanel,
|
||||
});
|
||||
}
|
||||
return new Icon({
|
||||
color: 'blue',
|
||||
accentColor: 'firebrick',
|
||||
content: locationIndex.toString(),
|
||||
contentColor: 'white',
|
||||
scale: 1,
|
||||
svg: PinCirclePanel,
|
||||
});
|
||||
};
|
||||
|
||||
const routingOptions = reactive({
|
||||
waypoints: [
|
||||
[40.910773020811, -73.891069806448],
|
||||
[40.90930366920829, -73.87658695470259],
|
||||
],
|
||||
});
|
||||
|
||||
const debugRoutingEvent = (event) => {
|
||||
console.log(`${event.type} event: `, event);
|
||||
};
|
||||
|
||||
function updateMarker(event: LeafletMouseEvent) {
|
||||
markerLatLng.value = [event.latlng.lat, event.latlng.lng];
|
||||
center.value = [event.latlng.lat, event.latlng.lng];
|
||||
@@ -114,10 +260,17 @@ function handleMarkerClick(event: LeafletMouseEvent) {
|
||||
}
|
||||
|
||||
function setLocation(coords: coords, delay: number) {
|
||||
let notType: string = 'positive';
|
||||
try {
|
||||
responseMessage.value = socketStore.simulationControl('add', delay, coords.lat, coords.lng);
|
||||
$q.notify({ type: 'positive', message: responseMessage.value });
|
||||
const setCmdRsp = socketStore.simulationControl('add', delay, coords.lat, coords.lng);
|
||||
if (setCmdRsp.sts === 'error') {
|
||||
notType = 'negative';
|
||||
}
|
||||
if (setCmdRsp.msg) {
|
||||
responseMessage.value = setCmdRsp.msg;
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
notType = 'negative';
|
||||
if (error instanceof Error) {
|
||||
console.error('Error setting location:', error.message);
|
||||
responseMessage.value = `Failed to set location: ${error.message}`;
|
||||
@@ -125,14 +278,65 @@ function setLocation(coords: coords, delay: number) {
|
||||
console.error('Error setting location:', error);
|
||||
responseMessage.value = `Failed to set location: Unknown error`;
|
||||
}
|
||||
$q.notify({ type: 'negative', message: responseMessage.value });
|
||||
} finally {
|
||||
$q.notify({ type: notType, message: responseMessage.value });
|
||||
}
|
||||
}
|
||||
|
||||
function zoomToCoods(arg: string) {
|
||||
leafletStore.setCenter(
|
||||
locationQueueData.value[arg].latitude,
|
||||
locationQueueData.value[arg].longitude,
|
||||
);
|
||||
leafletStore.setZoom(50);
|
||||
qLocDrawer.value = false;
|
||||
}
|
||||
|
||||
function zoomTo(loc: string) {
|
||||
switch (loc) {
|
||||
case 'fmLoc':
|
||||
if (findMyUpdate.value && findMyUpdate.value.latitude && findMyUpdate.value.longitude) {
|
||||
leafletStore.setCenter(findMyUpdate.value.latitude, findMyUpdate.value.longitude);
|
||||
}
|
||||
$q.notify({ type: 'negative', message: 'Find My Location not available' });
|
||||
break;
|
||||
case 'simLoc':
|
||||
if (
|
||||
currentLocation.value &&
|
||||
currentLocation.value.latitude &&
|
||||
currentLocation.value.longitude
|
||||
) {
|
||||
leafletStore.setCenter(currentLocation.value.latitude, currentLocation.value.longitude);
|
||||
}
|
||||
$q.notify({ type: 'negative', message: 'Simulation Location not available' });
|
||||
break;
|
||||
case 'nextLoc':
|
||||
if (nextLocation.value && nextLocation.value.latitude && nextLocation.value.longitude) {
|
||||
leafletStore.setCenter(nextLocation.value.latitude, nextLocation.value.longitude);
|
||||
}
|
||||
$q.notify({ type: 'negative', message: 'Next Location not available' });
|
||||
break;
|
||||
default:
|
||||
$q.notify({ type: 'negative', message: 'Invalid location' });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (findMyUpdate.value && findMyUpdate.value.latitude && findMyUpdate.value.longitude) {
|
||||
leafletStore.setCenter(findMyUpdate.value.latitude, findMyUpdate.value.longitude);
|
||||
} else {
|
||||
leafletStore.setCenter(favorites.home.coords.lat, favorites.home.coords.lng);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.l-map {
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
}
|
||||
<style lang="sass">
|
||||
.l-map
|
||||
height: 100vh
|
||||
width: 100vw
|
||||
|
||||
.q-item.q-router-link--active, .q-item--active
|
||||
background-color: $accent
|
||||
color: $primary
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user