mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2026-01-17 07:08:42 +00:00
new setting for selecting terrain source
This commit is contained in:
@@ -22,7 +22,7 @@ import {
|
|||||||
Binoculars,
|
Binoculars,
|
||||||
Toilet,
|
Toilet,
|
||||||
} from 'lucide-static';
|
} from 'lucide-static';
|
||||||
import { type StyleSpecification } from 'mapbox-gl';
|
import { type RasterDEMSourceSpecification, type StyleSpecification } from 'mapbox-gl';
|
||||||
import ignFrTopo from './custom/ign-fr-topo.json';
|
import ignFrTopo from './custom/ign-fr-topo.json';
|
||||||
import ignFrPlan from './custom/ign-fr-plan.json';
|
import ignFrPlan from './custom/ign-fr-plan.json';
|
||||||
import ignFrSatellite from './custom/ign-fr-satellite.json';
|
import ignFrSatellite from './custom/ign-fr-satellite.json';
|
||||||
@@ -1453,3 +1453,18 @@ export const overpassQueryData: Record<string, OverpassQueryData> = {
|
|||||||
symbol: 'Anchor',
|
symbol: 'Anchor',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const terrainSources: { [key: string]: RasterDEMSourceSpecification } = {
|
||||||
|
'mapbox-dem': {
|
||||||
|
type: 'raster-dem',
|
||||||
|
url: 'mapbox://mapbox.mapbox-terrain-dem-v1',
|
||||||
|
tileSize: 512,
|
||||||
|
maxzoom: 14,
|
||||||
|
},
|
||||||
|
mapterhorn: {
|
||||||
|
type: 'raster-dem',
|
||||||
|
url: 'https://tiles.mapterhorn.com/tilejson.json',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const defaultTerrainSource = 'mapbox-dem';
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
overlays,
|
overlays,
|
||||||
overlayTree,
|
overlayTree,
|
||||||
overpassTree,
|
overpassTree,
|
||||||
|
terrainSources,
|
||||||
} from '$lib/assets/layers';
|
} from '$lib/assets/layers';
|
||||||
import { getLayers, isSelected, toggle } from '$lib/components/map/layer-control/utils';
|
import { getLayers, isSelected, toggle } from '$lib/components/map/layer-control/utils';
|
||||||
import { i18n } from '$lib/i18n.svelte';
|
import { i18n } from '$lib/i18n.svelte';
|
||||||
@@ -31,6 +32,7 @@
|
|||||||
currentOverpassQueries,
|
currentOverpassQueries,
|
||||||
customLayers,
|
customLayers,
|
||||||
opacities,
|
opacities,
|
||||||
|
terrainSource,
|
||||||
} = settings;
|
} = settings;
|
||||||
|
|
||||||
const { isLayerFromExtension, getLayerName } = extensionAPI;
|
const { isLayerFromExtension, getLayerName } = extensionAPI;
|
||||||
@@ -233,6 +235,23 @@
|
|||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
</Accordion.Content>
|
</Accordion.Content>
|
||||||
</Accordion.Item>
|
</Accordion.Item>
|
||||||
|
<Accordion.Item value="terrain-source">
|
||||||
|
<Accordion.Trigger>{i18n._('layers.terrain')}</Accordion.Trigger>
|
||||||
|
<Accordion.Content class="flex flex-col gap-3 overflow-visible">
|
||||||
|
<Select.Root bind:value={$terrainSource} type="single">
|
||||||
|
<Select.Trigger class="mr-1 w-full" size="sm">
|
||||||
|
{i18n._(`layers.label.${$terrainSource}`)}
|
||||||
|
</Select.Trigger>
|
||||||
|
<Select.Content class="h-fit max-h-[40dvh] overflow-y-auto">
|
||||||
|
{#each Object.keys(terrainSources) as id}
|
||||||
|
<Select.Item value={id}>
|
||||||
|
{i18n._(`layers.label.${id}`)}
|
||||||
|
</Select.Item>
|
||||||
|
{/each}
|
||||||
|
</Select.Content>
|
||||||
|
</Select.Root>
|
||||||
|
</Accordion.Content>
|
||||||
|
</Accordion.Item>
|
||||||
</Accordion.Root>
|
</Accordion.Root>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
</Sheet.Header>
|
</Sheet.Header>
|
||||||
|
|||||||
@@ -3,8 +3,16 @@ import MapboxGeocoder from '@mapbox/mapbox-gl-geocoder';
|
|||||||
import { get, writable, type Writable } from 'svelte/store';
|
import { get, writable, type Writable } from 'svelte/store';
|
||||||
import { settings } from '$lib/logic/settings';
|
import { settings } from '$lib/logic/settings';
|
||||||
import { tick } from 'svelte';
|
import { tick } from 'svelte';
|
||||||
|
import { terrainSources } from '$lib/assets/layers';
|
||||||
|
|
||||||
const { treeFileView, elevationProfile, bottomPanelSize, rightPanelSize, distanceUnits } = settings;
|
const {
|
||||||
|
treeFileView,
|
||||||
|
elevationProfile,
|
||||||
|
bottomPanelSize,
|
||||||
|
rightPanelSize,
|
||||||
|
distanceUnits,
|
||||||
|
terrainSource,
|
||||||
|
} = settings;
|
||||||
|
|
||||||
let fitBoundsOptions: mapboxgl.MapOptions['fitBoundsOptions'] = {
|
let fitBoundsOptions: mapboxgl.MapOptions['fitBoundsOptions'] = {
|
||||||
maxZoom: 15,
|
maxZoom: 15,
|
||||||
@@ -123,34 +131,14 @@ export class MapboxGLMap {
|
|||||||
});
|
});
|
||||||
map.addControl(scaleControl);
|
map.addControl(scaleControl);
|
||||||
map.on('style.load', () => {
|
map.on('style.load', () => {
|
||||||
map.addSource('mapbox-dem', {
|
|
||||||
type: 'raster-dem',
|
|
||||||
url: 'mapbox://mapbox.mapbox-terrain-dem-v1',
|
|
||||||
tileSize: 512,
|
|
||||||
maxzoom: 14,
|
|
||||||
});
|
|
||||||
if (map.getPitch() > 0) {
|
|
||||||
map.setTerrain({
|
|
||||||
source: 'mapbox-dem',
|
|
||||||
exaggeration: 1,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
map.setFog({
|
map.setFog({
|
||||||
color: 'rgb(186, 210, 235)',
|
color: 'rgb(186, 210, 235)',
|
||||||
'high-color': 'rgb(36, 92, 223)',
|
'high-color': 'rgb(36, 92, 223)',
|
||||||
'horizon-blend': 0.1,
|
'horizon-blend': 0.1,
|
||||||
'space-color': 'rgb(156, 240, 255)',
|
'space-color': 'rgb(156, 240, 255)',
|
||||||
});
|
});
|
||||||
map.on('pitch', () => {
|
map.on('pitch', this.setTerrain.bind(this));
|
||||||
if (map.getPitch() > 0) {
|
this.setTerrain();
|
||||||
map.setTerrain({
|
|
||||||
source: 'mapbox-dem',
|
|
||||||
exaggeration: 1,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
map.setTerrain(null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
map.on('style.import.load', () => {
|
map.on('style.import.load', () => {
|
||||||
const basemap = map.getStyle().imports?.find((imprt) => imprt.id === 'basemap');
|
const basemap = map.getStyle().imports?.find((imprt) => imprt.id === 'basemap');
|
||||||
@@ -162,6 +150,7 @@ export class MapboxGLMap {
|
|||||||
this._map.set(map); // only set the store after the map has loaded
|
this._map.set(map); // only set the store after the map has loaded
|
||||||
window._map = map; // entry point for extensions
|
window._map = map; // entry point for extensions
|
||||||
this.resize();
|
this.resize();
|
||||||
|
this.setTerrain();
|
||||||
scaleControl.setUnit(get(distanceUnits));
|
scaleControl.setUnit(get(distanceUnits));
|
||||||
|
|
||||||
this._onLoadCallbacks.forEach((callback) => callback(map));
|
this._onLoadCallbacks.forEach((callback) => callback(map));
|
||||||
@@ -177,6 +166,7 @@ export class MapboxGLMap {
|
|||||||
scaleControl.setUnit(units);
|
scaleControl.setUnit(units);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
this._unsubscribes.push(terrainSource.subscribe(() => this.setTerrain()));
|
||||||
}
|
}
|
||||||
|
|
||||||
onLoad(callback: (map: mapboxgl.Map) => void) {
|
onLoad(callback: (map: mapboxgl.Map) => void) {
|
||||||
@@ -217,6 +207,24 @@ export class MapboxGLMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setTerrain() {
|
||||||
|
const map = get(this._map);
|
||||||
|
if (map) {
|
||||||
|
const source = get(terrainSource);
|
||||||
|
if (!map.getSource(source)) {
|
||||||
|
map.addSource(source, terrainSources[source]);
|
||||||
|
}
|
||||||
|
if (map.getPitch() > 0) {
|
||||||
|
map.setTerrain({
|
||||||
|
source: source,
|
||||||
|
exaggeration: 1,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
map.setTerrain(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const map = new MapboxGLMap();
|
export const map = new MapboxGLMap();
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
defaultOverlayTree,
|
defaultOverlayTree,
|
||||||
defaultOverpassQueries,
|
defaultOverpassQueries,
|
||||||
defaultOverpassTree,
|
defaultOverpassTree,
|
||||||
|
defaultTerrainSource,
|
||||||
type CustomLayer,
|
type CustomLayer,
|
||||||
} from '$lib/assets/layers';
|
} from '$lib/assets/layers';
|
||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
@@ -154,6 +155,7 @@ export const settings = {
|
|||||||
customLayers: new Setting<Record<string, CustomLayer>>('customLayers', {}),
|
customLayers: new Setting<Record<string, CustomLayer>>('customLayers', {}),
|
||||||
customBasemapOrder: new Setting<string[]>('customBasemapOrder', []),
|
customBasemapOrder: new Setting<string[]>('customBasemapOrder', []),
|
||||||
customOverlayOrder: new Setting<string[]>('customOverlayOrder', []),
|
customOverlayOrder: new Setting<string[]>('customOverlayOrder', []),
|
||||||
|
terrainSource: new Setting('terrainSource', defaultTerrainSource),
|
||||||
directionMarkers: new Setting('directionMarkers', false),
|
directionMarkers: new Setting('directionMarkers', false),
|
||||||
distanceMarkers: new Setting('distanceMarkers', false),
|
distanceMarkers: new Setting('distanceMarkers', false),
|
||||||
streetViewSource: new Setting('streetViewSource', 'mapillary'),
|
streetViewSource: new Setting('streetViewSource', 'mapillary'),
|
||||||
|
|||||||
@@ -282,6 +282,7 @@
|
|||||||
"update": "Update layer"
|
"update": "Update layer"
|
||||||
},
|
},
|
||||||
"opacity": "Overlay opacity",
|
"opacity": "Overlay opacity",
|
||||||
|
"terrain": "Terrain source",
|
||||||
"label": {
|
"label": {
|
||||||
"basemaps": "Basemaps",
|
"basemaps": "Basemaps",
|
||||||
"overlays": "Overlays",
|
"overlays": "Overlays",
|
||||||
@@ -379,7 +380,9 @@
|
|||||||
"railway-station": "Railway Station",
|
"railway-station": "Railway Station",
|
||||||
"tram-stop": "Tram Stop",
|
"tram-stop": "Tram Stop",
|
||||||
"bus-stop": "Bus Stop",
|
"bus-stop": "Bus Stop",
|
||||||
"ferry": "Ferry"
|
"ferry": "Ferry",
|
||||||
|
"mapbox-dem": "Mapbox DEM",
|
||||||
|
"mapterhorn": "Mapterhorn"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
|
|||||||
Reference in New Issue
Block a user