mirror of
https://github.com/FoggedLens/iD.git
synced 2026-04-21 19:26:41 +02:00
WIP: Move layer-hit to layer-points with explict sublayers, update tests
This is more work to further isolate the layers that entities draw to. It makes it easier to debug what is going on, and can eventually lead to deferred drawing, if each draw function is in its own place and not dependant on anything else. I've started to replace the vertex-hover with an explicit layer for touch targets. Also had to change a lot of the svg tests, which are really brittle. Things would happen like - the surface would be created, it would kick of a deferred redraw, which would notice that the zoom was 0 and call editOff, which would remove the osm layers that were just created and that the tests were trying to draw to. These tests need proper zoom and projection otherwise nothing works.
This commit is contained in:
+12
-3
@@ -45,6 +45,7 @@ g.point.selected .shadow {
|
||||
stroke-opacity: 0.7;
|
||||
}
|
||||
|
||||
g.vertex.active, g.vertex.active *,
|
||||
g.point.active, g.point.active * {
|
||||
pointer-events: none;
|
||||
}
|
||||
@@ -88,6 +89,12 @@ g.midpoint .shadow {
|
||||
fill-opacity: 0;
|
||||
}
|
||||
|
||||
/*debug*/
|
||||
.vertex.target {
|
||||
fill: #f00;
|
||||
fill-opacity: 0.5;
|
||||
}
|
||||
|
||||
/*g.vertex.vertex-hover {
|
||||
display: none;
|
||||
}
|
||||
@@ -99,6 +106,7 @@ g.midpoint .shadow {
|
||||
.mode-add-point g.vertex.vertex-hover,
|
||||
.mode-drag-node g.vertex.vertex-hover {
|
||||
display: block;
|
||||
color: #f00;
|
||||
}
|
||||
|
||||
.mode-draw-area .hover-disabled g.vertex.vertex-hover,
|
||||
@@ -110,8 +118,9 @@ g.midpoint .shadow {
|
||||
display: none;
|
||||
}
|
||||
*/
|
||||
|
||||
g.vertex.related:not(.selected) .shadow,
|
||||
g.vertex.hover:not(.selected) .shadow,
|
||||
/*g.vertex.hover:not(.selected) .shadow,*/
|
||||
g.midpoint.related:not(.selected) .shadow,
|
||||
g.midpoint.hover:not(.selected) .shadow {
|
||||
fill-opacity: 0.5;
|
||||
@@ -262,11 +271,11 @@ g.turn circle {
|
||||
}
|
||||
|
||||
path.gpx {
|
||||
stroke: #FF26D4;
|
||||
stroke: #ff26d4;
|
||||
stroke-width: 2;
|
||||
fill: none;
|
||||
}
|
||||
|
||||
text.gpx {
|
||||
fill: #FF26D4;
|
||||
fill: #ff26d4;
|
||||
}
|
||||
|
||||
+3
-3
@@ -44,12 +44,12 @@
|
||||
display: none;
|
||||
}
|
||||
*/
|
||||
.mode-draw-line .way.active,
|
||||
.mode-draw-area .way.active,
|
||||
/*.mode-draw-line .active,
|
||||
.mode-draw-area .active,
|
||||
.mode-drag-node .active {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
*/
|
||||
/* Ensure drawing doesn't interact with area fills. */
|
||||
.mode-add-point path.area.fill,
|
||||
.mode-draw-line path.area.fill,
|
||||
|
||||
+16
-16
@@ -178,23 +178,23 @@ export function rendererMap(context) {
|
||||
})
|
||||
.on('mousemove.map', function() {
|
||||
mousemove = d3_event;
|
||||
})
|
||||
.on('mouseover.vertices', function() {
|
||||
if (map.editable() && !transformed) {
|
||||
var hover = d3_event.target.__data__;
|
||||
surface.selectAll('.data-layer-osm')
|
||||
.call(drawVertices.drawHover, context.graph(), hover, map.extent());
|
||||
dispatch.call('drawn', this, { full: false });
|
||||
}
|
||||
})
|
||||
.on('mouseout.vertices', function() {
|
||||
if (map.editable() && !transformed) {
|
||||
var hover = d3_event.relatedTarget && d3_event.relatedTarget.__data__;
|
||||
surface.selectAll('.data-layer-osm')
|
||||
.call(drawVertices.drawHover, context.graph(), hover, map.extent());
|
||||
dispatch.call('drawn', this, { full: false });
|
||||
}
|
||||
});
|
||||
// .on('mouseover.vertices', function() {
|
||||
// if (map.editable() && !transformed) {
|
||||
// var hover = d3_event.target.__data__;
|
||||
// surface.selectAll('.data-layer-osm')
|
||||
// .call(drawVertices.drawHover, context.graph(), hover, map.extent());
|
||||
// dispatch.call('drawn', this, { full: false });
|
||||
// }
|
||||
// })
|
||||
// .on('mouseout.vertices', function() {
|
||||
// if (map.editable() && !transformed) {
|
||||
// var hover = d3_event.relatedTarget && d3_event.relatedTarget.__data__;
|
||||
// surface.selectAll('.data-layer-osm')
|
||||
// .call(drawVertices.drawHover, context.graph(), hover, map.extent());
|
||||
// dispatch.call('drawn', this, { full: false });
|
||||
// }
|
||||
// });
|
||||
|
||||
supersurface
|
||||
.call(context.background());
|
||||
|
||||
@@ -676,20 +676,10 @@ export function svgLabels(projection, context) {
|
||||
|
||||
|
||||
var layer = selection.selectAll('.layer-labels');
|
||||
|
||||
var groups = layer.selectAll('.layer-labels-group')
|
||||
.data(['halo','label','debug']);
|
||||
|
||||
groups = groups.enter()
|
||||
.append('g')
|
||||
.attr('class', function(d) { return 'layer-labels-group layer-labels-' + d; })
|
||||
.merge(groups);
|
||||
|
||||
var halo = layer.selectAll('.layer-labels-halo');
|
||||
var label = layer.selectAll('.layer-labels-label');
|
||||
var debug = layer.selectAll('.layer-labels-debug');
|
||||
|
||||
|
||||
// points
|
||||
drawPointLabels(label, labelled.point, filter, 'pointlabel', positions.point);
|
||||
drawPointLabels(halo, labelled.point, filter, 'pointlabel-halo', positions.point);
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
export function svgMidpoints(projection, context) {
|
||||
|
||||
return function drawMidpoints(selection, graph, entities, filter, extent) {
|
||||
var layer = selection.selectAll('.layer-hit');
|
||||
var layer = selection.selectAll('.layer-points .layer-points-midpoints');
|
||||
|
||||
var mode = context.mode();
|
||||
if (mode && mode.id !== 'select') {
|
||||
|
||||
+13
-1
@@ -4,10 +4,22 @@ export function svgOsm(projection, context, dispatch) {
|
||||
|
||||
function drawOsm(selection) {
|
||||
selection.selectAll('.layer-osm')
|
||||
.data(['areas', 'lines', 'hit', 'labels'])
|
||||
.data(['areas', 'lines', 'points', 'labels'])
|
||||
.enter()
|
||||
.append('g')
|
||||
.attr('class', function(d) { return 'layer-osm layer-' + d; });
|
||||
|
||||
selection.selectAll('.layer-points').selectAll('.layer-points-group')
|
||||
.data(['points', 'midpoints', 'vertices', 'turns', 'targets'])
|
||||
.enter()
|
||||
.append('g')
|
||||
.attr('class', function(d) { return 'layer-points-group layer-points-' + d; });
|
||||
|
||||
selection.selectAll('.layer-labels').selectAll('.layer-labels-group')
|
||||
.data(['halo', 'label', 'debug'])
|
||||
.enter()
|
||||
.append('g')
|
||||
.attr('class', function(d) { return 'layer-labels-group layer-labels-' + d; });
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -36,7 +36,8 @@ export function svgPoints(projection, context) {
|
||||
|
||||
points.sort(sortY);
|
||||
|
||||
var layer = selection.selectAll('.layer-hit');
|
||||
|
||||
var layer = selection.selectAll('.layer-points .layer-points-points');
|
||||
|
||||
var groups = layer.selectAll('g.point')
|
||||
.filter(filter)
|
||||
|
||||
@@ -18,7 +18,8 @@ export function svgTurns(projection) {
|
||||
(!turn.indirect_restriction && /^only_/.test(restriction) ? 'only' : 'no') + u;
|
||||
}
|
||||
|
||||
var groups = selection.selectAll('.layer-hit').selectAll('g.turn')
|
||||
var layer = selection.selectAll('.layer-points .layer-points-turns');
|
||||
var groups = layer.selectAll('g.turn')
|
||||
.data(turns, key);
|
||||
|
||||
groups.exit()
|
||||
|
||||
+97
-78
@@ -54,7 +54,8 @@ export function svgVertices(projection, context) {
|
||||
|
||||
function setClass(klass) {
|
||||
return function(entity) {
|
||||
this.setAttribute('class', 'node vertex ' + klass + ' ' + entity.id);
|
||||
d3_select(this)
|
||||
.attr('class', 'node vertex ' + klass + ' ' + entity.id);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -171,9 +172,7 @@ export function svgVertices(projection, context) {
|
||||
function drawVertices(selection, graph, entities, filter, extent) {
|
||||
var wireframe = context.surface().classed('fill-wireframe');
|
||||
var zoom = ktoz(projection.scale());
|
||||
|
||||
var siblings = {};
|
||||
getSiblingAndChildVertices(context.selectedIDs(), graph, extent);
|
||||
var siblings = getSiblingAndChildVertices(context.selectedIDs(), graph, extent, wireframe, zoom);
|
||||
|
||||
// always render selected and sibling vertices..
|
||||
var vertices = _clone(siblings);
|
||||
@@ -184,7 +183,7 @@ export function svgVertices(projection, context) {
|
||||
var entity = entities[i];
|
||||
var geometry = entity.geometry(graph);
|
||||
|
||||
if ((geometry === 'point') && renderAsVertex(entity)) {
|
||||
if ((geometry === 'point') && renderAsVertex(entity, graph, wireframe, zoom)) {
|
||||
vertices[entity.id] = entity;
|
||||
|
||||
} else if ((geometry === 'vertex') &&
|
||||
@@ -193,85 +192,105 @@ export function svgVertices(projection, context) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
selection.selectAll('.layer-hit')
|
||||
selection.selectAll('.layer-points .layer-points-vertices')
|
||||
.call(draw, _values(vertices), 'vertex-persistent', graph, siblings, filterWithSiblings);
|
||||
|
||||
// drawHover(selection, graph, extent, true);
|
||||
drawTargets(selection, graph, _values(vertices), filter, extent);
|
||||
|
||||
|
||||
// Points can also render as vertices:
|
||||
// 1. in wireframe mode or
|
||||
// 2. at higher zooms if they have a direction
|
||||
function renderAsVertex(entity) {
|
||||
var geometry = entity.geometry(graph);
|
||||
return geometry === 'vertex' || (geometry === 'point' && (
|
||||
wireframe || (zoom > 18 && entity.directions(graph, projection).length)
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
function getSiblingAndChildVertices(ids, graph, extent) {
|
||||
|
||||
function addChildVertices(entity) {
|
||||
var geometry = entity.geometry(graph);
|
||||
if (!context.features().isHiddenFeature(entity, graph, geometry)) {
|
||||
var i;
|
||||
if (entity.type === 'way') {
|
||||
for (i = 0; i < entity.nodes.length; i++) {
|
||||
var child = context.hasEntity(entity.nodes[i]);
|
||||
if (child) {
|
||||
addChildVertices(child);
|
||||
}
|
||||
}
|
||||
} else if (entity.type === 'relation') {
|
||||
for (i = 0; i < entity.members.length; i++) {
|
||||
var member = context.hasEntity(entity.members[i].id);
|
||||
if (member) {
|
||||
addChildVertices(member);
|
||||
}
|
||||
}
|
||||
} else if (renderAsVertex(entity) && entity.intersects(extent, graph)) {
|
||||
siblings[entity.id] = entity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ids.forEach(function(id) {
|
||||
var entity = context.hasEntity(id);
|
||||
if (!entity) return;
|
||||
|
||||
if (entity.type === 'node') {
|
||||
if (renderAsVertex(entity)) {
|
||||
siblings[entity.id] = entity;
|
||||
graph.parentWays(entity).forEach(function(entity) {
|
||||
addChildVertices(entity);
|
||||
});
|
||||
}
|
||||
} else { // way, relation
|
||||
addChildVertices(entity);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// function drawHover(selection, graph, extent, follow) {
|
||||
// var hovered = _hover ? siblingAndChildVertices([_hover.id], graph, extent) : {};
|
||||
// var wireframe = context.surface().classed('fill-wireframe');
|
||||
// var layer = selection.selectAll('.layer-hit');
|
||||
//
|
||||
// layer.selectAll('g.vertex.vertex-hover')
|
||||
// .call(draw, _values(hovered), 'vertex-hover', graph, {}, false);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// drawVertices.drawHover = function(selection, graph, target, extent) {
|
||||
// if (target === _hover) return;
|
||||
// _hover = target;
|
||||
// drawHover(selection, graph, extent);
|
||||
// };
|
||||
function drawTargets(selection, graph, entities, filter, extent) {
|
||||
// todo coming soon
|
||||
return;
|
||||
var layer = selection.selectAll('.layer-points .layer-points-targets');
|
||||
|
||||
var targets = layer.selectAll('g.vertex.target')
|
||||
.data(entities, osmEntity.key);
|
||||
|
||||
// exit
|
||||
targets.exit()
|
||||
.remove();
|
||||
|
||||
// enter/update
|
||||
targets.enter()
|
||||
.append('circle')
|
||||
.attr('r', radiuses.shadow[3]) // just use the biggest one for now
|
||||
.attr('class', function(d) { return 'node vertex target ' + d.id; })
|
||||
.merge(targets)
|
||||
.attr('transform', svgPointTransform(projection));
|
||||
}
|
||||
|
||||
|
||||
// Points can also render as vertices:
|
||||
// 1. in wireframe mode or
|
||||
// 2. at higher zooms if they have a direction
|
||||
function renderAsVertex(entity, graph, wireframe, zoom) {
|
||||
var geometry = entity.geometry(graph);
|
||||
return geometry === 'vertex' || (geometry === 'point' && (
|
||||
wireframe || (zoom > 18 && entity.directions(graph, projection).length)
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
function getSiblingAndChildVertices(ids, graph, extent, wireframe, zoom) {
|
||||
var results = {};
|
||||
|
||||
function addChildVertices(entity) {
|
||||
var geometry = entity.geometry(graph);
|
||||
if (!context.features().isHiddenFeature(entity, graph, geometry)) {
|
||||
var i;
|
||||
if (entity.type === 'way') {
|
||||
for (i = 0; i < entity.nodes.length; i++) {
|
||||
var child = context.hasEntity(entity.nodes[i]);
|
||||
if (child) {
|
||||
addChildVertices(child);
|
||||
}
|
||||
}
|
||||
} else if (entity.type === 'relation') {
|
||||
for (i = 0; i < entity.members.length; i++) {
|
||||
var member = context.hasEntity(entity.members[i].id);
|
||||
if (member) {
|
||||
addChildVertices(member);
|
||||
}
|
||||
}
|
||||
} else if (renderAsVertex(entity, graph, wireframe, zoom) && entity.intersects(extent, graph)) {
|
||||
results[entity.id] = entity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ids.forEach(function(id) {
|
||||
var entity = context.hasEntity(id);
|
||||
if (!entity) return;
|
||||
|
||||
if (entity.type === 'node') {
|
||||
if (renderAsVertex(entity, graph, wireframe, zoom)) {
|
||||
results[entity.id] = entity;
|
||||
graph.parentWays(entity).forEach(function(entity) {
|
||||
addChildVertices(entity);
|
||||
});
|
||||
}
|
||||
} else { // way, relation
|
||||
addChildVertices(entity);
|
||||
}
|
||||
});
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
drawVertices.drawHover = function(selection, graph, target, extent) {
|
||||
if (target === _hover) return;
|
||||
_hover = target;
|
||||
|
||||
var wireframe = context.surface().classed('fill-wireframe');
|
||||
var zoom = ktoz(projection.scale());
|
||||
var hovered = _hover ? getSiblingAndChildVertices([_hover.id], graph, extent, wireframe, zoom) : {};
|
||||
var filter = function() { return true; };
|
||||
|
||||
drawTargets(selection, graph, _values(hovered), filter, extent);
|
||||
};
|
||||
|
||||
return drawVertices;
|
||||
}
|
||||
|
||||
+73
-69
@@ -1,17 +1,21 @@
|
||||
describe('iD.svgAreas', function () {
|
||||
var context, surface,
|
||||
projection = d3.geoProjection(function(x, y) { return [x, -y]; })
|
||||
.translate([0, 0])
|
||||
.scale(180 / Math.PI)
|
||||
.clipExtent([[0, 0], [Infinity, Infinity]]),
|
||||
all = function() { return true; },
|
||||
none = function() { return false; };
|
||||
var TAU = 2 * Math.PI;
|
||||
function ztok(z) { return 256 * Math.pow(2, z) / TAU; }
|
||||
|
||||
var context, surface;
|
||||
var all = function() { return true; };
|
||||
var none = function() { return false; };
|
||||
var projection = d3.geoProjection(function(x, y) { return [x, -y]; })
|
||||
.translate([0, 0])
|
||||
.scale(ztok(17))
|
||||
.clipExtent([[0, 0], [Infinity, Infinity]]);
|
||||
|
||||
|
||||
beforeEach(function () {
|
||||
context = iD.Context();
|
||||
context = iD.coreContext();
|
||||
d3.select(document.createElement('div'))
|
||||
.attr('id', 'map')
|
||||
.call(context.map());
|
||||
.call(context.map().centerZoom([0, 0], 17));
|
||||
surface = context.surface();
|
||||
|
||||
iD.setAreaKeys({
|
||||
@@ -22,13 +26,13 @@ describe('iD.svgAreas', function () {
|
||||
});
|
||||
|
||||
it('adds way and area classes', function () {
|
||||
var graph = iD.Graph([
|
||||
iD.Node({id: 'a', loc: [0, 0]}),
|
||||
iD.Node({id: 'b', loc: [1, 0]}),
|
||||
iD.Node({id: 'c', loc: [1, 1]}),
|
||||
iD.Node({id: 'd', loc: [0, 1]}),
|
||||
iD.Way({id: 'w', tags: {building: 'yes'}, nodes: ['a', 'b', 'c', 'a']})
|
||||
]);
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({id: 'a', loc: [0, 0]}),
|
||||
iD.osmNode({id: 'b', loc: [1, 0]}),
|
||||
iD.osmNode({id: 'c', loc: [1, 1]}),
|
||||
iD.osmNode({id: 'd', loc: [0, 1]}),
|
||||
iD.osmWay({id: 'w', tags: {building: 'yes'}, nodes: ['a', 'b', 'c', 'a']})
|
||||
]);
|
||||
|
||||
surface.call(iD.svgAreas(projection, context), graph, [graph.entity('w')], none);
|
||||
|
||||
@@ -37,13 +41,13 @@ describe('iD.svgAreas', function () {
|
||||
});
|
||||
|
||||
it('adds tag classes', function () {
|
||||
var graph = iD.Graph([
|
||||
iD.Node({id: 'a', loc: [0, 0]}),
|
||||
iD.Node({id: 'b', loc: [1, 0]}),
|
||||
iD.Node({id: 'c', loc: [1, 1]}),
|
||||
iD.Node({id: 'd', loc: [0, 1]}),
|
||||
iD.Way({id: 'w', tags: {building: 'yes'}, nodes: ['a', 'b', 'c', 'a']})
|
||||
]);
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({id: 'a', loc: [0, 0]}),
|
||||
iD.osmNode({id: 'b', loc: [1, 0]}),
|
||||
iD.osmNode({id: 'c', loc: [1, 1]}),
|
||||
iD.osmNode({id: 'd', loc: [0, 1]}),
|
||||
iD.osmWay({id: 'w', tags: {building: 'yes'}, nodes: ['a', 'b', 'c', 'a']})
|
||||
]);
|
||||
|
||||
surface.call(iD.svgAreas(projection, context), graph, [graph.entity('w')], none);
|
||||
|
||||
@@ -52,14 +56,14 @@ describe('iD.svgAreas', function () {
|
||||
});
|
||||
|
||||
it('handles deletion of a way and a member vertex (#1903)', function () {
|
||||
var graph = iD.Graph([
|
||||
iD.Node({id: 'a', loc: [0, 0]}),
|
||||
iD.Node({id: 'b', loc: [1, 0]}),
|
||||
iD.Node({id: 'c', loc: [1, 1]}),
|
||||
iD.Node({id: 'd', loc: [1, 1]}),
|
||||
iD.Way({id: 'w', tags: {area: 'yes'}, nodes: ['a', 'b', 'c', 'a']}),
|
||||
iD.Way({id: 'x', tags: {area: 'yes'}, nodes: ['a', 'b', 'd', 'a']})
|
||||
]);
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({id: 'a', loc: [0, 0]}),
|
||||
iD.osmNode({id: 'b', loc: [1, 0]}),
|
||||
iD.osmNode({id: 'c', loc: [1, 1]}),
|
||||
iD.osmNode({id: 'd', loc: [1, 1]}),
|
||||
iD.osmWay({id: 'w', tags: {area: 'yes'}, nodes: ['a', 'b', 'c', 'a']}),
|
||||
iD.osmWay({id: 'x', tags: {area: 'yes'}, nodes: ['a', 'b', 'd', 'a']})
|
||||
]);
|
||||
|
||||
surface.call(iD.svgAreas(projection, context), graph, [graph.entity('x')], all);
|
||||
graph = graph.remove(graph.entity('x')).remove(graph.entity('d'));
|
||||
@@ -69,18 +73,18 @@ describe('iD.svgAreas', function () {
|
||||
});
|
||||
|
||||
describe('z-indexing', function() {
|
||||
var graph = iD.Graph([
|
||||
iD.Node({id: 'a', loc: [-0.0002, 0.0001]}),
|
||||
iD.Node({id: 'b', loc: [ 0.0002, 0.0001]}),
|
||||
iD.Node({id: 'c', loc: [ 0.0002, -0.0001]}),
|
||||
iD.Node({id: 'd', loc: [-0.0002, -0.0001]}),
|
||||
iD.Node({id: 'e', loc: [-0.0004, 0.0002]}),
|
||||
iD.Node({id: 'f', loc: [ 0.0004, 0.0002]}),
|
||||
iD.Node({id: 'g', loc: [ 0.0004, -0.0002]}),
|
||||
iD.Node({id: 'h', loc: [-0.0004, -0.0002]}),
|
||||
iD.Way({id: 's', tags: {building: 'yes'}, nodes: ['a', 'b', 'c', 'd', 'a']}),
|
||||
iD.Way({id: 'l', tags: {landuse: 'park'}, nodes: ['e', 'f', 'g', 'h', 'e']})
|
||||
]);
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({id: 'a', loc: [-0.0002, 0.0001]}),
|
||||
iD.osmNode({id: 'b', loc: [ 0.0002, 0.0001]}),
|
||||
iD.osmNode({id: 'c', loc: [ 0.0002, -0.0001]}),
|
||||
iD.osmNode({id: 'd', loc: [-0.0002, -0.0001]}),
|
||||
iD.osmNode({id: 'e', loc: [-0.0004, 0.0002]}),
|
||||
iD.osmNode({id: 'f', loc: [ 0.0004, 0.0002]}),
|
||||
iD.osmNode({id: 'g', loc: [ 0.0004, -0.0002]}),
|
||||
iD.osmNode({id: 'h', loc: [-0.0004, -0.0002]}),
|
||||
iD.osmWay({id: 's', tags: {building: 'yes'}, nodes: ['a', 'b', 'c', 'd', 'a']}),
|
||||
iD.osmWay({id: 'l', tags: {landuse: 'park'}, nodes: ['e', 'f', 'g', 'h', 'e']})
|
||||
]);
|
||||
|
||||
it('stacks smaller areas above larger ones in a single render', function () {
|
||||
surface.call(iD.svgAreas(projection, context), graph, [graph.entity('s'), graph.entity('l')], none);
|
||||
@@ -114,13 +118,13 @@ describe('iD.svgAreas', function () {
|
||||
});
|
||||
|
||||
it('renders fills for multipolygon areas', function () {
|
||||
var a = iD.Node({loc: [1, 1]}),
|
||||
b = iD.Node({loc: [2, 2]}),
|
||||
c = iD.Node({loc: [3, 3]}),
|
||||
w = iD.Way({nodes: [a.id, b.id, c.id, a.id]}),
|
||||
r = iD.Relation({tags: {type: 'multipolygon'}, members: [{id: w.id, type: 'way'}]}),
|
||||
graph = iD.Graph([a, b, c, w, r]),
|
||||
areas = [w, r];
|
||||
var a = iD.osmNode({loc: [1, 1]});
|
||||
var b = iD.osmNode({loc: [2, 2]});
|
||||
var c = iD.osmNode({loc: [3, 3]});
|
||||
var w = iD.osmWay({nodes: [a.id, b.id, c.id, a.id]});
|
||||
var r = iD.osmRelation({tags: {type: 'multipolygon'}, members: [{id: w.id, type: 'way'}]});
|
||||
var graph = iD.coreGraph([a, b, c, w, r]);
|
||||
var areas = [w, r];
|
||||
|
||||
surface.call(iD.svgAreas(projection, context), graph, areas, none);
|
||||
|
||||
@@ -128,13 +132,13 @@ describe('iD.svgAreas', function () {
|
||||
});
|
||||
|
||||
it('renders no strokes for multipolygon areas', function () {
|
||||
var a = iD.Node({loc: [1, 1]}),
|
||||
b = iD.Node({loc: [2, 2]}),
|
||||
c = iD.Node({loc: [3, 3]}),
|
||||
w = iD.Way({nodes: [a.id, b.id, c.id, a.id]}),
|
||||
r = iD.Relation({tags: {type: 'multipolygon'}, members: [{id: w.id, type: 'way'}]}),
|
||||
graph = iD.Graph([a, b, c, w, r]),
|
||||
areas = [w, r];
|
||||
var a = iD.osmNode({loc: [1, 1]});
|
||||
var b = iD.osmNode({loc: [2, 2]});
|
||||
var c = iD.osmNode({loc: [3, 3]});
|
||||
var w = iD.osmWay({nodes: [a.id, b.id, c.id, a.id]});
|
||||
var r = iD.osmRelation({tags: {type: 'multipolygon'}, members: [{id: w.id, type: 'way'}]});
|
||||
var graph = iD.coreGraph([a, b, c, w, r]);
|
||||
var areas = [w, r];
|
||||
|
||||
surface.call(iD.svgAreas(projection, context), graph, areas, none);
|
||||
|
||||
@@ -142,12 +146,12 @@ describe('iD.svgAreas', function () {
|
||||
});
|
||||
|
||||
it('renders fill for a multipolygon with tags on the outer way', function() {
|
||||
var a = iD.Node({loc: [1, 1]}),
|
||||
b = iD.Node({loc: [2, 2]}),
|
||||
c = iD.Node({loc: [3, 3]}),
|
||||
w = iD.Way({tags: {natural: 'wood'}, nodes: [a.id, b.id, c.id, a.id]}),
|
||||
r = iD.Relation({members: [{id: w.id, type: 'way'}], tags: {type: 'multipolygon'}}),
|
||||
graph = iD.Graph([a, b, c, w, r]);
|
||||
var a = iD.osmNode({loc: [1, 1]});
|
||||
var b = iD.osmNode({loc: [2, 2]});
|
||||
var c = iD.osmNode({loc: [3, 3]});
|
||||
var w = iD.osmWay({tags: {natural: 'wood'}, nodes: [a.id, b.id, c.id, a.id]});
|
||||
var r = iD.osmRelation({members: [{id: w.id, type: 'way'}], tags: {type: 'multipolygon'}});
|
||||
var graph = iD.coreGraph([a, b, c, w, r]);
|
||||
|
||||
surface.call(iD.svgAreas(projection, context), graph, [w, r], none);
|
||||
|
||||
@@ -157,12 +161,12 @@ describe('iD.svgAreas', function () {
|
||||
});
|
||||
|
||||
it('renders no strokes for a multipolygon with tags on the outer way', function() {
|
||||
var a = iD.Node({loc: [1, 1]}),
|
||||
b = iD.Node({loc: [2, 2]}),
|
||||
c = iD.Node({loc: [3, 3]}),
|
||||
w = iD.Way({tags: {natural: 'wood'}, nodes: [a.id, b.id, c.id, a.id]}),
|
||||
r = iD.Relation({members: [{id: w.id, type: 'way'}], tags: {type: 'multipolygon'}}),
|
||||
graph = iD.Graph([a, b, c, w, r]);
|
||||
var a = iD.osmNode({loc: [1, 1]});
|
||||
var b = iD.osmNode({loc: [2, 2]});
|
||||
var c = iD.osmNode({loc: [3, 3]});
|
||||
var w = iD.osmWay({tags: {natural: 'wood'}, nodes: [a.id, b.id, c.id, a.id]});
|
||||
var r = iD.osmRelation({members: [{id: w.id, type: 'way'}], tags: {type: 'multipolygon'}});
|
||||
var graph = iD.coreGraph([a, b, c, w, r]);
|
||||
|
||||
surface.call(iD.svgAreas(projection, context), graph, [w, r], none);
|
||||
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
describe('iD.svgLayers', function () {
|
||||
var context, container,
|
||||
projection = d3.geoProjection(function(x, y) { return [x, -y]; })
|
||||
.translate([0, 0])
|
||||
.scale(180 / Math.PI)
|
||||
.clipExtent([[0, 0], [Infinity, Infinity]]);
|
||||
var TAU = 2 * Math.PI;
|
||||
function ztok(z) { return 256 * Math.pow(2, z) / TAU; }
|
||||
|
||||
var context, container;
|
||||
var projection = d3.geoProjection(function(x, y) { return [x, -y]; })
|
||||
.translate([0, 0])
|
||||
.scale(ztok(17))
|
||||
.clipExtent([[0, 0], [Infinity, Infinity]]);
|
||||
|
||||
beforeEach(function () {
|
||||
context = iD.Context();
|
||||
context = iD.coreContext();
|
||||
container = d3.select(document.createElement('div'));
|
||||
});
|
||||
|
||||
|
||||
+47
-43
@@ -1,26 +1,30 @@
|
||||
describe('iD.svgLines', function () {
|
||||
var context, surface,
|
||||
projection = d3.geoProjection(function(x, y) { return [x, -y]; })
|
||||
.translate([0, 0])
|
||||
.scale(180 / Math.PI)
|
||||
.clipExtent([[0, 0], [Infinity, Infinity]]),
|
||||
all = function() { return true; },
|
||||
none = function() { return false; };
|
||||
var TAU = 2 * Math.PI;
|
||||
function ztok(z) { return 256 * Math.pow(2, z) / TAU; }
|
||||
|
||||
var context, surface;
|
||||
var all = function() { return true; };
|
||||
var none = function() { return false; };
|
||||
var projection = d3.geoProjection(function(x, y) { return [x, -y]; })
|
||||
.translate([0, 0])
|
||||
.scale(ztok(17))
|
||||
.clipExtent([[0, 0], [Infinity, Infinity]]);
|
||||
|
||||
|
||||
beforeEach(function () {
|
||||
context = iD.Context();
|
||||
context = iD.coreContext();
|
||||
d3.select(document.createElement('div'))
|
||||
.attr('id', 'map')
|
||||
.call(context.map());
|
||||
.call(context.map().centerZoom([0, 0], 17));
|
||||
surface = context.surface();
|
||||
});
|
||||
|
||||
|
||||
it('adds way and line classes', function () {
|
||||
var a = iD.Node({loc: [0, 0]}),
|
||||
b = iD.Node({loc: [1, 1]}),
|
||||
line = iD.Way({nodes: [a.id, b.id]}),
|
||||
graph = iD.Graph([a, b, line]);
|
||||
var a = iD.osmNode({loc: [0, 0]});
|
||||
var b = iD.osmNode({loc: [1, 1]});
|
||||
var line = iD.osmWay({nodes: [a.id, b.id]});
|
||||
var graph = iD.coreGraph([a, b, line]);
|
||||
|
||||
surface.call(iD.svgLines(projection, context), graph, [line], all);
|
||||
|
||||
@@ -29,10 +33,10 @@ describe('iD.svgLines', function () {
|
||||
});
|
||||
|
||||
it('adds tag classes', function () {
|
||||
var a = iD.Node({loc: [0, 0]}),
|
||||
b = iD.Node({loc: [1, 1]}),
|
||||
line = iD.Way({nodes: [a.id, b.id], tags: {highway: 'residential'}}),
|
||||
graph = iD.Graph([a, b, line]);
|
||||
var a = iD.osmNode({loc: [0, 0]});
|
||||
var b = iD.osmNode({loc: [1, 1]});
|
||||
var line = iD.osmWay({nodes: [a.id, b.id], tags: {highway: 'residential'}});
|
||||
var graph = iD.coreGraph([a, b, line]);
|
||||
|
||||
surface.call(iD.svgLines(projection, context), graph, [line], all);
|
||||
|
||||
@@ -41,11 +45,11 @@ describe('iD.svgLines', function () {
|
||||
});
|
||||
|
||||
it('adds stroke classes for the tags of the parent relation of multipolygon members', function() {
|
||||
var a = iD.Node({loc: [0, 0]}),
|
||||
b = iD.Node({loc: [1, 1]}),
|
||||
line = iD.Way({nodes: [a.id, b.id]}),
|
||||
relation = iD.Relation({members: [{id: line.id}], tags: {type: 'multipolygon', natural: 'wood'}}),
|
||||
graph = iD.Graph([a, b, line, relation]);
|
||||
var a = iD.osmNode({loc: [0, 0]});
|
||||
var b = iD.osmNode({loc: [1, 1]});
|
||||
var line = iD.osmWay({nodes: [a.id, b.id]});
|
||||
var relation = iD.osmRelation({members: [{id: line.id}], tags: {type: 'multipolygon', natural: 'wood'}});
|
||||
var graph = iD.coreGraph([a, b, line, relation]);
|
||||
|
||||
surface.call(iD.svgLines(projection, context), graph, [line], all);
|
||||
|
||||
@@ -53,12 +57,12 @@ describe('iD.svgLines', function () {
|
||||
});
|
||||
|
||||
it('renders stroke for outer way of multipolygon with tags on the outer way', function() {
|
||||
var a = iD.Node({loc: [1, 1]}),
|
||||
b = iD.Node({loc: [2, 2]}),
|
||||
c = iD.Node({loc: [3, 3]}),
|
||||
w = iD.Way({id: 'w-1', tags: {natural: 'wood'}, nodes: [a.id, b.id, c.id, a.id]}),
|
||||
r = iD.Relation({members: [{id: w.id}], tags: {type: 'multipolygon'}}),
|
||||
graph = iD.Graph([a, b, c, w, r]);
|
||||
var a = iD.osmNode({loc: [1, 1]});
|
||||
var b = iD.osmNode({loc: [2, 2]});
|
||||
var c = iD.osmNode({loc: [3, 3]});
|
||||
var w = iD.osmWay({id: 'w-1', tags: {natural: 'wood'}, nodes: [a.id, b.id, c.id, a.id]});
|
||||
var r = iD.osmRelation({members: [{id: w.id}], tags: {type: 'multipolygon'}});
|
||||
var graph = iD.coreGraph([a, b, c, w, r]);
|
||||
|
||||
surface.call(iD.svgLines(projection, context), graph, [w], all);
|
||||
|
||||
@@ -67,13 +71,13 @@ describe('iD.svgLines', function () {
|
||||
});
|
||||
|
||||
it('adds stroke classes for the tags of the outer way of multipolygon with tags on the outer way', function() {
|
||||
var a = iD.Node({loc: [1, 1]}),
|
||||
b = iD.Node({loc: [2, 2]}),
|
||||
c = iD.Node({loc: [3, 3]}),
|
||||
o = iD.Way({id: 'w-1', nodes: [a.id, b.id, c.id, a.id], tags: {natural: 'wood'}}),
|
||||
i = iD.Way({id: 'w-2', nodes: [a.id, b.id, c.id, a.id]}),
|
||||
r = iD.Relation({members: [{id: o.id, role: 'outer'}, {id: i.id, role: 'inner'}], tags: {type: 'multipolygon'}}),
|
||||
graph = iD.Graph([a, b, c, o, i, r]);
|
||||
var a = iD.osmNode({loc: [1, 1]});
|
||||
var b = iD.osmNode({loc: [2, 2]});
|
||||
var c = iD.osmNode({loc: [3, 3]});
|
||||
var o = iD.osmWay({id: 'w-1', nodes: [a.id, b.id, c.id, a.id], tags: {natural: 'wood'}});
|
||||
var i = iD.osmWay({id: 'w-2', nodes: [a.id, b.id, c.id, a.id]});
|
||||
var r = iD.osmRelation({members: [{id: o.id, role: 'outer'}, {id: i.id, role: 'inner'}], tags: {type: 'multipolygon'}});
|
||||
var graph = iD.coreGraph([a, b, c, o, i, r]);
|
||||
|
||||
surface.call(iD.svgLines(projection, context), graph, [i, o], all);
|
||||
|
||||
@@ -84,14 +88,14 @@ describe('iD.svgLines', function () {
|
||||
});
|
||||
|
||||
describe('z-indexing', function() {
|
||||
var graph = iD.Graph([
|
||||
iD.Node({id: 'a', loc: [0, 0]}),
|
||||
iD.Node({id: 'b', loc: [1, 1]}),
|
||||
iD.Node({id: 'c', loc: [0, 0]}),
|
||||
iD.Node({id: 'd', loc: [1, 1]}),
|
||||
iD.Way({id: 'lo', tags: {highway: 'residential', tunnel: 'yes'}, nodes: ['a', 'b']}),
|
||||
iD.Way({id: 'hi', tags: {highway: 'residential', bridge: 'yes'}, nodes: ['c', 'd']})
|
||||
]);
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({id: 'a', loc: [0, 0]}),
|
||||
iD.osmNode({id: 'b', loc: [1, 1]}),
|
||||
iD.osmNode({id: 'c', loc: [0, 0]}),
|
||||
iD.osmNode({id: 'd', loc: [1, 1]}),
|
||||
iD.osmWay({id: 'lo', tags: {highway: 'residential', tunnel: 'yes'}, nodes: ['a', 'b']}),
|
||||
iD.osmWay({id: 'hi', tags: {highway: 'residential', bridge: 'yes'}, nodes: ['c', 'd']})
|
||||
]);
|
||||
|
||||
it('stacks higher lines above lower ones in a single render', function () {
|
||||
surface.call(iD.svgLines(projection, context), graph, [graph.entity('lo'), graph.entity('hi')], none);
|
||||
|
||||
+58
-58
@@ -1,103 +1,103 @@
|
||||
describe('iD.svgMidpoints', function () {
|
||||
var context, surface,
|
||||
selectedIDs = [],
|
||||
projection = d3.geoProjection(function(x, y) { return [x, -y]; })
|
||||
.translate([0, 0])
|
||||
.scale(180 / Math.PI)
|
||||
.clipExtent([[0, 0], [Infinity, Infinity]]),
|
||||
filter = function() { return true; };
|
||||
var TAU = 2 * Math.PI;
|
||||
function ztok(z) { return 256 * Math.pow(2, z) / TAU; }
|
||||
|
||||
var context, surface;
|
||||
var _selectedIDs = [];
|
||||
var filter = function() { return true; };
|
||||
var projection = d3.geoProjection(function(x, y) { return [x, -y]; })
|
||||
.translate([0, 0])
|
||||
.scale(ztok(17))
|
||||
.clipExtent([[0, 0], [Infinity, Infinity]]);
|
||||
|
||||
|
||||
beforeEach(function () {
|
||||
context = iD.Context();
|
||||
context.mode = function() {
|
||||
return {
|
||||
id: 'select',
|
||||
selectedIDs: function() { return selectedIDs; }
|
||||
};
|
||||
};
|
||||
d3.select(document.createElement('div'))
|
||||
context = iD.coreContext();
|
||||
context.enter({
|
||||
id: 'select',
|
||||
enter: function() { },
|
||||
exit: function() { },
|
||||
selectedIDs: function() { return _selectedIDs; }
|
||||
});
|
||||
|
||||
var map = d3.select(document.createElement('div'))
|
||||
.attr('id', 'map')
|
||||
.call(context.map());
|
||||
.call(context.map().centerZoom([0, 0], 17));
|
||||
|
||||
surface = context.surface();
|
||||
});
|
||||
|
||||
|
||||
it('creates midpoint on segment completely within the extent', function () {
|
||||
var a = iD.Node({loc: [0, 0]}),
|
||||
b = iD.Node({loc: [50, 0]}),
|
||||
line = iD.Way({nodes: [a.id, b.id]}),
|
||||
graph = iD.Graph([a, b, line]),
|
||||
extent = iD.geoExtent([0, 0], [100, 100]);
|
||||
var a = iD.osmNode({loc: [0, 0]});
|
||||
var b = iD.osmNode({loc: [1, 0]});
|
||||
var line = iD.osmWay({nodes: [a.id, b.id]});
|
||||
var graph = iD.coreGraph([a, b, line]);
|
||||
var extent = iD.geoExtent([0, 0], [1, 1]);
|
||||
|
||||
selectedIDs = [line.id];
|
||||
context.selectedIDs = function() { return selectedIDs; };
|
||||
_selectedIDs = [line.id];
|
||||
context.entity = function(id) { return graph.entity(id); };
|
||||
context.hasEntity = context.entity;
|
||||
context.hasEntity = function(id) { return graph.entities[id]; };
|
||||
|
||||
surface.call(iD.svgMidpoints(projection, context), graph, [line], filter, extent);
|
||||
expect(surface.selectAll('.midpoint').datum().loc).to.eql([25, 0]);
|
||||
expect(surface.selectAll('.midpoint').datum().loc).to.eql([0.5, 0]);
|
||||
});
|
||||
|
||||
it('doesn\'t create midpoint on segment with pixel length less than 40', function () {
|
||||
var a = iD.Node({loc: [0, 0]}),
|
||||
b = iD.Node({loc: [39, 0]}),
|
||||
line = iD.Way({nodes: [a.id, b.id]}),
|
||||
graph = iD.Graph([a, b, line]),
|
||||
extent = iD.geoExtent([0, 0], [100, 100]);
|
||||
var a = iD.osmNode({loc: [0, 0]});
|
||||
var b = iD.osmNode({loc: [0.0001, 0]});
|
||||
var line = iD.osmWay({nodes: [a.id, b.id]});
|
||||
var graph = iD.coreGraph([a, b, line]);
|
||||
var extent = iD.geoExtent([0, 0], [1, 1]);
|
||||
|
||||
selectedIDs = [line.id];
|
||||
context.selectedIDs = function() { return selectedIDs; };
|
||||
_selectedIDs = [line.id];
|
||||
context.entity = function(id) { return graph.entity(id); };
|
||||
context.hasEntity = context.entity;
|
||||
context.hasEntity = function(id) { return graph.entities[id]; };
|
||||
|
||||
surface.call(iD.svgMidpoints(projection, context), graph, [line], filter, extent);
|
||||
expect(surface.selectAll('.midpoint').nodes()).to.have.length(0);
|
||||
});
|
||||
|
||||
it('doesn\'t create midpoint on segment completely outside of the extent', function () {
|
||||
var a = iD.Node({loc: [-100, 0]}),
|
||||
b = iD.Node({loc: [-50, 0]}),
|
||||
line = iD.Way({nodes: [a.id, b.id]}),
|
||||
graph = iD.Graph([a, b, line]),
|
||||
extent = iD.geoExtent([0, 0], [100, 100]);
|
||||
var a = iD.osmNode({loc: [-1, 0]});
|
||||
var b = iD.osmNode({loc: [-0.5, 0]});
|
||||
var line = iD.osmWay({nodes: [a.id, b.id]});
|
||||
var graph = iD.coreGraph([a, b, line]);
|
||||
var extent = iD.geoExtent([0, 0], [1, 1]);
|
||||
|
||||
selectedIDs = [line.id];
|
||||
context.selectedIDs = function() { return selectedIDs; };
|
||||
_selectedIDs = [line.id];
|
||||
context.entity = function(id) { return graph.entity(id); };
|
||||
context.hasEntity = context.entity;
|
||||
context.hasEntity = function(id) { return graph.entities[id]; };
|
||||
|
||||
surface.call(iD.svgMidpoints(projection, context), graph, [line], filter, extent);
|
||||
expect(surface.selectAll('.midpoint').nodes()).to.have.length(0);
|
||||
});
|
||||
|
||||
it('creates midpoint on extent edge for segment partially outside of the extent', function () {
|
||||
var a = iD.Node({loc: [50, 0]}),
|
||||
b = iD.Node({loc: [500, 0]}),
|
||||
line = iD.Way({nodes: [a.id, b.id]}),
|
||||
graph = iD.Graph([a, b, line]),
|
||||
extent = iD.geoExtent([0, 0], [100, 100]);
|
||||
var a = iD.osmNode({loc: [0.5, 0]});
|
||||
var b = iD.osmNode({loc: [2, 0]});
|
||||
var line = iD.osmWay({nodes: [a.id, b.id]});
|
||||
var graph = iD.coreGraph([a, b, line]);
|
||||
var extent = iD.geoExtent([0, 0], [1, 1]);
|
||||
|
||||
selectedIDs = [line.id];
|
||||
context.selectedIDs = function() { return selectedIDs; };
|
||||
_selectedIDs = [line.id];
|
||||
context.entity = function(id) { return graph.entity(id); };
|
||||
context.hasEntity = context.entity;
|
||||
context.hasEntity = function(id) { return graph.entities[id]; };
|
||||
|
||||
surface.call(iD.svgMidpoints(projection, context), graph, [line], filter, extent);
|
||||
expect(surface.selectAll('.midpoint').datum().loc).to.eql([100, 0]);
|
||||
expect(surface.selectAll('.midpoint').datum().loc).to.eql([1, 0]);
|
||||
});
|
||||
|
||||
it('doesn\'t create midpoint on extent edge for segment with pixel length less than 20', function () {
|
||||
var a = iD.Node({loc: [81, 0]}),
|
||||
b = iD.Node({loc: [500, 0]}),
|
||||
line = iD.Way({nodes: [a.id, b.id]}),
|
||||
graph = iD.Graph([a, b, line]),
|
||||
extent = iD.geoExtent([0, 0], [100, 100]);
|
||||
var a = iD.osmNode({loc: [0.9999, 0]});
|
||||
var b = iD.osmNode({loc: [2, 0]});
|
||||
var line = iD.osmWay({nodes: [a.id, b.id]});
|
||||
var graph = iD.coreGraph([a, b, line]);
|
||||
var extent = iD.geoExtent([0, 0], [1, 1]);
|
||||
|
||||
selectedIDs = [line.id];
|
||||
context.selectedIDs = function() { return selectedIDs; };
|
||||
_selectedIDs = [line.id];
|
||||
context.entity = function(id) { return graph.entity(id); };
|
||||
context.hasEntity = context.entity;
|
||||
context.hasEntity = function(id) { return graph.entities[id]; };
|
||||
|
||||
surface.call(iD.svgMidpoints(projection, context), graph, [line], filter, extent);
|
||||
expect(surface.selectAll('.midpoint').nodes()).to.have.length(0);
|
||||
|
||||
+26
-6
@@ -7,12 +7,32 @@ describe('iD.svgOsm', function () {
|
||||
|
||||
it('creates default osm layers', function () {
|
||||
container.call(iD.svgOsm());
|
||||
var nodes = container.selectAll('.layer-osm').nodes();
|
||||
expect(nodes.length).to.eql(4);
|
||||
expect(d3.select(nodes[0]).classed('layer-areas')).to.be.true;
|
||||
expect(d3.select(nodes[1]).classed('layer-lines')).to.be.true;
|
||||
expect(d3.select(nodes[2]).classed('layer-hit')).to.be.true;
|
||||
expect(d3.select(nodes[3]).classed('layer-labels')).to.be.true;
|
||||
var layers = container.selectAll('g.layer-osm').nodes();
|
||||
expect(layers.length).to.eql(4);
|
||||
expect(d3.select(layers[0]).classed('layer-areas')).to.be.true;
|
||||
expect(d3.select(layers[1]).classed('layer-lines')).to.be.true;
|
||||
expect(d3.select(layers[2]).classed('layer-points')).to.be.true;
|
||||
expect(d3.select(layers[3]).classed('layer-labels')).to.be.true;
|
||||
});
|
||||
|
||||
it('creates default osm point layers', function () {
|
||||
container.call(iD.svgOsm());
|
||||
var layers = container.selectAll('g.layer-points g.layer-points-group').nodes();
|
||||
expect(layers.length).to.eql(5);
|
||||
expect(d3.select(layers[0]).classed('layer-points-points')).to.be.true;
|
||||
expect(d3.select(layers[1]).classed('layer-points-midpoints')).to.be.true;
|
||||
expect(d3.select(layers[2]).classed('layer-points-vertices')).to.be.true;
|
||||
expect(d3.select(layers[3]).classed('layer-points-turns')).to.be.true;
|
||||
expect(d3.select(layers[4]).classed('layer-points-targets')).to.be.true;
|
||||
});
|
||||
|
||||
it('creates default osm label layers', function () {
|
||||
container.call(iD.svgOsm());
|
||||
var layers = container.selectAll('g.layer-labels g.layer-labels-group').nodes();
|
||||
expect(layers.length).to.eql(3);
|
||||
expect(d3.select(layers[0]).classed('layer-labels-halo')).to.be.true;
|
||||
expect(d3.select(layers[1]).classed('layer-labels-label')).to.be.true;
|
||||
expect(d3.select(layers[2]).classed('layer-labels-debug')).to.be.true;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
+12
-9
@@ -1,22 +1,25 @@
|
||||
describe('iD.svgPoints', function () {
|
||||
var context, surface,
|
||||
projection = d3.geoProjection(function(x, y) { return [x, -y]; })
|
||||
.translate([0, 0])
|
||||
.scale(180 / Math.PI)
|
||||
.clipExtent([[0, 0], [Infinity, Infinity]]);
|
||||
var TAU = 2 * Math.PI;
|
||||
function ztok(z) { return 256 * Math.pow(2, z) / TAU; }
|
||||
|
||||
var context, surface;
|
||||
var projection = d3.geoProjection(function(x, y) { return [x, -y]; })
|
||||
.translate([0, 0])
|
||||
.scale(ztok(17))
|
||||
.clipExtent([[0, 0], [Infinity, Infinity]]);
|
||||
|
||||
beforeEach(function () {
|
||||
context = iD.Context();
|
||||
context = iD.coreContext();
|
||||
d3.select(document.createElement('div'))
|
||||
.attr('id', 'map')
|
||||
.call(context.map());
|
||||
.call(context.map().centerZoom([0, 0], 17));
|
||||
surface = context.surface();
|
||||
});
|
||||
|
||||
|
||||
it('adds tag classes', function () {
|
||||
var point = iD.Node({tags: {amenity: 'cafe'}, loc: [0, 0]}),
|
||||
graph = iD.Graph([point]);
|
||||
var point = iD.osmNode({tags: {amenity: 'cafe'}, loc: [0, 0]});
|
||||
var graph = iD.coreGraph([point]);
|
||||
|
||||
surface.call(iD.svgPoints(projection, context), graph, [point]);
|
||||
|
||||
|
||||
@@ -7,156 +7,156 @@ describe('iD.svgTagClasses', function () {
|
||||
|
||||
it('adds no classes to elements whose datum has no tags', function() {
|
||||
selection
|
||||
.datum(iD.Entity())
|
||||
.datum(iD.osmEntity())
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.attr('class')).to.equal(null);
|
||||
});
|
||||
|
||||
it('adds classes for primary tag key and key-value', function() {
|
||||
selection
|
||||
.datum(iD.Entity({tags: {highway: 'primary'}}))
|
||||
.datum(iD.osmEntity({tags: {highway: 'primary'}}))
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.attr('class')).to.equal('tag-highway tag-highway-primary');
|
||||
});
|
||||
|
||||
it('adds only one primary tag', function() {
|
||||
selection
|
||||
.datum(iD.Entity({tags: {highway: 'primary', railway: 'rail'}}))
|
||||
.datum(iD.osmEntity({tags: {highway: 'primary', railway: 'rail'}}))
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.attr('class')).to.equal('tag-highway tag-highway-primary');
|
||||
});
|
||||
|
||||
it('orders primary tags', function() {
|
||||
selection
|
||||
.datum(iD.Entity({tags: {railway: 'rail', highway: 'primary'}}))
|
||||
.datum(iD.osmEntity({tags: {railway: 'rail', highway: 'primary'}}))
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.attr('class')).to.equal('tag-highway tag-highway-primary');
|
||||
});
|
||||
|
||||
it('adds status tag when status in primary value (`railway=abandoned`)', function() {
|
||||
selection
|
||||
.datum(iD.Entity({tags: {railway: 'abandoned'}}))
|
||||
.datum(iD.osmEntity({tags: {railway: 'abandoned'}}))
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.attr('class')).to.equal('tag-railway tag-status tag-status-abandoned');
|
||||
});
|
||||
|
||||
it('adds status tag when status in key and value matches "yes" (railway=rail + abandoned=yes)', function() {
|
||||
selection
|
||||
.datum(iD.Entity({tags: {railway: 'rail', abandoned: 'yes'}}))
|
||||
.datum(iD.osmEntity({tags: {railway: 'rail', abandoned: 'yes'}}))
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.attr('class')).to.equal('tag-railway tag-railway-rail tag-status tag-status-abandoned');
|
||||
});
|
||||
|
||||
it('adds status tag when status in key and value matches primary (railway=rail + abandoned=railway)', function() {
|
||||
selection
|
||||
.datum(iD.Entity({tags: {railway: 'rail', abandoned: 'railway'}}))
|
||||
.datum(iD.osmEntity({tags: {railway: 'rail', abandoned: 'railway'}}))
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.attr('class')).to.equal('tag-railway tag-railway-rail tag-status tag-status-abandoned');
|
||||
});
|
||||
|
||||
it('adds primary and status tag when status in key and no primary (abandoned=railway)', function() {
|
||||
selection
|
||||
.datum(iD.Entity({tags: {abandoned: 'railway'}}))
|
||||
.datum(iD.osmEntity({tags: {abandoned: 'railway'}}))
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.attr('class')).to.equal('tag-railway tag-status tag-status-abandoned');
|
||||
});
|
||||
|
||||
it('does not add status tag for different primary tag (highway=path + abandoned=railway)', function() {
|
||||
selection
|
||||
.datum(iD.Entity({tags: {highway: 'path', abandoned: 'railway'}}))
|
||||
.datum(iD.osmEntity({tags: {highway: 'path', abandoned: 'railway'}}))
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.attr('class')).to.equal('tag-highway tag-highway-path');
|
||||
});
|
||||
|
||||
it('adds secondary tags', function() {
|
||||
selection
|
||||
.datum(iD.Entity({tags: {highway: 'primary', bridge: 'yes'}}))
|
||||
.datum(iD.osmEntity({tags: {highway: 'primary', bridge: 'yes'}}))
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.attr('class')).to.equal('tag-highway tag-highway-primary tag-bridge tag-bridge-yes');
|
||||
});
|
||||
|
||||
it('adds no bridge=no tags', function() {
|
||||
selection
|
||||
.datum(iD.Entity({tags: {bridge: 'no'}}))
|
||||
.datum(iD.osmEntity({tags: {bridge: 'no'}}))
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.attr('class')).to.equal(null);
|
||||
});
|
||||
|
||||
it('adds tag-unpaved for highway=track with no surface tagging', function() {
|
||||
selection
|
||||
.datum(iD.Entity({tags: {highway: 'track'}}))
|
||||
.datum(iD.osmEntity({tags: {highway: 'track'}}))
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.classed('tag-unpaved')).to.be.true;
|
||||
});
|
||||
|
||||
it('does not add tag-unpaved for highway=track with explicit paved surface tagging', function() {
|
||||
selection
|
||||
.datum(iD.Entity({tags: {highway: 'track', surface: 'asphalt'}}))
|
||||
.datum(iD.osmEntity({tags: {highway: 'track', surface: 'asphalt'}}))
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.classed('tag-unpaved')).to.be.false;
|
||||
|
||||
selection
|
||||
.datum(iD.Entity({tags: {highway: 'track', tracktype: 'grade1'}}))
|
||||
.datum(iD.osmEntity({tags: {highway: 'track', tracktype: 'grade1'}}))
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.classed('tag-unpaved')).to.be.false;
|
||||
});
|
||||
|
||||
it('adds tag-unpaved for highway=track with explicit unpaved surface tagging', function() {
|
||||
selection
|
||||
.datum(iD.Entity({tags: {highway: 'track', surface: 'dirt'}}))
|
||||
.datum(iD.osmEntity({tags: {highway: 'track', surface: 'dirt'}}))
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.classed('tag-unpaved')).to.be.true;
|
||||
|
||||
selection
|
||||
.datum(iD.Entity({tags: {highway: 'track', tracktype: 'grade3'}}))
|
||||
.datum(iD.osmEntity({tags: {highway: 'track', tracktype: 'grade3'}}))
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.classed('tag-unpaved')).to.be.true;
|
||||
});
|
||||
|
||||
it('does not add tag-unpaved for other highway types with no surface tagging', function() {
|
||||
selection
|
||||
.datum(iD.Entity({tags: {highway: 'tertiary'}}))
|
||||
.datum(iD.osmEntity({tags: {highway: 'tertiary'}}))
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.classed('tag-unpaved')).to.be.false;
|
||||
|
||||
selection
|
||||
.datum(iD.Entity({tags: {highway: 'foo'}}))
|
||||
.datum(iD.osmEntity({tags: {highway: 'foo'}}))
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.classed('tag-unpaved')).to.be.false;
|
||||
});
|
||||
|
||||
it('does not add tag-unpaved for other highway types with explicit paved surface tagging', function() {
|
||||
selection
|
||||
.datum(iD.Entity({tags: {highway: 'tertiary', surface: 'asphalt'}}))
|
||||
.datum(iD.osmEntity({tags: {highway: 'tertiary', surface: 'asphalt'}}))
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.classed('tag-unpaved')).to.be.false;
|
||||
|
||||
selection
|
||||
.datum(iD.Entity({tags: {highway: 'foo', tracktype: 'grade1'}}))
|
||||
.datum(iD.osmEntity({tags: {highway: 'foo', tracktype: 'grade1'}}))
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.classed('tag-unpaved')).to.be.false;
|
||||
});
|
||||
|
||||
it('adds tag-unpaved for other highway types with explicit unpaved surface tagging', function() {
|
||||
selection
|
||||
.datum(iD.Entity({tags: {highway: 'tertiary', surface: 'dirt'}}))
|
||||
.datum(iD.osmEntity({tags: {highway: 'tertiary', surface: 'dirt'}}))
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.classed('tag-unpaved')).to.be.true;
|
||||
|
||||
selection
|
||||
.datum(iD.Entity({tags: {highway: 'foo', tracktype: 'grade3'}}))
|
||||
.datum(iD.osmEntity({tags: {highway: 'foo', tracktype: 'grade3'}}))
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.classed('tag-unpaved')).to.be.true;
|
||||
});
|
||||
|
||||
it('does not add tag-unpaved for non-highways', function() {
|
||||
selection
|
||||
.datum(iD.Entity({tags: {railway: 'abandoned', surface: 'gravel'}}))
|
||||
.datum(iD.osmEntity({tags: {railway: 'abandoned', surface: 'gravel'}}))
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.classed('tag-unpaved')).to.be.false;
|
||||
|
||||
selection
|
||||
.datum(iD.Entity({tags: {amenity: 'parking', surface: 'dirt'}}))
|
||||
.datum(iD.osmEntity({tags: {amenity: 'parking', surface: 'dirt'}}))
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.classed('tag-unpaved')).to.be.false;
|
||||
});
|
||||
@@ -164,7 +164,7 @@ describe('iD.svgTagClasses', function () {
|
||||
it('adds tags based on the result of the `tags` accessor', function() {
|
||||
var primary = function () { return { highway: 'primary'}; };
|
||||
selection
|
||||
.datum(iD.Entity())
|
||||
.datum(iD.osmEntity())
|
||||
.call(iD.svgTagClasses().tags(primary));
|
||||
expect(selection.attr('class')).to.equal('tag-highway tag-highway-primary');
|
||||
});
|
||||
@@ -172,7 +172,7 @@ describe('iD.svgTagClasses', function () {
|
||||
it('removes classes for tags that are no longer present', function() {
|
||||
selection
|
||||
.attr('class', 'tag-highway tag-highway-primary')
|
||||
.datum(iD.Entity())
|
||||
.datum(iD.osmEntity())
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.attr('class')).to.equal('');
|
||||
});
|
||||
@@ -180,7 +180,7 @@ describe('iD.svgTagClasses', function () {
|
||||
it('preserves existing non-"tag-"-prefixed classes', function() {
|
||||
selection
|
||||
.attr('class', 'selected')
|
||||
.datum(iD.Entity())
|
||||
.datum(iD.osmEntity())
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.attr('class')).to.equal('selected');
|
||||
});
|
||||
@@ -188,7 +188,7 @@ describe('iD.svgTagClasses', function () {
|
||||
it('works on SVG elements', function() {
|
||||
selection = d3.select(document.createElementNS('http://www.w3.org/2000/svg', 'g'));
|
||||
selection
|
||||
.datum(iD.Entity())
|
||||
.datum(iD.osmEntity())
|
||||
.call(iD.svgTagClasses());
|
||||
expect(selection.attr('class')).to.equal(null);
|
||||
});
|
||||
|
||||
@@ -11,19 +11,19 @@ describe('iD.svgVertices', function () {
|
||||
|
||||
|
||||
beforeEach(function () {
|
||||
context = iD.Context();
|
||||
context = iD.coreContext();
|
||||
d3.select(document.createElement('div'))
|
||||
.attr('id', 'map')
|
||||
.call(context.map());
|
||||
.call(context.map().centerZoom([0, 0], 17));
|
||||
surface = context.surface();
|
||||
});
|
||||
|
||||
|
||||
it('adds the .shared class to vertices that are members of two or more ways', function () {
|
||||
var node = iD.Node({loc: [0, 0]});
|
||||
var way1 = iD.Way({nodes: [node.id], tags: {highway: 'residential'}});
|
||||
var way2 = iD.Way({nodes: [node.id], tags: {highway: 'residential'}});
|
||||
var graph = iD.Graph([node, way1, way2]);
|
||||
var node = iD.osmNode({loc: [0, 0]});
|
||||
var way1 = iD.osmWay({nodes: [node.id], tags: {highway: 'residential'}});
|
||||
var way2 = iD.osmWay({nodes: [node.id], tags: {highway: 'residential'}});
|
||||
var graph = iD.coreGraph([node, way1, way2]);
|
||||
|
||||
surface.call(iD.svgVertices(projection, context), graph, [node]);
|
||||
expect(surface.select('.vertex').classed('shared')).to.be.true;
|
||||
|
||||
Reference in New Issue
Block a user