Enable the circularize operation for multiple selected features (close #7326)

This commit is contained in:
Quincy Morgan
2020-02-05 09:57:33 -05:00
parent f2638c0c1e
commit 4ff634b90f
3 changed files with 104 additions and 36 deletions
+22 -10
View File
@@ -85,17 +85,29 @@ en:
circularize:
title: Circularize
description:
line: Make this line circular.
area: Make this area circular.
single: Make this feature circular.
multiple: Make these features circular.
key: O
annotation:
line: Made a line circular.
area: Made an area circular.
not_closed: This can't be made circular because it's not a loop.
too_large: This can't be made circular because not enough of it is currently visible.
connected_to_hidden: This can't be made circular because it is connected to a hidden feature.
not_downloaded: This can't be made circular because parts of it have not yet been downloaded.
already_circular: This can't be made circular because it's already circular.
single: Made a feature circular.
multiple: Made features circular.
multiple_blockers:
multiple: These can't be made circular for multiple reasons.
not_closed:
single: This can't be made circular because it's not a loop.
multiple: These can't be made circular because they aren't loops.
too_large:
single: This can't be made circular because not enough of it is currently visible.
multiple: These can't be made circular because not enough of them are currently visible.
connected_to_hidden:
single: This can't be made circular because it is connected to a hidden feature.
multiple: These can't be made circular because some are connected to hidden features.
not_downloaded:
single: This can't be made circular because parts of it have not yet been downloaded.
multiple: These can't be made circular because parts of them have not yet been downloaded.
already_circular:
single: This can't be made more circular than it already is.
multiple: These can't be made more circular than they already are.
orthogonalize:
title: Square
description:
@@ -2067,4 +2079,4 @@ en:
wikidata:
identifier: "Identifier"
label: "Label"
description: "Description"
description: "Description"
+27 -9
View File
@@ -108,19 +108,37 @@
"circularize": {
"title": "Circularize",
"description": {
"line": "Make this line circular.",
"area": "Make this area circular."
"single": "Make this feature circular.",
"multiple": "Make these features circular."
},
"key": "O",
"annotation": {
"line": "Made a line circular.",
"area": "Made an area circular."
"single": "Made a feature circular.",
"multiple": "Made features circular."
},
"not_closed": "This can't be made circular because it's not a loop.",
"too_large": "This can't be made circular because not enough of it is currently visible.",
"connected_to_hidden": "This can't be made circular because it is connected to a hidden feature.",
"not_downloaded": "This can't be made circular because parts of it have not yet been downloaded.",
"already_circular": "This can't be made circular because it's already circular."
"multiple_blockers": {
"multiple": "These can't be made circular for multiple reasons."
},
"not_closed": {
"single": "This can't be made circular because it's not a loop.",
"multiple": "These can't be made circular because they aren't loops."
},
"too_large": {
"single": "This can't be made circular because not enough of it is currently visible.",
"multiple": "These can't be made circular because not enough of them are currently visible."
},
"connected_to_hidden": {
"single": "This can't be made circular because it is connected to a hidden feature.",
"multiple": "These can't be made circular because some are connected to hidden features."
},
"not_downloaded": {
"single": "This can't be made circular because parts of it have not yet been downloaded.",
"multiple": "These can't be made circular because parts of them have not yet been downloaded."
},
"already_circular": {
"single": "This can't be made more circular than it already is.",
"multiple": "These can't be made more circular than they already are."
}
},
"orthogonalize": {
"title": "Square",
+55 -17
View File
@@ -5,16 +5,41 @@ import { utilGetAllNodes } from '../util';
export function operationCircularize(selectedIDs, context) {
var entityID = selectedIDs[0];
var entity = context.entity(entityID);
var extent = entity.extent(context.graph());
var geometry = context.geometry(entityID);
var action = actionCircularize(entityID, context.projection);
var nodes = utilGetAllNodes(selectedIDs, context.graph());
var coords = nodes.map(function(n) { return n.loc; });
var _extent;
var _actions = selectedIDs.map(getAction).filter(Boolean);
var _amount = _actions.length === 1 ? 'single' : 'multiple';
var _coords = utilGetAllNodes(selectedIDs, context.graph())
.map(function(n) { return n.loc; });
function getAction(entityID) {
var entity = context.entity(entityID);
if (entity.type !== 'way' || new Set(entity.nodes).size <= 1) return null;
if (!_extent) {
_extent = entity.extent(context.graph());
} else {
_extent = _extent.extend(entity.extent(context.graph()));
}
return actionCircularize(entityID, context.projection);
}
var operation = function() {
context.perform(action, operation.annotation());
if (!_actions.length) return;
var combinedAction = function(graph, t) {
_actions.forEach(function(action) {
if (!action.disabled(graph)) {
graph = action(graph, t);
}
});
return graph;
};
combinedAction.transitionable = true;
context.perform(combinedAction, operation.annotation());
window.setTimeout(function() {
context.validator().validate();
@@ -23,18 +48,31 @@ export function operationCircularize(selectedIDs, context) {
operation.available = function() {
return selectedIDs.length === 1 &&
entity.type === 'way' &&
new Set(entity.nodes).size > 1;
return _actions.length && selectedIDs.length === _actions.length;
};
// don't cache this because the visible extent could change
operation.disabled = function() {
var actionDisabled = action.disabled(context.graph());
if (!_actions.length) return '';
var actionDisabled;
var actionDisableds = {};
if (_actions.every(function(action) {
var disabled = action.disabled(context.graph());
if (disabled) actionDisableds[disabled] = true;
return disabled;
})) {
actionDisabled = _actions[0].disabled(context.graph());
}
if (actionDisabled) {
if (Object.keys(actionDisableds).length > 1) {
return 'multiple_blockers';
}
return actionDisabled;
} else if (extent.percentContainedIn(context.extent()) < 0.8) {
} else if (_extent.percentContainedIn(context.extent()) < 0.8) {
return 'too_large';
} else if (someMissing()) {
return 'not_downloaded';
@@ -49,7 +87,7 @@ export function operationCircularize(selectedIDs, context) {
if (context.inIntro()) return false;
var osm = context.connection();
if (osm) {
var missing = coords.filter(function(loc) { return !osm.isDataLoaded(loc); });
var missing = _coords.filter(function(loc) { return !osm.isDataLoaded(loc); });
if (missing.length) {
missing.forEach(function(loc) { context.loadTileAtLoc(loc); });
return true;
@@ -63,13 +101,13 @@ export function operationCircularize(selectedIDs, context) {
operation.tooltip = function() {
var disable = operation.disabled();
return disable ?
t('operations.circularize.' + disable) :
t('operations.circularize.description.' + geometry);
t('operations.circularize.' + disable + '.' + _amount) :
t('operations.circularize.description.' + _amount);
};
operation.annotation = function() {
return t('operations.circularize.annotation.' + geometry);
return t('operations.circularize.annotation.' + _amount);
};