mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-13 01:02:58 +00:00
Render restriction paths with red/green/blue shadow
This commit is contained in:
@@ -26,6 +26,11 @@
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.lasso #map {
|
||||
pointer-events: visibleStroke;
|
||||
}
|
||||
|
||||
|
||||
/* `.target` objects are interactive */
|
||||
/* They can be picked up, clicked, hovered, or things can connect to them */
|
||||
.node.target {
|
||||
@@ -242,7 +247,7 @@ text.point {
|
||||
}
|
||||
|
||||
|
||||
/* Turns */
|
||||
/* Turn Restrictions */
|
||||
|
||||
g.turn rect,
|
||||
g.turn circle {
|
||||
@@ -255,9 +260,30 @@ g.turn circle {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.lasso #map {
|
||||
pointer-events: visibleStroke;
|
||||
/* Turn restriction paths and vertices */
|
||||
.surface.tr path.shadow.selected,
|
||||
.surface.tr path.shadow.related,
|
||||
.surface.tr g.vertex.selected .shadow,
|
||||
.surface.tr g.vertex.related .shadow {
|
||||
stroke-opacity: 0.7;
|
||||
stroke: #777;
|
||||
}
|
||||
.surface.tr path.shadow.related.allow,
|
||||
.surface.tr g.vertex.related.allow .shadow {
|
||||
stroke: #7a4;
|
||||
/*stroke: #8cd05f;*/
|
||||
}
|
||||
.surface.tr path.shadow.related.restrict,
|
||||
.surface.tr g.vertex.related.restrict .shadow {
|
||||
stroke: #d75;
|
||||
/*stroke: #e06d5f;*/
|
||||
}
|
||||
.surface.tr path.shadow.related.only,
|
||||
.surface.tr g.vertex.related.only .shadow {
|
||||
stroke: #78f;
|
||||
/*stroke: #7092ff;*/
|
||||
}
|
||||
|
||||
|
||||
/* GPX Paths */
|
||||
|
||||
|
||||
@@ -1910,10 +1910,10 @@ input[type=number] {
|
||||
font-weight: bold;
|
||||
}
|
||||
.restriction-help span.qualifier.allow {
|
||||
color: #8b5;
|
||||
color: #7a4;
|
||||
}
|
||||
.restriction-help span.qualifier.restrict {
|
||||
color: #d76;
|
||||
color: #d75;
|
||||
}
|
||||
.restriction-help span.qualifier.only {
|
||||
color: #78f;
|
||||
|
||||
@@ -210,7 +210,6 @@ export function osmIntersection(graph, startVertexId, maxDistance) {
|
||||
vertexIds.forEach(function(id) {
|
||||
var vertex = vgraph.entity(id);
|
||||
var parents = vgraph.parentWays(vertex);
|
||||
|
||||
vertices.push(vertex);
|
||||
ways = ways.concat(parents);
|
||||
});
|
||||
@@ -243,8 +242,21 @@ export function osmIntersection(graph, startVertexId, maxDistance) {
|
||||
__from: __from,
|
||||
__via: __via,
|
||||
__to: __to,
|
||||
__oneWay: __oneWay
|
||||
__oneWay: __oneWay,
|
||||
__fromOnly: fromOnly(way)
|
||||
});
|
||||
|
||||
function fromOnly(way) {
|
||||
var parents = vgraph.parentRelations(way);
|
||||
for (var i = 0; i < parents.length; i++) {
|
||||
var r = parents[i];
|
||||
var f = r.memberByRole('from');
|
||||
if (r.isRestriction() && /^only_/.test(r.tags.restriction) && f.id === way.id) {
|
||||
return r.id;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
ways = [];
|
||||
@@ -583,7 +595,7 @@ export function osmIntersection(graph, startVertexId, maxDistance) {
|
||||
}
|
||||
|
||||
return {
|
||||
key: path.join(','),
|
||||
key: path.join('_'),
|
||||
path: path,
|
||||
from: { node: fromNodeId, way: fromWayId, vertex: fromVertexId },
|
||||
via: { node: viaNodeId, ways: viaWayIds },
|
||||
|
||||
@@ -30,10 +30,10 @@ export function svgTurns(projection) {
|
||||
|
||||
var enter = groups.enter()
|
||||
.append('g')
|
||||
.attr('class', 'turn');
|
||||
.attr('class', function(d) { return 'turn ' + d.key; });
|
||||
|
||||
var nEnter = enter
|
||||
.filter(function (turn) { return !turn.u; });
|
||||
.filter(function(d) { return !d.u; });
|
||||
|
||||
nEnter.append('rect')
|
||||
.attr('transform', 'translate(-22, -12)')
|
||||
@@ -47,7 +47,7 @@ export function svgTurns(projection) {
|
||||
|
||||
|
||||
var uEnter = enter
|
||||
.filter(function (turn) { return turn.u; });
|
||||
.filter(function(d) { return d.u; });
|
||||
|
||||
uEnter.append('circle')
|
||||
.attr('r', '16');
|
||||
@@ -62,23 +62,23 @@ export function svgTurns(projection) {
|
||||
.merge(enter);
|
||||
|
||||
groups
|
||||
.attr('opacity', function (turn) {
|
||||
return turn.direct === false ? '0.7' : null;
|
||||
.attr('opacity', function(d) {
|
||||
return d.direct === false ? '0.7' : null;
|
||||
})
|
||||
.attr('transform', function (turn) {
|
||||
.attr('transform', function(d) {
|
||||
var pxRadius = 50;
|
||||
var toWay = graph.entity(turn.to.way);
|
||||
var toWay = graph.entity(d.to.way);
|
||||
var toPoints = graph.childNodes(toWay)
|
||||
.map(function (n) { return n.loc; })
|
||||
.map(projection);
|
||||
var toLength = geoPathLength(toPoints);
|
||||
var mid = toLength / 2; // midpoint of destination way
|
||||
|
||||
var toNode = graph.entity(turn.to.node);
|
||||
var toVertex = graph.entity(turn.to.vertex);
|
||||
var toNode = graph.entity(d.to.node);
|
||||
var toVertex = graph.entity(d.to.vertex);
|
||||
var a = geoAngle(toVertex, toNode, projection);
|
||||
var o = projection(toVertex.loc);
|
||||
var r = turn.u ? 0 // u-turn: no radius
|
||||
var r = d.u ? 0 // u-turn: no radius
|
||||
: !toWay.__via ? pxRadius // leaf way: put marker at pxRadius
|
||||
: Math.min(mid, pxRadius); // via way: prefer pxRadius, fallback to mid for very short ways
|
||||
|
||||
|
||||
@@ -283,7 +283,8 @@ export function uiFieldRestrictions(field, context) {
|
||||
selection
|
||||
.call(drawLayers);
|
||||
|
||||
var surface = selection.selectAll('.surface');
|
||||
var surface = selection.selectAll('.surface')
|
||||
.classed('tr', true);
|
||||
|
||||
if (firstTime) {
|
||||
_initialized = true;
|
||||
@@ -314,20 +315,26 @@ export function uiFieldRestrictions(field, context) {
|
||||
|
||||
surface
|
||||
.on('click.restrictions', click)
|
||||
.on('mouseover.restrictions', mouseover)
|
||||
.on('mouseout.restrictions', mouseout);
|
||||
.on('mouseover.restrictions', mouseover);
|
||||
|
||||
surface
|
||||
.selectAll('.selected')
|
||||
.classed('selected', false);
|
||||
|
||||
surface
|
||||
.selectAll('.related')
|
||||
.classed('related', false);
|
||||
|
||||
if (_fromWayID) {
|
||||
var way = vgraph.entity(_fromWayID);
|
||||
surface
|
||||
.selectAll('.' + _fromWayID)
|
||||
.classed('selected', true);
|
||||
.classed('selected', true)
|
||||
.classed('related', true)
|
||||
.classed('only', !!way.__fromOnly);
|
||||
}
|
||||
|
||||
mouseout();
|
||||
updateHelp(null);
|
||||
|
||||
|
||||
function click() {
|
||||
@@ -351,6 +358,7 @@ export function uiFieldRestrictions(field, context) {
|
||||
|
||||
if (datum.restrictionID && !datum.direct) {
|
||||
return;
|
||||
|
||||
} else if (datum.restrictionID && !datum.only) { // cycle thru the `only_` state
|
||||
var datumOnly = _cloneDeep(datum);
|
||||
datumOnly.only = true;
|
||||
@@ -371,8 +379,15 @@ export function uiFieldRestrictions(field, context) {
|
||||
t('operations.restriction.annotation.create')
|
||||
]);
|
||||
}
|
||||
|
||||
context.perform.apply(context, actions);
|
||||
|
||||
// At this point the datum will be changed, but will have same key..
|
||||
// Refresh it and update the help..
|
||||
var s = surface.selectAll('.' + datum.key);
|
||||
datum = s.empty() ? null : s.datum();
|
||||
updateHelp(datum);
|
||||
|
||||
} else {
|
||||
_fromWayID = null;
|
||||
redraw();
|
||||
@@ -386,24 +401,6 @@ export function uiFieldRestrictions(field, context) {
|
||||
}
|
||||
|
||||
|
||||
function mouseout() {
|
||||
var help = _container.selectAll('.restriction-help').html('');
|
||||
var div = help.append('div');
|
||||
var d;
|
||||
|
||||
if (_fromWayID) {
|
||||
d = display(vgraph.entity(_fromWayID), vgraph);
|
||||
div.append('span').attr('class', 'qualifier').text('FROM');
|
||||
div.append('span').text(d.name || d.type);
|
||||
|
||||
} else {
|
||||
div.append('span').text('Click to select the');
|
||||
div.append('span').attr('class', 'qualifier').text('FROM');
|
||||
div.append('span').text('way');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function redraw() {
|
||||
if (context.hasEntity(_vertexID)) {
|
||||
_container.call(renderViewer);
|
||||
@@ -413,7 +410,7 @@ export function uiFieldRestrictions(field, context) {
|
||||
|
||||
function updateHelp(datum) {
|
||||
var help = _container.selectAll('.restriction-help').html('');
|
||||
var div, d;
|
||||
var div, d, turnType, r;
|
||||
|
||||
var entity = datum && datum.properties && datum.properties.entity;
|
||||
if (entity) {
|
||||
@@ -421,24 +418,44 @@ export function uiFieldRestrictions(field, context) {
|
||||
}
|
||||
|
||||
surface.selectAll('.related')
|
||||
.classed('related', false);
|
||||
.classed('related', false)
|
||||
.classed('allow', false)
|
||||
.classed('restrict', false)
|
||||
.classed('only', false);
|
||||
|
||||
|
||||
if (datum instanceof osmWay) {
|
||||
surface.selectAll('.' + datum.id)
|
||||
.classed('related', true)
|
||||
.classed('only', !!datum.__fromOnly);
|
||||
|
||||
if (datum.__fromOnly) {
|
||||
r = vgraph.entity(datum.__fromOnly);
|
||||
|
||||
turnType = {
|
||||
'only_left_turn': 'Left Turn',
|
||||
'only_right_turn': 'Right Turn',
|
||||
'only_u_turn': 'U-Turn',
|
||||
'only_straight_on': 'Straight On'
|
||||
}[r.tags.restriction];
|
||||
|
||||
div = help.append('div');
|
||||
div.append('span').attr('class', 'qualifier only').text('ONLY ' + turnType);
|
||||
}
|
||||
|
||||
d = display(vgraph.entity(datum.id), vgraph);
|
||||
div = help.append('div');
|
||||
div.append('span').attr('class', 'qualifier').text('FROM');
|
||||
div.append('span').text(d.name || d.type);
|
||||
|
||||
} else if (datum instanceof osmTurn) {
|
||||
surface.selectAll(utilEntitySelector(datum.key.split(',')))
|
||||
.classed('related', true);
|
||||
|
||||
} else if (datum instanceof osmTurn) {
|
||||
var fromWayID = datum.from.way;
|
||||
var viaWayIDs = datum.via.ways;
|
||||
var toWayID = datum.to.way;
|
||||
var restrictionType = osmInferRestriction(vgraph, datum, projection);
|
||||
|
||||
var turnType = {
|
||||
turnType = {
|
||||
'no_left_turn': 'Left Turn',
|
||||
'no_right_turn': 'Right Turn',
|
||||
'no_u_turn': 'U-Turn',
|
||||
@@ -450,13 +467,19 @@ export function uiFieldRestrictions(field, context) {
|
||||
if (datum.no) { restrictType = 'NO'; klass = 'restrict'; }
|
||||
if (datum.only) { restrictType = 'ONLY'; klass = 'only'; }
|
||||
|
||||
var alongIDs = datum.path.slice();
|
||||
surface.selectAll(utilEntitySelector(alongIDs))
|
||||
.classed('related', true)
|
||||
.classed('allow', (klass === 'allow'))
|
||||
.classed('restrict', (klass === 'restrict'))
|
||||
.classed('only', (klass === 'only'));
|
||||
|
||||
|
||||
var s = (klass === 'allow' ? turnType + ' Allowed' : restrictType + ' ' + turnType);
|
||||
if (datum.direct === false) { s += ' (indirect)'; }
|
||||
|
||||
div = help.append('div');
|
||||
div.append('span')
|
||||
.attr('class', 'qualifier ' + klass)
|
||||
.text(s);
|
||||
div.append('span').attr('class', 'qualifier ' + klass).text(s);
|
||||
|
||||
div = help.append('div');
|
||||
d = display(vgraph.entity(fromWayID), vgraph);
|
||||
@@ -482,6 +505,40 @@ export function uiFieldRestrictions(field, context) {
|
||||
prev = curr;
|
||||
}
|
||||
}
|
||||
|
||||
} else { // datum is empty surface
|
||||
if (_fromWayID) {
|
||||
var way = vgraph.entity(_fromWayID);
|
||||
surface
|
||||
.selectAll('.' + _fromWayID)
|
||||
.classed('selected', true)
|
||||
.classed('related', true)
|
||||
.classed('only', !!way.__fromOnly);
|
||||
|
||||
if (way.__fromOnly) {
|
||||
r = vgraph.entity(way.__fromOnly);
|
||||
|
||||
turnType = {
|
||||
'only_left_turn': 'Left Turn',
|
||||
'only_right_turn': 'Right Turn',
|
||||
'only_u_turn': 'U-Turn',
|
||||
'only_straight_on': 'Straight On'
|
||||
}[r.tags.restriction];
|
||||
|
||||
div = help.append('div');
|
||||
div.append('span').attr('class', 'qualifier only').text('ONLY ' + turnType);
|
||||
}
|
||||
|
||||
d = display(vgraph.entity(_fromWayID), vgraph);
|
||||
div = help.append('div');
|
||||
div.append('span').attr('class', 'qualifier').text('FROM');
|
||||
div.append('span').text(d.name || d.type);
|
||||
} else {
|
||||
div = help.append('div');
|
||||
div.append('span').text('Click to select the');
|
||||
div.append('span').attr('class', 'qualifier').text('FROM');
|
||||
div.append('span').text('way');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -516,8 +573,7 @@ export function uiFieldRestrictions(field, context) {
|
||||
.call(hover.off)
|
||||
.call(breathe.off)
|
||||
.on('click.restrictions', null)
|
||||
.on('mouseover.restrictions', null)
|
||||
.on('mouseout.restrictions', null);
|
||||
.on('mouseover.restrictions', null);
|
||||
|
||||
d3_select(window)
|
||||
.on('resize.restrictions', null);
|
||||
|
||||
Reference in New Issue
Block a user