diff --git a/CHANGELOG.md b/CHANGELOG.md index ee71be19e..f0ada8d81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/modules/actions/split.js b/modules/actions/split.js index 172ec59aa..042b25aa0 100644 --- a/modules/actions/split.js +++ b/modules/actions/split.js @@ -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: [ diff --git a/modules/osm/index.js b/modules/osm/index.js index 755b7d91c..0046d72ca 100644 --- a/modules/osm/index.js +++ b/modules/osm/index.js @@ -17,9 +17,6 @@ export { } from './lanes'; export { - osmOldMultipolygonOuterMemberOfRelation, - osmIsOldMultipolygonOuterMember, - osmOldMultipolygonOuterMember, osmJoinWays } from './multipolygon'; diff --git a/modules/osm/multipolygon.js b/modules/osm/multipolygon.js index bbbb6b337..d227320f1 100644 --- a/modules/osm/multipolygon.js +++ b/modules/osm/multipolygon.js @@ -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, diff --git a/modules/svg/areas.js b/modules/svg/areas.js index 6a0da6d3c..49a7b309f 100644 --- a/modules/svg/areas.js +++ b/modules/svg/areas.js @@ -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)) diff --git a/modules/svg/lines.js b/modules/svg/lines.js index ba979478d..d380c5658 100644 --- a/modules/svg/lines.js +++ b/modules/svg/lines.js @@ -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 diff --git a/modules/validations/missing_tag.js b/modules/validations/missing_tag.js index 0c091855a..fd9f278f5 100644 --- a/modules/validations/missing_tag.js +++ b/modules/validations/missing_tag.js @@ -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; diff --git a/modules/validations/outdated_tags.js b/modules/validations/outdated_tags.js index 02114b927..6a5153815 100644 --- a/modules/validations/outdated_tags.js +++ b/modules/validations/outdated_tags.js @@ -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; diff --git a/test/spec/actions/split.js b/test/spec/actions/split.js index e5ea57a1f..7a4dfd635 100644 --- a/test/spec/actions/split.js +++ b/test/spec/actions/split.js @@ -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(['-', '=']); - }); }); diff --git a/test/spec/osm/multipolygon.js b/test/spec/osm/multipolygon.js index 646356954..a6e31c04f 100644 --- a/test/spec/osm/multipolygon.js +++ b/test/spec/osm/multipolygon.js @@ -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; }); diff --git a/test/spec/svg/areas.js b/test/spec/svg/areas.js index 571698787..69cab63f7 100644 --- a/test/spec/svg/areas.js +++ b/test/spec/svg/areas.js @@ -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); - }); }); diff --git a/test/spec/svg/lines.js b/test/spec/svg/lines.js index e4f6c60b8..9cff4aa5f 100644 --- a/test/spec/svg/lines.js +++ b/test/spec/svg/lines.js @@ -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]}), diff --git a/test/spec/validations/outdated_tags.js b/test/spec/validations/outdated_tags.js index 6f5d042e4..0a64a11bb 100644 --- a/test/spec/validations/outdated_tags.js +++ b/test/spec/validations/outdated_tags.js @@ -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); - }); - });