Download node_modules/d3-geo/src/bounds.js from NKessler/Horizon: direct link, hf CLI and curl.
- Browser
- Download file 5.55 kB
-
https://huggingface.co/NKessler/Horizon/resolve/main/node_modules/d3-geo/src/bounds.js
- Command line
-
hf download hf://NKessler/Horizon/node_modules/d3-geo/src/bounds.js
-
curl -L -o bounds.js https://huggingface.co/NKessler/Horizon/resolve/main/node_modules/d3-geo/src/bounds.js
5.55 kB
| import {Adder} from "d3-array"; | |
| import {areaStream, areaRingSum} from "./area.js"; | |
| import {cartesian, cartesianCross, cartesianNormalizeInPlace, spherical} from "./cartesian.js"; | |
| import {abs, degrees, epsilon, radians} from "./math.js"; | |
| import stream from "./stream.js"; | |
| var lambda0, phi0, lambda1, phi1, // bounds | |
| lambda2, // previous lambda-coordinate | |
| lambda00, phi00, // first point | |
| p0, // previous 3D point | |
| deltaSum, | |
| ranges, | |
| range; | |
| var boundsStream = { | |
| point: boundsPoint, | |
| lineStart: boundsLineStart, | |
| lineEnd: boundsLineEnd, | |
| polygonStart: function() { | |
| boundsStream.point = boundsRingPoint; | |
| boundsStream.lineStart = boundsRingStart; | |
| boundsStream.lineEnd = boundsRingEnd; | |
| deltaSum = new Adder(); | |
| areaStream.polygonStart(); | |
| }, | |
| polygonEnd: function() { | |
| areaStream.polygonEnd(); | |
| boundsStream.point = boundsPoint; | |
| boundsStream.lineStart = boundsLineStart; | |
| boundsStream.lineEnd = boundsLineEnd; | |
| if (areaRingSum < 0) lambda0 = -(lambda1 = 180), phi0 = -(phi1 = 90); | |
| else if (deltaSum > epsilon) phi1 = 90; | |
| else if (deltaSum < -epsilon) phi0 = -90; | |
| range[0] = lambda0, range[1] = lambda1; | |
| }, | |
| sphere: function() { | |
| lambda0 = -(lambda1 = 180), phi0 = -(phi1 = 90); | |
| } | |
| }; | |
| function boundsPoint(lambda, phi) { | |
| ranges.push(range = [lambda0 = lambda, lambda1 = lambda]); | |
| if (phi < phi0) phi0 = phi; | |
| if (phi > phi1) phi1 = phi; | |
| } | |
| function linePoint(lambda, phi) { | |
| var p = cartesian([lambda * radians, phi * radians]); | |
| if (p0) { | |
| var normal = cartesianCross(p0, p), | |
| equatorial = [normal[1], -normal[0], 0], | |
| inflection = cartesianCross(equatorial, normal); | |
| cartesianNormalizeInPlace(inflection); | |
| inflection = spherical(inflection); | |
| var delta = lambda - lambda2, | |
| sign = delta > 0 ? 1 : -1, | |
| lambdai = inflection[0] * degrees * sign, | |
| phii, | |
| antimeridian = abs(delta) > 180; | |
| if (antimeridian ^ (sign * lambda2 < lambdai && lambdai < sign * lambda)) { | |
| phii = inflection[1] * degrees; | |
| if (phii > phi1) phi1 = phii; | |
| } else if (lambdai = (lambdai + 360) % 360 - 180, antimeridian ^ (sign * lambda2 < lambdai && lambdai < sign * lambda)) { | |
| phii = -inflection[1] * degrees; | |
| if (phii < phi0) phi0 = phii; | |
| } else { | |
| if (phi < phi0) phi0 = phi; | |
| if (phi > phi1) phi1 = phi; | |
| } | |
| if (antimeridian) { | |
| if (lambda < lambda2) { | |
| if (angle(lambda0, lambda) > angle(lambda0, lambda1)) lambda1 = lambda; | |
| } else { | |
| if (angle(lambda, lambda1) > angle(lambda0, lambda1)) lambda0 = lambda; | |
| } | |
| } else { | |
| if (lambda1 >= lambda0) { | |
| if (lambda < lambda0) lambda0 = lambda; | |
| if (lambda > lambda1) lambda1 = lambda; | |
| } else { | |
| if (lambda > lambda2) { | |
| if (angle(lambda0, lambda) > angle(lambda0, lambda1)) lambda1 = lambda; | |
| } else { | |
| if (angle(lambda, lambda1) > angle(lambda0, lambda1)) lambda0 = lambda; | |
| } | |
| } | |
| } | |
| } else { | |
| ranges.push(range = [lambda0 = lambda, lambda1 = lambda]); | |
| } | |
| if (phi < phi0) phi0 = phi; | |
| if (phi > phi1) phi1 = phi; | |
| p0 = p, lambda2 = lambda; | |
| } | |
| function boundsLineStart() { | |
| boundsStream.point = linePoint; | |
| } | |
| function boundsLineEnd() { | |
| range[0] = lambda0, range[1] = lambda1; | |
| boundsStream.point = boundsPoint; | |
| p0 = null; | |
| } | |
| function boundsRingPoint(lambda, phi) { | |
| if (p0) { | |
| var delta = lambda - lambda2; | |
| deltaSum.add(abs(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delta); | |
| } else { | |
| lambda00 = lambda, phi00 = phi; | |
| } | |
| areaStream.point(lambda, phi); | |
| linePoint(lambda, phi); | |
| } | |
| function boundsRingStart() { | |
| areaStream.lineStart(); | |
| } | |
| function boundsRingEnd() { | |
| boundsRingPoint(lambda00, phi00); | |
| areaStream.lineEnd(); | |
| if (abs(deltaSum) > epsilon) lambda0 = -(lambda1 = 180); | |
| range[0] = lambda0, range[1] = lambda1; | |
| p0 = null; | |
| } | |
| // Finds the left-right distance between two longitudes. | |
| // This is almost the same as (lambda1 - lambda0 + 360°) % 360°, except that we want | |
| // the distance between ±180° to be 360°. | |
| function angle(lambda0, lambda1) { | |
| return (lambda1 -= lambda0) < 0 ? lambda1 + 360 : lambda1; | |
| } | |
| function rangeCompare(a, b) { | |
| return a[0] - b[0]; | |
| } | |
| function rangeContains(range, x) { | |
| return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x; | |
| } | |
| export default function(feature) { | |
| var i, n, a, b, merged, deltaMax, delta; | |
| phi1 = lambda1 = -(lambda0 = phi0 = Infinity); | |
| ranges = []; | |
| stream(feature, boundsStream); | |
| // First, sort ranges by their minimum longitudes. | |
| if (n = ranges.length) { | |
| ranges.sort(rangeCompare); | |
| // Then, merge any ranges that overlap. | |
| for (i = 1, a = ranges[0], merged = [a]; i < n; ++i) { | |
| b = ranges[i]; | |
| if (rangeContains(a, b[0]) || rangeContains(a, b[1])) { | |
| if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1]; | |
| if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0]; | |
| } else { | |
| merged.push(a = b); | |
| } | |
| } | |
| // Finally, find the largest gap between the merged ranges. | |
| // The final bounding box will be the inverse of this gap. | |
| for (deltaMax = -Infinity, n = merged.length - 1, i = 0, a = merged[n]; i <= n; a = b, ++i) { | |
| b = merged[i]; | |
| if ((delta = angle(a[1], b[0])) > deltaMax) deltaMax = delta, lambda0 = b[0], lambda1 = a[1]; | |
| } | |
| } | |
| ranges = range = null; | |
| return lambda0 === Infinity || phi0 === Infinity | |
| ? [[NaN, NaN], [NaN, NaN]] | |
| : [[lambda0, phi0], [lambda1, phi1]]; | |
| } | |