explore: grey map default; zoom-scaled heatmap lines; fix all/none type buttons
This commit is contained in:
@@ -30,13 +30,14 @@
|
|||||||
|
|
||||||
// Tile layers — same as planner
|
// Tile layers — same as planner
|
||||||
const TILES: Record<string, { tiles: string[]; attribution: string; label: string }> = {
|
const TILES: Record<string, { tiles: string[]; attribution: string; label: string }> = {
|
||||||
cyclosm: { label: 'Cycle', attribution: '© CyclOSM | © OpenStreetMap contributors', tiles: ['https://a.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png','https://b.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png','https://c.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png'] },
|
grey: { label: 'Grey', attribution: '© CARTO | © OpenStreetMap contributors', tiles: ['https://a.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png','https://b.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png','https://c.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png'] },
|
||||||
|
cyclosm: { label: 'Cycle', attribution: '© CyclOSM | © OpenStreetMap contributors', tiles: ['https://a.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png','https://b.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png','https://c.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png'] },
|
||||||
osm: { label: 'OSM', attribution: '© OpenStreetMap contributors', tiles: ['https://tile.openstreetmap.org/{z}/{x}/{y}.png'] },
|
osm: { label: 'OSM', attribution: '© OpenStreetMap contributors', tiles: ['https://tile.openstreetmap.org/{z}/{x}/{y}.png'] },
|
||||||
topo: { label: 'Topo', attribution: '© OpenTopoMap | © OpenStreetMap contributors', tiles: ['https://a.tile.opentopomap.org/{z}/{x}/{y}.png','https://b.tile.opentopomap.org/{z}/{x}/{y}.png','https://c.tile.opentopomap.org/{z}/{x}/{y}.png'] },
|
topo: { label: 'Topo', attribution: '© OpenTopoMap | © OpenStreetMap contributors', tiles: ['https://a.tile.opentopomap.org/{z}/{x}/{y}.png','https://b.tile.opentopomap.org/{z}/{x}/{y}.png','https://c.tile.opentopomap.org/{z}/{x}/{y}.png'] },
|
||||||
satellite: { label: 'Sat', attribution: '© Esri World Imagery', tiles: ['https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}'] },
|
satellite: { label: 'Sat', attribution: '© Esri World Imagery', tiles: ['https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}'] },
|
||||||
};
|
};
|
||||||
const TILE_ORDER = ['cyclosm', 'osm', 'topo', 'satellite'];
|
const TILE_ORDER = ['grey', 'cyclosm', 'osm', 'topo', 'satellite'];
|
||||||
let tileKey = 'cyclosm';
|
let tileKey = 'grey';
|
||||||
|
|
||||||
const TYPE_COLORS: Record<string, string> = {
|
const TYPE_COLORS: Record<string, string> = {
|
||||||
cycling: '#e879a0',
|
cycling: '#e879a0',
|
||||||
@@ -56,7 +57,8 @@
|
|||||||
$: allTypes = [...new Set(tracks.map(t => t.type))].sort();
|
$: allTypes = [...new Set(tracks.map(t => t.type))].sort();
|
||||||
$: availableYears = [...new Set(tracks.map(t => t.date.slice(0,4)).filter(Boolean))].sort().reverse();
|
$: availableYears = [...new Set(tracks.map(t => t.date.slice(0,4)).filter(Boolean))].sort().reverse();
|
||||||
|
|
||||||
$: if (allTypes.length > 0 && selectedTypes.size === 0) selectedTypes = new Set(allTypes);
|
let typesInitialized = false;
|
||||||
|
$: if (allTypes.length > 0 && !typesInitialized) { selectedTypes = new Set(allTypes); typesInitialized = true; }
|
||||||
|
|
||||||
$: filteredTracks = tracks.filter(t => {
|
$: filteredTracks = tracks.filter(t => {
|
||||||
if (!selectedTypes.has(t.type)) return false;
|
if (!selectedTypes.has(t.type)) return false;
|
||||||
@@ -170,7 +172,7 @@
|
|||||||
map = new maplibregl.Map({
|
map = new maplibregl.Map({
|
||||||
container: mapEl,
|
container: mapEl,
|
||||||
style: { version: 8,
|
style: { version: 8,
|
||||||
sources: { base: { type: 'raster', tiles: TILES.cyclosm.tiles, tileSize: 256, attribution: TILES.cyclosm.attribution } },
|
sources: { base: { type: 'raster', tiles: TILES.grey.tiles, tileSize: 256, attribution: TILES.grey.attribution } },
|
||||||
layers: [{ id: 'base', type: 'raster', source: 'base' }],
|
layers: [{ id: 'base', type: 'raster', source: 'base' }],
|
||||||
},
|
},
|
||||||
center: [12, 42], zoom: 5,
|
center: [12, 42], zoom: 5,
|
||||||
@@ -190,16 +192,19 @@
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const heatWidth = ['interpolate', ['linear'], ['zoom'], 5, 2, 10, 4, 14, 7, 18, 10];
|
||||||
|
const heatOpacity = ['interpolate', ['linear'], ['zoom'], 5, 0.10, 10, 0.12, 14, 0.15, 18, 0.18];
|
||||||
|
|
||||||
// Global heatmap — all lines in warm amber, very low opacity so overlapping routes stack up
|
// Global heatmap — all lines in warm amber, very low opacity so overlapping routes stack up
|
||||||
map.addLayer({ id: 'explore-heat-global', type: 'line', source: 'explore-lines', layout: { visibility: 'none' },
|
map.addLayer({ id: 'explore-heat-global', type: 'line', source: 'explore-lines', layout: { visibility: 'none' },
|
||||||
paint: { 'line-width': 4, 'line-opacity': 0.10, 'line-blur': 1, 'line-color': '#f97316' },
|
paint: { 'line-width': heatWidth, 'line-opacity': heatOpacity, 'line-blur': 1, 'line-color': '#f97316' },
|
||||||
});
|
});
|
||||||
|
|
||||||
// Per-type heatmap layers — same accumulation trick, type-specific colour
|
// Per-type heatmap layers — same accumulation trick, type-specific colour
|
||||||
for (const [type, hex] of Object.entries(TYPE_COLORS)) {
|
for (const [type, hex] of Object.entries(TYPE_COLORS)) {
|
||||||
map.addLayer({ id: `explore-heat-${type}`, type: 'line', source: 'explore-lines',
|
map.addLayer({ id: `explore-heat-${type}`, type: 'line', source: 'explore-lines',
|
||||||
filter: ['==', ['get', 'type'], type], layout: { visibility: 'none' },
|
filter: ['==', ['get', 'type'], type], layout: { visibility: 'none' },
|
||||||
paint: { 'line-width': 4, 'line-opacity': 0.12, 'line-blur': 1, 'line-color': hex },
|
paint: { 'line-width': heatWidth, 'line-opacity': heatOpacity, 'line-blur': 1, 'line-color': hex },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user