Skip to content

Commit

Permalink
cherrypick iD#10303 (render the side tag)
Browse files Browse the repository at this point in the history
  • Loading branch information
k-yle committed Jul 3, 2024
1 parent f5cd360 commit 60ec29e
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 14 deletions.
46 changes: 34 additions & 12 deletions modules/osm/node.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Extent, vecAngle } from '@id-sdk/math';
import { utilArrayUniq } from '@id-sdk/util';
import { utilArrayUniqBy } from '@id-sdk/util';

import { osmEntity } from './entity';

Expand All @@ -16,6 +16,8 @@ osmEntity.node = osmNode;

osmNode.prototype = Object.create(osmEntity.prototype);

const SIDES = new Set(['left', 'right', 'both']);

Object.assign(osmNode.prototype, {
type: 'node',
loc: [9999, 9999],
Expand Down Expand Up @@ -48,16 +50,28 @@ Object.assign(osmNode.prototype, {

// Inspect tags and geometry to determine which direction(s) this node/vertex points
directions: function(resolver, projection) {
var val;
/** @type {{ type: 'side' | 'direction'; value: string }[]} */
const rawValues = [];
var i;

// which tag to use?
if (this.isHighwayIntersection(resolver) && (this.tags.stop || '').toLowerCase() === 'all') {
// all-way stop tag on a highway intersection
val = 'all';
rawValues.push({
type: 'direction',
value: 'all',
});
} else {
// generic side tag
if (SIDES.has(this.tags.side?.toLowerCase())) {
rawValues.push({
type: 'side',
value: this.tags.side.toLowerCase(),
});
}

// generic direction tag
val = (this.tags.direction || '').toLowerCase();
let val = (this.tags.direction || '').toLowerCase();

// better suffix-style direction tag
var re = /:direction$/i;
Expand All @@ -68,9 +82,12 @@ Object.assign(osmNode.prototype, {
break;
}
}
for (const value of val.split(';')) {
rawValues.push({ type: 'direction', value });
}
}

if (val === '') return [];
if (!rawValues.length) return [];

var cardinal = {
north: 0, n: 0,
Expand All @@ -92,26 +109,28 @@ Object.assign(osmNode.prototype, {
};


var values = val.split(';');
/** @type {{ type: 'side' | 'direction'; angle: number }[]} */
var results = [];

values.forEach(function(v) {
rawValues.forEach(({ type, value: v }) => {
// swap cardinal for numeric directions
if (cardinal[v] !== undefined) {
v = cardinal[v];
}

// numeric direction - just add to results
if (v !== '' && !isNaN(+v)) {
results.push(+v);
results.push({ type: 'direction', angle: +v });
return;
}

const isSide = type === 'side' && SIDES.has(v);

// string direction - inspect parent ways
var lookBackward =
(this.tags['traffic_sign:backward'] || v === 'backward' || v === 'both' || v === 'all');
(this.tags['traffic_sign:backward'] || v === (isSide ? 'left' : 'backward') || v === 'both' || v === 'all');
var lookForward =
(this.tags['traffic_sign:forward'] || v === 'forward' || v === 'both' || v === 'all');
(this.tags['traffic_sign:forward'] || v === (isSide ? 'right' : 'forward') || v === 'both' || v === 'all');

if (!lookForward && !lookBackward) return;

Expand All @@ -134,12 +153,15 @@ Object.assign(osmNode.prototype, {
// +90 because vecAngle returns angle from X axis, not Y (north)
var a = projection(this.loc);
var b = projection(resolver.entity(nodeId).loc);
results.push( (vecAngle(a, b) * 180 / Math.PI) + 90 );
results.push({
type: isSide ? 'side' : 'direction',
angle: (vecAngle(a, b) * 180 / Math.PI) + (isSide ? 0 : 90)
});
}, this);

}, this);

return utilArrayUniq(results);
return utilArrayUniqBy(results, item => item.type + item.angle);
},

isCrossing: function(){
Expand Down
36 changes: 36 additions & 0 deletions modules/svg/defs.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,42 @@ export function svgDefs(context) {
.attr('stroke', '#fff')
.attr('stroke-width', '0.5px')
.attr('stroke-opacity', '0.75');
_defsSelection
.append('marker')
.attr('id', 'ideditor-viewfield-marker-side')
.attr('viewBox', '0 0 16 16')
.attr('refX', 8)
.attr('refY', 16)
.attr('markerWidth', 4)
.attr('markerHeight', 4)
.attr('markerUnits', 'strokeWidth')
.attr('orient', 'auto')
.append('path')
.attr('class', 'viewfield-marker-path')
.attr('d', 'M 6 14 C 8 13.4 8 13.4 10 14 L 14 7 L 14 5 L 2 5 L 2 7 Z')
.attr('fill', '#333')
.attr('fill-opacity', '0.75')
.attr('stroke', '#fff')
.attr('stroke-width', '0.5px')
.attr('stroke-opacity', '0.75');

_defsSelection
.append('marker')
.attr('id', 'ideditor-viewfield-marker-side-wireframe')
.attr('viewBox', '0 0 16 16')
.attr('refX', 8)
.attr('refY', 16)
.attr('markerWidth', 4)
.attr('markerHeight', 4)
.attr('markerUnits', 'strokeWidth')
.attr('orient', 'auto')
.append('path')
.attr('class', 'viewfield-marker-path')
.attr('d', 'M 6 14 C 8 13.4 8 13.4 10 14 L 14 7 L 14 5 L 2 5 L 2 7 Z')
.attr('fill', 'none')
.attr('stroke', '#fff')
.attr('stroke-width', '0.5px')
.attr('stroke-opacity', '0.75');

// add patterns
var patterns = _defsSelection.selectAll('pattern')
Expand Down
4 changes: 2 additions & 2 deletions modules/svg/vertices.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,8 @@ export function svgVertices(projection, context) {
.attr('class', 'viewfield')
.attr('d', 'M0,0H0')
.merge(viewfields)
.attr('marker-start', 'url(#ideditor-viewfield-marker' + (wireframe ? '-wireframe' : '') + ')')
.attr('transform', function(d) { return 'rotate(' + d + ')'; });
.attr('marker-start', d => 'url(#ideditor-viewfield-marker' + (d.type === 'side' ? '-side' : '') + (wireframe ? '-wireframe' : '') + ')')
.attr('transform', d => `rotate(${d.angle})`);
}


Expand Down

0 comments on commit 60ec29e

Please sign in to comment.