From 3ded861e438abfe1533dbded2a2867e8d69449d6 Mon Sep 17 00:00:00 2001 From: ak8abhinay Date: Mon, 2 Feb 2026 03:35:14 +0000 Subject: [PATCH] Validation: Remove layer fixes for building overlaps --- data/core.yaml | 3 +- modules/validations/crossing_ways.js | 46 ++++++++++++++++++++-------- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/data/core.yaml b/data/core.yaml index dcbbc2e45c4..5f617e2d350 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -1811,7 +1811,8 @@ en: aeroway-waterway: reference: "Aeroways crossing waterways should use tunnels." building-building: - reference: "Buildings should not intersect except on different layers." + message: "Buildings should not intersect. If they are vertically stacked, please use the level tag instead of layer." + reference: "Buildings should not intersect. If they are vertically stacked, please use the **level** tag instead of **layer**." building-highway: reference: "Highways crossing buildings should use bridges, tunnels, or different layers." building-railway: diff --git a/modules/validations/crossing_ways.js b/modules/validations/crossing_ways.js index f15fe3b7487..43a6c58be2c 100644 --- a/modules/validations/crossing_ways.js +++ b/modules/validations/crossing_ways.js @@ -89,21 +89,36 @@ export function validationCrossingWays(context) { return true; } + // assume 0 by default; don't use way.layer() since we account for structures here + var layer1 = tags1.layer || '0'; + var layer2 = tags2.layer || '0'; + + if (allowsBridge(featureType1) && allowsBridge(featureType2)) { + if (hasTag(tags1, 'bridge') && !hasTag(tags2, 'bridge')) return true; + if (!hasTag(tags1, 'bridge') && hasTag(tags2, 'bridge')) return true; + // crossing bridges must use different layers + if (hasTag(tags1, 'bridge') && hasTag(tags2, 'bridge') && layer1 !== layer2) return true; + } else if (allowsBridge(featureType1) && hasTag(tags1, 'bridge')) return true; + else if (allowsBridge(featureType2) && hasTag(tags2, 'bridge')) return true; + + if (allowsTunnel(featureType1) && allowsTunnel(featureType2)) { + if (hasTag(tags1, 'tunnel') && !hasTag(tags2, 'tunnel')) return true; + if (!hasTag(tags1, 'tunnel') && hasTag(tags2, 'tunnel')) return true; + // crossing tunnels must use different layers + if (hasTag(tags1, 'tunnel') && hasTag(tags2, 'tunnel') && layer1 !== layer2) return true; + } else if (allowsTunnel(featureType1) && hasTag(tags1, 'tunnel')) return true; + else if (allowsTunnel(featureType2) && hasTag(tags2, 'tunnel')) return true; + // don't flag crossing waterways and pier/highways if (featureType1 === 'waterway' && featureType2 === 'highway' && tags2.man_made === 'pier') return true; if (featureType2 === 'waterway' && featureType1 === 'highway' && tags1.man_made === 'pier') return true; - if (tags1.layer !== undefined && tags1.layer === tags2.layer) return false; // Warn if both have the same defined layer - - const isElement1Bridge = allowsBridge(featureType1) && hasTag(tags1, 'bridge'); - const isElement2Bridge = allowsBridge(featureType2) && hasTag(tags2, 'bridge'); - if (isElement1Bridge !== isElement2Bridge) return true; // Either one is bridge, the other is not - - const isElement1Tunnel = allowsTunnel(featureType1) && hasTag(tags1, 'tunnel'); - const isElement2Tunnel = allowsTunnel(featureType2) && hasTag(tags2, 'tunnel'); - if (isElement1Tunnel !== isElement2Tunnel ) return true; // Either one is tunnel, the other is not - - return (tags1.layer || '0') !== (tags2.layer || '0'); + if (featureType1 === 'building' || featureType2 === 'building' || + taggedAsIndoor(tags1) || taggedAsIndoor(tags2)) { + // for building crossings, different layers are enough + if (layer1 !== layer2) return true; + } + return false; } @@ -404,6 +419,7 @@ export function validationCrossingWays(context) { allowsTunnel(featureType2) && hasTag(entities[1].tags, 'tunnel'); var isCrossingBridges = allowsBridge(featureType1) && hasTag(entities[0].tags, 'bridge') && allowsBridge(featureType2) && hasTag(entities[1].tags, 'bridge'); + var isBothBuildings = featureType1 === 'building' && featureType2 === 'building'; var subtype = [featureType1, featureType2].sort().join('-'); @@ -475,8 +491,12 @@ export function validationCrossingWays(context) { featureType1 === 'building' || featureType2 === 'building') { - fixes.push(makeChangeLayerFix('higher')); - fixes.push(makeChangeLayerFix('lower')); + // For overlapping buildings, do not suggest changing the `layer=*` tag. + // Vertically stacked buildings should use `level=*` instead. + if (!isBothBuildings) { + fixes.push(makeChangeLayerFix('higher')); + fixes.push(makeChangeLayerFix('lower')); + } // can only add bridge/tunnel if both features are lines } else if (context.graph().geometry(this.entityIds[0]) === 'line' &&