Improve "add a bridge/tunnel" fixes by basing the structure length on the crossed feature type, not a fixed constant (re: #7202)

This commit is contained in:
Quincy Morgan
2020-01-08 12:03:30 -05:00
parent 0e629a8057
commit 09ad21a26f
2 changed files with 59 additions and 7 deletions
+36
View File
@@ -102,6 +102,42 @@ Object.assign(osmWay.prototype, {
},
// the approximate width of the line based on its tags except its `width` tag
impliedLineWidthMeters: function() {
var averageWidths = {
highway: { // width is for single lane
motorway: 5, motorway_link: 5, trunk: 4.5, trunk_link: 4.5,
primary: 4, secondary: 4, tertiary: 4,
primary_link: 4, secondary_link: 4, tertiary_link: 4,
unclassified: 4, road: 4, living_street: 4, bus_guideway: 4, pedestrian: 4,
residential: 3.5, service: 3.5, track: 3, cycleway: 2.5,
bridleway: 2, corridor: 2, steps: 2, path: 1.5, footway: 1.5
},
railway: { // width includes ties and rail bed, not just track gauge
rail: 2.5, light_rail: 2.5, tram: 2.5, subway: 2.5,
monorail: 2.5, funicular: 2.5, disused: 2.5, preserved: 2.5,
miniature: 1.5, narrow_gauge: 1.5
},
waterway: {
river: 50, canal: 25, stream: 5, tidal_channel: 5, fish_pass: 2.5, drain: 2.5, ditch: 1.5
}
};
for (var key in averageWidths) {
if (this.tags[key] && averageWidths[key][this.tags[key]]) {
var width = averageWidths[key][this.tags[key]];
if (key === 'highway') {
var laneCount = this.tags.lanes && parseInt(this.tags.lanes, 10);
if (!laneCount) laneCount = this.isOneWay() ? 1 : 2;
return width * laneCount;
}
return width;
}
}
return null;
},
isOneWay: function() {
// explicit oneway tag..
var values = {
+23 -7
View File
@@ -475,10 +475,10 @@ export function validationCrossingWays(context) {
var resultWayIDs = [selectedWayID];
var crossingWayID = this.issue.entityIds[0];
var crossedWayID = this.issue.entityIds[0];
var edge = this.issue.data.edges[1];
if (this.issue.entityIds[0] === selectedWayID) {
crossingWayID = this.issue.entityIds[1];
crossedWayID = this.issue.entityIds[1];
edge = this.issue.data.edges[0];
}
@@ -488,14 +488,30 @@ export function validationCrossingWays(context) {
var edgeNodes = [graph.entity(edge[0]), graph.entity(edge[1])];
var crossingWay = graph.hasEntity(crossingWayID);
// use the width of the crossing feature as the structure length, if available
var widthMeters = crossingWay && crossingWay.tags.width && parseFloat(crossingWay.tags.width);
var crossedWay = graph.hasEntity(crossedWayID);
// use the explicit width of the crossed feature as the structure length, if available
var widthMeters = crossedWay && crossedWay.tags.width && parseFloat(crossedWay.tags.width);
if (!widthMeters) {
widthMeters = crossedWay && crossedWay.impliedLineWidthMeters();
}
if (widthMeters) {
if (getFeatureTypeForTags(crossedWay.tags) === 'railway') {
// rail bridges are generally much wider than the rail bed itself, compensate
widthMeters *= 2;
}
} else {
// should ideally never land here since all rail/water/road tags should have implied width
widthMeters = 8;
}
// add padding since the structure must extend past the edges of the crossed feature
widthMeters += 4;
// clamp the width to a reasonable range
if (widthMeters) widthMeters = Math.min(Math.max(widthMeters, 0.5), 50);
widthMeters = Math.min(Math.max(widthMeters, 4), 50);
// the proposed length of the structure, in decimal degrees
var structLength = (widthMeters && geoMetersToLon(widthMeters, crossingLoc[1])) || 0.00008;
var structLength = geoMetersToLon(widthMeters, crossingLoc[1]);
var halfStructLength = structLength / 2;
var angle = geoVecAngle(edgeNodes[0].loc, edgeNodes[1].loc);