Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 

84 строки
2.8 KiB

  1. import {geoProjectionMutator as projectionMutator} from "d3-geo";
  2. import {abs, atan2, cos, degrees, epsilon, radians, sin, tan} from "./math.js";
  3. export function armadilloRaw(phi0) {
  4. var sinPhi0 = sin(phi0),
  5. cosPhi0 = cos(phi0),
  6. sPhi0 = phi0 >= 0 ? 1 : -1,
  7. tanPhi0 = tan(sPhi0 * phi0),
  8. k = (1 + sinPhi0 - cosPhi0) / 2;
  9. function forward(lambda, phi) {
  10. var cosPhi = cos(phi),
  11. cosLambda = cos(lambda /= 2);
  12. return [
  13. (1 + cosPhi) * sin(lambda),
  14. (sPhi0 * phi > -atan2(cosLambda, tanPhi0) - 1e-3 ? 0 : -sPhi0 * 10) + k + sin(phi) * cosPhi0 - (1 + cosPhi) * sinPhi0 * cosLambda // TODO D3 core should allow null or [NaN, NaN] to be returned.
  15. ];
  16. }
  17. forward.invert = function(x, y) {
  18. var lambda = 0,
  19. phi = 0,
  20. i = 50;
  21. do {
  22. var cosLambda = cos(lambda),
  23. sinLambda = sin(lambda),
  24. cosPhi = cos(phi),
  25. sinPhi = sin(phi),
  26. A = 1 + cosPhi,
  27. fx = A * sinLambda - x,
  28. fy = k + sinPhi * cosPhi0 - A * sinPhi0 * cosLambda - y,
  29. dxdLambda = A * cosLambda / 2,
  30. dxdPhi = -sinLambda * sinPhi,
  31. dydLambda = sinPhi0 * A * sinLambda / 2,
  32. dydPhi = cosPhi0 * cosPhi + sinPhi0 * cosLambda * sinPhi,
  33. denominator = dxdPhi * dydLambda - dydPhi * dxdLambda,
  34. dLambda = (fy * dxdPhi - fx * dydPhi) / denominator / 2,
  35. dPhi = (fx * dydLambda - fy * dxdLambda) / denominator;
  36. if (abs(dPhi) > 2) dPhi /= 2;
  37. lambda -= dLambda, phi -= dPhi;
  38. } while ((abs(dLambda) > epsilon || abs(dPhi) > epsilon) && --i > 0);
  39. return sPhi0 * phi > -atan2(cos(lambda), tanPhi0) - 1e-3 ? [lambda * 2, phi] : null;
  40. };
  41. return forward;
  42. }
  43. export default function() {
  44. var phi0 = 20 * radians,
  45. sPhi0 = phi0 >= 0 ? 1 : -1,
  46. tanPhi0 = tan(sPhi0 * phi0),
  47. m = projectionMutator(armadilloRaw),
  48. p = m(phi0),
  49. stream_ = p.stream;
  50. p.parallel = function(_) {
  51. if (!arguments.length) return phi0 * degrees;
  52. tanPhi0 = tan((sPhi0 = (phi0 = _ * radians) >= 0 ? 1 : -1) * phi0);
  53. return m(phi0);
  54. };
  55. p.stream = function(stream) {
  56. var rotate = p.rotate(),
  57. rotateStream = stream_(stream),
  58. sphereStream = (p.rotate([0, 0]), stream_(stream)),
  59. precision = p.precision();
  60. p.rotate(rotate);
  61. rotateStream.sphere = function() {
  62. sphereStream.polygonStart(), sphereStream.lineStart();
  63. for (var lambda = sPhi0 * -180; sPhi0 * lambda < 180; lambda += sPhi0 * 90)
  64. sphereStream.point(lambda, sPhi0 * 90);
  65. if (phi0) while (sPhi0 * (lambda -= 3 * sPhi0 * precision) >= -180) {
  66. sphereStream.point(lambda, sPhi0 * -atan2(cos(lambda * radians / 2), tanPhi0) * degrees);
  67. }
  68. sphereStream.lineEnd(), sphereStream.polygonEnd();
  69. };
  70. return rotateStream;
  71. };
  72. return p
  73. .scale(218.695)
  74. .center([0, 28.0974]);
  75. }