mapshaper 0.6.47 → 0.6.49

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.
Files changed (3) hide show
  1. package/mapshaper.js +257 -236
  2. package/package.json +1 -1
  3. package/www/mapshaper.js +257 -236
package/mapshaper.js CHANGED
@@ -1,6 +1,6 @@
1
1
  (function () {
2
2
 
3
- var VERSION = "0.6.47";
3
+ var VERSION = "0.6.49";
4
4
 
5
5
 
6
6
  var utils = /*#__PURE__*/Object.freeze({
@@ -17495,30 +17495,19 @@
17495
17495
  return feat;
17496
17496
  };
17497
17497
 
17498
- // switch to RFC 7946-compatible output (while retaining the original export function,
17499
- // so numerous tests will continue to work)
17500
- function exportGeoJSON2(dataset, opts) {
17501
- opts = utils.extend({}, opts);
17502
- opts.v2 = !opts.gj2008; // use RFC 7946 as the default
17503
- return exportGeoJSON(dataset, opts);
17504
- }
17505
-
17506
17498
  function exportGeoJSON(dataset, opts) {
17507
- opts = opts || {};
17499
+ opts = utils.extend({}, opts);
17500
+ opts.rfc7946 = !opts.gj2008; // use RFC 7946 as the default
17508
17501
  var extension = opts.extension || "json";
17509
17502
  var layerGroups, warn;
17510
17503
 
17511
17504
  // Apply coordinate precision
17512
- // rfc7946 flag is deprecated (default output is now RFC 7946 compatible)
17513
- // the flag is used here to preserve backwards compatibility
17514
- // (the rfc7946 flag applies a default precision threshold, even though rounding
17515
- // coordinates is only a recommendation, not a requirement of RFC 7946)
17516
- if (opts.precision || opts.rfc7946) {
17505
+ if (opts.precision) {
17517
17506
  dataset = copyDatasetForExport(dataset);
17518
17507
  setCoordinatePrecision(dataset, opts.precision || 0.000001);
17519
17508
  }
17520
17509
 
17521
- if (opts.v2 || opts.rfc7946) {
17510
+ if (opts.rfc7946) {
17522
17511
  warn = getRFC7946Warnings(dataset);
17523
17512
  if (warn) message(warn);
17524
17513
  }
@@ -17672,7 +17661,7 @@
17672
17661
  }
17673
17662
 
17674
17663
  if (opts.bbox) {
17675
- bbox = getDatasetBbox(dataset, opts.rfc7946 || opts.v2);
17664
+ bbox = getDatasetBbox(dataset, opts.rfc7946);
17676
17665
  if (bbox) {
17677
17666
  geojson.bbox = bbox;
17678
17667
  }
@@ -17772,7 +17761,7 @@
17772
17761
  var groups = groupPolygonRings(obj.pathData, arcs, opts.invert_y);
17773
17762
  // invert_y is used internally for SVG generation
17774
17763
  // mapshaper's internal winding order is the opposite of RFC 7946
17775
- var reverse = (opts.rfc7946 || opts.v2) && !opts.invert_y;
17764
+ var reverse = opts.rfc7946 && !opts.invert_y;
17776
17765
  var coords = groups.map(function(paths) {
17777
17766
  return paths.map(function(path) {
17778
17767
  if (reverse) path.points.reverse();
@@ -17886,7 +17875,6 @@
17886
17875
  var GeojsonExport = /*#__PURE__*/Object.freeze({
17887
17876
  __proto__: null,
17888
17877
  'default': GeoJSON,
17889
- exportGeoJSON2: exportGeoJSON2,
17890
17878
  exportGeoJSON: exportGeoJSON,
17891
17879
  exportLayerAsGeoJSON: exportLayerAsGeoJSON,
17892
17880
  getRFC7946Warnings: getRFC7946Warnings,
@@ -21775,7 +21763,7 @@ ${svg}
21775
21763
 
21776
21764
  var exporters = {
21777
21765
  // [PACKAGE_EXT]: exportPackedDatasets, // handled as a special case
21778
- geojson: exportGeoJSON2,
21766
+ geojson: exportGeoJSON,
21779
21767
  topojson: exportTopoJSON,
21780
21768
  shapefile: exportShapefile,
21781
21769
  dsv: exportDelim,
@@ -23678,13 +23666,6 @@ ${svg}
23678
23666
  // describe: 'pct of avg segment length for rounding (0.02 is default)',
23679
23667
  type: 'number'
23680
23668
  })
23681
- .option('rfc7946', {
23682
- // obsolete -- rfc 7946 compatible outptu is now the default.
23683
- // This option also rounds coordinates to 7 decimals. I'm retaining the
23684
- // option for backwards compatibility.
23685
- // describe: '[GeoJSON] follow RFC 7946 (CCW outer ring order, etc.)',
23686
- type: 'flag'
23687
- })
23688
23669
  // .option('winding', {
23689
23670
  // describe: '[GeoJSON] set polygon winding order (use CW with d3-geo)'
23690
23671
  // })
@@ -34841,7 +34822,7 @@ ${svg}
34841
34822
  // need to copy attribute to avoid circular references if geojson is assigned
34842
34823
  // to a data property.
34843
34824
  var copy = copyLayer(lyr);
34844
- var features = exportLayerAsGeoJSON(copy, dataset, {}, true);
34825
+ var features = exportLayerAsGeoJSON(copy, dataset, {rfc7946: true}, true);
34845
34826
  var features2 = [];
34846
34827
 
34847
34828
  api.get = function(i) {
@@ -39486,6 +39467,7 @@ ${svg}
39486
39467
  }
39487
39468
 
39488
39469
  function joinPolygonsViaMosaic(targetLyr, targetDataset, source, opts) {
39470
+ // merge source and target layers
39489
39471
  var mergedDataset = mergeLayersForOverlay([targetLyr], targetDataset, source, opts);
39490
39472
  var nodes = addIntersectionCuts(mergedDataset, opts);
39491
39473
  var sourceLyr = mergedDataset.layers.pop();
@@ -39495,6 +39477,7 @@ ${svg}
39495
39477
  geometry_type: 'polygon',
39496
39478
  shapes: targetLyr.shapes.concat(sourceLyr.shapes)
39497
39479
  };
39480
+ // make a mosaic from merged shapes of both layers
39498
39481
  var mosaicIndex = new MosaicIndex(mergedLyr, nodes, {flat: false});
39499
39482
 
39500
39483
  var joinOpts = utils.extend({}, opts);
@@ -39538,8 +39521,8 @@ ${svg}
39538
39521
  var mosaicRecords = mosaicShapes.map(function(tile, i) {
39539
39522
  var rec = {
39540
39523
  area: getShapeArea(tile, arcs),
39541
- weight: 0,
39542
- sourceId: -1
39524
+ weights: null,
39525
+ sourceIds: null
39543
39526
  };
39544
39527
  return rec;
39545
39528
  });
@@ -39549,32 +39532,49 @@ ${svg}
39549
39532
  sourceLyr.shapes.forEach(function(sourceShp, sourceId) {
39550
39533
  var tileIds = mosaicIndex.getTileIdsByShapeId(sourceId + destLen);
39551
39534
  var shapeArea = getShapeArea(sourceShp, arcs);
39552
- var tileRec;
39535
+ var tileRec, weight;
39553
39536
  for (var i=0; i<tileIds.length; i++) {
39554
39537
  tileRec = mosaicRecords[tileIds[i]];
39555
- if (tileRec.sourceId > -1) {
39556
- // overlap in source layer
39557
- continue;
39538
+ weight = tileRec.area / shapeArea;
39539
+ if (!tileRec.weights) {
39540
+ tileRec.weights = [];
39541
+ tileRec.sourceIds = [];
39558
39542
  }
39559
- tileRec.weight = tileRec.area / shapeArea;
39560
- tileRec.sourceId = sourceId;
39543
+ tileRec.weights.push(weight);
39544
+ tileRec.sourceIds.push(sourceId);
39561
39545
  }
39562
39546
  });
39563
39547
  return mosaicRecords;
39564
39548
  }
39565
39549
 
39566
39550
 
39551
+ // function getInterpolatedValue(field, tileRecords, sourceRecords) {
39552
+ // var value = 0, tileRec, sourceRec;
39553
+ // for (var i=0; i<tileRecords.length; i++) {
39554
+ // tileRec = tileRecords[i];
39555
+ // if (tileRec.sourceId == -1) continue;
39556
+
39557
+ // sourceRec = sourceRecords[tileRec.sourceId];
39558
+ // value += tileRec.weight * sourceRec[field];
39559
+ // }
39560
+ // return value;
39561
+ // }
39562
+
39567
39563
  function getInterpolatedValue(field, tileRecords, sourceRecords) {
39568
- var value = 0, tileRec, sourceRec;
39564
+ var value = 0, tileRec, sourceRec, sourceId;
39569
39565
  for (var i=0; i<tileRecords.length; i++) {
39570
39566
  tileRec = tileRecords[i];
39571
- if (tileRec.sourceId == -1) continue;
39572
- sourceRec = sourceRecords[tileRec.sourceId];
39573
- value += tileRec.weight * sourceRec[field];
39567
+ if (!tileRec.sourceIds) continue;
39568
+ for (var j=0; j<tileRec.sourceIds.length; j++) {
39569
+ sourceId = tileRec.sourceIds[j];
39570
+ sourceRec = sourceRecords[sourceId];
39571
+ value += tileRec.weights[j] * sourceRec[field];
39572
+ }
39574
39573
  }
39575
39574
  return value;
39576
39575
  }
39577
39576
 
39577
+
39578
39578
  function getIdConversionFunction(offset, length) {
39579
39579
  return function (mergedIds) {
39580
39580
  var ids = [], id;
@@ -40955,6 +40955,196 @@ ${svg}
40955
40955
  return rowsArr;
40956
40956
  }
40957
40957
 
40958
+ // Source: https://diego.assencio.com/?index=8d6ca3d82151bad815f78addf9b5c1c6
40959
+ function twoCircleIntersection(c1, r1, c2, r2) {
40960
+ var d = distance2D(c1[0], c1[1], c2[0], c2[1]);
40961
+ if (d >= r1 + r2) return 0;
40962
+ var r1sq = r1 * r1,
40963
+ r2sq = r2 * r2,
40964
+ d1 = (r1sq - r2sq + d * d) / (2 * d),
40965
+ d2 = d - d1;
40966
+ if (d <= Math.abs(r1 - r2)) {
40967
+ return Math.PI * Math.min(r1sq, r2sq);
40968
+ }
40969
+ return r1sq * Math.acos(d1/r1) - d1 * Math.sqrt(r1sq - d1 * d1) +
40970
+ r2sq * Math.acos(d2/r2) - d2 * Math.sqrt(r2sq - d2 * d2);
40971
+ }
40972
+
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
+ // Returns a function that receives a cell index and returns indices of points
41097
+ // within a given distance of the cell.
41098
+ function getGridToPointIndex(points, grid, radius) {
41099
+ var Flatbush = require('flatbush');
41100
+ var gridIndex = new IdTestIndex(grid.cells());
41101
+ var bboxIndex = new Flatbush(points.length);
41102
+ var empty = [];
41103
+ points.forEach(function(p) {
41104
+ var bbox = getPointBounds(p, radius);
41105
+ var addNeighbors = true; // TODO: only if radius is > 0?
41106
+ addPointToGridIndex(p, gridIndex, grid, addNeighbors);
41107
+ bboxIndex.add.apply(bboxIndex, bbox);
41108
+ });
41109
+ bboxIndex.finish();
41110
+ return function(i) {
41111
+ if (!gridIndex.hasId(i)) {
41112
+ return empty;
41113
+ }
41114
+ var bbox = grid.idxToBBox(i);
41115
+ var indices = bboxIndex.search.apply(bboxIndex, bbox);
41116
+ return indices;
41117
+ };
41118
+ }
41119
+
41120
+
41121
+ // TODO: support spherical coords
41122
+ function getPointBounds(p, radius) {
41123
+ return [p[0] - radius, p[1] - radius, p[0] + radius, p[1] + radius];
41124
+ }
41125
+
41126
+ function addPointToGridIndex(p, index, grid, addNeighbors) {
41127
+ var i = grid.pointToIdx(p);
41128
+ var c = grid.idxToCol(i);
41129
+ var r = grid.idxToRow(i);
41130
+ addCellToGridIndex(c, r, grid, index);
41131
+ 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);
41140
+ }
41141
+ }
41142
+
41143
+ function addCellToGridIndex(c, r, grid, index) {
41144
+ var i = grid.colRowToIdx(c, r);
41145
+ if (i > -1) index.setId(i);
41146
+ }
41147
+
40958
41148
  cmd.pointToGrid = function(targetLayers, targetDataset, opts) {
40959
41149
  targetLayers.forEach(requirePointLayer);
40960
41150
  if (opts.interval > 0 === false) {
@@ -40986,13 +41176,12 @@ ${svg}
40986
41176
  return outputLayers;
40987
41177
  };
40988
41178
 
40989
-
40990
41179
  function getPolygonDataset(pointLyr, gridBBox, opts) {
40991
41180
  var points = getPointsInLayer(pointLyr);
40992
41181
  var cellSize = opts.interval;
40993
- var grid = getGridData(gridBBox, cellSize, opts);
41182
+ var grid = getSquareGridMaker(gridBBox, cellSize, opts);
40994
41183
  var pointCircleRadius = getPointCircleRadius(opts);
40995
- var findPointIdsByCellId = getPointIndex(points, grid, pointCircleRadius);
41184
+ var findPointIdsByCellId = getGridToPointIndex(points, grid, pointCircleRadius);
40996
41185
  var geojson = {
40997
41186
  type: 'FeatureCollection',
40998
41187
  features: []
@@ -41011,7 +41200,7 @@ ${svg}
41011
41200
  geojson.features.push({
41012
41201
  type: 'Feature',
41013
41202
  properties: d,
41014
- geometry: makeCellPolygon(i, grid, opts)
41203
+ geometry: grid.makeCellPolygon(i, opts)
41015
41204
  });
41016
41205
  }
41017
41206
  return importGeoJSON(geojson, {});
@@ -41052,202 +41241,19 @@ ${svg}
41052
41241
  return weights;
41053
41242
  }
41054
41243
 
41055
- // Source: https://diego.assencio.com/?index=8d6ca3d82151bad815f78addf9b5c1c6
41056
- function twoCircleIntersection(c1, r1, c2, r2) {
41057
- var d = distance2D(c1[0], c1[1], c2[0], c2[1]);
41058
- if (d >= r1 + r2) return 0;
41059
- var r1sq = r1 * r1,
41060
- r2sq = r2 * r2,
41061
- d1 = (r1sq - r2sq + d * d) / (2 * d),
41062
- d2 = d - d1;
41063
- if (d <= Math.abs(r1 - r2)) {
41064
- return Math.PI * Math.min(r1sq, r2sq);
41065
- }
41066
- return r1sq * Math.acos(d1/r1) - d1 * Math.sqrt(r1sq - d1 * d1) +
41067
- r2sq * Math.acos(d2/r2) - d2 * Math.sqrt(r2sq - d2 * d2);
41068
- }
41069
-
41070
- function makeCellPolygon(idx, grid, opts) {
41071
- var coords = opts.circles ?
41072
- makeCircleCoords(grid.idxToPoint(idx), opts) :
41073
- makeCellCoords(grid.idxToBBox(idx), opts);
41074
- return {
41075
- type: 'Polygon',
41076
- coordinates: [coords]
41077
- };
41078
- }
41079
-
41080
- function makeCellCoords(bbox, opts) {
41081
- var margin = opts.interval * (opts.cell_margin || 0);
41082
- var a = bbox[0] + margin,
41083
- b = bbox[1] + margin,
41084
- c = bbox[2] - margin,
41085
- d = bbox[3] - margin;
41086
- return [[a, b],[a, d],[c, d],[c, b],[a, b]];
41087
- }
41088
-
41089
- function makeCircleCoords(center, opts) {
41090
- var margin = opts.cell_margin > 0 ? opts.cell_margin : 1e-6;
41091
- var radius = opts.interval / 2 * (1 - margin);
41092
- var vertices = opts.vertices || 20;
41093
- return getPointBufferCoordinates(center, radius, vertices, getPlanarSegmentEndpoint);
41094
- }
41095
-
41096
- // Returns a function that receives a cell index and returns indices of points
41097
- // within a given distance of the cell.
41098
- function getPointIndex(points, grid, radius) {
41099
- var Flatbush = require$1('flatbush');
41100
- var gridIndex = new IdTestIndex(grid.cells());
41101
- var bboxIndex = new Flatbush(points.length);
41102
- var empty = [];
41103
- points.forEach(function(p) {
41104
- var bbox = getPointBounds(p, radius);
41105
- addPointToGridIndex(p, gridIndex, grid);
41106
- bboxIndex.add.apply(bboxIndex, bbox);
41107
- });
41108
- bboxIndex.finish();
41109
- return function(i) {
41110
- if (!gridIndex.hasId(i)) {
41111
- return empty;
41112
- }
41113
- var bbox = grid.idxToBBox(i);
41114
- var indices = bboxIndex.search.apply(bboxIndex, bbox);
41115
- return indices;
41116
- };
41117
- }
41118
-
41119
- function addPointToGridIndex(p, index, grid) {
41120
- var i = grid.pointToIdx(p);
41121
- var c = grid.idxToCol(i);
41122
- var r = grid.idxToRow(i);
41123
- addCellToGridIndex(c+1, r+1, grid, index);
41124
- addCellToGridIndex(c+1, r, grid, index);
41125
- addCellToGridIndex(c+1, r-1, grid, index);
41126
- addCellToGridIndex(c, r+1, grid, index);
41127
- addCellToGridIndex(c, r, grid, index);
41128
- addCellToGridIndex(c, r-1, grid, index);
41129
- addCellToGridIndex(c-1, r+1, grid, index);
41130
- addCellToGridIndex(c-1, r, grid, index);
41131
- addCellToGridIndex(c-1, r-1, grid, index);
41132
- }
41133
-
41134
- function addCellToGridIndex(c, r, grid, index) {
41135
- var i = grid.colRowToIdx(c, r);
41136
- if (i > -1) index.setId(i);
41137
- }
41138
-
41139
- // TODO: support spherical coords
41140
- function getPointBounds(p, radius) {
41141
- return [p[0] - radius, p[1] - radius, p[0] + radius, p[1] + radius];
41142
- }
41143
-
41144
- // grid boundaries includes the origin
41145
- // (this way, grids calculated from different sets of points will all align)
41146
- function getAlignedRange(minCoord, maxCoord, interval) {
41147
- var idx = Math.floor(minCoord / interval) - 1;
41148
- var idx2 = Math.ceil(maxCoord / interval) + 1;
41149
- return [idx * interval, idx2 * interval];
41150
- }
41151
-
41152
- function getCenteredRange(minCoord, maxCoord, interval) {
41153
- var w = maxCoord - minCoord;
41154
- var w2 = Math.ceil(w / interval) * interval;
41155
- var pad = (w2 - w) / 2 + interval;
41156
- return [minCoord - pad, maxCoord + pad];
41157
- }
41158
-
41159
- function getAlignedGridBounds(bbox, interval) {
41160
- var xx = getAlignedRange(bbox[0], bbox[2], interval);
41161
- var yy = getAlignedRange(bbox[1], bbox[3], interval);
41162
- return [xx[0], yy[0], xx[1], yy[1]];
41163
- }
41164
-
41165
- function getCenteredGridBounds(bbox, interval) {
41166
- var xx = getCenteredRange(bbox[0], bbox[2], interval);
41167
- var yy = getCenteredRange(bbox[1], bbox[3], interval);
41168
- return [xx[0], yy[0], xx[1], yy[1]];
41169
- }
41170
-
41171
- // TODO: Use this function for other grid-based commands
41172
- function getGridData(bbox, interval, opts) {
41173
- var extent = opts && opts.aligned ?
41174
- getAlignedGridBounds(bbox, interval) :
41175
- getCenteredGridBounds(bbox, interval);
41176
- var xmin = extent[0];
41177
- var ymin = extent[1];
41178
- var w = extent[2] - xmin;
41179
- var h = extent[3] - ymin;
41180
- var cols = Math.round(w / interval);
41181
- var rows = Math.round(h / interval);
41182
- // var xmin = bbox[0] - interval;
41183
- // var ymin = bbox[1] - interval;
41184
- // var xmax = bbox[2] + interval;
41185
- // var ymax = bbox[3] + interval;
41186
- // var w = xmax - xmin;
41187
- // var h = ymax - ymin;
41188
- // var cols = Math.ceil(w / interval);
41189
- // var rows = Math.ceil(h / interval);
41190
- function size() {
41191
- return [cols, rows];
41192
- }
41193
- function cells() {
41194
- return cols * rows;
41195
- }
41196
- function pointToCol(xy) {
41197
- var dx = xy[0] - xmin;
41198
- return Math.floor(dx / w * cols);
41199
- }
41200
- function pointToRow(xy) {
41201
- var dy = xy[1] - ymin;
41202
- return Math.floor(dy / h * rows);
41203
- }
41204
- function colRowToIdx(c, r) {
41205
- if (c < 0 || r < 0 || c >= cols || r >= rows) return -1;
41206
- return r * cols + c;
41207
- }
41208
- function pointToIdx(xy) {
41209
- var c = pointToCol(xy);
41210
- var r = pointToRow(xy);
41211
- return colRowToIdx(c, r);
41212
- }
41213
- function idxToCol(i) {
41214
- return i % cols;
41215
- }
41216
- function idxToRow(i) {
41217
- return Math.floor(i / cols);
41218
- }
41219
- function idxToPoint(idx) {
41220
- var x = xmin + (idxToCol(idx) + 0.5) * interval;
41221
- var y = ymin + (idxToRow(idx) + 0.5) * interval;
41222
- return [x, y];
41223
- }
41224
- function idxToBBox(idx) {
41225
- var c = idxToCol(idx);
41226
- var r = idxToRow(idx);
41227
- return [
41228
- xmin + c * interval, ymin + r * interval,
41229
- xmin + (c + 1) * interval, ymin + (r + 1) * interval
41230
- ];
41231
- }
41232
-
41233
- return {
41234
- size, cells, pointToCol, pointToRow, colRowToIdx, pointToIdx,
41235
- idxToCol, idxToRow, idxToBBox, idxToPoint
41236
- };
41237
- }
41244
+ // function getPointsByIndex(points, indices) {
41245
+ // var arr = [];
41246
+ // for (var i=0; i<indices.length; i++) {
41247
+ // arr.push(points[indices[i]]);
41248
+ // }
41249
+ // return arr;
41250
+ // }
41238
41251
 
41239
41252
  var PointToGrid = /*#__PURE__*/Object.freeze({
41240
41253
  __proto__: null,
41241
41254
  getPointCircleRadius: getPointCircleRadius,
41242
41255
  calcCellProperties: calcCellProperties,
41243
- calcWeights: calcWeights,
41244
- twoCircleIntersection: twoCircleIntersection,
41245
- makeCellPolygon: makeCellPolygon,
41246
- makeCircleCoords: makeCircleCoords,
41247
- getPointIndex: getPointIndex,
41248
- getAlignedGridBounds: getAlignedGridBounds,
41249
- getCenteredGridBounds: getCenteredGridBounds,
41250
- getGridData: getGridData
41256
+ calcWeights: calcWeights
41251
41257
  });
41252
41258
 
41253
41259
  function closeUndershoots(lyr, dataset, opts) {
@@ -41503,11 +41509,26 @@ ${svg}
41503
41509
  parseConsoleCommands: parseConsoleCommands
41504
41510
  });
41505
41511
 
41512
+ // import { importGeoJSON } from '../geojson/geojson-import';
41513
+
41506
41514
  function getTargetProxy(target) {
41507
41515
  var lyr = target.layers[0];
41508
- var data = getLayerInfo(lyr, target.dataset);
41516
+ var data = getLayerInfo(lyr, target.dataset); // layer_name, feature_count etc
41509
41517
  data.layer = lyr;
41510
41518
  data.dataset = target.dataset;
41519
+ addGetters(data, {
41520
+ // export as an object, not a string or buffer
41521
+ geojson: getGeoJSON
41522
+ });
41523
+
41524
+ function getGeoJSON() {
41525
+ var features = exportLayerAsGeoJSON(lyr, target.dataset, {rfc7946: true}, true);
41526
+ return {
41527
+ type: 'FeatureCollection',
41528
+ features: features
41529
+ };
41530
+ }
41531
+
41511
41532
  return data;
41512
41533
  }
41513
41534
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mapshaper",
3
- "version": "0.6.47",
3
+ "version": "0.6.49",
4
4
  "description": "A tool for editing vector datasets for mapping and GIS.",
5
5
  "keywords": [
6
6
  "shapefile",
package/www/mapshaper.js CHANGED
@@ -1,6 +1,6 @@
1
1
  (function () {
2
2
 
3
- var VERSION = "0.6.47";
3
+ var VERSION = "0.6.49";
4
4
 
5
5
 
6
6
  var utils = /*#__PURE__*/Object.freeze({
@@ -17495,30 +17495,19 @@
17495
17495
  return feat;
17496
17496
  };
17497
17497
 
17498
- // switch to RFC 7946-compatible output (while retaining the original export function,
17499
- // so numerous tests will continue to work)
17500
- function exportGeoJSON2(dataset, opts) {
17501
- opts = utils.extend({}, opts);
17502
- opts.v2 = !opts.gj2008; // use RFC 7946 as the default
17503
- return exportGeoJSON(dataset, opts);
17504
- }
17505
-
17506
17498
  function exportGeoJSON(dataset, opts) {
17507
- opts = opts || {};
17499
+ opts = utils.extend({}, opts);
17500
+ opts.rfc7946 = !opts.gj2008; // use RFC 7946 as the default
17508
17501
  var extension = opts.extension || "json";
17509
17502
  var layerGroups, warn;
17510
17503
 
17511
17504
  // Apply coordinate precision
17512
- // rfc7946 flag is deprecated (default output is now RFC 7946 compatible)
17513
- // the flag is used here to preserve backwards compatibility
17514
- // (the rfc7946 flag applies a default precision threshold, even though rounding
17515
- // coordinates is only a recommendation, not a requirement of RFC 7946)
17516
- if (opts.precision || opts.rfc7946) {
17505
+ if (opts.precision) {
17517
17506
  dataset = copyDatasetForExport(dataset);
17518
17507
  setCoordinatePrecision(dataset, opts.precision || 0.000001);
17519
17508
  }
17520
17509
 
17521
- if (opts.v2 || opts.rfc7946) {
17510
+ if (opts.rfc7946) {
17522
17511
  warn = getRFC7946Warnings(dataset);
17523
17512
  if (warn) message(warn);
17524
17513
  }
@@ -17672,7 +17661,7 @@
17672
17661
  }
17673
17662
 
17674
17663
  if (opts.bbox) {
17675
- bbox = getDatasetBbox(dataset, opts.rfc7946 || opts.v2);
17664
+ bbox = getDatasetBbox(dataset, opts.rfc7946);
17676
17665
  if (bbox) {
17677
17666
  geojson.bbox = bbox;
17678
17667
  }
@@ -17772,7 +17761,7 @@
17772
17761
  var groups = groupPolygonRings(obj.pathData, arcs, opts.invert_y);
17773
17762
  // invert_y is used internally for SVG generation
17774
17763
  // mapshaper's internal winding order is the opposite of RFC 7946
17775
- var reverse = (opts.rfc7946 || opts.v2) && !opts.invert_y;
17764
+ var reverse = opts.rfc7946 && !opts.invert_y;
17776
17765
  var coords = groups.map(function(paths) {
17777
17766
  return paths.map(function(path) {
17778
17767
  if (reverse) path.points.reverse();
@@ -17886,7 +17875,6 @@
17886
17875
  var GeojsonExport = /*#__PURE__*/Object.freeze({
17887
17876
  __proto__: null,
17888
17877
  'default': GeoJSON,
17889
- exportGeoJSON2: exportGeoJSON2,
17890
17878
  exportGeoJSON: exportGeoJSON,
17891
17879
  exportLayerAsGeoJSON: exportLayerAsGeoJSON,
17892
17880
  getRFC7946Warnings: getRFC7946Warnings,
@@ -21775,7 +21763,7 @@ ${svg}
21775
21763
 
21776
21764
  var exporters = {
21777
21765
  // [PACKAGE_EXT]: exportPackedDatasets, // handled as a special case
21778
- geojson: exportGeoJSON2,
21766
+ geojson: exportGeoJSON,
21779
21767
  topojson: exportTopoJSON,
21780
21768
  shapefile: exportShapefile,
21781
21769
  dsv: exportDelim,
@@ -23678,13 +23666,6 @@ ${svg}
23678
23666
  // describe: 'pct of avg segment length for rounding (0.02 is default)',
23679
23667
  type: 'number'
23680
23668
  })
23681
- .option('rfc7946', {
23682
- // obsolete -- rfc 7946 compatible outptu is now the default.
23683
- // This option also rounds coordinates to 7 decimals. I'm retaining the
23684
- // option for backwards compatibility.
23685
- // describe: '[GeoJSON] follow RFC 7946 (CCW outer ring order, etc.)',
23686
- type: 'flag'
23687
- })
23688
23669
  // .option('winding', {
23689
23670
  // describe: '[GeoJSON] set polygon winding order (use CW with d3-geo)'
23690
23671
  // })
@@ -34841,7 +34822,7 @@ ${svg}
34841
34822
  // need to copy attribute to avoid circular references if geojson is assigned
34842
34823
  // to a data property.
34843
34824
  var copy = copyLayer(lyr);
34844
- var features = exportLayerAsGeoJSON(copy, dataset, {}, true);
34825
+ var features = exportLayerAsGeoJSON(copy, dataset, {rfc7946: true}, true);
34845
34826
  var features2 = [];
34846
34827
 
34847
34828
  api.get = function(i) {
@@ -39486,6 +39467,7 @@ ${svg}
39486
39467
  }
39487
39468
 
39488
39469
  function joinPolygonsViaMosaic(targetLyr, targetDataset, source, opts) {
39470
+ // merge source and target layers
39489
39471
  var mergedDataset = mergeLayersForOverlay([targetLyr], targetDataset, source, opts);
39490
39472
  var nodes = addIntersectionCuts(mergedDataset, opts);
39491
39473
  var sourceLyr = mergedDataset.layers.pop();
@@ -39495,6 +39477,7 @@ ${svg}
39495
39477
  geometry_type: 'polygon',
39496
39478
  shapes: targetLyr.shapes.concat(sourceLyr.shapes)
39497
39479
  };
39480
+ // make a mosaic from merged shapes of both layers
39498
39481
  var mosaicIndex = new MosaicIndex(mergedLyr, nodes, {flat: false});
39499
39482
 
39500
39483
  var joinOpts = utils.extend({}, opts);
@@ -39538,8 +39521,8 @@ ${svg}
39538
39521
  var mosaicRecords = mosaicShapes.map(function(tile, i) {
39539
39522
  var rec = {
39540
39523
  area: getShapeArea(tile, arcs),
39541
- weight: 0,
39542
- sourceId: -1
39524
+ weights: null,
39525
+ sourceIds: null
39543
39526
  };
39544
39527
  return rec;
39545
39528
  });
@@ -39549,32 +39532,49 @@ ${svg}
39549
39532
  sourceLyr.shapes.forEach(function(sourceShp, sourceId) {
39550
39533
  var tileIds = mosaicIndex.getTileIdsByShapeId(sourceId + destLen);
39551
39534
  var shapeArea = getShapeArea(sourceShp, arcs);
39552
- var tileRec;
39535
+ var tileRec, weight;
39553
39536
  for (var i=0; i<tileIds.length; i++) {
39554
39537
  tileRec = mosaicRecords[tileIds[i]];
39555
- if (tileRec.sourceId > -1) {
39556
- // overlap in source layer
39557
- continue;
39538
+ weight = tileRec.area / shapeArea;
39539
+ if (!tileRec.weights) {
39540
+ tileRec.weights = [];
39541
+ tileRec.sourceIds = [];
39558
39542
  }
39559
- tileRec.weight = tileRec.area / shapeArea;
39560
- tileRec.sourceId = sourceId;
39543
+ tileRec.weights.push(weight);
39544
+ tileRec.sourceIds.push(sourceId);
39561
39545
  }
39562
39546
  });
39563
39547
  return mosaicRecords;
39564
39548
  }
39565
39549
 
39566
39550
 
39551
+ // function getInterpolatedValue(field, tileRecords, sourceRecords) {
39552
+ // var value = 0, tileRec, sourceRec;
39553
+ // for (var i=0; i<tileRecords.length; i++) {
39554
+ // tileRec = tileRecords[i];
39555
+ // if (tileRec.sourceId == -1) continue;
39556
+
39557
+ // sourceRec = sourceRecords[tileRec.sourceId];
39558
+ // value += tileRec.weight * sourceRec[field];
39559
+ // }
39560
+ // return value;
39561
+ // }
39562
+
39567
39563
  function getInterpolatedValue(field, tileRecords, sourceRecords) {
39568
- var value = 0, tileRec, sourceRec;
39564
+ var value = 0, tileRec, sourceRec, sourceId;
39569
39565
  for (var i=0; i<tileRecords.length; i++) {
39570
39566
  tileRec = tileRecords[i];
39571
- if (tileRec.sourceId == -1) continue;
39572
- sourceRec = sourceRecords[tileRec.sourceId];
39573
- value += tileRec.weight * sourceRec[field];
39567
+ if (!tileRec.sourceIds) continue;
39568
+ for (var j=0; j<tileRec.sourceIds.length; j++) {
39569
+ sourceId = tileRec.sourceIds[j];
39570
+ sourceRec = sourceRecords[sourceId];
39571
+ value += tileRec.weights[j] * sourceRec[field];
39572
+ }
39574
39573
  }
39575
39574
  return value;
39576
39575
  }
39577
39576
 
39577
+
39578
39578
  function getIdConversionFunction(offset, length) {
39579
39579
  return function (mergedIds) {
39580
39580
  var ids = [], id;
@@ -40955,6 +40955,196 @@ ${svg}
40955
40955
  return rowsArr;
40956
40956
  }
40957
40957
 
40958
+ // Source: https://diego.assencio.com/?index=8d6ca3d82151bad815f78addf9b5c1c6
40959
+ function twoCircleIntersection(c1, r1, c2, r2) {
40960
+ var d = distance2D(c1[0], c1[1], c2[0], c2[1]);
40961
+ if (d >= r1 + r2) return 0;
40962
+ var r1sq = r1 * r1,
40963
+ r2sq = r2 * r2,
40964
+ d1 = (r1sq - r2sq + d * d) / (2 * d),
40965
+ d2 = d - d1;
40966
+ if (d <= Math.abs(r1 - r2)) {
40967
+ return Math.PI * Math.min(r1sq, r2sq);
40968
+ }
40969
+ return r1sq * Math.acos(d1/r1) - d1 * Math.sqrt(r1sq - d1 * d1) +
40970
+ r2sq * Math.acos(d2/r2) - d2 * Math.sqrt(r2sq - d2 * d2);
40971
+ }
40972
+
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
+ // Returns a function that receives a cell index and returns indices of points
41097
+ // within a given distance of the cell.
41098
+ function getGridToPointIndex(points, grid, radius) {
41099
+ var Flatbush = require('flatbush');
41100
+ var gridIndex = new IdTestIndex(grid.cells());
41101
+ var bboxIndex = new Flatbush(points.length);
41102
+ var empty = [];
41103
+ points.forEach(function(p) {
41104
+ var bbox = getPointBounds(p, radius);
41105
+ var addNeighbors = true; // TODO: only if radius is > 0?
41106
+ addPointToGridIndex(p, gridIndex, grid, addNeighbors);
41107
+ bboxIndex.add.apply(bboxIndex, bbox);
41108
+ });
41109
+ bboxIndex.finish();
41110
+ return function(i) {
41111
+ if (!gridIndex.hasId(i)) {
41112
+ return empty;
41113
+ }
41114
+ var bbox = grid.idxToBBox(i);
41115
+ var indices = bboxIndex.search.apply(bboxIndex, bbox);
41116
+ return indices;
41117
+ };
41118
+ }
41119
+
41120
+
41121
+ // TODO: support spherical coords
41122
+ function getPointBounds(p, radius) {
41123
+ return [p[0] - radius, p[1] - radius, p[0] + radius, p[1] + radius];
41124
+ }
41125
+
41126
+ function addPointToGridIndex(p, index, grid, addNeighbors) {
41127
+ var i = grid.pointToIdx(p);
41128
+ var c = grid.idxToCol(i);
41129
+ var r = grid.idxToRow(i);
41130
+ addCellToGridIndex(c, r, grid, index);
41131
+ 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);
41140
+ }
41141
+ }
41142
+
41143
+ function addCellToGridIndex(c, r, grid, index) {
41144
+ var i = grid.colRowToIdx(c, r);
41145
+ if (i > -1) index.setId(i);
41146
+ }
41147
+
40958
41148
  cmd.pointToGrid = function(targetLayers, targetDataset, opts) {
40959
41149
  targetLayers.forEach(requirePointLayer);
40960
41150
  if (opts.interval > 0 === false) {
@@ -40986,13 +41176,12 @@ ${svg}
40986
41176
  return outputLayers;
40987
41177
  };
40988
41178
 
40989
-
40990
41179
  function getPolygonDataset(pointLyr, gridBBox, opts) {
40991
41180
  var points = getPointsInLayer(pointLyr);
40992
41181
  var cellSize = opts.interval;
40993
- var grid = getGridData(gridBBox, cellSize, opts);
41182
+ var grid = getSquareGridMaker(gridBBox, cellSize, opts);
40994
41183
  var pointCircleRadius = getPointCircleRadius(opts);
40995
- var findPointIdsByCellId = getPointIndex(points, grid, pointCircleRadius);
41184
+ var findPointIdsByCellId = getGridToPointIndex(points, grid, pointCircleRadius);
40996
41185
  var geojson = {
40997
41186
  type: 'FeatureCollection',
40998
41187
  features: []
@@ -41011,7 +41200,7 @@ ${svg}
41011
41200
  geojson.features.push({
41012
41201
  type: 'Feature',
41013
41202
  properties: d,
41014
- geometry: makeCellPolygon(i, grid, opts)
41203
+ geometry: grid.makeCellPolygon(i, opts)
41015
41204
  });
41016
41205
  }
41017
41206
  return importGeoJSON(geojson, {});
@@ -41052,202 +41241,19 @@ ${svg}
41052
41241
  return weights;
41053
41242
  }
41054
41243
 
41055
- // Source: https://diego.assencio.com/?index=8d6ca3d82151bad815f78addf9b5c1c6
41056
- function twoCircleIntersection(c1, r1, c2, r2) {
41057
- var d = distance2D(c1[0], c1[1], c2[0], c2[1]);
41058
- if (d >= r1 + r2) return 0;
41059
- var r1sq = r1 * r1,
41060
- r2sq = r2 * r2,
41061
- d1 = (r1sq - r2sq + d * d) / (2 * d),
41062
- d2 = d - d1;
41063
- if (d <= Math.abs(r1 - r2)) {
41064
- return Math.PI * Math.min(r1sq, r2sq);
41065
- }
41066
- return r1sq * Math.acos(d1/r1) - d1 * Math.sqrt(r1sq - d1 * d1) +
41067
- r2sq * Math.acos(d2/r2) - d2 * Math.sqrt(r2sq - d2 * d2);
41068
- }
41069
-
41070
- function makeCellPolygon(idx, grid, opts) {
41071
- var coords = opts.circles ?
41072
- makeCircleCoords(grid.idxToPoint(idx), opts) :
41073
- makeCellCoords(grid.idxToBBox(idx), opts);
41074
- return {
41075
- type: 'Polygon',
41076
- coordinates: [coords]
41077
- };
41078
- }
41079
-
41080
- function makeCellCoords(bbox, opts) {
41081
- var margin = opts.interval * (opts.cell_margin || 0);
41082
- var a = bbox[0] + margin,
41083
- b = bbox[1] + margin,
41084
- c = bbox[2] - margin,
41085
- d = bbox[3] - margin;
41086
- return [[a, b],[a, d],[c, d],[c, b],[a, b]];
41087
- }
41088
-
41089
- function makeCircleCoords(center, opts) {
41090
- var margin = opts.cell_margin > 0 ? opts.cell_margin : 1e-6;
41091
- var radius = opts.interval / 2 * (1 - margin);
41092
- var vertices = opts.vertices || 20;
41093
- return getPointBufferCoordinates(center, radius, vertices, getPlanarSegmentEndpoint);
41094
- }
41095
-
41096
- // Returns a function that receives a cell index and returns indices of points
41097
- // within a given distance of the cell.
41098
- function getPointIndex(points, grid, radius) {
41099
- var Flatbush = require$1('flatbush');
41100
- var gridIndex = new IdTestIndex(grid.cells());
41101
- var bboxIndex = new Flatbush(points.length);
41102
- var empty = [];
41103
- points.forEach(function(p) {
41104
- var bbox = getPointBounds(p, radius);
41105
- addPointToGridIndex(p, gridIndex, grid);
41106
- bboxIndex.add.apply(bboxIndex, bbox);
41107
- });
41108
- bboxIndex.finish();
41109
- return function(i) {
41110
- if (!gridIndex.hasId(i)) {
41111
- return empty;
41112
- }
41113
- var bbox = grid.idxToBBox(i);
41114
- var indices = bboxIndex.search.apply(bboxIndex, bbox);
41115
- return indices;
41116
- };
41117
- }
41118
-
41119
- function addPointToGridIndex(p, index, grid) {
41120
- var i = grid.pointToIdx(p);
41121
- var c = grid.idxToCol(i);
41122
- var r = grid.idxToRow(i);
41123
- addCellToGridIndex(c+1, r+1, grid, index);
41124
- addCellToGridIndex(c+1, r, grid, index);
41125
- addCellToGridIndex(c+1, r-1, grid, index);
41126
- addCellToGridIndex(c, r+1, grid, index);
41127
- addCellToGridIndex(c, r, grid, index);
41128
- addCellToGridIndex(c, r-1, grid, index);
41129
- addCellToGridIndex(c-1, r+1, grid, index);
41130
- addCellToGridIndex(c-1, r, grid, index);
41131
- addCellToGridIndex(c-1, r-1, grid, index);
41132
- }
41133
-
41134
- function addCellToGridIndex(c, r, grid, index) {
41135
- var i = grid.colRowToIdx(c, r);
41136
- if (i > -1) index.setId(i);
41137
- }
41138
-
41139
- // TODO: support spherical coords
41140
- function getPointBounds(p, radius) {
41141
- return [p[0] - radius, p[1] - radius, p[0] + radius, p[1] + radius];
41142
- }
41143
-
41144
- // grid boundaries includes the origin
41145
- // (this way, grids calculated from different sets of points will all align)
41146
- function getAlignedRange(minCoord, maxCoord, interval) {
41147
- var idx = Math.floor(minCoord / interval) - 1;
41148
- var idx2 = Math.ceil(maxCoord / interval) + 1;
41149
- return [idx * interval, idx2 * interval];
41150
- }
41151
-
41152
- function getCenteredRange(minCoord, maxCoord, interval) {
41153
- var w = maxCoord - minCoord;
41154
- var w2 = Math.ceil(w / interval) * interval;
41155
- var pad = (w2 - w) / 2 + interval;
41156
- return [minCoord - pad, maxCoord + pad];
41157
- }
41158
-
41159
- function getAlignedGridBounds(bbox, interval) {
41160
- var xx = getAlignedRange(bbox[0], bbox[2], interval);
41161
- var yy = getAlignedRange(bbox[1], bbox[3], interval);
41162
- return [xx[0], yy[0], xx[1], yy[1]];
41163
- }
41164
-
41165
- function getCenteredGridBounds(bbox, interval) {
41166
- var xx = getCenteredRange(bbox[0], bbox[2], interval);
41167
- var yy = getCenteredRange(bbox[1], bbox[3], interval);
41168
- return [xx[0], yy[0], xx[1], yy[1]];
41169
- }
41170
-
41171
- // TODO: Use this function for other grid-based commands
41172
- function getGridData(bbox, interval, opts) {
41173
- var extent = opts && opts.aligned ?
41174
- getAlignedGridBounds(bbox, interval) :
41175
- getCenteredGridBounds(bbox, interval);
41176
- var xmin = extent[0];
41177
- var ymin = extent[1];
41178
- var w = extent[2] - xmin;
41179
- var h = extent[3] - ymin;
41180
- var cols = Math.round(w / interval);
41181
- var rows = Math.round(h / interval);
41182
- // var xmin = bbox[0] - interval;
41183
- // var ymin = bbox[1] - interval;
41184
- // var xmax = bbox[2] + interval;
41185
- // var ymax = bbox[3] + interval;
41186
- // var w = xmax - xmin;
41187
- // var h = ymax - ymin;
41188
- // var cols = Math.ceil(w / interval);
41189
- // var rows = Math.ceil(h / interval);
41190
- function size() {
41191
- return [cols, rows];
41192
- }
41193
- function cells() {
41194
- return cols * rows;
41195
- }
41196
- function pointToCol(xy) {
41197
- var dx = xy[0] - xmin;
41198
- return Math.floor(dx / w * cols);
41199
- }
41200
- function pointToRow(xy) {
41201
- var dy = xy[1] - ymin;
41202
- return Math.floor(dy / h * rows);
41203
- }
41204
- function colRowToIdx(c, r) {
41205
- if (c < 0 || r < 0 || c >= cols || r >= rows) return -1;
41206
- return r * cols + c;
41207
- }
41208
- function pointToIdx(xy) {
41209
- var c = pointToCol(xy);
41210
- var r = pointToRow(xy);
41211
- return colRowToIdx(c, r);
41212
- }
41213
- function idxToCol(i) {
41214
- return i % cols;
41215
- }
41216
- function idxToRow(i) {
41217
- return Math.floor(i / cols);
41218
- }
41219
- function idxToPoint(idx) {
41220
- var x = xmin + (idxToCol(idx) + 0.5) * interval;
41221
- var y = ymin + (idxToRow(idx) + 0.5) * interval;
41222
- return [x, y];
41223
- }
41224
- function idxToBBox(idx) {
41225
- var c = idxToCol(idx);
41226
- var r = idxToRow(idx);
41227
- return [
41228
- xmin + c * interval, ymin + r * interval,
41229
- xmin + (c + 1) * interval, ymin + (r + 1) * interval
41230
- ];
41231
- }
41232
-
41233
- return {
41234
- size, cells, pointToCol, pointToRow, colRowToIdx, pointToIdx,
41235
- idxToCol, idxToRow, idxToBBox, idxToPoint
41236
- };
41237
- }
41244
+ // function getPointsByIndex(points, indices) {
41245
+ // var arr = [];
41246
+ // for (var i=0; i<indices.length; i++) {
41247
+ // arr.push(points[indices[i]]);
41248
+ // }
41249
+ // return arr;
41250
+ // }
41238
41251
 
41239
41252
  var PointToGrid = /*#__PURE__*/Object.freeze({
41240
41253
  __proto__: null,
41241
41254
  getPointCircleRadius: getPointCircleRadius,
41242
41255
  calcCellProperties: calcCellProperties,
41243
- calcWeights: calcWeights,
41244
- twoCircleIntersection: twoCircleIntersection,
41245
- makeCellPolygon: makeCellPolygon,
41246
- makeCircleCoords: makeCircleCoords,
41247
- getPointIndex: getPointIndex,
41248
- getAlignedGridBounds: getAlignedGridBounds,
41249
- getCenteredGridBounds: getCenteredGridBounds,
41250
- getGridData: getGridData
41256
+ calcWeights: calcWeights
41251
41257
  });
41252
41258
 
41253
41259
  function closeUndershoots(lyr, dataset, opts) {
@@ -41503,11 +41509,26 @@ ${svg}
41503
41509
  parseConsoleCommands: parseConsoleCommands
41504
41510
  });
41505
41511
 
41512
+ // import { importGeoJSON } from '../geojson/geojson-import';
41513
+
41506
41514
  function getTargetProxy(target) {
41507
41515
  var lyr = target.layers[0];
41508
- var data = getLayerInfo(lyr, target.dataset);
41516
+ var data = getLayerInfo(lyr, target.dataset); // layer_name, feature_count etc
41509
41517
  data.layer = lyr;
41510
41518
  data.dataset = target.dataset;
41519
+ addGetters(data, {
41520
+ // export as an object, not a string or buffer
41521
+ geojson: getGeoJSON
41522
+ });
41523
+
41524
+ function getGeoJSON() {
41525
+ var features = exportLayerAsGeoJSON(lyr, target.dataset, {rfc7946: true}, true);
41526
+ return {
41527
+ type: 'FeatureCollection',
41528
+ features: features
41529
+ };
41530
+ }
41531
+
41511
41532
  return data;
41512
41533
  }
41513
41534