d2-ui
Version:
122 lines (104 loc) • 3.46 kB
JavaScript
import "../core/identity";
import "../core/rebind";
import "../math/trigonometry";
import "clip-antimeridian";
import "clip-circle";
import "clip-extent";
import "compose";
import "geo";
import "path";
import "resample";
import "rotation";
import "transform";
d3.geo.projection = d3_geo_projection;
d3.geo.projectionMutator = d3_geo_projectionMutator;
function d3_geo_projection(project) {
return d3_geo_projectionMutator(function() { return project; })();
}
function d3_geo_projectionMutator(projectAt) {
var project,
rotate,
projectRotate,
projectResample = d3_geo_resample(function(x, y) { x = project(x, y); return [x[0] * k + δx, δy - x[1] * k]; }),
k = 150, // scale
x = 480, y = 250, // translate
λ = 0, φ = 0, // center
δλ = 0, δφ = 0, δγ = 0, // rotate
δx, δy, // center
preclip = d3_geo_clipAntimeridian,
postclip = d3_identity,
clipAngle = null,
clipExtent = null,
stream;
function projection(point) {
point = projectRotate(point[0] * d3_radians, point[1] * d3_radians);
return [point[0] * k + δx, δy - point[1] * k];
}
function invert(point) {
point = projectRotate.invert((point[0] - δx) / k, (δy - point[1]) / k);
return point && [point[0] * d3_degrees, point[1] * d3_degrees];
}
projection.stream = function(output) {
if (stream) stream.valid = false;
stream = d3_geo_projectionRadians(preclip(rotate, projectResample(postclip(output))));
stream.valid = true; // allow caching by d3.geo.path
return stream;
};
projection.clipAngle = function(_) {
if (!arguments.length) return clipAngle;
preclip = _ == null ? (clipAngle = _, d3_geo_clipAntimeridian) : d3_geo_clipCircle((clipAngle = +_) * d3_radians);
return invalidate();
};
projection.clipExtent = function(_) {
if (!arguments.length) return clipExtent;
clipExtent = _;
postclip = _ ? d3_geo_clipExtent(_[0][0], _[0][1], _[1][0], _[1][1]) : d3_identity;
return invalidate();
};
projection.scale = function(_) {
if (!arguments.length) return k;
k = +_;
return reset();
};
projection.translate = function(_) {
if (!arguments.length) return [x, y];
x = +_[0];
y = +_[1];
return reset();
};
projection.center = function(_) {
if (!arguments.length) return [λ * d3_degrees, φ * d3_degrees];
λ = _[0] % 360 * d3_radians;
φ = _[1] % 360 * d3_radians;
return reset();
};
projection.rotate = function(_) {
if (!arguments.length) return [δλ * d3_degrees, δφ * d3_degrees, δγ * d3_degrees];
δλ = _[0] % 360 * d3_radians;
δφ = _[1] % 360 * d3_radians;
δγ = _.length > 2 ? _[2] % 360 * d3_radians : 0;
return reset();
};
d3.rebind(projection, projectResample, "precision");
function reset() {
projectRotate = d3_geo_compose(rotate = d3_geo_rotation(δλ, δφ, δγ), project);
var center = project(λ, φ);
δx = x - center[0] * k;
δy = y + center[1] * k;
return invalidate();
}
function invalidate() {
if (stream) stream.valid = false, stream = null;
return projection;
}
return function() {
project = projectAt.apply(this, arguments);
projection.invert = project.invert && invert;
return reset();
};
}
function d3_geo_projectionRadians(stream) {
return d3_geo_transformPoint(stream, function(x, y) {
stream.point(x * d3_radians, y * d3_radians);
});
}