improve layer stacking

This commit is contained in:
vcoppe
2026-01-30 21:30:37 +01:00
parent 2a4dfe010e
commit 9c6e03f4a8
9 changed files with 155 additions and 124 deletions

View File

@@ -48,7 +48,7 @@
language = 'en';
}
map.init(PUBLIC_MAPBOX_TOKEN, language, hash, geocoder, geolocate);
map.init(language, hash, geocoder, geolocate);
});
onDestroy(() => {

View File

@@ -3,7 +3,7 @@ import { gpxStatistics } from '$lib/logic/statistics';
import { getConvertedDistanceToKilometers } from '$lib/units';
import type { GeoJSONSource } from 'mapbox-gl';
import { get } from 'svelte/store';
import { map } from '$lib/components/map/map';
import { ANCHOR_LAYER_KEY, map } from '$lib/components/map/map';
import { allHidden } from '$lib/logic/hidden';
const { distanceMarkers, distanceUnits } = settings;
@@ -44,7 +44,8 @@ export class DistanceMarkers {
});
}
if (!map_.getLayer('distance-markers')) {
map_.addLayer({
map_.addLayer(
{
id: 'distance-markers',
type: 'symbol',
source: 'distance-markers',
@@ -79,9 +80,9 @@ export class DistanceMarkers {
'text-halo-width': 2,
'text-halo-color': 'white',
},
});
} else {
map_.moveLayer('distance-markers');
},
ANCHOR_LAYER_KEY.distanceMarkers
);
}
} else {
if (map_.getLayer('distance-markers')) {

View File

@@ -1,6 +1,6 @@
import { get, type Readable } from 'svelte/store';
import mapboxgl, { type FilterSpecification } from 'mapbox-gl';
import { map } from '$lib/components/map/map';
import { ANCHOR_LAYER_KEY, map } from '$lib/components/map/map';
import { waypointPopup, trackpointPopup } from './gpx-layer-popup';
import {
ListTrackSegmentItem,
@@ -196,7 +196,8 @@ export class GPXLayer {
}
if (!_map.getLayer(this.fileId)) {
_map.addLayer({
_map.addLayer(
{
id: this.fileId,
type: 'line',
source: this.fileId,
@@ -209,7 +210,9 @@ export class GPXLayer {
'line-width': ['get', 'width'],
'line-opacity': ['get', 'opacity'],
},
});
},
ANCHOR_LAYER_KEY.tracks
);
_map.on('click', this.fileId, this.layerOnClickBinded);
_map.on('contextmenu', this.fileId, this.layerOnContextMenuBinded);
@@ -232,7 +235,8 @@ export class GPXLayer {
}
if (!_map.getLayer(this.fileId + '-waypoints')) {
_map.addLayer({
_map.addLayer(
{
id: this.fileId + '-waypoints',
type: 'symbol',
source: this.fileId + '-waypoints',
@@ -243,7 +247,9 @@ export class GPXLayer {
'icon-padding': 0,
'icon-allow-overlap': true,
},
});
},
ANCHOR_LAYER_KEY.waypoints
);
_map.on(
'mouseenter',
@@ -292,7 +298,7 @@ export class GPXLayer {
'text-halo-color': 'white',
},
},
_map.getLayer('distance-markers') ? 'distance-markers' : undefined
ANCHOR_LAYER_KEY.directionMarkers
);
}
} else {
@@ -393,13 +399,13 @@ export class GPXLayer {
return;
}
if (_map.getLayer(this.fileId)) {
_map.moveLayer(this.fileId);
_map.moveLayer(this.fileId, ANCHOR_LAYER_KEY.tracks);
}
if (_map.getLayer(this.fileId + '-waypoints')) {
_map.moveLayer(this.fileId + '-waypoints');
_map.moveLayer(this.fileId + '-waypoints', ANCHOR_LAYER_KEY.waypoints);
}
if (_map.getLayer(this.fileId + '-direction')) {
_map.moveLayer(this.fileId + '-direction');
_map.moveLayer(this.fileId + '-direction', ANCHOR_LAYER_KEY.directionMarkers);
}
}

View File

@@ -6,6 +6,7 @@ import { overpassQueryData } from '$lib/assets/layers';
import { MapPopup } from '$lib/components/map/map-popup';
import { settings } from '$lib/logic/settings';
import { db } from '$lib/db';
import { ANCHOR_LAYER_KEY } from '$lib/components/map/map';
const { currentOverpassQueries } = settings;
@@ -85,7 +86,8 @@ export class OverpassLayer {
}
if (!this.map.getLayer('overpass')) {
this.map.addLayer({
this.map.addLayer(
{
id: 'overpass',
type: 'symbol',
source: 'overpass',
@@ -95,7 +97,9 @@ export class OverpassLayer {
'icon-padding': 0,
'icon-allow-overlap': ['step', ['zoom'], false, 14, true],
},
});
},
ANCHOR_LAYER_KEY.overpass
);
this.map.on('mouseenter', 'overpass', this.onHoverBinded);
this.map.on('click', 'overpass', this.onHoverBinded);

View File

@@ -20,6 +20,28 @@ let fitBoundsOptions: mapboxgl.MapOptions['fitBoundsOptions'] = {
easing: () => 1,
};
const emptySource: mapboxgl.GeoJSONSourceSpecification = {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [],
},
};
export const ANCHOR_LAYER_KEY = {
mapillary: 'mapillary-end',
tracks: 'tracks-end',
directionMarkers: 'direction-markers-end',
distanceMarkers: 'distance-markers-end',
interactions: 'interactions-end',
overpass: 'overpass-end',
waypoints: 'waypoints-end',
};
const anchorLayers: mapboxgl.LayerSpecification[] = Object.values(ANCHOR_LAYER_KEY).map((id) => ({
id: id,
type: 'symbol',
source: 'empty-source',
}));
export class MapboxGLMap {
private _map: Writable<mapboxgl.Map | null> = writable(null);
private _onLoadCallbacks: ((map: mapboxgl.Map) => void)[] = [];
@@ -29,19 +51,15 @@ export class MapboxGLMap {
return this._map.subscribe(run, invalidate);
}
init(
accessToken: string,
language: string,
hash: boolean,
geocoder: boolean,
geolocate: boolean
) {
init(language: string, hash: boolean, geocoder: boolean, geolocate: boolean) {
const map = new mapboxgl.Map({
container: 'map',
style: {
version: 8,
sources: {},
layers: [],
sources: {
'empty-source': emptySource,
},
layers: anchorLayers,
imports: [
{
id: 'basemap',
@@ -50,11 +68,6 @@ export class MapboxGLMap {
{
id: 'overlays',
url: '',
data: {
version: 8,
sources: {},
layers: [],
},
},
],
},

View File

@@ -2,6 +2,7 @@ import mapboxgl, { type LayerSpecification, type VectorSourceSpecification } fro
import { Viewer, type ViewerBearingEvent } from 'mapillary-js/dist/mapillary.module';
import 'mapillary-js/dist/mapillary.css';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
import { ANCHOR_LAYER_KEY } from '$lib/components/map/map';
const mapillarySource: VectorSourceSpecification = {
type: 'vector',
@@ -99,10 +100,10 @@ export class MapillaryLayer {
this.map.addSource('mapillary', mapillarySource);
}
if (!this.map.getLayer('mapillary-sequence')) {
this.map.addLayer(mapillarySequenceLayer);
this.map.addLayer(mapillarySequenceLayer, ANCHOR_LAYER_KEY.mapillary);
}
if (!this.map.getLayer('mapillary-image')) {
this.map.addLayer(mapillaryImageLayer);
this.map.addLayer(mapillaryImageLayer, ANCHOR_LAYER_KEY.mapillary);
}
this.map.on('style.load', this.addBinded);
this.map.on('mouseenter', 'mapillary-image', this.onMouseEnterBinded);

View File

@@ -15,7 +15,7 @@
import { onDestroy, onMount } from 'svelte';
import { getURLForLanguage } from '$lib/utils';
import { Trash2 } from '@lucide/svelte';
import { map } from '$lib/components/map/map';
import { ANCHOR_LAYER_KEY, map } from '$lib/components/map/map';
import type { GeoJSONSource } from 'mapbox-gl';
import { selection } from '$lib/logic/selection';
import { fileActions } from '$lib/logic/file-actions';
@@ -63,7 +63,8 @@
});
}
if (!$map.getLayer('rectangle')) {
$map.addLayer({
$map.addLayer(
{
id: 'rectangle',
type: 'fill',
source: 'rectangle',
@@ -71,7 +72,9 @@
'fill-color': 'SteelBlue',
'fill-opacity': 0.5,
},
});
},
ANCHOR_LAYER_KEY.interactions
);
}
}
}

View File

@@ -1,5 +1,5 @@
import { ListItem, ListTrackSegmentItem } from '$lib/components/file-list/file-list';
import { map } from '$lib/components/map/map';
import { ANCHOR_LAYER_KEY, map } from '$lib/components/map/map';
import { fileActions } from '$lib/logic/file-actions';
import { GPXFileStateCollectionObserver, type GPXFileState } from '$lib/logic/file-state';
import { selection } from '$lib/logic/selection';
@@ -144,7 +144,8 @@ export class ReducedGPXLayerCollection {
});
}
if (!map_.getLayer('simplified')) {
map_.addLayer({
map_.addLayer(
{
id: 'simplified',
type: 'line',
source: 'simplified',
@@ -152,9 +153,9 @@ export class ReducedGPXLayerCollection {
'line-color': 'white',
'line-width': 3,
},
});
} else {
map_.moveLayer('simplified');
},
ANCHOR_LAYER_KEY.interactions
);
}
}

View File

@@ -8,6 +8,7 @@ import { get } from 'svelte/store';
import { fileStateCollection } from '$lib/logic/file-state';
import { fileActions } from '$lib/logic/file-actions';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
import { ANCHOR_LAYER_KEY } from '$lib/components/map/map';
export class SplitControls {
map: mapboxgl.Map;
@@ -108,7 +109,8 @@ export class SplitControls {
}
if (!this.map.getLayer('split-controls')) {
this.map.addLayer({
this.map.addLayer(
{
id: 'split-controls',
type: 'symbol',
source: 'split-controls',
@@ -118,14 +120,14 @@ export class SplitControls {
'icon-padding': 0,
},
filter: ['<=', ['get', 'minZoom'], ['zoom']],
});
},
ANCHOR_LAYER_KEY.interactions
);
this.map.on('mouseenter', 'split-controls', this.layerOnMouseEnterBinded);
this.map.on('mouseleave', 'split-controls', this.layerOnMouseLeaveBinded);
this.map.on('click', 'split-controls', this.layerOnClickBinded);
}
this.map.moveLayer('split-controls');
} catch (e) {
// No reliable way to check if the map is ready to add sources and layers
}