mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-27 18:32:25 +02:00
Render turns of selected way
This commit is contained in:
+12
@@ -945,6 +945,18 @@ text.point {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
/* Turns */
|
||||
|
||||
g.turn path {
|
||||
stroke: green;
|
||||
stroke-width: 10px;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
|
||||
g.turn.restricted path {
|
||||
stroke: red;
|
||||
}
|
||||
|
||||
/* Cursors */
|
||||
|
||||
#map {
|
||||
|
||||
+1
-1
@@ -64,9 +64,9 @@
|
||||
<script src="js/id/svg/lines.js"></script>
|
||||
<script src="js/id/svg/midpoints.js"></script>
|
||||
<script src="js/id/svg/points.js"></script>
|
||||
<script src="js/id/svg/restrictions.js"></script>
|
||||
<script src="js/id/svg/surface.js"></script>
|
||||
<script src="js/id/svg/tag_classes.js"></script>
|
||||
<script src="js/id/svg/turns.js"></script>
|
||||
<script src="js/id/svg/vertices.js"></script>
|
||||
|
||||
<script src="js/id/ui.js"></script>
|
||||
|
||||
+21
-1
@@ -1,3 +1,23 @@
|
||||
iD.geo.Turn = function(turn) {
|
||||
turn = _.clone(turn);
|
||||
|
||||
turn.key = function() {
|
||||
var components = [turn.from, turn.to, turn.via, turn.toward];
|
||||
if (turn.restriction)
|
||||
components.push(turn.restriction);
|
||||
return components.map(iD.Entity.key).join('-');
|
||||
};
|
||||
|
||||
turn.angle = function(projection) {
|
||||
var v = projection(turn.via.loc),
|
||||
t = projection(turn.toward.loc);
|
||||
|
||||
return Math.atan2(t[1] - v[1], t[0] - v[0]);
|
||||
};
|
||||
|
||||
return turn;
|
||||
};
|
||||
|
||||
iD.geo.turns = function(graph, entityID) {
|
||||
var way = graph.entity(entityID);
|
||||
if (way.type !== 'way' || !way.tags.highway || way.isArea())
|
||||
@@ -19,7 +39,7 @@ iD.geo.turns = function(graph, entityID) {
|
||||
}
|
||||
});
|
||||
|
||||
return turn;
|
||||
return iD.geo.Turn(turn);
|
||||
}
|
||||
|
||||
var turns = [];
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
iD.svg.Restrictions = function(context) {
|
||||
var projection = context.projection;
|
||||
|
||||
function drawRestrictions(surface) {
|
||||
var turns = drawRestrictions.turns(context.graph(), context.selectedIDs());
|
||||
|
||||
var groups = surface.select('.layer-hit').selectAll('g.restriction')
|
||||
.data(turns, iD.Entity.key);
|
||||
|
||||
var enter = groups.enter().append('g')
|
||||
.attr('class', 'restriction');
|
||||
|
||||
enter.append('circle')
|
||||
.attr('class', 'restriction')
|
||||
.attr('r', 4);
|
||||
|
||||
groups
|
||||
.attr('transform', function(restriction) {
|
||||
var via = context.entity(restriction.memberByRole('via').id);
|
||||
return iD.svg.PointTransform(projection)(via);
|
||||
});
|
||||
|
||||
groups.exit()
|
||||
.remove();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
drawRestrictions.turns = function (graph, selectedIDs) {
|
||||
if (selectedIDs.length !== 1)
|
||||
return [];
|
||||
|
||||
var from = graph.entity(selectedIDs[0]);
|
||||
if (from.type !== 'way')
|
||||
return [];
|
||||
|
||||
return graph.parentRelations(from).filter(function(relation) {
|
||||
var f = relation.memberById(from.id),
|
||||
t = relation.memberByRole('to'),
|
||||
v = relation.memberByRole('via');
|
||||
|
||||
return relation.tags.type === 'restriction' && f.role === 'from' &&
|
||||
t && t.type === 'way' && graph.hasEntity(t.id) &&
|
||||
v && v.type === 'node' && graph.hasEntity(v.id) &&
|
||||
!graph.entity(t.id).isDegenerate() &&
|
||||
!graph.entity(f.id).isDegenerate() &&
|
||||
graph.entity(t.id).affix(v.id) &&
|
||||
graph.entity(f.id).affix(v.id);
|
||||
});
|
||||
};
|
||||
|
||||
drawRestrictions.datum = function(graph, from, restriction, projection) {
|
||||
var to = graph.entity(restriction.memberByRole('to').id),
|
||||
a = graph.entity(restriction.memberByRole('via').id),
|
||||
b;
|
||||
|
||||
if (to.first() === a.id) {
|
||||
b = graph.entity(to.nodes[1]);
|
||||
} else {
|
||||
b = graph.entity(to.nodes[to.nodes.length - 2]);
|
||||
}
|
||||
|
||||
a = projection(a.loc);
|
||||
b = projection(b.loc);
|
||||
|
||||
return {
|
||||
from: from,
|
||||
to: to,
|
||||
restriction: restriction,
|
||||
angle: Math.atan2(b[1] - a[1], b[0] - a[0])
|
||||
};
|
||||
};
|
||||
|
||||
return drawRestrictions;
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
iD.svg.Turns = function(projection) {
|
||||
return function(surface, graph, wayID) {
|
||||
var turns = wayID ? iD.geo.turns(graph, wayID) : [];
|
||||
|
||||
var groups = surface.select('.layer-hit').selectAll('g.turn')
|
||||
.data(turns, function(turn) { return turn.key(); });
|
||||
|
||||
var enter = groups.enter().append('g')
|
||||
.attr('class', 'turn');
|
||||
|
||||
enter.append('path')
|
||||
.attr('class', 'turn')
|
||||
.attr('d', function() {
|
||||
return 'M20 0 L50 0 M40 10 L50 0 M40 -10 L50 0';
|
||||
});
|
||||
|
||||
groups
|
||||
.classed('restricted', function(turn) {
|
||||
return turn.restriction;
|
||||
})
|
||||
.attr('transform', function(turn) {
|
||||
return iD.svg.PointTransform(projection)(turn.via) +
|
||||
'rotate(' + turn.angle(projection) * 180 / Math.PI + ')';
|
||||
});
|
||||
|
||||
groups.exit()
|
||||
.remove();
|
||||
|
||||
return this;
|
||||
};
|
||||
};
|
||||
@@ -1,6 +1,7 @@
|
||||
iD.ui.preset.restrictions = function(field, context) {
|
||||
var event = d3.dispatch('change'),
|
||||
entity;
|
||||
entity,
|
||||
selectedID;
|
||||
|
||||
function restrictions(selection) {
|
||||
var wrap = selection.selectAll('.preset-input-wrap')
|
||||
@@ -34,7 +35,8 @@ iD.ui.preset.restrictions = function(field, context) {
|
||||
entities = [],
|
||||
graph = context.graph(),
|
||||
lines = iD.svg.Lines(projection, context),
|
||||
vertices = iD.svg.Vertices(projection, context);
|
||||
vertices = iD.svg.Vertices(projection, context),
|
||||
turns = iD.svg.Turns(projection, context);
|
||||
|
||||
if (entity) {
|
||||
entities = graph.parentWays(entity).filter(function (parent) {
|
||||
@@ -44,9 +46,32 @@ iD.ui.preset.restrictions = function(field, context) {
|
||||
entities.push(entity);
|
||||
}
|
||||
|
||||
if (!selectedID && entities.length) {
|
||||
selectedID = entities[0].id;
|
||||
}
|
||||
|
||||
surface
|
||||
.call(vertices, graph, entities, filter, extent, z)
|
||||
.call(lines, graph, entities, filter);
|
||||
.call(lines, graph, entities, filter)
|
||||
.call(turns, graph, selectedID);
|
||||
|
||||
surface.on('click.select', function() {
|
||||
var datum = d3.event.target.__data__;
|
||||
if (datum instanceof iD.Entity) {
|
||||
selectedID = datum.id;
|
||||
render();
|
||||
}
|
||||
});
|
||||
|
||||
surface
|
||||
.selectAll('.selected')
|
||||
.classed('selected', false);
|
||||
|
||||
if (selectedID) {
|
||||
surface
|
||||
.selectAll('.' + selectedID)
|
||||
.classed('selected', true);
|
||||
}
|
||||
|
||||
context.history()
|
||||
.on('change.restrictions', render);
|
||||
@@ -59,12 +84,14 @@ iD.ui.preset.restrictions = function(field, context) {
|
||||
}
|
||||
}
|
||||
|
||||
restrictions.tags = function() {};
|
||||
|
||||
restrictions.entity = function(_) {
|
||||
entity = _;
|
||||
if (!entity || entity.id !== _.id) {
|
||||
selectedID = null;
|
||||
entity = _;
|
||||
}
|
||||
};
|
||||
|
||||
restrictions.tags = function() {};
|
||||
restrictions.focus = function() {};
|
||||
|
||||
return d3.rebind(restrictions, event, 'on');
|
||||
|
||||
+1
-1
@@ -258,7 +258,7 @@
|
||||
<script src="spec/svg/points.js"></script>
|
||||
<script src="spec/svg/vertices.js"></script>
|
||||
<script src="spec/svg/tag_classes.js"></script>
|
||||
<script src="spec/svg/restrictions.js"></script>
|
||||
<script src="spec/svg/turns.js"></script>
|
||||
|
||||
<script src="spec/ui/inspector.js"></script>
|
||||
<script src="spec/ui/raw_tag_editor.js"></script>
|
||||
|
||||
+98
-62
@@ -1,4 +1,23 @@
|
||||
describe('iD.geo.Turn', function() {
|
||||
describe('#angle', function() {
|
||||
it("calculates the angle of via to toward", function() {
|
||||
function projection(x) { return x; }
|
||||
|
||||
var turn = iD.geo.Turn({
|
||||
via: iD.Node({id: 'v', loc: [1, 0]}),
|
||||
toward: iD.Node({id: 'w', loc: [1, 1]})
|
||||
});
|
||||
|
||||
expect(turn.angle(projection)).to.eql(Math.PI / 2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("iD.geo.turns", function() {
|
||||
function properties(turns) {
|
||||
return turns.map(function (turn) { return _.pick(turn, 'from', 'to', 'via', 'toward', 'restriction') });
|
||||
}
|
||||
|
||||
it("returns an empty array for non-ways", function() {
|
||||
var graph = iD.Graph([
|
||||
iD.Node({id: 'n'})
|
||||
@@ -73,13 +92,15 @@ describe("iD.geo.turns", function() {
|
||||
it("permits turns onto a way forward", function() {
|
||||
// u====v--->w
|
||||
var graph = iD.Graph([
|
||||
iD.Node({id: 'u'}),
|
||||
iD.Node({id: 'v'}),
|
||||
iD.Node({id: 'w'}),
|
||||
iD.Way({id: '=', nodes: ['u', 'v'], tags: {highway: 'residential'}}),
|
||||
iD.Way({id: '-', nodes: ['v', 'w'], tags: {highway: 'residential'}})
|
||||
]);
|
||||
expect(iD.geo.turns(graph, '=')).to.eql([{
|
||||
iD.Node({id: 'u'}),
|
||||
iD.Node({id: 'v'}),
|
||||
iD.Node({id: 'w'}),
|
||||
iD.Way({id: '=', nodes: ['u', 'v'], tags: {highway: 'residential'}}),
|
||||
iD.Way({id: '-', nodes: ['v', 'w'], tags: {highway: 'residential'}})
|
||||
]),
|
||||
turns = iD.geo.turns(graph, '=');
|
||||
|
||||
expect(properties(turns)).to.eql([{
|
||||
from: graph.entity('='),
|
||||
to: graph.entity('-'),
|
||||
via: graph.entity('v'),
|
||||
@@ -90,13 +111,15 @@ describe("iD.geo.turns", function() {
|
||||
it("permits turns onto a way backward", function() {
|
||||
// u====v<---w
|
||||
var graph = iD.Graph([
|
||||
iD.Node({id: 'u'}),
|
||||
iD.Node({id: 'v'}),
|
||||
iD.Node({id: 'w'}),
|
||||
iD.Way({id: '=', nodes: ['u', 'v'], tags: {highway: 'residential'}}),
|
||||
iD.Way({id: '-', nodes: ['w', 'v'], tags: {highway: 'residential'}})
|
||||
]);
|
||||
expect(iD.geo.turns(graph, '=')).to.eql([{
|
||||
iD.Node({id: 'u'}),
|
||||
iD.Node({id: 'v'}),
|
||||
iD.Node({id: 'w'}),
|
||||
iD.Way({id: '=', nodes: ['u', 'v'], tags: {highway: 'residential'}}),
|
||||
iD.Way({id: '-', nodes: ['w', 'v'], tags: {highway: 'residential'}})
|
||||
]),
|
||||
turns = iD.geo.turns(graph, '=');
|
||||
|
||||
expect(properties(turns)).to.eql([{
|
||||
from: graph.entity('='),
|
||||
to: graph.entity('-'),
|
||||
via: graph.entity('v'),
|
||||
@@ -111,14 +134,16 @@ describe("iD.geo.turns", function() {
|
||||
// |
|
||||
// x
|
||||
var graph = iD.Graph([
|
||||
iD.Node({id: 'u'}),
|
||||
iD.Node({id: 'v'}),
|
||||
iD.Node({id: 'w'}),
|
||||
iD.Node({id: 'x'}),
|
||||
iD.Way({id: '=', nodes: ['u', 'v'], tags: {highway: 'residential'}}),
|
||||
iD.Way({id: '-', nodes: ['w', 'v', 'x'], tags: {highway: 'residential'}})
|
||||
]);
|
||||
expect(iD.geo.turns(graph, '=')).to.eql([{
|
||||
iD.Node({id: 'u'}),
|
||||
iD.Node({id: 'v'}),
|
||||
iD.Node({id: 'w'}),
|
||||
iD.Node({id: 'x'}),
|
||||
iD.Way({id: '=', nodes: ['u', 'v'], tags: {highway: 'residential'}}),
|
||||
iD.Way({id: '-', nodes: ['w', 'v', 'x'], tags: {highway: 'residential'}})
|
||||
]),
|
||||
turns = iD.geo.turns(graph, '=');
|
||||
|
||||
expect(properties(turns)).to.eql([{
|
||||
from: graph.entity('='),
|
||||
to: graph.entity('-'),
|
||||
via: graph.entity('v'),
|
||||
@@ -134,13 +159,15 @@ describe("iD.geo.turns", function() {
|
||||
it("permits turns from a oneway forward", function() {
|
||||
// u===>v----w
|
||||
var graph = iD.Graph([
|
||||
iD.Node({id: 'u'}),
|
||||
iD.Node({id: 'v'}),
|
||||
iD.Node({id: 'w'}),
|
||||
iD.Way({id: '=', nodes: ['u', 'v'], tags: {highway: 'residential', oneway: 'yes'}}),
|
||||
iD.Way({id: '-', nodes: ['v', 'w'], tags: {highway: 'residential'}})
|
||||
]);
|
||||
expect(iD.geo.turns(graph, '=')).to.eql([{
|
||||
iD.Node({id: 'u'}),
|
||||
iD.Node({id: 'v'}),
|
||||
iD.Node({id: 'w'}),
|
||||
iD.Way({id: '=', nodes: ['u', 'v'], tags: {highway: 'residential', oneway: 'yes'}}),
|
||||
iD.Way({id: '-', nodes: ['v', 'w'], tags: {highway: 'residential'}})
|
||||
]),
|
||||
turns = iD.geo.turns(graph, '=');
|
||||
|
||||
expect(properties(turns)).to.eql([{
|
||||
from: graph.entity('='),
|
||||
to: graph.entity('-'),
|
||||
via: graph.entity('v'),
|
||||
@@ -151,13 +178,15 @@ describe("iD.geo.turns", function() {
|
||||
it("permits turns from a reverse oneway backward", function() {
|
||||
// u<===v----w
|
||||
var graph = iD.Graph([
|
||||
iD.Node({id: 'u'}),
|
||||
iD.Node({id: 'v'}),
|
||||
iD.Node({id: 'w'}),
|
||||
iD.Way({id: '=', nodes: ['v', 'u'], tags: {highway: 'residential', oneway: '-1'}}),
|
||||
iD.Way({id: '-', nodes: ['v', 'w'], tags: {highway: 'residential'}})
|
||||
]);
|
||||
expect(iD.geo.turns(graph, '=')).to.eql([{
|
||||
iD.Node({id: 'u'}),
|
||||
iD.Node({id: 'v'}),
|
||||
iD.Node({id: 'w'}),
|
||||
iD.Way({id: '=', nodes: ['v', 'u'], tags: {highway: 'residential', oneway: '-1'}}),
|
||||
iD.Way({id: '-', nodes: ['v', 'w'], tags: {highway: 'residential'}})
|
||||
]),
|
||||
turns = iD.geo.turns(graph, '=');
|
||||
|
||||
expect(properties(turns)).to.eql([{
|
||||
from: graph.entity('='),
|
||||
to: graph.entity('-'),
|
||||
via: graph.entity('v'),
|
||||
@@ -192,13 +221,15 @@ describe("iD.geo.turns", function() {
|
||||
it("permits turns onto a oneway forward", function() {
|
||||
// u====v--->w
|
||||
var graph = iD.Graph([
|
||||
iD.Node({id: 'u'}),
|
||||
iD.Node({id: 'v'}),
|
||||
iD.Node({id: 'w'}),
|
||||
iD.Way({id: '=', nodes: ['u', 'v'], tags: {highway: 'residential'}}),
|
||||
iD.Way({id: '-', nodes: ['v', 'w'], tags: {highway: 'residential', oneway: 'yes'}})
|
||||
]);
|
||||
expect(iD.geo.turns(graph, '=')).to.eql([{
|
||||
iD.Node({id: 'u'}),
|
||||
iD.Node({id: 'v'}),
|
||||
iD.Node({id: 'w'}),
|
||||
iD.Way({id: '=', nodes: ['u', 'v'], tags: {highway: 'residential'}}),
|
||||
iD.Way({id: '-', nodes: ['v', 'w'], tags: {highway: 'residential', oneway: 'yes'}})
|
||||
]),
|
||||
turns = iD.geo.turns(graph, '=');
|
||||
|
||||
expect(properties(turns)).to.eql([{
|
||||
from: graph.entity('='),
|
||||
to: graph.entity('-'),
|
||||
via: graph.entity('v'),
|
||||
@@ -209,13 +240,15 @@ describe("iD.geo.turns", function() {
|
||||
it("permits turns onto a reverse oneway backward", function() {
|
||||
// u====v<---w
|
||||
var graph = iD.Graph([
|
||||
iD.Node({id: 'u'}),
|
||||
iD.Node({id: 'v'}),
|
||||
iD.Node({id: 'w'}),
|
||||
iD.Way({id: '=', nodes: ['u', 'v'], tags: {highway: 'residential'}}),
|
||||
iD.Way({id: '-', nodes: ['w', 'v'], tags: {highway: 'residential', oneway: '-1'}})
|
||||
]);
|
||||
expect(iD.geo.turns(graph, '=')).to.eql([{
|
||||
iD.Node({id: 'u'}),
|
||||
iD.Node({id: 'v'}),
|
||||
iD.Node({id: 'w'}),
|
||||
iD.Way({id: '=', nodes: ['u', 'v'], tags: {highway: 'residential'}}),
|
||||
iD.Way({id: '-', nodes: ['w', 'v'], tags: {highway: 'residential', oneway: '-1'}})
|
||||
]),
|
||||
turns = iD.geo.turns(graph, '=');
|
||||
|
||||
expect(properties(turns)).to.eql([{
|
||||
from: graph.entity('='),
|
||||
to: graph.entity('-'),
|
||||
via: graph.entity('v'),
|
||||
@@ -250,18 +283,20 @@ describe("iD.geo.turns", function() {
|
||||
it("restricts turns with a restriction relation", function() {
|
||||
// u====v--->w
|
||||
var graph = iD.Graph([
|
||||
iD.Node({id: 'u'}),
|
||||
iD.Node({id: 'v'}),
|
||||
iD.Node({id: 'w'}),
|
||||
iD.Way({id: '=', nodes: ['u', 'v'], tags: {highway: 'residential'}}),
|
||||
iD.Way({id: '-', nodes: ['v', 'w'], tags: {highway: 'residential'}}),
|
||||
iD.Relation({id: 'r', tags: {type: 'restriction'}, members: [
|
||||
{id: '=', role: 'from', type: 'way'},
|
||||
{id: '-', role: 'to', type: 'way'},
|
||||
{id: 'v', role: 'via', type: 'node'}
|
||||
]})
|
||||
]);
|
||||
expect(iD.geo.turns(graph, '=')).to.eql([{
|
||||
iD.Node({id: 'u'}),
|
||||
iD.Node({id: 'v'}),
|
||||
iD.Node({id: 'w'}),
|
||||
iD.Way({id: '=', nodes: ['u', 'v'], tags: {highway: 'residential'}}),
|
||||
iD.Way({id: '-', nodes: ['v', 'w'], tags: {highway: 'residential'}}),
|
||||
iD.Relation({id: 'r', tags: {type: 'restriction'}, members: [
|
||||
{id: '=', role: 'from', type: 'way'},
|
||||
{id: '-', role: 'to', type: 'way'},
|
||||
{id: 'v', role: 'via', type: 'node'}
|
||||
]})
|
||||
]),
|
||||
turns = iD.geo.turns(graph, '=');
|
||||
|
||||
expect(properties(turns)).to.eql([{
|
||||
from: graph.entity('='),
|
||||
to: graph.entity('-'),
|
||||
via: graph.entity('v'),
|
||||
@@ -270,6 +305,7 @@ describe("iD.geo.turns", function() {
|
||||
}]);
|
||||
});
|
||||
|
||||
// 'no' vs 'only'
|
||||
// U-turns
|
||||
// Self-intersections
|
||||
// Split point
|
||||
|
||||
@@ -1,151 +1,2 @@
|
||||
describe("iD.svg.Restrictions", function() {
|
||||
var restrictions = iD.svg.Restrictions({});
|
||||
|
||||
describe("#turns", function() {
|
||||
it("returns an empty array with no selection", function() {
|
||||
var graph = iD.Graph();
|
||||
expect(restrictions.turns(graph, [])).to.eql([]);
|
||||
});
|
||||
|
||||
it("returns an empty array with a multiselection", function() {
|
||||
var graph = iD.Graph();
|
||||
expect(restrictions.turns(graph, ['a', 'b'])).to.eql([]);
|
||||
});
|
||||
|
||||
var valid = iD.Graph([
|
||||
iD.Node({id: 'u'}),
|
||||
iD.Node({id: 'v'}),
|
||||
iD.Node({id: 'w'}),
|
||||
iD.Way({id: 'f', nodes: ['u', 'v']}),
|
||||
iD.Way({id: 't', nodes: ['v', 'w']}),
|
||||
iD.Relation({id: 'r', tags: {type: 'restriction'}, members: [
|
||||
{ role: 'via', id: 'v', type: 'node' },
|
||||
{ role: 'from', id: 'f', type: 'way' },
|
||||
{ role: 'to', id: 't', type: 'way' }
|
||||
]})
|
||||
]);
|
||||
|
||||
it("returns a valid restriction when the selected way has role 'from'", function() {
|
||||
expect(restrictions.turns(valid, ['f'])).to.eql([valid.entity('r')]);
|
||||
});
|
||||
|
||||
it("returns an empty array when the selected way has role 'to'", function() {
|
||||
expect(restrictions.turns(valid, ['t'])).to.eql([]);
|
||||
});
|
||||
|
||||
it("ignores restrictions missing a 'to' role", function() {
|
||||
var graph = valid.replace(valid.entity('r').removeMembersWithID('t'));
|
||||
expect(restrictions.turns(graph, ['f'])).to.eql([]);
|
||||
});
|
||||
|
||||
it("ignores restrictions with an incomplete 'to' role", function() {
|
||||
var graph = valid.remove(valid.entity('t'));
|
||||
expect(restrictions.turns(graph, ['f'])).to.eql([]);
|
||||
});
|
||||
|
||||
it("ignores restrictions missing a 'via' role", function() {
|
||||
var graph = valid.replace(valid.entity('r').removeMembersWithID('v'));
|
||||
expect(restrictions.turns(graph, ['f'])).to.eql([]);
|
||||
});
|
||||
|
||||
it("ignores restrictions with an incomplete 'via' role", function() {
|
||||
var graph = valid.remove(valid.entity('v'));
|
||||
expect(restrictions.turns(graph, ['f'])).to.eql([]);
|
||||
});
|
||||
|
||||
it("ignores restrictions whose 'from' role is not a way", function() {
|
||||
var graph = valid.replace(iD.Node({id: 'f2'}))
|
||||
.replace(valid.entity('r').replaceMember({id: 'f'}, {id: 'f2', type: 'node'}));
|
||||
expect(restrictions.turns(graph, ['f2'])).to.eql([]);
|
||||
});
|
||||
|
||||
it("ignores restrictions whose 'to' role is not a way", function() {
|
||||
var graph = valid.replace(iD.Node({id: 't2'}))
|
||||
.replace(valid.entity('r').replaceMember({id: 't'}, {id: 't2', type: 'node'}));
|
||||
expect(restrictions.turns(graph, ['f'])).to.eql([]);
|
||||
});
|
||||
|
||||
it("ignores restrictions whose 'via' role is not a node", function() {
|
||||
var graph = valid.replace(iD.Way({id: 'v2'}))
|
||||
.replace(valid.entity('r').replaceMember({id: 'v'}, {id: 'v2', type: 'way'}));
|
||||
expect(restrictions.turns(graph, ['f'])).to.eql([]);
|
||||
});
|
||||
|
||||
it("ignores restrictions whose 'from' role does not start or end with the via node", function() {
|
||||
var graph = valid.replace(valid.entity('f').update({nodes: ['o']}));
|
||||
expect(restrictions.turns(graph, ['f'])).to.eql([]);
|
||||
});
|
||||
|
||||
it("ignores restrictions whose 'to' role does not start or end with the via node", function() {
|
||||
var graph = valid.replace(valid.entity('t').update({nodes: ['o']}));
|
||||
expect(restrictions.turns(graph, ['f'])).to.eql([]);
|
||||
});
|
||||
|
||||
it("ignores restrictions whose 'from' role has less than two nodes", function() {
|
||||
var graph = valid.replace(valid.entity('f').update({nodes: ['v']}));
|
||||
expect(restrictions.turns(graph, ['f'])).to.eql([]);
|
||||
});
|
||||
|
||||
it("ignores restrictions whose 'to' role has less than two nodes", function() {
|
||||
var graph = valid.replace(valid.entity('t').update({nodes: ['v']}));
|
||||
expect(restrictions.turns(graph, ['f'])).to.eql([]);
|
||||
});
|
||||
|
||||
it("ignores restriction subtypes", function() {
|
||||
var graph = valid.replace(valid.entity('r').update({tags: {type: 'restriction:hgv'}}));
|
||||
expect(restrictions.turns(graph, ['f'])).to.eql([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#datum", function() {
|
||||
function projection(x) { return x; }
|
||||
|
||||
it("calculates the angle of a forward 'to' role", function() {
|
||||
// w---x--->y
|
||||
// |
|
||||
// u====>v
|
||||
// From = to - via v
|
||||
|
||||
var graph = iD.Graph([
|
||||
iD.Node({id: 'u', loc: [0, 0]}),
|
||||
iD.Node({id: 'v', loc: [1, 0]}),
|
||||
iD.Node({id: 'w', loc: [1, 1]}),
|
||||
iD.Node({id: 'x', loc: [2, 1]}),
|
||||
iD.Node({id: 'y', loc: [3, 1]}),
|
||||
iD.Way({id: '=', nodes: ['u', 'v']}),
|
||||
iD.Way({id: '-', nodes: ['v', 'w', 'x', 'y']}),
|
||||
iD.Relation({id: 'r', tags: {type: 'restriction'}, members: [
|
||||
{ role: 'via', id: 'v', type: 'node' },
|
||||
{ role: 'from', id: '=', type: 'way' },
|
||||
{ role: 'to', id: '-', type: 'way' }
|
||||
]})
|
||||
]);
|
||||
|
||||
expect(restrictions.datum(graph, graph.entity('='), graph.entity('r'), projection).angle).to.eql(Math.PI / 2);
|
||||
});
|
||||
|
||||
it("calculates the angle of a reverse 'to' role", function() {
|
||||
// w<---x---y
|
||||
// |
|
||||
// u====>v
|
||||
// From = to - via v
|
||||
|
||||
var graph = iD.Graph([
|
||||
iD.Node({id: 'u', loc: [0, 0]}),
|
||||
iD.Node({id: 'v', loc: [1, 0]}),
|
||||
iD.Node({id: 'w', loc: [1, 1]}),
|
||||
iD.Node({id: 'x', loc: [2, 1]}),
|
||||
iD.Node({id: 'y', loc: [3, 1]}),
|
||||
iD.Way({id: '=', nodes: ['u', 'v']}),
|
||||
iD.Way({id: '-', nodes: ['y', 'x', 'w', 'v']}),
|
||||
iD.Relation({id: 'r', tags: {type: 'restriction'}, members: [
|
||||
{ role: 'via', id: 'v', type: 'node' },
|
||||
{ role: 'from', id: '=', type: 'way' },
|
||||
{ role: 'to', id: '-', type: 'way' }
|
||||
]})
|
||||
]);
|
||||
|
||||
expect(restrictions.datum(graph, graph.entity('='), graph.entity('r'), projection).angle).to.eql(Math.PI / 2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user