mirror of
https://github.com/FoggedLens/iD.git
synced 2026-04-21 19:26:41 +02:00
Add ability to ignore warnings
Replace issue's array of entities with array of entity IDs Improve issue ID hashing
This commit is contained in:
@@ -1442,6 +1442,8 @@ en:
|
||||
title: Continue drawing from end
|
||||
delete_feature:
|
||||
title: Delete this feature
|
||||
ignore_issue:
|
||||
title: Ignore this issue
|
||||
move_tags:
|
||||
title: Move the tags
|
||||
annotation: Moved tags.
|
||||
|
||||
Vendored
+3
@@ -1793,6 +1793,9 @@
|
||||
"delete_feature": {
|
||||
"title": "Delete this feature"
|
||||
},
|
||||
"ignore_issue": {
|
||||
"title": "Ignore this issue"
|
||||
},
|
||||
"move_tags": {
|
||||
"title": "Move the tags",
|
||||
"annotation": "Moved tags."
|
||||
|
||||
@@ -7,10 +7,10 @@ export function validationIssue(attrs) {
|
||||
this.severity = attrs.severity; // required - 'warning' or 'error'
|
||||
this.message = attrs.message; // required - localized string
|
||||
this.reference = attrs.reference; // optional - function(selection) to render reference information
|
||||
this.entities = attrs.entities; // optional - array of entities involved in the issue
|
||||
this.entityIds = attrs.entityIds; // optional - array of IDs of entities involved in the issue
|
||||
this.loc = attrs.loc; // optional - [lon, lat] to zoom in on to see the issue
|
||||
this.data = attrs.data; // optional - object containing extra data for the fixes
|
||||
this.fixes = attrs.fixes; // optional - array of validationIssueFix objects
|
||||
this.fixes = attrs.fixes || []; // optional - array of validationIssueFix objects
|
||||
this.hash = attrs.hash; // optional - string to further differentiate the issue
|
||||
|
||||
this.id = generateID.apply(this); // generated - see below
|
||||
@@ -25,10 +25,14 @@ export function validationIssue(attrs) {
|
||||
parts.push(this.hash);
|
||||
}
|
||||
|
||||
if (this.subtype) {
|
||||
parts.push(this.subtype);
|
||||
}
|
||||
|
||||
// include entities this issue is for
|
||||
// (sort them so the id is deterministic)
|
||||
if (this.entities) {
|
||||
var entityKeys = this.entities.map(osmEntity.key).sort();
|
||||
if (this.entityIds) {
|
||||
var entityKeys = this.entityIds.slice().sort();
|
||||
parts.push.apply(parts, entityKeys);
|
||||
}
|
||||
|
||||
@@ -48,9 +52,9 @@ export function validationIssue(attrs) {
|
||||
if (this.loc) {
|
||||
return _extent = geoExtent(this.loc);
|
||||
}
|
||||
if (this.entities && this.entities.length) {
|
||||
return _extent = this.entities.reduce(function(extent, entity) {
|
||||
return extent.extend(entity.extent(resolver));
|
||||
if (this.entityIds && this.entityIds.length) {
|
||||
return _extent = this.entityIds.reduce(function(extent, entityId) {
|
||||
return extent.extend(resolver.entity(entityId).extent(resolver));
|
||||
}, geoExtent());
|
||||
}
|
||||
return null;
|
||||
|
||||
+43
-19
@@ -2,6 +2,8 @@ import { dispatch as d3_dispatch } from 'd3-dispatch';
|
||||
|
||||
import { coreDifference } from './difference';
|
||||
import { utilArrayGroupBy, utilCallWhenIdle, utilRebind } from '../util';
|
||||
import { t } from '../util/locale';
|
||||
import { validationIssueFix } from './validation/models';
|
||||
import * as Validations from '../validations/index';
|
||||
|
||||
|
||||
@@ -12,6 +14,7 @@ export function coreValidator(context) {
|
||||
var _rules = {};
|
||||
var _disabledRules = {};
|
||||
|
||||
var _ignoredIssueIDs = {}; // issue.id -> true
|
||||
var _issuesByIssueID = {}; // issue.id -> issue
|
||||
var _issuesByEntityID = {}; // entity.id -> set(issue.id)
|
||||
var _validatedGraph = null;
|
||||
@@ -57,9 +60,10 @@ export function coreValidator(context) {
|
||||
// options = {
|
||||
// what: 'edited', // 'all' or 'edited'
|
||||
// where: 'visible', // 'all' or 'visible'
|
||||
// includeIgnored: false // true or false
|
||||
// };
|
||||
validator.getIssues = function(options) {
|
||||
var opts = Object.assign({ what: 'all', where: 'all' }, options);
|
||||
var opts = Object.assign({ what: 'all', where: 'all', includeIgnored: false }, options);
|
||||
var issues = Object.values(_issuesByIssueID);
|
||||
var changes = context.history().difference().changes();
|
||||
var view = context.map().extent();
|
||||
@@ -69,19 +73,21 @@ export function coreValidator(context) {
|
||||
|
||||
// Sanity check: This issue may be for an entity that not longer exists.
|
||||
// If we detect this, uncache and return false so it is not incluced..
|
||||
var entities = issue.entities || [];
|
||||
for (var i = 0; i < entities.length; i++) {
|
||||
var entity = entities[i];
|
||||
if (!context.hasEntity(entity.id)) {
|
||||
delete _issuesByEntityID[entity.id];
|
||||
delete _issuesByIssueID[issue.id];
|
||||
var entityIds = issue.entityIds || [];
|
||||
for (var i = 0; i < entityIds.length; i++) {
|
||||
var entityId = entityIds[i];
|
||||
if (!context.hasEntity(entityId)) {
|
||||
delete _issuesByEntityID[entityId];
|
||||
delete _issuesByIssueID[entityId];
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!opts.includeIgnored && _ignoredIssueIDs[issue.id]) return false;
|
||||
|
||||
if (opts.what === 'edited') {
|
||||
var isEdited = entities.some(function(entity) { return changes[entity.id]; });
|
||||
if (entities.length && !isEdited) return false;
|
||||
var isEdited = entityIds.some(function(entityId) { return changes[entityId]; });
|
||||
if (entityIds.length && !isEdited) return false;
|
||||
}
|
||||
|
||||
if (opts.where === 'visible') {
|
||||
@@ -108,7 +114,7 @@ export function coreValidator(context) {
|
||||
|
||||
return Array.from(issueIDs)
|
||||
.map(function(id) { return _issuesByIssueID[id]; })
|
||||
.filter(function(issue) { return !_disabledRules[issue.type]; });
|
||||
.filter(function(issue) { return !_disabledRules[issue.type] && !_ignoredIssueIDs[issue.id]; });
|
||||
};
|
||||
|
||||
|
||||
@@ -158,10 +164,10 @@ export function coreValidator(context) {
|
||||
if (issue) {
|
||||
// When multiple entities are involved (e.g. crossing_ways),
|
||||
// remove this issue from the other entity caches too..
|
||||
var entities = issue.entities || [];
|
||||
entities.forEach(function(other) {
|
||||
if (other.id !== entityID) {
|
||||
var otherIssueIDs = _issuesByEntityID[other.id];
|
||||
var entityIds = issue.entityIds || [];
|
||||
entityIds.forEach(function(other) {
|
||||
if (other !== entityID) {
|
||||
var otherIssueIDs = _issuesByEntityID[other];
|
||||
if (otherIssueIDs) {
|
||||
otherIssueIDs.delete(issueID);
|
||||
}
|
||||
@@ -176,6 +182,11 @@ export function coreValidator(context) {
|
||||
}
|
||||
|
||||
|
||||
function ignoreIssue(id) {
|
||||
_ignoredIssueIDs[id] = true;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Run validation on a single entity
|
||||
//
|
||||
@@ -196,6 +207,19 @@ export function coreValidator(context) {
|
||||
}
|
||||
|
||||
var detected = fn(entity, context);
|
||||
detected.forEach(function(issue) {
|
||||
if (issue.severity === 'warning') {
|
||||
var ignoreFix = new validationIssueFix({
|
||||
title: t('issues.fix.ignore_issue.title'),
|
||||
icon: 'iD-icon-close',
|
||||
onClick: function() {
|
||||
ignoreIssue(this.issue.id);
|
||||
}
|
||||
});
|
||||
ignoreFix.issue = issue;
|
||||
issue.fixes.push(ignoreFix);
|
||||
}
|
||||
});
|
||||
entityIssues = entityIssues.concat(detected);
|
||||
ran[key] = true;
|
||||
return !detected.length;
|
||||
@@ -278,12 +302,12 @@ export function coreValidator(context) {
|
||||
var issues = validateEntity(entity);
|
||||
|
||||
issues.forEach(function(issue) {
|
||||
var entities = issue.entities || [];
|
||||
entities.forEach(function(entity) {
|
||||
if (!_issuesByEntityID[entity.id]) {
|
||||
_issuesByEntityID[entity.id] = new Set();
|
||||
var entityIds = issue.entityIds || [];
|
||||
entityIds.forEach(function(entityId) {
|
||||
if (!_issuesByEntityID[entityId]) {
|
||||
_issuesByEntityID[entityId] = new Set();
|
||||
}
|
||||
_issuesByEntityID[entity.id].add(issue.id);
|
||||
_issuesByEntityID[entityId].add(issue.id);
|
||||
});
|
||||
_issuesByIssueID[issue.id] = issue;
|
||||
});
|
||||
|
||||
@@ -222,7 +222,7 @@ export default {
|
||||
type: 'maprules',
|
||||
severity: severity,
|
||||
message: selector[severity],
|
||||
entities: [entity],
|
||||
entityIds: [entity.id],
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ export function uiCommit(context) {
|
||||
|
||||
// add counts of warnings generated by the user's edits
|
||||
var warnings = context.validator()
|
||||
.getIssuesBySeverity({ what: 'edited', where: 'all' }).warning;
|
||||
.getIssuesBySeverity({ what: 'edited', where: 'all', includeIgnored: true }).warning;
|
||||
|
||||
var warningsByType = utilArrayGroupBy(warnings, 'type');
|
||||
for (var warningType in warningsByType) {
|
||||
|
||||
@@ -67,10 +67,10 @@ export function uiCommitWarnings(context) {
|
||||
|
||||
items
|
||||
.on('mouseover', function(d) {
|
||||
if (d.entities) {
|
||||
if (d.entityIds) {
|
||||
context.surface().selectAll(
|
||||
utilEntityOrMemberSelector(
|
||||
d.entities.map(function(e) { return e.id; }),
|
||||
d.entityIds,
|
||||
context.graph()
|
||||
)
|
||||
).classed('hover', true);
|
||||
@@ -81,12 +81,9 @@ export function uiCommitWarnings(context) {
|
||||
.classed('hover', false);
|
||||
})
|
||||
.on('click', function(d) {
|
||||
if (d.entities && d.entities.length > 0) {
|
||||
context.map().zoomTo(d.entities[0]);
|
||||
context.enter(modeSelect(
|
||||
context,
|
||||
d.entities.map(function(e) { return e.id; })
|
||||
));
|
||||
if (d.entityIds && d.entityIds.length > 0) {
|
||||
context.map().zoomTo(context.entity(d.entityIds[0]));
|
||||
context.enter(modeSelect(context, d.entityIds));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -66,16 +66,14 @@ export function uiEntityIssues(context) {
|
||||
.attr('class', function(d) { return 'issue severity-' + d.severity; })
|
||||
.on('mouseover.highlight', function(d) {
|
||||
// don't hover-highlight the selected entity
|
||||
var ids = d.entities
|
||||
.filter(function(e) { return e.id !== _entityID; })
|
||||
.map(function(e) { return e.id; });
|
||||
var ids = d.entityIds
|
||||
.filter(function(e) { return e !== _entityID; });
|
||||
|
||||
utilHighlightEntities(ids, true, context);
|
||||
})
|
||||
.on('mouseout.highlight', function(d) {
|
||||
var ids = d.entities
|
||||
.filter(function(e) { return e.id !== _entityID; })
|
||||
.map(function(e) { return e.id; });
|
||||
var ids = d.entityIds
|
||||
.filter(function(e) { return e !== _entityID; });
|
||||
|
||||
utilHighlightEntities(ids, false, context);
|
||||
});
|
||||
@@ -189,7 +187,7 @@ export function uiEntityIssues(context) {
|
||||
})
|
||||
.on('click', function(d) {
|
||||
if (d.onClick) {
|
||||
var issueEntityIDs = d.issue.entities.map(function(e) { return e.id; });
|
||||
var issueEntityIDs = d.issue.entityIds;
|
||||
utilHighlightEntities(issueEntityIDs.concat(d.entityIds), false, context);
|
||||
d.onClick();
|
||||
context.validator().validate();
|
||||
|
||||
@@ -90,9 +90,9 @@ export function uiIssues(context) {
|
||||
context.map().centerZoomEase(extent.center(), setZoom);
|
||||
|
||||
// select the first entity
|
||||
if (d.entities && d.entities.length) {
|
||||
if (d.entityIds && d.entityIds.length) {
|
||||
window.setTimeout(function() {
|
||||
var ids = d.entities.map(function(e) { return e.id; });
|
||||
var ids = d.entityIds;
|
||||
context.enter(modeSelect(context, [ids[0]]));
|
||||
utilHighlightEntities(ids, true, context);
|
||||
}, 250); // after ease
|
||||
@@ -100,12 +100,10 @@ export function uiIssues(context) {
|
||||
}
|
||||
})
|
||||
.on('mouseover', function(d) {
|
||||
var ids = d.entities.map(function(e) { return e.id; });
|
||||
utilHighlightEntities(ids, true, context);
|
||||
utilHighlightEntities(d.entityIds, true, context);
|
||||
})
|
||||
.on('mouseout', function(d) {
|
||||
var ids = d.entities.map(function(e) { return e.id; });
|
||||
utilHighlightEntities(ids, false, context);
|
||||
utilHighlightEntities(d.entityIds, false, context);
|
||||
});
|
||||
|
||||
|
||||
@@ -147,7 +145,7 @@ export function uiIssues(context) {
|
||||
d3_event.preventDefault();
|
||||
d3_event.stopPropagation();
|
||||
|
||||
var issuesEntityIDs = d.issue.entities.map(function(e) { return e.id; });
|
||||
var issuesEntityIDs = d.issue.entityIds;
|
||||
utilHighlightEntities(issuesEntityIDs.concat(d.entityIds), false, context);
|
||||
|
||||
context.perform.apply(context, d.autoArgs);
|
||||
|
||||
@@ -47,10 +47,11 @@ export function validationAlmostJunction() {
|
||||
icon: 'iD-icon-abutment',
|
||||
title: t('issues.fix.connect_features.title'),
|
||||
onClick: function() {
|
||||
var endNode = this.issue.entities[1];
|
||||
var endNodeId = this.issue.entityIds[1];
|
||||
var endNode = context.entity(endNodeId);
|
||||
var targetEdge = this.issue.data.edge;
|
||||
var crossLoc = this.issue.data.cross_loc;
|
||||
var edgeNodes = [context.graph().entity(targetEdge[0]), context.graph().entity(targetEdge[1])];
|
||||
var edgeNodes = [context.entity(targetEdge[0]), context.entity(targetEdge[1])];
|
||||
var closestNodeInfo = geoSphericalClosestNode(edgeNodes, crossLoc);
|
||||
|
||||
var annotation = t('issues.fix.connect_almost_junction.annotation');
|
||||
@@ -76,7 +77,7 @@ export function validationAlmostJunction() {
|
||||
icon: 'maki-barrier',
|
||||
title: t('issues.fix.tag_as_disconnected.title'),
|
||||
onClick: function() {
|
||||
var nodeID = this.issue.entities[1].id;
|
||||
var nodeID = this.issue.entityIds[1];
|
||||
context.perform(
|
||||
actionChangeTags(nodeID, { noexit: 'yes' }),
|
||||
t('issues.fix.tag_as_disconnected.annotation')
|
||||
@@ -93,7 +94,7 @@ export function validationAlmostJunction() {
|
||||
feature2: utilDisplayLabel(edgeHighway, context)
|
||||
}),
|
||||
reference: showReference,
|
||||
entities: [entity, node, edgeHighway],
|
||||
entityIds: [entity.id, node.id, edgeHighway.id],
|
||||
loc: extendableNodeInfo.node.loc,
|
||||
data: {
|
||||
edge: extendableNodeInfo.edge,
|
||||
|
||||
@@ -489,7 +489,9 @@ export function validationCrossingWays() {
|
||||
severity: 'warning',
|
||||
message: t('issues.crossing_ways.message', messageDict),
|
||||
reference: showReference,
|
||||
entities: entities,
|
||||
entityIds: entities.map(function(entity) {
|
||||
return entity.id;
|
||||
}),
|
||||
data: {
|
||||
edges: crossing.edges,
|
||||
connectionTags: connectionTags
|
||||
@@ -521,8 +523,8 @@ export function validationCrossingWays() {
|
||||
if (selectedIDs.length !== 1) return;
|
||||
|
||||
var selectedID = selectedIDs[0];
|
||||
if (!this.issue.entities.some(function(entity) {
|
||||
return entity.id === selectedID;
|
||||
if (!this.issue.entityIds.some(function(entityId) {
|
||||
return entityId === selectedID;
|
||||
})) return;
|
||||
|
||||
var entity = context.hasEntity(selectedID);
|
||||
|
||||
@@ -69,7 +69,7 @@ export function validationDisconnectedWay() {
|
||||
title: t('issues.fix.delete_feature.title'),
|
||||
entityIds: [entity.id],
|
||||
onClick: function() {
|
||||
var id = this.issue.entities[0].id;
|
||||
var id = this.issue.entityIds[0];
|
||||
var operation = operationDelete([id], context);
|
||||
if (!operation.disabled()) {
|
||||
operation();
|
||||
@@ -83,7 +83,7 @@ export function validationDisconnectedWay() {
|
||||
severity: 'warning',
|
||||
message: t('issues.disconnected_way.highway.message', { highway: entityLabel }),
|
||||
reference: showReference,
|
||||
entities: [entity],
|
||||
entityIds: [entity.id],
|
||||
fixes: fixes
|
||||
})];
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ export function validationFixmeTag() {
|
||||
severity: 'warning',
|
||||
message: t('issues.fixme_tag.message', { feature: utilDisplayLabel(entity, context) }),
|
||||
reference: showReference,
|
||||
entities: [entity]
|
||||
entityIds: [entity.id]
|
||||
})];
|
||||
|
||||
function showReference(selection) {
|
||||
|
||||
@@ -59,17 +59,19 @@ export function validationGenericName() {
|
||||
severity: 'warning',
|
||||
message: t('issues.generic_name.message', {feature: preset.name(), name: generic}),
|
||||
reference: showReference,
|
||||
entities: [entity],
|
||||
entityIds: [entity.id],
|
||||
hash: generic,
|
||||
fixes: [
|
||||
new validationIssueFix({
|
||||
icon: 'iD-operation-delete',
|
||||
title: t('issues.fix.remove_generic_name.title'),
|
||||
onClick: function() {
|
||||
var entity = this.issue.entities[0];
|
||||
var entityId = this.issue.entityIds[0];
|
||||
var entity = context.entity(entityId);
|
||||
var tags = Object.assign({}, entity.tags); // shallow copy
|
||||
delete tags.name;
|
||||
context.perform(
|
||||
actionChangeTags(entity.id, tags),
|
||||
actionChangeTags(entityId, tags),
|
||||
t('issues.fix.remove_generic_name.annotation')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ export function validationImpossibleOneway() {
|
||||
title: t('issues.fix.reverse_feature.title'),
|
||||
entityIds: [way.id],
|
||||
onClick: function() {
|
||||
var id = this.issue.entities[0].id;
|
||||
var id = this.issue.entityIds[0];
|
||||
context.perform(actionReverse(id), t('operations.reverse.annotation'));
|
||||
}
|
||||
}));
|
||||
@@ -108,8 +108,8 @@ export function validationImpossibleOneway() {
|
||||
icon: 'iD-operation-continue' + (isFirst ? '-left' : ''),
|
||||
title: t('issues.fix.continue_from_' + (isFirst ? 'start' : 'end') + '.title'),
|
||||
onClick: function() {
|
||||
var entityID = this.issue.entities[0].id;
|
||||
var vertexID = this.issue.entities[1].id;
|
||||
var entityID = this.issue.entityIds[0];
|
||||
var vertexID = this.issue.entityIds[1];
|
||||
var way = context.entity(entityID);
|
||||
var vertex = context.entity(vertexID);
|
||||
continueDrawing(way, vertex, context);
|
||||
@@ -120,7 +120,7 @@ export function validationImpossibleOneway() {
|
||||
var placement = isFirst ? 'start' : 'end',
|
||||
messageID = wayType + '.',
|
||||
referenceID = wayType + '.';
|
||||
|
||||
|
||||
if (isWaterway) {
|
||||
messageID += 'connected.' + placement;
|
||||
referenceID += 'connected';
|
||||
@@ -137,7 +137,7 @@ export function validationImpossibleOneway() {
|
||||
feature: utilDisplayLabel(way, context)
|
||||
}),
|
||||
reference: getReference(referenceID),
|
||||
entities: [way, node],
|
||||
entityIds: [way.id, node.id],
|
||||
fixes: fixes
|
||||
})];
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ export function validationIncompatibleSource() {
|
||||
feature: utilDisplayLabel(entity, context),
|
||||
}),
|
||||
reference: getReference(invalidSource.id),
|
||||
entities: [entity],
|
||||
entityIds: [entity.id],
|
||||
fixes: [
|
||||
new validationIssueFix({
|
||||
title: t('issues.fix.remove_proprietary_data.title')
|
||||
|
||||
@@ -46,10 +46,11 @@ export function validationMissingRole() {
|
||||
relation: utilDisplayLabel(relation, context),
|
||||
}),
|
||||
reference: showReference,
|
||||
entities: [relation, way],
|
||||
entityIds: [relation.id, way.id],
|
||||
data: {
|
||||
member: member
|
||||
},
|
||||
hash: member.index.toString(),
|
||||
fixes: [
|
||||
makeAddRoleFix('inner', context),
|
||||
makeAddRoleFix('outer', context),
|
||||
@@ -58,7 +59,7 @@ export function validationMissingRole() {
|
||||
title: t('issues.fix.remove_from_relation.title'),
|
||||
onClick: function() {
|
||||
context.perform(
|
||||
actionDeleteMember(this.issue.entities[0].id, this.issue.data.member.index),
|
||||
actionDeleteMember(this.issue.entityIds[0], this.issue.data.member.index),
|
||||
t('operations.delete_member.annotation')
|
||||
);
|
||||
}
|
||||
@@ -83,9 +84,9 @@ export function validationMissingRole() {
|
||||
title: t('issues.fix.set_as_' + role + '.title'),
|
||||
onClick: function() {
|
||||
var oldMember = this.issue.data.member;
|
||||
var member = { id: this.issue.entities[1].id, type: oldMember.type, role: role };
|
||||
var member = { id: this.issue.entityIds[1], type: oldMember.type, role: role };
|
||||
context.perform(
|
||||
actionChangeMember(this.issue.entities[0].id, member, oldMember.index),
|
||||
actionChangeMember(this.issue.entityIds[0], member, oldMember.index),
|
||||
t('operations.change_role.annotation')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ export function validationMissingTag() {
|
||||
icon: 'iD-operation-delete',
|
||||
title: t('issues.fix.delete_feature.title'),
|
||||
onClick: function() {
|
||||
var id = this.issue.entities[0].id;
|
||||
var id = this.issue.entityIds[0];
|
||||
var operation = operationDelete([id], context);
|
||||
if (!operation.disabled()) {
|
||||
operation();
|
||||
@@ -113,7 +113,7 @@ export function validationMissingTag() {
|
||||
severity: severity,
|
||||
message: t('issues.' + messageID + '.message', messageObj),
|
||||
reference: showReference,
|
||||
entities: [entity],
|
||||
entityIds: [entity.id],
|
||||
fixes: fixes
|
||||
})];
|
||||
|
||||
|
||||
@@ -70,7 +70,8 @@ export function validationOutdatedTags() {
|
||||
severity: 'warning',
|
||||
message: t('issues.outdated_tags.message', { feature: utilDisplayLabel(entity, context) }),
|
||||
reference: showReference,
|
||||
entities: [entity],
|
||||
entityIds: [entity.id],
|
||||
hash: JSON.stringify(tagDiff),
|
||||
fixes: [
|
||||
new validationIssueFix({
|
||||
autoArgs: [doUpgrade, t('issues.fix.upgrade_tags.annotation')],
|
||||
@@ -143,7 +144,7 @@ export function validationOutdatedTags() {
|
||||
severity: 'warning',
|
||||
message: t('issues.old_multipolygon.message', { multipolygon: multipolygonLabel }),
|
||||
reference: showReference,
|
||||
entities: [outerWay, multipolygon],
|
||||
entityIds: [outerWay.id, multipolygon.id],
|
||||
fixes: [
|
||||
new validationIssueFix({
|
||||
autoArgs: [doUpgrade, t('issues.fix.move_tags.annotation')],
|
||||
|
||||
@@ -65,7 +65,7 @@ export function validationPrivateData() {
|
||||
feature: utilDisplayLabel(entity, context),
|
||||
}),
|
||||
reference: showReference,
|
||||
entities: [entity],
|
||||
entityIds: [entity.id],
|
||||
data: {
|
||||
newTags: keepTags
|
||||
},
|
||||
@@ -74,7 +74,7 @@ export function validationPrivateData() {
|
||||
icon: 'iD-operation-delete',
|
||||
title: t('issues.fix.' + fixID + '.title'),
|
||||
onClick: function() {
|
||||
var entityID = this.issue.entities[0].id;
|
||||
var entityID = this.issue.entityIds[0];
|
||||
var newTags = this.issue.data.newTags;
|
||||
context.perform(
|
||||
actionChangeTags(entityID, newTags),
|
||||
|
||||
@@ -43,7 +43,7 @@ export function validationTagSuggestsArea() {
|
||||
// make sure this will not create a self-intersection
|
||||
if (!geoHasSelfIntersections(testNodes, testNodes[0].id)) {
|
||||
connectEndpointsOnClick = function() {
|
||||
var way = this.issue.entities[0];
|
||||
var way = context.entity(this.issue.entityIds[0]);
|
||||
context.perform(
|
||||
actionMergeNodes([way.nodes[0], way.nodes[way.nodes.length-1]], nodes[0].loc),
|
||||
t('issues.fix.connect_endpoints.annotation')
|
||||
@@ -59,11 +59,12 @@ export function validationTagSuggestsArea() {
|
||||
// make sure this will not create a self-intersection
|
||||
if (!geoHasSelfIntersections(testNodes, testNodes[0].id)) {
|
||||
connectEndpointsOnClick = function() {
|
||||
var way = this.issue.entities[0];
|
||||
var wayId = this.issue.entityIds[0];
|
||||
var way = context.entity(wayId);
|
||||
var nodeId = way.nodes[0];
|
||||
var index = way.nodes.length;
|
||||
context.perform(
|
||||
actionAddVertex(way.id, nodeId, index),
|
||||
actionAddVertex(wayId, nodeId, index),
|
||||
t('issues.fix.connect_endpoints.annotation')
|
||||
);
|
||||
};
|
||||
@@ -80,13 +81,14 @@ export function validationTagSuggestsArea() {
|
||||
icon: 'iD-operation-delete',
|
||||
title: t('issues.fix.remove_tag.title'),
|
||||
onClick: function() {
|
||||
var entity = this.issue.entities[0];
|
||||
var entityId = this.issue.entityIds[0];
|
||||
var entity = context.entity(entityId);
|
||||
var tags = Object.assign({}, entity.tags); // shallow copy
|
||||
for (var key in tagSuggestingArea) {
|
||||
delete tags[key];
|
||||
}
|
||||
context.perform(
|
||||
actionChangeTags(entity.id, tags),
|
||||
actionChangeTags(entityId, tags),
|
||||
t('issues.fix.remove_tag.annotation')
|
||||
);
|
||||
}
|
||||
@@ -98,7 +100,8 @@ export function validationTagSuggestsArea() {
|
||||
severity: 'warning',
|
||||
message: t('issues.tag_suggests_area.message', { feature: featureLabel, tag: tagText }),
|
||||
reference: showReference,
|
||||
entities: [entity],
|
||||
entityIds: [entity.id],
|
||||
hash: JSON.stringify(tagSuggestingArea),
|
||||
fixes: fixes
|
||||
})];
|
||||
|
||||
|
||||
@@ -58,14 +58,14 @@ export function validationUnsquareWay() {
|
||||
context.validator().validate();
|
||||
};
|
||||
|
||||
return new validationIssue({
|
||||
return [new validationIssue({
|
||||
type: type,
|
||||
severity: 'warning',
|
||||
message: t('issues.unsquare_way.message', {
|
||||
feature: utilDisplayLabel(entity, context)
|
||||
}),
|
||||
reference: showReference,
|
||||
entities: [entity],
|
||||
entityIds: [entity.id],
|
||||
fixes: [
|
||||
new validationIssueFix({
|
||||
icon: 'iD-operation-orthogonalize',
|
||||
@@ -76,7 +76,7 @@ export function validationUnsquareWay() {
|
||||
}
|
||||
})
|
||||
]
|
||||
});
|
||||
})];
|
||||
|
||||
function showReference(selection) {
|
||||
selection.selectAll('.issue-reference')
|
||||
|
||||
@@ -36,8 +36,8 @@ describe('iD.validations.validator', function () {
|
||||
expect(issues).to.have.lengthOf(1);
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('missing_tag');
|
||||
expect(issue.entities).to.have.lengthOf(1);
|
||||
expect(issue.entities[0].id).to.eql('w-1');
|
||||
expect(issue.entityIds).to.have.lengthOf(1);
|
||||
expect(issue.entityIds[0]).to.eql('w-1');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -561,7 +561,7 @@ describe('maprules', function() {
|
||||
var type = Object.keys(selector).indexOf('error') ? 'error' : 'warning';
|
||||
|
||||
expect(issues.length).to.eql(1);
|
||||
expect(issue.entities).to.eql([entity]);
|
||||
expect(issue.entityIds).to.eql([entity.id]);
|
||||
expect(issue.message).to.eql(selector[type]);
|
||||
expect(type).to.eql(issue.severity);
|
||||
});
|
||||
|
||||
@@ -148,10 +148,10 @@ describe('iD.validations.almost_junction', function () {
|
||||
expect(issues).to.have.lengthOf(1);
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('almost_junction');
|
||||
expect(issue.entities).to.have.lengthOf(3);
|
||||
expect(issue.entities[0].id).to.eql('w-1');
|
||||
expect(issue.entities[1].id).to.eql('n-1');
|
||||
expect(issue.entities[2].id).to.eql('w-2');
|
||||
expect(issue.entityIds).to.have.lengthOf(3);
|
||||
expect(issue.entityIds[0]).to.eql('w-1');
|
||||
expect(issue.entityIds[1]).to.eql('n-1');
|
||||
expect(issue.entityIds[2]).to.eql('w-2');
|
||||
|
||||
expect(issue.loc).to.have.lengthOf(2);
|
||||
expect(issue.loc[0]).to.eql(22.42357);
|
||||
@@ -177,10 +177,10 @@ describe('iD.validations.almost_junction', function () {
|
||||
expect(issues).to.have.lengthOf(1);
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('almost_junction');
|
||||
expect(issue.entities).to.have.lengthOf(3);
|
||||
expect(issue.entities[0].id).to.eql('w-1');
|
||||
expect(issue.entities[1].id).to.eql('n-1');
|
||||
expect(issue.entities[2].id).to.eql('w-2');
|
||||
expect(issue.entityIds).to.have.lengthOf(3);
|
||||
expect(issue.entityIds[0]).to.eql('w-1');
|
||||
expect(issue.entityIds[1]).to.eql('n-1');
|
||||
expect(issue.entityIds[2]).to.eql('w-2');
|
||||
|
||||
expect(issue.loc).to.have.lengthOf(2);
|
||||
expect(issue.loc[0]).to.eql(22.42357);
|
||||
|
||||
@@ -67,7 +67,7 @@ describe('iD.validations.crossing_ways', function () {
|
||||
function verifySingleCrossingIssue(issues) {
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('crossing_ways');
|
||||
expect(issue.entities).to.have.lengthOf(2);
|
||||
expect(issue.entityIds).to.have.lengthOf(2);
|
||||
|
||||
expect(issue.loc).to.have.lengthOf(2);
|
||||
expect(issue.loc[0]).to.eql(1.5);
|
||||
@@ -224,7 +224,7 @@ describe('iD.validations.crossing_ways', function () {
|
||||
expect(issues).to.have.lengthOf(4);
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('crossing_ways');
|
||||
expect(issue.entities).to.have.lengthOf(2);
|
||||
expect(issue.entityIds).to.have.lengthOf(2);
|
||||
|
||||
expect(issue.loc).to.have.lengthOf(2);
|
||||
expect(issue.loc[0]).to.eql(1.5);
|
||||
@@ -232,7 +232,7 @@ describe('iD.validations.crossing_ways', function () {
|
||||
|
||||
issue = issues[1];
|
||||
expect(issue.type).to.eql('crossing_ways');
|
||||
expect(issue.entities).to.have.lengthOf(2);
|
||||
expect(issue.entityIds).to.have.lengthOf(2);
|
||||
|
||||
expect(issue.loc).to.have.lengthOf(2);
|
||||
expect(issue.loc[0]).to.eql(2.5);
|
||||
|
||||
@@ -56,8 +56,8 @@ describe('iD.validations.disconnected_way', function () {
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('disconnected_way');
|
||||
expect(issue.severity).to.eql('warning');
|
||||
expect(issue.entities).to.have.lengthOf(1);
|
||||
expect(issue.entities[0].id).to.eql('w-1');
|
||||
expect(issue.entityIds).to.have.lengthOf(1);
|
||||
expect(issue.entityIds[0]).to.eql('w-1');
|
||||
});
|
||||
|
||||
it('flags highway connected only to service area', function() {
|
||||
@@ -67,8 +67,8 @@ describe('iD.validations.disconnected_way', function () {
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('disconnected_way');
|
||||
expect(issue.severity).to.eql('warning');
|
||||
expect(issue.entities).to.have.lengthOf(1);
|
||||
expect(issue.entities[0].id).to.eql('w-1');
|
||||
expect(issue.entityIds).to.have.lengthOf(1);
|
||||
expect(issue.entityIds[0]).to.eql('w-1');
|
||||
});
|
||||
|
||||
it('flags disconnected highway with disconnected entrance vertex', function() {
|
||||
@@ -87,8 +87,8 @@ describe('iD.validations.disconnected_way', function () {
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('disconnected_way');
|
||||
expect(issue.severity).to.eql('warning');
|
||||
expect(issue.entities).to.have.lengthOf(1);
|
||||
expect(issue.entities[0].id).to.eql('w-1');
|
||||
expect(issue.entityIds).to.have.lengthOf(1);
|
||||
expect(issue.entityIds[0]).to.eql('w-1');
|
||||
});
|
||||
|
||||
it('ignores highways that are connected', function() {
|
||||
|
||||
@@ -65,8 +65,8 @@ describe('iD.validations.generic_name', function () {
|
||||
expect(issues).to.have.lengthOf(1);
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('generic_name');
|
||||
expect(issue.entities).to.have.lengthOf(1);
|
||||
expect(issue.entities[0].id).to.eql('w-1');
|
||||
expect(issue.entityIds).to.have.lengthOf(1);
|
||||
expect(issue.entityIds[0]).to.eql('w-1');
|
||||
});
|
||||
|
||||
it('flags feature with a name that is just a defining tag key', function() {
|
||||
@@ -75,8 +75,8 @@ describe('iD.validations.generic_name', function () {
|
||||
expect(issues).to.have.lengthOf(1);
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('generic_name');
|
||||
expect(issue.entities).to.have.lengthOf(1);
|
||||
expect(issue.entities[0].id).to.eql('w-1');
|
||||
expect(issue.entityIds).to.have.lengthOf(1);
|
||||
expect(issue.entityIds[0]).to.eql('w-1');
|
||||
});
|
||||
|
||||
it('flags feature with a name that is just a defining tag value', function() {
|
||||
@@ -85,8 +85,8 @@ describe('iD.validations.generic_name', function () {
|
||||
expect(issues).to.have.lengthOf(1);
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('generic_name');
|
||||
expect(issue.entities).to.have.lengthOf(1);
|
||||
expect(issue.entities[0].id).to.eql('w-1');
|
||||
expect(issue.entityIds).to.have.lengthOf(1);
|
||||
expect(issue.entityIds[0]).to.eql('w-1');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -53,8 +53,8 @@ describe('iD.validations.incompatible_source', function () {
|
||||
expect(issues).to.have.lengthOf(1);
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('incompatible_source');
|
||||
expect(issue.entities).to.have.lengthOf(1);
|
||||
expect(issue.entities[0].id).to.eql('w-1');
|
||||
expect(issue.entityIds).to.have.lengthOf(1);
|
||||
expect(issue.entityIds[0]).to.eql('w-1');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -80,9 +80,9 @@ describe('iD.validations.missing_role', function () {
|
||||
expect(issues[0].id).to.eql(issues[1].id);
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('missing_role');
|
||||
expect(issue.entities).to.have.lengthOf(2);
|
||||
expect(issue.entities[0].id).to.eql('r-1');
|
||||
expect(issue.entities[1].id).to.eql('w-1');
|
||||
expect(issue.entityIds).to.have.lengthOf(2);
|
||||
expect(issue.entityIds[0]).to.eql('r-1');
|
||||
expect(issue.entityIds[1]).to.eql('w-1');
|
||||
});
|
||||
|
||||
it('flags way with whitespace string role in multipolygon', function() {
|
||||
@@ -92,9 +92,9 @@ describe('iD.validations.missing_role', function () {
|
||||
expect(issues[0].id).to.eql(issues[1].id);
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('missing_role');
|
||||
expect(issue.entities).to.have.lengthOf(2);
|
||||
expect(issue.entities[0].id).to.eql('r-1');
|
||||
expect(issue.entities[1].id).to.eql('w-1');
|
||||
expect(issue.entityIds).to.have.lengthOf(2);
|
||||
expect(issue.entityIds[0]).to.eql('r-1');
|
||||
expect(issue.entityIds[1]).to.eql('w-1');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -68,8 +68,8 @@ describe('iD.validations.missing_tag', function () {
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('missing_tag');
|
||||
expect(issue.subtype).to.eql('any');
|
||||
expect(issue.entities).to.have.lengthOf(1);
|
||||
expect(issue.entities[0].id).to.eql('w-1');
|
||||
expect(issue.entityIds).to.have.lengthOf(1);
|
||||
expect(issue.entityIds[0]).to.eql('w-1');
|
||||
});
|
||||
|
||||
it('flags no descriptive tags', function() {
|
||||
@@ -79,8 +79,8 @@ describe('iD.validations.missing_tag', function () {
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('missing_tag');
|
||||
expect(issue.subtype).to.eql('descriptive');
|
||||
expect(issue.entities).to.have.lengthOf(1);
|
||||
expect(issue.entities[0].id).to.eql('w-1');
|
||||
expect(issue.entityIds).to.have.lengthOf(1);
|
||||
expect(issue.entityIds[0]).to.eql('w-1');
|
||||
});
|
||||
|
||||
it('flags no descriptive tags on multipolygon', function() {
|
||||
@@ -90,8 +90,8 @@ describe('iD.validations.missing_tag', function () {
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('missing_tag');
|
||||
expect(issue.subtype).to.eql('descriptive');
|
||||
expect(issue.entities).to.have.lengthOf(1);
|
||||
expect(issue.entities[0].id).to.eql('r-1');
|
||||
expect(issue.entityIds).to.have.lengthOf(1);
|
||||
expect(issue.entityIds[0]).to.eql('r-1');
|
||||
});
|
||||
|
||||
it('flags no type tag on relation', function() {
|
||||
@@ -101,8 +101,8 @@ describe('iD.validations.missing_tag', function () {
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('missing_tag');
|
||||
expect(issue.subtype).to.eql('relation_type');
|
||||
expect(issue.entities).to.have.lengthOf(1);
|
||||
expect(issue.entities[0].id).to.eql('r-1');
|
||||
expect(issue.entityIds).to.have.lengthOf(1);
|
||||
expect(issue.entityIds[0]).to.eql('r-1');
|
||||
});
|
||||
|
||||
it('ignores highway with classification', function() {
|
||||
@@ -118,8 +118,8 @@ describe('iD.validations.missing_tag', function () {
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('missing_tag');
|
||||
expect(issue.subtype).to.eql('highway_classification');
|
||||
expect(issue.entities).to.have.lengthOf(1);
|
||||
expect(issue.entities[0].id).to.eql('w-1');
|
||||
expect(issue.entityIds).to.have.lengthOf(1);
|
||||
expect(issue.entityIds[0]).to.eql('w-1');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -63,8 +63,8 @@ describe('iD.validations.outdated_tags', function () {
|
||||
expect(issue.type).to.eql('outdated_tags');
|
||||
expect(issue.subtype).to.eql('deprecated_tags');
|
||||
expect(issue.severity).to.eql('warning');
|
||||
expect(issue.entities).to.have.lengthOf(1);
|
||||
expect(issue.entities[0].id).to.eql('w-1');
|
||||
expect(issue.entityIds).to.have.lengthOf(1);
|
||||
expect(issue.entityIds[0]).to.eql('w-1');
|
||||
});
|
||||
|
||||
|
||||
@@ -87,9 +87,9 @@ describe('iD.validations.outdated_tags', function () {
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('outdated_tags');
|
||||
expect(issue.subtype).to.eql('old_multipolygon');
|
||||
expect(issue.entities).to.have.lengthOf(2);
|
||||
expect(issue.entities[0].id).to.eql('w-1');
|
||||
expect(issue.entities[1].id).to.eql('r-1');
|
||||
expect(issue.entityIds).to.have.lengthOf(2);
|
||||
expect(issue.entityIds[0]).to.eql('w-1');
|
||||
expect(issue.entityIds[1]).to.eql('r-1');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -65,8 +65,8 @@ describe('iD.validations.private_data', function () {
|
||||
expect(issues).to.have.lengthOf(1);
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('private_data');
|
||||
expect(issue.entities).to.have.lengthOf(1);
|
||||
expect(issue.entities[0].id).to.eql('w-1');
|
||||
expect(issue.entityIds).to.have.lengthOf(1);
|
||||
expect(issue.entityIds[0]).to.eql('w-1');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -88,8 +88,8 @@ describe('iD.validations.tag_suggests_area', function () {
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('tag_suggests_area');
|
||||
expect(issue.severity).to.eql('warning');
|
||||
expect(issue.entities).to.have.lengthOf(1);
|
||||
expect(issue.entities[0].id).to.eql('w-1');
|
||||
expect(issue.entityIds).to.have.lengthOf(1);
|
||||
expect(issue.entityIds[0]).to.eql('w-1');
|
||||
});
|
||||
|
||||
it('flags open way with both area and line tags', function() {
|
||||
@@ -99,8 +99,8 @@ describe('iD.validations.tag_suggests_area', function () {
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('tag_suggests_area');
|
||||
expect(issue.severity).to.eql('warning');
|
||||
expect(issue.entities).to.have.lengthOf(1);
|
||||
expect(issue.entities[0].id).to.eql('w-1');
|
||||
expect(issue.entityIds).to.have.lengthOf(1);
|
||||
expect(issue.entityIds[0]).to.eql('w-1');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user