Skip to content

Commit

Permalink
Extract EDTF date from OSM approximate date
Browse files Browse the repository at this point in the history
  • Loading branch information
1ec5 committed Dec 17, 2023
1 parent bde3244 commit f5ff76f
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 14 deletions.
93 changes: 80 additions & 13 deletions modules/validations/invalid_format.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,52 @@ import { localizer, t } from '../core/localizer';
import { utilDisplayLabel, utilNormalizeDateString } from '../util';
import { validationIssue, validationIssueFix } from '../core/validation';

import edtf, { format as formatEDTF } from 'edtf';

export function validationFormatting() {
var type = 'invalid_format';

/**
* Converts a date in OSM approximate date format to EDTF.
*/
function edtfFromOSMDate(osm) {
// https://wiki.openstreetmap.org/wiki/Key:start_date#Approximations
// https://wiki.openstreetmap.org/wiki/Special:Diff/510218/557626#Proposal_for_date_formatting
let [match, year, bc] = osm.match(/^~(\d+)( BC)?$/) || [];
if (match) {
if (bc) year = -parseInt(year, 10) + 1;
return `${year}~`;
}

[match, circa, decade, bc] = osm.match(/^(~)?(\d+)0s( BC)?$/) || [];
if (match) {
if (!circa) circa = '';
if (!bc) return `${decade}X${circa}`;
let startYear = -parseInt(decade, 10) * 10 - 8;
let endYear = -parseInt(decade, 10) * 10 + 1;
return `${startYear}${circa}/${endYear}${circa}`;
}

[match, circa, century, bc] = osm.match(/^(~)?C(\d+)( BC)?$/) || [];
if (match) {
if (!circa) circa = '';
if (!bc) return `${parseInt(century, 10) - 1}XX${circa}`;
let startYear = (parseInt(century, 10) - 1) * -100 - 98;
let endYear = (parseInt(century, 10) - 1) * -100 + 1;
return `${startYear}${circa}/${endYear}${circa}`;
}

[match, end] = osm.match(/^before (\d{4}(?:-\d\d)?(?:-\d\d)?)$/) || [];
if (match) {
return `[..${end}]`;
}

[match, start] = osm.match(/^after (\d{4}(?:-\d\d)?(?:-\d\d)?)$/) || [];
if (match) {
return `[${start}..]`;
}
}

var validation = function(entity) {
var issues = [];

Expand Down Expand Up @@ -36,21 +79,44 @@ export function validationFormatting() {
hash: key + entity.tags[key],
dynamicFixes: function() {
var fixes = [];

let alternatives = [];
if (normalized !== null) {
var localeDateString = normalized.date.toLocaleDateString(localizer.languageCode(), normalized.localeOptions);
fixes.push(new validationIssueFix({
title: t.append('issues.fix.reformat_date.title', { date: localeDateString }),
onClick: function(context) {
context.perform(function(graph) {
var entityInGraph = graph.hasEntity(entity.id);
if (!entityInGraph) return graph;
var newTags = Object.assign({}, entityInGraph.tags);
newTags[key] = normalized.value;
return actionChangeTags(entityInGraph.id, newTags)(graph);
}, t('issues.fix.reformat_date.annotation'));
}
}));
alternatives.push({
date: normalized.value,
label: normalized.date.toLocaleDateString(localizer.languageCode(), normalized.localeOptions),
});
}
let edtfFromOSM = edtfFromOSMDate(entity.tags[key]);
if (edtfFromOSM) {
let label;
try {
label = formatEDTF(edtf(edtfFromOSM), localizer.languageCode());
} catch (e) {}
alternatives.push({
edtf: edtfFromOSM,
label: label,
});
}

fixes.push(...alternatives.map(alt => new validationIssueFix({
title: t.append('issues.fix.reformat_date.title', { date: alt.label || alt.date || alt.edtf }),
onClick: function(context) {
context.perform(function(graph) {
var entityInGraph = graph.hasEntity(entity.id);
if (!entityInGraph) return graph;
var newTags = Object.assign({}, entityInGraph.tags);
if (alt.date) {
newTags[key] = alt.date;
} else {
delete newTags[key];
}
newTags[key + ':edtf'] = alt.edtf;
return actionChangeTags(entityInGraph.id, newTags)(graph);
}, t('issues.fix.reformat_date.annotation'));
}
})));

fixes.push(new validationIssueFix({
icon: 'iD-operation-delete',
title: t.append('issues.fix.remove_tag.title'),
Expand All @@ -64,6 +130,7 @@ export function validationFormatting() {
}, t('issues.fix.remove_tag.annotation'));
}
}));

return fixes;
}
}));
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"alif-toolkit": "^1.2.9",
"core-js-bundle": "^3.19.0",
"diacritics": "1.3.0",
"edtf": "^4.5.1",
"fast-deep-equal": "~3.1.1",
"fast-json-stable-stringify": "2.1.0",
"lodash-es": "~4.17.15",
Expand Down Expand Up @@ -86,7 +87,6 @@
"d3": "~7.8.1",
"esbuild": "^0.17.3",
"esbuild-visualizer": "^0.4.0",
"ohm-editor-layer-index": "github:openhistoricalmap/ohm-editor-layer-index#dist",
"eslint": "^8.8.0",
"fetch-mock": "^9.11.0",
"gaze": "^1.1.3",
Expand All @@ -106,6 +106,7 @@
"name-suggestion-index": "~6.0",
"node-fetch": "^2.6.1",
"npm-run-all": "^4.0.0",
"ohm-editor-layer-index": "github:openhistoricalmap/ohm-editor-layer-index#dist",
"osm-community-index": "~5.5.0",
"postcss": "^8.1.1",
"postcss-selector-prepend": "^0.5.0",
Expand Down

0 comments on commit f5ff76f

Please sign in to comment.