Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tagging: add climbing presets #208

Merged
merged 16 commits into from
Feb 12, 2024
3 changes: 2 additions & 1 deletion src/components/FeaturePanel/ImageSection/PoiDescription.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const PoiType = styled.div`
span {
position: absolute;
left: 20px;
${({ isSkeleton }) => isSkeleton && 'opacity: 0.4;'}
}
`;

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

return (
<PoiType>
<PoiType isSkeleton={feature.skeleton}>
<Maki ico={properties.class} invert middle />
<span>{poiType}</span>
</PoiType>
Expand Down
10 changes: 9 additions & 1 deletion src/components/FeaturePanel/Properties/IdSchemeFields.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ const render = (uiField: UiField, feature: Feature): string | ReactNode => {
return renderValue('wikidata', feature.tags.wikidata);
}

// combo with options
if (fieldTranslation?.options?.[v]) {
return renderValue(k, fieldTranslation.options[v]?.title);
}

// multicombo ?
if (fieldTranslation?.types && fieldTranslation?.options) {
return tagsForField.map(({ key, value: value2 }) => (
<div key={key}>
Expand Down Expand Up @@ -72,7 +78,9 @@ const removeUnits = (label) => label.replace(unitRegExp, '');
const addUnits = (label, value: string | ReactNode) => {
if (typeof value !== 'string') return value;
const unit = label.match(unitRegExp);
return `${value}${unit ? ` (${unit[1]})` : ''}`;
if (!unit) return value;
if (unit[1] === 'm') return `${value} m`;
return `${value} (${unit[1]})`;
};

const getTooltip = (field: Field, key: string) =>
Expand Down
9 changes: 7 additions & 2 deletions src/services/getPoiClass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const keys = [
'power',
'natural',
'route', // relation route=bicycle etc
'climbing',
];

const shops = [
Expand Down Expand Up @@ -90,7 +91,7 @@ const shops = [

// https://github.com/openmaptiles/openmaptiles/blob/bb00b4e53fa9dbf5778b394c910c629182c441f9/layers/poi/class.sql#L33
// TODO get from here https://github.com/openmaptiles/openmaptiles/blob/1614a46/layers/poi/poi.yaml#L18
const subclassToClassRules = [
const rules = [
{
subclass: shops,
resultClass: 'shop',
Expand Down Expand Up @@ -272,6 +273,10 @@ const subclassToClassRules = [
subclass: 'memorial',
resultClass: 'art_gallery',
},
// {
// mappingKey: 'climbing',
// resultClass: 'climbing',
// }
];

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

// find first matching rule
const resultRule = subclassToClassRules.find(
const resultRule = rules.find(
(rule) =>
(!rule.mappingKey && rule.subclass.includes(value)) ||
(rule.mappingKey === key && !rule.subclass) ||
Expand Down
5 changes: 4 additions & 1 deletion src/services/tagging/__tests__/idTaggingScheme.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,15 @@ describe('idTaggingScheme', () => {

expect(result.label).toBe('Motorway');
expect(result.presetKey).toBe('highway/motorway');
expect(result.matchedFields).toMatchObject([
expect(
result.matchedFields.map(({ label, value }) => ({ label, value })),
).toMatchObject([
{ label: 'Road Number', value: 'I 84' },
{ label: 'One Way', value: 'Yes' },
{ label: 'Speed Limit', value: '55 mph' },
{ label: 'Lanes', value: '2' },
{ label: 'Surface', value: 'Asphalt' },
{ label: 'Structure', value: undefined },
{
label: 'Allowed Access',
value: 'Foot: Prohibited,\nBicycles: Prohibited,\nHorses: Prohibited',
Expand Down
10 changes: 5 additions & 5 deletions src/services/tagging/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import presetsJson from '@openstreetmap/id-tagging-schema/dist/presets.json';
import { Fields } from './types/Fields';
import { Presets } from './types/Presets';
import { publishDbgObject } from '../../utils';
import { ourFields, ourPresets } from './ourPresets';

export const fields = fieldsJson as unknown as Fields;

Object.keys(fieldsJson).forEach((fieldKey) => {
export const fields = { ...fieldsJson, ...ourFields } as unknown as Fields;
Object.keys(fields).forEach((fieldKey) => {
fields[fieldKey].fieldKey = fieldKey;
});

export const presets = presetsJson as unknown as Presets;
Object.keys(presetsJson).forEach((presetKey) => {
export const presets = { ...presetsJson, ...ourPresets } as unknown as Presets;
Object.keys(presets).forEach((presetKey) => {
presets[presetKey].presetKey = presetKey;
});

Expand Down
3 changes: 2 additions & 1 deletion src/services/tagging/idTaggingScheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const getUiField = (
feature: Feature,
key: string,
): UiField => {
// TODO this should be removed now the parsing works ok (+run tests)
if (field.type === 'typeCombo') {
keysTodo.remove(field.key); // ignores eg. railway=tram_stop on public_transport=stop_position
return undefined;
Expand Down Expand Up @@ -79,7 +80,7 @@ const matchFieldsFromPreset = (

return getUiField(field, keysTodo, feature, key);
})
.filter((field) => field?.value);
.filter(Boolean);
};

const matchRestToFields = (keysTodo: KeysTodo, feature: Feature): UiField[] =>
Expand Down
204 changes: 204 additions & 0 deletions src/services/tagging/ourPresets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
import { RawPresets } from './types/Presets';

export const ourFields = {
'climbing/summit_log': {
key: 'climbing:summit_log',
type: 'check',
},
'climbing/routes': {
key: 'climbing:routes',
type: 'number',
minValue: 0,
},
'climbing/rock': {
key: 'climbing:rock',
type: 'combo',
options: ['limestone', 'sandstone', 'granite', 'basalt'],
},
'climbing/quality': {
key: 'climbing:quality',
type: 'combo',
options: ['fragile', 'medium', 'solid'],
},
'climbing/orientation': {
key: 'climbing:orientation',
type: 'combo',
options: ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'],
},
'climbing/length': {
key: 'climbing:length',
type: 'number',
minValue: 0,
},
'climbing/bolts': {
key: 'climbing:bolts',
type: 'number',
minValue: 0,
},
'climbing/bolted': {
key: 'climbing:bolted',
type: 'check',
},
'climbing/bolt': {
key: 'climbing:bolt',
type: 'combo',
options: ['expansion', 'glue-in', 'ring'],
},
'climbing/grade/uiaa': {
key: 'climbing:grade:uiaa',
type: 'text',
},
'climbing/grade/saxon': {
key: 'climbing:grade:saxon',
type: 'text',
},
'climbing/grade/french': {
key: 'climbing:grade:french',
type: 'text',
},
};

export const ourPresets = {
'climbing/route_bottom': {
icon: 'temaki-abseiling',
geometry: ['point'],
fields: ['{climbing/route}'],
moreFields: ['{climbing/route}'],
tags: {
climbing: 'route_bottom',
},
addTags: {
sport: 'climbing',
climbing: 'route_bottom',
},
},
'climbing/route': {
icon: 'temaki-abseiling',
geometry: ['point', 'line'],
fields: [
'name',
'climbing/length',
'climbing/grade/uiaa',
'climbing/grade/french',
'climbing/grade/saxon',
],
moreFields: [
'climbing/bolts',
'climbing/bolted',
'climbing/bolt',
'climbing/orientation',
'climbing/quality',
'climbing/rock',
'climbing/summit_log',
'website',
'ele',
],
tags: {
climbing: 'route',
},
addTags: {
sport: 'climbing',
climbing: 'route',
},
},
'climbing/crag': {
icon: 'temaki-abseiling',
geometry: ['point', 'relation'],
fields: ['name'],
moreFields: [
'climbing/length',
'climbing/routes',
'climbing/bolted',
'climbing/bolt',
'climbing/orientation',
'climbing/quality',
'climbing/rock',
'website',
'ele',
],
tags: {
climbing: 'crag',
},
addTags: {
sport: 'climbing',
climbing: 'crag',
},
},
} as RawPresets;

export const getOurTranslations = (lang) => ({
[lang]: {
presets: {
presets: {
'climbing/route_bottom': {
name: 'Climbing route (start)',
terms: 'rock climbing,climbing',
},
'climbing/route': {
name: 'Climbing route',
terms: 'rock climbing,climbing',
},
'climbing/crag': {
name: 'Climbing crag',
terms: 'rock climbing,climbing',
},
},
fields: {
'climbing/summit_log': {
label: 'Summit log',
},
'climbing/routes': {
label: 'Number of routes',
},
'climbing/rock': {
label: 'Rock type',
},
'climbing/quality': {
label: 'Rock quality',
},
'climbing/orientation': {
label: 'Orientation',
options: {
N: 'North',
NE: 'North-East',
E: 'East',
SE: 'South-East',
S: 'South',
SW: 'South-West',
W: 'West',
NW: 'North-West',
},
},
'climbing/length': {
label: 'Length (m)',
},
'climbing/bolts': {
label: 'Number of bolts',
},
'climbing/bolted': {
label: 'Bolted',
},
'climbing/bolt': {
label: 'Bolt type',
options: {
expansion: 'expansion bolt',
'glue-in': 'glue-in bolt',
ring: 'ring bolt',
},
},
'climbing/grade/uiaa': {
label: 'Grade (UIAA)',
placeholder: '6-',
},
'climbing/grade/saxon': {
label: 'Grade (saxon)',
placeholder: 'VIIa',
},
'climbing/grade/french': {
label: 'Grade (french)',
placeholder: '5c',
},
},
},
},
});
5 changes: 5 additions & 0 deletions src/services/tagging/translations.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { merge } from 'lodash';
import { fetchJson } from '../fetch';
import { Field } from './types/Fields';
import { intl } from '../intl';
import { publishDbgObject } from '../../utils';
import { FieldTranslation } from './types/Presets';
import { getOurTranslations } from './ourPresets';

// https://cdn.jsdelivr.net/npm/@openstreetmap/[email protected]/dist/translations/en.min.json
const cdnUrl = `https://cdn.jsdelivr.net/npm/@openstreetmap/id-tagging-schema`;
Expand All @@ -19,6 +21,9 @@ export const fetchSchemaTranslations = async () => {
translations = await fetchJson(
`${cdnUrl}@${version}/dist/translations/${intl.lang}.min.json`,
);

merge(translations, getOurTranslations(intl.lang));

publishDbgObject('schemaTranslations', translations);
};

Expand Down
4 changes: 4 additions & 0 deletions src/services/tagging/types/Presets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ export type Presets = {
[presetKey: string]: Preset;
};

export type RawPresets = {
[presetKey: string]: Omit<Preset, 'presetKey'>;
};

export type FieldTranslation = {
label: string;
placeholder: string;
Expand Down
Loading