mapshaper 0.6.98 → 0.6.100

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.
@@ -876,16 +876,36 @@
876
876
  };
877
877
 
878
878
  // Filter out delayed click events, e.g. so users can highlight and copy text
879
+ // Filter out context menu clicks
879
880
  GUI.onClick = function(el, cb) {
880
881
  var time;
881
882
  el.on('mousedown', function() {
882
883
  time = +new Date();
883
884
  });
884
885
  el.on('mouseup', function(e) {
885
- if (+new Date() - time < 300) cb(e);
886
+ if (looksLikeContextClick(e)) {
887
+ return;
888
+ }
889
+ if (+new Date() - time < 300) {
890
+ cb(e);
891
+ }
886
892
  });
887
893
  };
888
894
 
895
+ GUI.onContextClick = function(el, cb) {
896
+ el.on('mouseup', function(e) {
897
+ if (looksLikeContextClick(e)) {
898
+ e.stopPropagation();
899
+ e.preventDefault();
900
+ cb(e);
901
+ }
902
+ });
903
+ };
904
+
905
+ function looksLikeContextClick(e) {
906
+ return e.button > 1 || e.ctrlKey;
907
+ }
908
+
889
909
  // tests if filename is a type that can be used
890
910
  // GUI.isReadableFileType = function(filename) {
891
911
  // return !!internal.guessInputFileType(filename) || internal.couldBeDsvFile(filename) ||
@@ -1089,6 +1109,103 @@
1089
1109
  return _el;
1090
1110
  }
1091
1111
 
1112
+ function filterLayerByIds(lyr, ids) {
1113
+ var shapes;
1114
+ if (lyr.shapes) {
1115
+ shapes = ids.map(function(id) {
1116
+ return lyr.shapes[id];
1117
+ });
1118
+ return utils$1.defaults({shapes: shapes, data: null}, lyr);
1119
+ }
1120
+ return lyr;
1121
+ }
1122
+
1123
+ function formatLayerNameForDisplay(name) {
1124
+ return name || '[unnamed]';
1125
+ }
1126
+
1127
+ function cleanLayerName(raw) {
1128
+ return raw.replace(/[\n\t/\\]/g, '')
1129
+ .replace(/^[.\s]+/, '').replace(/[.\s]+$/, '');
1130
+ }
1131
+
1132
+ function updateLayerStackOrder(layers) {
1133
+ // 1. assign ascending ids to unassigned layers above the range of other layers
1134
+ layers.forEach(function(o, i) {
1135
+ if (!o.layer.menu_order) o.layer.menu_order = 1e6 + i;
1136
+ });
1137
+ // 2. sort in ascending order
1138
+ layers.sort(function(a, b) {
1139
+ return a.layer.menu_order - b.layer.menu_order;
1140
+ });
1141
+ // 3. assign consecutve ids
1142
+ layers.forEach(function(o, i) {
1143
+ o.layer.menu_order = i + 1;
1144
+ });
1145
+ return layers;
1146
+ }
1147
+
1148
+ function sortLayersForMenuDisplay(layers) {
1149
+ layers = updateLayerStackOrder(layers);
1150
+ return layers.reverse();
1151
+ }
1152
+
1153
+ function setLayerPinning(lyr, pinned) {
1154
+ lyr.pinned = !!pinned;
1155
+ }
1156
+
1157
+
1158
+ function adjustPointSymbolSizes(layers, overlayLyr, ext) {
1159
+ var bbox = ext.getBounds().scale(1.5).toArray();
1160
+ var testInBounds = function(p) {
1161
+ return p[0] > bbox[0] && p[0] < bbox[2] && p[1] > bbox[1] && p[1] < bbox[3];
1162
+ };
1163
+ var topTier = 50000;
1164
+ var count = 0;
1165
+ layers = layers.filter(function(lyr) {
1166
+ return lyr.geometry_type == 'point' && lyr.gui.style.dotSize > 0;
1167
+ });
1168
+ layers.forEach(function(lyr) {
1169
+ // short-circuit point counting above top threshold
1170
+ count += countPoints(lyr.gui.displayLayer.shapes, topTier, testInBounds);
1171
+ });
1172
+ count = Math.min(topTier, count) || 1;
1173
+ var k = Math.pow(6 - utils$1.clamp(Math.log10(count), 1, 5), 1.3);
1174
+
1175
+ // zoom adjustments
1176
+ var mapScale = ext.scale();
1177
+ if (mapScale < 0.5) {
1178
+ k *= Math.pow(mapScale + 0.5, 0.35);
1179
+ } else if (mapScale > 1) {
1180
+ // scale faster at first
1181
+ k *= Math.pow(Math.min(mapScale, 4), 0.15);
1182
+ k *= Math.pow(mapScale, 0.05);
1183
+ }
1184
+
1185
+ // scale down when map is small
1186
+ var smallSide = Math.min(ext.width(), ext.height());
1187
+ k *= utils$1.clamp(smallSide / 500, 0.5, 1);
1188
+
1189
+ layers.forEach(function(lyr) {
1190
+ lyr.gui.style.dotScale = k;
1191
+ });
1192
+ if (overlayLyr && overlayLyr.geometry_type == 'point' && overlayLyr.gui.style.dotSize > 0) {
1193
+ overlayLyr.gui.style.dotScale = k;
1194
+ }
1195
+ }
1196
+
1197
+ function countPoints(shapes, max, filter) {
1198
+ var count = 0;
1199
+ var i, j, n, m, shp;
1200
+ for (i=0, n=shapes.length; i<n && count<max; i++) {
1201
+ shp = shapes[i];
1202
+ for (j=0, m=(shp ? shp.length : 0); j<m; j++) {
1203
+ count += filter(shp[j]) ? 1 : 0;
1204
+ }
1205
+ }
1206
+ return count;
1207
+ }
1208
+
1092
1209
  async function showPrompt(msg, title) {
1093
1210
  var popup = showPopupAlert(msg, title);
1094
1211
  return new Promise(function(resolve) {
@@ -1971,7 +2088,12 @@
1971
2088
  model.setDefaultTarget([target.layers[0]], target.dataset);
1972
2089
  }
1973
2090
  }
1974
- model.updated({select: true});
2091
+ if (opts.display_all && importTotal === 0) {
2092
+ model.getLayers().forEach(function(o) {
2093
+ setLayerPinning(o.layer, true);
2094
+ });
2095
+ }
2096
+ model.updated({select: true}); // trigger redraw
1975
2097
  }
1976
2098
 
1977
2099
  function clearQueuedFiles() {
@@ -3206,99 +3328,6 @@
3206
3328
  }
3207
3329
  }
3208
3330
 
3209
- function filterLayerByIds(lyr, ids) {
3210
- var shapes;
3211
- if (lyr.shapes) {
3212
- shapes = ids.map(function(id) {
3213
- return lyr.shapes[id];
3214
- });
3215
- return utils$1.defaults({shapes: shapes, data: null}, lyr);
3216
- }
3217
- return lyr;
3218
- }
3219
-
3220
- function formatLayerNameForDisplay(name) {
3221
- return name || '[unnamed]';
3222
- }
3223
-
3224
- function cleanLayerName(raw) {
3225
- return raw.replace(/[\n\t/\\]/g, '')
3226
- .replace(/^[.\s]+/, '').replace(/[.\s]+$/, '');
3227
- }
3228
-
3229
- function updateLayerStackOrder(layers) {
3230
- // 1. assign ascending ids to unassigned layers above the range of other layers
3231
- layers.forEach(function(o, i) {
3232
- if (!o.layer.menu_order) o.layer.menu_order = 1e6 + i;
3233
- });
3234
- // 2. sort in ascending order
3235
- layers.sort(function(a, b) {
3236
- return a.layer.menu_order - b.layer.menu_order;
3237
- });
3238
- // 3. assign consecutve ids
3239
- layers.forEach(function(o, i) {
3240
- o.layer.menu_order = i + 1;
3241
- });
3242
- return layers;
3243
- }
3244
-
3245
- function sortLayersForMenuDisplay(layers) {
3246
- layers = updateLayerStackOrder(layers);
3247
- return layers.reverse();
3248
- }
3249
-
3250
-
3251
- function adjustPointSymbolSizes(layers, overlayLyr, ext) {
3252
- var bbox = ext.getBounds().scale(1.5).toArray();
3253
- var testInBounds = function(p) {
3254
- return p[0] > bbox[0] && p[0] < bbox[2] && p[1] > bbox[1] && p[1] < bbox[3];
3255
- };
3256
- var topTier = 50000;
3257
- var count = 0;
3258
- layers = layers.filter(function(lyr) {
3259
- return lyr.geometry_type == 'point' && lyr.gui.style.dotSize > 0;
3260
- });
3261
- layers.forEach(function(lyr) {
3262
- // short-circuit point counting above top threshold
3263
- count += countPoints(lyr.gui.displayLayer.shapes, topTier, testInBounds);
3264
- });
3265
- count = Math.min(topTier, count) || 1;
3266
- var k = Math.pow(6 - utils$1.clamp(Math.log10(count), 1, 5), 1.3);
3267
-
3268
- // zoom adjustments
3269
- var mapScale = ext.scale();
3270
- if (mapScale < 0.5) {
3271
- k *= Math.pow(mapScale + 0.5, 0.35);
3272
- } else if (mapScale > 1) {
3273
- // scale faster at first
3274
- k *= Math.pow(Math.min(mapScale, 4), 0.15);
3275
- k *= Math.pow(mapScale, 0.05);
3276
- }
3277
-
3278
- // scale down when map is small
3279
- var smallSide = Math.min(ext.width(), ext.height());
3280
- k *= utils$1.clamp(smallSide / 500, 0.5, 1);
3281
-
3282
- layers.forEach(function(lyr) {
3283
- lyr.gui.style.dotScale = k;
3284
- });
3285
- if (overlayLyr && overlayLyr.geometry_type == 'point' && overlayLyr.gui.style.dotSize > 0) {
3286
- overlayLyr.gui.style.dotScale = k;
3287
- }
3288
- }
3289
-
3290
- function countPoints(shapes, max, filter) {
3291
- var count = 0;
3292
- var i, j, n, m, shp;
3293
- for (i=0, n=shapes.length; i<n && count<max; i++) {
3294
- shp = shapes[i];
3295
- for (j=0, m=(shp ? shp.length : 0); j<m; j++) {
3296
- count += filter(shp[j]) ? 1 : 0;
3297
- }
3298
- }
3299
- return count;
3300
- }
3301
-
3302
3331
  // lyr: a map layer with gui property
3303
3332
  // displayCRS: CRS to use for display, or null (which clears any current display CRS)
3304
3333
  function projectLayerForDisplay(lyr, displayCRS) {
@@ -4994,6 +5023,201 @@
4994
5023
  };
4995
5024
  }
4996
5025
 
5026
+ var openMenu;
5027
+
5028
+ document.addEventListener('mousedown', function(e) {
5029
+ if (e.target.classList.contains('contextmenu-item')) {
5030
+ return; // don't close menu if clicking on a menu link
5031
+ }
5032
+ closeOpenMenu();
5033
+ });
5034
+
5035
+ function closeOpenMenu() {
5036
+ if (openMenu) {
5037
+ openMenu.close();
5038
+ openMenu = null;
5039
+ }
5040
+ }
5041
+
5042
+ function openContextMenu(e, lyr, parent) {
5043
+ var menu = new ContextMenu(parent);
5044
+ closeOpenMenu();
5045
+ menu.open(e, lyr);
5046
+ }
5047
+
5048
+ function ContextMenu(parentArg) {
5049
+ var body = document.querySelector('body');
5050
+ var parent = parentArg || body;
5051
+ // var menu = El('div').addClass('contextmenu rollover').appendTo(body);
5052
+ var menu = El('div').addClass('contextmenu rollover').appendTo(parent);
5053
+ var _open = false;
5054
+ var _openCount = 0;
5055
+
5056
+ this.isOpen = function() {
5057
+ return _open;
5058
+ };
5059
+
5060
+ this.close = close;
5061
+
5062
+ function close() {
5063
+ var count = _openCount;
5064
+ if (!_open) return;
5065
+ setTimeout(function() {
5066
+ if (count == _openCount) {
5067
+ menu.hide();
5068
+ _open = false;
5069
+ }
5070
+ }, 200);
5071
+ }
5072
+
5073
+ function addMenuItem(label, func, prefixArg) {
5074
+ var prefix = prefixArg === undefined ? '• &nbsp;' : prefixArg;
5075
+ var item = El('div')
5076
+ .appendTo(menu)
5077
+ .addClass('contextmenu-item')
5078
+ .html(prefix + label)
5079
+ .show();
5080
+
5081
+ GUI.onClick(item, function(e) {
5082
+ func();
5083
+ closeOpenMenu();
5084
+ });
5085
+ }
5086
+
5087
+ function addMenuLabel(label) {
5088
+ El('div')
5089
+ .appendTo(menu)
5090
+ .addClass('contextmenu-label')
5091
+ .html(label);
5092
+ }
5093
+
5094
+ this.open = function(e, lyr) {
5095
+ var copyable = e.ids?.length;
5096
+ if (_open) close();
5097
+ menu.empty();
5098
+
5099
+ if (openMenu && openMenu != this) {
5100
+ openMenu.close();
5101
+ }
5102
+ openMenu = this;
5103
+
5104
+ if (e.deleteLayer) {
5105
+ addMenuItem('delete layer', e.deleteLayer, '');
5106
+ }
5107
+ if (e.selectLayer) {
5108
+ addMenuItem('select layer', e.selectLayer, '');
5109
+ }
5110
+
5111
+ if (lyr && lyr.gui.geographic) {
5112
+ if (e.deleteVertex || e.deletePoint || copyable || e.deleteFeature) {
5113
+
5114
+ addMenuLabel('selection');
5115
+ if (e.deleteVertex) {
5116
+ addMenuItem('delete vertex', e.deleteVertex);
5117
+ }
5118
+ if (e.deletePoint) {
5119
+ addMenuItem('delete point', e.deletePoint);
5120
+ }
5121
+ if (e.ids?.length) {
5122
+ addMenuItem('copy as GeoJSON', copyGeoJSON);
5123
+ }
5124
+ if (e.deleteFeature) {
5125
+ addMenuItem(getDeleteLabel(), e.deleteFeature);
5126
+ }
5127
+ }
5128
+
5129
+ if (e.lonlat_coordinates) {
5130
+ addMenuLabel('longitude, latitude');
5131
+ addCoords(e.lonlat_coordinates);
5132
+ }
5133
+ if (e.projected_coordinates) {
5134
+ addMenuLabel('x, y');
5135
+ addCoords(e.projected_coordinates);
5136
+ }
5137
+ }
5138
+
5139
+ if (menu.node().childNodes.length === 0) {
5140
+ return;
5141
+ }
5142
+
5143
+ var rspace = body.clientWidth - e.pageX;
5144
+ var offs = getParentOffset();
5145
+ var xoffs = 10;
5146
+ if (rspace > 150) {
5147
+ menu.css('left', e.pageX - offs.left + xoffs + 'px');
5148
+ menu.css('right', null);
5149
+ } else {
5150
+ menu.css('right', (body.clientWidth - e.pageX - offs.left + xoffs) + 'px');
5151
+ menu.css('left', null);
5152
+ }
5153
+ menu.css('top', (e.pageY - offs.top - 15) + 'px');
5154
+ menu.show();
5155
+
5156
+ _open = true;
5157
+ _openCount++;
5158
+
5159
+ function getParentOffset() { // crossbrowser version
5160
+ if (parent == body) {
5161
+ return {top: 0, left: 0};
5162
+ }
5163
+
5164
+ var box = parent.getBoundingClientRect();
5165
+ var docEl = document.documentElement;
5166
+
5167
+ var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
5168
+ var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;
5169
+
5170
+ var clientTop = docEl.clientTop || body.clientTop || 0;
5171
+ var clientLeft = docEl.clientLeft || body.clientLeft || 0;
5172
+
5173
+ var top = box.top + scrollTop - clientTop;
5174
+ var left = box.left + scrollLeft - clientLeft;
5175
+
5176
+ return { top: Math.round(top), left: Math.round(left) };
5177
+ }
5178
+
5179
+ function getDeleteLabel() {
5180
+ return 'delete ' + (lyr.geometry_type == 'point' ? 'point' : 'shape');
5181
+ }
5182
+
5183
+ function addCoords(p) {
5184
+ var coordStr = p[0] + ',' + p[1];
5185
+ // var displayStr = '• &nbsp;' + coordStr.replace(/-/g, '–').replace(',', ', ');
5186
+ var displayStr = coordStr.replace(/-/g, '–').replace(',', ', ');
5187
+ addMenuItem(displayStr, function() {
5188
+ saveFileContentToClipboard(coordStr);
5189
+ });
5190
+ }
5191
+
5192
+ function copyGeoJSON() {
5193
+ var opts = {
5194
+ no_replace: true,
5195
+ ids: e.ids,
5196
+ quiet: true
5197
+ };
5198
+ var dataset = lyr.gui.source.dataset;
5199
+ var layer = mapshaper.cmd.filterFeatures(lyr, dataset.arcs, opts);
5200
+ // the drawing tool can send open paths with 'polygon' geometry type,
5201
+ // should be changed to 'polyline'
5202
+ if (layer.geometry_type == 'polygon' && layerHasOpenPaths(layer, dataset.arcs)) {
5203
+ layer.geometry_type = 'polyline';
5204
+ }
5205
+ var features = internal.exportLayerAsGeoJSON(layer, dataset, {rfc7946: true, prettify: true}, true, 'string');
5206
+ var str = internal.geojson.formatCollection({"type": "FeatureCollection"}, features);
5207
+ saveFileContentToClipboard(str);
5208
+ }
5209
+ };
5210
+ }
5211
+
5212
+
5213
+ function layerHasOpenPaths(layer, arcs) {
5214
+ var retn = false;
5215
+ internal.editShapes(layer.shapes, function(part) {
5216
+ if (!geom.pathIsClosed(part, arcs)) retn = true;
5217
+ });
5218
+ return retn;
5219
+ }
5220
+
4997
5221
  function LayerControl(gui) {
4998
5222
  var model = gui.model;
4999
5223
  var map = gui.map;
@@ -5029,7 +5253,7 @@
5029
5253
  pinAll.on('click', function() {
5030
5254
  var allOn = testAllLayersPinned();
5031
5255
  model.getLayers().forEach(function(target) {
5032
- map.setLayerPinning(target, !allOn);
5256
+ setLayerPinning(target.layer, !allOn);
5033
5257
  });
5034
5258
  El.findAll('.pinnable', el.node()).forEach(function(item) {
5035
5259
  El(item).classed('pinned', !allOn);
@@ -5200,8 +5424,8 @@
5200
5424
 
5201
5425
  html = '<!-- ' + lyr.menu_id + '--><div class="' + classes + '">';
5202
5426
  html += rowHTML('name', '<span class="layer-name colored-text dot-underline">' + formatLayerNameForDisplay(lyr.name) + '</span>', 'row1');
5203
- html += rowHTML('contents', describeLyr(lyr));
5204
- html += '<img class="close-btn" draggable="false" src="images/close.png">';
5427
+ html += rowHTML('contents', describeLyr(lyr, dataset));
5428
+ // html += '<img class="close-btn" draggable="false" src="images/close.png">';
5205
5429
  if (opts.pinnable) {
5206
5430
  html += '<img class="eye-btn black-eye" draggable="false" src="images/eye.png">';
5207
5431
  html += '<img class="eye-btn green-eye" draggable="false" src="images/eye2.png">';
@@ -5259,16 +5483,35 @@
5259
5483
  function initMouseEvents2(entry, id, pinnable) {
5260
5484
  initLayerDragging(entry, id);
5261
5485
 
5262
- // init delete button
5263
- GUI.onClick(entry.findChild('img.close-btn'), function(e) {
5486
+ function deleteLayer() {
5264
5487
  var target = findLayerById(id);
5265
- e.stopPropagation();
5266
5488
  if (map.isVisibleLayer(target.layer)) {
5267
5489
  // TODO: check for double map refresh after model.deleteLayer() below
5268
- map.setLayerPinning(target, false);
5490
+ setLayerPinning(target.layer, false);
5269
5491
  }
5270
5492
  model.deleteLayer(target.layer, target.dataset);
5271
- });
5493
+ }
5494
+
5495
+ function selectLayer(closeMenu) {
5496
+ var target = findLayerById(id);
5497
+ // don't select if user is typing or dragging
5498
+ if (GUI.textIsSelected() || dragging) return;
5499
+ // undo any temporary hiding when layer is selected
5500
+ target.layer.hidden = false;
5501
+ if (!map.isActiveLayer(target.layer)) {
5502
+ model.selectLayer(target.layer, target.dataset);
5503
+ }
5504
+ // close menu after a delay
5505
+ if (closeMenu === true) setTimeout(function() {
5506
+ gui.clearMode();
5507
+ }, 230);
5508
+ }
5509
+
5510
+ // init delete button
5511
+ // GUI.onClick(entry.findChild('img.close-btn'), function(e) {
5512
+ // e.stopPropagation();
5513
+ // deleteLayer();
5514
+ // });
5272
5515
 
5273
5516
  if (pinnable) {
5274
5517
  // init pin button
@@ -5289,7 +5532,7 @@
5289
5532
  }
5290
5533
  lyr.hidden = hidden;
5291
5534
  lyr.unpinned = unpinned;
5292
- map.setLayerPinning(target, pinned);
5535
+ setLayerPinning(lyr, pinned);
5293
5536
  entry.classed('pinned', pinned);
5294
5537
  entry.classed('invisible', hidden);
5295
5538
  updatePinAllButton();
@@ -5315,30 +5558,30 @@
5315
5558
 
5316
5559
  // init click-to-select
5317
5560
  GUI.onClick(entry, function() {
5318
- var target = findLayerById(id);
5319
- // don't select if user is typing or dragging
5320
- if (GUI.textIsSelected() || dragging) return;
5321
- // undo any temporary hiding when layer is selected
5322
- target.layer.hidden = false;
5323
- if (!map.isActiveLayer(target.layer)) {
5324
- model.selectLayer(target.layer, target.dataset);
5325
- }
5326
- // close menu after a delay
5327
- setTimeout(function() {
5328
- gui.clearMode();
5329
- }, 230);
5561
+ selectLayer(true);
5562
+ });
5563
+
5564
+ GUI.onContextClick(entry, function(e) {
5565
+ e.deleteLayer = deleteLayer;
5566
+ e.selectLayer = selectLayer;
5567
+ // contextMenu.open(e);
5568
+ // openContextMenu(e, null, entry.node())
5569
+ openContextMenu(e, null, null);
5330
5570
  });
5331
5571
  }
5332
5572
 
5333
- function describeLyr(lyr) {
5573
+ function describeLyr(lyr, dataset) {
5334
5574
  var n = internal.getFeatureCount(lyr),
5575
+ isFrame = internal.isFrameLayer(lyr, dataset.arcs),
5335
5576
  str, type;
5336
5577
  if (lyr.data && !lyr.shapes) {
5337
5578
  type = 'data record';
5338
5579
  } else if (lyr.geometry_type) {
5339
5580
  type = lyr.geometry_type + ' feature';
5340
5581
  }
5341
- if (type) {
5582
+ if (isFrame) {
5583
+ str = 'map frame';
5584
+ } else if (type) {
5342
5585
  str = utils$1.format('%,d %s%s', n, type, utils$1.pluralSuffix(n));
5343
5586
  } else {
5344
5587
  str = "[empty]";
@@ -12477,10 +12720,6 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
12477
12720
  drawLayers();
12478
12721
  };
12479
12722
 
12480
- this.setLayerPinning = function(target, pinned) {
12481
- target.layer.pinned = !!pinned;
12482
- };
12483
-
12484
12723
  this.pixelCoordsToLngLatCoords = function(x, y) {
12485
12724
  var crsFrom = this.getDisplayCRS();
12486
12725
  if (!crsFrom) return null; // e.g. table view
@@ -12904,11 +13143,13 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
12904
13143
  updateLayerStyles(contentLayers);
12905
13144
  updateLayerStackOrder(model.getLayers());// update menu_order property of all layers
12906
13145
  }
12907
- adjustPointSymbolSizes(contentLayers, _overlayLyr, _ext);
12908
13146
  sortMapLayers(contentLayers);
12909
13147
  if (_intersectionLyr) {
12910
13148
  contentLayers = contentLayers.concat(_intersectionLyr);
12911
13149
  }
13150
+ // moved this below intersection layer addition, so intersection dots get scaled
13151
+ adjustPointSymbolSizes(contentLayers, _overlayLyr, _ext);
13152
+
12912
13153
  // RENDERING
12913
13154
  // draw main content layers
12914
13155
  _renderer.drawMainLayers(contentLayers, action);
@@ -12954,139 +13195,6 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
12954
13195
  });
12955
13196
  }
12956
13197
 
12957
- function ContextMenu() {
12958
- var body = document.querySelector('body');
12959
- var menu = El('div').addClass('contextmenu rollover').appendTo(body);
12960
- var _open = false;
12961
- var _openCount = 0;
12962
- document.addEventListener('mousedown', close);
12963
-
12964
- this.isOpen = function() {
12965
- return _open;
12966
- };
12967
-
12968
- function close() {
12969
- var count = _openCount;
12970
- if (!_open) return;
12971
- setTimeout(function() {
12972
- if (count == _openCount) {
12973
- menu.hide();
12974
- _open = false;
12975
- }
12976
- }, 200);
12977
- }
12978
-
12979
- function addMenuItem(label, func) {
12980
- var prefix = '• &nbsp;';
12981
-
12982
- El('div')
12983
- .appendTo(menu)
12984
- .addClass('contextmenu-item')
12985
- .html(prefix + label)
12986
- .on('click', func)
12987
- .show();
12988
- }
12989
-
12990
- function addMenuLabel(label) {
12991
- El('div')
12992
- .appendTo(menu)
12993
- .addClass('contextmenu-label')
12994
- .html(label);
12995
- }
12996
-
12997
- this.open = function(e, lyr) {
12998
- var copyable = e.ids?.length;
12999
- if (lyr && !lyr.gui.geographic) return; // no popup for tabular data
13000
- menu.empty();
13001
-
13002
- // menu contents
13003
- //
13004
- if (e.deleteVertex || e.deletePoint || copyable || e.deleteFeature) {
13005
-
13006
- addMenuLabel('selection');
13007
- if (e.deleteVertex) {
13008
- addMenuItem('delete vertex', e.deleteVertex);
13009
- }
13010
- if (e.deletePoint) {
13011
- addMenuItem('delete point', e.deletePoint);
13012
- }
13013
- if (e.ids?.length) {
13014
- addMenuItem('copy as GeoJSON', copyGeoJSON);
13015
- }
13016
- if (e.deleteFeature) {
13017
- addMenuItem(getDeleteLabel(), e.deleteFeature);
13018
- }
13019
- }
13020
-
13021
- if (e.lonlat_coordinates) {
13022
- addMenuLabel('longitude, latitude');
13023
- addCoords(e.lonlat_coordinates);
13024
- }
13025
- if (e.projected_coordinates) {
13026
- addMenuLabel('x, y');
13027
- addCoords(e.projected_coordinates);
13028
- }
13029
-
13030
- if (menu.node().childNodes.length === 0) {
13031
- return;
13032
- }
13033
-
13034
- _open = true;
13035
- _openCount++;
13036
- var rspace = body.clientWidth - e.pageX;
13037
- var xoffs = 10;
13038
- if (rspace > 150) {
13039
- menu.css('left', e.pageX + xoffs + 'px');
13040
- menu.css('right', null);
13041
- } else {
13042
- menu.css('right', (body.clientWidth - e.pageX + xoffs) + 'px');
13043
- menu.css('left', null);
13044
- }
13045
- menu.css('top', (e.pageY - 15) + 'px');
13046
- menu.show();
13047
-
13048
- function getDeleteLabel() {
13049
- return 'delete ' + (lyr.geometry_type == 'point' ? 'point' : 'shape');
13050
- }
13051
-
13052
- function addCoords(p) {
13053
- var coordStr = p[0] + ',' + p[1];
13054
- // var displayStr = '• &nbsp;' + coordStr.replace(/-/g, '–').replace(',', ', ');
13055
- var displayStr = coordStr.replace(/-/g, '–').replace(',', ', ');
13056
- addMenuItem(displayStr, function() {
13057
- saveFileContentToClipboard(coordStr);
13058
- });
13059
- }
13060
-
13061
- function copyGeoJSON() {
13062
- var opts = {
13063
- no_replace: true,
13064
- ids: e.ids,
13065
- quiet: true
13066
- };
13067
- var dataset = lyr.gui.source.dataset;
13068
- var layer = mapshaper.cmd.filterFeatures(lyr, dataset.arcs, opts);
13069
- // the drawing tool can send open paths with 'polygon' geometry type,
13070
- // should be changed to 'polyline'
13071
- if (layer.geometry_type == 'polygon' && layerHasOpenPaths(layer, dataset.arcs)) {
13072
- layer.geometry_type = 'polyline';
13073
- }
13074
- var features = internal.exportLayerAsGeoJSON(layer, dataset, {rfc7946: true, prettify: true}, true, 'string');
13075
- var str = internal.geojson.formatCollection({"type": "FeatureCollection"}, features);
13076
- saveFileContentToClipboard(str);
13077
- }
13078
- };
13079
- }
13080
-
13081
-
13082
- function layerHasOpenPaths(layer, arcs) {
13083
- var retn = false;
13084
- internal.editShapes(layer.shapes, function(part) {
13085
- if (!geom.pathIsClosed(part, arcs)) retn = true;
13086
- });
13087
- return retn;
13088
- }
13089
-
13090
13198
  function loadScript(url, cb) {
13091
13199
  var script = document.createElement('script');
13092
13200
  script.onload = cb;
@@ -13558,14 +13666,9 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
13558
13666
  dataLoaded = true;
13559
13667
  gui.buttons.show();
13560
13668
  gui.basemap.show();
13561
- El('#mode-buttons').show();
13562
- El('#splash-buttons').hide();
13669
+ El('#mode-buttons').show(); // show Simplify, Console, Export, etc.
13670
+ El('#splash-buttons').hide(); // hide Wiki, Github buttons
13563
13671
  El('body').addClass('map-view');
13564
- if (importOpts.display_all) {
13565
- gui.model.getLayers().forEach(function(o) {
13566
- gui.map.setLayerPinning(o, true);
13567
- });
13568
- }
13569
13672
  gui.console.runInitialCommands(getInitialConsoleCommands());
13570
13673
  });
13571
13674
  };