Skip to content

Commit 26bbf05

Browse files
committed
Merge branch 'resample-min' into 3.2
2 parents d3c949d + a53c851 commit 26bbf05

4 files changed

Lines changed: 69 additions & 28 deletions

File tree

d3.js

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3242,8 +3242,9 @@ d3 = function() {
32423242
stream.lineStart();
32433243
}
32443244
function linePoint(λ, φ) {
3245-
var c = d3_geo_cartesian([ λ, φ ]), p = project(λ, φ);
3246-
resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream);
3245+
var c = d3_geo_cartesian([ λ, φ ]), p = project(λ, φ), buffer = [];
3246+
resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, buffer);
3247+
streamLine(buffer, stream);
32473248
stream.point(x0, y0);
32483249
}
32493250
function lineEnd() {
@@ -3258,21 +3259,29 @@ d3 = function() {
32583259
resample.point = linePoint;
32593260
};
32603261
resample.lineEnd = function() {
3261-
resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, stream);
3262+
var buffer = [];
3263+
resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, buffer);
3264+
streamLine(buffer, stream);
32623265
resample.lineEnd = lineEnd;
32633266
lineEnd();
32643267
};
32653268
}
3269+
function streamLine(line, stream) {
3270+
for (var i = 0, n = line.length, point; i < n; ++i) {
3271+
stream.point((point = line[i])[0], point[1]);
3272+
}
3273+
}
32663274
return resample;
32673275
}
3268-
function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, stream) {
3276+
function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, buffer) {
32693277
var dx = x1 - x0, dy = y1 - y0, d2 = dx * dx + dy * dy;
32703278
if (d2 > 4 * δ2 && depth--) {
3271-
var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = Math.sqrt(a * a + b * b + c * c), φ2 = Math.asin(c /= m), λ2 = Math.abs(Math.abs(c) - 1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a), p = project(λ2, φ2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, dz = dy * dx2 - dx * dy2;
3272-
if (dz * dz / d2 > δ2 || Math.abs((dx * dx2 + dy * dy2) / d2 - .5) > .3) {
3273-
resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream);
3274-
stream.point(x2, y2);
3275-
resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, stream);
3279+
var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = Math.sqrt(a * a + b * b + c * c), φ2 = Math.asin(c /= m), λ2 = Math.abs(Math.abs(c) - 1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a), p = project(λ2, φ2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, dz = dy * dx2 - dx * dy2, tooFar = false;
3280+
if (dz * dz / d2 > δ2 || Math.abs((dx * dx2 + dy * dy2) / d2 - .5) > .3 || (tooFar = dx2 * dx2 + dy2 * dy2 > 256 * δ2)) {
3281+
var s0 = resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, buffer);
3282+
buffer.push(p);
3283+
var s1 = resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, buffer);
3284+
return !tooFar || s0 || s1 || (buffer.pop(), false);
32763285
}
32773286
}
32783287
}

d3.min.js

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/geo/resample.js

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ function d3_geo_resample(project) {
2828
}
2929

3030
function linePoint(λ, φ) {
31-
var c = d3_geo_cartesian([λ, φ]), p = project(λ, φ);
32-
resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream);
31+
var c = d3_geo_cartesian([λ, φ]), p = project(λ, φ), buffer = [];
32+
resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, buffer);
33+
streamLine(buffer, stream);
3334
stream.point(x0, y0);
3435
}
3536

@@ -49,16 +50,24 @@ function d3_geo_resample(project) {
4950
};
5051

5152
resample.lineEnd = function() {
52-
resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, stream);
53+
var buffer = [];
54+
resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, buffer);
55+
streamLine(buffer, stream);
5356
resample.lineEnd = lineEnd;
5457
lineEnd();
5558
};
5659
}
5760

61+
function streamLine(line, stream) {
62+
for (var i = 0, n = line.length, point; i < n; ++i) {
63+
stream.point((point = line[i])[0], point[1]);
64+
}
65+
}
66+
5867
return resample;
5968
}
6069

61-
function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, stream) {
70+
function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, buffer) {
6271
var dx = x1 - x0,
6372
dy = y1 - y0,
6473
d2 = dx * dx + dy * dy;
@@ -74,11 +83,13 @@ function d3_geo_resample(project) {
7483
y2 = p[1],
7584
dx2 = x2 - x0,
7685
dy2 = y2 - y0,
77-
dz = dy * dx2 - dx * dy2;
78-
if (dz * dz / d2 > δ2 || Math.abs((dx * dx2 + dy * dy2) / d2 - .5) > .3) {
79-
resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream);
80-
stream.point(x2, y2);
81-
resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, stream);
86+
dz = dy * dx2 - dx * dy2,
87+
tooFar = false;
88+
if (dz * dz / d2 > δ2 || Math.abs((dx * dx2 + dy * dy2) / d2 - .5) > .3 || (tooFar = dx2 * dx2 + dy2 * dy2 > 256 * δ2)) {
89+
var s0 = resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, buffer);
90+
buffer.push(p);
91+
var s1 = resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, buffer);
92+
return !tooFar || s0 || s1 || (buffer.pop(), false);
8293
}
8394
}
8495
}

test/geo/path-test.js

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,9 @@ suite.addBatch({
294294
[[109.378, 189.584], [797.758, 504.660]], 1e-3);
295295
},
296296
"centroid of a line string": function(p) {
297-
assert.inDelta(p.centroid({type: "LineString", coordinates: [[-122, 37], [-74, 40], [-100, 0]]}), [545.130, 253.859], 1e-3);
297+
var centroid = p.centroid({type: "LineString", coordinates: [[-122, 37], [-74, 40], [-100, 0]]});
298+
assert.inDelta(centroid[0], 545.131, 1e-3);
299+
assert.inDelta(centroid[1], 253.860, 1e-3);
298300
}
299301
},
300302

@@ -757,19 +759,38 @@ suite.addBatch({
757759
},
758760

759761
"with an Albers projection and adaptive resampling": {
760-
topic: function(path) {
761-
return path()
762+
"correctly resamples near the poles": function(path) {
763+
var p = path()
762764
.context(testContext)
763765
.projection(_.geo.albers()
764766
.scale(140)
765767
.rotate([0, 0])
766768
.precision(1));
767-
},
768-
"correctly resamples near the poles": function(p) {
769769
p({type: "LineString", coordinates: [[0, 88], [180, 89]]});
770770
assert.isTrue(testContext.buffer().filter(function(d) { return d.type === "lineTo"; }).length > 1);
771771
p({type: "LineString", coordinates: [[180, 90], [1, 89.5]]});
772772
assert.isTrue(testContext.buffer().filter(function(d) { return d.type === "lineTo"; }).length > 1);
773+
},
774+
"rotate([11.5, 285])": function(path) {
775+
var p = path()
776+
.context(testContext)
777+
.projection(_.geo.albers()
778+
.scale(140)
779+
.rotate([11.5, 285])
780+
.precision(1));
781+
p({type: "LineString", coordinates: [[170, 20], [170, 0]]});
782+
assert.isTrue(testContext.buffer().filter(function(d) { return d.type === "lineTo"; }).length > 1);
783+
},
784+
"wavy projection": function(path) {
785+
var p = path()
786+
.context(testContext)
787+
.projection(_.geo.projection(function(λ, φ) {
788+
return [λ, Math.sin(λ * 4)];
789+
})
790+
.scale(140)
791+
.precision(1));
792+
p({type: "LineString", coordinates: [[-45, 0], [45, 0]]});
793+
assert.isTrue(testContext.buffer().filter(function(d) { return d.type === "lineTo"; }).length > 1);
773794
}
774795
},
775796

0 commit comments

Comments
 (0)