mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-15 05:30:35 +02:00
drop validator which checks for old style multipolygons
these have long been [fixed](https://blog.jochentopf.com/2017-08-28-polygon-fixing-effort-concluded.html) in OSM see wiki: https://wiki.openstreetmap.org/wiki/Old_style_multipolygons
This commit is contained in:
@@ -42,6 +42,7 @@ _Breaking developer changes, which may affect downstream projects or sites that
|
||||
#### :scissors: Operations
|
||||
#### :camera: Street-Level
|
||||
#### :white_check_mark: Validation
|
||||
* Drop validation which checks for [old style multipolygons](https://wiki.openstreetmap.org/wiki/Old_style_multipolygons), as these have long been [fixed](https://blog.jochentopf.com/2017-08-28-polygon-fixing-effort-concluded.html) in OSM
|
||||
#### :bug: Bugfixes
|
||||
#### :earth_asia: Localization
|
||||
#### :hourglass: Performance
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { actionAddMember } from './add_member';
|
||||
import { geoSphericalDistance } from '../geo/geo';
|
||||
import { osmIsOldMultipolygonOuterMember } from '../osm/multipolygon';
|
||||
import { osmRelation } from '../osm/relation';
|
||||
import { osmWay } from '../osm/way';
|
||||
import { utilArrayIntersection, utilWrap, utilArrayUniq } from '../util';
|
||||
@@ -100,7 +99,6 @@ export function actionSplit(nodeIds, newWayIds) {
|
||||
var nodesA;
|
||||
var nodesB;
|
||||
var isArea = wayA.isArea();
|
||||
var isOuter = osmIsOldMultipolygonOuterMember(wayA, graph);
|
||||
|
||||
if (wayA.isClosed()) {
|
||||
var nodes = wayA.nodes.slice(0, -1);
|
||||
@@ -220,12 +218,6 @@ export function actionSplit(nodeIds, newWayIds) {
|
||||
// 1. Both `wayA` and `wayB` remain in the relation
|
||||
// 2. But must be inserted as a pair (see `actionAddMember` for details)
|
||||
} else {
|
||||
if (relation === isOuter) {
|
||||
graph = graph.replace(relation.mergeTags(wayA.tags));
|
||||
graph = graph.replace(wayA.update({ tags: {} }));
|
||||
graph = graph.replace(wayB.update({ tags: {} }));
|
||||
}
|
||||
|
||||
member = {
|
||||
id: wayB.id,
|
||||
type: 'way',
|
||||
@@ -242,7 +234,7 @@ export function actionSplit(nodeIds, newWayIds) {
|
||||
}
|
||||
});
|
||||
|
||||
if (!isOuter && isArea) {
|
||||
if (isArea) {
|
||||
var multipolygon = osmRelation({
|
||||
tags: Object.assign({}, wayA.tags, { type: 'multipolygon' }),
|
||||
members: [
|
||||
|
||||
@@ -17,9 +17,6 @@ export {
|
||||
} from './lanes';
|
||||
|
||||
export {
|
||||
osmOldMultipolygonOuterMemberOfRelation,
|
||||
osmIsOldMultipolygonOuterMember,
|
||||
osmOldMultipolygonOuterMember,
|
||||
osmJoinWays
|
||||
} from './multipolygon';
|
||||
|
||||
|
||||
@@ -1,109 +1,7 @@
|
||||
import { actionReverse } from '../actions/reverse';
|
||||
import { osmIsInterestingTag } from './tags';
|
||||
import { osmWay } from './way';
|
||||
|
||||
|
||||
// "Old" multipolyons, previously known as "simple" multipolygons, are as follows:
|
||||
//
|
||||
// 1. Relation tagged with `type=multipolygon` and no interesting tags.
|
||||
// 2. One and only one member with the `outer` role. Must be a way with interesting tags.
|
||||
// 3. No members without a role.
|
||||
//
|
||||
// Old multipolygons are no longer recommended but are still rendered as areas by iD.
|
||||
|
||||
export function osmOldMultipolygonOuterMemberOfRelation(entity, graph) {
|
||||
if (entity.type !== 'relation' ||
|
||||
!entity.isMultipolygon()
|
||||
|| Object.keys(entity.tags).filter(osmIsInterestingTag).length > 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var outerMember;
|
||||
for (var memberIndex in entity.members) {
|
||||
var member = entity.members[memberIndex];
|
||||
if (!member.role || member.role === 'outer') {
|
||||
if (outerMember) return false;
|
||||
if (member.type !== 'way') return false;
|
||||
if (!graph.hasEntity(member.id)) return false;
|
||||
|
||||
outerMember = graph.entity(member.id);
|
||||
|
||||
if (Object.keys(outerMember.tags).filter(osmIsInterestingTag).length === 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return outerMember;
|
||||
}
|
||||
|
||||
// For fixing up rendering of multipolygons with tags on the outer member.
|
||||
// https://github.com/openstreetmap/iD/issues/613
|
||||
export function osmIsOldMultipolygonOuterMember(entity, graph) {
|
||||
if (entity.type !== 'way' ||
|
||||
Object.keys(entity.tags).filter(osmIsInterestingTag).length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var parents = graph.parentRelations(entity);
|
||||
if (parents.length !== 1) return false;
|
||||
|
||||
var parent = parents[0];
|
||||
if (!parent.isMultipolygon() ||
|
||||
Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var members = parent.members, member;
|
||||
for (var i = 0; i < members.length; i++) {
|
||||
member = members[i];
|
||||
if (member.id === entity.id && member.role && member.role !== 'outer') {
|
||||
// Not outer member
|
||||
return false;
|
||||
}
|
||||
if (member.id !== entity.id && (!member.role || member.role === 'outer')) {
|
||||
// Not a simple multipolygon
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
|
||||
export function osmOldMultipolygonOuterMember(entity, graph) {
|
||||
if (entity.type !== 'way') return false;
|
||||
|
||||
var parents = graph.parentRelations(entity);
|
||||
if (parents.length !== 1) return false;
|
||||
|
||||
var parent = parents[0];
|
||||
if (!parent.isMultipolygon() ||
|
||||
Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var members = parent.members, member, outerMember;
|
||||
for (var i = 0; i < members.length; i++) {
|
||||
member = members[i];
|
||||
if (!member.role || member.role === 'outer') {
|
||||
if (outerMember) return false; // Not a simple multipolygon
|
||||
outerMember = member;
|
||||
}
|
||||
}
|
||||
|
||||
if (!outerMember) return false;
|
||||
|
||||
var outerEntity = graph.hasEntity(outerMember.id);
|
||||
if (!outerEntity ||
|
||||
!Object.keys(outerEntity.tags).filter(osmIsInterestingTag).length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return outerEntity;
|
||||
}
|
||||
|
||||
|
||||
// Join `toJoin` array into sequences of connecting ways.
|
||||
|
||||
// Segments which share identical start/end nodes will, as much as possible,
|
||||
|
||||
+2
-10
@@ -1,7 +1,7 @@
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
import { bisector as d3_bisector } from 'd3-array';
|
||||
|
||||
import { osmEntity, osmIsOldMultipolygonOuterMember } from '../osm';
|
||||
import { osmEntity } from '../osm';
|
||||
import { svgPath, svgSegmentWay } from './helpers';
|
||||
import { svgTagClasses } from './tag_classes';
|
||||
import { svgTagPattern } from './tag_pattern';
|
||||
@@ -90,20 +90,12 @@ export function svgAreas(projection, context) {
|
||||
function drawAreas(selection, graph, entities, filter) {
|
||||
var path = svgPath(projection, graph, true);
|
||||
var areas = {};
|
||||
var multipolygon;
|
||||
var base = context.history().base();
|
||||
|
||||
for (var i = 0; i < entities.length; i++) {
|
||||
var entity = entities[i];
|
||||
if (entity.geometry(graph) !== 'area') continue;
|
||||
|
||||
multipolygon = osmIsOldMultipolygonOuterMember(entity, graph);
|
||||
if (multipolygon) {
|
||||
areas[multipolygon.id] = {
|
||||
entity: multipolygon.mergeTags(entity.tags),
|
||||
area: Math.abs(entity.area(graph))
|
||||
};
|
||||
} else if (!areas[entity.id]) {
|
||||
if (!areas[entity.id]) {
|
||||
areas[entity.id] = {
|
||||
entity: entity,
|
||||
area: Math.abs(entity.area(graph))
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
} from './helpers';
|
||||
import { svgTagClasses } from './tag_classes';
|
||||
|
||||
import { osmEntity, osmOldMultipolygonOuterMember } from '../osm';
|
||||
import { osmEntity } from '../osm';
|
||||
import { utilArrayFlatten, utilArrayGroupBy } from '../util';
|
||||
import { utilDetect } from '../util/detect';
|
||||
|
||||
@@ -237,11 +237,7 @@ export function svgLines(projection, context) {
|
||||
|
||||
for (var i = 0; i < entities.length; i++) {
|
||||
var entity = entities[i];
|
||||
var outer = osmOldMultipolygonOuterMember(entity, graph);
|
||||
if (outer) {
|
||||
ways.push(entity.mergeTags(outer.tags));
|
||||
oldMultiPolygonOuters[outer.id] = true;
|
||||
} else if (entity.geometry(graph) === 'line'
|
||||
if (entity.geometry(graph) === 'line'
|
||||
// to render side-markers for coastlines (see
|
||||
// https://github.com/openstreetmap/iD/issues/9293)
|
||||
|| entity.geometry(graph) === 'area' && entity.sidednessIdentifier
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { operationDelete } from '../operations/delete';
|
||||
import { osmIsInterestingTag } from '../osm/tags';
|
||||
import { osmOldMultipolygonOuterMemberOfRelation } from '../osm/multipolygon';
|
||||
import { t } from '../core/localizer';
|
||||
import { utilDisplayLabel } from '../util';
|
||||
import { validationIssue, validationIssueFix } from '../core/validation';
|
||||
@@ -25,10 +24,7 @@ export function validationMissingTag(context) {
|
||||
entity.tags.type === 'multipolygon') {
|
||||
// this relation's only interesting tag just says its a multipolygon,
|
||||
// which is not descriptive enough
|
||||
|
||||
// It's okay for a simple multipolygon to have no descriptive tags
|
||||
// if its outer way has them (old model, see `outdated_tags.js`)
|
||||
return osmOldMultipolygonOuterMemberOfRelation(entity, graph);
|
||||
return false;
|
||||
}
|
||||
|
||||
return entityDescriptiveKeys.length > 0;
|
||||
|
||||
@@ -6,7 +6,6 @@ import { actionUpgradeTags } from '../actions/upgrade_tags';
|
||||
import { fileFetcher } from '../core';
|
||||
import { presetManager } from '../presets';
|
||||
import { services } from '../services';
|
||||
import { osmIsOldMultipolygonOuterMember, osmOldMultipolygonOuterMemberOfRelation } from '../osm/multipolygon';
|
||||
import { utilDisplayLabel, utilHashcode, utilTagDiff } from '../util';
|
||||
import { validationIssue, validationIssueFix } from '../core/validation';
|
||||
|
||||
@@ -40,12 +39,18 @@ export function validationOutdatedTags() {
|
||||
preset = newPreset;
|
||||
}
|
||||
|
||||
const upgradeReasons = [];
|
||||
|
||||
// Upgrade deprecated tags..
|
||||
if (_dataDeprecated) {
|
||||
const deprecatedTags = entity.deprecatedTags(_dataDeprecated);
|
||||
if (deprecatedTags.length) {
|
||||
deprecatedTags.forEach(tag => {
|
||||
graph = actionUpgradeTags(entity.id, tag.old, tag.replace)(graph);
|
||||
upgradeReasons.push({
|
||||
source: 'id-tagging-schema--deprecated',
|
||||
data: tag
|
||||
});
|
||||
});
|
||||
entity = graph.entity(entity.id);
|
||||
}
|
||||
@@ -58,9 +63,13 @@ export function validationOutdatedTags() {
|
||||
if (!newTags[k]) {
|
||||
if (preset.addTags[k] === '*') {
|
||||
newTags[k] = 'yes';
|
||||
} else {
|
||||
} else if (preset.addTags[k]) {
|
||||
newTags[k] = preset.addTags[k];
|
||||
}
|
||||
upgradeReasons.push({
|
||||
source: 'id-tagging-schema--preset-addTags',
|
||||
data: preset
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -77,6 +86,10 @@ export function validationOutdatedTags() {
|
||||
if (nsiResult) {
|
||||
newTags = nsiResult.newTags;
|
||||
subtype = 'noncanonical_brand';
|
||||
upgradeReasons.push({
|
||||
source: 'name-suggestion-index',
|
||||
data: nsiResult
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,79 +237,7 @@ export function validationOutdatedTags() {
|
||||
}
|
||||
|
||||
|
||||
function oldMultipolygonIssues(entity, graph) {
|
||||
let multipolygon, outerWay;
|
||||
if (entity.type === 'relation') {
|
||||
outerWay = osmOldMultipolygonOuterMemberOfRelation(entity, graph);
|
||||
multipolygon = entity;
|
||||
} else if (entity.type === 'way') {
|
||||
multipolygon = osmIsOldMultipolygonOuterMember(entity, graph);
|
||||
outerWay = entity;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!multipolygon || !outerWay) return [];
|
||||
|
||||
return [new validationIssue({
|
||||
type: type,
|
||||
subtype: 'old_multipolygon',
|
||||
severity: 'warning',
|
||||
message: showMessage,
|
||||
reference: showReference,
|
||||
entityIds: [outerWay.id, multipolygon.id],
|
||||
dynamicFixes: () => {
|
||||
return [
|
||||
new validationIssueFix({
|
||||
autoArgs: [doUpgrade, t('issues.fix.move_tags.annotation')],
|
||||
title: t.append('issues.fix.move_tags.title'),
|
||||
onClick: (context) => {
|
||||
context.perform(doUpgrade, t('issues.fix.move_tags.annotation'));
|
||||
}
|
||||
})
|
||||
];
|
||||
}
|
||||
})];
|
||||
|
||||
|
||||
function doUpgrade(graph) {
|
||||
let currMultipolygon = graph.hasEntity(multipolygon.id);
|
||||
let currOuterWay = graph.hasEntity(outerWay.id);
|
||||
if (!currMultipolygon || !currOuterWay) return graph;
|
||||
|
||||
currMultipolygon = currMultipolygon.mergeTags(currOuterWay.tags);
|
||||
graph = graph.replace(currMultipolygon);
|
||||
return actionChangeTags(currOuterWay.id, {})(graph);
|
||||
}
|
||||
|
||||
|
||||
function showMessage(context) {
|
||||
let currMultipolygon = context.hasEntity(multipolygon.id);
|
||||
if (!currMultipolygon) return '';
|
||||
|
||||
return t.append('issues.old_multipolygon.message',
|
||||
{ multipolygon: utilDisplayLabel(currMultipolygon, context.graph(), true /* verbose */) }
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function showReference(selection) {
|
||||
selection.selectAll('.issue-reference')
|
||||
.data([0])
|
||||
.enter()
|
||||
.append('div')
|
||||
.attr('class', 'issue-reference')
|
||||
.call(t.append('issues.old_multipolygon.reference'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let validation = function checkOutdatedTags(entity, graph) {
|
||||
let issues = oldMultipolygonIssues(entity, graph);
|
||||
if (!issues.length) issues = oldTagIssues(entity, graph);
|
||||
return issues;
|
||||
};
|
||||
|
||||
let validation = oldTagIssues;
|
||||
|
||||
validation.type = type;
|
||||
|
||||
|
||||
@@ -1359,23 +1359,6 @@ describe('iD.actionSplit', function () {
|
||||
expect(graph.entity('=').nodes).to.eql(['a', 'b', 'c', 'a']);
|
||||
expect(graph.parentRelations(graph.entity('='))).to.have.length(0);
|
||||
});
|
||||
|
||||
it('converts simple multipolygon to a proper multipolygon', function () {
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({id: 'a'}),
|
||||
iD.osmNode({id: 'b'}),
|
||||
iD.osmNode({id: 'c'}),
|
||||
iD.osmWay({'id': '-', nodes: ['a', 'b', 'c'], tags: { area: 'yes' }}),
|
||||
iD.osmRelation({id: 'r', members: [{id: '-', type: 'way', role: 'outer'}], tags: {type: 'multipolygon'}})
|
||||
]);
|
||||
|
||||
graph = iD.actionSplit('b', ['='])(graph);
|
||||
|
||||
expect(graph.entity('-').tags).to.eql({});
|
||||
expect(graph.entity('r').tags).to.eql({type: 'multipolygon', area: 'yes' });
|
||||
var ids = graph.entity('r').members.map(function(m) { return m.id; });
|
||||
expect(ids).to.have.ordered.members(['-', '=']);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -1,149 +1,3 @@
|
||||
describe('iD.osmIsOldMultipolygonOuterMember', function() {
|
||||
it('returns the parent relation of a simple multipolygon outer', function() {
|
||||
var outer = iD.osmWay({tags: {'natural':'wood'}});
|
||||
var relation = iD.osmRelation(
|
||||
{tags: {type: 'multipolygon'}, members: [{id: outer.id, role: 'outer'}]}
|
||||
);
|
||||
var graph = iD.coreGraph([outer, relation]);
|
||||
expect(iD.osmIsOldMultipolygonOuterMember(outer, graph)).to.equal(relation);
|
||||
});
|
||||
|
||||
it('returns the parent relation of a simple multipolygon outer, assuming role outer if unspecified', function() {
|
||||
var outer = iD.osmWay({tags: {'natural':'wood'}});
|
||||
var relation = iD.osmRelation(
|
||||
{tags: {type: 'multipolygon'}, members: [{id: outer.id}]}
|
||||
);
|
||||
var graph = iD.coreGraph([outer, relation]);
|
||||
expect(iD.osmIsOldMultipolygonOuterMember(outer, graph)).to.equal(relation);
|
||||
});
|
||||
|
||||
it('returns false if entity is not a way', function() {
|
||||
var outer = iD.osmNode({tags: {'natural':'wood'}});
|
||||
var relation = iD.osmRelation(
|
||||
{tags: {type: 'multipolygon'}, members: [{id: outer.id, role: 'outer'}]}
|
||||
);
|
||||
var graph = iD.coreGraph([outer, relation]);
|
||||
expect(iD.osmIsOldMultipolygonOuterMember(outer, graph)).to.be.false;
|
||||
});
|
||||
|
||||
it('returns false if entity does not have interesting tags', function() {
|
||||
var outer = iD.osmWay({tags: {'tiger:reviewed':'no'}});
|
||||
var relation = iD.osmRelation(
|
||||
{tags: {type: 'multipolygon'}, members: [{id: outer.id, role: 'outer'}]}
|
||||
);
|
||||
var graph = iD.coreGraph([outer, relation]);
|
||||
expect(iD.osmIsOldMultipolygonOuterMember(outer, graph)).to.be.false;
|
||||
});
|
||||
|
||||
it('returns false if entity does not have a parent relation', function() {
|
||||
var outer = iD.osmWay({tags: {'natural':'wood'}});
|
||||
var graph = iD.coreGraph([outer]);
|
||||
expect(iD.osmIsOldMultipolygonOuterMember(outer, graph)).to.be.false;
|
||||
});
|
||||
|
||||
it('returns false if the parent is not a multipolygon', function() {
|
||||
var outer = iD.osmWay({tags: {'natural':'wood'}});
|
||||
var relation = iD.osmRelation(
|
||||
{tags: {type: 'route'}, members: [{id: outer.id, role: 'outer'}]}
|
||||
);
|
||||
var graph = iD.coreGraph([outer, relation]);
|
||||
expect(iD.osmIsOldMultipolygonOuterMember(outer, graph)).to.be.false;
|
||||
});
|
||||
|
||||
it('returns false if the parent has interesting tags', function() {
|
||||
var outer = iD.osmWay({tags: {'natural':'wood'}});
|
||||
var relation = iD.osmRelation(
|
||||
{tags: {natural: 'wood', type: 'multipolygon'}, members: [{id: outer.id, role: 'outer'}]}
|
||||
);
|
||||
var graph = iD.coreGraph([outer, relation]);
|
||||
expect(iD.osmIsOldMultipolygonOuterMember(outer, graph)).to.be.false;
|
||||
});
|
||||
|
||||
it('returns the parent relation of a simple multipolygon outer, ignoring uninteresting parent tags', function() {
|
||||
var outer = iD.osmWay({tags: {'natural':'wood'}});
|
||||
var relation = iD.osmRelation(
|
||||
{tags: {'tiger:reviewed':'no', type: 'multipolygon'}, members: [{id: outer.id, role: 'outer'}]}
|
||||
);
|
||||
var graph = iD.coreGraph([outer, relation]);
|
||||
expect(iD.osmIsOldMultipolygonOuterMember(outer, graph)).to.equal(relation);
|
||||
});
|
||||
|
||||
it('returns false if the parent has multiple outer ways', function() {
|
||||
var outer1 = iD.osmWay({tags: {'natural':'wood'}});
|
||||
var outer2 = iD.osmWay({tags: {'natural':'wood'}});
|
||||
var relation = iD.osmRelation(
|
||||
{tags: {type: 'multipolygon'}, members: [{id: outer1.id, role: 'outer'}, {id: outer2.id, role: 'outer'}]}
|
||||
);
|
||||
var graph = iD.coreGraph([outer1, outer2, relation]);
|
||||
expect(iD.osmIsOldMultipolygonOuterMember(outer1, graph)).to.be.false;
|
||||
expect(iD.osmIsOldMultipolygonOuterMember(outer2, graph)).to.be.false;
|
||||
});
|
||||
|
||||
it('returns false if the parent has multiple outer ways, assuming role outer if unspecified', function() {
|
||||
var outer1 = iD.osmWay({tags: {'natural':'wood'}});
|
||||
var outer2 = iD.osmWay({tags: {'natural':'wood'}});
|
||||
var relation = iD.osmRelation(
|
||||
{tags: {type: 'multipolygon'}, members: [{id: outer1.id}, {id: outer2.id}]}
|
||||
);
|
||||
var graph = iD.coreGraph([outer1, outer2, relation]);
|
||||
expect(iD.osmIsOldMultipolygonOuterMember(outer1, graph)).to.be.false;
|
||||
expect(iD.osmIsOldMultipolygonOuterMember(outer2, graph)).to.be.false;
|
||||
});
|
||||
|
||||
it('returns false if the entity is not an outer', function() {
|
||||
var inner = iD.osmWay({tags: {'natural':'wood'}});
|
||||
var relation = iD.osmRelation(
|
||||
{tags: {type: 'multipolygon'}, members: [{id: inner.id, role: 'inner'}]}
|
||||
);
|
||||
var graph = iD.coreGraph([inner, relation]);
|
||||
expect(iD.osmIsOldMultipolygonOuterMember(inner, graph)).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('iD.osmOldMultipolygonOuterMember', function() {
|
||||
it('returns the outer member of a simple multipolygon', function() {
|
||||
var inner = iD.osmWay();
|
||||
var outer = iD.osmWay({tags: {'natural':'wood'}});
|
||||
var relation = iD.osmRelation({tags: {type: 'multipolygon'}, members: [
|
||||
{id: outer.id, role: 'outer'},
|
||||
{id: inner.id, role: 'inner'}]
|
||||
});
|
||||
var graph = iD.coreGraph([inner, outer, relation]);
|
||||
|
||||
expect(iD.osmOldMultipolygonOuterMember(inner, graph)).to.equal(outer);
|
||||
expect(iD.osmOldMultipolygonOuterMember(outer, graph)).to.equal(outer);
|
||||
});
|
||||
|
||||
it('returns falsy for a complex multipolygon', function() {
|
||||
var inner = iD.osmWay();
|
||||
var outer1 = iD.osmWay({tags: {'natural':'wood'}});
|
||||
var outer2 = iD.osmWay({tags: {'natural':'wood'}});
|
||||
var relation = iD.osmRelation({tags: {type: 'multipolygon'}, members: [
|
||||
{id: outer1.id, role: 'outer'},
|
||||
{id: outer2.id, role: 'outer'},
|
||||
{id: inner.id, role: 'inner'}]
|
||||
});
|
||||
var graph = iD.coreGraph([inner, outer1, outer2, relation]);
|
||||
|
||||
expect(iD.osmOldMultipolygonOuterMember(inner, graph)).not.to.be.ok;
|
||||
expect(iD.osmOldMultipolygonOuterMember(outer1, graph)).not.to.be.ok;
|
||||
expect(iD.osmOldMultipolygonOuterMember(outer2, graph)).not.to.be.ok;
|
||||
});
|
||||
|
||||
it('handles incomplete relations', function() {
|
||||
var way = iD.osmWay({id: 'w'});
|
||||
var relation = iD.osmRelation({id: 'r', tags: {type: 'multipolygon'}, members: [
|
||||
{id: 'o', role: 'outer'},
|
||||
{id: 'w', role: 'inner'}]
|
||||
});
|
||||
var graph = iD.coreGraph([way, relation]);
|
||||
|
||||
expect(iD.osmOldMultipolygonOuterMember(way, graph)).not.to.be.ok;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('iD.osmJoinWays', function() {
|
||||
function getIDs(objects) {
|
||||
return objects.map(function(node) { return node.id; });
|
||||
|
||||
@@ -144,32 +144,4 @@ describe('iD.svgAreas', function () {
|
||||
|
||||
expect(_surface.selectAll('.stroke').size()).to.equal(0);
|
||||
});
|
||||
|
||||
it('renders fill for a multipolygon with tags on the outer way', function() {
|
||||
var a = iD.osmNode({loc: [1, 1]});
|
||||
var b = iD.osmNode({loc: [2, 2]});
|
||||
var c = iD.osmNode({loc: [3, 3]});
|
||||
var w = iD.osmWay({tags: {natural: 'wood'}, nodes: [a.id, b.id, c.id, a.id]});
|
||||
var r = iD.osmRelation({members: [{id: w.id, type: 'way'}], tags: {type: 'multipolygon'}});
|
||||
var graph = iD.coreGraph([a, b, c, w, r]);
|
||||
|
||||
_surface.call(iD.svgAreas(projection, context), graph, [w, r], none);
|
||||
|
||||
expect(_surface.selectAll('.way.fill').size()).to.equal(0);
|
||||
expect(_surface.selectAll('.relation.fill').size()).to.equal(1);
|
||||
expect(_surface.select('.relation.fill').classed('tag-natural-wood')).to.be.true;
|
||||
});
|
||||
|
||||
it('renders no strokes for a multipolygon with tags on the outer way', function() {
|
||||
var a = iD.osmNode({loc: [1, 1]});
|
||||
var b = iD.osmNode({loc: [2, 2]});
|
||||
var c = iD.osmNode({loc: [3, 3]});
|
||||
var w = iD.osmWay({tags: {natural: 'wood'}, nodes: [a.id, b.id, c.id, a.id]});
|
||||
var r = iD.osmRelation({members: [{id: w.id, type: 'way'}], tags: {type: 'multipolygon'}});
|
||||
var graph = iD.coreGraph([a, b, c, w, r]);
|
||||
|
||||
_surface.call(iD.svgAreas(projection, context), graph, [w, r], none);
|
||||
|
||||
expect(_surface.selectAll('.stroke').size()).to.equal(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -66,37 +66,6 @@ describe('iD.svgLines', function () {
|
||||
expect(surface.select('.stroke').classed('tag-natural-wood')).to.be.true;
|
||||
});
|
||||
|
||||
it('renders stroke for outer way of multipolygon with tags on the outer way', function() {
|
||||
var a = iD.osmNode({loc: [1, 1]});
|
||||
var b = iD.osmNode({loc: [2, 2]});
|
||||
var c = iD.osmNode({loc: [3, 3]});
|
||||
var w = iD.osmWay({id: 'w-1', tags: {natural: 'wood'}, nodes: [a.id, b.id, c.id, a.id]});
|
||||
var r = iD.osmRelation({members: [{id: w.id}], tags: {type: 'multipolygon'}});
|
||||
var graph = iD.coreGraph([a, b, c, w, r]);
|
||||
|
||||
surface.call(iD.svgLines(projection, context), graph, [w], all);
|
||||
|
||||
expect(surface.select('.stroke.w-1').classed('tag-natural-wood')).to.equal(true, 'outer tag-natural-wood true');
|
||||
expect(surface.select('.stroke.w-1').classed('old-multipolygon')).to.equal(true, 'outer old-multipolygon true');
|
||||
});
|
||||
|
||||
it('adds stroke classes for the tags of the outer way of multipolygon with tags on the outer way', function() {
|
||||
var a = iD.osmNode({loc: [1, 1]});
|
||||
var b = iD.osmNode({loc: [2, 2]});
|
||||
var c = iD.osmNode({loc: [3, 3]});
|
||||
var o = iD.osmWay({id: 'w-1', nodes: [a.id, b.id, c.id, a.id], tags: {natural: 'wood'}});
|
||||
var i = iD.osmWay({id: 'w-2', nodes: [a.id, b.id, c.id, a.id]});
|
||||
var r = iD.osmRelation({members: [{id: o.id, role: 'outer'}, {id: i.id, role: 'inner'}], tags: {type: 'multipolygon'}});
|
||||
var graph = iD.coreGraph([a, b, c, o, i, r]);
|
||||
|
||||
surface.call(iD.svgLines(projection, context), graph, [i, o], all);
|
||||
|
||||
expect(surface.select('.stroke.w-1').classed('tag-natural-wood')).to.equal(true, 'outer tag-natural-wood true');
|
||||
expect(surface.select('.stroke.w-1').classed('old-multipolygon')).to.equal(true, 'outer old-multipolygon true');
|
||||
expect(surface.select('.stroke.w-2').classed('tag-natural-wood')).to.equal(true, 'inner tag-natural-wood true');
|
||||
expect(surface.select('.stroke.w-2').classed('old-multipolygon')).to.equal(false, 'inner old-multipolygon false');
|
||||
});
|
||||
|
||||
describe('z-indexing', function() {
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({id: 'a', loc: [0, 0]}),
|
||||
|
||||
@@ -125,21 +125,4 @@ describe('iD.validations.outdated_tags', function () {
|
||||
done();
|
||||
}, 20);
|
||||
});
|
||||
|
||||
it('flags multipolygon tagged on the outer way', function(done) {
|
||||
createRelation({ building: 'yes' }, { type: 'multipolygon' });
|
||||
var validator = iD.validationOutdatedTags(context);
|
||||
window.setTimeout(function() { // async, so data will be available
|
||||
var issues = validate(validator);
|
||||
expect(issues).to.not.have.lengthOf(0);
|
||||
var issue = issues[0];
|
||||
expect(issue.type).to.eql('outdated_tags');
|
||||
expect(issue.subtype).to.eql('old_multipolygon');
|
||||
expect(issue.entityIds).to.have.lengthOf(2);
|
||||
expect(issue.entityIds[0]).to.eql('w-1');
|
||||
expect(issue.entityIds[1]).to.eql('r-1');
|
||||
done();
|
||||
}, 20);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user