adds gpx upload for summit logs

This commit is contained in:
Christian Beutel
2024-11-01 20:35:50 +01:00
parent 18e57aa211
commit 9c07aae339
13 changed files with 505 additions and 27 deletions

View File

@@ -176,7 +176,7 @@
<div class="trail-info-panel-header">
<section class="relative h-80">
<img
class="w-full h-80 "
class="w-full h-80"
class:rounded-t-3xl={mode !== "list"}
src={thumbnail}
alt=""
@@ -302,7 +302,10 @@
{#if activeTab == 1}
<ul>
{#each trail.expand.waypoints ?? [] as waypoint, i}
<li on:mouseenter={() => openMarkerPopup(i)} on:mouseleave={() => closeMarkerPopup(i)}>
<li
on:mouseenter={() => openMarkerPopup(i)}
on:mouseleave={() => closeMarkerPopup(i)}
>
<WaypointCard {waypoint}></WaypointCard>
</li>
{/each}
@@ -333,8 +336,8 @@
{/if}
{#if activeTab == 3}
<ul>
{#each trail.expand.summit_logs ?? [] as log}
<li><SummitLogCard {log}></SummitLogCard></li>
{#each trail.expand.summit_logs ?? [] as log, i}
<li><SummitLogCard {log} index={i}></SummitLogCard></li>
{/each}
</ul>
{/if}

View File

@@ -0,0 +1,119 @@
<script lang="ts">
import { gpx } from "$lib/vendor/toGeoJSON/toGeoJSON";
import "leaflet/dist/leaflet.css";
import type { Map } from "leaflet";
import { onMount, tick } from "svelte";
export let trailFile: File | null;
export let trailData: string | undefined;
export let label: string = "";
let map: Map;
let L: any;
let layer: any;
$: if (trailData !== undefined) {
showTrailOnMap();
} else {
removeTrailFromMap();
}
onMount(async () => {
if (!map) {
await initMap();
}
});
async function initMap() {
L = (await import("leaflet")).default;
map = L.map("trail-picker-map", {
zoomControl: false,
scrollWheelZoom: false,
dragging: false,
});
map.attributionControl.setPrefix(false);
}
function openTrailBrowser() {
if (trailData) {
trailFile = null;
trailData = undefined;
} else {
document.getElementById("trail-input")!.click();
}
}
async function handleTrailSelection(files?: FileList | null) {
if (!files) {
files = (document.getElementById("trail-input") as HTMLInputElement)
.files;
}
if (!files) {
return;
}
trailFile = files.item(0);
trailData = await trailFile?.text();
}
async function showTrailOnMap() {
if (!trailData) {
return;
}
const geoJson = gpx(
new DOMParser().parseFromString(trailData, "text/xml"),
);
if (layer) {
map.removeLayer(layer);
}
layer = L.geoJson(geoJson, {
filter: (feature: any, layer: any) => {
return feature.geometry.type !== "Point";
},
}).addTo(map);
map.fitBounds(layer.getBounds());
map.invalidateSize();
}
function removeTrailFromMap() {
if (layer) {
map?.removeLayer(layer);
}
}
</script>
<div>
{#if label.length}
<p class="text-sm font-medium pb-1">
{label}
</p>
{/if}
<div class="flex gap-x-4" role="dialog">
<input
type="file"
id="trail-input"
accept=".gpx,.GPX,.tcx,.TCX,.kml,.KML,.fit,.FIT"
multiple={false}
style="display: none;"
on:change={() => handleTrailSelection()}
/>
<button
type="button"
on:click={openTrailBrowser}
class="h-28 aspect-square rounded-xl !bg-background border border-input-border-focus hover:!bg-secondary-hover group"
id="trail-picker-map"
>
{#if !trailFile && !trailData}
<i class="fa fa-plus text-lg"></i>
{:else}
<i
class="fa fa-trash text-red-500 text-lg hidden group-hover:block relative"
style="z-index: 1000"
></i>
{/if}
</button>
</div>
</div>