mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-25 09:34:04 +02:00
Add Downgrade operation to remove most tags from features but retain address and building tags instead of immediate deletion
This commit is contained in:
@@ -149,6 +149,23 @@ en:
|
||||
has_wikidata_tag:
|
||||
single: This feature can't be deleted because it has a Wikidata tag.
|
||||
multiple: These features can't be deleted because some have Wikidata tags.
|
||||
downgrade:
|
||||
title: Downgrade
|
||||
description:
|
||||
building_address: Remove all non-address and non-building tags.
|
||||
building: Remove all non-building tags.
|
||||
address: Remove all non-address tags.
|
||||
annotation:
|
||||
building:
|
||||
single: Downgraded a feature to a basic building.
|
||||
multiple: "Downgraded {n} features to basic buildings."
|
||||
address:
|
||||
single: Downgraded a feature to an address.
|
||||
multiple: "Downgraded {n} features to addresses."
|
||||
multiple: "Downgraded {n} features."
|
||||
has_wikidata_tag:
|
||||
single: This feature can't be downgraded because it has a Wikidata tag.
|
||||
multiple: These features can't be downgraded because some have Wikidata tags.
|
||||
add_member:
|
||||
annotation: Added a member to a relation.
|
||||
delete_member:
|
||||
|
||||
Vendored
+23
@@ -191,6 +191,29 @@
|
||||
"multiple": "These features can't be deleted because some have Wikidata tags."
|
||||
}
|
||||
},
|
||||
"downgrade": {
|
||||
"title": "Downgrade",
|
||||
"description": {
|
||||
"building_address": "Remove all non-address and non-building tags.",
|
||||
"building": "Remove all non-building tags.",
|
||||
"address": "Remove all non-address tags."
|
||||
},
|
||||
"annotation": {
|
||||
"building": {
|
||||
"single": "Downgraded a feature to a basic building.",
|
||||
"multiple": "Downgraded {n} features to basic buildings."
|
||||
},
|
||||
"address": {
|
||||
"single": "Downgraded a feature to an address.",
|
||||
"multiple": "Downgraded {n} features to addresses."
|
||||
},
|
||||
"multiple": "Downgraded {n} features."
|
||||
},
|
||||
"has_wikidata_tag": {
|
||||
"single": "This feature can't be downgraded because it has a Wikidata tag.",
|
||||
"multiple": "These features can't be downgraded because some have Wikidata tags."
|
||||
}
|
||||
},
|
||||
"add_member": {
|
||||
"annotation": "Added a member to a relation."
|
||||
},
|
||||
|
||||
@@ -241,15 +241,19 @@ export function modeSelect(context, selectedIDs) {
|
||||
|
||||
var operations = Object.values(Operations)
|
||||
.map(function(o) { return o(selectedIDs, context); })
|
||||
.filter(function(o) { return o.available() && o.id !== 'delete'; });
|
||||
.filter(function(o) { return o.available() && o.id !== 'delete' && o.id !== 'downgrade'; });
|
||||
|
||||
var downgradeOperation = Operations.operationDowngrade(selectedIDs, context);
|
||||
// don't allow delete if downgrade is available
|
||||
var lastOperation = downgradeOperation.available() ? downgradeOperation : Operations.operationDelete(selectedIDs, context);
|
||||
|
||||
// deprecation warning - Radial Menu to be removed in iD v3
|
||||
var isRadialMenu = context.storage('edit-menu-style') === 'radial';
|
||||
if (isRadialMenu) {
|
||||
operations = operations.slice(0,7);
|
||||
operations.unshift(Operations.operationDelete(selectedIDs, context));
|
||||
operations.unshift(lastOperation);
|
||||
} else {
|
||||
operations.push(Operations.operationDelete(selectedIDs, context));
|
||||
operations.push(lastOperation);
|
||||
}
|
||||
|
||||
operations.forEach(function(operation) {
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
import { actionChangeTags } from '../actions';
|
||||
import { behaviorOperation } from '../behavior';
|
||||
import { modeSelect } from '../modes';
|
||||
import { t } from '../util/locale';
|
||||
import { uiCmd } from '../ui';
|
||||
|
||||
|
||||
export function operationDowngrade(selectedIDs, context) {
|
||||
|
||||
var affectedFeatureCount = 0;
|
||||
var downgradeType;
|
||||
|
||||
setDowngradeTypeForEntityIDs();
|
||||
|
||||
var multi = affectedFeatureCount === 1 ? 'single' : 'multiple';
|
||||
|
||||
function setDowngradeTypeForEntityIDs() {
|
||||
for (var i in selectedIDs) {
|
||||
var entityID = selectedIDs[i];
|
||||
var type = downgradeTypeForEntityID(entityID);
|
||||
if (type) {
|
||||
affectedFeatureCount += 1;
|
||||
if (downgradeType && type !== downgradeType) {
|
||||
downgradeType = 'building_address';
|
||||
} else {
|
||||
downgradeType = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function downgradeTypeForEntityID(entityID) {
|
||||
var graph = context.graph();
|
||||
var entity = graph.entity(entityID);
|
||||
var preset = context.presets().match(entity, graph);
|
||||
|
||||
if (preset.isFallback()) return null;
|
||||
|
||||
if (entity.type === 'node' &&
|
||||
preset.id !== 'address' &&
|
||||
Object.keys(entity.tags).some(function(key) {
|
||||
return key.match(/^addr:.{1,}/);
|
||||
})) {
|
||||
|
||||
return 'address';
|
||||
}
|
||||
if (entity.geometry(graph) === 'area' &&
|
||||
entity.tags.building &&
|
||||
!preset.tags.building) {
|
||||
|
||||
return 'building';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
var buildingKeysToKeep = ['architect', 'building', 'height', 'layer', 'source', 'type', 'wheelchair'];
|
||||
var addressKeysToKeep = ['source'];
|
||||
|
||||
var operation = function () {
|
||||
context.perform(function(graph) {
|
||||
|
||||
for (var i in selectedIDs) {
|
||||
var entityID = selectedIDs[i];
|
||||
var type = downgradeTypeForEntityID(entityID);
|
||||
if (!type) continue;
|
||||
|
||||
var tags = Object.assign({}, graph.entity(entityID).tags); // shallow copy
|
||||
for (var key in tags) {
|
||||
if (type === 'address' && addressKeysToKeep.indexOf(key) !== -1) continue;
|
||||
if (type === 'building') {
|
||||
if (buildingKeysToKeep.indexOf(key) !== -1 ||
|
||||
key.match(/^building:.{1,}/) ||
|
||||
key.match(/^roof:.{1,}/)) continue;
|
||||
}
|
||||
// keep address tags for buildings too
|
||||
if (key.match(/^addr:.{1,}/)) continue;
|
||||
|
||||
delete tags[key];
|
||||
}
|
||||
graph = actionChangeTags(entityID, tags)(graph);
|
||||
}
|
||||
return graph;
|
||||
}, operation.annotation());
|
||||
|
||||
// refresh the select mode to enable the delete operation
|
||||
context.enter(modeSelect(context, selectedIDs));
|
||||
};
|
||||
|
||||
|
||||
operation.available = function () {
|
||||
return downgradeType;
|
||||
};
|
||||
|
||||
|
||||
operation.disabled = function () {
|
||||
var reason;
|
||||
if (selectedIDs.some(hasWikidataTag)) {
|
||||
reason = 'has_wikidata_tag';
|
||||
}
|
||||
function hasWikidataTag(id) {
|
||||
var entity = context.entity(id);
|
||||
return entity.tags.wikidata && entity.tags.wikidata.trim().length > 0;
|
||||
}
|
||||
return reason;
|
||||
};
|
||||
|
||||
|
||||
operation.tooltip = function () {
|
||||
var disable = operation.disabled();
|
||||
return disable ?
|
||||
t('operations.downgrade.' + disable + '.' + multi) :
|
||||
t('operations.downgrade.description.' + downgradeType);
|
||||
};
|
||||
|
||||
|
||||
operation.annotation = function () {
|
||||
var suffix;
|
||||
if (downgradeType === 'building_address') {
|
||||
suffix = 'multiple';
|
||||
} else {
|
||||
suffix = downgradeType + '.' + multi;
|
||||
}
|
||||
return t('operations.downgrade.annotation.' + suffix, { n: affectedFeatureCount});
|
||||
};
|
||||
|
||||
|
||||
operation.id = 'downgrade';
|
||||
operation.keys = [uiCmd('⌘⌫'), uiCmd('⌘⌦'), uiCmd('⌦')];
|
||||
operation.title = t('operations.downgrade.title');
|
||||
operation.behavior = behaviorOperation(context).which(operation);
|
||||
|
||||
|
||||
return operation;
|
||||
}
|
||||
@@ -2,6 +2,7 @@ export { operationCircularize } from './circularize';
|
||||
export { operationContinue } from './continue';
|
||||
export { operationDelete } from './delete';
|
||||
export { operationDisconnect } from './disconnect';
|
||||
export { operationDowngrade } from './downgrade';
|
||||
export { operationMerge } from './merge';
|
||||
export { operationMove } from './move';
|
||||
export { operationOrthogonalize } from './orthogonalize';
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="20" height="20" viewBox="0 0 20 20">
|
||||
<path d="M10,14.999 C10.453,15.014 10.695,14.905 10.949,14.663 C11.203,14.42 16.199,8.808 16.949,7.971 C17.398,7.47 17.338,6.716 16.813,6.286 C16.289,5.857 15.5,5.915 15.051,6.416 C11.367,10.524 10.683,11.236 10,11.999 C5.699,7.202 5.699,7.252 4.949,6.416 C4.5,5.915 3.711,5.857 3.187,6.286 C2.662,6.716 2.602,7.47 3.051,7.971 C8.301,13.826 8.766,14.342 9.051,14.663 C9.312,14.889 9.547,14.983 10,14.999 z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 731 B |
Reference in New Issue
Block a user