Skip to content

Commit ffd047b

Browse files
committed
Implement path.area using d3.geo.stream.
1 parent e7fa28b commit ffd047b

4 files changed

Lines changed: 86 additions & 65 deletions

File tree

d3.js

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6331,34 +6331,11 @@
63316331
buffer = [];
63326332
return result;
63336333
}
6334-
path.area = d3_geo_type({
6335-
Feature: function(feature) {
6336-
return areaType.geometry(feature.geometry);
6337-
},
6338-
FeatureCollection: function(collection) {
6339-
return d3.sum(collection.features, areaType.Feature);
6340-
},
6341-
GeometryCollection: function(collection) {
6342-
return d3.sum(collection.geometries, areaType.geometry);
6343-
},
6344-
LineString: d3_zero,
6345-
MultiLineString: d3_zero,
6346-
MultiPoint: d3_zero,
6347-
MultiPolygon: objectArea,
6348-
Point: d3_zero,
6349-
Polygon: objectArea,
6350-
Sphere: objectArea
6351-
});
6352-
function objectArea(o) {
6353-
o = projection.object(o);
6354-
return o ? o.type === "Polygon" ? polygonArea(o.coordinates) : d3.sum(o.coordinates, polygonArea) : 0;
6355-
}
6356-
function polygonArea(polygon) {
6357-
return Math.abs(d3.sum(polygon, ringArea));
6358-
}
6359-
function ringArea(ring) {
6360-
return d3.geom.polygon(ring).area();
6361-
}
6334+
path.area = function(object) {
6335+
d3_geo_areaSum = 0;
6336+
d3.geo.stream(object, projection.stream(d3_geo_pathArea));
6337+
return d3_geo_areaSum;
6338+
};
63626339
path.bounds = function(object) {
63636340
return d3_geo_bounds(projection)(object);
63646341
};
@@ -6449,6 +6426,35 @@
64496426
function d3_geo_pathCircle(radius) {
64506427
return "m0," + radius + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + "a" + radius + "," + radius + " 0 1,1 0," + +2 * radius + "z";
64516428
}
6429+
var d3_geo_pathExterior;
6430+
var d3_geo_pathArea = {
6431+
point: d3_noop,
6432+
lineStart: d3_noop,
6433+
lineEnd: d3_noop,
6434+
polygonStart: function() {
6435+
d3_geo_pathExterior = true;
6436+
d3_geo_pathArea.lineStart = d3_geo_pathAreaRingStart;
6437+
d3_geo_pathArea.lineEnd = d3_geo_pathAreaRingEnd;
6438+
},
6439+
polygonEnd: function() {
6440+
d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop;
6441+
}
6442+
};
6443+
function d3_geo_pathAreaRingStart() {
6444+
var x0, y0;
6445+
d3_geo_pathArea.point = function(x, y) {
6446+
d3_geo_pathArea.point = nextPoint;
6447+
x0 = x, y0 = y;
6448+
};
6449+
function nextPoint(x, y) {
6450+
d3_geo_areaRing += y0 * x - x0 * y;
6451+
x0 = x, y0 = y;
6452+
}
6453+
}
6454+
function d3_geo_pathAreaRingEnd() {
6455+
d3_geo_areaSum += Math.abs(d3_geo_areaRing) / (d3_geo_pathExterior ? 2 : -2);
6456+
d3_geo_pathExterior = false;
6457+
}
64526458
d3.geo.area = function(object) {
64536459
d3_geo_areaSum = 0;
64546460
d3.geo.stream(object, d3_geo_area);
@@ -6468,14 +6474,14 @@
64686474
},
64696475
polygonEnd: function() {
64706476
d3_geo_areaSum += d3_geo_areaRing < 0 ? 4 * π + d3_geo_areaRing : d3_geo_areaRing;
6471-
d3_geo_area.point = d3_geo_area.lineStart = d3_noop;
6477+
d3_geo_area.lineStart = d3_geo_area.point = d3_noop;
64726478
}
64736479
};
64746480
function d3_geo_areaRingStart() {
64756481
var λ00, φ00, λ0, φ0, cosφ0, sinφ0;
64766482
d3_geo_area.point = function(λ, φ) {
6477-
λ00 = λ0 = λ * d3_radians, φ00 = φ0 = φ * d3_radians, cosφ0 = Math.cos(φ0), sinφ0 = Math.sin(φ0);
64786483
d3_geo_area.point = nextPoint;
6484+
λ00 = λ0 = λ * d3_radians, φ00 = φ0 = φ * d3_radians, cosφ0 = Math.cos(φ0), sinφ0 = Math.sin(φ0);
64796485
};
64806486
function nextPoint(λ, φ) {
64816487
λ *= d3_radians, φ *= d3_radians;

d3.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/area.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ var d3_geo_area = {
2020
},
2121
polygonEnd: function() {
2222
d3_geo_areaSum += d3_geo_areaRing < 0 ? 4 * π + d3_geo_areaRing : d3_geo_areaRing;
23-
d3_geo_area.point = d3_geo_area.lineStart = d3_noop;
23+
d3_geo_area.lineStart = d3_geo_area.point = d3_noop;
2424
}
2525
};
2626

@@ -29,8 +29,8 @@ function d3_geo_areaRingStart() {
2929

3030
// For the first point, …
3131
d3_geo_area.point = function(λ, φ) {
32-
λ00 = λ0 = λ * d3_radians, φ00 = φ0 = φ * d3_radians, cosφ0 = Math.cos(φ0), sinφ0 = Math.sin(φ0);
3332
d3_geo_area.point = nextPoint;
33+
λ00 = λ0 = λ * d3_radians, φ00 = φ0 = φ * d3_radians, cosφ0 = Math.cos(φ0), sinφ0 = Math.sin(φ0);
3434
};
3535

3636
// For subsequent points, …

src/geo/path.js

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,35 +17,11 @@ d3.geo.path = function() {
1717
return result;
1818
}
1919

20-
path.area = d3_geo_type({
21-
Feature: function(feature) { return areaType.geometry(feature.geometry); },
22-
FeatureCollection: function(collection) { return d3.sum(collection.features, areaType.Feature); },
23-
GeometryCollection: function(collection) { return d3.sum(collection.geometries, areaType.geometry); },
24-
LineString: d3_zero,
25-
MultiLineString: d3_zero,
26-
MultiPoint: d3_zero,
27-
MultiPolygon: objectArea,
28-
Point: d3_zero,
29-
Polygon: objectArea,
30-
Sphere: objectArea
31-
});
32-
33-
// For object types Polygon, MultiPolygon and Sphere only.
34-
function objectArea(o) {
35-
o = projection.object(o);
36-
return o
37-
? o.type === "Polygon" ? polygonArea(o.coordinates)
38-
: d3.sum(o.coordinates, polygonArea)
39-
: 0;
40-
}
41-
42-
function polygonArea(polygon) {
43-
return Math.abs(d3.sum(polygon, ringArea));
44-
}
45-
46-
function ringArea(ring) {
47-
return d3.geom.polygon(ring).area();
48-
}
20+
path.area = function(object) {
21+
d3_geo_areaSum = 0;
22+
d3.geo.stream(object, projection.stream(d3_geo_pathArea));
23+
return d3_geo_areaSum;
24+
};
4925

5026
path.bounds = function(object) {
5127
return d3_geo_bounds(projection)(object);
@@ -184,3 +160,42 @@ function d3_geo_pathCircle(radius) {
184160
+ "a" + radius + "," + radius + " 0 1,1 0," + (+2 * radius)
185161
+ "z";
186162
}
163+
164+
var d3_geo_pathExterior;
165+
166+
var d3_geo_pathArea = {
167+
point: d3_noop,
168+
lineStart: d3_noop,
169+
lineEnd: d3_noop,
170+
171+
// Only count area for polygon rings.
172+
polygonStart: function() {
173+
d3_geo_pathExterior = true;
174+
d3_geo_pathArea.lineStart = d3_geo_pathAreaRingStart;
175+
d3_geo_pathArea.lineEnd = d3_geo_pathAreaRingEnd;
176+
},
177+
polygonEnd: function() {
178+
d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop;
179+
}
180+
};
181+
182+
function d3_geo_pathAreaRingStart() {
183+
var x0, y0;
184+
185+
// For the first point, …
186+
d3_geo_pathArea.point = function(x, y) {
187+
d3_geo_pathArea.point = nextPoint;
188+
x0 = x, y0 = y;
189+
};
190+
191+
// For subsequent points, …
192+
function nextPoint(x, y) {
193+
d3_geo_areaRing += y0 * x - x0 * y;
194+
x0 = x, y0 = y;
195+
}
196+
}
197+
198+
function d3_geo_pathAreaRingEnd() {
199+
d3_geo_areaSum += Math.abs(d3_geo_areaRing) / (d3_geo_pathExterior ? 2 : -2);
200+
d3_geo_pathExterior = false;
201+
}

0 commit comments

Comments
 (0)