Add index of tags that positively identify points or vertices, derived from the presets

Delete nodes that can only be vertices when deleting parent ways (close #6230)
Allow snapping ways to nodes that cannot be positively identified as vertex-only
This commit is contained in:
Quincy Morgan
2019-05-14 12:09:44 -04:00
parent e36c51c7f7
commit 409968dfc2
5 changed files with 106 additions and 25 deletions
+14 -3
View File
@@ -1,3 +1,4 @@
import { osmNodeGeometriesForTags } from '../osm/tags';
import { actionDeleteRelation } from './delete_relation';
@@ -5,9 +6,19 @@ import { actionDeleteRelation } from './delete_relation';
export function actionDeleteWay(wayID) {
function canDeleteNode(node, graph) {
return !graph.parentWays(node).length &&
!graph.parentRelations(node).length &&
!node.hasInterestingTags();
// don't delete nodes still attached to ways or relations
if (graph.parentWays(node).length ||
graph.parentRelations(node).length) return false;
var geometries = osmNodeGeometriesForTags(node.tags);
// don't delete if this node can be a standalone point
if (geometries.point) return false;
// delete if this node only be a vertex
if (geometries.vertex) return true;
// iD doesn't know if this should be a point or vertex,
// so only delete if there are no interesting tags
return !node.hasInterestingTags();
}
+5 -1
View File
@@ -6,7 +6,7 @@ import { select as d3_select } from 'd3-selection';
import { t, currentLocale, addTranslation, setLocale } from '../util/locale';
import { osmSetAreaKeys } from '../osm/tags';
import { osmSetAreaKeys, osmSetPointTags, osmSetVertexTags } from '../osm/tags';
import { coreHistory } from './history';
import { coreValidator } from './validator';
@@ -553,10 +553,14 @@ export function coreContext() {
presets.fromExternal(external, function(externalPresets) {
context.presets = function() { return externalPresets; }; // default + external presets...
osmSetAreaKeys(presets.areaKeys());
osmSetPointTags(presets.pointTags());
osmSetVertexTags(presets.vertexTags());
});
} else {
presets.init();
osmSetAreaKeys(presets.areaKeys());
osmSetPointTags(presets.pointTags());
osmSetVertexTags(presets.vertexTags());
}
return context;
+12 -2
View File
@@ -24,7 +24,17 @@ export {
} from './multipolygon';
export {
osmAreaKeys,
osmSetAreaKeys,
osmPointTags,
osmSetPointTags,
osmVertexTags,
osmSetVertexTags,
osmNodeGeometriesForTags,
osmOneWayTags,
osmPavedTags,
osmIsInterestingTag
} from './tags';
osmIsInterestingTag,
osmRoutableHighwayTagValues,
osmFlowingWaterwayTagValues,
osmRailwayTrackTagValues
} from './tags';
+30 -1
View File
@@ -7,11 +7,40 @@ export function osmIsInterestingTag(key) {
}
export var osmAreaKeys = {};
export function osmSetAreaKeys(value) {
osmAreaKeys = value;
}
// Tags that indicate a node can be a standalone point
// e.g. { amenity: { bar: true, parking: true, ... } ... }
export var osmPointTags = {};
export function osmSetPointTags(value) {
osmPointTags = value;
}
// Tags that indicate a node can be part of a way
// e.g. { amenity: { parking: true, ... }, highway: { stop: true ... } ... }
export var osmVertexTags = {};
export function osmSetVertexTags(value) {
osmVertexTags = value;
}
export function osmNodeGeometriesForTags(nodeTags) {
var geometries = {};
for (var key in nodeTags) {
if (osmPointTags[key] &&
(osmPointTags[key]['*'] || osmPointTags[key][nodeTags[key]])) {
geometries.point = true;
}
if (osmVertexTags[key] &&
(osmVertexTags[key]['*'] || osmVertexTags[key][nodeTags[key]])) {
geometries.vertex = true;
}
// break early if both are already supported
if (geometries.point && geometries.vertex) break;
}
return geometries;
}
export var osmOneWayTags = {
'aerialway': {
'chair_lift': true,
+45 -18
View File
@@ -2,6 +2,7 @@ import { dispatch as d3_dispatch } from 'd3-dispatch';
import { json as d3_json } from 'd3-fetch';
import { data } from '../../data/index';
import { osmNodeGeometriesForTags } from '../osm/tags';
import { presetCategory } from './category';
import { presetCollection } from './collection';
import { presetField } from './field';
@@ -86,24 +87,14 @@ export function presetIndex(context) {
if (Object.keys(entity.tags).length === 0) return true;
return resolver.transient(entity, 'vertexMatch', function() {
var vertexPresets = _index.vertex;
if (entity.isOnAddressLine(resolver)) {
return true;
} else {
var didFindMatches = false;
for (var k in entity.tags) {
var keyMatches = vertexPresets[k];
if (!keyMatches) continue;
didFindMatches = true;
for (var i = 0; i < keyMatches.length; i++) {
var preset = keyMatches[i];
if (preset.searchable !== false && preset.matchScore(entity.tags) > -1) {
return preset;
}
}
}
return !didFindMatches;
}
// address lines allow vertices to act as standalone points
if (entity.isOnAddressLine(resolver)) return true;
var geometries = osmNodeGeometriesForTags(entity.tags);
if (geometries.vertex) return true;
if (geometries.point) return false;
// allow vertices for unspecified points
return true;
});
};
@@ -156,6 +147,42 @@ export function presetIndex(context) {
return areaKeys;
};
all.pointTags = function() {
return all.collection.reduce(function(pointTags, d) {
// ignore name-suggestion-index, deprecated, and generic presets
if (d.suggestion || d.replacement || d.searchable === false) return pointTags;
// only care about the primary tag
for (var key in d.tags) break;
if (!key) return pointTags;
// if this can be a point
if (d.geometry.indexOf('point') !== -1) {
pointTags[key] = pointTags[key] || {};
pointTags[key][d.tags[key]] = true;
}
return pointTags;
}, {});
};
all.vertexTags = function() {
return all.collection.reduce(function(vertexTags, d) {
// ignore name-suggestion-index, deprecated, and generic presets
if (d.suggestion || d.replacement || d.searchable === false) return vertexTags;
// only care about the primary tag
for (var key in d.tags) break;
if (!key) return vertexTags;
// if this can be a vertex
if (d.geometry.indexOf('vertex') !== -1) {
vertexTags[key] = vertexTags[key] || {};
vertexTags[key][d.tags[key]] = true;
}
return vertexTags;
}, {});
};
all.build = function(d, visible) {
if (d.fields) {
Object.keys(d.fields).forEach(function(id) {