mapshaper 0.6.73 → 0.6.75

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.
@@ -1144,10 +1144,18 @@
1144
1144
  return self;
1145
1145
  };
1146
1146
 
1147
- self.close = function() {
1148
- if (el) el.remove();
1147
+ self.close = function(action) {
1148
+ var ms = 0;
1149
+ var _el = el;
1150
+ if (action == 'fade' && _el) {
1151
+ ms = 1000;
1152
+ _el.addClass('fade-out');
1153
+ }
1149
1154
  if (_close) _close();
1150
1155
  el = _cancel = _close = null;
1156
+ setTimeout(function() {
1157
+ if (_el) _el.remove();
1158
+ }, ms);
1151
1159
  };
1152
1160
  return self;
1153
1161
  }
@@ -1753,6 +1761,9 @@
1753
1761
  }],
1754
1762
  info: {}
1755
1763
  };
1764
+ if (type == 'polygon' || type == 'point') {
1765
+ dataset.arcs = new internal.ArcCollection();
1766
+ }
1756
1767
  if (crsInfo) {
1757
1768
  internal.setDatasetCrsInfo(dataset, crsInfo);
1758
1769
  }
@@ -2426,7 +2437,10 @@
2426
2437
  }
2427
2438
 
2428
2439
  function error() {
2429
- stop.apply(null, utils$1.toArray(arguments));
2440
+ var msg = GUI.formatMessageArgs(arguments);
2441
+ console.error(msg);
2442
+ gui.alert('An unkown error occured');
2443
+ throw new Error(msg);
2430
2444
  }
2431
2445
 
2432
2446
  function message() {
@@ -2807,7 +2821,7 @@
2807
2821
  strokeWidth: 1.2,
2808
2822
  vertices: true,
2809
2823
  vertex_overlay_color: o.hit_type == 'vertex' ? violet : black,
2810
- vertex_overlay_scale: o.hit_type == 'vertex' ? 2.4 : 1.7,
2824
+ vertex_overlay_scale: o.hit_type == 'vertex' ? 2.5 : 2,
2811
2825
  vertex_overlay: o.hit_coordinates || null,
2812
2826
  selected_points: o.selected_points || null,
2813
2827
  fillColor: null
@@ -3025,6 +3039,11 @@
3025
3039
  return internal.getUnfilteredArcCoords(arcId, target.source.dataset.arcs);
3026
3040
  }
3027
3041
 
3042
+ function getLastVertexCoords(target) {
3043
+ var arcs = target.source.dataset.arcs;
3044
+ return internal.getVertexCoords(arcs.getPointCount() - 1, arcs);
3045
+ }
3046
+
3028
3047
  function getLastArcLength(target) {
3029
3048
  var arcId = target.source.dataset.arcs.size() - 1;
3030
3049
  return internal.getUnfilteredArcLength(arcId, target.source.dataset.arcs);
@@ -4920,13 +4939,10 @@
4920
4939
  return internal.getLayerSourceFile(lyr, dataset);
4921
4940
  }
4922
4941
 
4923
-
4924
4942
  function isPinnable(lyr) {
4925
- return internal.layerHasGeometry(lyr) || internal.layerHasFurniture(lyr);
4943
+ return internal.layerIsGeometric(lyr) || internal.layerHasFurniture(lyr);
4926
4944
  }
4927
4945
 
4928
-
4929
-
4930
4946
  function rowHTML(c1, c2, cname) {
4931
4947
  return utils$1.format('<div class="row%s"><div class="col1">%s</div>' +
4932
4948
  '<div class="col2">%s</div></div>', cname ? ' ' + cname : '', c1, c2);
@@ -5205,10 +5221,10 @@
5205
5221
 
5206
5222
  gui.on('path_extend', function(e) {
5207
5223
  var redo = function() {
5208
- gui.dispatchEvent('redo_path_extend', {p: e.p});
5224
+ gui.dispatchEvent('redo_path_extend', {p: e.p, shapes: e.shapes2});
5209
5225
  };
5210
5226
  var undo = function() {
5211
- gui.dispatchEvent('undo_path_extend');
5227
+ gui.dispatchEvent('undo_path_extend', {shapes: e.shapes1});
5212
5228
  };
5213
5229
  addHistoryState(undo, redo);
5214
5230
  });
@@ -5543,22 +5559,23 @@
5543
5559
  if (!o || !o.layer) {
5544
5560
  return menus.standard; // TODO: more sensible handling of missing layer
5545
5561
  }
5546
- if (!internal.layerHasGeometry(o.layer)) {
5562
+ if (!o.layer.geometry_type) {
5547
5563
  return menus.table;
5548
5564
  }
5549
5565
  if (internal.layerHasLabels(o.layer)) {
5550
5566
  return menus.labels;
5551
5567
  }
5552
- if (internal.layerHasPoints(o.layer)) {
5568
+ if (o.layer.geometry_type == 'point') {
5553
5569
  return menus.points;
5554
5570
  }
5555
- if (internal.layerHasPaths(o.layer) && o.layer.geometry_type == 'polyline') {
5571
+ if (o.layer.geometry_type == 'polyline') {
5556
5572
  return menus.lines;
5557
5573
  }
5558
- if (internal.layerHasPaths(o.layer) && o.layer.geometry_type == 'polygon') {
5574
+ if (o.layer.geometry_type == 'polygon') {
5559
5575
  return internal.layerOnlyHasRectangles(o.layer, o.dataset.arcs) ?
5560
5576
  menus.rectangles : menus.polygons;
5561
5577
  }
5578
+
5562
5579
  return menus.standard;
5563
5580
  }
5564
5581
 
@@ -5908,13 +5925,13 @@
5908
5925
  }
5909
5926
 
5910
5927
  // Format an array of (preferably short) strings in columns for console logging.
5911
- function formatStringsAsGrid(arr) {
5928
+ function formatStringsAsGrid(arr, width) {
5912
5929
  // TODO: variable column width
5913
5930
  var longest = arr.reduce(function(len, str) {
5914
5931
  return Math.max(len, str.length);
5915
5932
  }, 0),
5916
5933
  colWidth = longest + 2,
5917
- perLine = Math.floor(80 / colWidth) || 1;
5934
+ perLine = Math.floor((width || 80) / colWidth) || 1;
5918
5935
  return arr.reduce(function(memo, name, i) {
5919
5936
  var col = i % perLine;
5920
5937
  if (i > 0 && col === 0) memo += '\n';
@@ -6575,7 +6592,7 @@
6575
6592
  }
6576
6593
 
6577
6594
  function getGenericComparator(asc) {
6578
- asc = asc !== false;
6595
+ asc = asc !== false && asc != 'descending'; // ascending is the default
6579
6596
  return function(a, b) {
6580
6597
  var retn = 0;
6581
6598
  if (b == null) {
@@ -9262,6 +9279,7 @@
9262
9279
  } else {
9263
9280
  rec = getMultiRecord(recIds, table);
9264
9281
  }
9282
+ rec = rec || {};
9265
9283
  utils$1.forEachProperty(rec, function(v, k) {
9266
9284
  // missing GeoJSON fields are set to undefined on import; skip these
9267
9285
  if (v === undefined) return;
@@ -9709,12 +9727,14 @@
9709
9727
  var prevClickEvent;
9710
9728
  var prevHoverEvent;
9711
9729
  var initialArcCount = -1;
9730
+ var initialShapeCount = -1;
9712
9731
  var drawingId = -1; // feature id of path being drawn
9732
+ var sessionCount = 0;
9713
9733
  var alert;
9714
9734
  var _dragging = false;
9715
9735
 
9716
9736
  function active() {
9717
- return !!alert;
9737
+ return initialArcCount >= 0;
9718
9738
  }
9719
9739
 
9720
9740
  function dragging() {
@@ -9752,7 +9772,7 @@
9752
9772
  appendNewPath(target, e.p1, e.p2);
9753
9773
  deleteLastVertex(target); // second vertex is a placeholder
9754
9774
  gui.undo.redo(); // add next vertex in the path
9755
- gui.model.updated({arc_count: true});
9775
+ fullRedraw();
9756
9776
  });
9757
9777
 
9758
9778
  gui.on('undo_path_add', function(e) {
@@ -9768,8 +9788,28 @@
9768
9788
  } else {
9769
9789
  appendVertex$1(target, e.p);
9770
9790
  }
9791
+ if (e.shapes) {
9792
+ replaceShapes(e.shapes);
9793
+ }
9771
9794
  });
9772
9795
 
9796
+ function replaceShapes(shapes) {
9797
+ var target = hit.getHitTarget();
9798
+ var records = target.layer.data?.getRecords();
9799
+ var prevLen = target.layer.shapes.length;
9800
+ var newLen = initialShapeCount + shapes.length;
9801
+ var recordCount = records?.length || 0;
9802
+ target.layer.shapes = target.layer.shapes.slice(0, initialShapeCount).concat(shapes);
9803
+ while (records && records.length > newLen) {
9804
+ records.pop();
9805
+ }
9806
+ while (records && records.length < newLen) {
9807
+ appendNewDataRecord(target.layer);
9808
+ }
9809
+ }
9810
+
9811
+
9812
+
9773
9813
  gui.on('undo_path_extend', function(e) {
9774
9814
  var target = hit.getHitTarget();
9775
9815
  if (drawing() && prevHoverEvent) {
@@ -9781,72 +9821,70 @@
9781
9821
  if (getLastArcLength(target) < 2) {
9782
9822
  gui.undo.undo(); // remove the path
9783
9823
  }
9824
+ if (e.shapes) {
9825
+ replaceShapes(e.shapes);
9826
+ }
9784
9827
  });
9785
9828
 
9786
9829
  function turnOn() {
9787
9830
  var target = hit.getHitTarget();
9788
- var pathStr = polygonMode() ? 'closed paths' : 'paths';
9831
+ initialArcCount = target.arcs.size();
9832
+ initialShapeCount = target.layer.shapes.length;
9833
+ if (sessionCount === 0) {
9834
+ showInstructions();
9835
+ }
9836
+ sessionCount++;
9837
+ }
9838
+
9839
+ function showInstructions() {
9789
9840
  var isMac = navigator.userAgent.includes('Mac');
9790
9841
  var symbol = isMac ? '⌘' : '^';
9842
+ var pathStr = polygonMode() ? 'closed paths' : 'paths';
9791
9843
  var msg = `Instructions: Click on the map to draw ${pathStr}. Drag vertices to reshape a path. Type ${symbol}Z/${symbol}Y to undo/redo.`;
9792
- initialArcCount = hit.getHitTarget().arcs.size();
9793
- alert = showPopupAlert(msg, null, {non_blocking: true, max_width: '360px'});
9844
+ alert = showPopupAlert(msg, null, {
9845
+ non_blocking: true, max_width: '360px'});
9794
9846
  }
9795
9847
 
9796
9848
  function turnOff() {
9797
- finishPath();
9849
+ var removed = 0;
9850
+ finishCurrentPath();
9798
9851
  if (polygonMode()) {
9799
- finishPolygons();
9852
+ removed = removeOpenPolygons();
9800
9853
  }
9801
9854
  clearDrawingInfo();
9802
- alert.close();
9803
- alert = null;
9855
+ if (alert) {
9856
+ alert.close();
9857
+ alert = null;
9858
+ }
9804
9859
  initialArcCount = -1;
9860
+ initialShapeCount = -1;
9805
9861
  if (gui.interaction.getMode() == 'drawing') {
9806
9862
  // mode change was not initiated by interactive menu -- turn off interactivity
9807
9863
  gui.interaction.turnOff();
9808
9864
  }
9809
- }
9810
-
9811
- function finish() {
9812
- if (polygonMode()) {
9813
- finishPolygons();
9865
+ if (removed > 0) {
9866
+ fullRedraw();
9814
9867
  }
9815
9868
  }
9816
9869
 
9817
- function finishPolygons() {
9818
- // step1: make a polyline layer containing just newly drawn paths
9870
+ // returns number of removed shapes
9871
+ function removeOpenPolygons() {
9819
9872
  var target = hit.getHitTarget();
9820
- if (target.arcs.size() <= initialArcCount) return; // no paths added
9821
- var polygonLyr = target.source.layer;
9822
- var polygonRecords = polygonLyr.data ? polygonLyr.data.getRecords() : null;
9823
- var templateRecord;
9824
- if (polygonRecords) {
9825
- // use one of the newly created records as a template (they should all be the same)
9826
- templateRecord = polygonRecords.pop();
9827
- polygonRecords.splice(initialArcCount); // remove new records
9828
- }
9829
- var polylineLyr = {
9830
- geometry_type: 'polyline',
9831
- shapes: polygonLyr.shapes.splice(initialArcCount) // move new shapes to polyline layer
9832
- };
9833
-
9834
- // step2: convert polylines to polygons
9835
- //
9836
- // create a temp dataset containing both layers (so original arcs are preserved)
9837
- var tmp = Object.assign({}, target.source.dataset);
9838
- tmp.layers = tmp.layers.concat(polylineLyr);
9839
- var outputLayers = mapshaper.cmd.polygons([polylineLyr], tmp, {});
9840
-
9841
- // step3: add new polygons to the original polygons
9842
- outputLayers[0].shapes.forEach(function(shp) {
9843
- polygonLyr.shapes.push(shp);
9844
- if (polygonRecords) {
9845
- polygonRecords.push(internal.copyRecord(templateRecord));
9873
+ var arcs = target.source.dataset.arcs;
9874
+ var n = target.layer.shapes.length;
9875
+ // delete open paths (should only occur on single-arc shapes)
9876
+ for (var i=initialShapeCount; i<n; i++) {
9877
+ var shp = target.layer.shapes[i];
9878
+ if (!geom.pathIsClosed(shp[0], arcs)) {
9879
+ target.layer.shapes[i] = null;
9846
9880
  }
9847
- });
9881
+ }
9882
+ // removes polygons with wrong winding order and null geometry
9883
+ mapshaper.cmd.filterFeatures(target.layer, arcs, {remove_empty: true, quiet: true});
9884
+ return n - target.layer.shapes.length;
9885
+ }
9848
9886
 
9849
- // step4: update map
9887
+ function fullRedraw() {
9850
9888
  gui.model.updated({arc_count: true});
9851
9889
  }
9852
9890
 
@@ -9859,6 +9897,9 @@
9859
9897
 
9860
9898
  hit.on('dragstart', function(e) {
9861
9899
  if (!active() || drawing() || !hoverVertexInfo) return;
9900
+ if (alert) {
9901
+ alert.close('fade');
9902
+ }
9862
9903
  e.originalEvent.stopPropagation();
9863
9904
  _dragging = true;
9864
9905
  if (hoverVertexInfo.type == 'interpolated') {
@@ -9899,12 +9940,10 @@
9899
9940
  // double-click finishes a path (when drawing)
9900
9941
  hit.on('dblclick', function(e) {
9901
9942
  if (!active()) return;
9943
+ // double click finishes a path
9944
+ // note: if the preceding 'click' finished the path, this does not fire
9902
9945
  if (drawing()) {
9903
- // double click finishes a path
9904
- // before: dblclick is preceded by two clicks, need another vertex delete
9905
- // now: second click is suppressed
9906
- // deleteLastVertex(hit.getHitTarget());
9907
- finishPath();
9946
+ finishCurrentPath();
9908
9947
  e.originalEvent.stopPropagation(); // prevent dblclick zoom
9909
9948
  return;
9910
9949
  }
@@ -9916,7 +9955,7 @@
9916
9955
  if (!active() || dragging()) return;
9917
9956
  if (drawing()) {
9918
9957
  if (!e.overMap) {
9919
- finishPath();
9958
+ finishCurrentPath();
9920
9959
  return;
9921
9960
  }
9922
9961
  if (gui.keyboard.shiftIsPressed()) {
@@ -9944,27 +9983,27 @@
9944
9983
  if (!active()) return;
9945
9984
  if (detectDoubleClick(e)) return; // ignore second click of a dblclick
9946
9985
  var p = pixToDataCoords(e.x, e.y);
9947
- if (drawing() && hoverVertexInfo) {
9948
- // finish the path if a vertex is highlighted
9949
- p = hoverVertexInfo.point;
9950
- extendPath(p);
9951
- finishPath();
9952
- } else if (drawing()) {
9953
- extendPath(p);
9986
+ if (drawing()) {
9987
+ extendCurrentPath(hoverVertexInfo?.point || p);
9988
+ // extendCurrentPath(p); // just extend to current mouse position (not hover vertex)
9954
9989
  } else if (gui.keyboard.shiftIsPressed()) {
9955
9990
  deleteActiveVertex(e);
9956
9991
  } else {
9957
- startPath(p);
9992
+ startNewPath(p);
9993
+ if (alert) {
9994
+ alert.close('fade');
9995
+ }
9958
9996
  }
9959
9997
  prevClickEvent = e;
9960
9998
  });
9961
9999
 
9962
10000
  // esc key finishes a path
9963
10001
  gui.keyboard.on('keydown', function(e) {
9964
- if (active() && e.keyName == 'esc') {
9965
- finishPath();
10002
+ if (active() && (e.keyName == 'esc' || e.keyName == 'enter')) {
10003
+ e.stopPropagation();
10004
+ finishCurrentPath();
9966
10005
  }
9967
- });
10006
+ }, null, 10);
9968
10007
 
9969
10008
  // detect second 'click' event of a double-click action
9970
10009
  function detectDoubleClick(evt) {
@@ -10032,7 +10071,7 @@
10032
10071
  thisEvt.y = snapped.y;
10033
10072
  }
10034
10073
 
10035
- function finishPath() {
10074
+ function finishCurrentPath() {
10036
10075
  if (!drawing()) return;
10037
10076
  var target = hit.getHitTarget();
10038
10077
  if (getLastArcLength(target) <= 2) { // includes hover point
@@ -10041,27 +10080,44 @@
10041
10080
  deleteLastVertex(target);
10042
10081
  }
10043
10082
  clearDrawingInfo();
10044
- gui.model.updated({arc_count: true});
10083
+ fullRedraw();
10045
10084
  }
10046
10085
 
10047
10086
  // p: [x, y] source data coordinates
10048
- function startPath(p2) {
10087
+ function startNewPath(p2) {
10049
10088
  var target = hit.getHitTarget();
10050
- var p1 = hoverVertexInfo ? hoverVertexInfo.point : p2;
10089
+ var p1 = hoverVertexInfo?.point || p2;
10051
10090
  appendNewPath(target, p1, p2);
10052
10091
  gui.dispatchEvent('path_add', {target, p1, p2});
10053
10092
  drawingId = target.layer.shapes.length - 1;
10054
10093
  hit.setDrawingId(drawingId);
10055
10094
  }
10056
10095
 
10057
- // p: [x, y] source data coordinates
10058
- function extendPath(p) {
10096
+ // p: [x, y] source data coordinates of new point on path
10097
+ function extendCurrentPath(p) {
10059
10098
  var target = hit.getHitTarget();
10060
- if (getLastArcLength(target) >= 2) {
10099
+ var shapes1, shapes2;
10100
+ // finish the path if a vertex is selected (but not an interpolated point)
10101
+ var finish = hoverVertexInfo?.type == 'vertex';
10102
+ if (getLastArcLength(target) < 2) {
10103
+ error$1('Defective path');
10104
+ }
10105
+ if (finish && polygonMode()) {
10106
+ shapes1 = target.layer.shapes.slice(initialShapeCount);
10107
+ shapes2 = tryToClosePath(shapes1);
10108
+ }
10109
+ if (shapes2) {
10110
+ replaceShapes(shapes2);
10111
+ gui.dispatchEvent('path_extend', {target, p, shapes1, shapes2});
10112
+ clearDrawingInfo();
10113
+ fullRedraw();
10114
+
10115
+ } else {
10116
+ appendVertex$1(target, p);
10061
10117
  gui.dispatchEvent('path_extend', {target, p});
10118
+ hit.triggerChangeEvent(); // trigger overlay redraw
10062
10119
  }
10063
- appendVertex$1(target, p);
10064
- hit.triggerChangeEvent();
10120
+
10065
10121
  }
10066
10122
 
10067
10123
  // p: [x, y] source data coordinates
@@ -10156,6 +10212,55 @@
10156
10212
  return closest;
10157
10213
  }
10158
10214
 
10215
+ // shapes: shapes that have been drawn in the current session
10216
+ //
10217
+ function tryToClosePath(shapes) {
10218
+ var target = hit.getHitTarget();
10219
+ var tmpLyr = {
10220
+ geometry_type: 'polyline',
10221
+ shapes: shapes.concat()
10222
+ };
10223
+ // create a temp dataset containing tmp layer and original layers
10224
+ // (so original arcs are retained)
10225
+ var tmpDataset = Object.assign({}, target.source.dataset);
10226
+ tmpDataset.layers = tmpDataset.layers.concat(tmpLyr);
10227
+ // NOTE: added "no_cuts" option to prevent polygons function from modifying
10228
+ // arcs, which would break undo/redo and cause other problems
10229
+ var outputLyr = mapshaper.cmd.polygons([tmpLyr], tmpDataset, {no_cuts: true})[0];
10230
+ var isOpenPath = getOpenPathTest(outputLyr.shapes);
10231
+ var shapes2 = [];
10232
+ shapes.forEach(function(shp) {
10233
+ if (isOpenPath(shp)) {
10234
+ shapes2.push(shp);
10235
+ }
10236
+ });
10237
+ return shapes2.concat(outputLyr.shapes);
10238
+ }
10239
+
10240
+ // Returns a function for testing if a shape is an unclosed path, and doesn't
10241
+ // overlap with an array of polygon shapes
10242
+ // polygons: array of polygon shapes
10243
+ function getOpenPathTest(polygons) {
10244
+ var arcs = [];
10245
+ internal.forEachArcId(polygons, function(arcId) {
10246
+ if (arcId < 0) arcId = ~arcId;
10247
+ arcs.push(arcId);
10248
+ });
10249
+ return function(shp) {
10250
+ // assume that compound shapes are already polygons
10251
+ var isOpen = false;
10252
+ if (shapeHasOneFwdArc(shp)) {
10253
+ var arcId = shp[0][0];
10254
+ if (arcId < 0) arcId = ~arcId;
10255
+ isOpen = !arcs.includes(arcId);
10256
+ }
10257
+ return isOpen;
10258
+ };
10259
+ }
10260
+
10261
+ function shapeHasOneFwdArc(shp) {
10262
+ return shp.length == 1 && shp[0].length == 1 && shp[0][0] >= 0;
10263
+ }
10159
10264
  }
10160
10265
 
10161
10266
  function initPointDrawing(gui, ext, hit) {
@@ -10752,8 +10857,8 @@
10752
10857
  function getArcsForRendering(obj, ext) {
10753
10858
  var dataset = obj.source.dataset;
10754
10859
  var sourceArcs = dataset.arcs;
10755
- if (obj.geographic && dataset.displayArcs) {
10756
- return dataset.displayArcs.getScaledArcs(ext);
10860
+ if (obj.geographic && dataset.gui?.displayArcs) {
10861
+ return dataset.gui.displayArcs.getScaledArcs(ext);
10757
10862
  }
10758
10863
  return obj.arcs;
10759
10864
  }
@@ -11760,6 +11865,10 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
11760
11865
 
11761
11866
  // Only generate low-detail arcs for larger datasets
11762
11867
  if (size > 5e5) {
11868
+ update();
11869
+ }
11870
+
11871
+ function update() {
11763
11872
  if (unfilteredArcs.getVertexData().zz) {
11764
11873
  // Use precalculated simplification data for vertex filtering, if available
11765
11874
  filteredArcs = initFilteredArcs(unfilteredArcs);
@@ -11783,6 +11892,14 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
11783
11892
 
11784
11893
  // TODO: better job of detecting arc change... e.g. revision number
11785
11894
  unfilteredArcs.getScaledArcs = function(ext) {
11895
+ // check for changes in the number of arcs (probably due to editing)
11896
+ if (filteredArcs && filteredArcs.size() != unfilteredArcs.size()) {
11897
+ // arc count has changed... probably due to editing
11898
+ update();
11899
+ if (filteredArcs.size() != unfilteredArcs.size()) {
11900
+ throw Error('Internal error');
11901
+ }
11902
+ }
11786
11903
  if (filteredArcs) {
11787
11904
  // match simplification of unfiltered arcs
11788
11905
  filteredArcs.setRetainedInterval(unfilteredArcs.getRetainedInterval());
@@ -11861,10 +11978,10 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
11861
11978
  //if (!lyr.geographic || !sourceCRS) {
11862
11979
  // let getDisplayLayer() handle case of unprojectable source
11863
11980
  if (!lyr.geographic) {
11864
- return lyr;
11981
+ return;
11865
11982
  }
11866
11983
  if (lyr.dynamic_crs && internal.crsAreEqual(sourceCRS, lyr.dynamic_crs)) {
11867
- return lyr;
11984
+ return;
11868
11985
  }
11869
11986
  lyr2 = getDisplayLayer(lyr.source.layer, lyr.source.dataset, {crs: displayCRS});
11870
11987
  // kludge: copy projection-related properties to original layer
@@ -11900,7 +12017,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
11900
12017
 
11901
12018
  var displayCRS = opts.crs || null;
11902
12019
  // display arcs may have been generated when another layer in the dataset was converted for display... re-use if available
11903
- var displayArcs = dataset.displayArcs || null;
12020
+ var displayArcs = dataset.gui?.displayArcs || null;
11904
12021
  var sourceCRS;
11905
12022
  var emptyArcs;
11906
12023
 
@@ -11917,7 +12034,8 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
11917
12034
 
11918
12035
  // Assume that dataset.displayArcs is in the display CRS
11919
12036
  // (it must be deleted upstream if reprojection is needed)
11920
- if (!obj.empty && dataset.arcs && !displayArcs) {
12037
+ // if (!obj.empty && dataset.arcs && !displayArcs) {
12038
+ if (dataset.arcs && !displayArcs) {
11921
12039
  // project arcs, if needed
11922
12040
  if (needReprojectionForDisplay(sourceCRS, displayCRS)) {
11923
12041
  displayArcs = projectArcsForDisplay(dataset.arcs, sourceCRS, displayCRS);
@@ -11927,7 +12045,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
11927
12045
  }
11928
12046
 
11929
12047
  enhanceArcCollectionForDisplay(displayArcs);
11930
- dataset.displayArcs = displayArcs; // stash these in the dataset for other layers to use
12048
+ dataset.gui = {displayArcs}; // stash these in the dataset for other layers to use
11931
12049
  }
11932
12050
 
11933
12051
  if (internal.layerHasFurniture(layer)) {
@@ -11939,14 +12057,14 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
11939
12057
  // treating furniture layers (other than frame) as tabular for now,
11940
12058
  // so there is something to show if they are selected
11941
12059
  // obj.tabular = obj.furniture_type != 'frame';
11942
- } else if (obj.empty) {
11943
- obj.layer = {shapes: []}; // ideally we should avoid empty layers
11944
- } else if (!layer.geometry_type) {
11945
- obj.tabular = true;
11946
- } else {
12060
+ } else if (layer.geometry_type) {
11947
12061
  obj.geographic = true;
11948
12062
  obj.layer = layer;
11949
12063
  obj.arcs = displayArcs;
12064
+ } else if (!obj.empty) {
12065
+ obj.tabular = true;
12066
+ } else {
12067
+ obj.layer = {shapes: []}; // ideally we should avoid empty layers
11950
12068
  }
11951
12069
 
11952
12070
  if (obj.tabular) {
@@ -12371,13 +12489,13 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
12371
12489
  updateFullBounds();
12372
12490
  };
12373
12491
 
12374
- function getGlobalStyleOptions() {
12492
+ function getGlobalStyleOptions(opts) {
12375
12493
  var mode = gui.state.interaction_mode;
12376
- return {
12494
+ return Object.assign({
12377
12495
  darkMode: !!gui.state.dark_basemap,
12378
12496
  outlineMode: mode == 'vertices',
12379
12497
  interactionMode: mode
12380
- };
12498
+ }, opts);
12381
12499
  }
12382
12500
 
12383
12501
  // Refresh map display in response to data changes, layer selection, etc.
@@ -12392,7 +12510,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
12392
12510
 
12393
12511
  if (arcsMayHaveChanged(e.flags)) {
12394
12512
  // regenerate filtered arcs the next time they are needed for rendering
12395
- // delete e.dataset.displayArcs;
12513
+ // delete e.dataset.gui.displayArcs
12396
12514
  clearAllDisplayArcs();
12397
12515
 
12398
12516
  // reset simplification after projection (thresholds have changed)
@@ -12490,7 +12608,8 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
12490
12608
  }
12491
12609
 
12492
12610
  function getStrictBounds() {
12493
- if (internal.isWebMercator(map.getDisplayCRS())) {
12611
+ // if (internal.isWebMercator(map.getDisplayCRS())) {
12612
+ if (_dynamicCRS && internal.isWebMercator(map.getDisplayCRS())) {
12494
12613
  return getMapboxBounds();
12495
12614
  }
12496
12615
  return null;
@@ -12568,7 +12687,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
12568
12687
 
12569
12688
  function clearAllDisplayArcs() {
12570
12689
  model.getDatasets().forEach(function(o) {
12571
- delete o.displayArcs;
12690
+ delete o.gui;
12572
12691
  });
12573
12692
  }
12574
12693