Minor optimizations to d3_geo_resample.
This commit is contained in:
Родитель
4782853182
Коммит
0c295a2f62
|
@ -5427,74 +5427,72 @@
|
||||||
d[1] /= l;
|
d[1] /= l;
|
||||||
d[2] /= l;
|
d[2] /= l;
|
||||||
}
|
}
|
||||||
function d3_geo_resample(projectPoint) {
|
function d3_geo_resample(project) {
|
||||||
var δ2 = .5, maxDepth = 16;
|
var δ2 = .5, maxDepth = 16;
|
||||||
function resample(listener) {
|
function resample(stream) {
|
||||||
|
var λ0, x0, y0, a0, b0, c0;
|
||||||
var resample = {
|
var resample = {
|
||||||
point: resamplePoint,
|
point: point,
|
||||||
lineStart: lineStart,
|
lineStart: lineStart,
|
||||||
lineEnd: lineEnd,
|
lineEnd: lineEnd,
|
||||||
polygonStart: function() {
|
polygonStart: function() {
|
||||||
listener.polygonStart();
|
stream.polygonStart();
|
||||||
resample.lineStart = ringStart;
|
resample.lineStart = polygonLineStart;
|
||||||
},
|
},
|
||||||
polygonEnd: function() {
|
polygonEnd: function() {
|
||||||
listener.polygonEnd();
|
stream.polygonEnd();
|
||||||
},
|
}
|
||||||
sphere: d3_noop
|
|
||||||
};
|
};
|
||||||
|
function point(x, y) {
|
||||||
|
x = project(x, y);
|
||||||
|
stream.point(x[0], x[1]);
|
||||||
|
}
|
||||||
function lineStart() {
|
function lineStart() {
|
||||||
x0 = NaN;
|
x0 = NaN;
|
||||||
resample.point = resamplePointLine;
|
resample.point = linePoint;
|
||||||
listener.lineStart();
|
stream.lineStart();
|
||||||
|
}
|
||||||
|
function linePoint(λ, φ) {
|
||||||
|
var c = d3_geo_cartesian([ λ, φ ]), p = project(λ, φ);
|
||||||
|
resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream);
|
||||||
|
stream.point(x0, y0);
|
||||||
}
|
}
|
||||||
function lineEnd() {
|
function lineEnd() {
|
||||||
resample.point = resamplePoint;
|
resample.point = point;
|
||||||
listener.lineEnd();
|
stream.lineEnd();
|
||||||
}
|
}
|
||||||
function ringStart() {
|
function polygonLineStart() {
|
||||||
var λ00, φ00;
|
var λ00, φ00, x00, y00, a00, b00, c00;
|
||||||
lineStart();
|
lineStart();
|
||||||
resample.point = function(λ, φ) {
|
resample.point = function(λ, φ) {
|
||||||
resamplePointLine(λ00 = λ, φ00 = φ);
|
linePoint(λ00 = λ, φ00 = φ), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0;
|
||||||
resample.point = resamplePointLine;
|
resample.point = linePoint;
|
||||||
};
|
};
|
||||||
resample.lineEnd = function() {
|
resample.lineEnd = function() {
|
||||||
var cartesian = d3_geo_cartesian([ λ00, φ00 ]), p = projectPoint(λ00, φ00);
|
resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, stream);
|
||||||
resampleLineTo(x0, y0, λ0, a0, b0, c0, p[0], p[1], λ00, cartesian[0], cartesian[1], cartesian[2], maxDepth, listener);
|
|
||||||
resample.lineEnd = lineEnd;
|
resample.lineEnd = lineEnd;
|
||||||
lineEnd();
|
lineEnd();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
function resamplePoint(λ, φ) {
|
|
||||||
var point = projectPoint(λ, φ);
|
|
||||||
listener.point(point[0], point[1]);
|
|
||||||
}
|
|
||||||
var λ0, x0, y0, a0, b0, c0;
|
|
||||||
function resamplePointLine(λ, φ) {
|
|
||||||
var cartesian = d3_geo_cartesian([ λ, φ ]), p = projectPoint(λ, φ);
|
|
||||||
resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = cartesian[0], b0 = cartesian[1], c0 = cartesian[2], maxDepth, listener);
|
|
||||||
listener.point(x0, y0);
|
|
||||||
}
|
|
||||||
return resample;
|
return resample;
|
||||||
}
|
}
|
||||||
|
function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, stream) {
|
||||||
|
var dx = x1 - x0, dy = y1 - y0, distance2 = dx * dx + dy * dy;
|
||||||
|
if (distance2 > 4 * δ2 && depth--) {
|
||||||
|
var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = Math.sqrt(a * a + b * b + c * c), φ2 = Math.asin(c /= m), λ2 = Math.abs(Math.abs(c) - 1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a), p = project(λ2, φ2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, dz = dy * dx2 - dx * dy2;
|
||||||
|
if (dz * dz / distance2 > δ2 || Math.abs((dx * dx2 + dy * dy2) / distance2 - .5) > .3) {
|
||||||
|
resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream);
|
||||||
|
stream.point(x2, y2);
|
||||||
|
resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
resample.precision = function(_) {
|
resample.precision = function(_) {
|
||||||
if (!arguments.length) return Math.sqrt(δ2);
|
if (!arguments.length) return Math.sqrt(δ2);
|
||||||
maxDepth = (δ2 = _ * _) > 0 && 16;
|
maxDepth = (δ2 = _ * _) > 0 && 16;
|
||||||
return resample;
|
return resample;
|
||||||
};
|
};
|
||||||
return resample;
|
return resample;
|
||||||
function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, listener) {
|
|
||||||
var dx = x1 - x0, dy = y1 - y0, distance2 = dx * dx + dy * dy;
|
|
||||||
if (distance2 > 4 * δ2 && depth--) {
|
|
||||||
var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = Math.sqrt(a * a + b * b + c * c), φ2 = Math.asin(c /= m), λ2 = Math.abs(Math.abs(c) - 1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a), p = projectPoint(λ2, φ2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, dz = dy * dx2 - dx * dy2;
|
|
||||||
if (dz * dz / distance2 > δ2 || Math.abs((dx * dx2 + dy * dy2) / distance2 - .5) > .3) {
|
|
||||||
resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, listener);
|
|
||||||
listener.point(x2, y2);
|
|
||||||
resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
d3.geo.albersUsa = function() {
|
d3.geo.albersUsa = function() {
|
||||||
var lower48 = d3.geo.albers();
|
var lower48 = d3.geo.albers();
|
||||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -1,77 +1,85 @@
|
||||||
function d3_geo_resample(projectPoint) {
|
function d3_geo_resample(project) {
|
||||||
var δ2 = .5, // precision, px²
|
var δ2 = .5, // precision, px²
|
||||||
maxDepth = 16;
|
maxDepth = 16;
|
||||||
|
|
||||||
// TODO rename: this is not just resampling, it also projects and transforms!
|
function resample(stream) {
|
||||||
function resample(listener) {
|
var λ0, x0, y0, a0, b0, c0; // previous point
|
||||||
|
|
||||||
var resample = {
|
var resample = {
|
||||||
point: resamplePoint,
|
point: point,
|
||||||
lineStart: lineStart,
|
lineStart: lineStart,
|
||||||
lineEnd: lineEnd,
|
lineEnd: lineEnd,
|
||||||
polygonStart: function() {
|
polygonStart: function() { stream.polygonStart(); resample.lineStart = polygonLineStart; },
|
||||||
listener.polygonStart();
|
polygonEnd: function() { stream.polygonEnd(); }
|
||||||
resample.lineStart = ringStart;
|
|
||||||
},
|
|
||||||
polygonEnd: function() { listener.polygonEnd(); },
|
|
||||||
sphere: d3_noop
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function point(x, y) {
|
||||||
|
x = project(x, y);
|
||||||
|
stream.point(x[0], x[1]);
|
||||||
|
}
|
||||||
|
|
||||||
function lineStart() {
|
function lineStart() {
|
||||||
x0 = NaN;
|
x0 = NaN;
|
||||||
resample.point = resamplePointLine;
|
resample.point = linePoint;
|
||||||
listener.lineStart();
|
stream.lineStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
function linePoint(λ, φ) {
|
||||||
|
var c = d3_geo_cartesian([λ, φ]), p = project(λ, φ);
|
||||||
|
resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream);
|
||||||
|
stream.point(x0, y0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function lineEnd() {
|
function lineEnd() {
|
||||||
resample.point = resamplePoint;
|
resample.point = point;
|
||||||
listener.lineEnd();
|
stream.lineEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
function ringStart() {
|
function polygonLineStart() {
|
||||||
var λ00, φ00; // first point
|
var λ00, φ00, x00, y00, a00, b00, c00; // first point
|
||||||
|
|
||||||
lineStart();
|
lineStart();
|
||||||
|
|
||||||
resample.point = function(λ, φ) {
|
resample.point = function(λ, φ) {
|
||||||
resamplePointLine(λ00 = λ, φ00 = φ);
|
linePoint(λ00 = λ, φ00 = φ), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0;
|
||||||
resample.point = resamplePointLine;
|
resample.point = linePoint;
|
||||||
};
|
};
|
||||||
|
|
||||||
resample.lineEnd = function() {
|
resample.lineEnd = function() {
|
||||||
var cartesian = d3_geo_cartesian([λ00, φ00]),
|
resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, stream);
|
||||||
p = projectPoint(λ00, φ00);
|
|
||||||
resampleLineTo(x0, y0, λ0, a0, b0, c0,
|
|
||||||
p[0], p[1], λ00, cartesian[0], cartesian[1], cartesian[2],
|
|
||||||
maxDepth, listener);
|
|
||||||
resample.lineEnd = lineEnd;
|
resample.lineEnd = lineEnd;
|
||||||
lineEnd();
|
lineEnd();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO rename: this is not just resampling, it also projects and transforms!
|
|
||||||
function resamplePoint(λ, φ) {
|
|
||||||
var point = projectPoint(λ, φ);
|
|
||||||
listener.point(point[0], point[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
var λ0,
|
|
||||||
x0,
|
|
||||||
y0,
|
|
||||||
a0,
|
|
||||||
b0,
|
|
||||||
c0;
|
|
||||||
|
|
||||||
// TODO rename: this is not just resampling, it also projects and transforms!
|
|
||||||
function resamplePointLine(λ, φ) {
|
|
||||||
var cartesian = d3_geo_cartesian([λ, φ]),
|
|
||||||
p = projectPoint(λ, φ);
|
|
||||||
resampleLineTo(x0, y0, λ0, a0, b0, c0,
|
|
||||||
x0 = p[0], y0 = p[1], λ0 = λ, a0 = cartesian[0], b0 = cartesian[1], c0 = cartesian[2],
|
|
||||||
maxDepth, listener);
|
|
||||||
listener.point(x0, y0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return resample;
|
return resample;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, stream) {
|
||||||
|
var dx = x1 - x0,
|
||||||
|
dy = y1 - y0,
|
||||||
|
d2 = dx * dx + dy * dy;
|
||||||
|
if (d2 > 4 * δ2 && depth--) {
|
||||||
|
var a = a0 + a1,
|
||||||
|
b = b0 + b1,
|
||||||
|
c = c0 + c1,
|
||||||
|
m = Math.sqrt(a * a + b * b + c * c),
|
||||||
|
φ2 = Math.asin(c /= m),
|
||||||
|
λ2 = Math.abs(Math.abs(c) - 1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a),
|
||||||
|
p = project(λ2, φ2),
|
||||||
|
x2 = p[0],
|
||||||
|
y2 = p[1],
|
||||||
|
dx2 = x2 - x0,
|
||||||
|
dy2 = y2 - y0,
|
||||||
|
dz = dy * dx2 - dx * dy2;
|
||||||
|
if (dz * dz / d2 > δ2 || Math.abs((dx * dx2 + dy * dy2) / d2 - .5) > .3) {
|
||||||
|
resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream);
|
||||||
|
stream.point(x2, y2);
|
||||||
|
resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
resample.precision = function(_) {
|
resample.precision = function(_) {
|
||||||
if (!arguments.length) return Math.sqrt(δ2);
|
if (!arguments.length) return Math.sqrt(δ2);
|
||||||
maxDepth = (δ2 = _ * _) > 0 && 16;
|
maxDepth = (δ2 = _ * _) > 0 && 16;
|
||||||
|
@ -79,30 +87,4 @@ function d3_geo_resample(projectPoint) {
|
||||||
};
|
};
|
||||||
|
|
||||||
return resample;
|
return resample;
|
||||||
|
|
||||||
// TODO rename: this is not just resampling, it also projects and transforms!
|
|
||||||
function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, listener) {
|
|
||||||
var dx = x1 - x0,
|
|
||||||
dy = y1 - y0,
|
|
||||||
distance2 = dx * dx + dy * dy;
|
|
||||||
if (distance2 > 4 * δ2 && depth--) {
|
|
||||||
var a = a0 + a1,
|
|
||||||
b = b0 + b1,
|
|
||||||
c = c0 + c1,
|
|
||||||
m = Math.sqrt(a * a + b * b + c * c),
|
|
||||||
φ2 = Math.asin(c /= m),
|
|
||||||
λ2 = Math.abs(Math.abs(c) - 1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a),
|
|
||||||
p = projectPoint(λ2, φ2),
|
|
||||||
x2 = p[0],
|
|
||||||
y2 = p[1],
|
|
||||||
dx2 = x2 - x0,
|
|
||||||
dy2 = y2 - y0,
|
|
||||||
dz = dy * dx2 - dx * dy2;
|
|
||||||
if (dz * dz / distance2 > δ2 || Math.abs((dx * dx2 + dy * dy2) / distance2 - .5) > .3) {
|
|
||||||
resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, listener);
|
|
||||||
listener.point(x2, y2);
|
|
||||||
resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче