Files
gpx.studio/website/src/lib/components/GPX.svelte

184 lines
3.7 KiB
Svelte
Raw Normal View History

2024-04-17 16:46:51 +02:00
<script context="module" lang="ts">
let id = 0;
function getLayerId() {
return `gpx-${id++}`;
}
let defaultWeight = 6;
let defaultOpacity = 1;
const colors = [
'#ff0000',
'#0000ff',
'#46e646',
'#00ccff',
'#ff9900',
'#ff00ff',
'#ffff32',
'#288228',
'#9933ff',
'#50f0be',
'#8c645a'
];
const colorCount: { [key: string]: number } = {};
for (let color of colors) {
colorCount[color] = 0;
}
// Get the color with the least amount of uses
function getColor() {
let color = colors.reduce((a, b) => (colorCount[a] <= colorCount[b] ? a : b));
colorCount[color]++;
return color;
}
2024-04-18 15:30:19 +02:00
function decrementColor(color: string) {
colorCount[color]--;
}
2024-04-17 16:46:51 +02:00
</script>
2024-04-16 22:57:28 +02:00
<script lang="ts">
2024-04-22 10:45:02 +02:00
import { onDestroy, onMount } from 'svelte';
2024-04-20 18:47:16 +02:00
import { GPXFile } from 'gpx';
2024-04-22 10:45:02 +02:00
import { map, selectedFiles, selectFiles, files } from '$lib/stores';
2024-04-20 18:47:16 +02:00
import { get } from 'svelte/store';
2024-04-17 11:44:37 +02:00
2024-04-16 22:57:28 +02:00
export let file: GPXFile;
2024-04-17 16:46:51 +02:00
let layerId = getLayerId();
let layerColor = getColor();
2024-04-18 15:30:19 +02:00
function selectOnClick(e: any) {
if (e.originalEvent.shiftKey) {
2024-04-20 18:47:16 +02:00
get(selectFiles).addSelect(file);
2024-04-18 15:30:19 +02:00
} else {
2024-04-20 18:47:16 +02:00
get(selectFiles).select(file);
2024-04-18 15:30:19 +02:00
}
}
function toPointerCursor() {
if ($map) {
$map.getCanvas().style.cursor = 'pointer';
}
}
function toDefaultCursor() {
if ($map) {
$map.getCanvas().style.cursor = '';
}
}
2024-04-17 12:21:56 +02:00
function addGPXLayer() {
2024-04-17 16:46:51 +02:00
if ($map) {
if (!$map.getSource(layerId)) {
let data = file.toGeoJSON();
for (let feature of data.features) {
if (!feature.properties.color) {
feature.properties.color = layerColor;
}
if (!feature.properties.weight) {
feature.properties.weight = defaultWeight;
}
if (!feature.properties.opacity) {
feature.properties.opacity = defaultOpacity;
}
}
$map.addSource(layerId, {
type: 'geojson',
data
});
2024-04-17 12:21:56 +02:00
}
2024-04-17 16:46:51 +02:00
if (!$map.getLayer(layerId)) {
$map.addLayer({
id: layerId,
type: 'line',
source: layerId,
layout: {
'line-join': 'round',
'line-cap': 'round'
},
paint: {
'line-color': ['get', 'color'],
'line-width': ['get', 'weight'],
'line-opacity': ['get', 'opacity']
}
});
2024-04-18 15:30:19 +02:00
$map.on('click', layerId, selectOnClick);
$map.on('mouseenter', layerId, toPointerCursor);
$map.on('mouseleave', layerId, toDefaultCursor);
2024-04-17 16:46:51 +02:00
}
}
2024-04-17 12:21:56 +02:00
}
$: if ($map) {
$map.on('style.load', () => {
addGPXLayer();
2024-04-16 22:57:28 +02:00
});
}
2024-04-18 15:30:19 +02:00
$: if ($selectedFiles.has(file)) {
if ($map) {
$map.moveLayer(layerId);
}
}
2024-04-22 10:45:02 +02:00
onMount(() => {
addGPXLayer();
if ($map) {
if ($files.length == 1) {
$map.fitBounds([file.statistics.bounds.southWest, file.statistics.bounds.northEast], {
padding: 60,
linear: true,
easing: () => 1
});
} else {
let mapBounds = $map.getBounds();
if (
mapBounds.contains(file.statistics.bounds.southWest) &&
mapBounds.contains(file.statistics.bounds.northEast) &&
mapBounds.contains([
file.statistics.bounds.southWest.lon,
file.statistics.bounds.northEast.lat
]) &&
mapBounds.contains([
file.statistics.bounds.northEast.lon,
file.statistics.bounds.southWest.lat
])
) {
return;
}
$map.fitBounds(
$map
.getBounds()
.extend([
file.statistics.bounds.southWest.lon,
file.statistics.bounds.southWest.lat,
file.statistics.bounds.northEast.lon,
file.statistics.bounds.northEast.lat
]),
{
padding: 60
}
);
}
}
});
2024-04-18 15:30:19 +02:00
onDestroy(() => {
if ($map) {
$map.off('click', layerId, selectOnClick);
$map.off('mouseenter', layerId, toPointerCursor);
$map.off('mouseleave', layerId, toDefaultCursor);
$map.removeLayer(layerId);
$map.removeSource(layerId);
}
decrementColor(layerColor);
});
2024-04-16 22:57:28 +02:00
</script>