Skip to content

Commit e8d8b13

Browse files
committed
Merge branch 'geo-length' into 3.1.0
2 parents 995b699 + f4a4d70 commit e8d8b13

5 files changed

Lines changed: 120 additions & 5 deletions

File tree

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ d3.geo.js: \
211211
src/geo/path-centroid.js \
212212
src/geo/area.js \
213213
src/geo/centroid.js \
214+
src/geo/length.js \
214215
src/geo/projection.js \
215216
src/geo/rotation.js \
216217
src/geo/stereographic.js \

d3.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6564,6 +6564,35 @@ d3 = function() {
65646564
nextPoint(λ00, φ00);
65656565
};
65666566
}
6567+
d3.geo.length = function(object) {
6568+
d3_geo_lengthSum = 0;
6569+
d3.geo.stream(object, d3_geo_length);
6570+
return d3_geo_lengthSum;
6571+
};
6572+
var d3_geo_lengthSum;
6573+
var d3_geo_length = {
6574+
sphere: d3_noop,
6575+
point: d3_noop,
6576+
lineStart: d3_geo_lengthLineStart,
6577+
lineEnd: d3_noop,
6578+
polygonStart: d3_noop,
6579+
polygonEnd: d3_noop
6580+
};
6581+
function d3_geo_lengthLineStart() {
6582+
var λ0, sinφ0, cosφ0;
6583+
d3_geo_length.point = function(λ, φ) {
6584+
λ0 = λ * d3_radians, sinφ0 = Math.sin(φ *= d3_radians), cosφ0 = Math.cos(φ);
6585+
d3_geo_length.point = nextPoint;
6586+
};
6587+
d3_geo_length.lineEnd = function() {
6588+
d3_geo_length.point = d3_geo_length.lineEnd = d3_noop;
6589+
};
6590+
function nextPoint(λ, φ) {
6591+
var sinφ = Math.sin(φ *= d3_radians), cosφ = Math.cos(φ), t = Math.abs((λ *= d3_radians) - λ0), cosΔλ = Math.cos(t);
6592+
d3_geo_lengthSum += Math.atan2(Math.sqrt((t = cosφ * Math.sin(t)) * t + (t = cosφ0 * sinφ - sinφ0 * cosφ * cosΔλ) * t), sinφ0 * sinφ + cosφ0 * cosφ * cosΔλ);
6593+
λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ;
6594+
}
6595+
}
65676596
d3.geo.projection = d3_geo_projection;
65686597
d3.geo.projectionMutator = d3_geo_projectionMutator;
65696598
function d3_geo_projection(project) {

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/length.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
d3.geo.length = function(object) {
2+
d3_geo_lengthSum = 0;
3+
d3.geo.stream(object, d3_geo_length);
4+
return d3_geo_lengthSum;
5+
};
6+
7+
var d3_geo_lengthSum;
8+
9+
var d3_geo_length = {
10+
sphere: d3_noop,
11+
point: d3_noop,
12+
lineStart: d3_geo_lengthLineStart,
13+
lineEnd: d3_noop,
14+
polygonStart: d3_noop,
15+
polygonEnd: d3_noop
16+
};
17+
18+
function d3_geo_lengthLineStart() {
19+
var λ0, sinφ0, cosφ0;
20+
21+
d3_geo_length.point = function(λ, φ) {
22+
λ0 = λ * d3_radians, sinφ0 = Math.sin(φ *= d3_radians), cosφ0 = Math.cos(φ);
23+
d3_geo_length.point = nextPoint;
24+
};
25+
26+
d3_geo_length.lineEnd = function() {
27+
d3_geo_length.point = d3_geo_length.lineEnd = d3_noop;
28+
};
29+
30+
function nextPoint(λ, φ) {
31+
var sinφ = Math.sin(φ *= d3_radians),
32+
cosφ = Math.cos(φ),
33+
t = Math.abs((λ *= d3_radians) - λ0),
34+
cosΔλ = Math.cos(t);
35+
d3_geo_lengthSum += Math.atan2(Math.sqrt((t = cosφ * Math.sin(t)) * t + (t = cosφ0 * sinφ - sinφ0 * cosφ * cosΔλ) * t), sinφ0 * sinφ + cosφ0 * cosφ * cosΔλ);
36+
λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ;
37+
}
38+
}

test/geo/length-test.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
require("../env");
2+
3+
var vows = require("vows"),
4+
assert = require("assert");
5+
6+
var suite = vows.describe("d3.geo.length");
7+
8+
var π = Math.PI;
9+
10+
suite.addBatch({
11+
"length": {
12+
topic: function() {
13+
return d3.geo.length;
14+
},
15+
"the length of points are zero": function(length) {
16+
assert.inDelta(length({type: "Point", coordinates: [0, 0]}), 0, 1e-6);
17+
assert.inDelta(length({type: "MultiPoint", coordinates: [[0, 1], [2, 3]]}), 0, 1e-6);
18+
},
19+
"the length of a line string is the sum of its great arc segments": function(length) {
20+
assert.inDelta(length({type: "LineString", coordinates: [[-45, 0], [45, 0]]}), Math.PI / 2, 1e-6);
21+
assert.inDelta(length({type: "LineString", coordinates: [[-45, 0], [-30, 0], [-15, 0], [0, 0]]}), Math.PI / 4, 1e-6);
22+
assert.inDelta(length({type: "MultiLineString", coordinates: [[[-45, 0], [-30, 0]], [[-15, 0], [0, 0]]]}), Math.PI / 6, 1e-6);
23+
},
24+
"the length of a polygon is its perimeter": function(length) {
25+
assert.inDelta(length({type: "Polygon", coordinates: [[[0, 0], [3, 0], [3, 3], [0, 3], [0, 0]]]}), 0.157008, 1e-6);
26+
assert.inDelta(length({type: "MultiPolygon", coordinates: [[[[0, 0], [3, 0], [3, 3], [0, 3], [0, 0]]]]}), 0.157008, 1e-6);
27+
assert.inDelta(length({type: "MultiPolygon", coordinates: [[[[0, 0], [3, 0], [3, 3], [0, 3], [0, 0]]], [[[1, 1], [2, 1], [2, 2], [1, 2], [1, 1]]]]}), 0.209354, 1e-6);
28+
},
29+
"the length of a polygon is its perimeter, including holes": function(length) {
30+
assert.inDelta(length({type: "Polygon", coordinates: [[[0, 0], [3, 0], [3, 3], [0, 3], [0, 0]], [[1, 1], [2, 1], [2, 2], [1, 2], [1, 1]]]}), 0.209354, 1e-6);
31+
},
32+
"the length of a feature collection is the sum of its features": function(length) {
33+
assert.inDelta(length({type: "FeatureCollection", features: [
34+
{type: "Feature", geometry: {type: "LineString", coordinates: [[-45, 0], [0, 0]]}},
35+
{type: "Feature", geometry: {type: "LineString", coordinates: [[0, 0], [45, 0]]}}
36+
]}), Math.PI / 2, 1e-6);
37+
},
38+
"the length of a geometry collection is the sum of its geometries": function(length) {
39+
assert.inDelta(length({type: "GeometryCollection", geometries: [
40+
{type: "GeometryCollection", geometries: [{type: "LineString", coordinates: [[-45, 0], [0, 0]]}]},
41+
{type: "LineString", coordinates: [[0, 0], [45, 0]]}
42+
]}), Math.PI / 2, 1e-6);
43+
}
44+
}
45+
});
46+
47+
suite.export(module);

0 commit comments

Comments
 (0)