Skip to content

Commit

Permalink
Add d3.geo.simplify.
Browse files Browse the repository at this point in the history
Assumes that the third dimension (z) of each coordinate represents the
importance of that coordinate, and implements a filter stream that skips
coordinates that fail to meet the minimum importance threshold.
  • Loading branch information
mbostock committed Aug 15, 2013
1 parent 36e5526 commit 508ae65
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 82 deletions.
99 changes: 49 additions & 50 deletions d3.js
Expand Up @@ -2249,12 +2249,11 @@ d3 = function() {
listener.sphere();
},
Point: function(object, listener) {
var coordinate = object.coordinates;
listener.point(coordinate[0], coordinate[1]);
listener.point.apply(listener, object.coordinates);
},
MultiPoint: function(object, listener) {
var coordinates = object.coordinates, i = -1, n = coordinates.length, coordinate;
while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1]);
var coordinates = object.coordinates, i = -1, n = coordinates.length;
while (++i < n) listener.point.apply(listener, coordinates[i]);
},
LineString: function(object, listener) {
d3_geo_streamLine(object.coordinates, listener, 0);
Expand All @@ -2276,9 +2275,9 @@ d3 = function() {
}
};
function d3_geo_streamLine(coordinates, listener, closed) {
var i = -1, n = coordinates.length - closed, coordinate;
var i = -1, n = coordinates.length - closed;
listener.lineStart();
while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1]);
while (++i < n) listener.point.apply(listener, coordinates[i]);
listener.lineEnd();
}
function d3_geo_streamPolygon(coordinates, listener) {
Expand All @@ -2287,6 +2286,26 @@ d3 = function() {
while (++i < n) d3_geo_streamLine(coordinates[i], listener, 1);
listener.polygonEnd();
}
function d3_geo_streamTransform(stream, point) {
return {
point: point,
sphere: function() {
stream.sphere();
},
lineStart: function() {
stream.lineStart();
},
lineEnd: function() {
stream.lineEnd();
},
polygonStart: function() {
stream.polygonStart();
},
polygonEnd: function() {
stream.polygonEnd();
}
};
}
d3.geo.area = function(object) {
d3_geo_areaSum = 0;
d3.geo.stream(object, d3_geo_area);
Expand Down Expand Up @@ -3556,31 +3575,13 @@ d3 = function() {
return path.projection(d3.geo.albersUsa()).context(null);
};
function d3_geo_pathProjectStream(project) {
var resample = d3_geo_resample(function(λ, φ) {
return project([ λ * d3_degrees, φ * d3_degrees ]);
var resample = d3_geo_resample(function(x, y) {
return project([ x * d3_degrees, y * d3_degrees ]);
});
return function(stream) {
stream = resample(stream);
return {
point: function(λ, φ) {
stream.point(λ * d3_radians, φ * d3_radians);
},
sphere: function() {
stream.sphere();
},
lineStart: function() {
stream.lineStart();
},
lineEnd: function() {
stream.lineEnd();
},
polygonStart: function() {
stream.polygonStart();
},
polygonEnd: function() {
stream.polygonEnd();
}
};
return d3_geo_streamTransform(stream = resample(stream), function(x, y) {
stream.point(x * d3_radians, y * d3_radians);
});
};
}
d3.geo.projection = d3_geo_projection;
Expand Down Expand Up @@ -3663,27 +3664,10 @@ d3 = function() {
};
}
function d3_geo_projectionRadiansRotate(rotate, stream) {
return {
point: function(x, y) {
y = rotate(x * d3_radians, y * d3_radians), x = y[0];
stream.point(x > π ? x - 2 * π : x < -π ? x + 2 * π : x, y[1]);
},
sphere: function() {
stream.sphere();
},
lineStart: function() {
stream.lineStart();
},
lineEnd: function() {
stream.lineEnd();
},
polygonStart: function() {
stream.polygonStart();
},
polygonEnd: function() {
stream.polygonEnd();
}
};
return d3_geo_streamTransform(stream, function(x, y) {
y = rotate(x * d3_radians, y * d3_radians), x = y[0];
stream.point(x > π ? x - 2 * π : x < -π ? x + 2 * π : x, y[1]);
});
}
function d3_geo_equirectangular(λ, φ) {
return [ λ, φ ];
Expand Down Expand Up @@ -3953,6 +3937,21 @@ d3 = function() {
λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ;
}
}
d3.geo.simplify = function() {
var importance = 1, simplify = {
stream: function(stream) {
return d3_geo_streamTransform(stream, function(x, y, z) {
if (z >= importance) stream.point(x, y);
});
},
importance: function(_) {
if (!arguments.length) return importance;
importance = +_;
return simplify;
}
};
return simplify;
};
function d3_geo_azimuthal(scale, angle) {
function azimuthal(λ, φ) {
var cosλ = Math.cos(λ), cosφ = Math.cos(φ), k = scale(cosλ * cosφ);
Expand Down
10 changes: 5 additions & 5 deletions d3.min.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/geo/index.js
Expand Up @@ -16,6 +16,7 @@ import "path-context";
import "projection";
import "rotation";
import "stream";
import "simplify";
import "albers";
import "albers-usa";
import "azimuthal";
Expand Down
14 changes: 4 additions & 10 deletions src/geo/path.js
Expand Up @@ -82,16 +82,10 @@ d3.geo.path = function() {
};

function d3_geo_pathProjectStream(project) {
var resample = d3_geo_resample(function(λ, φ) { return project([λ * d3_degrees, φ * d3_degrees]); });
var resample = d3_geo_resample(function(x, y) { return project([x * d3_degrees, y * d3_degrees]); });
return function(stream) {
stream = resample(stream);
return {
point: function(λ, φ) { stream.point(λ * d3_radians, φ * d3_radians); },
sphere: function() { stream.sphere(); },
lineStart: function() { stream.lineStart(); },
lineEnd: function() { stream.lineEnd(); },
polygonStart: function() { stream.polygonStart(); },
polygonEnd: function() { stream.polygonEnd(); }
};
return d3_geo_streamTransform(stream = resample(stream), function(x, y) {
stream.point(x * d3_radians, y * d3_radians);
});
};
}
15 changes: 4 additions & 11 deletions src/geo/projection.js
Expand Up @@ -115,15 +115,8 @@ function d3_geo_projectionMutator(projectAt) {
}

function d3_geo_projectionRadiansRotate(rotate, stream) {
return {
point: function(x, y) {
y = rotate(x * d3_radians, y * d3_radians), x = y[0];
stream.point(x > π ? x - 2 * π : x < -π ? x + 2 * π : x, y[1]);
},
sphere: function() { stream.sphere(); },
lineStart: function() { stream.lineStart(); },
lineEnd: function() { stream.lineEnd(); },
polygonStart: function() { stream.polygonStart(); },
polygonEnd: function() { stream.polygonEnd(); }
};
return d3_geo_streamTransform(stream, function(x, y) {
y = rotate(x * d3_radians, y * d3_radians), x = y[0];
stream.point(x > π ? x - 2 * π : x < -π ? x + 2 * π : x, y[1]);
});
}
18 changes: 18 additions & 0 deletions src/geo/simplify.js
@@ -0,0 +1,18 @@
import "geo";
import "stream";

d3.geo.simplify = function() {
var importance = 1, simplify = {
stream: function(stream) {
return d3_geo_streamTransform(stream, function(x, y, z) {
if (z >= importance) stream.point(x, y);
});
},
importance: function(_) {
if (!arguments.length) return importance;
importance = +_;
return simplify;
}
};
return simplify;
};
22 changes: 16 additions & 6 deletions src/geo/stream.js
Expand Up @@ -29,12 +29,11 @@ var d3_geo_streamGeometryType = {
listener.sphere();
},
Point: function(object, listener) {
var coordinate = object.coordinates;
listener.point(coordinate[0], coordinate[1]);
listener.point.apply(listener, object.coordinates);
},
MultiPoint: function(object, listener) {
var coordinates = object.coordinates, i = -1, n = coordinates.length, coordinate;
while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1]);
var coordinates = object.coordinates, i = -1, n = coordinates.length;
while (++i < n) listener.point.apply(listener, coordinates[i]);
},
LineString: function(object, listener) {
d3_geo_streamLine(object.coordinates, listener, 0);
Expand All @@ -57,9 +56,9 @@ var d3_geo_streamGeometryType = {
};

function d3_geo_streamLine(coordinates, listener, closed) {
var i = -1, n = coordinates.length - closed, coordinate;
var i = -1, n = coordinates.length - closed;
listener.lineStart();
while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1]);
while (++i < n) listener.point.apply(listener, coordinates[i]);
listener.lineEnd();
}

Expand All @@ -69,3 +68,14 @@ function d3_geo_streamPolygon(coordinates, listener) {
while (++i < n) d3_geo_streamLine(coordinates[i], listener, 1);
listener.polygonEnd();
}

function d3_geo_streamTransform(stream, point) {
return {
point: point,
sphere: function() { stream.sphere(); },
lineStart: function() { stream.lineStart(); },
lineEnd: function() { stream.lineEnd(); },
polygonStart: function() { stream.polygonStart(); },
polygonEnd: function() { stream.polygonEnd(); }
};
}

0 comments on commit 508ae65

Please sign in to comment.