Skip to content

Commit 95c88eb

Browse files
committed
Enforce built-in precision for outline, too.
1 parent fb449fc commit 95c88eb

4 files changed

Lines changed: 154 additions & 38 deletions

File tree

d3.v2.js

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1971,6 +1971,22 @@
19711971
function d3_geo_equirectangular(λ, φ) {
19721972
return [ λ, φ ];
19731973
}
1974+
function d3_geo_graticuleX(y0, y1) {
1975+
var y = d3.range(y0, y1 - ε, d3_geo_graticulePrecision).concat(y1);
1976+
return function(x) {
1977+
return y.map(function(y) {
1978+
return [ x, y ];
1979+
});
1980+
};
1981+
}
1982+
function d3_geo_graticuleY(x0, x1) {
1983+
var x = d3.range(x0, x1 - ε, d3_geo_graticulePrecision).concat(x1);
1984+
return function(y) {
1985+
return x.map(function(x) {
1986+
return [ x, y ];
1987+
});
1988+
};
1989+
}
19741990
function d3_geo_greatArcSource(d) {
19751991
return d.source;
19761992
}
@@ -6315,29 +6331,19 @@
63156331
geometries: graticule.lines()
63166332
};
63176333
}
6318-
var x1 = 180 - ε, x0 = -x1, y1 = 90 - ε, y0 = -y1, dx = 22.5, dy = dx, δx = 2, δy = 2;
6334+
var x1, x0, y1, y0, dx = 22.5, dy = dx, x, y;
63196335
graticule.lines = function() {
6320-
var xSteps = d3.range(x0, x1 - ε, δx).concat(x1), ySteps = d3.range(y0, y1 - ε, δy).concat(y1), xLines = d3.range(Math.ceil(x0 / dx) * dx, x1, dx).map(function(x) {
6321-
return ySteps.map(function(y) {
6322-
return [ x, y ];
6323-
});
6324-
}), yLines = d3.range(Math.ceil(y0 / dy) * dy, y1, dy).map(function(y) {
6325-
return xSteps.map(function(x) {
6326-
return [ x, y ];
6327-
});
6328-
});
6329-
return xLines.concat(yLines).map(function(coordinates) {
6336+
return d3.range(Math.ceil(x0 / dx) * dx, x1, dx).map(x).concat(d3.range(Math.ceil(y0 / dy) * dy, y1, dy).map(y)).map(function(coordinates) {
63306337
return {
63316338
type: "LineString",
63326339
coordinates: coordinates
63336340
};
63346341
});
63356342
};
63366343
graticule.outline = function() {
6337-
var x2 = (x0 + x1) / 2;
63386344
return {
63396345
type: "Polygon",
6340-
coordinates: [ [ [ x0, y1 ], [ x2, y1 ], [ x1, y1 ], [ x1, y0 ], [ x2, y0 ], [ x0, y0 ], [ x0, y1 ] ] ]
6346+
coordinates: [ x(x0).concat(y(y1).slice(1), x(x1).reverse().slice(1), y(y0).reverse().slice(1)) ]
63416347
};
63426348
};
63436349
graticule.extent = function(_) {
@@ -6346,15 +6352,18 @@
63466352
y0 = +_[0][1], y1 = +_[1][1];
63476353
if (x0 > x1) _ = x0, x0 = x1, x1 = _;
63486354
if (y0 > y1) _ = y0, y0 = y1, y1 = _;
6355+
x = d3_geo_graticuleX(y0, y1);
6356+
y = d3_geo_graticuleY(x0, x1);
63496357
return graticule;
63506358
};
63516359
graticule.step = function(_) {
63526360
if (!arguments.length) return [ dx, dy ];
63536361
dx = +_[0], dy = +_[1];
63546362
return graticule;
63556363
};
6356-
return graticule;
6364+
return graticule.extent([ [ -180 + ε, -90 + ε ], [ 180 - ε, 90 - ε ] ]);
63576365
};
6366+
var d3_geo_graticulePrecision = 3;
63586367
d3.geo.greatArc = function() {
63596368
function greatArc() {
63606369
var d = greatArc.distance.apply(this, arguments), t = 0, dt = precision / d, coordinates = [ p0 ];

d3.v2.min.js

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

src/geo/graticule.js

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
d3.geo.graticule = function() {
2-
var x1 = 180 - ε, x0 = -x1,
3-
y1 = 90 - ε, y0 = -y1,
2+
var x1, x0,
3+
y1, y0,
44
dx = 22.5, dy = dx,
5-
δx = 2, δy = 2;
5+
x, y;
66

77
function graticule() {
88
return {
@@ -12,27 +12,25 @@ d3.geo.graticule = function() {
1212
}
1313

1414
graticule.lines = function() {
15-
var xSteps = d3.range(x0, x1 - ε, δx).concat(x1),
16-
ySteps = d3.range(y0, y1 - ε, δy).concat(y1),
17-
xLines = d3.range(Math.ceil(x0 / dx) * dx, x1, dx).map(function(x) { return ySteps.map(function(y) { return [x, y]; }); }),
18-
yLines = d3.range(Math.ceil(y0 / dy) * dy, y1, dy).map(function(y) { return xSteps.map(function(x) { return [x, y]; }); });
19-
return xLines.concat(yLines).map(function(coordinates) {
20-
return {
21-
type: "LineString",
22-
coordinates: coordinates
23-
};
24-
});
15+
return d3.range(Math.ceil(x0 / dx) * dx, x1, dx).map(x)
16+
.concat(d3.range(Math.ceil(y0 / dy) * dy, y1, dy).map(y))
17+
.map(function(coordinates) {
18+
return {
19+
type: "LineString",
20+
coordinates: coordinates
21+
};
22+
});
2523
}
2624

2725
graticule.outline = function() {
28-
var x2 = (x0 + x1) / 2;
2926
return {
3027
type: "Polygon",
31-
coordinates: [[
32-
[x0, y1], [x2, y1], [x1, y1],
33-
[x1, y0], [x2, y0], [x0, y0],
34-
[x0, y1]
35-
]]
28+
coordinates: [
29+
x(x0)
30+
.concat(y(y1).slice(1),
31+
x(x1).reverse().slice(1),
32+
y(y0).reverse().slice(1))
33+
]
3634
};
3735
};
3836

@@ -42,6 +40,8 @@ d3.geo.graticule = function() {
4240
y0 = +_[0][1], y1 = +_[1][1];
4341
if (x0 > x1) _ = x0, x0 = x1, x1 = _;
4442
if (y0 > y1) _ = y0, y0 = y1, y1 = _;
43+
x = d3_geo_graticuleX(y0, y1);
44+
y = d3_geo_graticuleY(x0, x1);
4545
return graticule;
4646
};
4747

@@ -51,5 +51,25 @@ d3.geo.graticule = function() {
5151
return graticule;
5252
};
5353

54-
return graticule;
54+
return graticule.extent([[-180 + ε, -90 + ε], [180 - ε, 90 - ε]]);
5555
};
56+
57+
var d3_geo_graticulePrecision = 3;
58+
59+
function d3_geo_graticuleX(y0, y1) {
60+
var y = d3.range(y0, y1 - ε, d3_geo_graticulePrecision).concat(y1);
61+
return function(x) {
62+
return y.map(function(y) {
63+
return [x, y];
64+
});
65+
};
66+
}
67+
68+
function d3_geo_graticuleY(x0, x1) {
69+
var x = d3.range(x0, x1 - ε, d3_geo_graticulePrecision).concat(x1);
70+
return function(y) {
71+
return x.map(function(x) {
72+
return [x, y];
73+
});
74+
};
75+
}

test/geo/graticule-test.js

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
require("../env");
2+
3+
var vows = require("vows"),
4+
assert = require("assert");
5+
6+
var suite = vows.describe("d3.geo.graticule");
7+
8+
var ε = 1e-6;
9+
10+
suite.addBatch({
11+
"graticule": {
12+
topic: function() {
13+
return d3.geo.graticule()
14+
.extent([[-90, -45], [90, 45]])
15+
.step([45, 45]);
16+
},
17+
18+
"extent": {
19+
"defaults to just inside –180º, -90º to +180º, +90º": function() {
20+
assert.deepEqual(d3.geo.graticule().extent(), [[-180 + ε, -90 + ε], [180 - ε, 90 - ε]]);
21+
},
22+
"coerces input values to numbers": function() {
23+
var graticule = d3.geo.graticule().extent([["-90", "-45"], ["+90", "+45"]]),
24+
extent = graticule.extent();
25+
assert.strictEqual(extent[0][0], -90);
26+
assert.strictEqual(extent[0][1], -45);
27+
assert.strictEqual(extent[1][0], +90);
28+
assert.strictEqual(extent[1][1], +45);
29+
}
30+
},
31+
32+
"returns a GeometryCollection of LineStrings": function(graticule) {
33+
assert.deepEqual(graticule(), {
34+
type: "GeometryCollection",
35+
geometries: [
36+
{type: "LineString", coordinates: [[-90,-45],[-90,-42],[-90,-39],[-90,-36],[-90,-33],[-90,-30],[-90,-27],[-90,-24],[-90,-21],[-90,-18],[-90,-15],[-90,-12],[-90,-9],[-90,-6],[-90,-3],[-90,0],[-90,3],[-90,6],[-90,9],[-90,12],[-90,15],[-90,18],[-90,21],[-90,24],[-90,27],[-90,30],[-90,33],[-90,36],[-90,39],[-90,42],[-90,45]]},
37+
{type: "LineString", coordinates: [[-45,-45],[-45,-42],[-45,-39],[-45,-36],[-45,-33],[-45,-30],[-45,-27],[-45,-24],[-45,-21],[-45,-18],[-45,-15],[-45,-12],[-45,-9],[-45,-6],[-45,-3],[-45,0],[-45,3],[-45,6],[-45,9],[-45,12],[-45,15],[-45,18],[-45,21],[-45,24],[-45,27],[-45,30],[-45,33],[-45,36],[-45,39],[-45,42],[-45,45]]},
38+
{type: "LineString", coordinates: [[0,-45],[0,-42],[0,-39],[0,-36],[0,-33],[0,-30],[0,-27],[0,-24],[0,-21],[0,-18],[0,-15],[0,-12],[0,-9],[0,-6],[0,-3],[0,0],[0,3],[0,6],[0,9],[0,12],[0,15],[0,18],[0,21],[0,24],[0,27],[0,30],[0,33],[0,36],[0,39],[0,42],[0,45]]},
39+
{type: "LineString", coordinates: [[45,-45],[45,-42],[45,-39],[45,-36],[45,-33],[45,-30],[45,-27],[45,-24],[45,-21],[45,-18],[45,-15],[45,-12],[45,-9],[45,-6],[45,-3],[45,0],[45,3],[45,6],[45,9],[45,12],[45,15],[45,18],[45,21],[45,24],[45,27],[45,30],[45,33],[45,36],[45,39],[45,42],[45,45]]},
40+
{type: "LineString", coordinates: [[-90,-45],[-87,-45],[-84,-45],[-81,-45],[-78,-45],[-75,-45],[-72,-45],[-69,-45],[-66,-45],[-63,-45],[-60,-45],[-57,-45],[-54,-45],[-51,-45],[-48,-45],[-45,-45],[-42,-45],[-39,-45],[-36,-45],[-33,-45],[-30,-45],[-27,-45],[-24,-45],[-21,-45],[-18,-45],[-15,-45],[-12,-45],[-9,-45],[-6,-45],[-3,-45],[0,-45],[3,-45],[6,-45],[9,-45],[12,-45],[15,-45],[18,-45],[21,-45],[24,-45],[27,-45],[30,-45],[33,-45],[36,-45],[39,-45],[42,-45],[45,-45],[48,-45],[51,-45],[54,-45],[57,-45],[60,-45],[63,-45],[66,-45],[69,-45],[72,-45],[75,-45],[78,-45],[81,-45],[84,-45],[87,-45],[90,-45]]},
41+
{type: "LineString", coordinates: [[-90,0],[-87,0],[-84,0],[-81,0],[-78,0],[-75,0],[-72,0],[-69,0],[-66,0],[-63,0],[-60,0],[-57,0],[-54,0],[-51,0],[-48,0],[-45,0],[-42,0],[-39,0],[-36,0],[-33,0],[-30,0],[-27,0],[-24,0],[-21,0],[-18,0],[-15,0],[-12,0],[-9,0],[-6,0],[-3,0],[0,0],[3,0],[6,0],[9,0],[12,0],[15,0],[18,0],[21,0],[24,0],[27,0],[30,0],[33,0],[36,0],[39,0],[42,0],[45,0],[48,0],[51,0],[54,0],[57,0],[60,0],[63,0],[66,0],[69,0],[72,0],[75,0],[78,0],[81,0],[84,0],[87,0],[90,0]]}
42+
]
43+
});
44+
},
45+
46+
"step": {
47+
"defaults to 22.5º, 22.5º": function(graticule) {
48+
assert.deepEqual(d3.geo.graticule().step(), [22.5, 22.5]);
49+
},
50+
"coerces input values to numbers": function() {
51+
var graticule = d3.geo.graticule().step(["45", "11.25"]),
52+
step = graticule.step();
53+
assert.strictEqual(step[0], 45);
54+
assert.strictEqual(step[1], 11.25);
55+
}
56+
},
57+
58+
"outline": {
59+
"returns a Polygon": function(graticule) {
60+
assert.deepEqual(graticule.outline(), {
61+
type: "Polygon",
62+
coordinates: [[
63+
[-90,-45],[-90,-42],[-90,-39],[-90,-36],[-90,-33],[-90,-30],[-90,-27],[-90,-24],[-90,-21],[-90,-18],[-90,-15],[-90,-12],[-90,-9],[-90,-6],[-90,-3],[-90,0],[-90,3],[-90,6],[-90,9],[-90,12],[-90,15],[-90,18],[-90,21],[-90,24],[-90,27],[-90,30],[-90,33],[-90,36],[-90,39],[-90,42],[-90,45],
64+
[-87,45],[-84,45],[-81,45],[-78,45],[-75,45],[-72,45],[-69,45],[-66,45],[-63,45],[-60,45],[-57,45],[-54,45],[-51,45],[-48,45],[-45,45],[-42,45],[-39,45],[-36,45],[-33,45],[-30,45],[-27,45],[-24,45],[-21,45],[-18,45],[-15,45],[-12,45],[-9,45],[-6,45],[-3,45],[0,45],[3,45],[6,45],[9,45],[12,45],[15,45],[18,45],[21,45],[24,45],[27,45],[30,45],[33,45],[36,45],[39,45],[42,45],[45,45],[48,45],[51,45],[54,45],[57,45],[60,45],[63,45],[66,45],[69,45],[72,45],[75,45],[78,45],[81,45],[84,45],[87,45],[90,45],
65+
[90,42],[90,39],[90,36],[90,33],[90,30],[90,27],[90,24],[90,21],[90,18],[90,15],[90,12],[90,9],[90,6],[90,3],[90,0],[90,-3],[90,-6],[90,-9],[90,-12],[90,-15],[90,-18],[90,-21],[90,-24],[90,-27],[90,-30],[90,-33],[90,-36],[90,-39],[90,-42],[90,-45],
66+
[87,-45],[84,-45],[81,-45],[78,-45],[75,-45],[72,-45],[69,-45],[66,-45],[63,-45],[60,-45],[57,-45],[54,-45],[51,-45],[48,-45],[45,-45],[42,-45],[39,-45],[36,-45],[33,-45],[30,-45],[27,-45],[24,-45],[21,-45],[18,-45],[15,-45],[12,-45],[9,-45],[6,-45],[3,-45],[0,-45],[-3,-45],[-6,-45],[-9,-45],[-12,-45],[-15,-45],[-18,-45],[-21,-45],[-24,-45],[-27,-45],[-30,-45],[-33,-45],[-36,-45],[-39,-45],[-42,-45],[-45,-45],[-48,-45],[-51,-45],[-54,-45],[-57,-45],[-60,-45],[-63,-45],[-66,-45],[-69,-45],[-72,-45],[-75,-45],[-78,-45],[-81,-45],[-84,-45],[-87,-45],[-90,-45]
67+
]]
68+
});
69+
}
70+
},
71+
72+
"line": {
73+
"returns an array of LineStrings": function(graticule) {
74+
assert.deepEqual(graticule.lines(), [
75+
{type: "LineString", coordinates: [[-90,-45],[-90,-42],[-90,-39],[-90,-36],[-90,-33],[-90,-30],[-90,-27],[-90,-24],[-90,-21],[-90,-18],[-90,-15],[-90,-12],[-90,-9],[-90,-6],[-90,-3],[-90,0],[-90,3],[-90,6],[-90,9],[-90,12],[-90,15],[-90,18],[-90,21],[-90,24],[-90,27],[-90,30],[-90,33],[-90,36],[-90,39],[-90,42],[-90,45]]},
76+
{type: "LineString", coordinates: [[-45,-45],[-45,-42],[-45,-39],[-45,-36],[-45,-33],[-45,-30],[-45,-27],[-45,-24],[-45,-21],[-45,-18],[-45,-15],[-45,-12],[-45,-9],[-45,-6],[-45,-3],[-45,0],[-45,3],[-45,6],[-45,9],[-45,12],[-45,15],[-45,18],[-45,21],[-45,24],[-45,27],[-45,30],[-45,33],[-45,36],[-45,39],[-45,42],[-45,45]]},
77+
{type: "LineString", coordinates: [[0,-45],[0,-42],[0,-39],[0,-36],[0,-33],[0,-30],[0,-27],[0,-24],[0,-21],[0,-18],[0,-15],[0,-12],[0,-9],[0,-6],[0,-3],[0,0],[0,3],[0,6],[0,9],[0,12],[0,15],[0,18],[0,21],[0,24],[0,27],[0,30],[0,33],[0,36],[0,39],[0,42],[0,45]]},
78+
{type: "LineString", coordinates: [[45,-45],[45,-42],[45,-39],[45,-36],[45,-33],[45,-30],[45,-27],[45,-24],[45,-21],[45,-18],[45,-15],[45,-12],[45,-9],[45,-6],[45,-3],[45,0],[45,3],[45,6],[45,9],[45,12],[45,15],[45,18],[45,21],[45,24],[45,27],[45,30],[45,33],[45,36],[45,39],[45,42],[45,45]]},
79+
{type: "LineString", coordinates: [[-90,-45],[-87,-45],[-84,-45],[-81,-45],[-78,-45],[-75,-45],[-72,-45],[-69,-45],[-66,-45],[-63,-45],[-60,-45],[-57,-45],[-54,-45],[-51,-45],[-48,-45],[-45,-45],[-42,-45],[-39,-45],[-36,-45],[-33,-45],[-30,-45],[-27,-45],[-24,-45],[-21,-45],[-18,-45],[-15,-45],[-12,-45],[-9,-45],[-6,-45],[-3,-45],[0,-45],[3,-45],[6,-45],[9,-45],[12,-45],[15,-45],[18,-45],[21,-45],[24,-45],[27,-45],[30,-45],[33,-45],[36,-45],[39,-45],[42,-45],[45,-45],[48,-45],[51,-45],[54,-45],[57,-45],[60,-45],[63,-45],[66,-45],[69,-45],[72,-45],[75,-45],[78,-45],[81,-45],[84,-45],[87,-45],[90,-45]]},
80+
{type: "LineString", coordinates: [[-90,0],[-87,0],[-84,0],[-81,0],[-78,0],[-75,0],[-72,0],[-69,0],[-66,0],[-63,0],[-60,0],[-57,0],[-54,0],[-51,0],[-48,0],[-45,0],[-42,0],[-39,0],[-36,0],[-33,0],[-30,0],[-27,0],[-24,0],[-21,0],[-18,0],[-15,0],[-12,0],[-9,0],[-6,0],[-3,0],[0,0],[3,0],[6,0],[9,0],[12,0],[15,0],[18,0],[21,0],[24,0],[27,0],[30,0],[33,0],[36,0],[39,0],[42,0],[45,0],[48,0],[51,0],[54,0],[57,0],[60,0],[63,0],[66,0],[69,0],[72,0],[75,0],[78,0],[81,0],[84,0],[87,0],[90,0]]}
81+
]);
82+
}
83+
}
84+
}
85+
});
86+
87+
suite.export(module);

0 commit comments

Comments
 (0)