mapshaper 0.6.101 → 0.6.103

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/mapshaper.js CHANGED
@@ -67,6 +67,7 @@
67
67
  get formatIntlNumber () { return formatIntlNumber; },
68
68
  get formatNumberForDisplay () { return formatNumberForDisplay; },
69
69
  get shuffle () { return shuffle; },
70
+ get pickOne () { return pickOne; },
70
71
  get sortOn () { return sortOn; },
71
72
  get genericSort () { return genericSort; },
72
73
  get getSortedIds () { return getSortedIds; },
@@ -133,8 +134,24 @@
133
134
  clearStash: clearStash
134
135
  });
135
136
 
137
+ // Several dependencies are loaded via require()
138
+ var f;
139
+ if (typeof require == 'function') {
140
+ // Node.js context: native require() function
141
+ f = require;
142
+ } else if (typeof window == 'object' && window.modules) {
143
+ // running in web GUI
144
+ f = function(name) {
145
+ return window.modules[name];
146
+ };
147
+ } else {
148
+ // stub to avoid runtime error in a handful of tests
149
+ f = function() {};
150
+ }
151
+ var require$1 = f;
152
+
136
153
  // Fall back to browserify's Buffer polyfill
137
- var B$3 = typeof Buffer != 'undefined' ? Buffer : require('buffer').Buffer;
154
+ var B$3 = typeof Buffer != 'undefined' ? Buffer : require$1('buffer').Buffer;
138
155
 
139
156
  var uniqCount = 0;
140
157
  function getUniqueName(prefix) {
@@ -267,6 +284,7 @@
267
284
  });
268
285
  }
269
286
 
287
+
270
288
  function defaults(dest) {
271
289
  for (var i=1, n=arguments.length; i<n; i++) {
272
290
  var src = arguments[i] || {};
@@ -683,6 +701,10 @@
683
701
  }
684
702
  }
685
703
 
704
+ function pickOne(arr) {
705
+ return arr[Math.floor(Math.random() * arr.length)];
706
+ }
707
+
686
708
  // Sort an array of objects based on one or more properties.
687
709
  // Usage: sortOn(array, key1, asc?[, key2, asc? ...])
688
710
  //
@@ -1755,12 +1777,29 @@
1755
1777
  return count;
1756
1778
  }
1757
1779
 
1780
+ // export function getPointBounds(shapes) {
1781
+ // var bounds = new Bounds();
1782
+ // forEachPoint(shapes, function(p) {
1783
+ // bounds.mergePoint(p[0], p[1]);
1784
+ // });
1785
+ // return bounds;
1786
+ // }
1787
+
1758
1788
  function getPointBounds$1(shapes) {
1759
- var bounds = new Bounds();
1760
- forEachPoint(shapes, function(p) {
1761
- bounds.mergePoint(p[0], p[1]);
1762
- });
1763
- return bounds;
1789
+ new Bounds();
1790
+ var shp, x, y, xmin = Infinity, ymin = Infinity, xmax = -Infinity, ymax = -Infinity;
1791
+ for (var i=0, n=shapes.length; i<n; i++) {
1792
+ shp = shapes[i];
1793
+ for (var j=0, m=shp ? shp.length : 0; j<m; j++) {
1794
+ x = shp[j][0];
1795
+ y = shp[j][1];
1796
+ if (x > xmax) xmax = x;
1797
+ if (x < xmin) xmin = x;
1798
+ if (y > ymax) ymax = y;
1799
+ if (y < ymin) ymin = y;
1800
+ }
1801
+ }
1802
+ return shp ? new Bounds(xmin, ymin, xmax, ymax) : new Bounds();
1764
1803
  }
1765
1804
 
1766
1805
  function getPointFeatureBounds(shape, bounds) {
@@ -3714,20 +3753,6 @@
3714
3753
  findMaxPartCount: findMaxPartCount
3715
3754
  });
3716
3755
 
3717
- // Several dependencies are loaded via require() ... this module returns a
3718
- // stub function when require() does not exist as a global function,
3719
- // to avoid runtime errors (this should only happen in some tests when single
3720
- // modules are imported)
3721
- var f;
3722
- if (typeof require == 'function') {
3723
- f = require;
3724
- } else {
3725
- f = function() {
3726
- // console.error('Unable to load module', name);
3727
- };
3728
- }
3729
- var require$1 = f;
3730
-
3731
3756
  var iconv = require$1('iconv-lite');
3732
3757
 
3733
3758
  // import iconv from 'iconv-lite';
@@ -9614,11 +9639,10 @@
9614
9639
  });
9615
9640
 
9616
9641
  // aliases for shorter compressed code (most minifers don't do this)
9617
- var u8 = Uint8Array, u16 = Uint16Array, u32 = Uint32Array;
9642
+ var u8 = Uint8Array, u16 = Uint16Array, i32 = Int32Array;
9618
9643
  // fixed length extra bits
9619
9644
  var fleb = new u8([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, /* unused */ 0, 0, /* impossible */ 0]);
9620
9645
  // fixed distance extra bits
9621
- // see fleb note
9622
9646
  var fdeb = new u8([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, /* unused */ 0, 0]);
9623
9647
  // code length index map
9624
9648
  var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
@@ -9629,26 +9653,26 @@
9629
9653
  b[i] = start += 1 << eb[i - 1];
9630
9654
  }
9631
9655
  // numbers here are at max 18 bits
9632
- var r = new u32(b[30]);
9656
+ var r = new i32(b[30]);
9633
9657
  for (var i = 1; i < 30; ++i) {
9634
9658
  for (var j = b[i]; j < b[i + 1]; ++j) {
9635
9659
  r[j] = ((j - b[i]) << 5) | i;
9636
9660
  }
9637
9661
  }
9638
- return [b, r];
9662
+ return { b: b, r: r };
9639
9663
  };
9640
- var _a = freb(fleb, 2), fl = _a[0], revfl = _a[1];
9664
+ var _a = freb(fleb, 2), fl = _a.b, revfl = _a.r;
9641
9665
  // we can ignore the fact that the other numbers are wrong; they never happen anyway
9642
9666
  fl[28] = 258, revfl[258] = 28;
9643
- var _b = freb(fdeb, 0), fd = _b[0], revfd = _b[1];
9667
+ var _b = freb(fdeb, 0), fd = _b.b, revfd = _b.r;
9644
9668
  // map of value to reverse (assuming 16 bits)
9645
9669
  var rev = new u16(32768);
9646
9670
  for (var i = 0; i < 32768; ++i) {
9647
9671
  // reverse table algorithm from SO
9648
- var x = ((i & 0xAAAA) >>> 1) | ((i & 0x5555) << 1);
9649
- x = ((x & 0xCCCC) >>> 2) | ((x & 0x3333) << 2);
9650
- x = ((x & 0xF0F0) >>> 4) | ((x & 0x0F0F) << 4);
9651
- rev[i] = (((x & 0xFF00) >>> 8) | ((x & 0x00FF) << 8)) >>> 1;
9672
+ var x = ((i & 0xAAAA) >> 1) | ((i & 0x5555) << 1);
9673
+ x = ((x & 0xCCCC) >> 2) | ((x & 0x3333) << 2);
9674
+ x = ((x & 0xF0F0) >> 4) | ((x & 0x0F0F) << 4);
9675
+ rev[i] = (((x & 0xFF00) >> 8) | ((x & 0x00FF) << 8)) >> 1;
9652
9676
  }
9653
9677
  // create huffman tree from u8 "map": index -> code length for code index
9654
9678
  // mb (max bits) must be at most 15
@@ -9666,7 +9690,7 @@
9666
9690
  }
9667
9691
  // u16 "map": index -> minimum code for bit length = index
9668
9692
  var le = new u16(mb);
9669
- for (i = 0; i < mb; ++i) {
9693
+ for (i = 1; i < mb; ++i) {
9670
9694
  le[i] = (le[i - 1] + l[i - 1]) << 1;
9671
9695
  }
9672
9696
  var co;
@@ -9687,7 +9711,7 @@
9687
9711
  // m is end value
9688
9712
  for (var m = v | ((1 << r_1) - 1); v <= m; ++v) {
9689
9713
  // every 16 bit value starting with the code yields the same result
9690
- co[rev[v] >>> rvb] = sv;
9714
+ co[rev[v] >> rvb] = sv;
9691
9715
  }
9692
9716
  }
9693
9717
  }
@@ -9696,7 +9720,7 @@
9696
9720
  co = new u16(s);
9697
9721
  for (i = 0; i < s; ++i) {
9698
9722
  if (cd[i]) {
9699
- co[i] = rev[le[cd[i] - 1]++] >>> (15 - cd[i]);
9723
+ co[i] = rev[le[cd[i] - 1]++] >> (15 - cd[i]);
9700
9724
  }
9701
9725
  }
9702
9726
  }
@@ -9749,9 +9773,7 @@
9749
9773
  if (e == null || e > v.length)
9750
9774
  e = v.length;
9751
9775
  // can't use .constructor in case user-supplied
9752
- var n = new (v.BYTES_PER_ELEMENT == 2 ? u16 : v.BYTES_PER_ELEMENT == 4 ? u32 : u8)(e - s);
9753
- n.set(v.subarray(s, e));
9754
- return n;
9776
+ return new u8(v.subarray(s, e));
9755
9777
  };
9756
9778
  // error codes
9757
9779
  var ec = [
@@ -9781,19 +9803,18 @@
9781
9803
  return e;
9782
9804
  };
9783
9805
  // expands raw DEFLATE data
9784
- var inflt = function (dat, buf, st) {
9785
- // source length
9786
- var sl = dat.length;
9787
- if (!sl || (st && st.f && !st.l))
9806
+ var inflt = function (dat, st, buf, dict) {
9807
+ // source length dict length
9808
+ var sl = dat.length, dl = dict ? dict.length : 0;
9809
+ if (!sl || st.f && !st.l)
9788
9810
  return buf || new u8(0);
9811
+ var noBuf = !buf;
9789
9812
  // have to estimate size
9790
- var noBuf = !buf || st;
9813
+ var resize = noBuf || st.i != 2;
9791
9814
  // no state
9792
- var noSt = !st || st.i;
9793
- if (!st)
9794
- st = {};
9815
+ var noSt = st.i;
9795
9816
  // Assumes roughly 33% compression ratio average
9796
- if (!buf)
9817
+ if (noBuf)
9797
9818
  buf = new u8(sl * 3);
9798
9819
  // ensure buffer can fit at least l elements
9799
9820
  var cbuf = function (l) {
@@ -9826,7 +9847,7 @@
9826
9847
  break;
9827
9848
  }
9828
9849
  // ensure size
9829
- if (noBuf)
9850
+ if (resize)
9830
9851
  cbuf(bt + l);
9831
9852
  // Copy over uncompressed data
9832
9853
  buf.set(dat.subarray(s, t), bt);
@@ -9859,7 +9880,7 @@
9859
9880
  // bits read
9860
9881
  pos += r & 15;
9861
9882
  // symbol
9862
- var s = r >>> 4;
9883
+ var s = r >> 4;
9863
9884
  // code length to copy
9864
9885
  if (s < 16) {
9865
9886
  ldt[i++] = s;
@@ -9895,14 +9916,14 @@
9895
9916
  }
9896
9917
  }
9897
9918
  // Make sure the buffer can hold this + the largest possible addition
9898
- // Maximum chunk size (practically, theoretically infinite) is 2^17;
9899
- if (noBuf)
9919
+ // Maximum chunk size (practically, theoretically infinite) is 2^17
9920
+ if (resize)
9900
9921
  cbuf(bt + 131072);
9901
9922
  var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;
9902
9923
  var lpos = pos;
9903
9924
  for (;; lpos = pos) {
9904
9925
  // bits read, code
9905
- var c = lm[bits16(dat, pos) & lms], sym = c >>> 4;
9926
+ var c = lm[bits16(dat, pos) & lms], sym = c >> 4;
9906
9927
  pos += c & 15;
9907
9928
  if (pos > tbts) {
9908
9929
  if (noSt)
@@ -9927,52 +9948,55 @@
9927
9948
  pos += b;
9928
9949
  }
9929
9950
  // dist
9930
- var d = dm[bits16(dat, pos) & dms], dsym = d >>> 4;
9951
+ var d = dm[bits16(dat, pos) & dms], dsym = d >> 4;
9931
9952
  if (!d)
9932
9953
  err(3);
9933
9954
  pos += d & 15;
9934
9955
  var dt = fd[dsym];
9935
9956
  if (dsym > 3) {
9936
9957
  var b = fdeb[dsym];
9937
- dt += bits16(dat, pos) & ((1 << b) - 1), pos += b;
9958
+ dt += bits16(dat, pos) & (1 << b) - 1, pos += b;
9938
9959
  }
9939
9960
  if (pos > tbts) {
9940
9961
  if (noSt)
9941
9962
  err(0);
9942
9963
  break;
9943
9964
  }
9944
- if (noBuf)
9965
+ if (resize)
9945
9966
  cbuf(bt + 131072);
9946
9967
  var end = bt + add;
9947
- for (; bt < end; bt += 4) {
9948
- buf[bt] = buf[bt - dt];
9949
- buf[bt + 1] = buf[bt + 1 - dt];
9950
- buf[bt + 2] = buf[bt + 2 - dt];
9951
- buf[bt + 3] = buf[bt + 3 - dt];
9968
+ if (bt < dt) {
9969
+ var shift = dl - dt, dend = Math.min(dt, end);
9970
+ if (shift + bt < 0)
9971
+ err(3);
9972
+ for (; bt < dend; ++bt)
9973
+ buf[bt] = dict[shift + bt];
9952
9974
  }
9953
- bt = end;
9975
+ for (; bt < end; ++bt)
9976
+ buf[bt] = buf[bt - dt];
9954
9977
  }
9955
9978
  }
9956
9979
  st.l = lm, st.p = lpos, st.b = bt, st.f = final;
9957
9980
  if (lm)
9958
9981
  final = 1, st.m = lbt, st.d = dm, st.n = dbt;
9959
9982
  } while (!final);
9960
- return bt == buf.length ? buf : slc(buf, 0, bt);
9983
+ // don't reallocate for streams or user buffers
9984
+ return bt != buf.length && noBuf ? slc(buf, 0, bt) : buf.subarray(0, bt);
9961
9985
  };
9962
9986
  // starting at p, write the minimum number of bits that can hold v to d
9963
9987
  var wbits = function (d, p, v) {
9964
9988
  v <<= p & 7;
9965
9989
  var o = (p / 8) | 0;
9966
9990
  d[o] |= v;
9967
- d[o + 1] |= v >>> 8;
9991
+ d[o + 1] |= v >> 8;
9968
9992
  };
9969
9993
  // starting at p, write the minimum number of bits (>8) that can hold v to d
9970
9994
  var wbits16 = function (d, p, v) {
9971
9995
  v <<= p & 7;
9972
9996
  var o = (p / 8) | 0;
9973
9997
  d[o] |= v;
9974
- d[o + 1] |= v >>> 8;
9975
- d[o + 2] |= v >>> 16;
9998
+ d[o + 1] |= v >> 8;
9999
+ d[o + 2] |= v >> 16;
9976
10000
  };
9977
10001
  // creates code lengths from a frequency table
9978
10002
  var hTree = function (d, mb) {
@@ -9985,11 +10009,11 @@
9985
10009
  var s = t.length;
9986
10010
  var t2 = t.slice();
9987
10011
  if (!s)
9988
- return [et, 0];
10012
+ return { t: et, l: 0 };
9989
10013
  if (s == 1) {
9990
10014
  var v = new u8(t[0].s + 1);
9991
10015
  v[t[0].s] = 1;
9992
- return [v, 1];
10016
+ return { t: v, l: 1 };
9993
10017
  }
9994
10018
  t.sort(function (a, b) { return a.f - b.f; });
9995
10019
  // after i2 reaches last ind, will be stopped
@@ -10033,7 +10057,7 @@
10033
10057
  else
10034
10058
  break;
10035
10059
  }
10036
- dt >>>= lft;
10060
+ dt >>= lft;
10037
10061
  while (dt > 0) {
10038
10062
  var i2_2 = t2[i].s;
10039
10063
  if (tr[i2_2] < mb)
@@ -10050,7 +10074,7 @@
10050
10074
  }
10051
10075
  mbt = mb;
10052
10076
  }
10053
- return [new u8(tr), mbt];
10077
+ return { t: new u8(tr), l: mbt };
10054
10078
  };
10055
10079
  // get the max length and assign length codes
10056
10080
  var ln = function (n, l, d) {
@@ -10093,7 +10117,7 @@
10093
10117
  cln = c[i];
10094
10118
  }
10095
10119
  }
10096
- return [cl.subarray(0, cli), s];
10120
+ return { c: cl.subarray(0, cli), n: s };
10097
10121
  };
10098
10122
  // calculate the length of output from tree, code lengths
10099
10123
  var clen = function (cf, cl) {
@@ -10109,7 +10133,7 @@
10109
10133
  var s = dat.length;
10110
10134
  var o = shft(pos + 2);
10111
10135
  out[o] = s & 255;
10112
- out[o + 1] = s >>> 8;
10136
+ out[o + 1] = s >> 8;
10113
10137
  out[o + 2] = out[o] ^ 255;
10114
10138
  out[o + 3] = out[o + 1] ^ 255;
10115
10139
  for (var i = 0; i < s; ++i)
@@ -10120,23 +10144,23 @@
10120
10144
  var wblk = function (dat, out, final, syms, lf, df, eb, li, bs, bl, p) {
10121
10145
  wbits(out, p++, final);
10122
10146
  ++lf[256];
10123
- var _a = hTree(lf, 15), dlt = _a[0], mlb = _a[1];
10124
- var _b = hTree(df, 15), ddt = _b[0], mdb = _b[1];
10125
- var _c = lc(dlt), lclt = _c[0], nlc = _c[1];
10126
- var _d = lc(ddt), lcdt = _d[0], ndc = _d[1];
10147
+ var _a = hTree(lf, 15), dlt = _a.t, mlb = _a.l;
10148
+ var _b = hTree(df, 15), ddt = _b.t, mdb = _b.l;
10149
+ var _c = lc(dlt), lclt = _c.c, nlc = _c.n;
10150
+ var _d = lc(ddt), lcdt = _d.c, ndc = _d.n;
10127
10151
  var lcfreq = new u16(19);
10128
10152
  for (var i = 0; i < lclt.length; ++i)
10129
- lcfreq[lclt[i] & 31]++;
10153
+ ++lcfreq[lclt[i] & 31];
10130
10154
  for (var i = 0; i < lcdt.length; ++i)
10131
- lcfreq[lcdt[i] & 31]++;
10132
- var _e = hTree(lcfreq, 7), lct = _e[0], mlcb = _e[1];
10155
+ ++lcfreq[lcdt[i] & 31];
10156
+ var _e = hTree(lcfreq, 7), lct = _e.t, mlcb = _e.l;
10133
10157
  var nlcc = 19;
10134
10158
  for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc)
10135
10159
  ;
10136
10160
  var flen = (bl + 5) << 3;
10137
10161
  var ftlen = clen(lf, flt) + clen(df, fdt) + eb;
10138
- var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + (2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18]);
10139
- if (flen <= ftlen && flen <= dtlen)
10162
+ var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + 2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18];
10163
+ if (bs >= 0 && flen <= ftlen && flen <= dtlen)
10140
10164
  return wfblk(out, p, dat.subarray(bs, bs + bl));
10141
10165
  var lm, ll, dm, dl;
10142
10166
  wbits(out, p, 1 + (dtlen < ftlen)), p += 2;
@@ -10157,7 +10181,7 @@
10157
10181
  var len = clct[i] & 31;
10158
10182
  wbits(out, p, llm[len]), p += lct[len];
10159
10183
  if (len > 15)
10160
- wbits(out, p, (clct[i] >>> 5) & 127), p += clct[i] >>> 12;
10184
+ wbits(out, p, (clct[i] >> 5) & 127), p += clct[i] >> 12;
10161
10185
  }
10162
10186
  }
10163
10187
  }
@@ -10165,63 +10189,55 @@
10165
10189
  lm = flm, ll = flt, dm = fdm, dl = fdt;
10166
10190
  }
10167
10191
  for (var i = 0; i < li; ++i) {
10168
- if (syms[i] > 255) {
10169
- var len = (syms[i] >>> 18) & 31;
10192
+ var sym = syms[i];
10193
+ if (sym > 255) {
10194
+ var len = (sym >> 18) & 31;
10170
10195
  wbits16(out, p, lm[len + 257]), p += ll[len + 257];
10171
10196
  if (len > 7)
10172
- wbits(out, p, (syms[i] >>> 23) & 31), p += fleb[len];
10173
- var dst = syms[i] & 31;
10197
+ wbits(out, p, (sym >> 23) & 31), p += fleb[len];
10198
+ var dst = sym & 31;
10174
10199
  wbits16(out, p, dm[dst]), p += dl[dst];
10175
10200
  if (dst > 3)
10176
- wbits16(out, p, (syms[i] >>> 5) & 8191), p += fdeb[dst];
10201
+ wbits16(out, p, (sym >> 5) & 8191), p += fdeb[dst];
10177
10202
  }
10178
10203
  else {
10179
- wbits16(out, p, lm[syms[i]]), p += ll[syms[i]];
10204
+ wbits16(out, p, lm[sym]), p += ll[sym];
10180
10205
  }
10181
10206
  }
10182
10207
  wbits16(out, p, lm[256]);
10183
10208
  return p + ll[256];
10184
10209
  };
10185
10210
  // deflate options (nice << 13) | chain
10186
- var deo = /*#__PURE__*/ new u32([65540, 131080, 131088, 131104, 262176, 1048704, 1048832, 2114560, 2117632]);
10211
+ var deo = /*#__PURE__*/ new i32([65540, 131080, 131088, 131104, 262176, 1048704, 1048832, 2114560, 2117632]);
10187
10212
  // empty
10188
10213
  var et = /*#__PURE__*/ new u8(0);
10189
10214
  // compresses data into a raw DEFLATE buffer
10190
- var dflt = function (dat, lvl, plvl, pre, post, lst) {
10191
- var s = dat.length;
10215
+ var dflt = function (dat, lvl, plvl, pre, post, st) {
10216
+ var s = st.z || dat.length;
10192
10217
  var o = new u8(pre + s + 5 * (1 + Math.ceil(s / 7000)) + post);
10193
10218
  // writing to this writes to the output buffer
10194
10219
  var w = o.subarray(pre, o.length - post);
10195
- var pos = 0;
10196
- if (!lvl || s < 8) {
10197
- for (var i = 0; i <= s; i += 65535) {
10198
- // end
10199
- var e = i + 65535;
10200
- if (e >= s) {
10201
- // write final block
10202
- w[pos >> 3] = lst;
10203
- }
10204
- pos = wfblk(w, pos + 1, dat.subarray(i, e));
10205
- }
10206
- }
10207
- else {
10220
+ var lst = st.l;
10221
+ var pos = (st.r || 0) & 7;
10222
+ if (lvl) {
10223
+ if (pos)
10224
+ w[0] = st.r >> 3;
10208
10225
  var opt = deo[lvl - 1];
10209
- var n = opt >>> 13, c = opt & 8191;
10226
+ var n = opt >> 13, c = opt & 8191;
10210
10227
  var msk_1 = (1 << plvl) - 1;
10211
10228
  // prev 2-byte val map curr 2-byte val map
10212
- var prev = new u16(32768), head = new u16(msk_1 + 1);
10229
+ var prev = st.p || new u16(32768), head = st.h || new u16(msk_1 + 1);
10213
10230
  var bs1_1 = Math.ceil(plvl / 3), bs2_1 = 2 * bs1_1;
10214
10231
  var hsh = function (i) { return (dat[i] ^ (dat[i + 1] << bs1_1) ^ (dat[i + 2] << bs2_1)) & msk_1; };
10215
10232
  // 24576 is an arbitrary number of maximum symbols per block
10216
10233
  // 424 buffer for last block
10217
- var syms = new u32(25000);
10234
+ var syms = new i32(25000);
10218
10235
  // length/literal freq distance freq
10219
10236
  var lf = new u16(288), df = new u16(32);
10220
- // l/lcnt exbits index l/lind waitdx bitpos
10221
- var lc_1 = 0, eb = 0, i = 0, li = 0, wi = 0, bs = 0;
10222
- for (; i < s; ++i) {
10237
+ // l/lcnt exbits index l/lind waitdx blkpos
10238
+ var lc_1 = 0, eb = 0, i = st.i || 0, li = 0, wi = st.w || 0, bs = 0;
10239
+ for (; i + 2 < s; ++i) {
10223
10240
  // hash value
10224
- // deopt when i > s - 3 - at end, deopt acceptable
10225
10241
  var hv = hsh(i);
10226
10242
  // index mod 32768 previous index mod
10227
10243
  var imod = i & 32767, pimod = head[hv];
@@ -10232,7 +10248,7 @@
10232
10248
  if (wi <= i) {
10233
10249
  // bytes remaining
10234
10250
  var rem = s - i;
10235
- if ((lc_1 > 7000 || li > 24576) && rem > 423) {
10251
+ if ((lc_1 > 7000 || li > 24576) && (rem > 423 || !lst)) {
10236
10252
  pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i - bs, pos);
10237
10253
  li = lc_1 = eb = 0, bs = i;
10238
10254
  for (var j = 0; j < 286; ++j)
@@ -10241,7 +10257,7 @@
10241
10257
  df[j] = 0;
10242
10258
  }
10243
10259
  // len dist chain
10244
- var l = 2, d = 0, ch_1 = c, dif = (imod - pimod) & 32767;
10260
+ var l = 2, d = 0, ch_1 = c, dif = imod - pimod & 32767;
10245
10261
  if (rem > 2 && hv == hsh(i - dif)) {
10246
10262
  var maxn = Math.min(n, rem) - 1;
10247
10263
  var maxd = Math.min(32767, i);
@@ -10264,9 +10280,9 @@
10264
10280
  var mmd = Math.min(dif, nl - 2);
10265
10281
  var md = 0;
10266
10282
  for (var j = 0; j < mmd; ++j) {
10267
- var ti = (i - dif + j + 32768) & 32767;
10283
+ var ti = i - dif + j & 32767;
10268
10284
  var pti = prev[ti];
10269
- var cd = (ti - pti + 32768) & 32767;
10285
+ var cd = ti - pti & 32767;
10270
10286
  if (cd > md)
10271
10287
  md = cd, pimod = ti;
10272
10288
  }
@@ -10274,12 +10290,12 @@
10274
10290
  }
10275
10291
  // check the previous match
10276
10292
  imod = pimod, pimod = prev[imod];
10277
- dif += (imod - pimod + 32768) & 32767;
10293
+ dif += imod - pimod & 32767;
10278
10294
  }
10279
10295
  }
10280
10296
  // d will be nonzero only when a match was found
10281
10297
  if (d) {
10282
- // store both dist and len data in one Uint32
10298
+ // store both dist and len data in one int32
10283
10299
  // Make sure this is recognized as a len/dist with 28th bit (2^28)
10284
10300
  syms[li++] = 268435456 | (revfl[l] << 18) | revfd[d];
10285
10301
  var lin = revfl[l] & 31, din = revfd[d] & 31;
@@ -10295,10 +10311,30 @@
10295
10311
  }
10296
10312
  }
10297
10313
  }
10314
+ for (i = Math.max(i, wi); i < s; ++i) {
10315
+ syms[li++] = dat[i];
10316
+ ++lf[dat[i]];
10317
+ }
10298
10318
  pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i - bs, pos);
10299
- // this is the easiest way to avoid needing to maintain state
10300
- if (!lst && pos & 7)
10301
- pos = wfblk(w, pos + 1, et);
10319
+ if (!lst) {
10320
+ st.r = (pos & 7) | w[(pos / 8) | 0] << 3;
10321
+ // shft(pos) now 1 less if pos & 7 != 0
10322
+ pos -= 7;
10323
+ st.h = head, st.p = prev, st.i = i, st.w = wi;
10324
+ }
10325
+ }
10326
+ else {
10327
+ for (var i = st.w || 0; i < s + lst; i += 65535) {
10328
+ // end
10329
+ var e = i + 65535;
10330
+ if (e >= s) {
10331
+ // write final block
10332
+ w[(pos / 8) | 0] = lst;
10333
+ e = s;
10334
+ }
10335
+ pos = wfblk(w, pos + 1, dat.subarray(i, e));
10336
+ }
10337
+ st.i = s;
10302
10338
  }
10303
10339
  return slc(o, 0, pre + shft(pos) + post);
10304
10340
  };
@@ -10329,7 +10365,18 @@
10329
10365
  };
10330
10366
  // deflate with opts
10331
10367
  var dopt = function (dat, opt, pre, post, st) {
10332
- return dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : (12 + opt.mem), pre, post, !st);
10368
+ if (!st) {
10369
+ st = { l: 1 };
10370
+ if (opt.dictionary) {
10371
+ var dict = opt.dictionary.subarray(-32768);
10372
+ var newDat = new u8(dict.length + dat.length);
10373
+ newDat.set(dict);
10374
+ newDat.set(dat, dict.length);
10375
+ dat = newDat;
10376
+ st.w = dict.length;
10377
+ }
10378
+ }
10379
+ return dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? (st.l ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : 20) : (12 + opt.mem), pre, post, st);
10333
10380
  };
10334
10381
  // Walmart object spread
10335
10382
  var mrg = function (a, b) {
@@ -10374,7 +10421,7 @@
10374
10421
  else
10375
10422
  td[k] = v;
10376
10423
  }
10377
- return [fnStr, td];
10424
+ return fnStr;
10378
10425
  };
10379
10426
  var ch = [];
10380
10427
  // clone bufs
@@ -10389,27 +10436,29 @@
10389
10436
  };
10390
10437
  // use a worker to execute code
10391
10438
  var wrkr = function (fns, init, id, cb) {
10392
- var _a;
10393
10439
  if (!ch[id]) {
10394
10440
  var fnStr = '', td_1 = {}, m = fns.length - 1;
10395
10441
  for (var i = 0; i < m; ++i)
10396
- _a = wcln(fns[i], fnStr, td_1), fnStr = _a[0], td_1 = _a[1];
10397
- ch[id] = wcln(fns[m], fnStr, td_1);
10442
+ fnStr = wcln(fns[i], fnStr, td_1);
10443
+ ch[id] = { c: wcln(fns[m], fnStr, td_1), e: td_1 };
10398
10444
  }
10399
- var td = mrg({}, ch[id][1]);
10400
- return wk(ch[id][0] + ';onmessage=function(e){for(var k in e.data)self[k]=e.data[k];onmessage=' + init.toString() + '}', id, td, cbfs(td), cb);
10445
+ var td = mrg({}, ch[id].e);
10446
+ return wk(ch[id].c + ';onmessage=function(e){for(var k in e.data)self[k]=e.data[k];onmessage=' + init.toString() + '}', id, td, cbfs(td), cb);
10401
10447
  };
10402
10448
  // base async inflate fn
10403
- var bInflt = function () { return [u8, u16, u32, fleb, fdeb, clim, fl, fd, flrm, fdrm, rev, ec, hMap, max, bits, bits16, shft, slc, err, inflt, inflateSync, pbf, gu8]; };
10404
- var bDflt = function () { return [u8, u16, u32, fleb, fdeb, clim, revfl, revfd, flm, flt, fdm, fdt, rev, deo, et, hMap, wbits, wbits16, hTree, ln, lc, clen, wfblk, wblk, shft, slc, dflt, dopt, deflateSync, pbf]; };
10449
+ var bInflt = function () { return [u8, u16, i32, fleb, fdeb, clim, fl, fd, flrm, fdrm, rev, ec, hMap, max, bits, bits16, shft, slc, err, inflt, inflateSync, pbf, gopt]; };
10450
+ var bDflt = function () { return [u8, u16, i32, fleb, fdeb, clim, revfl, revfd, flm, flt, fdm, fdt, rev, deo, et, hMap, wbits, wbits16, hTree, ln, lc, clen, wfblk, wblk, shft, slc, dflt, dopt, deflateSync, pbf]; };
10405
10451
  // gzip extra
10406
10452
  var gze = function () { return [gzh, gzhl, wbytes, crc, crct]; };
10407
10453
  // gunzip extra
10408
10454
  var guze = function () { return [gzs, gzl]; };
10409
10455
  // post buf
10410
10456
  var pbf = function (msg) { return postMessage(msg, [msg.buffer]); };
10411
- // get u8
10412
- var gu8 = function (o) { return o && o.size && new u8(o.size); };
10457
+ // get opts
10458
+ var gopt = function (o) { return o && {
10459
+ out: o.size && new u8(o.size),
10460
+ dictionary: o.dictionary
10461
+ }; };
10413
10462
  // async helper
10414
10463
  var cbify = function (dat, opts, fns, init, id, cb) {
10415
10464
  var w = wrkr(fns, init, id, function (err, dat) {
@@ -10449,7 +10498,7 @@
10449
10498
  var flg = d[3];
10450
10499
  var st = 10;
10451
10500
  if (flg & 4)
10452
- st += d[10] | (d[11] << 8) + 2;
10501
+ st += (d[10] | d[11] << 8) + 2;
10453
10502
  for (var zs = (flg >> 3 & 1) + (flg >> 4 & 1); zs > 0; zs -= !d[st++])
10454
10503
  ;
10455
10504
  return st + (flg & 2);
@@ -10457,10 +10506,10 @@
10457
10506
  // gzip length
10458
10507
  var gzl = function (d) {
10459
10508
  var l = d.length;
10460
- return ((d[l - 4] | d[l - 3] << 8 | d[l - 2] << 16) | (d[l - 1] << 24)) >>> 0;
10509
+ return (d[l - 4] | d[l - 3] << 8 | d[l - 2] << 16 | d[l - 1] << 24) >>> 0;
10461
10510
  };
10462
10511
  // gzip header length
10463
- var gzhl = function (o) { return 10 + ((o.filename && (o.filename.length + 1)) || 0); };
10512
+ var gzhl = function (o) { return 10 + (o.filename ? o.filename.length + 1 : 0); };
10464
10513
  function deflate(data, opts, cb) {
10465
10514
  if (!cb)
10466
10515
  cb = opts, opts = {};
@@ -10486,16 +10535,16 @@
10486
10535
  err(7);
10487
10536
  return cbify(data, opts, [
10488
10537
  bInflt
10489
- ], function (ev) { return pbf(inflateSync(ev.data[0], gu8(ev.data[1]))); }, 1, cb);
10538
+ ], function (ev) { return pbf(inflateSync(ev.data[0], gopt(ev.data[1]))); }, 1, cb);
10490
10539
  }
10491
10540
  /**
10492
10541
  * Expands DEFLATE data with no wrapper
10493
10542
  * @param data The data to decompress
10494
- * @param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length.
10543
+ * @param opts The decompression options
10495
10544
  * @returns The decompressed version of the data
10496
10545
  */
10497
- function inflateSync(data, out) {
10498
- return inflt(data, out);
10546
+ function inflateSync(data, opts) {
10547
+ return inflt(data, { i: 2 }, opts && opts.out, opts && opts.dictionary);
10499
10548
  }
10500
10549
  function gzip(data, opts, cb) {
10501
10550
  if (!cb)
@@ -10531,16 +10580,19 @@
10531
10580
  bInflt,
10532
10581
  guze,
10533
10582
  function () { return [gunzipSync$1]; }
10534
- ], function (ev) { return pbf(gunzipSync$1(ev.data[0])); }, 3, cb);
10583
+ ], function (ev) { return pbf(gunzipSync$1(ev.data[0], ev.data[1])); }, 3, cb);
10535
10584
  }
10536
10585
  /**
10537
10586
  * Expands GZIP data
10538
10587
  * @param data The data to decompress
10539
- * @param out Where to write the data. GZIP already encodes the output size, so providing this doesn't save memory.
10588
+ * @param opts The decompression options
10540
10589
  * @returns The decompressed version of the data
10541
10590
  */
10542
- function gunzipSync$1(data, out) {
10543
- return inflt(data.subarray(gzs(data), -8), out || new u8(gzl(data)));
10591
+ function gunzipSync$1(data, opts) {
10592
+ var st = gzs(data);
10593
+ if (st + 8 > data.length)
10594
+ err(6, 'invalid gzip data');
10595
+ return inflt(data.subarray(st, -8), { i: 2 }, opts && opts.out || new u8(gzl(data)), opts && opts.dictionary);
10544
10596
  }
10545
10597
  // flatten a directory structure
10546
10598
  var fltn = function (d, p, t, o) {
@@ -10573,7 +10625,7 @@
10573
10625
  var c = d[i++];
10574
10626
  var eb = (c > 127) + (c > 223) + (c > 239);
10575
10627
  if (i + eb > d.length)
10576
- return [r, slc(d, i - 1)];
10628
+ return { s: r, r: slc(d, i - 1) };
10577
10629
  if (!eb)
10578
10630
  r += String.fromCharCode(c);
10579
10631
  else if (eb == 3) {
@@ -10639,13 +10691,14 @@
10639
10691
  r += String.fromCharCode.apply(null, dat.subarray(i, i + 16384));
10640
10692
  return r;
10641
10693
  }
10642
- else if (td)
10694
+ else if (td) {
10643
10695
  return td.decode(dat);
10696
+ }
10644
10697
  else {
10645
- var _a = dutf8(dat), out = _a[0], ext = _a[1];
10646
- if (ext.length)
10698
+ var _a = dutf8(dat), s = _a.s, r = _a.r;
10699
+ if (r.length)
10647
10700
  err(8);
10648
- return out;
10701
+ return s;
10649
10702
  }
10650
10703
  }
10651
10704
  // skip local zip header
@@ -10688,7 +10741,7 @@
10688
10741
  var dt = new Date(f.mtime == null ? Date.now() : f.mtime), y = dt.getFullYear() - 1980;
10689
10742
  if (y < 0 || y > 119)
10690
10743
  err(10);
10691
- wbytes(d, b, (y << 25) | ((dt.getMonth() + 1) << 21) | (dt.getDate() << 16) | (dt.getHours() << 11) | (dt.getMinutes() << 5) | (dt.getSeconds() >>> 1)), b += 4;
10744
+ wbytes(d, b, (y << 25) | ((dt.getMonth() + 1) << 21) | (dt.getDate() << 16) | (dt.getHours() << 11) | (dt.getMinutes() << 5) | (dt.getSeconds() >> 1)), b += 4;
10692
10745
  if (c != -1) {
10693
10746
  wbytes(d, b, f.crc);
10694
10747
  wbytes(d, b + 4, c < 0 ? -c - 2 : c);
@@ -10928,9 +10981,10 @@
10928
10981
  cbl(null, slc(data, b, b + sc));
10929
10982
  else if (c_1 == 8) {
10930
10983
  var infl = data.subarray(b, b + sc);
10931
- if (sc < 320000) {
10984
+ // Synchronously decompress under 512KB, or barely-compressed data
10985
+ if (su < 524288 || sc > 0.8 * su) {
10932
10986
  try {
10933
- cbl(null, inflateSync(infl, new u8(su)));
10987
+ cbl(null, inflateSync(infl, { out: new u8(su) }));
10934
10988
  }
10935
10989
  catch (e) {
10936
10990
  cbl(e, null);
@@ -10993,7 +11047,7 @@
10993
11047
  if (!c_2)
10994
11048
  files[fn] = slc(data, b, b + sc);
10995
11049
  else if (c_2 == 8)
10996
- files[fn] = inflateSync(data.subarray(b, b + sc), new u8(su));
11050
+ files[fn] = inflateSync(data.subarray(b, b + sc), { out: new u8(su) });
10997
11051
  else
10998
11052
  err(14, 'unknown compression type ' + c_2);
10999
11053
  }
@@ -13762,7 +13816,7 @@
13762
13816
  convertIntervalParam(opt[1], crs)];
13763
13817
  }
13764
13818
 
13765
- // Accepts a single value or a list of four values. List order is l,b,t,r
13819
+ // Accepts a single value or a list of four values. List order is l,b,r,t
13766
13820
  function convertFourSides(opt, crs, bounds) {
13767
13821
  var arr = opt.includes(',') ? opt.split(',') : opt.split(' ');
13768
13822
  if (arr.length == 1) {
@@ -13776,7 +13830,7 @@
13776
13830
  tmp = parseFloat(param) / 100 || 0;
13777
13831
  return tmp * (i == 1 || i == 3 ? bounds.height() : bounds.width());
13778
13832
  }
13779
- return convertIntervalParam(opt, crs);
13833
+ return convertIntervalParam(param, crs);
13780
13834
  });
13781
13835
  }
13782
13836
 
@@ -18486,18 +18540,30 @@
18486
18540
  type: 'frame'
18487
18541
  }
18488
18542
  */
18543
+
18544
+
18489
18545
  function getFrameData(dataset, exportOpts) {
18490
18546
  var frameLyr = findFrameLayerInDataset(dataset);
18491
- var frameData;
18547
+ var data;
18492
18548
  if (frameLyr) {
18493
- frameData = getFrameLayerData(frameLyr, dataset.arcs);
18549
+ data = getFrameLayerData(frameLyr, dataset.arcs);
18494
18550
  } else {
18495
- frameData = calcFrameData(dataset, exportOpts);
18551
+ data = calcFrameData(dataset, exportOpts);
18496
18552
  }
18497
- frameData.crs = getDatasetCRS(dataset);
18498
- return frameData;
18553
+ data.invert_y = !!exportOpts.invert_y;
18554
+ data.crs = getDatasetCRS(dataset);
18555
+ return data;
18499
18556
  }
18500
18557
 
18558
+ function fitDatasetToFrame(dataset, frame) {
18559
+ var bounds = new Bounds(frame.bbox);
18560
+ var bounds2 = frame.bbox2 ? new Bounds(frame.bbox2) : new Bounds(0, 0, frame.width, frame.height);
18561
+ bounds.fillOut(bounds2.width() / bounds2.height());
18562
+ var fwd = bounds.getTransform(bounds2, frame.invert_y);
18563
+ transformPoints(dataset, function(x, y) {
18564
+ return fwd.transform(x, y);
18565
+ });
18566
+ }
18501
18567
 
18502
18568
  function getFrameLayerData(lyr, arcs) {
18503
18569
  var bounds = getLayerBounds(lyr, arcs);
@@ -18515,17 +18581,17 @@
18515
18581
 
18516
18582
 
18517
18583
  function calcFrameData(dataset, opts) {
18518
- var bounds;
18519
- var outputBbox = opts.svg_bbox || opts.output_bbox || null;
18520
- if (outputBbox) {
18521
- bounds = new Bounds(outputBbox);
18584
+ var inputBounds, outputBounds;
18585
+ if (opts.svg_bbox) {
18586
+ inputBounds = new Bounds(opts.svg_bbox);
18522
18587
  opts = Object.assign({margin: 0}, opts); // prevent default pixel margin around content
18523
18588
  } else {
18524
- bounds = getDatasetBounds(dataset);
18589
+ inputBounds = getDatasetBounds(dataset);
18525
18590
  }
18526
- var outputBounds = calcOutputSizeInPixels(bounds, opts);
18591
+ // side effect: inputBounds may be expanded to add margins
18592
+ outputBounds = calcOutputBounds(inputBounds, opts);
18527
18593
  return {
18528
- bbox: bounds.toArray(),
18594
+ bbox: inputBounds.toArray(),
18529
18595
  bbox2: outputBounds.toArray(),
18530
18596
  width: Math.round(outputBounds.width()),
18531
18597
  height: Math.round(outputBounds.height()) || 1,
@@ -18533,7 +18599,7 @@
18533
18599
  };
18534
18600
  }
18535
18601
 
18536
- // Used by mapshaper-frame and mapshaper-pixel-transform. TODO: refactor
18602
+ // Used by mapshaper-frame TODO: refactor
18537
18603
  function getFrameSize(bounds, opts) {
18538
18604
  var aspectRatio = bounds.width() / bounds.height();
18539
18605
  var height, width;
@@ -18602,9 +18668,9 @@
18602
18668
 
18603
18669
 
18604
18670
  // bounds: Bounds object containing bounds of content in geographic coordinates
18605
- // returns Bounds object containing bounds of pixel output
18671
+ // returns Bounds object containing output bounds
18606
18672
  // side effect: bounds param is modified to match the output frame
18607
- function calcOutputSizeInPixels(bounds, opts) {
18673
+ function calcOutputBounds(bounds, opts) {
18608
18674
  var padX = 0,
18609
18675
  padY = 0,
18610
18676
  offX = 0,
@@ -18617,65 +18683,59 @@
18617
18683
  // TODO: add option to tweak alignment of content when both width and height are given
18618
18684
  wx = 0.5, // how padding is distributed horizontally (0: left aligned, 0.5: centered, 1: right aligned)
18619
18685
  wy = 0.5, // vertical padding distribution
18620
- widthPx, heightPx, size, kx, ky;
18686
+ width2, height2, size2, kx, ky;
18621
18687
 
18622
18688
  if (opts.fit_bbox) {
18623
18689
  // scale + shift content to fit within a bbox
18624
18690
  offX = opts.fit_bbox[0];
18625
18691
  offY = opts.fit_bbox[1];
18626
- widthPx = opts.fit_bbox[2] - offX;
18627
- heightPx = opts.fit_bbox[3] - offY;
18628
- if (width / height > widthPx / heightPx) {
18629
- // data is wider than fit box...
18630
- // scale the data to fit widthwise
18631
- heightPx = 0;
18632
- } else {
18633
- widthPx = 0; // fit the data to the height
18634
- }
18692
+ width2 = opts.fit_bbox[2] - offX;
18693
+ height2 = opts.fit_bbox[3] - offY;
18635
18694
  marginX = marginY = 0; // TODO: support margins
18636
18695
 
18637
18696
  } else if (opts.svg_scale > 0) {
18638
18697
  // alternative to using a fixed width (e.g. when generating multiple files
18639
18698
  // at a consistent geographic scale)
18640
- widthPx = width / opts.svg_scale + marginX;
18641
- heightPx = 0;
18699
+ width2 = width / opts.svg_scale + marginX;
18700
+ height2 = 0;
18642
18701
  } else if (+opts.pixels) {
18643
- size = getFrameSize(bounds, opts);
18644
- widthPx = size[0];
18645
- heightPx = size[1];
18702
+ size2 = getFrameSize(bounds, opts);
18703
+ width2 = size2[0];
18704
+ height2 = size2[1];
18646
18705
  } else {
18647
- heightPx = opts.height || 0;
18648
- widthPx = opts.width || (heightPx > 0 ? 0 : 800); // 800 is default width
18706
+ height2 = opts.height || 0;
18707
+ width2 = opts.width || (height2 > 0 ? 0 : 800); // 800 is default width
18649
18708
  }
18650
18709
 
18651
- if (heightPx > 0) {
18710
+ if (height2 > 0) {
18652
18711
  // vertical meters per pixel to fit height param
18653
- ky = (height || width || 1) / (heightPx - marginY);
18712
+ ky = (height || width || 1) / (height2 - marginY);
18654
18713
  }
18655
- if (widthPx > 0) {
18714
+ if (width2 > 0) {
18656
18715
  // horizontal meters per pixel to fit width param
18657
- kx = (width || height || 1) / (widthPx - marginX);
18716
+ kx = (width || height || 1) / (width2 - marginX);
18658
18717
  }
18659
18718
 
18660
- if (!widthPx) { // heightPx and ky are defined, set width to match
18719
+ if (!width2) { // height2 and ky are defined, set width to match
18661
18720
  kx = ky;
18662
- widthPx = width > 0 ? marginX + width / kx : heightPx; // export square graphic if content has 0 width (reconsider this?)
18663
- } else if (!heightPx) { // widthPx and kx are set, set height to match
18721
+ width2 = width > 0 ? marginX + width / kx : height2; // export square graphic if content has 0 width (reconsider this?)
18722
+ } else if (!height2) { // width2 and kx are set, set height to match
18664
18723
  ky = kx;
18665
- heightPx = height > 0 ? marginY + height / ky : widthPx;
18724
+ height2 = height > 0 ? marginY + height / ky : width2;
18666
18725
  // limit height if max_height is defined
18667
- if (opts.max_height > 0 && heightPx > opts.max_height) {
18668
- ky = kx * heightPx / opts.max_height;
18669
- heightPx = opts.max_height;
18726
+ if (opts.max_height > 0 && height2 > opts.max_height) {
18727
+ ky = kx * height2 / opts.max_height;
18728
+ height2 = opts.max_height;
18670
18729
  }
18671
18730
  }
18672
18731
 
18732
+ // add padding, if needed
18673
18733
  if (kx > ky) { // content is wide -- need to pad vertically
18674
18734
  ky = kx;
18675
- padY = ky * (heightPx - marginY) - height;
18735
+ padY = ky * (height2 - marginY) - height;
18676
18736
  } else if (ky > kx) { // content is tall -- need to pad horizontally
18677
18737
  kx = ky;
18678
- padX = kx * (widthPx - marginX) - width;
18738
+ padX = kx * (width2 - marginX) - width;
18679
18739
  }
18680
18740
 
18681
18741
  bounds.padBounds(
@@ -18684,14 +18744,14 @@
18684
18744
  margins[2] * kx + padX * (1 - wx),
18685
18745
  margins[3] * ky + padY * (1 - wy));
18686
18746
 
18687
- if (!(widthPx > 0 && heightPx > 0)) {
18747
+ if (!(width2 > 0 && height2 > 0)) {
18688
18748
  error("Missing valid height and width parameters");
18689
18749
  }
18690
18750
  if (!(kx === ky && kx > 0)) {
18691
18751
  error("Missing valid margin parameters");
18692
18752
  }
18693
18753
 
18694
- return new Bounds(offX, offY, widthPx + offX, heightPx + offY);
18754
+ return new Bounds(offX, offY, width2 + offX, height2 + offY);
18695
18755
  }
18696
18756
 
18697
18757
  function parseMarginOption(opt) {
@@ -18702,13 +18762,14 @@
18702
18762
  if (margins.length == 3) margins.push(margins[2]);
18703
18763
  return margins.map(function(str) {
18704
18764
  var px = parseFloat(str);
18705
- return isNaN(px) ? 1 : px; // 1 is default
18765
+ return isNaN(px) ? 0 : px; // 0 is default
18706
18766
  });
18707
18767
  }
18708
18768
 
18709
- var FrameData = /*#__PURE__*/Object.freeze({
18769
+ var FrameUtils = /*#__PURE__*/Object.freeze({
18710
18770
  __proto__: null,
18711
18771
  getFrameData: getFrameData,
18772
+ fitDatasetToFrame: fitDatasetToFrame,
18712
18773
  getFrameLayerData: getFrameLayerData,
18713
18774
  calcFrameData: calcFrameData,
18714
18775
  getFrameSize: getFrameSize,
@@ -18719,7 +18780,7 @@
18719
18780
  findFrame: findFrame,
18720
18781
  getFrameLayerBounds: getFrameLayerBounds,
18721
18782
  getMapFrameMetersPerPixel: getMapFrameMetersPerPixel,
18722
- calcOutputSizeInPixels: calcOutputSizeInPixels,
18783
+ calcOutputBounds: calcOutputBounds,
18723
18784
  parseMarginOption: parseMarginOption
18724
18785
  });
18725
18786
 
@@ -20152,27 +20213,6 @@
20152
20213
  renderFurnitureLayer: renderFurnitureLayer
20153
20214
  });
20154
20215
 
20155
- function transformDatasetToPixels(dataset, opts) {
20156
- var frame = getFrameData(dataset, opts);
20157
- fitDatasetToFrame(dataset, frame, opts);
20158
- return [frame.width, frame.height];
20159
- }
20160
-
20161
- function fitDatasetToFrame(dataset, frame, opts) {
20162
- var bounds = new Bounds(frame.bbox);
20163
- var bounds2 = frame.bbox2 ? new Bounds(frame.bbox2) : new Bounds(0, 0, frame.width, frame.height);
20164
- var fwd = bounds.getTransform(bounds2, opts.invert_y);
20165
- transformPoints(dataset, function(x, y) {
20166
- return fwd.transform(x, y);
20167
- });
20168
- }
20169
-
20170
- var PixelTransform = /*#__PURE__*/Object.freeze({
20171
- __proto__: null,
20172
- transformDatasetToPixels: transformDatasetToPixels,
20173
- fitDatasetToFrame: fitDatasetToFrame
20174
- });
20175
-
20176
20216
  function stringify(obj) {
20177
20217
  var svg, joinStr;
20178
20218
  if (!obj || !obj.tag) return '';
@@ -20460,10 +20500,11 @@
20460
20500
  dataset = copyDataset(dataset); // Modify a copy of the dataset
20461
20501
  }
20462
20502
 
20463
- // invert_y setting for screen coordinates and geojson polygon generation
20464
- utils.extend(opts, {invert_y: true});
20503
+ // use invert_y: 0 setting for screen coordinates and geojson polygon generation
20504
+ // use 1px default margin so typical strokes don't get cut off on the sides
20505
+ opts = Object.assign({invert_y: true, margin: "1"}, opts);
20465
20506
  frame = getFrameData(dataset, opts);
20466
- fitDatasetToFrame(dataset, frame, opts);
20507
+ fitDatasetToFrame(dataset, frame);
20467
20508
  setCoordinatePrecision(dataset, opts.precision || 0.0001);
20468
20509
 
20469
20510
  // error if one or more svg_data fields are not present in any layers
@@ -20705,7 +20746,7 @@ ${svg}
20705
20746
  // import { isKmzFile } from '../io/mapshaper-file-types';
20706
20747
 
20707
20748
  function exportKML(dataset, opts) {
20708
- var toKML = require("@placemarkio/tokml").toKML;
20749
+ var toKML = require$1("@placemarkio/tokml").toKML;
20709
20750
  var geojsonOpts = Object.assign({combine_layers: true, geojson_type: 'FeatureCollection'}, opts);
20710
20751
  var geojson = exportDatasetAsGeoJSON(dataset, geojsonOpts);
20711
20752
  var kml = toKML(geojson);
@@ -22099,10 +22140,14 @@ ${svg}
22099
22140
  }
22100
22141
 
22101
22142
  if (opts.width > 0 || opts.height > 0) {
22143
+ // these options create a TopoJSON with pixel coordinates, including
22144
+ // origin (0,0) in the top left corner of the viewport, generally for
22145
+ // direct conversion to SVG (many online examples using d3 are like this)
22146
+ //
22102
22147
  opts = utils.defaults({invert_y: true}, opts);
22103
- transformDatasetToPixels(dataset, opts);
22148
+ fitDatasetToFrame(dataset, getFrameData(dataset, opts));
22104
22149
  } else if (opts.fit_bbox) {
22105
- transformDatasetToPixels(dataset, {fit_bbox: opts.fit_bbox});
22150
+ fitDatasetToFrame(dataset, getFrameData(dataset, {fit_bbox: opts.fit_bbox}));
22106
22151
  }
22107
22152
 
22108
22153
  if (opts.precision && opts.no_quantization) {
@@ -24311,7 +24356,7 @@ ${svg}
24311
24356
  describe: 'aspect ratio as a number or range (e.g. 2 0.8,1.6 ,2)'
24312
24357
  },
24313
24358
  offsetOpt = {
24314
- describe: 'padding as distance or pct of h/w (single value or list)',
24359
+ describe: 'offset distance or pct of h/w (single value or l,b,r,t list)',
24315
24360
  type: 'distance'
24316
24361
  };
24317
24362
 
@@ -25324,6 +25369,14 @@ ${svg}
25324
25369
  describe: '(polygon-polygon join) use max overlap to join one polygon',
25325
25370
  type: 'flag'
25326
25371
  })
25372
+ .option('min-overlap-pct', {
25373
+ describe: '(polygon-polygon join) min overlap as pct of target polygon',
25374
+ type: 'percent'
25375
+ })
25376
+ .option('min-overlap-area', {
25377
+ describe: '(polygon-polygon join) minimum area of overlap',
25378
+ type: 'area'
25379
+ })
25327
25380
  // .option('nearest-point', {
25328
25381
  // describe: '(point-point join)',
25329
25382
  // type: 'flag'
@@ -25762,6 +25815,10 @@ ${svg}
25762
25815
  parser.command('style')
25763
25816
  .oldAlias('svg-style')
25764
25817
  .describe('set SVG style properties using JS or literal values')
25818
+ .option('clear', {
25819
+ describe: 'remove all style properties from a layer',
25820
+ type: 'flag'
25821
+ })
25765
25822
  .option('where', whereOpt)
25766
25823
  .option('class', {
25767
25824
  describe: 'name of CSS class or classes (space-separated)'
@@ -33402,18 +33459,22 @@ ${svg}
33402
33459
  function getCategoricalClassifier(classValues, nullVal, opts) {
33403
33460
  // categories: strings to match in the data
33404
33461
  var categories = opts.categories;
33462
+ // index categories for better performance on datasets with many categories
33463
+ var index = categories.reduce((memo, key, i) => {
33464
+ memo[key] = i;
33465
+ return memo;
33466
+ }, {});
33405
33467
  var classToValue = getDiscreteValueGetter(classValues, nullVal, opts.other);
33406
33468
  return function(val) {
33407
- var i = categories.indexOf(val);
33408
- var idx = -1;
33409
- if (i >= 0) {
33410
- idx = i;
33411
- } else if (val) {
33412
- idx = -2; // field contains an 'other' value
33469
+ var i;
33470
+ if (val in index) {
33471
+ i = index[val];
33472
+ } else if (val || val === 0) {
33473
+ i = -2; // -2 indicates an 'other' value
33413
33474
  } else {
33414
- idx = -1; // field is empty (null value)
33475
+ i = -1; // field is empty (null value)
33415
33476
  }
33416
- return classToValue(idx);
33477
+ return classToValue(i);
33417
33478
  };
33418
33479
  }
33419
33480
 
@@ -34282,7 +34343,6 @@ ${svg}
34282
34343
  addCategoricalScheme('Tableau20',
34283
34344
  '4c78a89ecae9f58518ffbf7954a24b88d27ab79a20f2cf5b43989483bcb6e45756ff9d9879706ebab0acd67195fcbfd2b279a2d6a5c99e765fd8b5a5');
34284
34345
  index.all = [].concat(index.sequential, index.rainbow, index.diverging, index.categorical);
34285
-
34286
34346
  }
34287
34347
 
34288
34348
  function standardName(name) {
@@ -34296,8 +34356,15 @@ ${svg}
34296
34356
  return null;
34297
34357
  }
34298
34358
 
34299
- function addSchemesFromD3(type, names) {
34300
- index[type] = index[type].concat(names.split(','));
34359
+ function addSchemesFromD3(type, namesStr) {
34360
+ var names = namesStr.split(',');
34361
+ index[type] = index[type].concat(names);
34362
+ if (type == 'categorical') {
34363
+ // copy categorical colors for simplicity
34364
+ names.forEach(name => {
34365
+ ramps[name] = d3Scales['scheme' + name];
34366
+ });
34367
+ }
34301
34368
  }
34302
34369
 
34303
34370
  function addCategoricalScheme(name, str) {
@@ -34351,16 +34418,14 @@ ${svg}
34351
34418
  initSchemes();
34352
34419
  var names = index[type];
34353
34420
  if (!names) error('Unknown color scheme type:', type);
34354
- var i = Math.floor(Math.random() * names.length);
34355
- return names[i];
34421
+ return utils.pickOne(names);
34356
34422
  }
34357
34423
 
34358
- function getRandomColors(n) {
34424
+ function pickRandomCategoricalScheme(n) {
34359
34425
  initSchemes();
34360
- var colors = getCategoricalColorScheme('Tableau20', 20);
34361
- utils.shuffle(colors);
34362
- colors = wrapColors(colors, n);
34363
- return colors.slice(0, n);
34426
+ var minSize = Math.min(n, 20); // use largest available if n is too large
34427
+ var schemes = index.categorical.filter(name => ramps[name].length >= minSize);
34428
+ return utils.pickOne(schemes) || 'Tableau20';
34364
34429
  }
34365
34430
 
34366
34431
  function getCategoricalColorScheme(name, n) {
@@ -34469,10 +34534,11 @@ ${svg}
34469
34534
 
34470
34535
  if (colorArg == 'random') {
34471
34536
  if (categorical) {
34472
- return getRandomColors(n);
34537
+ colorScheme = pickRandomCategoricalScheme(n);
34538
+ } else {
34539
+ colorScheme = pickRandomColorScheme('sequential');
34473
34540
  }
34474
- colorScheme = pickRandomColorScheme('sequential');
34475
- message('Randomly selected color ramp:', colorScheme);
34541
+ message('Randomly selected color scheme:', colorScheme);
34476
34542
  } else if (isColorSchemeName(colorArg)) {
34477
34543
  colorScheme = colorArg;
34478
34544
  } else if (colorArg && !parseColor(colorArg)) {
@@ -36725,7 +36791,7 @@ ${svg}
36725
36791
 
36726
36792
  // Join data from @src table to records in @destLyr layer.
36727
36793
  // @join function
36728
- // Receives index of record in the dest table
36794
+ // Receives index of one record in the dest table
36729
36795
  // Returns array of matching records in src table, or null if no matches
36730
36796
  //
36731
36797
  function joinTableToLayer(destLyr, src, join, opts) {
@@ -36751,7 +36817,7 @@ ${svg}
36751
36817
  collisionFields = [],
36752
36818
  skipCount = 0,
36753
36819
  retn = {},
36754
- srcRec, srcId, destRec, joins, count, filter, calc, i, j, n, m;
36820
+ srcRec, srcId, destRec, joinIds, count, filter, calc, i, j, n, m;
36755
36821
 
36756
36822
  // support for duplication of destination records for many-to-one joins
36757
36823
  var duplicateRecords, destShapes;
@@ -36773,14 +36839,14 @@ ${svg}
36773
36839
  n = destRecords.length;
36774
36840
  for (i=0; i<n; i++) {
36775
36841
  destRec = destRecords[i];
36776
- joins = join(i);
36777
- if (joins && filter) {
36778
- skipCount += joins.length;
36779
- joins = filter(joins, destRec);
36780
- skipCount -= joins.length;
36781
- }
36782
- for (j=0, count=0, m=joins ? joins.length : 0; j<m; j++) {
36783
- srcId = joins[j];
36842
+ joinIds = join(i);
36843
+ if (joinIds && filter) {
36844
+ skipCount += joinIds.length;
36845
+ joinIds = filter(joinIds, destRec);
36846
+ skipCount -= joinIds.length;
36847
+ }
36848
+ for (j=0, count=0, m=joinIds ? joinIds.length : 0; j<m; j++) {
36849
+ srcId = joinIds[j];
36784
36850
  srcRec = srcRecords[srcId];
36785
36851
  // duplication mode: many-to-one joins add new features to the target layer.
36786
36852
  if (count > 0 && useDuplication) {
@@ -36806,7 +36872,7 @@ ${svg}
36806
36872
  count++;
36807
36873
  }
36808
36874
  if (calc) {
36809
- calc(joins, destRec);
36875
+ calc(joinIds, destRec);
36810
36876
  }
36811
36877
  if (count > 0) {
36812
36878
  matchCount++;
@@ -39353,7 +39419,7 @@ ${svg}
39353
39419
  // TODO: consider projections that may or may not be aligned,
39354
39420
  // depending on parameters
39355
39421
  if (inList(P, 'cassini,gnom,bertin1953,chamb,ob_tran,tpeqd,healpix,rhealpix,' +
39356
- 'ocea,omerc,tmerc,etmerc')) {
39422
+ 'ocea,omerc,tmerc,etmerc,nicol')) {
39357
39423
  return false;
39358
39424
  }
39359
39425
  if (isAzimuthal(P)) {
@@ -39928,7 +39994,7 @@ ${svg}
39928
39994
  }
39929
39995
 
39930
39996
  function isCircleClippedProjection(P) {
39931
- return inList(P, 'stere,sterea,ups,ortho,gnom,laea,nsper,tpers,geos');
39997
+ return inList(P, 'stere,sterea,ups,ortho,gnom,laea,nsper,tpers,geos,nicol');
39932
39998
  }
39933
39999
 
39934
40000
  function getPerspectiveClipAngle(P) {
@@ -39953,6 +40019,7 @@ ${svg}
39953
40019
  laea: 179,
39954
40020
  //ortho: 89.9, // projection errors betwen lat +/-35 to 55
39955
40021
  ortho: 89.85, // TODO: investigate
40022
+ nicol: 89.85,
39956
40023
  stere: 142,
39957
40024
  sterea: 142,
39958
40025
  ups: 10.5 // TODO: should be 6.5 deg at north pole
@@ -40765,11 +40832,14 @@ ${svg}
40765
40832
  };
40766
40833
  // make a mosaic from merged shapes of both layers
40767
40834
  var mosaicIndex = new MosaicIndex(mergedLyr, nodes, {flat: false});
40768
-
40769
40835
  var joinOpts = utils.extend({}, opts);
40770
- var joinFunction = getPolygonToPolygonFunction(targetLyr, sourceLyr, mosaicIndex, opts);
40771
- var retn = joinTableToLayer(targetLyr, sourceLyr.data, joinFunction, joinOpts);
40836
+ if (joinOpts.min_overlap_area) {
40837
+ // convert area arg to square meters (typically)
40838
+ joinOpts.min_overlap_area = convertAreaParam(joinOpts.min_overlap_area, getDatasetCRS(targetDataset));
40839
+ }
40772
40840
 
40841
+ var joinFunction = getPolygonToPolygonFunction(targetLyr, sourceLyr, mosaicIndex, joinOpts);
40842
+ var retn = joinTableToLayer(targetLyr, sourceLyr.data, joinFunction, joinOpts);
40773
40843
  if (opts.interpolate) {
40774
40844
  if (opts.duplication) stop('duplication and interpolate options cannot be used together');
40775
40845
  interpolateFieldsByArea(targetLyr, sourceLyr, mosaicIndex, opts);
@@ -40783,6 +40853,22 @@ ${svg}
40783
40853
  var sourceFields = opts.interpolate;
40784
40854
  var sourceRecords = sourceLyr.data.getRecords();
40785
40855
 
40856
+ // Use different interpolation methods for qualitative and quantitative data
40857
+ // Assumes string and boolean fields are qualitative and numeric fields are
40858
+ // quantitative (TODO: somehow recognize numeric index data as qualitative)
40859
+ var quantitativeFields = [];
40860
+ var qualitativeFields = [];
40861
+ sourceFields.forEach(function(field) {
40862
+ var type = getColumnType(field, sourceRecords);
40863
+ if (type == 'number') {
40864
+ quantitativeFields.push(field);
40865
+ } else if (type == 'string' || type == 'boolean') {
40866
+ qualitativeFields.push(field);
40867
+ } else {
40868
+ message(`"${field}" field appears to contain ${type}-type data. No interpolation method is available.`);
40869
+ }
40870
+ });
40871
+
40786
40872
  // for each destination polygon, calculate interpolated values,
40787
40873
  // using the data calculated in previous steps
40788
40874
  destLyr.data.getRecords().forEach(function(destRec, destId) {
@@ -40791,9 +40877,13 @@ ${svg}
40791
40877
  for (i=0; i<tileIds.length; i++) {
40792
40878
  tileRecords.push(mosaicRecords[tileIds[i]]);
40793
40879
  }
40794
- for (i=0; i<sourceFields.length; i++) {
40880
+ for (i=0; i<quantitativeFields.length; i++) {
40795
40881
  field = sourceFields[i];
40796
- destRec[field] = getInterpolatedValue(field, tileRecords, sourceRecords);
40882
+ destRec[field] = getInterpolatedNumber(field, tileRecords, sourceRecords);
40883
+ }
40884
+ for (i=0; i<qualitativeFields.length; i++) {
40885
+ field = sourceFields[i];
40886
+ destRec[field] = getInterpolatedCategory(field, tileRecords, sourceRecords);
40797
40887
  }
40798
40888
  });
40799
40889
  }
@@ -40846,7 +40936,7 @@ ${svg}
40846
40936
  // return value;
40847
40937
  // }
40848
40938
 
40849
- function getInterpolatedValue(field, tileRecords, sourceRecords) {
40939
+ function getInterpolatedNumber(field, tileRecords, sourceRecords) {
40850
40940
  var value = 0, tileRec, sourceRec, sourceId;
40851
40941
  for (var i=0; i<tileRecords.length; i++) {
40852
40942
  tileRec = tileRecords[i];
@@ -40860,6 +40950,31 @@ ${svg}
40860
40950
  return value;
40861
40951
  }
40862
40952
 
40953
+ function getInterpolatedCategory(field, tileRecords, sourceRecords) {
40954
+ var value, tileRec, sourceRec, sourceId, idx;
40955
+ var areas = [];
40956
+ var values = [];
40957
+ for (var i=0; i<tileRecords.length; i++) {
40958
+ tileRec = tileRecords[i];
40959
+ if (!tileRec.sourceIds) continue;
40960
+ for (var j=0; j<tileRec.sourceIds.length; j++) {
40961
+ sourceId = tileRec.sourceIds[j];
40962
+ sourceRec = sourceRecords[sourceId];
40963
+ value = sourceRec[field];
40964
+ idx = values.indexOf(value);
40965
+ if (idx == -1) {
40966
+ values.push(value);
40967
+ areas.push(tileRec.area);
40968
+ } else {
40969
+ areas[idx] += tileRec.area;
40970
+ }
40971
+ }
40972
+ }
40973
+ var maxArea = Math.max.apply(null, areas);
40974
+ var maxIdx = areas.indexOf(maxArea);
40975
+ return maxIdx == -1 ? null : values[maxIdx];
40976
+ }
40977
+
40863
40978
 
40864
40979
  function getIdConversionFunction(offset, length) {
40865
40980
  return function (mergedIds) {
@@ -40872,17 +40987,50 @@ ${svg}
40872
40987
  };
40873
40988
  }
40874
40989
 
40875
- function getMaxOverlapFunction(destLyr, srcLyr, mosaicIndex) {
40876
- var arcs = mosaicIndex.nodes.arcs;
40990
+ function getMinPctFunction(minPct, destLyr, mosaicIndex) {
40991
+ mosaicIndex.nodes.arcs;
40877
40992
  var destLen = destLyr.shapes.length;
40878
40993
 
40879
- function getTotalArea(tileIds) {
40880
- var area = 0;
40881
- for (var i=0; i<tileIds.length; i++) {
40882
- area += geom.getShapeArea(mosaicIndex.mosaic[tileIds[i]], arcs);
40883
- }
40884
- return area;
40994
+ return function(destId, srcIds) {
40995
+ var destTileIds = mosaicIndex.getTileIdsByShapeId(destId);
40996
+ var destArea = getAreaOfTiles(destTileIds, mosaicIndex);
40997
+ return srcIds.filter(function(srcId, i) {
40998
+ var srcTileIds = mosaicIndex.getTileIdsByShapeId(srcId + destLen);
40999
+ var sharedIds = utils.intersection(destTileIds, srcTileIds);
41000
+ var overlapArea = getAreaOfTiles(sharedIds, mosaicIndex);
41001
+ var overlapPct = overlapArea / destArea || 0;
41002
+ return overlapPct >= minPct;
41003
+ });
41004
+ };
41005
+ }
41006
+
41007
+ function getMinAreaFunction(minArea, destLyr, mosaicIndex) {
41008
+ mosaicIndex.nodes.arcs;
41009
+ var destLen = destLyr.shapes.length;
41010
+
41011
+ return function(destId, srcIds) {
41012
+ var destTileIds = mosaicIndex.getTileIdsByShapeId(destId);
41013
+
41014
+ return srcIds.filter(function(srcId, i) {
41015
+ var srcTileIds = mosaicIndex.getTileIdsByShapeId(srcId + destLen);
41016
+ var sharedIds = utils.intersection(destTileIds, srcTileIds);
41017
+ var overlapArea = getAreaOfTiles(sharedIds, mosaicIndex);
41018
+ return overlapArea >= minArea;
41019
+ });
41020
+ };
41021
+ }
41022
+
41023
+ function getAreaOfTiles(tileIds, mosaicIndex) {
41024
+ var arcs = mosaicIndex.nodes.arcs;
41025
+ var area = 0;
41026
+ for (var i=0; i<tileIds.length; i++) {
41027
+ area += geom.getShapeArea(mosaicIndex.mosaic[tileIds[i]], arcs);
40885
41028
  }
41029
+ return area;
41030
+ }
41031
+
41032
+ function getMaxOverlapFunction(destLyr, mosaicIndex) {
41033
+ var destLen = destLyr.shapes.length;
40886
41034
 
40887
41035
  return function(destId, srcIds) {
40888
41036
  var destTileIds = mosaicIndex.getTileIdsByShapeId(destId);
@@ -40891,7 +41039,7 @@ ${svg}
40891
41039
  srcIds.forEach(function(srcId, i) {
40892
41040
  var srcTileIds = mosaicIndex.getTileIdsByShapeId(srcId + destLen);
40893
41041
  var sharedIds = utils.intersection(destTileIds, srcTileIds);
40894
- var area = getTotalArea(sharedIds);
41042
+ var area = getAreaOfTiles(sharedIds, mosaicIndex);
40895
41043
  if (area >= maxArea) {
40896
41044
  maxId = srcId;
40897
41045
  maxArea = area;
@@ -40904,14 +41052,21 @@ ${svg}
40904
41052
 
40905
41053
 
40906
41054
  // Returned function converts a target layer feature id to multiple source feature ids
40907
- // TODO: option to join the source polygon with the greatest overlapping area
40908
41055
  // TODO: option to ignore source polygon with small overlaps
40909
41056
  // (as a percentage of the area of one or the other polygon?)
40910
41057
  function getPolygonToPolygonFunction(targetLyr, srcLyr, mosaicIndex, opts) {
40911
41058
  var mergedToSourceIds = getIdConversionFunction(targetLyr.shapes.length, srcLyr.shapes.length);
40912
41059
  var selectMaxOverlap;
41060
+ var minAreaFilter;
41061
+ var minPctFilter;
40913
41062
  if (opts.largest_overlap) {
40914
- selectMaxOverlap = getMaxOverlapFunction(targetLyr, srcLyr, mosaicIndex);
41063
+ selectMaxOverlap = getMaxOverlapFunction(targetLyr, mosaicIndex);
41064
+ }
41065
+ if (opts.min_overlap_pct) {
41066
+ minPctFilter = getMinPctFunction(opts.min_overlap_pct, targetLyr, mosaicIndex);
41067
+ }
41068
+ if (opts.min_overlap_area) {
41069
+ minAreaFilter = getMinAreaFunction(opts.min_overlap_area, targetLyr, mosaicIndex);
40915
41070
  }
40916
41071
 
40917
41072
  return function(targId) {
@@ -40926,6 +41081,12 @@ ${svg}
40926
41081
  if (sourceIds.length > 1 && opts.largest_overlap) {
40927
41082
  sourceIds = selectMaxOverlap(targId, sourceIds);
40928
41083
  }
41084
+ if (minAreaFilter) {
41085
+ sourceIds = minAreaFilter(targId, sourceIds);
41086
+ }
41087
+ if (minPctFilter) {
41088
+ sourceIds = minPctFilter(targId, sourceIds);
41089
+ }
40929
41090
  return sourceIds;
40930
41091
  };
40931
41092
  }
@@ -44443,7 +44604,7 @@ ${svg}
44443
44604
  };
44444
44605
 
44445
44606
  cmd.svgStyle = function(lyr, dataset, opts) {
44446
- var filter;
44607
+ var filterFn;
44447
44608
  if (getFeatureCount(lyr) === 0) {
44448
44609
  return;
44449
44610
  }
@@ -44451,7 +44612,10 @@ ${svg}
44451
44612
  initDataTable(lyr);
44452
44613
  }
44453
44614
  if (opts.where) {
44454
- filter = compileFeatureExpression(opts.where, lyr, dataset.arcs);
44615
+ filterFn = compileFeatureExpression(opts.where, lyr, dataset.arcs);
44616
+ }
44617
+ if (opts.clear) {
44618
+ lyr.data.getFields().filter(isSupportedSvgStyleProperty).forEach(lyr.data.deleteField, lyr.data);
44455
44619
  }
44456
44620
  Object.keys(opts).forEach(function(optName) {
44457
44621
  var svgName = optName.replace('_', '-'); // undo cli parser name conversion
@@ -44461,7 +44625,7 @@ ${svg}
44461
44625
  var strVal = opts[optName].trim();
44462
44626
  var accessor = getSymbolPropertyAccessor(strVal, svgName, lyr);
44463
44627
  getLayerDataTable(lyr).getRecords().forEach(function(rec, i) {
44464
- if (filter && !filter(i)) {
44628
+ if (filterFn && !filterFn(i)) {
44465
44629
  // make sure field exists if record is excluded by filter
44466
44630
  if (svgName in rec === false) {
44467
44631
  rec[svgName] = undefined;
@@ -45905,7 +46069,7 @@ ${svg}
45905
46069
  });
45906
46070
  }
45907
46071
 
45908
- var version = "0.6.101";
46072
+ var version = "0.6.103";
45909
46073
 
45910
46074
  // Parse command line args into commands and run them
45911
46075
  // Function takes an optional Node-style callback. A Promise is returned if no callback is given.
@@ -46598,7 +46762,7 @@ ${svg}
46598
46762
  FileTypes,
46599
46763
  FilterGeom,
46600
46764
  Frame,
46601
- FrameData,
46765
+ FrameUtils,
46602
46766
  Furniture,
46603
46767
  Geodesic,
46604
46768
  GeojsonExport,
@@ -46633,7 +46797,7 @@ ${svg}
46633
46797
  PathImport,
46634
46798
  PathRepair,
46635
46799
  PathUtils,
46636
- PixelTransform,
46800
+ // PixelTransform,
46637
46801
  PointPolygonJoin,
46638
46802
  Points,
46639
46803
  PointToGrid,