mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-20 07:25:15 +02:00
Fix svg layer selections, fix and add tests..
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import * as d3 from 'd3';
|
||||
import { d3geoTile } from '../lib/d3.geo.tile';
|
||||
import { prefixCSSProperty, functor } from '../util/index';
|
||||
import { prefixCSSProperty } from '../util/index';
|
||||
import { BackgroundSource } from './background_source.js';
|
||||
|
||||
export function TileLayer(context) {
|
||||
var tileSize = 256,
|
||||
@@ -10,7 +11,7 @@ export function TileLayer(context) {
|
||||
tileOrigin,
|
||||
z,
|
||||
transformProp = prefixCSSProperty('Transform'),
|
||||
source = functor('');
|
||||
source = BackgroundSource.None();
|
||||
|
||||
|
||||
// blacklist overlay tiles around Null Island..
|
||||
|
||||
+10
-8
@@ -24,23 +24,25 @@ export function Layers(projection, context) {
|
||||
svg = selection.selectAll('.surface')
|
||||
.data([0]);
|
||||
|
||||
svg.enter()
|
||||
svg = svg.enter()
|
||||
.append('svg')
|
||||
.attr('class', 'surface')
|
||||
.merge(svg);
|
||||
|
||||
svg
|
||||
.append('defs');
|
||||
|
||||
var groups = svg.selectAll('.data-layer')
|
||||
.data(layers);
|
||||
|
||||
groups.enter()
|
||||
.append('g')
|
||||
.attr('class', function(d) { return 'data-layer data-layer-' + d.id; });
|
||||
|
||||
groups
|
||||
.each(function(d) { d3.select(this).call(d.layer); });
|
||||
|
||||
groups.exit()
|
||||
.remove();
|
||||
|
||||
groups.enter()
|
||||
.append('g')
|
||||
.attr('class', function(d) { return 'data-layer data-layer-' + d.id; })
|
||||
.merge(groups)
|
||||
.each(function(d) { d3.select(this).call(d.layer); });
|
||||
}
|
||||
|
||||
drawLayers.all = function() {
|
||||
|
||||
@@ -64,13 +64,16 @@ export function Midpoints(projection, context) {
|
||||
if (midpoints[d.id])
|
||||
return true;
|
||||
|
||||
for (var i = 0; i < d.parents.length; i++)
|
||||
if (filter(d.parents[i]))
|
||||
for (var i = 0; i < d.parents.length; i++) {
|
||||
if (filter(d.parents[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
var layer = selection.selectAll('.layer-hit');
|
||||
|
||||
var groups = layer
|
||||
@@ -78,6 +81,9 @@ export function Midpoints(projection, context) {
|
||||
.filter(midpointFilter)
|
||||
.data(_.values(midpoints), function(d) { return d.id; });
|
||||
|
||||
groups.exit()
|
||||
.remove();
|
||||
|
||||
var enter = groups.enter()
|
||||
.insert('g', ':first-child')
|
||||
.attr('class', 'midpoint');
|
||||
@@ -90,11 +96,12 @@ export function Midpoints(projection, context) {
|
||||
.attr('points', '-3,4 5,0 -3,-4')
|
||||
.attr('class', 'fill');
|
||||
|
||||
groups
|
||||
groups = groups
|
||||
.merge(enter)
|
||||
.attr('transform', function(d) {
|
||||
var translate = PointTransform(projection),
|
||||
a = context.entity(d.edge[0]),
|
||||
b = context.entity(d.edge[1]),
|
||||
a = graph.entity(d.edge[0]),
|
||||
b = graph.entity(d.edge[1]),
|
||||
angleVal = Math.round(angle(a, b, projection) * (180 / Math.PI));
|
||||
return translate(d) + ' rotate(' + angleVal + ')';
|
||||
})
|
||||
@@ -106,7 +113,5 @@ export function Midpoints(projection, context) {
|
||||
groups.select('polygon.shadow');
|
||||
groups.select('polygon.fill');
|
||||
|
||||
groups.exit()
|
||||
.remove();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ export function Points(projection, context) {
|
||||
groups.select('.icon')
|
||||
.attr('xlink:href', function(entity) {
|
||||
var preset = context.presets().match(entity, graph);
|
||||
return preset.icon ? '#' + preset.icon + '-12' : '';
|
||||
return (preset && preset.icon) ? '#' + preset.icon + '-12' : '';
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@@ -104,8 +104,10 @@
|
||||
|
||||
<script src='spec/svg/areas.js'></script>
|
||||
<script src='spec/svg/icon.js'></script>
|
||||
<script src='spec/svg/layers.js'></script>
|
||||
<script src='spec/svg/lines.js'></script>
|
||||
<script src='spec/svg/midpoints.js'></script>
|
||||
<script src='spec/svg/osm.js'></script>
|
||||
<script src='spec/svg/points.js'></script>
|
||||
<script src='spec/svg/svg.js'></script>
|
||||
<script src='spec/svg/tag_classes.js'></script>
|
||||
|
||||
+24
-18
@@ -1,13 +1,19 @@
|
||||
describe('iD.svg.Areas', function () {
|
||||
var surface,
|
||||
projection = d3.geoProjection(function(x, y) { return [x, y]; })
|
||||
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; };
|
||||
|
||||
beforeEach(function () {
|
||||
surface = d3.select(document.createElementNS('http://www.w3.org/2000/svg', 'svg'))
|
||||
.call(iD.svg.Layers(projection, iD.Context(window)));
|
||||
context = iD.Context(window);
|
||||
d3.select(document.createElement('div'))
|
||||
.attr('id', 'map')
|
||||
.call(context.map());
|
||||
surface = context.surface();
|
||||
|
||||
iD.setAreaKeys({
|
||||
building: {},
|
||||
landuse: {},
|
||||
@@ -24,7 +30,7 @@ describe('iD.svg.Areas', function () {
|
||||
iD.Way({id: 'w', tags: {building: 'yes'}, nodes: ['a', 'b', 'c', 'a']})
|
||||
]);
|
||||
|
||||
surface.call(iD.svg.Areas(projection), graph, [graph.entity('w')], none);
|
||||
surface.call(iD.svg.Areas(projection, context), graph, [graph.entity('w')], none);
|
||||
|
||||
expect(surface.select('path.way')).to.be.classed('way');
|
||||
expect(surface.select('path.area')).to.be.classed('area');
|
||||
@@ -39,7 +45,7 @@ describe('iD.svg.Areas', function () {
|
||||
iD.Way({id: 'w', tags: {building: 'yes'}, nodes: ['a', 'b', 'c', 'a']})
|
||||
]);
|
||||
|
||||
surface.call(iD.svg.Areas(projection), graph, [graph.entity('w')], none);
|
||||
surface.call(iD.svg.Areas(projection, context), graph, [graph.entity('w')], none);
|
||||
|
||||
expect(surface.select('.area')).to.be.classed('tag-building');
|
||||
expect(surface.select('.area')).to.be.classed('tag-building-yes');
|
||||
@@ -55,10 +61,10 @@ describe('iD.svg.Areas', function () {
|
||||
iD.Way({id: 'x', tags: {area: 'yes'}, nodes: ['a', 'b', 'd', 'a']})
|
||||
]);
|
||||
|
||||
surface.call(iD.svg.Areas(projection), graph, [graph.entity('x')], all);
|
||||
surface.call(iD.svg.Areas(projection, context), graph, [graph.entity('x')], all);
|
||||
graph = graph.remove(graph.entity('x')).remove(graph.entity('d'));
|
||||
|
||||
surface.call(iD.svg.Areas(projection), graph, [graph.entity('w')], all);
|
||||
surface.call(iD.svg.Areas(projection, context), graph, [graph.entity('w')], all);
|
||||
expect(surface.select('.area').size()).to.equal(1);
|
||||
});
|
||||
|
||||
@@ -77,30 +83,30 @@ describe('iD.svg.Areas', function () {
|
||||
]);
|
||||
|
||||
it('stacks smaller areas above larger ones in a single render', function () {
|
||||
surface.call(iD.svg.Areas(projection), graph, [graph.entity('s'), graph.entity('l')], none);
|
||||
surface.call(iD.svg.Areas(projection, context), graph, [graph.entity('s'), graph.entity('l')], none);
|
||||
|
||||
expect(surface.select('.area:nth-child(1)')).to.be.classed('tag-landuse-park');
|
||||
expect(surface.select('.area:nth-child(2)')).to.be.classed('tag-building-yes');
|
||||
});
|
||||
|
||||
it('stacks smaller areas above larger ones in a single render (reverse)', function () {
|
||||
surface.call(iD.svg.Areas(projection), graph, [graph.entity('l'), graph.entity('s')], none);
|
||||
surface.call(iD.svg.Areas(projection, context), graph, [graph.entity('l'), graph.entity('s')], none);
|
||||
|
||||
expect(surface.select('.area:nth-child(1)')).to.be.classed('tag-landuse-park');
|
||||
expect(surface.select('.area:nth-child(2)')).to.be.classed('tag-building-yes');
|
||||
});
|
||||
|
||||
it('stacks smaller areas above larger ones in separate renders', function () {
|
||||
surface.call(iD.svg.Areas(projection), graph, [graph.entity('s')], none);
|
||||
surface.call(iD.svg.Areas(projection), graph, [graph.entity('l')], none);
|
||||
surface.call(iD.svg.Areas(projection, context), graph, [graph.entity('s')], none);
|
||||
surface.call(iD.svg.Areas(projection, context), graph, [graph.entity('l')], none);
|
||||
|
||||
expect(surface.select('.area:nth-child(1)')).to.be.classed('tag-landuse-park');
|
||||
expect(surface.select('.area:nth-child(2)')).to.be.classed('tag-building-yes');
|
||||
});
|
||||
|
||||
it('stacks smaller areas above larger ones in separate renders (reverse)', function () {
|
||||
surface.call(iD.svg.Areas(projection), graph, [graph.entity('l')], none);
|
||||
surface.call(iD.svg.Areas(projection), graph, [graph.entity('s')], none);
|
||||
surface.call(iD.svg.Areas(projection, context), graph, [graph.entity('l')], none);
|
||||
surface.call(iD.svg.Areas(projection, context), graph, [graph.entity('s')], none);
|
||||
|
||||
expect(surface.select('.area:nth-child(1)')).to.be.classed('tag-landuse-park');
|
||||
expect(surface.select('.area:nth-child(2)')).to.be.classed('tag-building-yes');
|
||||
@@ -116,7 +122,7 @@ describe('iD.svg.Areas', function () {
|
||||
graph = iD.Graph([a, b, c, w, r]),
|
||||
areas = [w, r];
|
||||
|
||||
surface.call(iD.svg.Areas(projection), graph, areas, none);
|
||||
surface.call(iD.svg.Areas(projection, context), graph, areas, none);
|
||||
|
||||
expect(surface.select('.fill')).to.be.classed('relation');
|
||||
});
|
||||
@@ -130,7 +136,7 @@ describe('iD.svg.Areas', function () {
|
||||
graph = iD.Graph([a, b, c, w, r]),
|
||||
areas = [w, r];
|
||||
|
||||
surface.call(iD.svg.Areas(projection), graph, areas, none);
|
||||
surface.call(iD.svg.Areas(projection, context), graph, areas, none);
|
||||
|
||||
expect(surface.selectAll('.stroke').size()).to.equal(0);
|
||||
});
|
||||
@@ -143,7 +149,7 @@ describe('iD.svg.Areas', function () {
|
||||
r = iD.Relation({members: [{id: w.id, type: 'way'}], tags: {type: 'multipolygon'}}),
|
||||
graph = iD.Graph([a, b, c, w, r]);
|
||||
|
||||
surface.call(iD.svg.Areas(projection), graph, [w, r], none);
|
||||
surface.call(iD.svg.Areas(projection, context), graph, [w, r], none);
|
||||
|
||||
expect(surface.selectAll('.way.fill').size()).to.equal(0);
|
||||
expect(surface.selectAll('.relation.fill').size()).to.equal(1);
|
||||
@@ -158,7 +164,7 @@ describe('iD.svg.Areas', function () {
|
||||
r = iD.Relation({members: [{id: w.id, type: 'way'}], tags: {type: 'multipolygon'}}),
|
||||
graph = iD.Graph([a, b, c, w, r]);
|
||||
|
||||
surface.call(iD.svg.Areas(projection), graph, [w, r], none);
|
||||
surface.call(iD.svg.Areas(projection, context), graph, [w, r], none);
|
||||
|
||||
expect(surface.selectAll('.stroke').size()).to.equal(0);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
describe('iD.svg.Layers', 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]]);
|
||||
|
||||
beforeEach(function () {
|
||||
context = iD.Context(window);
|
||||
container = d3.select(document.createElement('div'));
|
||||
});
|
||||
|
||||
|
||||
it('creates a surface', function () {
|
||||
container.call(iD.svg.Layers(projection, context));
|
||||
expect(container.selectAll('svg')).to.be.classed('surface');
|
||||
});
|
||||
|
||||
it('creates default data layers', function () {
|
||||
container.call(iD.svg.Layers(projection, context));
|
||||
var nodes = container.selectAll('svg .data-layer').nodes();
|
||||
expect(nodes.length).to.eql(5);
|
||||
expect(d3.select(nodes[0])).to.be.classed('data-layer-osm');
|
||||
expect(d3.select(nodes[1])).to.be.classed('data-layer-gpx');
|
||||
expect(d3.select(nodes[2])).to.be.classed('data-layer-mapillary-images');
|
||||
expect(d3.select(nodes[3])).to.be.classed('data-layer-mapillary-signs');
|
||||
expect(d3.select(nodes[4])).to.be.classed('data-layer-debug');
|
||||
});
|
||||
|
||||
});
|
||||
+10
-4
@@ -1,15 +1,21 @@
|
||||
describe('iD.svg.Lines', function () {
|
||||
var surface,
|
||||
projection = d3.geoProjection(function(x, y) { return [x, y]; })
|
||||
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; };
|
||||
|
||||
beforeEach(function () {
|
||||
surface = d3.select(document.createElementNS('http://www.w3.org/2000/svg', 'svg'))
|
||||
.call(iD.svg.Layers(projection, iD.Context(window)));
|
||||
context = iD.Context(window);
|
||||
d3.select(document.createElement('div'))
|
||||
.attr('id', 'map')
|
||||
.call(context.map());
|
||||
surface = context.surface();
|
||||
});
|
||||
|
||||
|
||||
it('adds way and line classes', function () {
|
||||
var a = iD.Node({loc: [0, 0]}),
|
||||
b = iD.Node({loc: [1, 1]}),
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
describe('iD.svg.Midpoints', function () {
|
||||
var surface,
|
||||
projection = Object,
|
||||
filter = function() { return true; },
|
||||
context;
|
||||
var context, surface,
|
||||
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; };
|
||||
|
||||
beforeEach(function () {
|
||||
context = iD.Context(window);
|
||||
surface = d3.select(document.createElementNS('http://www.w3.org/2000/svg', 'svg'))
|
||||
.call(iD.svg.Layers(projection, context));
|
||||
d3.select(document.createElement('div'))
|
||||
.attr('id', 'map')
|
||||
.call(context.map());
|
||||
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]}),
|
||||
@@ -21,7 +26,7 @@ describe('iD.svg.Midpoints', function () {
|
||||
context.entity = function(id) { return graph.entity(id); };
|
||||
surface.call(iD.svg.Midpoints(projection, context), graph, [line], filter, extent);
|
||||
|
||||
expect(surface.select('.midpoint').datum().loc).to.eql([25, 0]);
|
||||
expect(surface.selectAll('.midpoint').datum().loc).to.eql([25, 0]);
|
||||
});
|
||||
|
||||
it('doesn\'t create midpoint on segment with pixel length less than 40', function () {
|
||||
@@ -61,7 +66,7 @@ describe('iD.svg.Midpoints', function () {
|
||||
context.entity = function(id) { return graph.entity(id); };
|
||||
surface.call(iD.svg.Midpoints(projection, context), graph, [line], filter, extent);
|
||||
|
||||
expect(surface.select('.midpoint').datum().loc).to.eql([100, 0]);
|
||||
expect(surface.selectAll('.midpoint').datum().loc).to.eql([100, 0]);
|
||||
});
|
||||
|
||||
it('doesn\'t create midpoint on extent edge for segment with pixel length less than 20', function () {
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
describe('iD.svg.Osm', function () {
|
||||
var container;
|
||||
|
||||
beforeEach(function () {
|
||||
container = d3.select(document.createElementNS('http://www.w3.org/2000/svg', 'svg'));
|
||||
});
|
||||
|
||||
it('creates default osm layers', function () {
|
||||
container.call(iD.svg.Osm());
|
||||
var nodes = container.selectAll('.layer-osm').nodes();
|
||||
expect(nodes.length).to.eql(5);
|
||||
expect(d3.select(nodes[0])).to.be.classed('layer-areas');
|
||||
expect(d3.select(nodes[1])).to.be.classed('layer-lines');
|
||||
expect(d3.select(nodes[2])).to.be.classed('layer-hit');
|
||||
expect(d3.select(nodes[3])).to.be.classed('layer-halo');
|
||||
expect(d3.select(nodes[4])).to.be.classed('layer-label');
|
||||
});
|
||||
|
||||
});
|
||||
+11
-6
@@ -1,14 +1,19 @@
|
||||
describe('iD.svg.Points', function () {
|
||||
var surface,
|
||||
projection = Object,
|
||||
context;
|
||||
var context, surface,
|
||||
projection = d3.geoProjection(function(x, y) { return [x, -y]; })
|
||||
.translate([0, 0])
|
||||
.scale(180 / Math.PI)
|
||||
.clipExtent([[0, 0], [Infinity, Infinity]]);
|
||||
|
||||
beforeEach(function () {
|
||||
context = iD.Context(window).presets(iD.data.presets);
|
||||
surface = d3.select(document.createElementNS('http://www.w3.org/2000/svg', 'svg'))
|
||||
.call(iD.svg.Layers(projection, context));
|
||||
context = iD.Context(window);
|
||||
d3.select(document.createElement('div'))
|
||||
.attr('id', 'map')
|
||||
.call(context.map());
|
||||
surface = context.surface();
|
||||
});
|
||||
|
||||
|
||||
it('adds tag classes', function () {
|
||||
var point = iD.Node({tags: {amenity: 'cafe'}, loc: [0, 0]}),
|
||||
graph = iD.Graph([point]);
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
describe('iD.svg.Vertices', function () {
|
||||
var surface,
|
||||
projection = Object,
|
||||
context;
|
||||
var context, surface,
|
||||
projection = d3.geoProjection(function(x, y) { return [x, -y]; })
|
||||
.translate([0, 0])
|
||||
.scale(180 / Math.PI)
|
||||
.clipExtent([[0, 0], [Infinity, Infinity]]);
|
||||
|
||||
beforeEach(function () {
|
||||
context = iD.Context(window);
|
||||
surface = d3.select(document.createElementNS('http://www.w3.org/2000/svg', 'svg'))
|
||||
.call(iD.svg.Layers(projection, context));
|
||||
d3.select(document.createElement('div'))
|
||||
.attr('id', 'map')
|
||||
.call(context.map());
|
||||
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]}),
|
||||
way1 = iD.Way({nodes: [node.id], tags: {highway: 'residential'}}),
|
||||
|
||||
Reference in New Issue
Block a user