mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-25 17:37:49 +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:
@@ -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';
|
||||
|
||||
Reference in New Issue
Block a user