mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-16 05:49:16 +02:00
move deprecatedTags logic out of osmEntity and into a helper function (#10842)
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
/** @typedef {{ old: Tags; replace?: Tags }[]} DataDeprecated */
|
||||
|
||||
/** @param {Tags} tags @param {DataDeprecated} dataDeprecated */
|
||||
export function getDeprecatedTags(tags, dataDeprecated) {
|
||||
// if there are no tags, none can be deprecated
|
||||
if (Object.keys(tags).length === 0) return [];
|
||||
|
||||
/** @type {DataDeprecated} */
|
||||
var deprecated = [];
|
||||
dataDeprecated.forEach((d) => {
|
||||
var oldKeys = Object.keys(d.old);
|
||||
if (d.replace) {
|
||||
var hasExistingValues = Object.keys(d.replace).some((replaceKey) => {
|
||||
if (!tags[replaceKey] || d.old[replaceKey]) return false;
|
||||
var replaceValue = d.replace[replaceKey];
|
||||
if (replaceValue === '*') return false;
|
||||
if (replaceValue === tags[replaceKey]) return false;
|
||||
return true;
|
||||
});
|
||||
// don't flag deprecated tags if the upgrade path would overwrite existing data - #7843
|
||||
if (hasExistingValues) return;
|
||||
}
|
||||
|
||||
var matchesDeprecatedTags = oldKeys.every((oldKey) => {
|
||||
if (!tags[oldKey]) return false;
|
||||
if (d.old[oldKey] === '*') return true;
|
||||
if (d.old[oldKey] === tags[oldKey]) return true;
|
||||
|
||||
var vals = tags[oldKey].split(';').filter(Boolean);
|
||||
if (vals.length === 0) {
|
||||
return false;
|
||||
} else if (vals.length > 1) {
|
||||
return vals.indexOf(d.old[oldKey]) !== -1;
|
||||
} else {
|
||||
if (tags[oldKey] === d.old[oldKey]) {
|
||||
if (d.replace && d.old[oldKey] === d.replace[oldKey]) {
|
||||
var replaceKeys = Object.keys(d.replace);
|
||||
return !replaceKeys.every((replaceKey) => {
|
||||
return tags[replaceKey] === d.replace[replaceKey];
|
||||
});
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
if (matchesDeprecatedTags) {
|
||||
deprecated.push(d);
|
||||
}
|
||||
});
|
||||
|
||||
return deprecated;
|
||||
}
|
||||
|
||||
/** @type {{ [key: string]: string[] }} */
|
||||
var _deprecatedTagValuesByKey;
|
||||
|
||||
/** @param {DataDeprecated} dataDeprecated */
|
||||
export function deprecatedTagValuesByKey(dataDeprecated) {
|
||||
if (!_deprecatedTagValuesByKey) {
|
||||
_deprecatedTagValuesByKey = {};
|
||||
dataDeprecated.forEach((d) => {
|
||||
var oldKeys = Object.keys(d.old);
|
||||
if (oldKeys.length === 1) {
|
||||
var oldKey = oldKeys[0];
|
||||
var oldValue = d.old[oldKey];
|
||||
if (oldValue !== '*') {
|
||||
if (!_deprecatedTagValuesByKey[oldKey]) {
|
||||
_deprecatedTagValuesByKey[oldKey] = [oldValue];
|
||||
} else {
|
||||
_deprecatedTagValuesByKey[oldKey].push(oldValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return _deprecatedTagValuesByKey;
|
||||
};
|
||||
@@ -54,29 +54,6 @@ osmEntity.key = function(entity) {
|
||||
return entity.id + 'v' + (entity.v || 0);
|
||||
};
|
||||
|
||||
var _deprecatedTagValuesByKey;
|
||||
|
||||
osmEntity.deprecatedTagValuesByKey = function(dataDeprecated) {
|
||||
if (!_deprecatedTagValuesByKey) {
|
||||
_deprecatedTagValuesByKey = {};
|
||||
dataDeprecated.forEach(function(d) {
|
||||
var oldKeys = Object.keys(d.old);
|
||||
if (oldKeys.length === 1) {
|
||||
var oldKey = oldKeys[0];
|
||||
var oldValue = d.old[oldKey];
|
||||
if (oldValue !== '*') {
|
||||
if (!_deprecatedTagValuesByKey[oldKey]) {
|
||||
_deprecatedTagValuesByKey[oldKey] = [oldValue];
|
||||
} else {
|
||||
_deprecatedTagValuesByKey[oldKey].push(oldValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return _deprecatedTagValuesByKey;
|
||||
};
|
||||
|
||||
|
||||
osmEntity.prototype = {
|
||||
|
||||
@@ -185,56 +162,4 @@ osmEntity.prototype = {
|
||||
isDegenerate: function() {
|
||||
return true;
|
||||
},
|
||||
|
||||
deprecatedTags: function(dataDeprecated) {
|
||||
var tags = this.tags;
|
||||
|
||||
// if there are no tags, none can be deprecated
|
||||
if (Object.keys(tags).length === 0) return [];
|
||||
|
||||
var deprecated = [];
|
||||
dataDeprecated.forEach(function(d) {
|
||||
var oldKeys = Object.keys(d.old);
|
||||
if (d.replace) {
|
||||
var hasExistingValues = Object.keys(d.replace).some(function(replaceKey) {
|
||||
if (!tags[replaceKey] || d.old[replaceKey]) return false;
|
||||
var replaceValue = d.replace[replaceKey];
|
||||
if (replaceValue === '*') return false;
|
||||
if (replaceValue === tags[replaceKey]) return false;
|
||||
return true;
|
||||
});
|
||||
// don't flag deprecated tags if the upgrade path would overwrite existing data - #7843
|
||||
if (hasExistingValues) return;
|
||||
}
|
||||
var matchesDeprecatedTags = oldKeys.every(function(oldKey) {
|
||||
if (!tags[oldKey]) return false;
|
||||
if (d.old[oldKey] === '*') return true;
|
||||
if (d.old[oldKey] === tags[oldKey]) return true;
|
||||
|
||||
var vals = tags[oldKey].split(';').filter(Boolean);
|
||||
if (vals.length === 0) {
|
||||
return false;
|
||||
} else if (vals.length > 1) {
|
||||
return vals.indexOf(d.old[oldKey]) !== -1;
|
||||
} else {
|
||||
if (tags[oldKey] === d.old[oldKey]) {
|
||||
if (d.replace && d.old[oldKey] === d.replace[oldKey]) {
|
||||
var replaceKeys = Object.keys(d.replace);
|
||||
return !replaceKeys.every(function(replaceKey) {
|
||||
return tags[replaceKey] === d.replace[replaceKey];
|
||||
});
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (matchesDeprecatedTags) {
|
||||
deprecated.push(d);
|
||||
}
|
||||
});
|
||||
|
||||
return deprecated;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -4,7 +4,6 @@ import { drag as d3_drag } from 'd3-drag';
|
||||
import * as countryCoder from '@rapideditor/country-coder';
|
||||
|
||||
import { fileFetcher } from '../../core/file_fetcher';
|
||||
import { osmEntity } from '../../osm/entity';
|
||||
import { t } from '../../core/localizer';
|
||||
import { services } from '../../services';
|
||||
import { uiCombobox } from '../combobox';
|
||||
@@ -13,6 +12,7 @@ import { svgIcon } from '../../svg/icon';
|
||||
import { utilKeybinding } from '../../util/keybinding';
|
||||
import { utilArrayUniq, utilGetSetValue, utilNoAuto, utilRebind, utilTotalExtent, utilUnicodeCharsCount } from '../../util';
|
||||
import { uiLengthIndicator } from '../length_indicator';
|
||||
import { deprecatedTagValuesByKey } from '../../osm/deprecated';
|
||||
|
||||
export {
|
||||
uiFieldCombo as uiFieldManyCombo,
|
||||
@@ -258,7 +258,7 @@ export function uiFieldCombo(field, context) {
|
||||
return value === restrictTagValueSpelling(value);
|
||||
});
|
||||
|
||||
var deprecatedValues = osmEntity.deprecatedTagValuesByKey(_dataDeprecated)[field.key];
|
||||
var deprecatedValues = deprecatedTagValuesByKey(_dataDeprecated)[field.key];
|
||||
if (deprecatedValues) {
|
||||
// don't suggest deprecated tag values
|
||||
data = data.filter(d =>
|
||||
|
||||
@@ -9,6 +9,7 @@ import { services } from '../services';
|
||||
import { utilHashcode, utilTagDiff } from '../util';
|
||||
import { utilDisplayLabel } from '../util/utilDisplayLabel';
|
||||
import { validationIssue, validationIssueFix } from '../core/validation';
|
||||
import { getDeprecatedTags } from '../osm/deprecated';
|
||||
|
||||
/** @import { TagDiff } from '../util/util'. */
|
||||
|
||||
@@ -43,7 +44,7 @@ export function validationOutdatedTags() {
|
||||
|
||||
// Upgrade deprecated tags..
|
||||
if (_dataDeprecated) {
|
||||
const deprecatedTags = entity.deprecatedTags(_dataDeprecated);
|
||||
const deprecatedTags = getDeprecatedTags(entity.tags, _dataDeprecated);
|
||||
if (entity.type === 'way' && entity.isClosed() &&
|
||||
entity.tags.traffic_calming === 'island' && !entity.tags.highway) {
|
||||
// https://github.com/openstreetmap/id-tagging-schema/issues/1162#issuecomment-2000356902
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
import {
|
||||
deprecatedTagValuesByKey,
|
||||
getDeprecatedTags,
|
||||
type DataDeprecated,
|
||||
} from '../../../modules/osm/deprecated';
|
||||
|
||||
var deprecated: DataDeprecated = [
|
||||
{ old: { highway: 'no' } },
|
||||
{ old: { amenity: 'toilet' }, replace: { amenity: 'toilets' } },
|
||||
{ old: { speedlimit: '*' }, replace: { maxspeed: '$1' } },
|
||||
{
|
||||
old: { man_made: 'water_tank' },
|
||||
replace: { man_made: 'storage_tank', content: 'water' },
|
||||
},
|
||||
{
|
||||
old: { amenity: 'gambling', gambling: 'casino' },
|
||||
replace: { amenity: 'casino' },
|
||||
},
|
||||
];
|
||||
|
||||
describe('getDeprecatedTags', () => {
|
||||
it('returns none if entity has no tags', () => {
|
||||
expect(getDeprecatedTags({}, deprecated)).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it('returns none when no tags are deprecated', () => {
|
||||
expect(getDeprecatedTags({ amenity: 'toilets' }, deprecated)).toStrictEqual(
|
||||
[],
|
||||
);
|
||||
});
|
||||
|
||||
it('returns 1:0 replacement', () => {
|
||||
expect(getDeprecatedTags({ highway: 'no' }, deprecated)).toStrictEqual([
|
||||
{ old: { highway: 'no' } },
|
||||
]);
|
||||
});
|
||||
|
||||
it('returns 1:1 replacement', () => {
|
||||
expect(getDeprecatedTags({ amenity: 'toilet' }, deprecated)).toStrictEqual([
|
||||
{ old: { amenity: 'toilet' }, replace: { amenity: 'toilets' } },
|
||||
]);
|
||||
});
|
||||
|
||||
it('returns 1:1 wildcard', () => {
|
||||
expect(getDeprecatedTags({ speedlimit: '50' }, deprecated)).toStrictEqual([
|
||||
{ old: { speedlimit: '*' }, replace: { maxspeed: '$1' } },
|
||||
]);
|
||||
});
|
||||
|
||||
it('returns 1:2 total replacement', () => {
|
||||
expect(
|
||||
getDeprecatedTags({ man_made: 'water_tank' }, deprecated),
|
||||
).toStrictEqual([
|
||||
{
|
||||
old: { man_made: 'water_tank' },
|
||||
replace: { man_made: 'storage_tank', content: 'water' },
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('returns 1:2 partial replacement', () => {
|
||||
expect(
|
||||
getDeprecatedTags(
|
||||
{ man_made: 'water_tank', content: 'water' },
|
||||
deprecated,
|
||||
),
|
||||
).toStrictEqual([
|
||||
{
|
||||
old: { man_made: 'water_tank' },
|
||||
replace: { man_made: 'storage_tank', content: 'water' },
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('returns 2:1 replacement', () => {
|
||||
expect(
|
||||
getDeprecatedTags(
|
||||
{ amenity: 'gambling', gambling: 'casino' },
|
||||
deprecated,
|
||||
),
|
||||
).toStrictEqual([
|
||||
{
|
||||
old: { amenity: 'gambling', gambling: 'casino' },
|
||||
replace: { amenity: 'casino' },
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('deprecatedTagValuesByKey', () => {
|
||||
it('groups simple deprecations by key', () => {
|
||||
expect(deprecatedTagValuesByKey(deprecated)).toStrictEqual({
|
||||
amenity: ['toilet'], // `gambling` not included
|
||||
highway: ['no'],
|
||||
man_made: ['water_tank'],
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -226,60 +226,6 @@ describe('iD.osmEntity', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#deprecatedTags', function () {
|
||||
var deprecated = [
|
||||
{ old: { highway: 'no' } },
|
||||
{ old: { amenity: 'toilet' }, replace: { amenity: 'toilets' } },
|
||||
{ old: { speedlimit: '*' }, replace: { maxspeed: '$1' } },
|
||||
{ old: { man_made: 'water_tank' }, replace: { man_made: 'storage_tank', content: 'water' } },
|
||||
{ old: { amenity: 'gambling', gambling: 'casino' }, replace: { amenity: 'casino' } }
|
||||
];
|
||||
|
||||
it('returns none if entity has no tags', function () {
|
||||
expect(iD.osmEntity().deprecatedTags(deprecated)).to.eql([]);
|
||||
});
|
||||
|
||||
it('returns none when no tags are deprecated', function () {
|
||||
expect(iD.osmEntity({ tags: { amenity: 'toilets' } }).deprecatedTags(deprecated)).to.eql([]);
|
||||
});
|
||||
|
||||
it('returns 1:0 replacement', function () {
|
||||
expect(iD.osmEntity({ tags: { highway: 'no' } }).deprecatedTags(deprecated)).to.eql(
|
||||
[{ old: { highway: 'no' } }]
|
||||
);
|
||||
});
|
||||
|
||||
it('returns 1:1 replacement', function () {
|
||||
expect(iD.osmEntity({ tags: { amenity: 'toilet' } }).deprecatedTags(deprecated)).to.eql(
|
||||
[{ old: { amenity: 'toilet' }, replace: { amenity: 'toilets' } }]
|
||||
);
|
||||
});
|
||||
|
||||
it('returns 1:1 wildcard', function () {
|
||||
expect(iD.osmEntity({ tags: { speedlimit: '50' } }).deprecatedTags(deprecated)).to.eql(
|
||||
[{ old: { speedlimit: '*' }, replace: { maxspeed: '$1' } }]
|
||||
);
|
||||
});
|
||||
|
||||
it('returns 1:2 total replacement', function () {
|
||||
expect(iD.osmEntity({ tags: { man_made: 'water_tank' } }).deprecatedTags(deprecated)).to.eql(
|
||||
[{ old: { man_made: 'water_tank' }, replace: { man_made: 'storage_tank', content: 'water' } }]
|
||||
);
|
||||
});
|
||||
|
||||
it('returns 1:2 partial replacement', function () {
|
||||
expect(iD.osmEntity({ tags: { man_made: 'water_tank', content: 'water' } }).deprecatedTags(deprecated)).to.eql(
|
||||
[{ old: { man_made: 'water_tank' }, replace: { man_made: 'storage_tank', content: 'water' } }]
|
||||
);
|
||||
});
|
||||
|
||||
it('returns 2:1 replacement', function () {
|
||||
expect(iD.osmEntity({ tags: { amenity: 'gambling', gambling: 'casino' } }).deprecatedTags(deprecated)).to.eql(
|
||||
[{ old: { amenity: 'gambling', gambling: 'casino' }, replace: { amenity: 'casino' } }]
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#hasInterestingTags', function () {
|
||||
it('returns false if the entity has no tags', function () {
|
||||
expect(iD.osmEntity().hasInterestingTags()).to.equal(false);
|
||||
|
||||
Reference in New Issue
Block a user