mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-20 07:25:15 +02:00
Merge in master
This commit is contained in:
+6
-1
@@ -108,10 +108,15 @@ export var osmRightSideIsInsideTags = {
|
||||
};
|
||||
|
||||
// "highway" tag values for pedestrian or vehicle right-of-ways that make up the routable network
|
||||
// (does not include `raceway`)
|
||||
export var osmRoutableHighwayTagValues = {
|
||||
motorway: true, trunk: true, primary: true, secondary: true, tertiary: true, residential: true,
|
||||
motorway_link: true, trunk_link: true, primary_link: true, secondary_link: true, tertiary_link: true,
|
||||
unclassified: true, road: true, service: true, track: true, living_street: true, raceway: true, bus_guideway: true,
|
||||
unclassified: true, road: true, service: true, track: true, living_street: true, bus_guideway: true,
|
||||
path: true, footway: true, cycleway: true, bridleway: true, pedestrian: true, corridor: true, steps: true
|
||||
};
|
||||
// "highway" tag values that generally do not allow motor vehicles
|
||||
export var osmPathHighwayTagValues = {
|
||||
path: true, footway: true, cycleway: true, bridleway: true, pedestrian: true, corridor: true, steps: true
|
||||
};
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ export function presetCollection(collection) {
|
||||
search: function(value, geometry, countryCode) {
|
||||
if (!value) return this;
|
||||
|
||||
value = value.toLowerCase();
|
||||
value = value.toLowerCase().trim();
|
||||
|
||||
// match at name beginning or just after a space (e.g. "office" -> match "Law Office")
|
||||
function leading(a) {
|
||||
|
||||
@@ -91,7 +91,7 @@ function loadNextTilePage(which, currZoom, url, tile) {
|
||||
if (!response.ok) {
|
||||
throw new Error(response.status + ' ' + response.statusText);
|
||||
}
|
||||
var linkHeader = response.headers.Link;
|
||||
var linkHeader = response.headers.get('Link');
|
||||
if (linkHeader) {
|
||||
var pagination = parsePagination(linkHeader);
|
||||
if (pagination.next) {
|
||||
|
||||
@@ -2,12 +2,42 @@ import { actionMergeNodes } from '../actions/merge_nodes';
|
||||
import { utilDisplayLabel } from '../util';
|
||||
import { t } from '../util/locale';
|
||||
import { validationIssue, validationIssueFix } from '../core/validation';
|
||||
import { osmPathHighwayTagValues } from '../osm/tags';
|
||||
import { geoSphericalDistance } from '../geo/geo';
|
||||
|
||||
|
||||
export function validationCloseNodes() {
|
||||
var type = 'close_nodes';
|
||||
var thresholdMeters = 0.2;
|
||||
|
||||
// expect some features to be mapped with higher levels of detail
|
||||
var indoorThresholdMeters = 0.01;
|
||||
var buildingThresholdMeters = 0.05;
|
||||
var pathThresholdMeters = 0.1;
|
||||
var defaultThresholdMeters = 0.2;
|
||||
|
||||
function featureTypeForWay(way, graph) {
|
||||
|
||||
if (osmPathHighwayTagValues[way.tags.highway]) return 'path';
|
||||
|
||||
if (way.tags.indoor && way.tags.indoor !== 'no') return 'indoor';
|
||||
if ((way.tags.building && way.tags.building !== 'no') ||
|
||||
(way.tags['building:part'] && way.tags['building:part'] !== 'no')) return 'building';
|
||||
if (way.tags.boundary && way.tags.boundary !== 'no') return 'boundary';
|
||||
|
||||
var parentRelations = graph.parentRelations(way);
|
||||
for (var i in parentRelations) {
|
||||
var relation = parentRelations[i];
|
||||
if (relation.isMultipolygon()) {
|
||||
if (relation.tags.indoor && relation.tags.indoor !== 'no') return 'indoor';
|
||||
if ((relation.tags.building && relation.tags.building !== 'no') ||
|
||||
(relation.tags['building:part'] && relation.tags['building:part'] !== 'no')) return 'building';
|
||||
} else {
|
||||
if (relation.tags.type === 'boundary') return 'boundary';
|
||||
}
|
||||
}
|
||||
|
||||
return 'other';
|
||||
}
|
||||
|
||||
function shouldCheckWay(way, context) {
|
||||
|
||||
@@ -15,16 +45,8 @@ export function validationCloseNodes() {
|
||||
if (way.nodes.length <= 2 ||
|
||||
(way.isClosed() && way.nodes.length <= 4)) return false;
|
||||
|
||||
// expect that indoor features may be mapped in very fine detail
|
||||
if (way.tags.indoor) return false;
|
||||
|
||||
var parentRelations = context.graph().parentRelations(way);
|
||||
|
||||
// don't flag close nodes in boundaries since it's unlikely the user can accurately resolve them
|
||||
if (way.tags.boundary) return false;
|
||||
if (parentRelations.length && parentRelations.some(function(parentRelation) {
|
||||
return parentRelation.tags.type === 'boundary';
|
||||
})) return false;
|
||||
var featureType = featureTypeForWay(way, context.graph());
|
||||
if (featureType === 'boundary') return false;
|
||||
|
||||
var bbox = way.extent(context.graph()).bbox();
|
||||
var hypotenuseMeters = geoSphericalDistance([bbox.minX, bbox.minY], [bbox.maxX, bbox.maxY]);
|
||||
@@ -88,10 +110,17 @@ export function validationCloseNodes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
var nodesAreVeryClose = node1.loc === node2.loc ||
|
||||
geoSphericalDistance(node1.loc, node2.loc) < thresholdMeters;
|
||||
if (node1.loc !== node2.loc) {
|
||||
|
||||
if (!nodesAreVeryClose) return null;
|
||||
var featureType = featureTypeForWay(way, context.graph());
|
||||
var threshold = defaultThresholdMeters;
|
||||
if (featureType === 'indoor') threshold = indoorThresholdMeters;
|
||||
else if (featureType === 'building') threshold = buildingThresholdMeters;
|
||||
else if (featureType === 'path') threshold = pathThresholdMeters;
|
||||
|
||||
var distance = geoSphericalDistance(node1.loc, node2.loc);
|
||||
if (distance > threshold) return null;
|
||||
}
|
||||
|
||||
return new validationIssue({
|
||||
type: type,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { actionChangeTags } from '../actions/change_tags';
|
||||
import { actionMergeNodes } from '../actions/merge_nodes';
|
||||
import { geoExtent, geoLineIntersection, geoSphericalClosestNode } from '../geo';
|
||||
import { osmNode } from '../osm/node';
|
||||
import { osmFlowingWaterwayTagValues, osmRailwayTrackTagValues, osmRoutableHighwayTagValues } from '../osm/tags';
|
||||
import { osmFlowingWaterwayTagValues, osmPathHighwayTagValues, osmRailwayTrackTagValues, osmRoutableHighwayTagValues } from '../osm/tags';
|
||||
import { t } from '../util/locale';
|
||||
import { utilDisplayLabel } from '../util';
|
||||
import { validationIssue, validationIssueFix } from '../core/validation';
|
||||
@@ -146,10 +146,6 @@ export function validationCrossingWays() {
|
||||
motorway: true, motorway_link: true, trunk: true, trunk_link: true,
|
||||
primary: true, primary_link: true, secondary: true, secondary_link: true
|
||||
};
|
||||
var pathHighways = {
|
||||
path: true, footway: true, cycleway: true, bridleway: true,
|
||||
pedestrian: true, steps: true, corridor: true
|
||||
};
|
||||
var nonCrossingHighways = { track: true };
|
||||
|
||||
function tagsForConnectionNodeIfAllowed(entity1, entity2) {
|
||||
@@ -157,8 +153,8 @@ export function validationCrossingWays() {
|
||||
var featureType2 = getFeatureTypeForTags(entity2.tags);
|
||||
if (featureType1 === featureType2) {
|
||||
if (featureType1 === 'highway') {
|
||||
var entity1IsPath = pathHighways[entity1.tags.highway];
|
||||
var entity2IsPath = pathHighways[entity2.tags.highway];
|
||||
var entity1IsPath = osmPathHighwayTagValues[entity1.tags.highway];
|
||||
var entity2IsPath = osmPathHighwayTagValues[entity2.tags.highway];
|
||||
if ((entity1IsPath || entity2IsPath) && entity1IsPath !== entity2IsPath) {
|
||||
// one feature is a path but not both
|
||||
|
||||
@@ -184,8 +180,8 @@ export function validationCrossingWays() {
|
||||
var featureTypes = [featureType1, featureType2];
|
||||
if (featureTypes.indexOf('highway') !== -1) {
|
||||
if (featureTypes.indexOf('railway') !== -1) {
|
||||
if (pathHighways[entity1.tags.highway] ||
|
||||
pathHighways[entity2.tags.highway]) {
|
||||
if (osmPathHighwayTagValues[entity1.tags.highway] ||
|
||||
osmPathHighwayTagValues[entity2.tags.highway]) {
|
||||
// path-rail connections use this tag
|
||||
return { railway: 'crossing' };
|
||||
} else {
|
||||
|
||||
@@ -15,7 +15,7 @@ export function validationOutdatedTags() {
|
||||
// initialize name-suggestion-index matcher
|
||||
var nsiMatcher = matcher();
|
||||
nsiMatcher.buildMatchIndex(brands.brands);
|
||||
var nsiKeys = ['amenity', 'shop', 'tourism', 'leisure'];
|
||||
var nsiKeys = ['amenity', 'shop', 'tourism', 'leisure', 'office'];
|
||||
|
||||
|
||||
function oldTagIssues(entity, context) {
|
||||
@@ -68,7 +68,7 @@ export function validationOutdatedTags() {
|
||||
if (match.d) continue;
|
||||
|
||||
var brand = brands.brands[match.kvnd];
|
||||
if (brand) {
|
||||
if (brand && brand.tags['brand:wikidata']) {
|
||||
Object.assign(newTags, brand.tags);
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user