Skip to content

Commit

Permalink
climbing: add layer as overlay (#238)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Pavel Zbytovský <zbytovsky@gmail.com>
  • Loading branch information
jvaclavik and zbycz authored Feb 16, 2024
1 parent 67df7d6 commit c2ac40e
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/components/LayerSwitcher/LayerSwitcherContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const getAllLayers = (userLayers: Layer[], view: View): AllLayers => {

const entries = Object.entries(osmappLayers);
const basemaps = entries.filter(([, v]) => v.type === 'basemap');
const overlays = entries.filter(([, v]) => v.type === 'overlay');
const overlays = entries.filter(([, v]) => v.type.startsWith('overlay'));

const basemapLayers = [
...basemaps.filter(filterMakina).map(toLayer),
Expand Down
12 changes: 12 additions & 0 deletions src/components/LayerSwitcher/osmappLayers.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import React from 'react';
import ExploreIcon from '@material-ui/icons/Explore';
import FilterHdrIcon from '@material-ui/icons/FilterHdr';
import MapIcon from '@material-ui/icons/Map';
Expand All @@ -7,6 +8,7 @@ import AcUnitIcon from '@material-ui/icons/AcUnit';
import { Layer } from '../utils/MapStateContext';
import { t } from '../../services/intl';
import { isBrowser } from '../helpers';
import Maki from '../utils/Maki';

interface Layers {
[key: string]: Layer;
Expand All @@ -15,6 +17,10 @@ interface Layers {
const retina =
((isBrowser() && window.devicePixelRatio) || 1) >= 2 ? '@2x' : '';

const ClimbingIcon = () => (
<Maki ico="climbing" size={16} style={{ opacity: 0.3, marginLeft: '3px' }} />
);

export const osmappLayers: Layers = {
basic: {
name: t('layers.basic'),
Expand Down Expand Up @@ -85,4 +91,10 @@ export const osmappLayers: Layers = {
'osm',
],
},
climbing: {
name: t('layers.climbing'),
type: 'overlayClimbing',
Icon: ClimbingIcon,
attribution: ['osm'],
},
};
1 change: 0 additions & 1 deletion src/components/Map/Map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ const NoscriptMessage = () => (

const Map = () => {
const [mapLoaded, setLoaded, setNotLoaded] = useBoolState(true);

useEffect(setNotLoaded, []);

return (
Expand Down
26 changes: 25 additions & 1 deletion src/components/Map/behaviour/useUpdateStyle.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Map } from 'maplibre-gl';
import type { Map, GeoJSONSource } from 'maplibre-gl';
import cloneDeep from 'lodash/cloneDeep';
import { useMapEffect } from '../../helpers';
import { basicStyle } from '../styles/basicStyle';
Expand All @@ -7,6 +7,19 @@ import { osmappLayers } from '../../LayerSwitcher/osmappLayers';
import { rasterStyle } from '../styles/rasterStyle';
import { DEFAULT_MAP } from '../../../config';
import { makinaAfricaStyle } from '../styles/makinaAfricaStyle';
import { fetchJson } from '../../../services/fetch';
import { overpassGeomToGeojson } from '../../../services/overpassSearch';
import { climbingLayers } from '../styles/layers/climbingLayers';
import { emptyGeojsonSource } from '../consts';

const fetchCrags = async () => {
const query = `[out:json][timeout:25];(relation["climbing"="crag"](48,11,51,19););out geom qt;`;
const data = encodeURIComponent(query);
const url = `https://overpass-api.de/api/interpreter?data=${data}`;
const overpass = await fetchJson(url);
const features = overpassGeomToGeojson(overpass);
return { type: 'FeatureCollection', features } as GeoJSON.FeatureCollection;
};

export const getRasterStyle = (key) => {
const url = osmappLayers[key]?.url ?? key; // if `key` not found, it contains tiles URL
Expand Down Expand Up @@ -42,6 +55,17 @@ export const useUpdateStyle = useMapEffect((map: Map, activeLayers) => {
const raster = getRasterStyle(overlayKey);
style.sources[overlayKey] = raster.sources[overlayKey];
style.layers.push(raster.layers[0]);

// TODO maxzoom 19 only for snow overlay
}

if (overlay?.type === 'overlayClimbing') {
style.sources.climbing = emptyGeojsonSource;
style.layers.push(...climbingLayers); // must be also in `layersWithOsmId` because of hover effect
fetchCrags().then((geojson) => {
const geojsonSource = map.getSource('climbing') as GeoJSONSource;
geojsonSource?.setData(geojson); // TODO can be undefined at first map render
});
}
});

Expand Down
16 changes: 9 additions & 7 deletions src/components/Map/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ export const OSMAPP_SPRITE = `${window.location.protocol}//${window.location.hos

export const GLYPHS = `https://api.maptiler.com/fonts/{fontstack}/{range}.pbf?key=${apiKey}`;

export const emptyGeojsonSource = {
type: 'geojson' as const,
data: {
type: 'FeatureCollection',
features: [],
},
};

export const OSMAPP_SOURCES = {
maptiler_planet: {
type: 'vector' as const,
Expand All @@ -29,13 +37,7 @@ export const OSMAPP_SOURCES = {
url: `https://api.maptiler.com/tiles/outdoor/tiles.json?key=${apiKey}`,
type: 'vector' as const,
},
overpass: {
type: 'geojson' as const,
data: {
type: 'FeatureCollection',
features: [],
},
},
overpass: emptyGeojsonSource,
};

export const BACKGROUND = [
Expand Down
8 changes: 5 additions & 3 deletions src/components/Map/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { OsmApiId } from '../../services/helpers';
import { basicStyle } from './styles/basicStyle';
import { climbingLayers } from './styles/layers/climbingLayers';

const isOsmLayer = (id) => {
if (id.startsWith('place-country-')) return false; // https://github.com/zbycz/osmapp/issues/35
if (id === 'place-continent') return false;
if (id === 'water-name-ocean') return false;
const prefixes = ['water-name-', 'poi-', 'place-', 'overpass-'];
const prefixes = ['water-name-', 'poi-', 'place-', 'overpass-', 'climbing-'];
return prefixes.some((prefix) => id.startsWith(prefix));
};

export const layersWithOsmId = basicStyle.layers // TODO make it custom for basic/outdoor + revert place_
.map((x) => x.id)
.filter((id) => isOsmLayer(id));
.filter((id) => isOsmLayer(id))
.concat(climbingLayers.map((x) => x.id));

export const getIsOsmObject = ({ id, layer }) => {
// these layers with id <= ~10000 are broken
Expand All @@ -24,7 +26,7 @@ export const getIsOsmObject = ({ id, layer }) => {
return false;
}

if (layer.id?.startsWith('overpass')) {
if (layer.id?.startsWith('overpass') || layer.id?.startsWith('climbing-')) {
return true;
}

Expand Down
14 changes: 14 additions & 0 deletions src/components/Map/styles/layers/climbingLayers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { LayerSpecification } from '@maplibre/maplibre-gl-style-spec';
import { overpassLayers } from './overpassLayers';

export const climbingLayers: LayerSpecification[] = [
...overpassLayers.map(
(layer) =>
({
...layer,
id: `climbing-${layer.id}`,
source: 'climbing',
} as LayerSpecification),
),
// override specific settings for climbing here
];
2 changes: 1 addition & 1 deletion src/components/utils/MapStateContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { usePersistedState } from './usePersistedState';
import { DEFAULT_MAP } from '../../config';

export interface Layer {
type: 'basemap' | 'overlay' | 'user' | 'spacer';
type: 'basemap' | 'overlay' | 'user' | 'spacer' | 'overlayClimbing';
name?: string;
url?: string;
key?: string;
Expand Down
1 change: 1 addition & 0 deletions src/locales/cs.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,5 @@ export default {
'layers.maptilerSat': 'Letecká Maptiler ',
'layers.bingSat': 'Letecká Bing',
'layers.bike': 'Cyklo',
'layers.climbing': 'Sportovní lezení',
};
1 change: 1 addition & 0 deletions src/locales/vocabulary.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ export default {
'layers.maptilerSat': 'Maptiler Satellite (z<14)',
'layers.bingSat': 'Bing Satellite',
'layers.bike': 'Bike',
'layers.climbing': 'Climbing',

'climbingpanel.create_climbing_route': 'Draw new route in schema',
'climbingpanel.edit_climbing_route': 'Edit route in schema',
Expand Down

0 comments on commit c2ac40e

Please sign in to comment.