Skip to content

Commit 24c12ea

Browse files
authored
tagging: add climbing presets (#208)
1 parent aca9d77 commit 24c12ea

File tree

9 files changed

+242
-11
lines changed

9 files changed

+242
-11
lines changed

src/components/FeaturePanel/ImageSection/PoiDescription.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const PoiType = styled.div`
1818
span {
1919
position: absolute;
2020
left: 20px;
21+
${({ isSkeleton }) => isSkeleton && 'opacity: 0.4;'}
2122
}
2223
`;
2324

@@ -27,7 +28,7 @@ export const PoiDescription = () => {
2728
const poiType = getPoiType(feature);
2829

2930
return (
30-
<PoiType>
31+
<PoiType isSkeleton={feature.skeleton}>
3132
<Maki ico={properties.class} invert middle />
3233
<span>{poiType}</span>
3334
</PoiType>

src/components/FeaturePanel/Properties/IdSchemeFields.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ const render = (uiField: UiField, feature: Feature): string | ReactNode => {
3131
return renderValue('wikidata', feature.tags.wikidata);
3232
}
3333

34+
// combo with options
35+
if (fieldTranslation?.options?.[v]) {
36+
return renderValue(k, fieldTranslation.options[v]?.title);
37+
}
38+
39+
// multicombo ?
3440
if (fieldTranslation?.types && fieldTranslation?.options) {
3541
return tagsForField.map(({ key, value: value2 }) => (
3642
<div key={key}>
@@ -72,7 +78,9 @@ const removeUnits = (label) => label.replace(unitRegExp, '');
7278
const addUnits = (label, value: string | ReactNode) => {
7379
if (typeof value !== 'string') return value;
7480
const unit = label.match(unitRegExp);
75-
return `${value}${unit ? ` (${unit[1]})` : ''}`;
81+
if (!unit) return value;
82+
if (unit[1] === 'm') return `${value} m`;
83+
return `${value} (${unit[1]})`;
7684
};
7785

7886
const getTooltip = (field: Field, key: string) =>

src/services/getPoiClass.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const keys = [
2323
'power',
2424
'natural',
2525
'route', // relation route=bicycle etc
26+
'climbing',
2627
];
2728

2829
const shops = [
@@ -90,7 +91,7 @@ const shops = [
9091

9192
// https://github.com/openmaptiles/openmaptiles/blob/bb00b4e53fa9dbf5778b394c910c629182c441f9/layers/poi/class.sql#L33
9293
// TODO get from here https://github.com/openmaptiles/openmaptiles/blob/1614a46/layers/poi/poi.yaml#L18
93-
const subclassToClassRules = [
94+
const rules = [
9495
{
9596
subclass: shops,
9697
resultClass: 'shop',
@@ -272,6 +273,10 @@ const subclassToClassRules = [
272273
subclass: 'memorial',
273274
resultClass: 'art_gallery',
274275
},
276+
// {
277+
// mappingKey: 'climbing',
278+
// resultClass: 'climbing',
279+
// }
275280
];
276281

277282
interface PoiClass {
@@ -284,7 +289,7 @@ export const getPoiClass = (tags): PoiClass => {
284289
const value = tags[key]; // its value
285290

286291
// find first matching rule
287-
const resultRule = subclassToClassRules.find(
292+
const resultRule = rules.find(
288293
(rule) =>
289294
(!rule.mappingKey && rule.subclass.includes(value)) ||
290295
(rule.mappingKey === key && !rule.subclass) ||

src/services/tagging/__tests__/idTaggingScheme.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,15 @@ describe('idTaggingScheme', () => {
4343

4444
expect(result.label).toBe('Motorway');
4545
expect(result.presetKey).toBe('highway/motorway');
46-
expect(result.matchedFields).toMatchObject([
46+
expect(
47+
result.matchedFields.map(({ label, value }) => ({ label, value })),
48+
).toMatchObject([
4749
{ label: 'Road Number', value: 'I 84' },
4850
{ label: 'One Way', value: 'Yes' },
4951
{ label: 'Speed Limit', value: '55 mph' },
5052
{ label: 'Lanes', value: '2' },
5153
{ label: 'Surface', value: 'Asphalt' },
54+
{ label: 'Structure', value: undefined },
5255
{
5356
label: 'Allowed Access',
5457
value: 'Foot: Prohibited,\nBicycles: Prohibited,\nHorses: Prohibited',

src/services/tagging/data.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ import presetsJson from '@openstreetmap/id-tagging-schema/dist/presets.json';
33
import { Fields } from './types/Fields';
44
import { Presets } from './types/Presets';
55
import { publishDbgObject } from '../../utils';
6+
import { ourFields, ourPresets } from './ourPresets';
67

7-
export const fields = fieldsJson as unknown as Fields;
8-
9-
Object.keys(fieldsJson).forEach((fieldKey) => {
8+
export const fields = { ...fieldsJson, ...ourFields } as unknown as Fields;
9+
Object.keys(fields).forEach((fieldKey) => {
1010
fields[fieldKey].fieldKey = fieldKey;
1111
});
1212

13-
export const presets = presetsJson as unknown as Presets;
14-
Object.keys(presetsJson).forEach((presetKey) => {
13+
export const presets = { ...presetsJson, ...ourPresets } as unknown as Presets;
14+
Object.keys(presets).forEach((presetKey) => {
1515
presets[presetKey].presetKey = presetKey;
1616
});
1717

src/services/tagging/idTaggingScheme.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const getUiField = (
2727
feature: Feature,
2828
key: string,
2929
): UiField => {
30+
// TODO this should be removed now the parsing works ok (+run tests)
3031
if (field.type === 'typeCombo') {
3132
keysTodo.remove(field.key); // ignores eg. railway=tram_stop on public_transport=stop_position
3233
return undefined;
@@ -79,7 +80,7 @@ const matchFieldsFromPreset = (
7980

8081
return getUiField(field, keysTodo, feature, key);
8182
})
82-
.filter((field) => field?.value);
83+
.filter(Boolean);
8384
};
8485

8586
const matchRestToFields = (keysTodo: KeysTodo, feature: Feature): UiField[] =>

src/services/tagging/ourPresets.ts

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
import { RawPresets } from './types/Presets';
2+
3+
export const ourFields = {
4+
'climbing/summit_log': {
5+
key: 'climbing:summit_log',
6+
type: 'check',
7+
},
8+
'climbing/routes': {
9+
key: 'climbing:routes',
10+
type: 'number',
11+
minValue: 0,
12+
},
13+
'climbing/rock': {
14+
key: 'climbing:rock',
15+
type: 'combo',
16+
options: ['limestone', 'sandstone', 'granite', 'basalt'],
17+
},
18+
'climbing/quality': {
19+
key: 'climbing:quality',
20+
type: 'combo',
21+
options: ['fragile', 'medium', 'solid'],
22+
},
23+
'climbing/orientation': {
24+
key: 'climbing:orientation',
25+
type: 'combo',
26+
options: ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'],
27+
},
28+
'climbing/length': {
29+
key: 'climbing:length',
30+
type: 'number',
31+
minValue: 0,
32+
},
33+
'climbing/bolts': {
34+
key: 'climbing:bolts',
35+
type: 'number',
36+
minValue: 0,
37+
},
38+
'climbing/bolted': {
39+
key: 'climbing:bolted',
40+
type: 'check',
41+
},
42+
'climbing/bolt': {
43+
key: 'climbing:bolt',
44+
type: 'combo',
45+
options: ['expansion', 'glue-in', 'ring'],
46+
},
47+
'climbing/grade/uiaa': {
48+
key: 'climbing:grade:uiaa',
49+
type: 'text',
50+
},
51+
'climbing/grade/saxon': {
52+
key: 'climbing:grade:saxon',
53+
type: 'text',
54+
},
55+
'climbing/grade/french': {
56+
key: 'climbing:grade:french',
57+
type: 'text',
58+
},
59+
};
60+
61+
export const ourPresets = {
62+
'climbing/route_bottom': {
63+
icon: 'temaki-abseiling',
64+
geometry: ['point'],
65+
fields: ['{climbing/route}'],
66+
moreFields: ['{climbing/route}'],
67+
tags: {
68+
climbing: 'route_bottom',
69+
},
70+
addTags: {
71+
sport: 'climbing',
72+
climbing: 'route_bottom',
73+
},
74+
},
75+
'climbing/route': {
76+
icon: 'temaki-abseiling',
77+
geometry: ['point', 'line'],
78+
fields: [
79+
'name',
80+
'climbing/length',
81+
'climbing/grade/uiaa',
82+
'climbing/grade/french',
83+
'climbing/grade/saxon',
84+
],
85+
moreFields: [
86+
'climbing/bolts',
87+
'climbing/bolted',
88+
'climbing/bolt',
89+
'climbing/orientation',
90+
'climbing/quality',
91+
'climbing/rock',
92+
'climbing/summit_log',
93+
'website',
94+
'ele',
95+
],
96+
tags: {
97+
climbing: 'route',
98+
},
99+
addTags: {
100+
sport: 'climbing',
101+
climbing: 'route',
102+
},
103+
},
104+
'climbing/crag': {
105+
icon: 'temaki-abseiling',
106+
geometry: ['point', 'relation'],
107+
fields: ['name'],
108+
moreFields: [
109+
'climbing/length',
110+
'climbing/routes',
111+
'climbing/bolted',
112+
'climbing/bolt',
113+
'climbing/orientation',
114+
'climbing/quality',
115+
'climbing/rock',
116+
'website',
117+
'ele',
118+
],
119+
tags: {
120+
climbing: 'crag',
121+
},
122+
addTags: {
123+
sport: 'climbing',
124+
climbing: 'crag',
125+
},
126+
},
127+
} as RawPresets;
128+
129+
export const getOurTranslations = (lang) => ({
130+
[lang]: {
131+
presets: {
132+
presets: {
133+
'climbing/route_bottom': {
134+
name: 'Climbing route (start)',
135+
terms: 'rock climbing,climbing',
136+
},
137+
'climbing/route': {
138+
name: 'Climbing route',
139+
terms: 'rock climbing,climbing',
140+
},
141+
'climbing/crag': {
142+
name: 'Climbing crag',
143+
terms: 'rock climbing,climbing',
144+
},
145+
},
146+
fields: {
147+
'climbing/summit_log': {
148+
label: 'Summit log',
149+
},
150+
'climbing/routes': {
151+
label: 'Number of routes',
152+
},
153+
'climbing/rock': {
154+
label: 'Rock type',
155+
},
156+
'climbing/quality': {
157+
label: 'Rock quality',
158+
},
159+
'climbing/orientation': {
160+
label: 'Orientation',
161+
options: {
162+
N: 'North',
163+
NE: 'North-East',
164+
E: 'East',
165+
SE: 'South-East',
166+
S: 'South',
167+
SW: 'South-West',
168+
W: 'West',
169+
NW: 'North-West',
170+
},
171+
},
172+
'climbing/length': {
173+
label: 'Length (m)',
174+
},
175+
'climbing/bolts': {
176+
label: 'Number of bolts',
177+
},
178+
'climbing/bolted': {
179+
label: 'Bolted',
180+
},
181+
'climbing/bolt': {
182+
label: 'Bolt type',
183+
options: {
184+
expansion: 'expansion bolt',
185+
'glue-in': 'glue-in bolt',
186+
ring: 'ring bolt',
187+
},
188+
},
189+
'climbing/grade/uiaa': {
190+
label: 'Grade (UIAA)',
191+
placeholder: '6-',
192+
},
193+
'climbing/grade/saxon': {
194+
label: 'Grade (saxon)',
195+
placeholder: 'VIIa',
196+
},
197+
'climbing/grade/french': {
198+
label: 'Grade (french)',
199+
placeholder: '5c',
200+
},
201+
},
202+
},
203+
},
204+
});

src/services/tagging/translations.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import { merge } from 'lodash';
12
import { fetchJson } from '../fetch';
23
import { Field } from './types/Fields';
34
import { intl } from '../intl';
45
import { publishDbgObject } from '../../utils';
56
import { FieldTranslation } from './types/Presets';
7+
import { getOurTranslations } from './ourPresets';
68

79
// https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema@6.1.0/dist/translations/en.min.json
810
const cdnUrl = `https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema`;
@@ -19,6 +21,9 @@ export const fetchSchemaTranslations = async () => {
1921
translations = await fetchJson(
2022
`${cdnUrl}@${version}/dist/translations/${intl.lang}.min.json`,
2123
);
24+
25+
merge(translations, getOurTranslations(intl.lang));
26+
2227
publishDbgObject('schemaTranslations', translations);
2328
};
2429

src/services/tagging/types/Presets.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ export type Presets = {
9898
[presetKey: string]: Preset;
9999
};
100100

101+
export type RawPresets = {
102+
[presetKey: string]: Omit<Preset, 'presetKey'>;
103+
};
104+
101105
export type FieldTranslation = {
102106
label: string;
103107
placeholder: string;

0 commit comments

Comments
 (0)