mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-13 04:44:50 +02:00
Merge pull request #6267 from gaoxm/dupeNodeValidation
add validation for very close node on road
This commit is contained in:
@@ -1403,6 +1403,11 @@ en:
|
||||
unknown_road:
|
||||
message: "{feature} has no classification"
|
||||
reference: "Roads without a specific type may not appear in maps or routing."
|
||||
dupe_node_on_road:
|
||||
title: Very close nodes on road
|
||||
message: "Very close nodes on road"
|
||||
ref_merge: "Nodes are less than 2 meters away; you may want to merge them."
|
||||
ref_move_away: "Nodes are less than 2 meters away but not mergable; you may want to move them further apart."
|
||||
impossible_oneway:
|
||||
title: Impossible One-Ways
|
||||
tip: "Find route issues with one-way features"
|
||||
@@ -1491,6 +1496,8 @@ en:
|
||||
title: Use different levels
|
||||
use_tunnel:
|
||||
title: Use a tunnel
|
||||
merge_nodes:
|
||||
title: Merge these nodes
|
||||
intro:
|
||||
done: done
|
||||
ok: OK
|
||||
|
||||
Vendored
+9
-14
@@ -1737,6 +1737,12 @@
|
||||
"message": "{feature} has no classification",
|
||||
"reference": "Roads without a specific type may not appear in maps or routing."
|
||||
},
|
||||
"dupe_node_on_road": {
|
||||
"title": "Very close nodes on road",
|
||||
"message": "Very close nodes on road",
|
||||
"ref_merge": "Nodes are less than 2 meters away; you may want to merge them.",
|
||||
"ref_move_away": "Nodes are less than 2 meters away but not mergable; you may want to move them further apart."
|
||||
},
|
||||
"impossible_oneway": {
|
||||
"title": "Impossible One-Ways",
|
||||
"tip": "Find route issues with one-way features",
|
||||
@@ -1863,6 +1869,9 @@
|
||||
},
|
||||
"use_tunnel": {
|
||||
"title": "Use a tunnel"
|
||||
},
|
||||
"merge_nodes": {
|
||||
"title": "Merge these nodes"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -9092,20 +9101,6 @@
|
||||
"description": "Japan GSI ortho Imagery. Usually better than bing, but a bit older.",
|
||||
"name": "Japan GSI ortho Imagery"
|
||||
},
|
||||
"gsi.go.jp_airphoto": {
|
||||
"attribution": {
|
||||
"text": "GSI Japan"
|
||||
},
|
||||
"description": "Japan GSI airphoto Imagery. Not fully orthorectified, but a bit newer and/or differently covered than GSI ortho Imagery.",
|
||||
"name": "Japan GSI airphoto Imagery"
|
||||
},
|
||||
"gsi.go.jp_seamlessphoto": {
|
||||
"attribution": {
|
||||
"text": "GSI Japan seamless photo"
|
||||
},
|
||||
"description": "Japan GSI seamlessphoto Imagery. The collection of latest imageries of GSI ortho, airphoto, post disaster and others.",
|
||||
"name": "Japan GSI seamlessphoto Imagery"
|
||||
},
|
||||
"gsi.go.jp_std_map": {
|
||||
"attribution": {
|
||||
"text": "GSI Japan"
|
||||
|
||||
@@ -52,8 +52,10 @@ export function uiInspector(context) {
|
||||
var hasNonGeometryTags = entity.hasNonGeometryTags();
|
||||
var isTaglessOrIntersectionVertex = entity.geometry(context.graph()) === 'vertex' &&
|
||||
(!hasNonGeometryTags && !entity.isHighwayIntersection(context.graph()));
|
||||
var issues = context.validator().getEntityIssues(_entityID);
|
||||
// start with the preset list if the feature is new and untagged or is an uninteresting vertex
|
||||
var showPresetList = (newFeature && !hasNonGeometryTags) || isTaglessOrIntersectionVertex;
|
||||
var showPresetList = issues.length === 0 &&
|
||||
((newFeature && !hasNonGeometryTags) || isTaglessOrIntersectionVertex);
|
||||
|
||||
if (showPresetList) {
|
||||
wrap.style('right', '-100%');
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
import { operationMerge } from '../operations/index';
|
||||
import { t } from '../util/locale';
|
||||
import { validationIssue, validationIssueFix } from '../core/validation';
|
||||
import { geoExtent } from '../geo';
|
||||
|
||||
|
||||
export function validationDupeNodeOnRoad() {
|
||||
var type = 'dupe_node_on_road';
|
||||
|
||||
|
||||
function isNodeOnRoad(node, context) {
|
||||
var parentWays = context.graph().parentWays(node);
|
||||
for (var i = 0; i < parentWays.length; i++) {
|
||||
if (parentWays[i].tags.highway) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function findDupeNode(node, context) {
|
||||
var epsilon = 2e-5,
|
||||
extent = geoExtent([
|
||||
[node.loc[0] - epsilon, node.loc[1] - epsilon],
|
||||
[node.loc[0] + epsilon, node.loc[1] + epsilon]
|
||||
]);
|
||||
var filteredEnts = context.intersects(extent);
|
||||
for (var i = 0; i < filteredEnts.length; i++) {
|
||||
var entity = filteredEnts[i];
|
||||
if (entity.type === 'node' && entity.id !== node.id &&
|
||||
Math.abs(node.loc[0] - entity.loc[0]) < epsilon &&
|
||||
Math.abs(node.loc[1] - entity.loc[1]) < epsilon &&
|
||||
isNodeOnRoad(entity, context) ) {
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
var validation = function(entity, context) {
|
||||
if (entity.type !== 'node' || !isNodeOnRoad(entity, context)) return [];
|
||||
|
||||
var dupe = findDupeNode(entity, context);
|
||||
if (dupe === null) return [];
|
||||
|
||||
var mergable = !operationMerge([entity.id, dupe.id], context).disabled();
|
||||
var fixes = [];
|
||||
if (mergable) {
|
||||
fixes.push(
|
||||
new validationIssueFix({
|
||||
icon: 'iD-icon-plus',
|
||||
title: t('issues.fix.merge_nodes.title'),
|
||||
onClick: function() {
|
||||
var entities = this.issue.entities,
|
||||
operation = operationMerge([entities[0].id, entities[1].id], context);
|
||||
if (!operation.disabled()) {
|
||||
operation();
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
return [new validationIssue({
|
||||
type: type,
|
||||
severity: 'warning',
|
||||
message: t('issues.dupe_node_on_road.message'),
|
||||
reference: showReference,
|
||||
entities: [entity, dupe],
|
||||
fixes: fixes
|
||||
})];
|
||||
|
||||
|
||||
function showReference(selection) {
|
||||
var referenceText = mergable
|
||||
? t('issues.dupe_node_on_road.ref_merge')
|
||||
: t('issues.dupe_node_on_road.ref_move_away');
|
||||
selection.selectAll('.issue-reference')
|
||||
.data([0])
|
||||
.enter()
|
||||
.append('div')
|
||||
.attr('class', 'issue-reference')
|
||||
.text(referenceText);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
validation.type = type;
|
||||
|
||||
return validation;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
export { validationAlmostJunction } from './almost_junction';
|
||||
export { validationCrossingWays } from './crossing_ways';
|
||||
export { validationDisconnectedWay } from './disconnected_way';
|
||||
export { validationDupeNodeOnRoad } from './dupe_node_on_road';
|
||||
export { validationFixmeTag } from './fixme_tag';
|
||||
export { validationGenericName } from './generic_name';
|
||||
export { validationImpossibleOneway } from './impossible_oneway';
|
||||
|
||||
Reference in New Issue
Block a user