mapshaper 0.6.49 → 0.6.51

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
@@ -1,6 +1,6 @@
1
1
  (function () {
2
2
 
3
- var VERSION = "0.6.49";
3
+ var VERSION = "0.6.51";
4
4
 
5
5
 
6
6
  var utils = /*#__PURE__*/Object.freeze({
@@ -18,7 +18,7 @@
18
18
  get isNonNegNumber () { return isNonNegNumber; },
19
19
  get isInteger () { return isInteger; },
20
20
  get isEven () { return isEven; },
21
- get isOdd () { return isOdd; },
21
+ get isOdd () { return isOdd$1; },
22
22
  get isString () { return isString; },
23
23
  get isDate () { return isDate; },
24
24
  get isBoolean () { return isBoolean; },
@@ -195,7 +195,7 @@
195
195
  return (obj % 2) === 0;
196
196
  }
197
197
 
198
- function isOdd(obj) {
198
+ function isOdd$1(obj) {
199
199
  return (obj % 2) === 1;
200
200
  }
201
201
 
@@ -11259,12 +11259,6 @@
11259
11259
  return ss && ss.isFile() || false;
11260
11260
  };
11261
11261
 
11262
- cli.checkCommandEnv = function(cname) {
11263
- var blocked = ['i', 'include', 'require', 'external'];
11264
- if (runningInBrowser() && blocked.includes(cname)) {
11265
- stop('The -' + cname + ' command cannot be run in the browser');
11266
- }
11267
- };
11268
11262
 
11269
11263
  // cli.fileSize = function(path) {
11270
11264
  // var ss = cli.statSync(path);
@@ -24344,6 +24338,19 @@ ${svg}
24344
24338
  .option('name', nameOpt);
24345
24339
 
24346
24340
 
24341
+ // for testing grid update
24342
+ parser.command('grid2')
24343
+ .option('type', {
24344
+ describe: 'square, hex or hex2 (default is square)'
24345
+ })
24346
+ .option('interval', {
24347
+ describe: 'side length (e.g. 500m, 12km)',
24348
+ type: 'distance'
24349
+ })
24350
+ .option('name', nameOpt)
24351
+ .option('target', targetOpt)
24352
+ .option('no-replace', noReplaceOpt);
24353
+
24347
24354
  parser.command('grid')
24348
24355
  .describe('create a grid of square or hexagonal polygons')
24349
24356
  .option('type', {
@@ -24353,12 +24360,12 @@ ${svg}
24353
24360
  describe: 'side length (e.g. 500m, 12km)',
24354
24361
  type: 'distance'
24355
24362
  })
24356
- // .option('cols', {
24357
- // type: 'integer'
24358
- // })
24359
- // .option('rows', {
24360
- // type: 'integer'
24361
- // })
24363
+ .option('cols', {
24364
+ type: 'integer'
24365
+ })
24366
+ .option('rows', {
24367
+ type: 'integer'
24368
+ })
24362
24369
  // .option('bbox', {
24363
24370
  // type: 'bbox',
24364
24371
  // describe: 'xmin,ymin,xmax,ymax (default is bbox of data)'
@@ -28093,7 +28100,6 @@ ${svg}
28093
28100
  var files = opts.files || [];
28094
28101
  var dataset;
28095
28102
 
28096
- cli.checkCommandEnv('i');
28097
28103
  if (opts.stdin) {
28098
28104
  dataset = importFile('/dev/stdin', opts);
28099
28105
  catalog.addDataset(dataset);
@@ -35465,8 +35471,15 @@ ${svg}
35465
35471
  // Returns array of matching records in src table, or null if no matches
35466
35472
  //
35467
35473
  function joinTableToLayer(destLyr, src, join, opts) {
35468
- var dest = destLyr.data,
35469
- useDuplication = !!opts.duplication,
35474
+ var dest = destLyr.data;
35475
+
35476
+ if (src == dest) {
35477
+ // self-join... duplicate source records to prevent assignment problems
35478
+ // (in calc= expressions and possibly elsewhere)
35479
+ src = src.clone();
35480
+ }
35481
+
35482
+ var useDuplication = !!opts.duplication,
35470
35483
  srcRecords = src.getRecords(),
35471
35484
  destRecords = dest.getRecords(),
35472
35485
  prefix = opts.prefix || '',
@@ -35482,7 +35495,7 @@ ${svg}
35482
35495
  retn = {},
35483
35496
  srcRec, srcId, destRec, joins, count, filter, calc, i, j, n, m;
35484
35497
 
35485
- // support for duplication of destination records
35498
+ // support for duplication of destination records for many-to-one joins
35486
35499
  var duplicateRecords, destShapes;
35487
35500
  if (useDuplication) {
35488
35501
  if (opts.calc) stop('duplication and calc options cannot be used together');
@@ -40638,6 +40651,423 @@ ${svg}
40638
40651
  return [lyr2];
40639
40652
  };
40640
40653
 
40654
+ // Columns are vertical and rows are horizontal in the "flat-top" orientation;
40655
+ // columns are horizontal in the "pointy-top" orientation
40656
+ // Array indexes are column-first in both orientations
40657
+ // The 0,0 cell is in the bottom left corner
40658
+ // Currently the origin cell is always an "outie" (protruding); in the future
40659
+ // "innie" origin cells may be supported
40660
+
40661
+ function getHexGridParams(bbox, interval, opts) {
40662
+ opts.type != 'hex2'; // hex2 is "pointy-top" orientation
40663
+
40664
+ // get origin and counts for centered grid
40665
+ // params.u0 = _getUOrigin();
40666
+ // params.v0 = _getVOrigin();
40667
+ // params.colCounts = _getColCounts(bbox, interval);
40668
+ // params.rowCounts = _getRowCounts(bbox, interval);
40669
+
40670
+ if (opts.aligned) ;
40671
+ }
40672
+
40673
+
40674
+ // interval: side length in projected coordinates
40675
+ // bbox: bounding box of area to be enclosed by grid
40676
+ //
40677
+ function getHexGridMaker(bbox, interval, opts) {
40678
+ var flatTop = opts.type != 'hex2'; // hex2 is "pointy-top" orientation
40679
+ // origin cell (bottom left) may be "outie" or "innie" ... could be settable
40680
+ var outieOrigin = true;
40681
+ var minorInterval = interval * Math.sqrt(3) / 2;
40682
+ var _colCounts = _getColCounts(bbox, interval);
40683
+ var _rowCounts = _getRowCounts(bbox, interval);
40684
+ // coordinates of the center of the bottom left cell
40685
+ var _uOrigin = _getUOrigin();
40686
+ var _vOrigin = _getVOrigin();
40687
+
40688
+ getHexGridParams(bbox, interval, opts);
40689
+
40690
+ function cells() {
40691
+ return _rowCounts[0] * _colCounts[0] + _rowCounts[1] * _colCounts[1];
40692
+ }
40693
+
40694
+ // a is col in flatTop orientation
40695
+ function colRowToIdx(col, row) {
40696
+ // fatCol: a pair of adjacent (offset) columns
40697
+ var fatColSize = _rowCounts[0] + _rowCounts[1];
40698
+ var fatColId = Math.floor(col / 2);
40699
+ var idx = fatColId * fatColSize;
40700
+ // oddCol: cell is in an odd-numbered column (or row)
40701
+ var oddCols = col % 2 == 1;
40702
+ if (oddCols) {
40703
+ idx += _rowCounts[1];
40704
+ }
40705
+ idx += row;
40706
+
40707
+ // check index bounds
40708
+ if (col < 0 || row < 0) error('negative grid index');
40709
+ if (oddCols && row >= _rowCounts[1] || !oddCols && row >= _rowCounts[0]) {
40710
+ error('out-of-bounds minor axis index');
40711
+ }
40712
+ if (oddCols && col >= _colCounts[1] || !oddCols && col >= _colCounts[0]) {
40713
+ error('out-of-bounds major axis index');
40714
+ }
40715
+ return idx;
40716
+ }
40717
+
40718
+ function pointToIdx(xy) {
40719
+ return flatTop ?
40720
+ _uvToIdx(xy[0], xy[1]) :
40721
+ _uvToIdx(xy[1], xy[0]);
40722
+ }
40723
+
40724
+ // Col,row numbering and array indexing are aligned (same for both flat-top and pointed-top orientations)
40725
+ function idxToColRow(id) {
40726
+ var fatColSize = _rowCounts[0] + _rowCounts[1];
40727
+ var fatColId = Math.floor(id / fatColSize);
40728
+ var col = fatColId * 2;
40729
+ var extra = id - fatColId * fatColSize;
40730
+ if (extra >= _rowCounts[0]) {
40731
+ col++;
40732
+ extra -= _rowCounts[0];
40733
+ }
40734
+ return [col, extra];
40735
+ }
40736
+
40737
+ function idxToBBox(id) {
40738
+ var bbox = _idxToBBox(id);
40739
+ return flatTop ? bbox: [bbox[1], bbox[0], bbox[3], bbox[2]];
40740
+ }
40741
+
40742
+ function makeCellPolygon(idx, opts) {
40743
+ var geom = {
40744
+ type: 'Polygon',
40745
+ coordinates: [_makeCellCoords(idx)]
40746
+ };
40747
+ if (!flatTop) {
40748
+ flipPolygonCoords(geom);
40749
+ }
40750
+ return geom;
40751
+ }
40752
+
40753
+ function forEachNeighbor(c, r, cb) {
40754
+ var rowShift;
40755
+ {
40756
+ rowShift = isOdd(c) ? 0 : -1;
40757
+ }
40758
+ cb(c, r+1);
40759
+ cb(c+1, r + rowShift + 1);
40760
+ cb(c+1, r + rowShift);
40761
+ cb(c, r-1);
40762
+ cb(c-1, r + rowShift + 1);
40763
+ }
40764
+
40765
+ // horizontal origin (x coord) in flat-top orientation
40766
+ function _getUOrigin() {
40767
+ var range = _getUAxisRange(bbox);
40768
+ var extent = range[1] - range[0];
40769
+ var cols = _colCounts[0] + _colCounts[1];
40770
+ var outerExtent = 1.5 * cols * interval + 0.5 * interval;
40771
+ var margin = (outerExtent - extent) / 2; // center data bbox within grid
40772
+ // origin is one side length to the right of the left boundary
40773
+ var origin = range[0] - margin + interval;
40774
+ return origin;
40775
+ }
40776
+
40777
+ // vertical origin (y coord) in flat-top orientation
40778
+ function _getVOrigin() {
40779
+ var range = _getVAxisRange(bbox);
40780
+ var extent = range[1] - range[0];
40781
+ var rows = _rowCounts[0] + _rowCounts[1];
40782
+ var outerExtent = (rows + 1) * minorInterval;
40783
+ var margin = (outerExtent - extent) / 2;
40784
+ var origin = range[0] - margin + minorInterval;
40785
+ return origin;
40786
+ }
40787
+
40788
+ function _getUAxisRange(bbox) {
40789
+ return flatTop ? [bbox[0], bbox[2]] : [bbox[1], bbox[3]];
40790
+ }
40791
+
40792
+ function _getVAxisRange(bbox) {
40793
+ return flatTop ? [bbox[1], bbox[3]] : [bbox[0], bbox[2]];
40794
+ }
40795
+
40796
+ function _uvToIdx(u, v) {
40797
+ var [c, r] = _uvToColRow(u, v);
40798
+ return colRowToIdx(c, r);
40799
+ }
40800
+
40801
+ // x, y are reversed in pointy-top orientation
40802
+ function _uvToColRow(u, v) {
40803
+ var left = _uOrigin - 1.5 * interval;
40804
+ var vOffs = 0 ;
40805
+ var bottom = _vOrigin - minorInterval + vOffs;
40806
+ var ui = Math.floor((u - left) / (1.5 * interval));
40807
+ var vi = Math.floor((v - bottom) / minorInterval);
40808
+ var cwBar = isOdd(ui) != isOdd(vi);
40809
+ var u1 = left + ui * 1.5 * interval + interval * 0.5;
40810
+ var u2 = u1 + interval * 0.5;
40811
+ var v1 = bottom + vi * minorInterval;
40812
+ var v2 = v1 + minorInterval;
40813
+ var orientation = cwBar ?
40814
+ orient2D(u1, v1, u2, v2, u, v) :
40815
+ orient2D(u2, v1, u1, v2, u, v);
40816
+ var colId = orientation > 0 ? ui - 1 : ui;
40817
+ var rowId = Math.floor(vi / 2);
40818
+ return [colId, rowId];
40819
+ }
40820
+
40821
+ function _idxToBBox(id) {
40822
+ var uv = _idxToPoint(id);
40823
+ return [
40824
+ uv[0] - interval,
40825
+ uv[1] - minorInterval,
40826
+ uv[0] + interval,
40827
+ uv[1] + minorInterval
40828
+ ];
40829
+ }
40830
+
40831
+ // center point of cell
40832
+ function idxToPoint(id) {
40833
+ var p = _idxToPoint(id);
40834
+ return flatTop ? p : flipPoint(p);
40835
+ }
40836
+
40837
+ function _isUpperCell(col) {
40838
+ return isOdd(col) || !outieOrigin ;
40839
+ }
40840
+
40841
+ function _idxToPoint(id) {
40842
+ var [c, r] = idxToColRow(id);
40843
+ return _colRowToPoint(c, r);
40844
+ }
40845
+
40846
+ function _colRowToPoint(c, r) {
40847
+ var vShift = isOdd(c) ? (minorInterval ) : 0;
40848
+ var u = _uOrigin + c * 1.5 * interval;
40849
+ var v = _vOrigin + vShift + r * minorInterval * 2;
40850
+ return [u, v];
40851
+ }
40852
+
40853
+ function _colRowToVertex(c, r, half) {
40854
+ var [u, v] = _colRowToPoint(c, r);
40855
+ return [u - (half ? interval : interval / 2), v - (half ? 0 : minorInterval)];
40856
+ }
40857
+
40858
+ function _makeCellCoords(idx) {
40859
+ var [c, r] = idxToColRow(idx);
40860
+ var rowOffs = _isUpperCell(c) ? 0 : -1;
40861
+ var v0 = _colRowToVertex(c, r, false);
40862
+ return [
40863
+ v0,
40864
+ _colRowToVertex(c, r, false),
40865
+ _colRowToVertex(c, r, true),
40866
+ _colRowToVertex(c, r + 1, false),
40867
+ _colRowToVertex(c + 1, r + 1 + rowOffs, true),
40868
+ _colRowToVertex(c + 1, r + 1 + rowOffs, false),
40869
+ _colRowToVertex(c + 1, r + rowOffs, true),
40870
+ v0
40871
+ ];
40872
+ }
40873
+
40874
+ function _getColCounts(bbox, interval) {
40875
+ var extent = flatTop ? bbox[2] - bbox[0] : bbox[3] - bbox[1];
40876
+ var n = Math.ceil((2 * extent + interval) / (3 * interval));
40877
+ var a = Math.ceil(n / 2);
40878
+ var b = Math.floor(n / 2);
40879
+ return [a, b] ;
40880
+ }
40881
+
40882
+ function _getRowCounts(bbox, interval) {
40883
+ var extent = flatTop ? bbox[3] - bbox[1] : bbox[2] - bbox[0];
40884
+ var n = Math.ceil(1 + 2 * extent / (interval * Math.sqrt(3)));
40885
+ var a = Math.ceil(n / 2);
40886
+ var b = Math.floor(n / 2);
40887
+ return [a, b] ;
40888
+ }
40889
+
40890
+ return {
40891
+ cells,
40892
+ colRowToIdx,
40893
+ idxToColRow,
40894
+ pointToIdx,
40895
+ idxToPoint,
40896
+ idxToBBox,
40897
+ makeCellPolygon,
40898
+ forEachNeighbor
40899
+ };
40900
+ }
40901
+
40902
+ function isOdd(int) {
40903
+ return int % 2 !== 0;
40904
+ }
40905
+
40906
+ function flipPolygonCoords(geom) {
40907
+ for (var i=0, n=geom ? geom.coordinates.length : 0; i<n; i++) {
40908
+ geom.coordinates[i].forEach(flipPoint);
40909
+ }
40910
+ }
40911
+
40912
+ function flipPoint(p) {
40913
+ p[1];
40914
+ p[1] = p[0];
40915
+ p[0] = p[1];
40916
+ return p;
40917
+ }
40918
+
40919
+ function getAlignedGridBounds(bbox, interval) {
40920
+ var xx = getAlignedRange(bbox[0], bbox[2], interval);
40921
+ var yy = getAlignedRange(bbox[1], bbox[3], interval);
40922
+ return [xx[0], yy[0], xx[1], yy[1]];
40923
+ }
40924
+
40925
+ function getCenteredGridBounds(bbox, interval) {
40926
+ var xx = getCenteredRange(bbox[0], bbox[2], interval);
40927
+ var yy = getCenteredRange(bbox[1], bbox[3], interval);
40928
+ return [xx[0], yy[0], xx[1], yy[1]];
40929
+ }
40930
+
40931
+ // grid boundaries includes the origin
40932
+ // (this way, grids calculated from different sets of points will all align)
40933
+ function getAlignedRange(minCoord, maxCoord, interval) {
40934
+ var idx = Math.floor(minCoord / interval) - 1;
40935
+ var idx2 = Math.ceil(maxCoord / interval) + 1;
40936
+ return [idx * interval, idx2 * interval];
40937
+ }
40938
+
40939
+ function getCenteredRange(minCoord, maxCoord, interval) {
40940
+ var w = maxCoord - minCoord;
40941
+ var w2 = Math.ceil(w / interval) * interval;
40942
+ var pad = (w2 - w) / 2 + interval;
40943
+ return [minCoord - pad, maxCoord + pad];
40944
+ }
40945
+
40946
+ // TODO: Use this function for other grid-based commands
40947
+ function getSquareGridMaker(bbox, interval, opts) {
40948
+ var extent = opts && opts.aligned ?
40949
+ getAlignedGridBounds(bbox, interval) :
40950
+ getCenteredGridBounds(bbox, interval);
40951
+ var xmin = extent[0];
40952
+ var ymin = extent[1];
40953
+ var w = extent[2] - xmin;
40954
+ var h = extent[3] - ymin;
40955
+ var cols = Math.round(w / interval);
40956
+ var rows = Math.round(h / interval);
40957
+ // var xmin = bbox[0] - interval;
40958
+ // var ymin = bbox[1] - interval;
40959
+ // var xmax = bbox[2] + interval;
40960
+ // var ymax = bbox[3] + interval;
40961
+ // var w = xmax - xmin;
40962
+ // var h = ymax - ymin;
40963
+ // var cols = Math.ceil(w / interval);
40964
+ // var rows = Math.ceil(h / interval);
40965
+
40966
+ // function size() {
40967
+ // return [cols, rows];
40968
+ // }
40969
+
40970
+ function cells() {
40971
+ return cols * rows;
40972
+ }
40973
+
40974
+ function pointToCol(xy) {
40975
+ var dx = xy[0] - xmin;
40976
+ return Math.floor(dx / w * cols);
40977
+ }
40978
+
40979
+ function pointToRow(xy) {
40980
+ var dy = xy[1] - ymin;
40981
+ return Math.floor(dy / h * rows);
40982
+ }
40983
+
40984
+ function colRowToIdx(c, r) {
40985
+ if (c < 0 || r < 0 || c >= cols || r >= rows) return -1;
40986
+ return r * cols + c;
40987
+ }
40988
+
40989
+ function pointToIdx(xy) {
40990
+ var c = pointToCol(xy);
40991
+ var r = pointToRow(xy);
40992
+ return colRowToIdx(c, r);
40993
+ }
40994
+
40995
+ function idxToColRow(i) {
40996
+ return [i % cols, Math.floor(i / cols)];
40997
+ }
40998
+
40999
+ function idxToPoint(idx) {
41000
+ var [c, r] = idxToColRow(idx);
41001
+ var x = xmin + (c + 0.5) * interval;
41002
+ var y = ymin + (r + 0.5) * interval;
41003
+ return [x, y];
41004
+ }
41005
+
41006
+ function idxToBBox(idx) {
41007
+ var cr = idxToColRow(idx);
41008
+ return [
41009
+ xmin + cr[0] * interval, ymin + cr[1] * interval,
41010
+ xmin + (cr[0] + 1) * interval, ymin + (cr[1] + 1) * interval
41011
+ ];
41012
+ }
41013
+
41014
+ function makeCellPolygon(idx, opts) {
41015
+ var coords = opts.circles ?
41016
+ makeCircleCoords(idx, opts) :
41017
+ makeCellCoords(idx, opts);
41018
+ return {
41019
+ type: 'Polygon',
41020
+ coordinates: [coords]
41021
+ };
41022
+ }
41023
+
41024
+ function makeCellCoords(idx, opts) {
41025
+ var bbox = idxToBBox(idx);
41026
+ var margin = opts.interval * (opts.cell_margin || 0);
41027
+ var a = bbox[0] + margin,
41028
+ b = bbox[1] + margin,
41029
+ c = bbox[2] - margin,
41030
+ d = bbox[3] - margin;
41031
+ return [[a, b],[a, d],[c, d],[c, b],[a, b]];
41032
+ }
41033
+
41034
+ function makeCircleCoords(idx, opts) {
41035
+ var center = idxToPoint(idx);
41036
+ var margin = opts.cell_margin > 0 ? opts.cell_margin : 1e-6;
41037
+ var radius = opts.interval / 2 * (1 - margin);
41038
+ var vertices = opts.vertices || 20;
41039
+ return getPointBufferCoordinates(center, radius, vertices, getPlanarSegmentEndpoint);
41040
+ }
41041
+
41042
+ function forEachNeighbor(c, r, cb) {
41043
+ cb(c+1, r+1);
41044
+ cb(c+1, r);
41045
+ cb(c+1, r-1);
41046
+ cb(c, r+1);
41047
+ cb(c, r-1);
41048
+ cb(c-1, r+1);
41049
+ cb(c-1, r);
41050
+ cb(c-1, r-1);
41051
+ }
41052
+
41053
+ return {
41054
+ // size,
41055
+ // pointToCol,
41056
+ // pointToRow,
41057
+ // makeCellCoords,
41058
+ // makeCircleCoords,
41059
+ cells,
41060
+ colRowToIdx,
41061
+ pointToIdx,
41062
+ idxToColRow,
41063
+ // idxToRow,
41064
+ idxToBBox,
41065
+ idxToPoint,
41066
+ makeCellPolygon,
41067
+ forEachNeighbor
41068
+ };
41069
+ }
41070
+
40641
41071
  cmd.polygonGrid = function(targetLayers, targetDataset, opts) {
40642
41072
  requireProjectedDataset(targetDataset);
40643
41073
  var params = getGridParams(targetLayers, targetDataset, opts);
@@ -40648,6 +41078,44 @@ ${svg}
40648
41078
  return gridDataset;
40649
41079
  };
40650
41080
 
41081
+
41082
+ // TODO: Update -point-grid command to use this function
41083
+ cmd.polygonGrid2 = function(targetLayers, targetDataset, opts) {
41084
+ requireProjectedDataset(targetDataset);
41085
+ var params = getGridParams(targetLayers, targetDataset, opts);
41086
+ // alignGridToBounds(geojson, params.bbox);
41087
+ var gridDataset = makeGridDataset2(params, opts);
41088
+ gridDataset.info = copyDatasetInfo(targetDataset.info);
41089
+ setOutputLayerName(gridDataset.layers[0], null, 'grid', opts);
41090
+ return gridDataset;
41091
+ };
41092
+
41093
+ function makeGridDataset2(params, opts) {
41094
+ var geojson, dataset, grid;
41095
+ if (params.type == 'square') {
41096
+ grid = getSquareGridMaker(params.bbox, params.interval, opts);
41097
+ } else if (params.type == 'hex') {
41098
+ grid = getHexGridMaker(params.bbox, params.interval, opts);
41099
+ } else {
41100
+ stop('Unsupported grid type');
41101
+ }
41102
+ var features = [];
41103
+ for (var i=0, n=grid.cells(); i<n; i++) {
41104
+ features.push({
41105
+ type: 'Feature',
41106
+ properties: null,
41107
+ geometry: grid.makeCellPolygon(i, opts)
41108
+ });
41109
+ }
41110
+ geojson = {
41111
+ type: 'FeatureCollection',
41112
+ features: features
41113
+ };
41114
+ dataset = importGeoJSON(geojson, {});
41115
+ buildTopology(dataset);
41116
+ return dataset;
41117
+ }
41118
+
40651
41119
  // TODO: Update -point-grid command to use this function
40652
41120
  cmd.pointGrid2 = function(targetLayers, targetDataset, opts) {
40653
41121
  var params = getGridParams(targetLayers, targetDataset, opts);
@@ -40970,129 +41438,6 @@ ${svg}
40970
41438
  r2sq * Math.acos(d2/r2) - d2 * Math.sqrt(r2sq - d2 * d2);
40971
41439
  }
40972
41440
 
40973
- function getAlignedGridBounds(bbox, interval) {
40974
- var xx = getAlignedRange(bbox[0], bbox[2], interval);
40975
- var yy = getAlignedRange(bbox[1], bbox[3], interval);
40976
- return [xx[0], yy[0], xx[1], yy[1]];
40977
- }
40978
-
40979
- function getCenteredGridBounds(bbox, interval) {
40980
- var xx = getCenteredRange(bbox[0], bbox[2], interval);
40981
- var yy = getCenteredRange(bbox[1], bbox[3], interval);
40982
- return [xx[0], yy[0], xx[1], yy[1]];
40983
- }
40984
-
40985
- // grid boundaries includes the origin
40986
- // (this way, grids calculated from different sets of points will all align)
40987
- function getAlignedRange(minCoord, maxCoord, interval) {
40988
- var idx = Math.floor(minCoord / interval) - 1;
40989
- var idx2 = Math.ceil(maxCoord / interval) + 1;
40990
- return [idx * interval, idx2 * interval];
40991
- }
40992
-
40993
- function getCenteredRange(minCoord, maxCoord, interval) {
40994
- var w = maxCoord - minCoord;
40995
- var w2 = Math.ceil(w / interval) * interval;
40996
- var pad = (w2 - w) / 2 + interval;
40997
- return [minCoord - pad, maxCoord + pad];
40998
- }
40999
-
41000
- // TODO: Use this function for other grid-based commands
41001
- function getSquareGridMaker(bbox, interval, opts) {
41002
- var extent = opts && opts.aligned ?
41003
- getAlignedGridBounds(bbox, interval) :
41004
- getCenteredGridBounds(bbox, interval);
41005
- var xmin = extent[0];
41006
- var ymin = extent[1];
41007
- var w = extent[2] - xmin;
41008
- var h = extent[3] - ymin;
41009
- var cols = Math.round(w / interval);
41010
- var rows = Math.round(h / interval);
41011
- function cells() {
41012
- return cols * rows;
41013
- }
41014
- function pointToCol(xy) {
41015
- var dx = xy[0] - xmin;
41016
- return Math.floor(dx / w * cols);
41017
- }
41018
- function pointToRow(xy) {
41019
- var dy = xy[1] - ymin;
41020
- return Math.floor(dy / h * rows);
41021
- }
41022
- function colRowToIdx(c, r) {
41023
- if (c < 0 || r < 0 || c >= cols || r >= rows) return -1;
41024
- return r * cols + c;
41025
- }
41026
- function pointToIdx(xy) {
41027
- var c = pointToCol(xy);
41028
- var r = pointToRow(xy);
41029
- return colRowToIdx(c, r);
41030
- }
41031
- function idxToCol(i) {
41032
- return i % cols;
41033
- }
41034
- function idxToRow(i) {
41035
- return Math.floor(i / cols);
41036
- }
41037
- function idxToPoint(idx) {
41038
- var x = xmin + (idxToCol(idx) + 0.5) * interval;
41039
- var y = ymin + (idxToRow(idx) + 0.5) * interval;
41040
- return [x, y];
41041
- }
41042
- function idxToBBox(idx) {
41043
- var c = idxToCol(idx);
41044
- var r = idxToRow(idx);
41045
- return [
41046
- xmin + c * interval, ymin + r * interval,
41047
- xmin + (c + 1) * interval, ymin + (r + 1) * interval
41048
- ];
41049
- }
41050
-
41051
- function makeCellPolygon(idx, opts) {
41052
- var coords = opts.circles ?
41053
- makeCircleCoords(idx, opts) :
41054
- makeCellCoords(idx, opts);
41055
- return {
41056
- type: 'Polygon',
41057
- coordinates: [coords]
41058
- };
41059
- }
41060
-
41061
- function makeCellCoords(idx, opts) {
41062
- var bbox = idxToBBox(idx);
41063
- var margin = opts.interval * (opts.cell_margin || 0);
41064
- var a = bbox[0] + margin,
41065
- b = bbox[1] + margin,
41066
- c = bbox[2] - margin,
41067
- d = bbox[3] - margin;
41068
- return [[a, b],[a, d],[c, d],[c, b],[a, b]];
41069
- }
41070
-
41071
- function makeCircleCoords(idx, opts) {
41072
- var center = idxToPoint(idx);
41073
- var margin = opts.cell_margin > 0 ? opts.cell_margin : 1e-6;
41074
- var radius = opts.interval / 2 * (1 - margin);
41075
- var vertices = opts.vertices || 20;
41076
- return getPointBufferCoordinates(center, radius, vertices, getPlanarSegmentEndpoint);
41077
- }
41078
-
41079
- return {
41080
- // size,
41081
- // pointToCol,
41082
- // pointToRow,
41083
- // makeCellCoords,
41084
- // makeCircleCoords,
41085
- cells,
41086
- colRowToIdx,
41087
- pointToIdx,
41088
- idxToCol,
41089
- idxToRow,
41090
- idxToBBox,
41091
- idxToPoint,
41092
- makeCellPolygon
41093
- };
41094
- }
41095
-
41096
41441
  // Returns a function that receives a cell index and returns indices of points
41097
41442
  // within a given distance of the cell.
41098
41443
  function getGridToPointIndex(points, grid, radius) {
@@ -41107,6 +41452,7 @@ ${svg}
41107
41452
  bboxIndex.add.apply(bboxIndex, bbox);
41108
41453
  });
41109
41454
  bboxIndex.finish();
41455
+
41110
41456
  return function(i) {
41111
41457
  if (!gridIndex.hasId(i)) {
41112
41458
  return empty;
@@ -41117,7 +41463,6 @@ ${svg}
41117
41463
  };
41118
41464
  }
41119
41465
 
41120
-
41121
41466
  // TODO: support spherical coords
41122
41467
  function getPointBounds(p, radius) {
41123
41468
  return [p[0] - radius, p[1] - radius, p[0] + radius, p[1] + radius];
@@ -41125,18 +41470,12 @@ ${svg}
41125
41470
 
41126
41471
  function addPointToGridIndex(p, index, grid, addNeighbors) {
41127
41472
  var i = grid.pointToIdx(p);
41128
- var c = grid.idxToCol(i);
41129
- var r = grid.idxToRow(i);
41473
+ var [c, r] = grid.idxToColRow(i);
41130
41474
  addCellToGridIndex(c, r, grid, index);
41131
41475
  if (addNeighbors) {
41132
- addCellToGridIndex(c+1, r+1, grid, index);
41133
- addCellToGridIndex(c+1, r, grid, index);
41134
- addCellToGridIndex(c+1, r-1, grid, index);
41135
- addCellToGridIndex(c, r+1, grid, index);
41136
- addCellToGridIndex(c, r-1, grid, index);
41137
- addCellToGridIndex(c-1, r+1, grid, index);
41138
- addCellToGridIndex(c-1, r, grid, index);
41139
- addCellToGridIndex(c-1, r-1, grid, index);
41476
+ grid.forEachNeighbor(c, r, function(c, r) {
41477
+ addCellToGridIndex(c, r, grid, index);
41478
+ });
41140
41479
  }
41141
41480
  }
41142
41481
 
@@ -41497,7 +41836,9 @@ ${svg}
41497
41836
  var str = standardizeConsoleCommands(raw);
41498
41837
  var parsed = parseCommands(str);
41499
41838
  parsed.forEach(function(cmd) {
41500
- cli.checkCommandEnv(cmd.name);
41839
+ if (['i', 'include', 'require', 'external'].includes(cmd.name)) {
41840
+ stop('The ' + cmd.name + ' command cannot be run in the web console.');
41841
+ }
41501
41842
  });
41502
41843
  return parsed;
41503
41844
  }
@@ -44032,6 +44373,9 @@ ${svg}
44032
44373
  } else if (name == 'grid') {
44033
44374
  outputDataset = cmd.polygonGrid(targetLayers, targetDataset, opts);
44034
44375
 
44376
+ } else if (name == 'grid2') {
44377
+ outputDataset = cmd.polygonGrid2(targetLayers, targetDataset, opts);
44378
+
44035
44379
  } else if (name == 'help') {
44036
44380
  // placing help command here to handle errors from invalid command names
44037
44381
  cmd.printHelp(command.options);