mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-20 23:44:47 +02:00
Merge pull request #918 from systemed/resample-oneway
Resample oneway paths to produce markers.
This commit is contained in:
+4
-7
@@ -695,17 +695,14 @@ text {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.oneway .textpath {
|
||||
pointer-events: none;
|
||||
font-size: 7px;
|
||||
baseline-shift: 2px;
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.oneway .textpath.tag-waterway {
|
||||
fill: #002F35;
|
||||
}
|
||||
|
||||
marker#oneway-marker path {
|
||||
fill:#000;
|
||||
}
|
||||
|
||||
text.tag-oneway {
|
||||
fill:#91CFFF;
|
||||
stroke:#2C6B9B;
|
||||
|
||||
+29
-2
@@ -13,8 +13,34 @@ iD.svg = {
|
||||
};
|
||||
},
|
||||
|
||||
LineString: function(projection, graph, dimensions) {
|
||||
var cache = {};
|
||||
resample: function(points, dx) {
|
||||
var o = [];
|
||||
for (var i = 0; i < points.length - 1; i++) {
|
||||
var a = points[i], b = points[i + 1],
|
||||
span = iD.geo.dist(a, b);
|
||||
o.push(a);
|
||||
// if there is space to fit one or more oneway mark
|
||||
// in this segment
|
||||
if (span > dx) {
|
||||
// the angle from a to b
|
||||
var angle = Math.atan2(b[1] - a[1], b[0] - a[0]),
|
||||
to = points[i].slice();
|
||||
while (iD.geo.dist(a, to) < (span - dx)) {
|
||||
// a dx-length line segment in that angle
|
||||
to[0] += Math.cos(angle) * dx;
|
||||
to[1] += Math.sin(angle) * dx;
|
||||
o.push(to.slice());
|
||||
}
|
||||
}
|
||||
o.push(b);
|
||||
}
|
||||
return o;
|
||||
},
|
||||
|
||||
LineString: function(projection, graph, dimensions, dx) {
|
||||
var cache = {},
|
||||
resample = this.resample;
|
||||
|
||||
return function(entity) {
|
||||
if (cache[entity.id] !== undefined) {
|
||||
return cache[entity.id];
|
||||
@@ -34,6 +60,7 @@ iD.svg = {
|
||||
|
||||
cache[entity.id] =
|
||||
segments.map(function(points) {
|
||||
if (dx) points = resample(points, dx);
|
||||
return 'M' + points.map(function(p) {
|
||||
return p[0] + ',' + p[1];
|
||||
}).join('L');
|
||||
|
||||
+5
-55
@@ -1,8 +1,5 @@
|
||||
iD.svg.Lines = function(projection) {
|
||||
|
||||
var arrowtext = '►\u3000\u3000\u3000',
|
||||
alength;
|
||||
|
||||
var highway_stack = {
|
||||
motorway: 0,
|
||||
motorway_link: 1,
|
||||
@@ -92,16 +89,6 @@ iD.svg.Lines = function(projection) {
|
||||
return paths;
|
||||
}
|
||||
|
||||
if (!alength) {
|
||||
var container = surface.append('g')
|
||||
.attr('class', 'oneway'),
|
||||
arrow = container.append('text')
|
||||
.attr('class', 'textpath')
|
||||
.text(arrowtext);
|
||||
alength = arrow.node().getComputedTextLength();
|
||||
container.remove();
|
||||
}
|
||||
|
||||
var lines = [];
|
||||
|
||||
for (var i = 0; i < entities.length; i++) {
|
||||
@@ -117,6 +104,7 @@ iD.svg.Lines = function(projection) {
|
||||
lines.sort(waystack);
|
||||
|
||||
var lineString = iD.svg.LineString(projection, graph, dimensions);
|
||||
var lineStringResampled = iD.svg.LineString(projection, graph, dimensions, 35);
|
||||
|
||||
var shadow = surface.select('.layer-shadow'),
|
||||
casing = surface.select('.layer-casing'),
|
||||
@@ -127,47 +115,9 @@ iD.svg.Lines = function(projection) {
|
||||
casings = drawPaths(casing, lines, filter, 'casing', lineString),
|
||||
strokes = drawPaths(stroke, lines, filter, 'stroke', lineString);
|
||||
|
||||
// Determine the lengths of oneway paths
|
||||
var lengths = {},
|
||||
oneways = strokes.filter(function(d) { return d.isOneWay(); }).each(function(d) {
|
||||
lengths[d.id] = Math.floor(this.getTotalLength() / alength);
|
||||
}).data();
|
||||
|
||||
var uses = defs.selectAll('path')
|
||||
.filter(filter)
|
||||
.data(oneways, iD.Entity.key);
|
||||
|
||||
uses.enter()
|
||||
.append('path');
|
||||
|
||||
uses
|
||||
.attr('id', function(d) { return 'shadow-' + d.id; })
|
||||
.attr('d', lineString);
|
||||
|
||||
uses.exit()
|
||||
.remove();
|
||||
|
||||
var labels = text.selectAll('text')
|
||||
.filter(filter)
|
||||
.data(oneways, iD.Entity.key);
|
||||
|
||||
var tagClasses = iD.svg.TagClasses();
|
||||
|
||||
var tp = labels.enter()
|
||||
.append('text')
|
||||
.attr({ 'class': 'oneway', dy: 4 })
|
||||
.append('textPath')
|
||||
.attr('class', 'textpath')
|
||||
.call(tagClasses);
|
||||
|
||||
labels.exit().remove();
|
||||
|
||||
text.selectAll('.textpath')
|
||||
.filter(filter)
|
||||
.attr('xlink:href', function(d) { return '#shadow-' + d.id; })
|
||||
.text(function(d) {
|
||||
// adding longer text than necessary, since overflow is hidden
|
||||
return (new Array(Math.floor(lengths[d.id] * 1.1))).join(arrowtext);
|
||||
});
|
||||
strokes
|
||||
.filter(function(d) { return d.isOneWay(); })
|
||||
.attr('marker-mid', 'url(#oneway-marker)')
|
||||
.attr('d', lineStringResampled);
|
||||
};
|
||||
};
|
||||
|
||||
+12
-1
@@ -1,6 +1,17 @@
|
||||
iD.svg.Surface = function() {
|
||||
return function drawSurface(selection) {
|
||||
selection.append('defs');
|
||||
var defs = selection.append('defs');
|
||||
defs.append('marker')
|
||||
.attr({
|
||||
id: 'oneway-marker',
|
||||
viewBox: '0 0 10 10',
|
||||
refY: 2.5,
|
||||
markerWidth: 2,
|
||||
markerHeight: 2,
|
||||
orient: 'auto'
|
||||
})
|
||||
.append('path')
|
||||
.attr('d', 'M 0 0 L 5 2.5 L 0 5 z');
|
||||
|
||||
var layers = selection.selectAll('.layer')
|
||||
.data(['fill', 'shadow', 'casing', 'stroke', 'text', 'hit', 'halo', 'label']);
|
||||
|
||||
@@ -14,8 +14,8 @@ describe("iD.svg.Areas", function () {
|
||||
|
||||
surface.call(iD.svg.Areas(projection), graph, [area], filter);
|
||||
|
||||
expect(surface.select('path')).to.be.classed('way');
|
||||
expect(surface.select('path')).to.be.classed('area');
|
||||
expect(surface.select('path.way')).to.be.classed('way');
|
||||
expect(surface.select('path.area')).to.be.classed('area');
|
||||
});
|
||||
|
||||
it("adds tag classes", function () {
|
||||
|
||||
@@ -17,8 +17,8 @@ describe("iD.svg.Lines", function () {
|
||||
|
||||
surface.call(iD.svg.Lines(projection), graph, [line], filter, dimensions);
|
||||
|
||||
expect(surface.select('path')).to.be.classed('way');
|
||||
expect(surface.select('path')).to.be.classed('line');
|
||||
expect(surface.select('path.way')).to.be.classed('way');
|
||||
expect(surface.select('path.line')).to.be.classed('line');
|
||||
});
|
||||
|
||||
it("adds tag classes", function () {
|
||||
|
||||
Reference in New Issue
Block a user