mapshaper 0.7.41 → 0.7.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/www/modules.js CHANGED
@@ -27172,7 +27172,8 @@
27172
27172
  MAXROUND = 20,
27173
27173
  EPSILON = 1e-12,
27174
27174
  round = 0,
27175
- iter, D, C, f1, f2, f1p, f1l, f2p, f2l, dp, dl, sl, sp, cp, cl, x, y;
27175
+ iter, D, C, denom, determinant, f1, f2, f1p, f1l, f2p, f2l, dp, dl,
27176
+ sl, sp, cp, cl, x, y;
27176
27177
 
27177
27178
  if ((fabs(xy.x) < EPSILON) && (fabs(xy.y) < EPSILON )) {
27178
27179
  lp.phi = 0;
@@ -27189,7 +27190,12 @@
27189
27190
  sp = sin(lp.phi); cp = cos(lp.phi);
27190
27191
  D = cp * cl;
27191
27192
  C = 1 - D * D;
27192
- D = acos(D) / pow(C, 1.5);
27193
+ denom = pow(C, 1.5);
27194
+ if (denom === 0) {
27195
+ i_error();
27196
+ return;
27197
+ }
27198
+ D = acos(D) / denom;
27193
27199
  f1 = 2 * D * C * cp * sl;
27194
27200
  f2 = D * C * sp;
27195
27201
  f1p = 2 * (sl * cl * sp * cp / C - D * sp * sl);
@@ -27205,10 +27211,14 @@
27205
27211
  f2l *= 0.5;
27206
27212
  }
27207
27213
  f1 -= xy.x; f2 -= xy.y;
27208
- dl = (f2 * f1p - f1 * f2p) / (dp = f1p * f2l - f2p * f1l);
27209
- dp = (f1 * f2l - f2 * f1l) / dp;
27210
- while (dl > M_PI) dl -= M_PI; /* set to interval [-M_PI, M_PI] */
27211
- while (dl < -M_PI) dl += M_PI; /* set to interval [-M_PI, M_PI] */
27214
+ determinant = f1p * f2l - f2p * f1l;
27215
+ if (determinant === 0) {
27216
+ i_error();
27217
+ return;
27218
+ }
27219
+ dl = (f2 * f1p - f1 * f2p) / determinant;
27220
+ dp = (f1 * f2l - f2 * f1l) / determinant;
27221
+ dl %= M_PI; /* set to interval [-M_PI, M_PI] */
27212
27222
  lp.phi -= dp; lp.lam -= dl;
27213
27223
  } while ((fabs(dp) > EPSILON || fabs(dl) > EPSILON) && (iter++ < MAXITER));
27214
27224
  if (lp.phi > M_HALFPI) lp.phi -= 2*(lp.phi-M_HALFPI); /* correct if symmetrical solution for Aitoff */
@@ -28105,19 +28115,25 @@
28105
28115
  function s_inv(xy, lp) {
28106
28116
  var EPS = 1e-9,
28107
28117
  NITER = 12,
28108
- paramLat = xy.y,
28118
+ MAX_Y = 1.3173627591574,
28119
+ y = Math.max(-MAX_Y, Math.min(MAX_Y, xy.y)),
28120
+ paramLat = y,
28109
28121
  paramLatSq, paramLatPow6, fy, fpy, dlat, i;
28110
28122
 
28111
28123
  for (i = 0; i < NITER; ++i) {
28112
28124
  paramLatSq = paramLat * paramLat;
28113
28125
  paramLatPow6 = paramLatSq * paramLatSq * paramLatSq;
28114
- fy = paramLat * (A1 + A2 * paramLatSq + paramLatPow6 * (A3 + A4 * paramLatSq)) - xy.y;
28126
+ fy = paramLat * (A1 + A2 * paramLatSq + paramLatPow6 * (A3 + A4 * paramLatSq)) - y;
28115
28127
  fpy = A1 + 3 * A2 * paramLatSq + paramLatPow6 * (7 * A3 + 9 * A4 * paramLatSq);
28116
28128
  paramLat -= dlat = fy / fpy;
28117
28129
  if (Math.abs(dlat) < EPS) {
28118
28130
  break;
28119
28131
  }
28120
28132
  }
28133
+ if (i === NITER) {
28134
+ i_error();
28135
+ return;
28136
+ }
28121
28137
  paramLatSq = paramLat * paramLat;
28122
28138
  paramLatPow6 = paramLatSq * paramLatSq * paramLatSq;
28123
28139
  lp.lam = M * xy.x * (A1 + 3 * A2 * paramLatSq + paramLatPow6 * (7 * A3 + 9 * A4 * paramLatSq)) /
@@ -29495,12 +29511,236 @@
29495
29511
  }
29496
29512
 
29497
29513
 
29514
+ pj_add(pj_igh, 'igh', 'Interrupted Goode Homolosine', 'PCyl, Sph., no inv.');
29515
+
29516
+ // Forward-only implementation of the standard land-emphasis layout.
29517
+ // Projection regions and source-geometry cutting are separate concerns:
29518
+ // mproj routes points; clients such as Mapshaper must split paths at the
29519
+ // interruption meridians before projecting them.
29520
+ function pj_igh(P) {
29521
+ var D2R = M_PI / 180,
29522
+ PHI_LIM = (40 + 44 / 60 + 11.8 / 3600) * D2R,
29523
+ LON_NORTH = -40 * D2R,
29524
+ LON_SOUTH_1 = -100 * D2R,
29525
+ LON_SOUTH_2 = -20 * D2R,
29526
+ LON_SOUTH_3 = 80 * D2R,
29527
+ sinuFwd, mollFwd, yCor;
29528
+
29529
+ P.es = 0;
29530
+ pj_sinu(P);
29531
+ sinuFwd = P.fwd;
29532
+ pj_moll(P);
29533
+ mollFwd = P.fwd;
29534
+ yCor = getYCorr();
29535
+ P.inv = null;
29536
+
29537
+ P.fwd = function(lp, xy) {
29538
+ var phi = lp.phi,
29539
+ lon0 = getLobeCenter(lp),
29540
+ useMoll = fabs(phi) >= PHI_LIM;
29541
+ lp.lam -= lon0;
29542
+ if (useMoll) {
29543
+ mollFwd(lp, xy);
29544
+ xy.y -= phi > 0 ? yCor : -yCor;
29545
+ } else {
29546
+ sinuFwd(lp, xy);
29547
+ }
29548
+ xy.x += lon0;
29549
+ };
29550
+
29551
+ function getLobeCenter(lp) {
29552
+ if (lp.phi >= 0) {
29553
+ return lp.lam <= LON_NORTH ? -100 * D2R : 30 * D2R;
29554
+ }
29555
+ if (lp.lam <= LON_SOUTH_1) return -160 * D2R;
29556
+ if (lp.lam <= LON_SOUTH_2) return -60 * D2R;
29557
+ if (lp.lam <= LON_SOUTH_3) return 20 * D2R;
29558
+ return 140 * D2R;
29559
+ }
29560
+
29561
+ function getYCorr() {
29562
+ var lp = {lam: 0, phi: PHI_LIM},
29563
+ sinuXY = {},
29564
+ mollXY = {};
29565
+ sinuFwd({lam: lp.lam, phi: lp.phi}, sinuXY);
29566
+ mollFwd({lam: lp.lam, phi: lp.phi}, mollXY);
29567
+ return mollXY.y - sinuXY.y;
29568
+ }
29569
+ }
29570
+
29571
+
29572
+ pj_add(pj_igh_o, 'igh_o', 'Interrupted Goode Homolosine Oceanic View', 'PCyl, Sph., no inv.');
29573
+
29574
+ function pj_igh_o(P) {
29575
+ var D2R = M_PI / 180,
29576
+ PHI_LIM = (40 + 44 / 60 + 11.8 / 3600) * D2R,
29577
+ NORTH_WEST = -90 * D2R,
29578
+ NORTH_EAST = 60 * D2R,
29579
+ SOUTH_WEST = -60 * D2R,
29580
+ SOUTH_EAST = 90 * D2R,
29581
+ sinuFwd, mollFwd, yCor;
29582
+
29583
+ P.es = 0;
29584
+ pj_sinu(P);
29585
+ sinuFwd = P.fwd;
29586
+ pj_moll(P);
29587
+ mollFwd = P.fwd;
29588
+ yCor = getYCorr();
29589
+ P.inv = null;
29590
+
29591
+ P.fwd = function(lp, xy) {
29592
+ var phi = lp.phi,
29593
+ lon0 = getLobeCenter(lp),
29594
+ useMoll = fabs(phi) >= PHI_LIM;
29595
+ lp.lam -= lon0;
29596
+ if (useMoll) {
29597
+ mollFwd(lp, xy);
29598
+ xy.y -= phi > 0 ? yCor : -yCor;
29599
+ } else {
29600
+ sinuFwd(lp, xy);
29601
+ }
29602
+ xy.x += lon0;
29603
+ };
29604
+
29605
+ function getLobeCenter(lp) {
29606
+ if (lp.phi >= 0) {
29607
+ if (lp.lam <= NORTH_WEST) return -140 * D2R;
29608
+ if (lp.lam >= NORTH_EAST) return 130 * D2R;
29609
+ return -10 * D2R;
29610
+ }
29611
+ if (lp.lam <= SOUTH_WEST) return -110 * D2R;
29612
+ if (lp.lam >= SOUTH_EAST) return 150 * D2R;
29613
+ return 20 * D2R;
29614
+ }
29615
+
29616
+ function getYCorr() {
29617
+ var sinuXY = {},
29618
+ mollXY = {};
29619
+ sinuFwd({lam: 0, phi: PHI_LIM}, sinuXY);
29620
+ mollFwd({lam: 0, phi: PHI_LIM}, mollXY);
29621
+ return mollXY.y - sinuXY.y;
29622
+ }
29623
+ }
29624
+
29625
+
29626
+ pj_add(pj_imoll, 'imoll', 'Interrupted Mollweide', 'PCyl, Sph., no inv.');
29627
+
29628
+ function pj_imoll(P) {
29629
+ var D2R = M_PI / 180,
29630
+ EPS = 1e-10,
29631
+ centers = [-100, 30, -160, -60, 20, 140].map(toRadians),
29632
+ offsets = centers.concat(),
29633
+ mollFwd;
29634
+
29635
+ P.es = 0;
29636
+ pj_moll(P);
29637
+ mollFwd = P.fwd;
29638
+ adjustOffsets();
29639
+ P.inv = null;
29640
+
29641
+ P.fwd = function(lp, xy) {
29642
+ var zone = getZone(lp);
29643
+ projectZone(zone, lp.lam, lp.phi, xy);
29644
+ };
29645
+
29646
+ function getZone(lp) {
29647
+ if (lp.phi >= 0) return lp.lam <= -40 * D2R ? 0 : 1;
29648
+ if (lp.lam <= -100 * D2R) return 2;
29649
+ if (lp.lam <= -20 * D2R) return 3;
29650
+ if (lp.lam <= 80 * D2R) return 4;
29651
+ return 5;
29652
+ }
29653
+
29654
+ function projectZone(zone, lam, phi, xy) {
29655
+ mollFwd({lam: lam - centers[zone], phi: phi}, xy);
29656
+ xy.x += offsets[zone];
29657
+ }
29658
+
29659
+ function getZoneOffset(zone1, zone2, lam, phi1, phi2) {
29660
+ var xy1 = {}, xy2 = {};
29661
+ projectZone(zone1, lam, phi1, xy1);
29662
+ projectZone(zone2, lam, phi2, xy2);
29663
+ return xy2.x - xy1.x;
29664
+ }
29665
+
29666
+ function adjustOffsets() {
29667
+ offsets[2] += getZoneOffset(2, 0, -160 * D2R, -EPS, EPS);
29668
+ offsets[1] += getZoneOffset(1, 0, -40 * D2R, EPS, EPS);
29669
+ offsets[3] += getZoneOffset(3, 0, -100 * D2R, -EPS, EPS);
29670
+ offsets[4] += getZoneOffset(4, 1, -20 * D2R, -EPS, EPS);
29671
+ offsets[5] += getZoneOffset(5, 1, 80 * D2R, -EPS, EPS);
29672
+ }
29673
+
29674
+ function toRadians(degrees) {
29675
+ return degrees * D2R;
29676
+ }
29677
+ }
29678
+
29679
+
29680
+ pj_add(pj_imoll_o, 'imoll_o', 'Interrupted Mollweide Oceanic View', 'PCyl, Sph., no inv.');
29681
+
29682
+ function pj_imoll_o(P) {
29683
+ var D2R = M_PI / 180,
29684
+ EPS = 1e-10,
29685
+ centers = [-140, -10, 130, -110, 20, 150].map(toRadians),
29686
+ offsets = centers.concat(),
29687
+ mollFwd;
29688
+
29689
+ P.es = 0;
29690
+ pj_moll(P);
29691
+ mollFwd = P.fwd;
29692
+ adjustOffsets();
29693
+ P.inv = null;
29694
+
29695
+ P.fwd = function(lp, xy) {
29696
+ var zone = getZone(lp);
29697
+ projectZone(zone, lp.lam, lp.phi, xy);
29698
+ };
29699
+
29700
+ function getZone(lp) {
29701
+ if (lp.phi >= 0) {
29702
+ if (lp.lam <= -90 * D2R) return 0;
29703
+ if (lp.lam >= 60 * D2R) return 2;
29704
+ return 1;
29705
+ }
29706
+ if (lp.lam <= -60 * D2R) return 3;
29707
+ if (lp.lam >= 90 * D2R) return 5;
29708
+ return 4;
29709
+ }
29710
+
29711
+ function projectZone(zone, lam, phi, xy) {
29712
+ mollFwd({lam: lam - centers[zone], phi: phi}, xy);
29713
+ xy.x += offsets[zone];
29714
+ }
29715
+
29716
+ function getZoneOffset(zone1, zone2, lam, phi1, phi2) {
29717
+ var xy1 = {}, xy2 = {};
29718
+ projectZone(zone1, lam, phi1, xy1);
29719
+ projectZone(zone2, lam, phi2, xy2);
29720
+ return xy2.x - xy1.x;
29721
+ }
29722
+
29723
+ function adjustOffsets() {
29724
+ offsets[1] += getZoneOffset(1, 0, -90 * D2R, EPS, EPS);
29725
+ offsets[2] += getZoneOffset(2, 1, 60 * D2R, EPS, EPS);
29726
+ offsets[3] += getZoneOffset(3, 0, -180 * D2R, -EPS, EPS);
29727
+ offsets[4] += getZoneOffset(4, 1, -60 * D2R, -EPS, EPS);
29728
+ offsets[5] += getZoneOffset(5, 2, 90 * D2R, -EPS, EPS);
29729
+ }
29730
+
29731
+ function toRadians(degrees) {
29732
+ return degrees * D2R;
29733
+ }
29734
+ }
29735
+
29736
+
29498
29737
  pj_add(pj_krovak, 'krovak', 'Krovak', 'PCyl., Ellps.');
29499
29738
 
29500
29739
  function pj_krovak(P) {
29501
29740
  var u0, n0, g;
29502
29741
  var alpha, k, n, rho0, ad, czech;
29503
29742
  var EPS = 1e-15;
29743
+ var MAX_ITER = 100;
29504
29744
  var S45 = 0.785398163397448; /* 45 deg */
29505
29745
  var S90 = 1.570796326794896; /* 90 deg */
29506
29746
  var UQ = 1.04216856380474; /* DU(2, 59, 42, 42.69689) */
@@ -29559,7 +29799,7 @@
29559
29799
 
29560
29800
  function e_inv(xy, lp) {
29561
29801
  var u, deltav, s, d, eps, rho, fi1, xy0;
29562
- var ok;
29802
+ var i;
29563
29803
  xy0 = xy.x;
29564
29804
  xy.x = xy.y;
29565
29805
  xy.y = xy0;
@@ -29569,21 +29809,28 @@
29569
29809
  rho = sqrt(xy.x * xy.x + xy.y * xy.y);
29570
29810
  eps = atan2(xy.y, xy.x);
29571
29811
  d = eps / sin(S0);
29572
- s = 2 * (atan( pow(rho0 / rho, 1 / n) * tan(S0 / 2 + S45)) - S45);
29812
+ if (rho === 0) {
29813
+ s = M_HALFPI;
29814
+ } else {
29815
+ s = 2 * (atan(pow(rho0 / rho, 1 / n) * tan(S0 / 2 + S45)) - S45);
29816
+ }
29573
29817
  u = asin(cos(ad) * sin(s) - sin(ad) * cos(s) * cos(d));
29574
29818
  deltav = asin(cos(s) * sin(d) / cos(u));
29575
29819
  lp.lam = P.lam0 - deltav / alpha;
29576
29820
 
29577
29821
  /* ITERATION FOR lp.phi */
29578
29822
  fi1 = u;
29579
- ok = 0;
29580
- do {
29823
+ for (i = MAX_ITER; i; --i) {
29581
29824
  lp.phi = 2 * (atan(pow( k, -1 / alpha) * pow( tan(u / 2 + S45), 1 / alpha) *
29582
29825
  pow( (1 + P.e * sin(fi1)) / (1 - P.e * sin(fi1)) , P.e / 2)) - S45);
29583
- if (fabs(fi1 - lp.phi) < EPS) ok=1;
29826
+ if (fabs(fi1 - lp.phi) < EPS) break;
29584
29827
  fi1 = lp.phi;
29585
- } while (ok===0);
29586
- lp.lam -= P.lam0;
29828
+ }
29829
+ if (!i) {
29830
+ i_error();
29831
+ return;
29832
+ }
29833
+ lp.lam -= P.lam0;
29587
29834
  }
29588
29835
  }
29589
29836
 
@@ -30499,6 +30746,7 @@
30499
30746
  C3 = (9 * B3),
30500
30747
  C4 = (11 * B4),
30501
30748
  EPS = 1e-11,
30749
+ MAX_ITER = 100,
30502
30750
  MAX_Y = (0.8707 * 0.52 * M_PI);
30503
30751
 
30504
30752
  P.es = 0;
@@ -30515,7 +30763,7 @@
30515
30763
 
30516
30764
  function s_inv(xy, lp) {
30517
30765
  var x = xy.x, y = xy.y;
30518
- var yc, tol, y2, y4, f, fder;
30766
+ var yc, tol, y2, y4, f, fder, i;
30519
30767
  if (y > MAX_Y) {
30520
30768
  y = MAX_Y;
30521
30769
  } else if (y < -MAX_Y) {
@@ -30523,7 +30771,7 @@
30523
30771
  }
30524
30772
 
30525
30773
  yc = y;
30526
- for (;;) { /* Newton-Raphson */
30774
+ for (i = MAX_ITER; i; --i) { /* Newton-Raphson */
30527
30775
  y2 = yc * yc;
30528
30776
  y4 = y2 * y2;
30529
30777
  f = (yc * (B0 + y2 * (B1 + y4 * (B2 + B3 * y2 + B4 * y4)))) - y;
@@ -30533,6 +30781,10 @@
30533
30781
  break;
30534
30782
  }
30535
30783
  }
30784
+ if (!i) {
30785
+ i_error();
30786
+ return;
30787
+ }
30536
30788
  lp.phi = yc;
30537
30789
  y2 = yc * yc;
30538
30790
  lp.lam = x / (A0 + y2 * (A1 + y2 * (A2 + y2 * y2 * y2 * (A3 + y2 * A4))));
@@ -30555,6 +30807,7 @@
30555
30807
  C2 = (11 * B2),
30556
30808
  C3 = (13 * B3),
30557
30809
  EPS = 1e-11,
30810
+ MAX_ITER = 100,
30558
30811
  MAX_Y = (0.84719 * 0.535117535153096 * M_PI);
30559
30812
 
30560
30813
  P.es = 0;
@@ -30572,14 +30825,14 @@
30572
30825
 
30573
30826
  function s_inv(xy, lp) {
30574
30827
  var x = xy.x, y = xy.y;
30575
- var yc, tol, y2, y4, y6, f, fder;
30828
+ var yc, tol, y2, y4, y6, f, fder, i;
30576
30829
  if (y > MAX_Y) {
30577
30830
  y = MAX_Y;
30578
30831
  } else if (y < -MAX_Y) {
30579
30832
  y = -MAX_Y;
30580
30833
  }
30581
30834
  yc = y;
30582
- for (;;) { /* Newton-Raphson */
30835
+ for (i = MAX_ITER; i; --i) { /* Newton-Raphson */
30583
30836
  y2 = yc * yc;
30584
30837
  y4 = y2 * y2;
30585
30838
  f = (yc * (B0 + y4 * y4 * (B1 + B2 * y2 + B3 * y4))) - y;
@@ -30589,6 +30842,10 @@
30589
30842
  break;
30590
30843
  }
30591
30844
  }
30845
+ if (!i) {
30846
+ i_error();
30847
+ return;
30848
+ }
30592
30849
  lp.phi = yc;
30593
30850
  y2 = yc * yc;
30594
30851
  y4 = y2 * y2;
@@ -32088,7 +32345,9 @@
32088
32345
  RC1 = 0.08726646259971647884,
32089
32346
  NODES = 18,
32090
32347
  ONEEPS = 1.000001,
32091
- EPS = 1e-8;
32348
+ EPS = 1e-10,
32349
+ LAM_EPS = 1e-8,
32350
+ MAX_ITER = 100;
32092
32351
 
32093
32352
  P.es = 0;
32094
32353
  P.fwd = s_fwd;
@@ -32096,9 +32355,9 @@
32096
32355
 
32097
32356
  function s_fwd(lp, xy) {
32098
32357
  var i, dphi;
32099
- i = floor((dphi = fabs(lp.phi)) * C1);
32358
+ i = floor((dphi = fabs(lp.phi)) * C1 + 1e-15);
32100
32359
  if (i < 0) f_error();
32101
- if (i >= NODES) i = NODES - 1;
32360
+ if (i >= NODES) i = NODES;
32102
32361
  dphi = RAD_TO_DEG * (dphi - RC1 * i);
32103
32362
  xy.x = V(X[i], dphi) * FXC * lp.lam;
32104
32363
  xy.y = V(Y[i], dphi) * FYC;
@@ -32106,7 +32365,7 @@
32106
32365
  }
32107
32366
 
32108
32367
  function s_inv(xy, lp) {
32109
- var t, t1, T, i;
32368
+ var t, t1, T, i, iterations;
32110
32369
  lp.lam = xy.x / FXC;
32111
32370
  lp.phi = fabs(xy.y / FYC);
32112
32371
  if (lp.phi >= 1) { /* simple pathologic cases */
@@ -32131,13 +32390,24 @@
32131
32390
  t = 5 * (lp.phi - T[0])/(Y[i+1][0] - T[0]);
32132
32391
  /* make into root */
32133
32392
  T[0] -= lp.phi;
32134
- for (;;) { /* Newton-Raphson reduction */
32393
+ for (iterations = MAX_ITER; iterations; --iterations) { /* Newton-Raphson reduction */
32135
32394
  t -= t1 = V(T,t) / DV(T,t);
32136
32395
  if (fabs(t1) < EPS) break;
32137
32396
  }
32397
+ if (!iterations) {
32398
+ i_error();
32399
+ return;
32400
+ }
32138
32401
  lp.phi = (5 * i + t) * DEG_TO_RAD;
32139
32402
  if (xy.y < 0) lp.phi = -lp.phi;
32140
32403
  lp.lam /= V(X[i], t);
32404
+ if (fabs(lp.lam) > M_PI) {
32405
+ if (fabs(lp.lam) <= M_PI + LAM_EPS) {
32406
+ lp.lam = lp.lam < 0 ? -M_PI : M_PI;
32407
+ } else {
32408
+ i_error();
32409
+ }
32410
+ }
32141
32411
  }
32142
32412
  }
32143
32413