prevent most operations on things connected to hidden features..

This commit is contained in:
Bryan Housel
2014-10-11 00:58:08 -04:00
parent 8a98339bc2
commit dcc9812986
15 changed files with 102 additions and 35 deletions

View File

@@ -55,6 +55,7 @@ en:
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.
orthogonalize:
title: Square
description:
@@ -66,12 +67,14 @@ en:
area: Squared the corners of an area.
not_squarish: This can't be made square because it is not squarish.
too_large: This can't be made square because not enough of it is currently visible.
connected_to_hidden: This can't be made square because it is connected to a hidden feature.
straighten:
title: Straighten
description: Straighten this line.
key: S
annotation: Straightened a line.
too_bendy: This can't be straightened because it bends too much.
connected_to_hidden: This line can't be straightened because it is connected to a hidden feature.
delete:
title: Delete
description: Delete object permanently.
@@ -83,6 +86,7 @@ en:
relation: Deleted a relation.
multiple: "Deleted {n} objects."
incomplete_relation: This feature can't be deleted because it hasn't been fully downloaded.
connected_to_hidden: This can't be deleted because it is connected to a hidden feature.
add_member:
annotation: Added a member to a relation.
delete_member:
@@ -99,6 +103,7 @@ en:
key: D
annotation: Disconnected lines/areas.
not_connected: There aren't enough lines/areas here to disconnect.
connected_to_hidden: This can't be disconnected because it is connected to a hidden feature.
merge:
title: Merge
description: Merge these lines.
@@ -120,6 +125,7 @@ en:
multiple: Moved multiple objects.
incomplete_relation: This feature can't be moved because it hasn't been fully downloaded.
too_large: This can't be moved because not enough of it is currently visible.
connected_to_hidden: This can't be moved because it is connected to a hidden feature.
rotate:
title: Rotate
description: Rotate this object around its center point.
@@ -128,6 +134,7 @@ en:
line: Rotated a line.
area: Rotated an area.
too_large: This can't be rotated because not enough of it is currently visible.
connected_to_hidden: This can't be rotated because it is connected to a hidden feature.
reverse:
title: Reverse
description: Make this line go in the opposite direction.
@@ -146,6 +153,7 @@ en:
multiple: "Split {n} lines/area boundaries."
not_eligible: Lines can't be split at their beginning or end.
multiple_ways: There are too many lines here to split.
connected_to_hidden: This can't be split because it is connected to a hidden feature.
restriction:
help:
select: Click to select a road segment.

24
dist/locales/en.json vendored
View File

@@ -72,7 +72,8 @@
"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."
"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."
},
"orthogonalize": {
"title": "Square",
@@ -86,14 +87,16 @@
"area": "Squared the corners of an area."
},
"not_squarish": "This can't be made square because it is not squarish.",
"too_large": "This can't be made square because not enough of it is currently visible."
"too_large": "This can't be made square because not enough of it is currently visible.",
"connected_to_hidden": "This can't be made square because it is connected to a hidden feature."
},
"straighten": {
"title": "Straighten",
"description": "Straighten this line.",
"key": "S",
"annotation": "Straightened a line.",
"too_bendy": "This can't be straightened because it bends too much."
"too_bendy": "This can't be straightened because it bends too much.",
"connected_to_hidden": "This line can't be straightened because it is connected to a hidden feature."
},
"delete": {
"title": "Delete",
@@ -106,7 +109,8 @@
"relation": "Deleted a relation.",
"multiple": "Deleted {n} objects."
},
"incomplete_relation": "This feature can't be deleted because it hasn't been fully downloaded."
"incomplete_relation": "This feature can't be deleted because it hasn't been fully downloaded.",
"connected_to_hidden": "This can't be deleted because it is connected to a hidden feature."
},
"add_member": {
"annotation": "Added a member to a relation."
@@ -127,7 +131,8 @@
"description": "Disconnect these lines/areas from each other.",
"key": "D",
"annotation": "Disconnected lines/areas.",
"not_connected": "There aren't enough lines/areas here to disconnect."
"not_connected": "There aren't enough lines/areas here to disconnect.",
"connected_to_hidden": "This can't be disconnected because it is connected to a hidden feature."
},
"merge": {
"title": "Merge",
@@ -151,7 +156,8 @@
"multiple": "Moved multiple objects."
},
"incomplete_relation": "This feature can't be moved because it hasn't been fully downloaded.",
"too_large": "This can't be moved because not enough of it is currently visible."
"too_large": "This can't be moved because not enough of it is currently visible.",
"connected_to_hidden": "This can't be moved because it is connected to a hidden feature."
},
"rotate": {
"title": "Rotate",
@@ -161,7 +167,8 @@
"line": "Rotated a line.",
"area": "Rotated an area."
},
"too_large": "This can't be rotated because not enough of it is currently visible."
"too_large": "This can't be rotated because not enough of it is currently visible.",
"connected_to_hidden": "This can't be rotated because it is connected to a hidden feature."
},
"reverse": {
"title": "Reverse",
@@ -183,7 +190,8 @@
"multiple": "Split {n} lines/area boundaries."
},
"not_eligible": "Lines can't be split at their beginning or end.",
"multiple_ways": "There are too many lines here to split."
"multiple_ways": "There are too many lines here to split.",
"connected_to_hidden": "This can't be split because it is connected to a hidden feature."
},
"restriction": {
"help": {

View File

@@ -72,8 +72,10 @@ iD.Graph.prototype = {
return this._childNodes[entity.id];
var nodes = [];
for (var i = 0, l = entity.nodes.length; i < l; i++) {
nodes[i] = this.entity(entity.nodes[i]);
if (entity.nodes) {
for (var i = 0, l = entity.nodes.length; i < l; i++) {
nodes[i] = this.entity(entity.nodes[i]);
}
}
if (iD.debug) Object.freeze(nodes);

View File

@@ -206,6 +206,10 @@ window.iD = function () {
/* Features */
var features = iD.Features(context);
context.features = function() { return features; };
context.hasHiddenConnections = function(id) {
var entity = history.graph().entity(id);
return features.hasHiddenConnections(entity);
};
/* Map */
var map = iD.Map(context);

View File

@@ -48,7 +48,7 @@ iD.modes.DragNode = function(context) {
}
function start(entity) {
cancelled = d3.event.sourceEvent.shiftKey;
cancelled = d3.event.sourceEvent.shiftKey || context.features().hasHiddenConnections(entity);
if (cancelled) return behavior.cancel();
wasMidpoint = entity.type === 'midpoint';

View File

@@ -20,6 +20,8 @@ iD.operations.Circularize = function(selectedIDs, context) {
var reason;
if (extent.percentContainedIn(context.extent()) < 0.8) {
reason = 'too_large';
} else if (context.hasHiddenConnections(entityId)) {
reason = 'connected_to_hidden';
}
return action.disabled(context.graph()) || reason;
};

View File

@@ -23,7 +23,8 @@ iD.operations.Continue = function(selectedIDs, context) {
};
operation.available = function() {
return geometries.vertex.length === 1 && geometries.line.length <= 1;
return geometries.vertex.length === 1 && geometries.line.length <= 1 &&
!context.features().hasHiddenConnections(vertex);
};
operation.disabled = function() {

View File

@@ -52,7 +52,11 @@ iD.operations.Delete = function(selectedIDs, context) {
};
operation.disabled = function() {
return action.disabled(context.graph());
var reason;
if (_.any(selectedIDs, context.hasHiddenConnections)) {
reason = 'connected_to_hidden';
}
return action.disabled(context.graph()) || reason;
};
operation.tooltip = function() {

View File

@@ -19,7 +19,11 @@ iD.operations.Disconnect = function(selectedIDs, context) {
};
operation.disabled = function() {
return action.disabled(context.graph());
var reason;
if (_.any(selectedIDs, context.hasHiddenConnections)) {
reason = 'connected_to_hidden';
}
return action.disabled(context.graph()) || reason;
};
operation.tooltip = function() {

View File

@@ -16,6 +16,8 @@ iD.operations.Move = function(selectedIDs, context) {
var reason;
if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
reason = 'too_large';
} else if (_.any(selectedIDs, context.hasHiddenConnections)) {
reason = 'connected_to_hidden';
}
return iD.actions.Move(selectedIDs).disabled(context.graph()) || reason;
};

View File

@@ -21,6 +21,8 @@ iD.operations.Orthogonalize = function(selectedIDs, context) {
var reason;
if (extent.percentContainedIn(context.extent()) < 0.8) {
reason = 'too_large';
} else if (context.hasHiddenConnections(entityId)) {
reason = 'connected_to_hidden';
}
return action.disabled(context.graph()) || reason;
};

View File

@@ -22,6 +22,8 @@ iD.operations.Rotate = function(selectedIDs, context) {
operation.disabled = function() {
if (extent.percentContainedIn(context.extent()) < 0.8) {
return 'too_large';
} else if (context.hasHiddenConnections(entityId)) {
return 'connected_to_hidden';
} else {
return false;
}

View File

@@ -29,7 +29,11 @@ iD.operations.Split = function(selectedIDs, context) {
};
operation.disabled = function() {
return action.disabled(context.graph());
var reason;
if (_.any(selectedIDs, context.hasHiddenConnections)) {
reason = 'connected_to_hidden';
}
return action.disabled(context.graph()) || reason;
};
operation.tooltip = function() {

View File

@@ -16,7 +16,11 @@ iD.operations.Straighten = function(selectedIDs, context) {
};
operation.disabled = function() {
return action.disabled(context.graph());
var reason;
if (context.hasHiddenConnections(entityId)) {
reason = 'connected_to_hidden';
}
return action.disabled(context.graph()) || reason;
};
operation.tooltip = function() {

View File

@@ -41,8 +41,7 @@ iD.Features = function(context) {
'obliterated': true
};
var graph = context.graph(),
dispatch = d3.dispatch('change', 'redraw'),
var dispatch = d3.dispatch('change', 'redraw'),
feature = {};
function defineFeature(k, filter, max) {
@@ -64,24 +63,24 @@ iD.Features = function(context) {
}
defineFeature('points', function(entity) {
return entity.geometry(graph) === 'point';
return entity.geometry(context.graph()) === 'point';
}, 100);
defineFeature('major_roads', function(entity) {
return entity.geometry(graph) === 'line' && major_roads[entity.tags.highway];
return entity.geometry(context.graph()) === 'line' && major_roads[entity.tags.highway];
});
defineFeature('minor_roads', function(entity) {
return entity.geometry(graph) === 'line' && minor_roads[entity.tags.highway];
return entity.geometry(context.graph()) === 'line' && minor_roads[entity.tags.highway];
});
defineFeature('paths', function(entity) {
return entity.geometry(graph) === 'line' && paths[entity.tags.highway];
return entity.geometry(context.graph()) === 'line' && paths[entity.tags.highway];
});
defineFeature('buildings', function(entity) {
return (
entity.geometry(graph) === 'area' && (
entity.geometry(context.graph()) === 'area' && (
(!!entity.tags.building && entity.tags.building !== 'no') ||
entity.tags.amenity === 'shelter' ||
entity.tags.parking === 'multi-storey' ||
@@ -93,7 +92,7 @@ iD.Features = function(context) {
}, 100);
defineFeature('landuse', function(entity) {
return entity.geometry(graph) === 'area' &&
return entity.geometry(context.graph()) === 'area' &&
!feature.buildings.filter(entity) &&
!feature.water.filter(entity);
});
@@ -138,8 +137,8 @@ iD.Features = function(context) {
// lines or areas that don't match another feature filter.
defineFeature('others', function(entity) {
return (
entity.geometry(graph) === 'line' ||
entity.geometry(graph) === 'area'
entity.geometry(context.graph()) === 'line' ||
entity.geometry(context.graph()) === 'area'
) &&
_.reduce(_.omit(feature, 'others'), function(result, v) {
return result && !v.filter(entity);
@@ -244,17 +243,38 @@ iD.Features = function(context) {
return stats;
};
features.isHidden = function(entity) {
var hidden = features.hidden();
features.isHiddenFeature = function(entity) {
return _.any(features.hidden(), function(k) { return feature[k].filter(entity); });
};
function isHiddenFeature(entity) {
return _.any(hidden, function(k) { return feature[k].filter(entity); });
features.isHiddenChild = function(entity) {
var g = context.graph(),
parents = _.union(g.parentWays(entity), g.parentRelations(entity));
return parents.length ? _.all(parents, features.isHidden) : false;
};
features.hasHiddenConnections = function(entity) {
var g = context.graph(),
childNodes, connections;
if (entity.type === 'midpoint') {
childNodes = [context.entity(entity.edge[0]), context.entity(entity.edge[1])];
} else {
childNodes = g.childNodes(entity);
}
function isHiddenChild(entity) {
var parents = _.union(graph.parentWays(entity), graph.parentRelations(entity));
return parents.length ? _.all(parents, features.isHidden) : false;
}
return isHiddenFeature(entity) || isHiddenChild(entity);
// gather parents..
connections = _.union(g.parentWays(entity), g.parentRelations(entity));
// gather ways connected to child nodes..
connections = _.reduce(childNodes, function(result, e) {
return g.isShared(e) ? _.union(result, g.parentWays(e)) : result;
}, connections);
return connections.length ? _.any(connections, features.isHidden) : false;
};
features.isHidden = function(entity) {
return features.isHiddenFeature(entity) || features.isHiddenChild(entity);
};
features.filter = function(d) {