mapshaper 0.7.12 → 0.7.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/mapshaper.js +252 -99
- package/package.json +1 -1
- package/www/index.html +27 -29
- package/www/mapshaper-gui.js +365 -102
- package/www/mapshaper.js +252 -99
- package/www/page.css +247 -110
package/www/mapshaper-gui.js
CHANGED
|
@@ -6097,6 +6097,7 @@
|
|
|
6097
6097
|
// gui.container.addClass('queued-files');
|
|
6098
6098
|
El('#import-options').show();
|
|
6099
6099
|
gui.container.classed('queued-files', queuedFiles.length > 0);
|
|
6100
|
+
updateSidebarTabZIndex();
|
|
6100
6101
|
El('#path-import-options').classed('hidden', !filesMayContainPaths(queuedFiles));
|
|
6101
6102
|
showQueuedFiles();
|
|
6102
6103
|
updateGeoPackageLayerSelectionMenu();
|
|
@@ -6104,9 +6105,15 @@
|
|
|
6104
6105
|
|
|
6105
6106
|
function hideImportMenu() {
|
|
6106
6107
|
// gui.container.removeClass('queued-files');
|
|
6108
|
+
gui.container.removeClass('sidebar-tabs-over-popup');
|
|
6107
6109
|
El('#import-options').hide();
|
|
6108
6110
|
}
|
|
6109
6111
|
|
|
6112
|
+
function updateSidebarTabZIndex() {
|
|
6113
|
+
gui.container.classed('sidebar-tabs-over-popup',
|
|
6114
|
+
queuedFiles.length === 0 && !gui.sidebarPanelIsOpen());
|
|
6115
|
+
}
|
|
6116
|
+
|
|
6110
6117
|
function getFileNames(files) {
|
|
6111
6118
|
return Array.from(files).map(function(f) {return f.name;});
|
|
6112
6119
|
}
|
|
@@ -7927,7 +7934,7 @@
|
|
|
7927
7934
|
function Console(gui) {
|
|
7928
7935
|
var model = gui.model;
|
|
7929
7936
|
var CURSOR = '$ ';
|
|
7930
|
-
var PROMPT = 'Enter mapshaper commands or type "tips" for
|
|
7937
|
+
var PROMPT = 'Enter mapshaper commands or type "tips" for console help.';
|
|
7931
7938
|
var el = gui.container.findChild('.console').hide();
|
|
7932
7939
|
var content = el.findChild('.console-buffer');
|
|
7933
7940
|
var log = El('div').appendTo(content);
|
|
@@ -7948,6 +7955,7 @@
|
|
|
7948
7955
|
.on('keydown', function(e) {
|
|
7949
7956
|
if (e.key == 'Enter' || e.key == ' ') {
|
|
7950
7957
|
e.preventDefault();
|
|
7958
|
+
e.stopPropagation();
|
|
7951
7959
|
toggle();
|
|
7952
7960
|
}
|
|
7953
7961
|
});
|
|
@@ -7963,7 +7971,7 @@
|
|
|
7963
7971
|
this.runCommand = function(str) {
|
|
7964
7972
|
str = str.trim();
|
|
7965
7973
|
if (!str) return;
|
|
7966
|
-
|
|
7974
|
+
gui.setSidebarPanel('console');
|
|
7967
7975
|
submit(str);
|
|
7968
7976
|
};
|
|
7969
7977
|
|
|
@@ -7981,10 +7989,17 @@
|
|
|
7981
7989
|
});
|
|
7982
7990
|
|
|
7983
7991
|
function toggle() {
|
|
7984
|
-
|
|
7985
|
-
else turnOn();
|
|
7992
|
+
gui.toggleSidebarPanel('console');
|
|
7986
7993
|
}
|
|
7987
7994
|
|
|
7995
|
+
gui.on('sidebar', function(e) {
|
|
7996
|
+
if (e.name == 'console') {
|
|
7997
|
+
turnOn();
|
|
7998
|
+
} else if (e.prev == 'console') {
|
|
7999
|
+
turnOff();
|
|
8000
|
+
}
|
|
8001
|
+
});
|
|
8002
|
+
|
|
7988
8003
|
function getHistory() {
|
|
7989
8004
|
return GUI.getSavedValue('console_history') || [];
|
|
7990
8005
|
}
|
|
@@ -8004,10 +8019,30 @@
|
|
|
8004
8019
|
scrollDown();
|
|
8005
8020
|
}
|
|
8006
8021
|
|
|
8022
|
+
function toLogNode(node, cname) {
|
|
8023
|
+
var msg = El('div').appendTo(log);
|
|
8024
|
+
if (cname) {
|
|
8025
|
+
msg.addClass(cname);
|
|
8026
|
+
}
|
|
8027
|
+
msg.node().appendChild(node);
|
|
8028
|
+
scrollDown();
|
|
8029
|
+
}
|
|
8030
|
+
|
|
8031
|
+
function getStructuredConsoleMessage(args) {
|
|
8032
|
+
var arr = utils$1.toArray(args);
|
|
8033
|
+
var msg;
|
|
8034
|
+
// print() sends its arguments as one array argument.
|
|
8035
|
+
if (arr.length == 1 && Array.isArray(arr[0])) {
|
|
8036
|
+
arr = arr[0];
|
|
8037
|
+
}
|
|
8038
|
+
msg = arr[arr.length - 1];
|
|
8039
|
+
return msg && msg.type && /^mapshaper-console-/.test(msg.type) ? msg : null;
|
|
8040
|
+
}
|
|
8041
|
+
|
|
8007
8042
|
function turnOn() {
|
|
8008
8043
|
// if (!_isOpen && !model.isEmpty()) {
|
|
8009
8044
|
if (!_isOpen) {
|
|
8010
|
-
btn.addClass('active');
|
|
8045
|
+
btn.addClass('active').attr('aria-expanded', 'true');
|
|
8011
8046
|
_isOpen = true;
|
|
8012
8047
|
// Route logging output to the in-app console while it's open, so a
|
|
8013
8048
|
// user typing CLI commands here sees the results inline -- the same
|
|
@@ -8019,9 +8054,7 @@
|
|
|
8019
8054
|
// gui instances with the console open. E.g. console could close
|
|
8020
8055
|
// when an instance loses focus.
|
|
8021
8056
|
internal.setLoggingFunctions(consoleMessage, consoleError, consoleStop, consoleWarn);
|
|
8022
|
-
gui.container.addClass('console-open');
|
|
8023
8057
|
el.show();
|
|
8024
|
-
gui.dispatchEvent('resize');
|
|
8025
8058
|
input.node().focus();
|
|
8026
8059
|
history = getHistory();
|
|
8027
8060
|
}
|
|
@@ -8029,7 +8062,7 @@
|
|
|
8029
8062
|
|
|
8030
8063
|
function turnOff() {
|
|
8031
8064
|
if (_isOpen) {
|
|
8032
|
-
btn.removeClass('active');
|
|
8065
|
+
btn.removeClass('active').attr('aria-expanded', 'false');
|
|
8033
8066
|
_isOpen = false;
|
|
8034
8067
|
if (GUI.isActiveInstance(gui)) {
|
|
8035
8068
|
setLoggingForGUI(gui); // reset stop, message and error functions
|
|
@@ -8037,8 +8070,6 @@
|
|
|
8037
8070
|
el.hide();
|
|
8038
8071
|
input.node().blur();
|
|
8039
8072
|
saveHistory();
|
|
8040
|
-
gui.container.removeClass('console-open');
|
|
8041
|
-
gui.dispatchEvent('resize');
|
|
8042
8073
|
}
|
|
8043
8074
|
}
|
|
8044
8075
|
|
|
@@ -8098,7 +8129,7 @@
|
|
|
8098
8129
|
if (gui.getMode()) {
|
|
8099
8130
|
gui.clearMode(); // esc closes any open panels
|
|
8100
8131
|
} else {
|
|
8101
|
-
|
|
8132
|
+
gui.setSidebarPanel(null);
|
|
8102
8133
|
}
|
|
8103
8134
|
capture = true;
|
|
8104
8135
|
|
|
@@ -8134,8 +8165,8 @@
|
|
|
8134
8165
|
} else if (kc == 40) {
|
|
8135
8166
|
forward();
|
|
8136
8167
|
} else if (kc == 32 && (!typing || (inputText === '' && typingInConsole))) {
|
|
8137
|
-
// space bar
|
|
8138
|
-
|
|
8168
|
+
// space bar toggles the sidebar if nothing has been typed
|
|
8169
|
+
gui.toggleSidebar();
|
|
8139
8170
|
} else if (!typing && e.target != input.node() && !metaKey(e)) {
|
|
8140
8171
|
// typing returns focus, unless a meta key is down (to allow Cmd-C copy)
|
|
8141
8172
|
// or user is typing in a different input area somewhere
|
|
@@ -8152,9 +8183,9 @@
|
|
|
8152
8183
|
|
|
8153
8184
|
// various shortcuts (while not typing in an input field or editable el)
|
|
8154
8185
|
} else if (!typing) {
|
|
8155
|
-
if (kc == 32) { // space bar
|
|
8186
|
+
if (kc == 32) { // space bar toggles the sidebar
|
|
8156
8187
|
capture = true;
|
|
8157
|
-
|
|
8188
|
+
gui.toggleSidebar();
|
|
8158
8189
|
// } else if (kc == 73) { // letter i opens inspector
|
|
8159
8190
|
// gui.dispatchEvent('interaction_toggle');
|
|
8160
8191
|
} else if (kc == 72) { // letter h resets map extent
|
|
@@ -8535,9 +8566,15 @@
|
|
|
8535
8566
|
}
|
|
8536
8567
|
|
|
8537
8568
|
function consoleMessage() {
|
|
8538
|
-
var
|
|
8569
|
+
var structured = getStructuredConsoleMessage(arguments);
|
|
8570
|
+
var msg;
|
|
8539
8571
|
if (internal.loggingEnabled()) {
|
|
8540
|
-
|
|
8572
|
+
if (structured) {
|
|
8573
|
+
toLogNode(renderStructuredConsoleMessage(structured), 'console-message');
|
|
8574
|
+
} else {
|
|
8575
|
+
msg = GUI.formatMessageArgs(arguments);
|
|
8576
|
+
toLog(msg, 'console-message');
|
|
8577
|
+
}
|
|
8541
8578
|
}
|
|
8542
8579
|
}
|
|
8543
8580
|
|
|
@@ -8562,6 +8599,137 @@
|
|
|
8562
8599
|
printExample("Clear the console", "$ clear");
|
|
8563
8600
|
}
|
|
8564
8601
|
|
|
8602
|
+
function renderStructuredConsoleMessage(msg) {
|
|
8603
|
+
if (msg.type == 'mapshaper-console-help') {
|
|
8604
|
+
return renderHelpMessage(msg.lines);
|
|
8605
|
+
}
|
|
8606
|
+
if (msg.type == 'mapshaper-console-info') {
|
|
8607
|
+
return renderInfoMessage(msg.layers);
|
|
8608
|
+
}
|
|
8609
|
+
return document.createTextNode('');
|
|
8610
|
+
}
|
|
8611
|
+
|
|
8612
|
+
function renderHelpMessage(lines) {
|
|
8613
|
+
var container = document.createElement('div');
|
|
8614
|
+
var rows = [];
|
|
8615
|
+
container.className = 'console-help';
|
|
8616
|
+
(lines || []).forEach(function(line) {
|
|
8617
|
+
if (Array.isArray(line)) {
|
|
8618
|
+
rows.push(line);
|
|
8619
|
+
} else {
|
|
8620
|
+
flushRows();
|
|
8621
|
+
appendHelpLine(container, line);
|
|
8622
|
+
}
|
|
8623
|
+
});
|
|
8624
|
+
flushRows();
|
|
8625
|
+
return container;
|
|
8626
|
+
|
|
8627
|
+
function flushRows() {
|
|
8628
|
+
if (rows.length > 0) {
|
|
8629
|
+
container.appendChild(renderKeyValueTable(rows, 'console-help-table'));
|
|
8630
|
+
rows = [];
|
|
8631
|
+
}
|
|
8632
|
+
}
|
|
8633
|
+
}
|
|
8634
|
+
|
|
8635
|
+
function appendHelpLine(container, line) {
|
|
8636
|
+
var div = document.createElement('div');
|
|
8637
|
+
div.className = line ? 'console-help-line' : 'console-help-spacer';
|
|
8638
|
+
div.textContent = line || '';
|
|
8639
|
+
container.appendChild(div);
|
|
8640
|
+
}
|
|
8641
|
+
|
|
8642
|
+
function renderInfoMessage(layers) {
|
|
8643
|
+
var container = document.createElement('div');
|
|
8644
|
+
container.className = 'console-info';
|
|
8645
|
+
(layers || []).forEach(function(info) {
|
|
8646
|
+
var section = document.createElement('div');
|
|
8647
|
+
var title = document.createElement('div');
|
|
8648
|
+
section.className = 'console-info-layer';
|
|
8649
|
+
title.className = 'console-info-title';
|
|
8650
|
+
title.textContent = 'Layer: ' + (info.layer_name || '[unnamed layer]');
|
|
8651
|
+
section.appendChild(title);
|
|
8652
|
+
section.appendChild(renderKeyValueTable(getInfoRows(info), 'console-info-table'));
|
|
8653
|
+
section.appendChild(renderAttributeInfoTable(info.attribute_data));
|
|
8654
|
+
container.appendChild(section);
|
|
8655
|
+
});
|
|
8656
|
+
return container;
|
|
8657
|
+
}
|
|
8658
|
+
|
|
8659
|
+
function getInfoRows(info) {
|
|
8660
|
+
var rows = [
|
|
8661
|
+
['Type', info.geometry_type || 'tabular data'],
|
|
8662
|
+
['Records', utils$1.format('%,d', info.feature_count)]
|
|
8663
|
+
];
|
|
8664
|
+
if (info.null_shape_count > 0) {
|
|
8665
|
+
rows.push(['Nulls', utils$1.format("%'d", info.null_shape_count)]);
|
|
8666
|
+
}
|
|
8667
|
+
if (info.geometry_type && info.feature_count > info.null_shape_count) {
|
|
8668
|
+
rows.push(['Bounds', info.bbox.join(',')]);
|
|
8669
|
+
rows.push(['CRS', info.proj4]);
|
|
8670
|
+
}
|
|
8671
|
+
rows.push(['Source', info.source_file || 'n/a']);
|
|
8672
|
+
return rows;
|
|
8673
|
+
}
|
|
8674
|
+
|
|
8675
|
+
function renderAttributeInfoTable(fields) {
|
|
8676
|
+
var wrapper = document.createElement('div');
|
|
8677
|
+
var title = document.createElement('div');
|
|
8678
|
+
wrapper.className = 'console-attribute-info';
|
|
8679
|
+
title.className = 'console-info-subtitle';
|
|
8680
|
+
title.textContent = 'Attribute data';
|
|
8681
|
+
wrapper.appendChild(title);
|
|
8682
|
+
if (!fields) {
|
|
8683
|
+
var none = document.createElement('div');
|
|
8684
|
+
none.className = 'console-info-empty';
|
|
8685
|
+
none.textContent = '[none]';
|
|
8686
|
+
wrapper.appendChild(none);
|
|
8687
|
+
return wrapper;
|
|
8688
|
+
}
|
|
8689
|
+
wrapper.appendChild(renderDataTable(
|
|
8690
|
+
[['Field', 'First value']].concat(fields.map(function(o) {
|
|
8691
|
+
var valKey = 'first_value' in o ? 'first_value' : 'value';
|
|
8692
|
+
return [o.field, formatInfoValue(o[valKey])];
|
|
8693
|
+
})),
|
|
8694
|
+
'console-attribute-table'
|
|
8695
|
+
));
|
|
8696
|
+
return wrapper;
|
|
8697
|
+
}
|
|
8698
|
+
|
|
8699
|
+
function renderKeyValueTable(rows, className) {
|
|
8700
|
+
return renderDataTable(rows, className + ' console-key-value-table');
|
|
8701
|
+
}
|
|
8702
|
+
|
|
8703
|
+
function renderDataTable(rows, className) {
|
|
8704
|
+
var table = document.createElement('table');
|
|
8705
|
+
var tbody = document.createElement('tbody');
|
|
8706
|
+
table.className = className;
|
|
8707
|
+
rows.forEach(function(row, i) {
|
|
8708
|
+
var tr = document.createElement('tr');
|
|
8709
|
+
row.forEach(function(val) {
|
|
8710
|
+
var cell = document.createElement(i === 0 && rows.length > 1 && className == 'console-attribute-table' ? 'th' : 'td');
|
|
8711
|
+
cell.textContent = val == null ? '' : String(val);
|
|
8712
|
+
tr.appendChild(cell);
|
|
8713
|
+
});
|
|
8714
|
+
tbody.appendChild(tr);
|
|
8715
|
+
});
|
|
8716
|
+
table.appendChild(tbody);
|
|
8717
|
+
return table;
|
|
8718
|
+
}
|
|
8719
|
+
|
|
8720
|
+
function formatInfoValue(val) {
|
|
8721
|
+
if (val === null || val === undefined) return '';
|
|
8722
|
+
if (utils$1.isString(val)) {
|
|
8723
|
+
return "'" + val.replace(/[\r\t\n]/g, function(c) {
|
|
8724
|
+
return c == '\n' ? '\\n' : c == '\r' ? '\\r' : '\\t';
|
|
8725
|
+
}) + "'";
|
|
8726
|
+
}
|
|
8727
|
+
if (utils$1.isNumber(val) || val === true || val === false) {
|
|
8728
|
+
return String(val);
|
|
8729
|
+
}
|
|
8730
|
+
return JSON.stringify(val);
|
|
8731
|
+
}
|
|
8732
|
+
|
|
8565
8733
|
function saveRuntimeContext() {
|
|
8566
8734
|
var json = stringifyRuntimeStateContext(gui);
|
|
8567
8735
|
saveBlobToLocalFile2('mapshaper-runtime-context.json', new Blob([json], {type: 'application/json'}));
|
|
@@ -9148,6 +9316,7 @@
|
|
|
9148
9316
|
}
|
|
9149
9317
|
|
|
9150
9318
|
var openMenu;
|
|
9319
|
+
var openMenuId;
|
|
9151
9320
|
|
|
9152
9321
|
document.addEventListener('mousedown', function(e) {
|
|
9153
9322
|
if (e.target.classList.contains('contextmenu-item')) {
|
|
@@ -9156,17 +9325,23 @@
|
|
|
9156
9325
|
closeOpenMenu();
|
|
9157
9326
|
});
|
|
9158
9327
|
|
|
9159
|
-
function closeOpenMenu() {
|
|
9328
|
+
function closeOpenMenu(immediate) {
|
|
9160
9329
|
if (openMenu) {
|
|
9161
|
-
openMenu.close();
|
|
9330
|
+
openMenu.close(immediate);
|
|
9162
9331
|
openMenu = null;
|
|
9332
|
+
openMenuId = null;
|
|
9163
9333
|
}
|
|
9164
9334
|
}
|
|
9165
9335
|
|
|
9166
9336
|
function openContextMenu(e, lyr, parent) {
|
|
9167
9337
|
var menu = new ContextMenu(parent);
|
|
9168
|
-
|
|
9338
|
+
if (e.contextMenuId && e.contextMenuId == openMenuId) {
|
|
9339
|
+
closeOpenMenu(true);
|
|
9340
|
+
return;
|
|
9341
|
+
}
|
|
9342
|
+
closeOpenMenu(true);
|
|
9169
9343
|
menu.open(e, lyr);
|
|
9344
|
+
openMenuId = e.contextMenuId || null;
|
|
9170
9345
|
}
|
|
9171
9346
|
|
|
9172
9347
|
function ContextMenu(parentArg) {
|
|
@@ -9183,9 +9358,14 @@
|
|
|
9183
9358
|
|
|
9184
9359
|
this.close = close;
|
|
9185
9360
|
|
|
9186
|
-
function close() {
|
|
9361
|
+
function close(immediate) {
|
|
9187
9362
|
var count = _openCount;
|
|
9188
9363
|
if (!_open) return;
|
|
9364
|
+
if (immediate) {
|
|
9365
|
+
menu.hide();
|
|
9366
|
+
_open = false;
|
|
9367
|
+
return;
|
|
9368
|
+
}
|
|
9189
9369
|
setTimeout(function() {
|
|
9190
9370
|
if (count == _openCount) {
|
|
9191
9371
|
menu.hide();
|
|
@@ -9346,8 +9526,10 @@
|
|
|
9346
9526
|
function LayerControl(gui) {
|
|
9347
9527
|
var model = gui.model;
|
|
9348
9528
|
var map = gui.map;
|
|
9349
|
-
var el = gui.container.findChild(".layer-control")
|
|
9529
|
+
var el = gui.container.findChild(".layer-control");
|
|
9350
9530
|
var btn = gui.container.findChild('.layer-control-btn');
|
|
9531
|
+
var headerBtn = btn.findChild('.active-layer-label');
|
|
9532
|
+
var tab = gui.container.findChild('.layer-tab');
|
|
9351
9533
|
var isOpen = false;
|
|
9352
9534
|
var cache = new DomCache();
|
|
9353
9535
|
var pinAll = el.findChild('.pin-all'); // button for toggling layer visibility
|
|
@@ -9357,7 +9539,34 @@
|
|
|
9357
9539
|
var dragging = false;
|
|
9358
9540
|
var layerOrderSlug;
|
|
9359
9541
|
|
|
9360
|
-
|
|
9542
|
+
headerBtn.on('click', function() {
|
|
9543
|
+
toggle();
|
|
9544
|
+
}).on('keydown', function(e) {
|
|
9545
|
+
if (e.key == 'Enter' || e.key == ' ') {
|
|
9546
|
+
e.preventDefault();
|
|
9547
|
+
e.stopPropagation();
|
|
9548
|
+
toggle();
|
|
9549
|
+
}
|
|
9550
|
+
});
|
|
9551
|
+
tab.on('click', toggle).on('keydown', function(e) {
|
|
9552
|
+
if (e.key == 'Enter' || e.key == ' ') {
|
|
9553
|
+
e.preventDefault();
|
|
9554
|
+
e.stopPropagation();
|
|
9555
|
+
toggle();
|
|
9556
|
+
}
|
|
9557
|
+
});
|
|
9558
|
+
|
|
9559
|
+
function toggle() {
|
|
9560
|
+
gui.toggleSidebarPanel('layers');
|
|
9561
|
+
}
|
|
9562
|
+
|
|
9563
|
+
gui.on('sidebar', function(e) {
|
|
9564
|
+
if (e.name == 'layers') {
|
|
9565
|
+
turnOn();
|
|
9566
|
+
} else if (e.prev == 'layers') {
|
|
9567
|
+
turnOff();
|
|
9568
|
+
}
|
|
9569
|
+
});
|
|
9361
9570
|
|
|
9362
9571
|
// kludge to show menu button after initial import dialog is dismissed
|
|
9363
9572
|
gui.on('mode', function(e) {
|
|
@@ -9443,53 +9652,33 @@
|
|
|
9443
9652
|
}
|
|
9444
9653
|
|
|
9445
9654
|
function turnOn() {
|
|
9655
|
+
if (isOpen) return;
|
|
9446
9656
|
isOpen = true;
|
|
9447
|
-
|
|
9657
|
+
tab.addClass('active').attr('aria-expanded', 'true');
|
|
9448
9658
|
render();
|
|
9449
9659
|
el.show();
|
|
9450
9660
|
}
|
|
9451
9661
|
|
|
9452
9662
|
function turnOff() {
|
|
9663
|
+
if (!isOpen) return;
|
|
9453
9664
|
stopDragging();
|
|
9454
9665
|
isOpen = false;
|
|
9666
|
+
tab.removeClass('active').attr('aria-expanded', 'false');
|
|
9455
9667
|
el.hide();
|
|
9456
9668
|
}
|
|
9457
9669
|
|
|
9458
9670
|
function updateMenuBtn() {
|
|
9459
9671
|
var lyr = model.getActiveLayer()?.layer;
|
|
9460
9672
|
var lyrName = lyr?.name || '';
|
|
9461
|
-
var menuTitle = lyrName || lyr && '[unnamed layer]' || '[no data]';
|
|
9462
9673
|
var pageTitle = lyrName || 'mapshaper';
|
|
9463
|
-
btn.classed('active',
|
|
9674
|
+
btn.classed('active', !!lyr);
|
|
9675
|
+
headerBtn.text(lyr ? 'Active: ' + formatLayerNameForDisplay(lyr.name) : '');
|
|
9464
9676
|
window.document.title = pageTitle;
|
|
9465
9677
|
}
|
|
9466
9678
|
|
|
9467
9679
|
function render() {
|
|
9468
9680
|
renderLayerList();
|
|
9469
|
-
renderSourceFileList();
|
|
9470
|
-
}
|
|
9471
|
-
|
|
9472
|
-
function renderSourceFileList() {
|
|
9473
9681
|
el.findChild('.no-layer-note').classed('hidden', model.getActiveLayer());
|
|
9474
|
-
el.findChild('.source-file-section').classed('hidden', !model.getActiveLayer());
|
|
9475
|
-
var list = el.findChild('.file-list');
|
|
9476
|
-
var files = [];
|
|
9477
|
-
list.empty();
|
|
9478
|
-
model.forEachLayer(function(lyr, dataset) {
|
|
9479
|
-
var file = internal.getLayerSourceFile(lyr, dataset);
|
|
9480
|
-
if (!file || files.includes(file)) return;
|
|
9481
|
-
files.push(file);
|
|
9482
|
-
var warnings = getWarnings(lyr, dataset);
|
|
9483
|
-
var html = '<div class="layer-item">';
|
|
9484
|
-
html += rowHTML('name', file);
|
|
9485
|
-
if (warnings) {
|
|
9486
|
-
// html += rowHTML('problems', warnings, 'layer-problems');
|
|
9487
|
-
html += rowHTML('', warnings, 'layer-problems');
|
|
9488
|
-
}
|
|
9489
|
-
html += '</div>';
|
|
9490
|
-
list.appendChild(El('div').html(html).firstChild());
|
|
9491
|
-
});
|
|
9492
|
-
|
|
9493
9682
|
}
|
|
9494
9683
|
|
|
9495
9684
|
function renderLayerList() {
|
|
@@ -9550,10 +9739,10 @@
|
|
|
9550
9739
|
html = '<!-- ' + lyr.menu_id + '--><div class="' + classes + '">';
|
|
9551
9740
|
html += rowHTML('name', '<span class="layer-name colored-text dot-underline">' + formatLayerNameForDisplay(lyr.name) + '</span>', 'row1');
|
|
9552
9741
|
html += rowHTML('contents', describeLyr(lyr, dataset));
|
|
9553
|
-
|
|
9742
|
+
html += '<span class="more-btn layer-btn" role="button" tabindex="0" aria-label="More layer options"></span>';
|
|
9554
9743
|
if (opts.pinnable) {
|
|
9555
|
-
html += '<img class="eye-btn black-eye" draggable="false" src="images/eye.png">';
|
|
9556
|
-
html += '<img class="eye-btn green-eye" draggable="false" src="images/eye2.png">';
|
|
9744
|
+
html += '<img class="eye-btn black-eye layer-btn" draggable="false" src="images/eye.png">';
|
|
9745
|
+
html += '<img class="eye-btn green-eye layer-btn" draggable="false" src="images/eye2.png">';
|
|
9557
9746
|
}
|
|
9558
9747
|
html += '</div>';
|
|
9559
9748
|
return html;
|
|
@@ -9561,8 +9750,10 @@
|
|
|
9561
9750
|
|
|
9562
9751
|
function initMouseEvents(entry, id, pinnable) {
|
|
9563
9752
|
entry.on('mouseover', init);
|
|
9753
|
+
entry.on('focusin', init);
|
|
9564
9754
|
function init() {
|
|
9565
9755
|
entry.removeEventListener('mouseover', init);
|
|
9756
|
+
entry.removeEventListener('focusin', init);
|
|
9566
9757
|
initMouseEvents2(entry, id, pinnable);
|
|
9567
9758
|
}
|
|
9568
9759
|
}
|
|
@@ -9578,10 +9769,6 @@
|
|
|
9578
9769
|
}
|
|
9579
9770
|
// start dragging when button is first pressed
|
|
9580
9771
|
if (e.buttons && !dragTargetId) {
|
|
9581
|
-
// don't start dragging if pointer is over the close button
|
|
9582
|
-
// (before, clicking this button wqs finicky -- the mouse had to remain
|
|
9583
|
-
// perfectly still between mousedown and mouseup)
|
|
9584
|
-
if (El(e.target).hasClass('close-btn')) return;
|
|
9585
9772
|
dragTargetId = id;
|
|
9586
9773
|
entry.addClass('drag-target');
|
|
9587
9774
|
}
|
|
@@ -9606,6 +9793,7 @@
|
|
|
9606
9793
|
}
|
|
9607
9794
|
|
|
9608
9795
|
function initMouseEvents2(entry, id, pinnable) {
|
|
9796
|
+
var moreBtn = entry.findChild('.more-btn');
|
|
9609
9797
|
initLayerDragging(entry, id);
|
|
9610
9798
|
|
|
9611
9799
|
function deleteLayer() {
|
|
@@ -9630,7 +9818,7 @@
|
|
|
9630
9818
|
}
|
|
9631
9819
|
}
|
|
9632
9820
|
|
|
9633
|
-
function selectLayer(
|
|
9821
|
+
function selectLayer() {
|
|
9634
9822
|
var target = findLayerById(id);
|
|
9635
9823
|
// don't select if user is typing or dragging
|
|
9636
9824
|
if (GUI.textIsSelected() || dragging) return;
|
|
@@ -9639,17 +9827,24 @@
|
|
|
9639
9827
|
if (!map.isActiveLayer(target.layer)) {
|
|
9640
9828
|
model.selectLayer(target.layer, target.dataset);
|
|
9641
9829
|
}
|
|
9642
|
-
// close menu after a delay
|
|
9643
|
-
if (closeMenu === true) setTimeout(function() {
|
|
9644
|
-
gui.clearMode();
|
|
9645
|
-
}, 230);
|
|
9646
9830
|
}
|
|
9647
9831
|
|
|
9648
|
-
|
|
9649
|
-
|
|
9650
|
-
|
|
9651
|
-
|
|
9652
|
-
|
|
9832
|
+
function openLayerMenu(e) {
|
|
9833
|
+
var menuEvent = e;
|
|
9834
|
+
e.stopPropagation();
|
|
9835
|
+
if (!isFinite(e.pageX) || !isFinite(e.pageY)) {
|
|
9836
|
+
var rect = moreBtn.node().getBoundingClientRect();
|
|
9837
|
+
menuEvent = {
|
|
9838
|
+
pageX: rect.right,
|
|
9839
|
+
pageY: rect.top + rect.height / 2
|
|
9840
|
+
};
|
|
9841
|
+
}
|
|
9842
|
+
menuEvent.deleteLayer = deleteLayer;
|
|
9843
|
+
menuEvent.selectLayer = selectLayer;
|
|
9844
|
+
menuEvent.contextMenuId = 'layer-' + id;
|
|
9845
|
+
openContextMenu(menuEvent, null, null);
|
|
9846
|
+
}
|
|
9847
|
+
|
|
9653
9848
|
|
|
9654
9849
|
if (pinnable) {
|
|
9655
9850
|
// init pin button
|
|
@@ -9692,18 +9887,22 @@
|
|
|
9692
9887
|
renameLayer(target, str);
|
|
9693
9888
|
});
|
|
9694
9889
|
|
|
9890
|
+
moreBtn.on('mousedown', function(e) {
|
|
9891
|
+
e.stopPropagation();
|
|
9892
|
+
});
|
|
9893
|
+
GUI.onClick(moreBtn, openLayerMenu);
|
|
9894
|
+
moreBtn.on('keydown', function(e) {
|
|
9895
|
+
if (e.key == 'Enter' || e.key == ' ') {
|
|
9896
|
+
e.preventDefault();
|
|
9897
|
+
openLayerMenu(e);
|
|
9898
|
+
}
|
|
9899
|
+
});
|
|
9900
|
+
|
|
9695
9901
|
// init click-to-select
|
|
9696
9902
|
GUI.onClick(entry, function() {
|
|
9697
|
-
selectLayer(
|
|
9903
|
+
selectLayer();
|
|
9698
9904
|
});
|
|
9699
9905
|
|
|
9700
|
-
GUI.onContextClick(entry, function(e) {
|
|
9701
|
-
e.deleteLayer = deleteLayer;
|
|
9702
|
-
e.selectLayer = selectLayer;
|
|
9703
|
-
// contextMenu.open(e);
|
|
9704
|
-
// openContextMenu(e, null, entry.node())
|
|
9705
|
-
openContextMenu(e, null, null);
|
|
9706
|
-
});
|
|
9707
9906
|
}
|
|
9708
9907
|
|
|
9709
9908
|
function describeLyr(lyr, dataset) {
|
|
@@ -9750,30 +9949,6 @@
|
|
|
9750
9949
|
}
|
|
9751
9950
|
}
|
|
9752
9951
|
|
|
9753
|
-
function getWarnings(lyr, dataset) {
|
|
9754
|
-
var file = internal.getLayerSourceFile(lyr, dataset);
|
|
9755
|
-
var missing = [];
|
|
9756
|
-
var msg;
|
|
9757
|
-
// show missing file warning for first layer in dataset
|
|
9758
|
-
// (assuming it represents the content of the original file)
|
|
9759
|
-
if (utils$1.endsWith(file, '.shp') && lyr == dataset.layers[0]) {
|
|
9760
|
-
if (!lyr.data) {
|
|
9761
|
-
missing.push('.dbf');
|
|
9762
|
-
}
|
|
9763
|
-
if (!dataset.info.wkt1 && !dataset.info.crs) {
|
|
9764
|
-
missing.push('.prj');
|
|
9765
|
-
}
|
|
9766
|
-
}
|
|
9767
|
-
if (missing.length) {
|
|
9768
|
-
msg = 'missing ' + missing.join(' and ') + ' data';
|
|
9769
|
-
}
|
|
9770
|
-
return msg;
|
|
9771
|
-
}
|
|
9772
|
-
|
|
9773
|
-
function describeSrc(lyr, dataset) {
|
|
9774
|
-
return internal.getLayerSourceFile(lyr, dataset);
|
|
9775
|
-
}
|
|
9776
|
-
|
|
9777
9952
|
function isPinnable(lyr) {
|
|
9778
9953
|
return internal.layerIsGeometric(lyr) || internal.layerHasFurniture(lyr);
|
|
9779
9954
|
}
|
|
@@ -9970,7 +10145,7 @@
|
|
|
9970
10145
|
function getRestoreDataNote(gui) {
|
|
9971
10146
|
var stats = getUndoPayloadStats(gui);
|
|
9972
10147
|
var bytes = stats ? stats.ownBytes || 0 : 0;
|
|
9973
|
-
return '
|
|
10148
|
+
return 'restore data stored on-disk: ' + formatBytes(bytes);
|
|
9974
10149
|
}
|
|
9975
10150
|
|
|
9976
10151
|
function getUndoPayloadStats(gui) {
|
|
@@ -11991,8 +12166,8 @@
|
|
|
11991
12166
|
// DELETE key
|
|
11992
12167
|
// delete pinned feature
|
|
11993
12168
|
// to help protect against inadvertent deletion, don't delete
|
|
11994
|
-
// when
|
|
11995
|
-
if (!gui.getMode() && !gui.
|
|
12169
|
+
// when a sidebar panel or popup menu is open
|
|
12170
|
+
if (!gui.getMode() && !gui.sidebarPanelIsOpen()) {
|
|
11996
12171
|
internal.deleteFeatureById(targetLayer, pinnedId());
|
|
11997
12172
|
self.clearSelection();
|
|
11998
12173
|
gui.model.updated({flags: 'filter'}); // signal map to update
|
|
@@ -18326,6 +18501,10 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
18326
18501
|
|
|
18327
18502
|
|
|
18328
18503
|
gui.state = {};
|
|
18504
|
+
var sidebarPanel = null;
|
|
18505
|
+
var lastSidebarPanel = 'console';
|
|
18506
|
+
var sidebarWidth = GUI.getSavedValue('sidebar_width') || 0;
|
|
18507
|
+
var sidebarResizeFrame = null;
|
|
18329
18508
|
|
|
18330
18509
|
var msgCount = 0;
|
|
18331
18510
|
var clearMsg;
|
|
@@ -18366,10 +18545,50 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
18366
18545
|
// if (gui.progressMessage) gui.progressMessage.hide();
|
|
18367
18546
|
};
|
|
18368
18547
|
|
|
18548
|
+
if (sidebarWidth) {
|
|
18549
|
+
setSidebarWidth(sidebarWidth);
|
|
18550
|
+
}
|
|
18551
|
+
|
|
18552
|
+
gui.getSidebarPanel = function() {
|
|
18553
|
+
return sidebarPanel;
|
|
18554
|
+
};
|
|
18555
|
+
|
|
18556
|
+
gui.setSidebarPanel = function(name) {
|
|
18557
|
+
var prev = sidebarPanel;
|
|
18558
|
+
sidebarPanel = name || null;
|
|
18559
|
+
if (sidebarPanel && gui.getMode()) {
|
|
18560
|
+
gui.clearMode();
|
|
18561
|
+
}
|
|
18562
|
+
if (sidebarPanel == prev) return;
|
|
18563
|
+
if (sidebarPanel) {
|
|
18564
|
+
lastSidebarPanel = sidebarPanel;
|
|
18565
|
+
}
|
|
18566
|
+
gui.container
|
|
18567
|
+
.classed('sidebar-open', !!sidebarPanel)
|
|
18568
|
+
.classed('layers-open', sidebarPanel == 'layers')
|
|
18569
|
+
.classed('console-open', sidebarPanel == 'console');
|
|
18570
|
+
gui.dispatchEvent('sidebar', {name: sidebarPanel, prev: prev});
|
|
18571
|
+
gui.dispatchEvent('resize');
|
|
18572
|
+
};
|
|
18573
|
+
|
|
18574
|
+
gui.toggleSidebarPanel = function(name) {
|
|
18575
|
+
gui.setSidebarPanel(sidebarPanel == name ? null : name);
|
|
18576
|
+
};
|
|
18577
|
+
|
|
18578
|
+
gui.toggleSidebar = function() {
|
|
18579
|
+
gui.setSidebarPanel(sidebarPanel ? null : lastSidebarPanel);
|
|
18580
|
+
};
|
|
18581
|
+
|
|
18582
|
+
gui.sidebarPanelIsOpen = function() {
|
|
18583
|
+
return !!sidebarPanel;
|
|
18584
|
+
};
|
|
18585
|
+
|
|
18369
18586
|
gui.consoleIsOpen = function() {
|
|
18370
|
-
return
|
|
18587
|
+
return sidebarPanel == 'console';
|
|
18371
18588
|
};
|
|
18372
18589
|
|
|
18590
|
+
initSidebarResizing();
|
|
18591
|
+
|
|
18373
18592
|
gui.getRuntimeStateContext = function() {
|
|
18374
18593
|
return getRuntimeStateContext(gui);
|
|
18375
18594
|
};
|
|
@@ -18411,6 +18630,50 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
18411
18630
|
}
|
|
18412
18631
|
|
|
18413
18632
|
return gui;
|
|
18633
|
+
|
|
18634
|
+
function initSidebarResizing() {
|
|
18635
|
+
var handle = gui.container.findChild('.sidebar-resize-handle');
|
|
18636
|
+
if (!handle) return;
|
|
18637
|
+
handle.on('mousedown', function(e) {
|
|
18638
|
+
if (!gui.sidebarPanelIsOpen()) return;
|
|
18639
|
+
e.preventDefault();
|
|
18640
|
+
e.stopPropagation();
|
|
18641
|
+
gui.container.addClass('sidebar-resizing');
|
|
18642
|
+
window.addEventListener('mousemove', onMove);
|
|
18643
|
+
window.addEventListener('mouseup', onRelease);
|
|
18644
|
+
});
|
|
18645
|
+
|
|
18646
|
+
function onMove(e) {
|
|
18647
|
+
setSidebarWidth(e.pageX);
|
|
18648
|
+
scheduleSidebarResize();
|
|
18649
|
+
}
|
|
18650
|
+
|
|
18651
|
+
function onRelease() {
|
|
18652
|
+
window.removeEventListener('mousemove', onMove);
|
|
18653
|
+
window.removeEventListener('mouseup', onRelease);
|
|
18654
|
+
gui.container.removeClass('sidebar-resizing');
|
|
18655
|
+
GUI.setSavedValue('sidebar_width', sidebarWidth);
|
|
18656
|
+
scheduleSidebarResize();
|
|
18657
|
+
}
|
|
18658
|
+
}
|
|
18659
|
+
|
|
18660
|
+
function setSidebarWidth(width) {
|
|
18661
|
+
sidebarWidth = clampSidebarWidth(width);
|
|
18662
|
+
gui.container.node().style.setProperty('--left-sidebar-width', sidebarWidth + 'px');
|
|
18663
|
+
}
|
|
18664
|
+
|
|
18665
|
+
function clampSidebarWidth(width) {
|
|
18666
|
+
var max = Math.min(720, Math.round(window.innerWidth * 0.6));
|
|
18667
|
+
return Math.max(220, Math.min(max, Math.round(width)));
|
|
18668
|
+
}
|
|
18669
|
+
|
|
18670
|
+
function scheduleSidebarResize() {
|
|
18671
|
+
if (sidebarResizeFrame) return;
|
|
18672
|
+
sidebarResizeFrame = requestAnimationFrame(function() {
|
|
18673
|
+
sidebarResizeFrame = null;
|
|
18674
|
+
gui.dispatchEvent('resize');
|
|
18675
|
+
});
|
|
18676
|
+
}
|
|
18414
18677
|
}
|
|
18415
18678
|
|
|
18416
18679
|
function createUndoTestApi(gui) {
|