waypoint sym icons, and change layer color design

This commit is contained in:
vcoppe
2024-08-08 23:20:09 +02:00
parent f10b18afe2
commit 00d6c9b45d
5 changed files with 72 additions and 47 deletions

View File

@@ -1,45 +1,56 @@
import { Landmark, type Icon, Shell, Bike, Building, Tent, Car, Wrench, ShoppingBasket, Droplet, DoorOpen, Trees, Fuel, Home, Info, TreeDeciduous, CircleParking, Cross, Utensils, Construction, BrickWall, ShowerHead, Mountain, Phone, Eye, TrainFront, Bed } from "lucide-svelte";
import { Landmark as LandmarkSvg, Shell as ShellSvg, Bike as BikeSvg, Building as BuildingSvg, Tent as TentSvg, Car as CarSvg, Wrench as WrenchSvg, ShoppingBasket as ShoppingBasketSvg, Droplet as DropletSvg, DoorOpen as DoorOpenSvg, Trees as TreesSvg, Fuel as FuelSvg, Home as HomeSvg, Info as InfoSvg, TreeDeciduous as TreeDeciduousSvg, CircleParking as CircleParkingSvg, Cross as CrossSvg, Utensils as UtensilsSvg, Construction as ConstructionSvg, BrickWall as BrickWallSvg, ShowerHead as ShowerHeadSvg, Mountain as MountainSvg, Phone as PhoneSvg, Eye as EyeSvg, TrainFront as TrainFrontSvg, Bed as BedSvg } from "lucide-static";
import type { ComponentType } from "svelte";
export type Symbol = {
value: string;
icon?: ComponentType<Icon>;
iconSvg?: string;
};
export const symbols: { [key: string]: Symbol } = {
bank: { value: 'Bank', icon: Landmark },
beach: { value: 'Beach', icon: Shell },
bike_trail: { value: 'Bike Trail', icon: Bike },
bank: { value: 'Bank', icon: Landmark, iconSvg: LandmarkSvg },
beach: { value: 'Beach', icon: Shell, iconSvg: ShellSvg },
bike_trail: { value: 'Bike Trail', icon: Bike, iconSvg: BikeSvg },
bridge: { value: 'Bridge' },
building: { value: 'Building', icon: Building },
campground: { value: 'Campground', icon: Tent },
car: { value: 'Car', icon: Car },
car_repair: { value: 'Car Repair', icon: Wrench },
convenience_store: { value: 'Convenience Store', icon: ShoppingBasket },
building: { value: 'Building', icon: Building, iconSvg: BuildingSvg },
campground: { value: 'Campground', icon: Tent, iconSvg: TentSvg },
car: { value: 'Car', icon: Car, iconSvg: CarSvg },
car_repair: { value: 'Car Repair', icon: Wrench, iconSvg: WrenchSvg },
convenience_store: { value: 'Convenience Store', icon: ShoppingBasket, iconSvg: ShoppingBasketSvg },
crossing: { value: 'Crossing' },
department_store: { value: 'Department Store', icon: ShoppingBasket },
drinking_water: { value: 'Drinking Water', icon: Droplet },
exit: { value: 'Exit', icon: DoorOpen },
lodge: { value: 'Lodge', icon: Home },
forest: { value: 'Forest', icon: Trees },
gas_station: { value: 'Gas Station', icon: Fuel },
ground_transportation: { value: 'Ground Transportation', icon: TrainFront },
hotel: { value: 'Hotel', icon: Bed },
house: { value: 'House', icon: Home },
information: { value: 'Information', icon: Info },
park: { value: 'Park', icon: TreeDeciduous },
parking_area: { value: 'Parking Area', icon: CircleParking },
pharmacy: { value: 'Pharmacy', icon: Cross },
picnic_area: { value: 'Picnic Area', icon: Utensils },
restaurant: { value: 'Restaurant', icon: Utensils },
restricted_area: { value: 'Restricted Area', icon: Construction },
department_store: { value: 'Department Store', icon: ShoppingBasket, iconSvg: ShoppingBasketSvg },
drinking_water: { value: 'Drinking Water', icon: Droplet, iconSvg: DropletSvg },
exit: { value: 'Exit', icon: DoorOpen, iconSvg: DoorOpenSvg },
lodge: { value: 'Lodge', icon: Home, iconSvg: HomeSvg },
lodging: { value: 'Lodging', icon: Bed, iconSvg: BedSvg },
forest: { value: 'Forest', icon: Trees, iconSvg: TreesSvg },
gas_station: { value: 'Gas Station', icon: Fuel, iconSvg: FuelSvg },
ground_transportation: { value: 'Ground Transportation', icon: TrainFront, iconSvg: TrainFrontSvg },
hotel: { value: 'Hotel', icon: Bed, iconSvg: BedSvg },
house: { value: 'House', icon: Home, iconSvg: HomeSvg },
information: { value: 'Information', icon: Info, iconSvg: InfoSvg },
park: { value: 'Park', icon: TreeDeciduous, iconSvg: TreeDeciduousSvg },
parking_area: { value: 'Parking Area', icon: CircleParking, iconSvg: CircleParkingSvg },
pharmacy: { value: 'Pharmacy', icon: Cross, iconSvg: CrossSvg },
picnic_area: { value: 'Picnic Area', icon: Utensils, iconSvg: UtensilsSvg },
restaurant: { value: 'Restaurant', icon: Utensils, iconSvg: UtensilsSvg },
restricted_area: { value: 'Restricted Area', icon: Construction, iconSvg: ConstructionSvg },
restroom: { value: 'Restroom' },
road: { value: 'Road', icon: BrickWall },
road: { value: 'Road', icon: BrickWall, iconSvg: BrickWallSvg },
scenic_area: { value: 'Scenic Area', icon: Eye },
shopping_center: { value: 'Shopping Center', icon: ShoppingBasket },
shower: { value: 'Shower', icon: ShowerHead },
summit: { value: 'Summit', icon: Mountain },
telephone: { value: 'Telephone', icon: Phone },
shower: { value: 'Shower', icon: ShowerHead, iconSvg: ShowerHeadSvg },
summit: { value: 'Summit', icon: Mountain, iconSvg: MountainSvg },
telephone: { value: 'Telephone', icon: Phone, iconSvg: PhoneSvg },
tunnel: { value: 'Tunnel' },
water_source: { value: 'Water Source', icon: Droplet },
};
water_source: { value: 'Water Source', icon: Droplet, iconSvg: DropletSvg },
};
export function getSymbolKey(value: string | undefined): string | undefined {
if (value === undefined) {
return undefined;
} else {
return Object.keys(symbols).find(key => symbols[key].value === value);
}
}

View File

@@ -9,7 +9,8 @@ import type { Waypoint } from "gpx";
import { getElevation, resetCursor, setGrabbingCursor, setPointerCursor, setScissorsCursor } from "$lib/utils";
import { font } from "$lib/assets/layers";
import { selectedWaypoint } from "$lib/components/toolbar/tools/Waypoint.svelte";
import { MapPin } from "lucide-static";
import { MapPin, Square } from "lucide-static";
import { getSymbolKey, symbols } from "$lib/assets/symbols";
const colors = [
'#ff0000',
@@ -43,6 +44,25 @@ function decrementColor(color: string) {
}
}
function getMarkerForSymbol(symbol: string | undefined, layerColor: string) {
let symbolSvg = symbol ? symbols[symbol]?.iconSvg : undefined;
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
${Square
.replace('stroke="currentColor"', 'stroke="SteelBlue" stroke-width="1.5" transform="translate(9.6, 0.4) scale(0.5)"')
.replace('fill="none"', `fill="${layerColor}"`)}
${MapPin
.replace('width="24"', '')
.replace('height="24"', '')
.replace('stroke="currentColor"', '')
.replace('path', `path fill="#3fb1ce" stroke="SteelBlue" stroke-width="1"`)
.replace('circle', `circle fill="${symbolSvg ? 'none' : 'white'}" stroke="${symbolSvg ? 'none' : 'white'}" stroke-width="2"`)}
${symbolSvg?.replace('stroke="currentColor"', 'stroke="white" stroke-width="2.5" transform="translate(7.2, 5) scale(0.4)"') ?? ''}
</svg>`
}
const { directionMarkers, verticalFileView, currentBasemap, defaultOpacity, defaultWeight } = settings;
export class GPXLayer {
@@ -184,19 +204,15 @@ export class GPXLayer {
if (get(selection).hasAnyChildren(new ListFileItem(this.fileId))) {
file.wpt.forEach((waypoint) => { // Update markers
let symbolKey = getSymbolKey(waypoint.sym);
if (markerIndex < this.markers.length) {
this.markers[markerIndex].getElement().querySelector('circle')?.setAttribute('fill', this.layerColor);
this.markers[markerIndex].getElement().innerHTML = getMarkerForSymbol(symbolKey, this.layerColor);
this.markers[markerIndex].setLngLat(waypoint.getCoordinates());
Object.defineProperty(this.markers[markerIndex], '_waypoint', { value: waypoint, writable: true });
} else {
let element = document.createElement('div');
element.classList.add('w-8', 'h-8', 'drop-shadow-xl');
element.innerHTML = MapPin
.replace('width="24"', '')
.replace('height="24"', '')
.replace('stroke="currentColor"', '')
.replace('path', `path fill="#3fb1ce" stroke="SteelBlue" stroke-width="1"`)
.replace('circle', `circle fill="${this.layerColor}" stroke="white" stroke-width="2.5"`);
element.innerHTML = getMarkerForSymbol(symbolKey, this.layerColor);
let marker = new mapboxgl.Marker({
draggable: this.draggable,
element,

View File

@@ -7,7 +7,7 @@
import { Dot, Trash2 } from 'lucide-svelte';
import { onMount } from 'svelte';
import { Tool, currentTool } from '$lib/stores';
import { symbols } from '$lib/assets/symbols';
import { getSymbolKey, symbols } from '$lib/assets/symbols';
import { _ } from 'svelte-i18n';
let popupElement: HTMLDivElement;
@@ -17,10 +17,7 @@
popupElement.classList.remove('hidden');
});
$: symbolKey =
$currentPopupWaypoint && $currentPopupWaypoint[0].sym
? Object.keys(symbols).find((key) => symbols[key].value === $currentPopupWaypoint[0].sym)
: undefined;
$: symbolKey = $currentPopupWaypoint ? getSymbolKey($currentPopupWaypoint[0].sym) : undefined;
</script>
<div bind:this={popupElement} class="hidden">
@@ -30,8 +27,8 @@
<Card.Title class="text-md">{$currentPopupWaypoint[0].name}</Card.Title>
</Card.Header>
<Card.Content class="flex flex-col p-0 text-sm">
<div class="flex flex-row items-center text-muted-foreground text-xs">
{#if symbolKey && symbols.hasOwnProperty(symbolKey)}
<div class="flex flex-row items-center text-muted-foreground text-xs whitespace-nowrap">
{#if symbolKey}
<span>
{#if symbols[symbolKey].icon}
<svelte:component

View File

@@ -21,7 +21,7 @@
import { map } from '$lib/stores';
import { resetCursor, setCrosshairCursor } from '$lib/utils';
import { CirclePlus, CircleX, Save } from 'lucide-svelte';
import { symbols } from '$lib/assets/symbols';
import { getSymbolKey, symbols } from '$lib/assets/symbols';
let name: string;
let description: string;
@@ -68,7 +68,7 @@
description += '\n\n' + $selectedWaypoint[0].cmt;
}
let symbol = $selectedWaypoint[0].sym ?? '';
let symbolKey = Object.keys(symbols).find((key) => symbols[key].value === symbol);
let symbolKey = getSymbolKey(symbol);
if (symbolKey) {
selectedSymbol = {
value: symbol,

View File

@@ -402,6 +402,7 @@
"drinking_water": "Water",
"exit": "Exit",
"lodge": "Hut",
"lodging": "Accommodation",
"forest": "Forest",
"gas_station": "Fuel Station",
"ground_transportation": "Ground Transportation",