customIcon

This commit is contained in:
2026-04-01 15:47:38 -04:00
parent e63a8a6329
commit a6264fad67
4 changed files with 89 additions and 29 deletions

View File

@@ -51,7 +51,7 @@
v-model="qLocDrawer" v-model="qLocDrawer"
show-if-above show-if-above
overlay overlay
:width="300" :width="250"
side="left" side="left"
:breakpoint="500" :breakpoint="500"
@mouseenter="miniState = false" @mouseenter="miniState = false"

View File

@@ -3,6 +3,8 @@ import { storeToRefs } from 'pinia';
import { useSocketioStore } from 'stores/socketio'; import { useSocketioStore } from 'stores/socketio';
import { computed, onMounted, onUnmounted, ref } from 'vue'; import { computed, onMounted, onUnmounted, ref } from 'vue';
import { Icon, PinCirclePanel, PinStarPanel } from 'leaflet-extra-markers';
const socketStore = useSocketioStore(); const socketStore = useSocketioStore();
const { currentLocation, locationQueueOrder, simulationRunning } = storeToRefs(socketStore); const { currentLocation, locationQueueOrder, simulationRunning } = storeToRefs(socketStore);
@@ -52,6 +54,9 @@ const props = defineProps({
// Define custom events that this component can emit // Define custom events that this component can emit
const emit = defineEmits(['item-clicked']); const emit = defineEmits(['item-clicked']);
const markerHTML = ref('');
function itemClicked() { function itemClicked() {
const param1 = props.loc_id; const param1 = props.loc_id;
emit('item-clicked', param1); emit('item-clicked', param1);
@@ -195,24 +200,48 @@ function formatAddress(input: string): string {
return `${streetNumber} ${streetName}, ${city}, ${state} ${zip}`; return `${streetNumber} ${streetName}, ${city}, ${state} ${zip}`;
} }
const currentIndex = computed(() => {
return currentLocation.value ? locationQueueOrder.value.indexOf(currentLocation.value.loc_id) : 0;
});
const myIndex = computed(() => {
return locationQueueOrder.value.indexOf(props.loc_id);
});
const myUpdatedIndex = computed(() => {
return (myIndex.value - currentIndex.value)
});
const markerIndex = computed(() => { const markerIndex = computed(() => {
const currentIndex = currentLocation.value return props.active ? '*' : myUpdatedIndex.value.toString();
? locationQueueOrder.value.indexOf(currentLocation.value.loc_id)
: 0;
const locationIndex = locationQueueOrder.value.indexOf(props.loc_id);
return props.active ? '*' : (locationIndex - currentIndex).toString();
}); });
const itemClass = computed(() => { const itemClass = computed(() => {
const currentIndex = currentLocation.value if (myUpdatedIndex.value > 0) return 'future';
? locationQueueOrder.value.indexOf(currentLocation.value.loc_id) else if (myUpdatedIndex.value < 0) return 'past';
: 0;
const locationIndex = locationQueueOrder.value.indexOf(props.loc_id);
if (locationIndex - currentIndex > 0) return 'future';
else if (locationIndex - currentIndex < 0) return 'past';
else return 'active'; else return 'active';
}); });
const customIcon = computed(() => {
return new Icon({
color: 'blue',
accentColor: 'firebrick',
content: myUpdatedIndex.value.toString(),
contentColor: 'white',
scale: 1,
svg: PinCirclePanel,
});
});
const iconElement = computed(() => {
return customIcon.value.createIcon();
});
const iconHtml = computed(() => {
return iconElement.outerHTML;
});
onMounted(() => { onMounted(() => {
const update = () => { const update = () => {
currentTime.value = new Date(); currentTime.value = new Date();
@@ -239,17 +268,15 @@ onUnmounted(() => {
<q-item-label caption lines="1" v-if="end && simulationRunning"> <q-item-label caption lines="1" v-if="end && simulationRunning">
end: {{ humanReadableDateTime(end) }} end: {{ humanReadableDateTime(end) }}
</q-item-label> </q-item-label>
<q-item-label caption lines="1" v-else>
delay: {{ delay }} seconds
</q-item-label>
</q-item-section> </q-item-section>
<q-item-section side top> <q-item-section side>
<q-item-label caption lines="1" v-if="simulationRunning"> <q-item-label caption lines="1" v-if="simulationRunning">
{{ calculateDeltaT }} {{ calculateDeltaT }}
</q-item-label> </q-item-label>
<q-item-label caption lines="1" v-else> delay: {{ secondsToTime }} seconds </q-item-label> <q-icon class="q-mt-lg" v-html="iconElement.outerHTML" />
<q-item-section avatar class="q-pt-md">
<q-btn dense color="primary" round icon="location_on" class="q-ml-md">
<q-badge color="accent" floating>{{ markerIndex }}</q-badge>
</q-btn>
</q-item-section>
</q-item-section> </q-item-section>
</q-item> </q-item>
<q-separator spaced inset v-if="isLast" /> <q-separator spaced inset v-if="isLast" />

View File

@@ -2,7 +2,7 @@ import { useLeafletStore } from 'stores/leaflet';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
const leafletStore = useLeafletStore(); const leafletStore = useLeafletStore();
const { routeSegments } = storeToRefs(leafletStore); const { routeSegments, routeDirections } = storeToRefs(leafletStore);
type RouteSummary = { type RouteSummary = {
@@ -17,10 +17,19 @@ type RouteWaypoint = {
}; };
}; };
type RouteInstructions = {
text: string;
distance: number;
time: number;
index: number;
};
type RouteResult = { type RouteResult = {
summary?: RouteSummary; summary?: RouteSummary;
segments?: RouteSummary[]; segments?: RouteSummary[];
inputWaypoints?: RouteWaypoint[]; inputWaypoints?: RouteWaypoint[];
instructions?: RouteInstructions[];
waypoints?: RouteWaypoint[];
}; };
export function useRoutingEvents() { export function useRoutingEvents() {
@@ -46,6 +55,19 @@ export function useRoutingEvents() {
routeSegments.value = segmentSummary; routeSegments.value = segmentSummary;
console.log('Waypoint segment summary:', segmentSummary); console.log('Waypoint segment summary:', segmentSummary);
} }
if (route.instructions?.length) {
const directionsSummary = route.instructions.map((direction, inx) => ({
waypoint: inx,
text: direction.text,
distance: direction.distance,
time: direction.time,
coordinates: route.waypoints?.[direction.index],
}));
console.log('Direction waypoint segment summary:', directionsSummary);
routeDirections.value = directionsSummary;
}
}; };
return { return {

View File

@@ -18,6 +18,14 @@ interface routeSegments {
toCoordinates: LatLng | null | undefined; toCoordinates: LatLng | null | undefined;
} }
interface routeDirections {
waypoint: number;
text: string;
distance: number;
time: number;
coordinates: LatLng | null | undefined;
}
interface RouteSet { interface RouteSet {
start: [number, number] | [null, null] | [undefined, undefined] | null | undefined; start: [number, number] | [null, null] | [undefined, undefined] | null | undefined;
@@ -37,6 +45,7 @@ interface State {
}; };
routesSet: RoutesSet[] | null; routesSet: RoutesSet[] | null;
routeSegments?: routeSegments[] | null; routeSegments?: routeSegments[] | null;
routeDirections?: routeDirections[] | null;
} }
export const useLeafletStore = defineStore('leaflet', { export const useLeafletStore = defineStore('leaflet', {
@@ -46,16 +55,15 @@ export const useLeafletStore = defineStore('leaflet', {
center: [favorites.home.coords.lat, favorites.home.coords.lng], center: [favorites.home.coords.lat, favorites.home.coords.lng],
markerLatLng: null, markerLatLng: null,
qLocDrawer: false, qLocDrawer: false,
routeSet: routeSet: {
{ start: { lat: null, lng: null },
start: { lat: null, lng: null }, end: { lat: null, lng: null },
end: { lat: null, lng: null}, wayPoints: null,
wayPoints: null, },
},
routesSet: null, routesSet: null,
routeSegments: null, routeSegments: null,
routeDirections: null,
} };
}, },
actions: { actions: {
setCenter(lat: number, lng: number) { setCenter(lat: number, lng: number) {
@@ -69,7 +77,10 @@ export const useLeafletStore = defineStore('leaflet', {
}, },
toggleQLocDrawer() { toggleQLocDrawer() {
this.qLocDrawer = !this.qLocDrawer this.qLocDrawer = !this.qLocDrawer
} },
setRouteDirs(data: routeDirections[]) {
this.routeDirections = data;
},
} }
}) })