mapshaper 0.6.102 → 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/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) {
@@ -684,6 +701,10 @@
684
701
  }
685
702
  }
686
703
 
704
+ function pickOne(arr) {
705
+ return arr[Math.floor(Math.random() * arr.length)];
706
+ }
707
+
687
708
  // Sort an array of objects based on one or more properties.
688
709
  // Usage: sortOn(array, key1, asc?[, key2, asc? ...])
689
710
  //
@@ -1756,12 +1777,29 @@
1756
1777
  return count;
1757
1778
  }
1758
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
+
1759
1788
  function getPointBounds$1(shapes) {
1760
- var bounds = new Bounds();
1761
- forEachPoint(shapes, function(p) {
1762
- bounds.mergePoint(p[0], p[1]);
1763
- });
1764
- 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();
1765
1803
  }
1766
1804
 
1767
1805
  function getPointFeatureBounds(shape, bounds) {
@@ -3715,20 +3753,6 @@
3715
3753
  findMaxPartCount: findMaxPartCount
3716
3754
  });
3717
3755
 
3718
- // Several dependencies are loaded via require() ... this module returns a
3719
- // stub function when require() does not exist as a global function,
3720
- // to avoid runtime errors (this should only happen in some tests when single
3721
- // modules are imported)
3722
- var f;
3723
- if (typeof require == 'function') {
3724
- f = require;
3725
- } else {
3726
- f = function() {
3727
- // console.error('Unable to load module', name);
3728
- };
3729
- }
3730
- var require$1 = f;
3731
-
3732
3756
  var iconv = require$1('iconv-lite');
3733
3757
 
3734
3758
  // import iconv from 'iconv-lite';
@@ -9615,11 +9639,10 @@
9615
9639
  });
9616
9640
 
9617
9641
  // aliases for shorter compressed code (most minifers don't do this)
9618
- var u8 = Uint8Array, u16 = Uint16Array, u32 = Uint32Array;
9642
+ var u8 = Uint8Array, u16 = Uint16Array, i32 = Int32Array;
9619
9643
  // fixed length extra bits
9620
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]);
9621
9645
  // fixed distance extra bits
9622
- // see fleb note
9623
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]);
9624
9647
  // code length index map
9625
9648
  var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
@@ -9630,26 +9653,26 @@
9630
9653
  b[i] = start += 1 << eb[i - 1];
9631
9654
  }
9632
9655
  // numbers here are at max 18 bits
9633
- var r = new u32(b[30]);
9656
+ var r = new i32(b[30]);
9634
9657
  for (var i = 1; i < 30; ++i) {
9635
9658
  for (var j = b[i]; j < b[i + 1]; ++j) {
9636
9659
  r[j] = ((j - b[i]) << 5) | i;
9637
9660
  }
9638
9661
  }
9639
- return [b, r];
9662
+ return { b: b, r: r };
9640
9663
  };
9641
- var _a = freb(fleb, 2), fl = _a[0], revfl = _a[1];
9664
+ var _a = freb(fleb, 2), fl = _a.b, revfl = _a.r;
9642
9665
  // we can ignore the fact that the other numbers are wrong; they never happen anyway
9643
9666
  fl[28] = 258, revfl[258] = 28;
9644
- var _b = freb(fdeb, 0), fd = _b[0], revfd = _b[1];
9667
+ var _b = freb(fdeb, 0), fd = _b.b, revfd = _b.r;
9645
9668
  // map of value to reverse (assuming 16 bits)
9646
9669
  var rev = new u16(32768);
9647
9670
  for (var i = 0; i < 32768; ++i) {
9648
9671
  // reverse table algorithm from SO
9649
- var x = ((i & 0xAAAA) >>> 1) | ((i & 0x5555) << 1);
9650
- x = ((x & 0xCCCC) >>> 2) | ((x & 0x3333) << 2);
9651
- x = ((x & 0xF0F0) >>> 4) | ((x & 0x0F0F) << 4);
9652
- 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;
9653
9676
  }
9654
9677
  // create huffman tree from u8 "map": index -> code length for code index
9655
9678
  // mb (max bits) must be at most 15
@@ -9667,7 +9690,7 @@
9667
9690
  }
9668
9691
  // u16 "map": index -> minimum code for bit length = index
9669
9692
  var le = new u16(mb);
9670
- for (i = 0; i < mb; ++i) {
9693
+ for (i = 1; i < mb; ++i) {
9671
9694
  le[i] = (le[i - 1] + l[i - 1]) << 1;
9672
9695
  }
9673
9696
  var co;
@@ -9688,7 +9711,7 @@
9688
9711
  // m is end value
9689
9712
  for (var m = v | ((1 << r_1) - 1); v <= m; ++v) {
9690
9713
  // every 16 bit value starting with the code yields the same result
9691
- co[rev[v] >>> rvb] = sv;
9714
+ co[rev[v] >> rvb] = sv;
9692
9715
  }
9693
9716
  }
9694
9717
  }
@@ -9697,7 +9720,7 @@
9697
9720
  co = new u16(s);
9698
9721
  for (i = 0; i < s; ++i) {
9699
9722
  if (cd[i]) {
9700
- co[i] = rev[le[cd[i] - 1]++] >>> (15 - cd[i]);
9723
+ co[i] = rev[le[cd[i] - 1]++] >> (15 - cd[i]);
9701
9724
  }
9702
9725
  }
9703
9726
  }
@@ -9750,9 +9773,7 @@
9750
9773
  if (e == null || e > v.length)
9751
9774
  e = v.length;
9752
9775
  // can't use .constructor in case user-supplied
9753
- var n = new (v.BYTES_PER_ELEMENT == 2 ? u16 : v.BYTES_PER_ELEMENT == 4 ? u32 : u8)(e - s);
9754
- n.set(v.subarray(s, e));
9755
- return n;
9776
+ return new u8(v.subarray(s, e));
9756
9777
  };
9757
9778
  // error codes
9758
9779
  var ec = [
@@ -9782,19 +9803,18 @@
9782
9803
  return e;
9783
9804
  };
9784
9805
  // expands raw DEFLATE data
9785
- var inflt = function (dat, buf, st) {
9786
- // source length
9787
- var sl = dat.length;
9788
- 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)
9789
9810
  return buf || new u8(0);
9811
+ var noBuf = !buf;
9790
9812
  // have to estimate size
9791
- var noBuf = !buf || st;
9813
+ var resize = noBuf || st.i != 2;
9792
9814
  // no state
9793
- var noSt = !st || st.i;
9794
- if (!st)
9795
- st = {};
9815
+ var noSt = st.i;
9796
9816
  // Assumes roughly 33% compression ratio average
9797
- if (!buf)
9817
+ if (noBuf)
9798
9818
  buf = new u8(sl * 3);
9799
9819
  // ensure buffer can fit at least l elements
9800
9820
  var cbuf = function (l) {
@@ -9827,7 +9847,7 @@
9827
9847
  break;
9828
9848
  }
9829
9849
  // ensure size
9830
- if (noBuf)
9850
+ if (resize)
9831
9851
  cbuf(bt + l);
9832
9852
  // Copy over uncompressed data
9833
9853
  buf.set(dat.subarray(s, t), bt);
@@ -9860,7 +9880,7 @@
9860
9880
  // bits read
9861
9881
  pos += r & 15;
9862
9882
  // symbol
9863
- var s = r >>> 4;
9883
+ var s = r >> 4;
9864
9884
  // code length to copy
9865
9885
  if (s < 16) {
9866
9886
  ldt[i++] = s;
@@ -9896,14 +9916,14 @@
9896
9916
  }
9897
9917
  }
9898
9918
  // Make sure the buffer can hold this + the largest possible addition
9899
- // Maximum chunk size (practically, theoretically infinite) is 2^17;
9900
- if (noBuf)
9919
+ // Maximum chunk size (practically, theoretically infinite) is 2^17
9920
+ if (resize)
9901
9921
  cbuf(bt + 131072);
9902
9922
  var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;
9903
9923
  var lpos = pos;
9904
9924
  for (;; lpos = pos) {
9905
9925
  // bits read, code
9906
- var c = lm[bits16(dat, pos) & lms], sym = c >>> 4;
9926
+ var c = lm[bits16(dat, pos) & lms], sym = c >> 4;
9907
9927
  pos += c & 15;
9908
9928
  if (pos > tbts) {
9909
9929
  if (noSt)
@@ -9928,52 +9948,55 @@
9928
9948
  pos += b;
9929
9949
  }
9930
9950
  // dist
9931
- var d = dm[bits16(dat, pos) & dms], dsym = d >>> 4;
9951
+ var d = dm[bits16(dat, pos) & dms], dsym = d >> 4;
9932
9952
  if (!d)
9933
9953
  err(3);
9934
9954
  pos += d & 15;
9935
9955
  var dt = fd[dsym];
9936
9956
  if (dsym > 3) {
9937
9957
  var b = fdeb[dsym];
9938
- dt += bits16(dat, pos) & ((1 << b) - 1), pos += b;
9958
+ dt += bits16(dat, pos) & (1 << b) - 1, pos += b;
9939
9959
  }
9940
9960
  if (pos > tbts) {
9941
9961
  if (noSt)
9942
9962
  err(0);
9943
9963
  break;
9944
9964
  }
9945
- if (noBuf)
9965
+ if (resize)
9946
9966
  cbuf(bt + 131072);
9947
9967
  var end = bt + add;
9948
- for (; bt < end; bt += 4) {
9949
- buf[bt] = buf[bt - dt];
9950
- buf[bt + 1] = buf[bt + 1 - dt];
9951
- buf[bt + 2] = buf[bt + 2 - dt];
9952
- 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];
9953
9974
  }
9954
- bt = end;
9975
+ for (; bt < end; ++bt)
9976
+ buf[bt] = buf[bt - dt];
9955
9977
  }
9956
9978
  }
9957
9979
  st.l = lm, st.p = lpos, st.b = bt, st.f = final;
9958
9980
  if (lm)
9959
9981
  final = 1, st.m = lbt, st.d = dm, st.n = dbt;
9960
9982
  } while (!final);
9961
- 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);
9962
9985
  };
9963
9986
  // starting at p, write the minimum number of bits that can hold v to d
9964
9987
  var wbits = function (d, p, v) {
9965
9988
  v <<= p & 7;
9966
9989
  var o = (p / 8) | 0;
9967
9990
  d[o] |= v;
9968
- d[o + 1] |= v >>> 8;
9991
+ d[o + 1] |= v >> 8;
9969
9992
  };
9970
9993
  // starting at p, write the minimum number of bits (>8) that can hold v to d
9971
9994
  var wbits16 = function (d, p, v) {
9972
9995
  v <<= p & 7;
9973
9996
  var o = (p / 8) | 0;
9974
9997
  d[o] |= v;
9975
- d[o + 1] |= v >>> 8;
9976
- d[o + 2] |= v >>> 16;
9998
+ d[o + 1] |= v >> 8;
9999
+ d[o + 2] |= v >> 16;
9977
10000
  };
9978
10001
  // creates code lengths from a frequency table
9979
10002
  var hTree = function (d, mb) {
@@ -9986,11 +10009,11 @@
9986
10009
  var s = t.length;
9987
10010
  var t2 = t.slice();
9988
10011
  if (!s)
9989
- return [et, 0];
10012
+ return { t: et, l: 0 };
9990
10013
  if (s == 1) {
9991
10014
  var v = new u8(t[0].s + 1);
9992
10015
  v[t[0].s] = 1;
9993
- return [v, 1];
10016
+ return { t: v, l: 1 };
9994
10017
  }
9995
10018
  t.sort(function (a, b) { return a.f - b.f; });
9996
10019
  // after i2 reaches last ind, will be stopped
@@ -10034,7 +10057,7 @@
10034
10057
  else
10035
10058
  break;
10036
10059
  }
10037
- dt >>>= lft;
10060
+ dt >>= lft;
10038
10061
  while (dt > 0) {
10039
10062
  var i2_2 = t2[i].s;
10040
10063
  if (tr[i2_2] < mb)
@@ -10051,7 +10074,7 @@
10051
10074
  }
10052
10075
  mbt = mb;
10053
10076
  }
10054
- return [new u8(tr), mbt];
10077
+ return { t: new u8(tr), l: mbt };
10055
10078
  };
10056
10079
  // get the max length and assign length codes
10057
10080
  var ln = function (n, l, d) {
@@ -10094,7 +10117,7 @@
10094
10117
  cln = c[i];
10095
10118
  }
10096
10119
  }
10097
- return [cl.subarray(0, cli), s];
10120
+ return { c: cl.subarray(0, cli), n: s };
10098
10121
  };
10099
10122
  // calculate the length of output from tree, code lengths
10100
10123
  var clen = function (cf, cl) {
@@ -10110,7 +10133,7 @@
10110
10133
  var s = dat.length;
10111
10134
  var o = shft(pos + 2);
10112
10135
  out[o] = s & 255;
10113
- out[o + 1] = s >>> 8;
10136
+ out[o + 1] = s >> 8;
10114
10137
  out[o + 2] = out[o] ^ 255;
10115
10138
  out[o + 3] = out[o + 1] ^ 255;
10116
10139
  for (var i = 0; i < s; ++i)
@@ -10121,23 +10144,23 @@
10121
10144
  var wblk = function (dat, out, final, syms, lf, df, eb, li, bs, bl, p) {
10122
10145
  wbits(out, p++, final);
10123
10146
  ++lf[256];
10124
- var _a = hTree(lf, 15), dlt = _a[0], mlb = _a[1];
10125
- var _b = hTree(df, 15), ddt = _b[0], mdb = _b[1];
10126
- var _c = lc(dlt), lclt = _c[0], nlc = _c[1];
10127
- 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;
10128
10151
  var lcfreq = new u16(19);
10129
10152
  for (var i = 0; i < lclt.length; ++i)
10130
- lcfreq[lclt[i] & 31]++;
10153
+ ++lcfreq[lclt[i] & 31];
10131
10154
  for (var i = 0; i < lcdt.length; ++i)
10132
- lcfreq[lcdt[i] & 31]++;
10133
- 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;
10134
10157
  var nlcc = 19;
10135
10158
  for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc)
10136
10159
  ;
10137
10160
  var flen = (bl + 5) << 3;
10138
10161
  var ftlen = clen(lf, flt) + clen(df, fdt) + eb;
10139
- var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + (2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18]);
10140
- 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)
10141
10164
  return wfblk(out, p, dat.subarray(bs, bs + bl));
10142
10165
  var lm, ll, dm, dl;
10143
10166
  wbits(out, p, 1 + (dtlen < ftlen)), p += 2;
@@ -10158,7 +10181,7 @@
10158
10181
  var len = clct[i] & 31;
10159
10182
  wbits(out, p, llm[len]), p += lct[len];
10160
10183
  if (len > 15)
10161
- wbits(out, p, (clct[i] >>> 5) & 127), p += clct[i] >>> 12;
10184
+ wbits(out, p, (clct[i] >> 5) & 127), p += clct[i] >> 12;
10162
10185
  }
10163
10186
  }
10164
10187
  }
@@ -10166,63 +10189,55 @@
10166
10189
  lm = flm, ll = flt, dm = fdm, dl = fdt;
10167
10190
  }
10168
10191
  for (var i = 0; i < li; ++i) {
10169
- if (syms[i] > 255) {
10170
- var len = (syms[i] >>> 18) & 31;
10192
+ var sym = syms[i];
10193
+ if (sym > 255) {
10194
+ var len = (sym >> 18) & 31;
10171
10195
  wbits16(out, p, lm[len + 257]), p += ll[len + 257];
10172
10196
  if (len > 7)
10173
- wbits(out, p, (syms[i] >>> 23) & 31), p += fleb[len];
10174
- var dst = syms[i] & 31;
10197
+ wbits(out, p, (sym >> 23) & 31), p += fleb[len];
10198
+ var dst = sym & 31;
10175
10199
  wbits16(out, p, dm[dst]), p += dl[dst];
10176
10200
  if (dst > 3)
10177
- wbits16(out, p, (syms[i] >>> 5) & 8191), p += fdeb[dst];
10201
+ wbits16(out, p, (sym >> 5) & 8191), p += fdeb[dst];
10178
10202
  }
10179
10203
  else {
10180
- wbits16(out, p, lm[syms[i]]), p += ll[syms[i]];
10204
+ wbits16(out, p, lm[sym]), p += ll[sym];
10181
10205
  }
10182
10206
  }
10183
10207
  wbits16(out, p, lm[256]);
10184
10208
  return p + ll[256];
10185
10209
  };
10186
10210
  // deflate options (nice << 13) | chain
10187
- 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]);
10188
10212
  // empty
10189
10213
  var et = /*#__PURE__*/ new u8(0);
10190
10214
  // compresses data into a raw DEFLATE buffer
10191
- var dflt = function (dat, lvl, plvl, pre, post, lst) {
10192
- var s = dat.length;
10215
+ var dflt = function (dat, lvl, plvl, pre, post, st) {
10216
+ var s = st.z || dat.length;
10193
10217
  var o = new u8(pre + s + 5 * (1 + Math.ceil(s / 7000)) + post);
10194
10218
  // writing to this writes to the output buffer
10195
10219
  var w = o.subarray(pre, o.length - post);
10196
- var pos = 0;
10197
- if (!lvl || s < 8) {
10198
- for (var i = 0; i <= s; i += 65535) {
10199
- // end
10200
- var e = i + 65535;
10201
- if (e >= s) {
10202
- // write final block
10203
- w[pos >> 3] = lst;
10204
- }
10205
- pos = wfblk(w, pos + 1, dat.subarray(i, e));
10206
- }
10207
- }
10208
- 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;
10209
10225
  var opt = deo[lvl - 1];
10210
- var n = opt >>> 13, c = opt & 8191;
10226
+ var n = opt >> 13, c = opt & 8191;
10211
10227
  var msk_1 = (1 << plvl) - 1;
10212
10228
  // prev 2-byte val map curr 2-byte val map
10213
- 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);
10214
10230
  var bs1_1 = Math.ceil(plvl / 3), bs2_1 = 2 * bs1_1;
10215
10231
  var hsh = function (i) { return (dat[i] ^ (dat[i + 1] << bs1_1) ^ (dat[i + 2] << bs2_1)) & msk_1; };
10216
10232
  // 24576 is an arbitrary number of maximum symbols per block
10217
10233
  // 424 buffer for last block
10218
- var syms = new u32(25000);
10234
+ var syms = new i32(25000);
10219
10235
  // length/literal freq distance freq
10220
10236
  var lf = new u16(288), df = new u16(32);
10221
- // l/lcnt exbits index l/lind waitdx bitpos
10222
- var lc_1 = 0, eb = 0, i = 0, li = 0, wi = 0, bs = 0;
10223
- 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) {
10224
10240
  // hash value
10225
- // deopt when i > s - 3 - at end, deopt acceptable
10226
10241
  var hv = hsh(i);
10227
10242
  // index mod 32768 previous index mod
10228
10243
  var imod = i & 32767, pimod = head[hv];
@@ -10233,7 +10248,7 @@
10233
10248
  if (wi <= i) {
10234
10249
  // bytes remaining
10235
10250
  var rem = s - i;
10236
- if ((lc_1 > 7000 || li > 24576) && rem > 423) {
10251
+ if ((lc_1 > 7000 || li > 24576) && (rem > 423 || !lst)) {
10237
10252
  pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i - bs, pos);
10238
10253
  li = lc_1 = eb = 0, bs = i;
10239
10254
  for (var j = 0; j < 286; ++j)
@@ -10242,7 +10257,7 @@
10242
10257
  df[j] = 0;
10243
10258
  }
10244
10259
  // len dist chain
10245
- 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;
10246
10261
  if (rem > 2 && hv == hsh(i - dif)) {
10247
10262
  var maxn = Math.min(n, rem) - 1;
10248
10263
  var maxd = Math.min(32767, i);
@@ -10265,9 +10280,9 @@
10265
10280
  var mmd = Math.min(dif, nl - 2);
10266
10281
  var md = 0;
10267
10282
  for (var j = 0; j < mmd; ++j) {
10268
- var ti = (i - dif + j + 32768) & 32767;
10283
+ var ti = i - dif + j & 32767;
10269
10284
  var pti = prev[ti];
10270
- var cd = (ti - pti + 32768) & 32767;
10285
+ var cd = ti - pti & 32767;
10271
10286
  if (cd > md)
10272
10287
  md = cd, pimod = ti;
10273
10288
  }
@@ -10275,12 +10290,12 @@
10275
10290
  }
10276
10291
  // check the previous match
10277
10292
  imod = pimod, pimod = prev[imod];
10278
- dif += (imod - pimod + 32768) & 32767;
10293
+ dif += imod - pimod & 32767;
10279
10294
  }
10280
10295
  }
10281
10296
  // d will be nonzero only when a match was found
10282
10297
  if (d) {
10283
- // store both dist and len data in one Uint32
10298
+ // store both dist and len data in one int32
10284
10299
  // Make sure this is recognized as a len/dist with 28th bit (2^28)
10285
10300
  syms[li++] = 268435456 | (revfl[l] << 18) | revfd[d];
10286
10301
  var lin = revfl[l] & 31, din = revfd[d] & 31;
@@ -10296,10 +10311,30 @@
10296
10311
  }
10297
10312
  }
10298
10313
  }
10314
+ for (i = Math.max(i, wi); i < s; ++i) {
10315
+ syms[li++] = dat[i];
10316
+ ++lf[dat[i]];
10317
+ }
10299
10318
  pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i - bs, pos);
10300
- // this is the easiest way to avoid needing to maintain state
10301
- if (!lst && pos & 7)
10302
- 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;
10303
10338
  }
10304
10339
  return slc(o, 0, pre + shft(pos) + post);
10305
10340
  };
@@ -10330,7 +10365,18 @@
10330
10365
  };
10331
10366
  // deflate with opts
10332
10367
  var dopt = function (dat, opt, pre, post, st) {
10333
- 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);
10334
10380
  };
10335
10381
  // Walmart object spread
10336
10382
  var mrg = function (a, b) {
@@ -10375,7 +10421,7 @@
10375
10421
  else
10376
10422
  td[k] = v;
10377
10423
  }
10378
- return [fnStr, td];
10424
+ return fnStr;
10379
10425
  };
10380
10426
  var ch = [];
10381
10427
  // clone bufs
@@ -10390,27 +10436,29 @@
10390
10436
  };
10391
10437
  // use a worker to execute code
10392
10438
  var wrkr = function (fns, init, id, cb) {
10393
- var _a;
10394
10439
  if (!ch[id]) {
10395
10440
  var fnStr = '', td_1 = {}, m = fns.length - 1;
10396
10441
  for (var i = 0; i < m; ++i)
10397
- _a = wcln(fns[i], fnStr, td_1), fnStr = _a[0], td_1 = _a[1];
10398
- 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 };
10399
10444
  }
10400
- var td = mrg({}, ch[id][1]);
10401
- 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);
10402
10447
  };
10403
10448
  // base async inflate fn
10404
- 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]; };
10405
- 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]; };
10406
10451
  // gzip extra
10407
10452
  var gze = function () { return [gzh, gzhl, wbytes, crc, crct]; };
10408
10453
  // gunzip extra
10409
10454
  var guze = function () { return [gzs, gzl]; };
10410
10455
  // post buf
10411
10456
  var pbf = function (msg) { return postMessage(msg, [msg.buffer]); };
10412
- // get u8
10413
- 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
+ }; };
10414
10462
  // async helper
10415
10463
  var cbify = function (dat, opts, fns, init, id, cb) {
10416
10464
  var w = wrkr(fns, init, id, function (err, dat) {
@@ -10450,7 +10498,7 @@
10450
10498
  var flg = d[3];
10451
10499
  var st = 10;
10452
10500
  if (flg & 4)
10453
- st += d[10] | (d[11] << 8) + 2;
10501
+ st += (d[10] | d[11] << 8) + 2;
10454
10502
  for (var zs = (flg >> 3 & 1) + (flg >> 4 & 1); zs > 0; zs -= !d[st++])
10455
10503
  ;
10456
10504
  return st + (flg & 2);
@@ -10458,10 +10506,10 @@
10458
10506
  // gzip length
10459
10507
  var gzl = function (d) {
10460
10508
  var l = d.length;
10461
- 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;
10462
10510
  };
10463
10511
  // gzip header length
10464
- 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); };
10465
10513
  function deflate(data, opts, cb) {
10466
10514
  if (!cb)
10467
10515
  cb = opts, opts = {};
@@ -10487,16 +10535,16 @@
10487
10535
  err(7);
10488
10536
  return cbify(data, opts, [
10489
10537
  bInflt
10490
- ], 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);
10491
10539
  }
10492
10540
  /**
10493
10541
  * Expands DEFLATE data with no wrapper
10494
10542
  * @param data The data to decompress
10495
- * @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
10496
10544
  * @returns The decompressed version of the data
10497
10545
  */
10498
- function inflateSync(data, out) {
10499
- return inflt(data, out);
10546
+ function inflateSync(data, opts) {
10547
+ return inflt(data, { i: 2 }, opts && opts.out, opts && opts.dictionary);
10500
10548
  }
10501
10549
  function gzip(data, opts, cb) {
10502
10550
  if (!cb)
@@ -10532,16 +10580,19 @@
10532
10580
  bInflt,
10533
10581
  guze,
10534
10582
  function () { return [gunzipSync$1]; }
10535
- ], 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);
10536
10584
  }
10537
10585
  /**
10538
10586
  * Expands GZIP data
10539
10587
  * @param data The data to decompress
10540
- * @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
10541
10589
  * @returns The decompressed version of the data
10542
10590
  */
10543
- function gunzipSync$1(data, out) {
10544
- 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);
10545
10596
  }
10546
10597
  // flatten a directory structure
10547
10598
  var fltn = function (d, p, t, o) {
@@ -10574,7 +10625,7 @@
10574
10625
  var c = d[i++];
10575
10626
  var eb = (c > 127) + (c > 223) + (c > 239);
10576
10627
  if (i + eb > d.length)
10577
- return [r, slc(d, i - 1)];
10628
+ return { s: r, r: slc(d, i - 1) };
10578
10629
  if (!eb)
10579
10630
  r += String.fromCharCode(c);
10580
10631
  else if (eb == 3) {
@@ -10640,13 +10691,14 @@
10640
10691
  r += String.fromCharCode.apply(null, dat.subarray(i, i + 16384));
10641
10692
  return r;
10642
10693
  }
10643
- else if (td)
10694
+ else if (td) {
10644
10695
  return td.decode(dat);
10696
+ }
10645
10697
  else {
10646
- var _a = dutf8(dat), out = _a[0], ext = _a[1];
10647
- if (ext.length)
10698
+ var _a = dutf8(dat), s = _a.s, r = _a.r;
10699
+ if (r.length)
10648
10700
  err(8);
10649
- return out;
10701
+ return s;
10650
10702
  }
10651
10703
  }
10652
10704
  // skip local zip header
@@ -10689,7 +10741,7 @@
10689
10741
  var dt = new Date(f.mtime == null ? Date.now() : f.mtime), y = dt.getFullYear() - 1980;
10690
10742
  if (y < 0 || y > 119)
10691
10743
  err(10);
10692
- 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;
10693
10745
  if (c != -1) {
10694
10746
  wbytes(d, b, f.crc);
10695
10747
  wbytes(d, b + 4, c < 0 ? -c - 2 : c);
@@ -10929,9 +10981,10 @@
10929
10981
  cbl(null, slc(data, b, b + sc));
10930
10982
  else if (c_1 == 8) {
10931
10983
  var infl = data.subarray(b, b + sc);
10932
- if (sc < 320000) {
10984
+ // Synchronously decompress under 512KB, or barely-compressed data
10985
+ if (su < 524288 || sc > 0.8 * su) {
10933
10986
  try {
10934
- cbl(null, inflateSync(infl, new u8(su)));
10987
+ cbl(null, inflateSync(infl, { out: new u8(su) }));
10935
10988
  }
10936
10989
  catch (e) {
10937
10990
  cbl(e, null);
@@ -10994,7 +11047,7 @@
10994
11047
  if (!c_2)
10995
11048
  files[fn] = slc(data, b, b + sc);
10996
11049
  else if (c_2 == 8)
10997
- files[fn] = inflateSync(data.subarray(b, b + sc), new u8(su));
11050
+ files[fn] = inflateSync(data.subarray(b, b + sc), { out: new u8(su) });
10998
11051
  else
10999
11052
  err(14, 'unknown compression type ' + c_2);
11000
11053
  }
@@ -20693,7 +20746,7 @@ ${svg}
20693
20746
  // import { isKmzFile } from '../io/mapshaper-file-types';
20694
20747
 
20695
20748
  function exportKML(dataset, opts) {
20696
- var toKML = require("@placemarkio/tokml").toKML;
20749
+ var toKML = require$1("@placemarkio/tokml").toKML;
20697
20750
  var geojsonOpts = Object.assign({combine_layers: true, geojson_type: 'FeatureCollection'}, opts);
20698
20751
  var geojson = exportDatasetAsGeoJSON(dataset, geojsonOpts);
20699
20752
  var kml = toKML(geojson);
@@ -25316,6 +25369,14 @@ ${svg}
25316
25369
  describe: '(polygon-polygon join) use max overlap to join one polygon',
25317
25370
  type: 'flag'
25318
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
+ })
25319
25380
  // .option('nearest-point', {
25320
25381
  // describe: '(point-point join)',
25321
25382
  // type: 'flag'
@@ -25754,6 +25815,10 @@ ${svg}
25754
25815
  parser.command('style')
25755
25816
  .oldAlias('svg-style')
25756
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
+ })
25757
25822
  .option('where', whereOpt)
25758
25823
  .option('class', {
25759
25824
  describe: 'name of CSS class or classes (space-separated)'
@@ -33394,18 +33459,22 @@ ${svg}
33394
33459
  function getCategoricalClassifier(classValues, nullVal, opts) {
33395
33460
  // categories: strings to match in the data
33396
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
+ }, {});
33397
33467
  var classToValue = getDiscreteValueGetter(classValues, nullVal, opts.other);
33398
33468
  return function(val) {
33399
- var i = categories.indexOf(val);
33400
- var idx = -1;
33401
- if (i >= 0) {
33402
- idx = i;
33403
- } else if (val) {
33404
- 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
33405
33474
  } else {
33406
- idx = -1; // field is empty (null value)
33475
+ i = -1; // field is empty (null value)
33407
33476
  }
33408
- return classToValue(idx);
33477
+ return classToValue(i);
33409
33478
  };
33410
33479
  }
33411
33480
 
@@ -34274,7 +34343,6 @@ ${svg}
34274
34343
  addCategoricalScheme('Tableau20',
34275
34344
  '4c78a89ecae9f58518ffbf7954a24b88d27ab79a20f2cf5b43989483bcb6e45756ff9d9879706ebab0acd67195fcbfd2b279a2d6a5c99e765fd8b5a5');
34276
34345
  index.all = [].concat(index.sequential, index.rainbow, index.diverging, index.categorical);
34277
-
34278
34346
  }
34279
34347
 
34280
34348
  function standardName(name) {
@@ -34288,8 +34356,15 @@ ${svg}
34288
34356
  return null;
34289
34357
  }
34290
34358
 
34291
- function addSchemesFromD3(type, names) {
34292
- 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
+ }
34293
34368
  }
34294
34369
 
34295
34370
  function addCategoricalScheme(name, str) {
@@ -34343,16 +34418,14 @@ ${svg}
34343
34418
  initSchemes();
34344
34419
  var names = index[type];
34345
34420
  if (!names) error('Unknown color scheme type:', type);
34346
- var i = Math.floor(Math.random() * names.length);
34347
- return names[i];
34421
+ return utils.pickOne(names);
34348
34422
  }
34349
34423
 
34350
- function getRandomColors(n) {
34424
+ function pickRandomCategoricalScheme(n) {
34351
34425
  initSchemes();
34352
- var colors = getCategoricalColorScheme('Tableau20', 20);
34353
- utils.shuffle(colors);
34354
- colors = wrapColors(colors, n);
34355
- 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';
34356
34429
  }
34357
34430
 
34358
34431
  function getCategoricalColorScheme(name, n) {
@@ -34461,10 +34534,11 @@ ${svg}
34461
34534
 
34462
34535
  if (colorArg == 'random') {
34463
34536
  if (categorical) {
34464
- return getRandomColors(n);
34537
+ colorScheme = pickRandomCategoricalScheme(n);
34538
+ } else {
34539
+ colorScheme = pickRandomColorScheme('sequential');
34465
34540
  }
34466
- colorScheme = pickRandomColorScheme('sequential');
34467
- message('Randomly selected color ramp:', colorScheme);
34541
+ message('Randomly selected color scheme:', colorScheme);
34468
34542
  } else if (isColorSchemeName(colorArg)) {
34469
34543
  colorScheme = colorArg;
34470
34544
  } else if (colorArg && !parseColor(colorArg)) {
@@ -36717,7 +36791,7 @@ ${svg}
36717
36791
 
36718
36792
  // Join data from @src table to records in @destLyr layer.
36719
36793
  // @join function
36720
- // Receives index of record in the dest table
36794
+ // Receives index of one record in the dest table
36721
36795
  // Returns array of matching records in src table, or null if no matches
36722
36796
  //
36723
36797
  function joinTableToLayer(destLyr, src, join, opts) {
@@ -36743,7 +36817,7 @@ ${svg}
36743
36817
  collisionFields = [],
36744
36818
  skipCount = 0,
36745
36819
  retn = {},
36746
- srcRec, srcId, destRec, joins, count, filter, calc, i, j, n, m;
36820
+ srcRec, srcId, destRec, joinIds, count, filter, calc, i, j, n, m;
36747
36821
 
36748
36822
  // support for duplication of destination records for many-to-one joins
36749
36823
  var duplicateRecords, destShapes;
@@ -36765,14 +36839,14 @@ ${svg}
36765
36839
  n = destRecords.length;
36766
36840
  for (i=0; i<n; i++) {
36767
36841
  destRec = destRecords[i];
36768
- joins = join(i);
36769
- if (joins && filter) {
36770
- skipCount += joins.length;
36771
- joins = filter(joins, destRec);
36772
- skipCount -= joins.length;
36773
- }
36774
- for (j=0, count=0, m=joins ? joins.length : 0; j<m; j++) {
36775
- 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];
36776
36850
  srcRec = srcRecords[srcId];
36777
36851
  // duplication mode: many-to-one joins add new features to the target layer.
36778
36852
  if (count > 0 && useDuplication) {
@@ -36798,7 +36872,7 @@ ${svg}
36798
36872
  count++;
36799
36873
  }
36800
36874
  if (calc) {
36801
- calc(joins, destRec);
36875
+ calc(joinIds, destRec);
36802
36876
  }
36803
36877
  if (count > 0) {
36804
36878
  matchCount++;
@@ -40758,11 +40832,14 @@ ${svg}
40758
40832
  };
40759
40833
  // make a mosaic from merged shapes of both layers
40760
40834
  var mosaicIndex = new MosaicIndex(mergedLyr, nodes, {flat: false});
40761
-
40762
40835
  var joinOpts = utils.extend({}, opts);
40763
- var joinFunction = getPolygonToPolygonFunction(targetLyr, sourceLyr, mosaicIndex, opts);
40764
- 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
+ }
40765
40840
 
40841
+ var joinFunction = getPolygonToPolygonFunction(targetLyr, sourceLyr, mosaicIndex, joinOpts);
40842
+ var retn = joinTableToLayer(targetLyr, sourceLyr.data, joinFunction, joinOpts);
40766
40843
  if (opts.interpolate) {
40767
40844
  if (opts.duplication) stop('duplication and interpolate options cannot be used together');
40768
40845
  interpolateFieldsByArea(targetLyr, sourceLyr, mosaicIndex, opts);
@@ -40776,6 +40853,22 @@ ${svg}
40776
40853
  var sourceFields = opts.interpolate;
40777
40854
  var sourceRecords = sourceLyr.data.getRecords();
40778
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
+
40779
40872
  // for each destination polygon, calculate interpolated values,
40780
40873
  // using the data calculated in previous steps
40781
40874
  destLyr.data.getRecords().forEach(function(destRec, destId) {
@@ -40784,9 +40877,13 @@ ${svg}
40784
40877
  for (i=0; i<tileIds.length; i++) {
40785
40878
  tileRecords.push(mosaicRecords[tileIds[i]]);
40786
40879
  }
40787
- for (i=0; i<sourceFields.length; i++) {
40880
+ for (i=0; i<quantitativeFields.length; i++) {
40788
40881
  field = sourceFields[i];
40789
- 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);
40790
40887
  }
40791
40888
  });
40792
40889
  }
@@ -40839,7 +40936,7 @@ ${svg}
40839
40936
  // return value;
40840
40937
  // }
40841
40938
 
40842
- function getInterpolatedValue(field, tileRecords, sourceRecords) {
40939
+ function getInterpolatedNumber(field, tileRecords, sourceRecords) {
40843
40940
  var value = 0, tileRec, sourceRec, sourceId;
40844
40941
  for (var i=0; i<tileRecords.length; i++) {
40845
40942
  tileRec = tileRecords[i];
@@ -40853,6 +40950,31 @@ ${svg}
40853
40950
  return value;
40854
40951
  }
40855
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
+
40856
40978
 
40857
40979
  function getIdConversionFunction(offset, length) {
40858
40980
  return function (mergedIds) {
@@ -40865,17 +40987,50 @@ ${svg}
40865
40987
  };
40866
40988
  }
40867
40989
 
40868
- function getMaxOverlapFunction(destLyr, srcLyr, mosaicIndex) {
40869
- var arcs = mosaicIndex.nodes.arcs;
40990
+ function getMinPctFunction(minPct, destLyr, mosaicIndex) {
40991
+ mosaicIndex.nodes.arcs;
40870
40992
  var destLen = destLyr.shapes.length;
40871
40993
 
40872
- function getTotalArea(tileIds) {
40873
- var area = 0;
40874
- for (var i=0; i<tileIds.length; i++) {
40875
- area += geom.getShapeArea(mosaicIndex.mosaic[tileIds[i]], arcs);
40876
- }
40877
- 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);
40878
41028
  }
41029
+ return area;
41030
+ }
41031
+
41032
+ function getMaxOverlapFunction(destLyr, mosaicIndex) {
41033
+ var destLen = destLyr.shapes.length;
40879
41034
 
40880
41035
  return function(destId, srcIds) {
40881
41036
  var destTileIds = mosaicIndex.getTileIdsByShapeId(destId);
@@ -40884,7 +41039,7 @@ ${svg}
40884
41039
  srcIds.forEach(function(srcId, i) {
40885
41040
  var srcTileIds = mosaicIndex.getTileIdsByShapeId(srcId + destLen);
40886
41041
  var sharedIds = utils.intersection(destTileIds, srcTileIds);
40887
- var area = getTotalArea(sharedIds);
41042
+ var area = getAreaOfTiles(sharedIds, mosaicIndex);
40888
41043
  if (area >= maxArea) {
40889
41044
  maxId = srcId;
40890
41045
  maxArea = area;
@@ -40897,14 +41052,21 @@ ${svg}
40897
41052
 
40898
41053
 
40899
41054
  // Returned function converts a target layer feature id to multiple source feature ids
40900
- // TODO: option to join the source polygon with the greatest overlapping area
40901
41055
  // TODO: option to ignore source polygon with small overlaps
40902
41056
  // (as a percentage of the area of one or the other polygon?)
40903
41057
  function getPolygonToPolygonFunction(targetLyr, srcLyr, mosaicIndex, opts) {
40904
41058
  var mergedToSourceIds = getIdConversionFunction(targetLyr.shapes.length, srcLyr.shapes.length);
40905
41059
  var selectMaxOverlap;
41060
+ var minAreaFilter;
41061
+ var minPctFilter;
40906
41062
  if (opts.largest_overlap) {
40907
- 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);
40908
41070
  }
40909
41071
 
40910
41072
  return function(targId) {
@@ -40919,6 +41081,12 @@ ${svg}
40919
41081
  if (sourceIds.length > 1 && opts.largest_overlap) {
40920
41082
  sourceIds = selectMaxOverlap(targId, sourceIds);
40921
41083
  }
41084
+ if (minAreaFilter) {
41085
+ sourceIds = minAreaFilter(targId, sourceIds);
41086
+ }
41087
+ if (minPctFilter) {
41088
+ sourceIds = minPctFilter(targId, sourceIds);
41089
+ }
40922
41090
  return sourceIds;
40923
41091
  };
40924
41092
  }
@@ -44436,7 +44604,7 @@ ${svg}
44436
44604
  };
44437
44605
 
44438
44606
  cmd.svgStyle = function(lyr, dataset, opts) {
44439
- var filter;
44607
+ var filterFn;
44440
44608
  if (getFeatureCount(lyr) === 0) {
44441
44609
  return;
44442
44610
  }
@@ -44444,7 +44612,10 @@ ${svg}
44444
44612
  initDataTable(lyr);
44445
44613
  }
44446
44614
  if (opts.where) {
44447
- 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);
44448
44619
  }
44449
44620
  Object.keys(opts).forEach(function(optName) {
44450
44621
  var svgName = optName.replace('_', '-'); // undo cli parser name conversion
@@ -44454,7 +44625,7 @@ ${svg}
44454
44625
  var strVal = opts[optName].trim();
44455
44626
  var accessor = getSymbolPropertyAccessor(strVal, svgName, lyr);
44456
44627
  getLayerDataTable(lyr).getRecords().forEach(function(rec, i) {
44457
- if (filter && !filter(i)) {
44628
+ if (filterFn && !filterFn(i)) {
44458
44629
  // make sure field exists if record is excluded by filter
44459
44630
  if (svgName in rec === false) {
44460
44631
  rec[svgName] = undefined;
@@ -45898,7 +46069,7 @@ ${svg}
45898
46069
  });
45899
46070
  }
45900
46071
 
45901
- var version = "0.6.102";
46072
+ var version = "0.6.103";
45902
46073
 
45903
46074
  // Parse command line args into commands and run them
45904
46075
  // Function takes an optional Node-style callback. A Promise is returned if no callback is given.