mapshaper 0.6.19 → 0.6.21
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 +169 -81
- package/package.json +1 -1
- package/www/index.html +2 -0
- package/www/mapshaper-gui.js +153 -94
- package/www/mapshaper.js +169 -81
- package/www/page.css +17 -7
package/www/mapshaper-gui.js
CHANGED
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
get defaults () { return defaults; },
|
|
28
28
|
get extend () { return extend; },
|
|
29
29
|
get inherit () { return inherit; },
|
|
30
|
+
get promisify () { return promisify; },
|
|
30
31
|
get reduceAsync () { return reduceAsync; },
|
|
31
32
|
get merge () { return merge; },
|
|
32
33
|
get difference () { return difference; },
|
|
@@ -84,6 +85,7 @@
|
|
|
84
85
|
get formatter () { return formatter; },
|
|
85
86
|
get wildcardToRegExp () { return wildcardToRegExp; },
|
|
86
87
|
get createBuffer () { return createBuffer; },
|
|
88
|
+
get toBuffer () { return toBuffer; },
|
|
87
89
|
get expandoBuffer () { return expandoBuffer; },
|
|
88
90
|
get copyElements () { return copyElements; },
|
|
89
91
|
get extendBuffer () { return extendBuffer; },
|
|
@@ -588,12 +590,12 @@
|
|
|
588
590
|
if (arguments.length == 1) {
|
|
589
591
|
return this.el.getAttribute(obj);
|
|
590
592
|
}
|
|
591
|
-
|
|
592
|
-
|
|
593
|
+
if (value === null) {
|
|
594
|
+
this.el.removeAttribute(obj);
|
|
595
|
+
} else {
|
|
596
|
+
this.el.setAttribute(obj, value);
|
|
597
|
+
}
|
|
593
598
|
}
|
|
594
|
-
// else if (!value) {
|
|
595
|
-
// Opts.copyAllParams(this.el, obj);
|
|
596
|
-
// }
|
|
597
599
|
return this;
|
|
598
600
|
},
|
|
599
601
|
|
|
@@ -1342,13 +1344,6 @@
|
|
|
1342
1344
|
var sessionId = getUniqId('session');
|
|
1343
1345
|
var snapshotCount = 0;
|
|
1344
1346
|
|
|
1345
|
-
window.addEventListener('beforeunload', async function() {
|
|
1346
|
-
// delete snapshot data
|
|
1347
|
-
// This is not ideal, because the data gets deleted even if the user
|
|
1348
|
-
// cancels the page close... but there's no apparent good alternative
|
|
1349
|
-
await finalCleanup();
|
|
1350
|
-
});
|
|
1351
|
-
|
|
1352
1347
|
function getUniqId(prefix) {
|
|
1353
1348
|
return prefix + '_' + (Math.random() + 1).toString(36).substring(2,8);
|
|
1354
1349
|
}
|
|
@@ -1358,29 +1353,43 @@
|
|
|
1358
1353
|
}
|
|
1359
1354
|
|
|
1360
1355
|
function SessionSnapshots(gui) {
|
|
1361
|
-
if (!gui.options.saveControl) return;
|
|
1362
1356
|
var _menuOpen = false;
|
|
1363
1357
|
var _menuTimeout;
|
|
1364
|
-
var btn
|
|
1365
|
-
var menu = El('div').addClass('nav-sub-menu save-menu').appendTo(btn.node());
|
|
1358
|
+
var btn, menu;
|
|
1366
1359
|
|
|
1367
|
-
|
|
1360
|
+
init();
|
|
1368
1361
|
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
if (!_menuOpen) {
|
|
1373
|
-
openMenu();
|
|
1374
|
-
}
|
|
1375
|
-
});
|
|
1362
|
+
async function init() {
|
|
1363
|
+
var enabled = await isStorageEnabled();
|
|
1364
|
+
if (!enabled) return;
|
|
1376
1365
|
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1366
|
+
btn = gui.buttons.addButton('#ribbon-icon').addClass('menu-btn save-btn');
|
|
1367
|
+
menu = El('div').addClass('nav-sub-menu save-menu').appendTo(btn.node());
|
|
1368
|
+
await initialCleanup();
|
|
1369
|
+
|
|
1370
|
+
window.addEventListener('beforeunload', async function() {
|
|
1371
|
+
// delete snapshot data
|
|
1372
|
+
// This is not ideal, because the data gets deleted even if the user
|
|
1373
|
+
// cancels the page close... but there's no apparent good alternative
|
|
1374
|
+
await finalCleanup();
|
|
1375
|
+
});
|
|
1376
|
+
|
|
1377
|
+
btn.on('mouseenter', function() {
|
|
1378
|
+
btn.addClass('hover');
|
|
1379
|
+
clearTimeout(_menuTimeout); // prevent timed closing
|
|
1380
|
+
if (!_menuOpen) {
|
|
1381
|
+
openMenu();
|
|
1382
|
+
}
|
|
1383
|
+
});
|
|
1384
|
+
|
|
1385
|
+
btn.on('mouseleave', function() {
|
|
1386
|
+
if (!_menuOpen) {
|
|
1387
|
+
btn.removeClass('hover');
|
|
1388
|
+
} else {
|
|
1389
|
+
closeMenu(200);
|
|
1390
|
+
}
|
|
1391
|
+
});
|
|
1392
|
+
}
|
|
1384
1393
|
|
|
1385
1394
|
async function renderMenu() {
|
|
1386
1395
|
var snapshots = await fetchSnapshotList();
|
|
@@ -1389,7 +1398,7 @@
|
|
|
1389
1398
|
addMenuLink({
|
|
1390
1399
|
slug: 'stash',
|
|
1391
1400
|
// label: 'save data snapshot',
|
|
1392
|
-
label: '
|
|
1401
|
+
label: 'create a snapshot',
|
|
1393
1402
|
action: saveSnapshot
|
|
1394
1403
|
});
|
|
1395
1404
|
|
|
@@ -1407,7 +1416,7 @@
|
|
|
1407
1416
|
var line = El('div').appendTo(menu).addClass('save-menu-item');
|
|
1408
1417
|
El('span').appendTo(line).html(`<span class="save-item-label">#${item.number}</span> `);
|
|
1409
1418
|
// show snapshot size
|
|
1410
|
-
|
|
1419
|
+
El('span').appendTo(line).html(` <span class="save-item-size">${item.display_size}</span>`);
|
|
1411
1420
|
El('span').addClass('save-menu-btn').appendTo(line).on('click', async function(e) {
|
|
1412
1421
|
await restoreSnapshotById(item.id, gui);
|
|
1413
1422
|
closeMenu(100);
|
|
@@ -1461,7 +1470,7 @@
|
|
|
1461
1470
|
}
|
|
1462
1471
|
|
|
1463
1472
|
async function saveSnapshot(gui) {
|
|
1464
|
-
var buf = captureSnapshot(gui);
|
|
1473
|
+
var buf = await captureSnapshot(gui);
|
|
1465
1474
|
var entryId = String(++snapshotCount).padStart(3, '0');
|
|
1466
1475
|
var snapshotId = sessionId + '_' + entryId; // e.g. session_d89fw_001
|
|
1467
1476
|
var entry = {
|
|
@@ -1512,7 +1521,7 @@
|
|
|
1512
1521
|
console.log('Snapshot not available:', id);
|
|
1513
1522
|
return;
|
|
1514
1523
|
}
|
|
1515
|
-
var data = internal.unpackSession(buf);
|
|
1524
|
+
var data = await internal.unpackSession(buf);
|
|
1516
1525
|
buf = null;
|
|
1517
1526
|
gui.model.clear();
|
|
1518
1527
|
importDatasets(data.datasets, gui);
|
|
@@ -1522,11 +1531,11 @@
|
|
|
1522
1531
|
// Add datasets to the current project
|
|
1523
1532
|
// TODO: figure out if interface data should be imported (e.g. should
|
|
1524
1533
|
// visibility flag of imported layers be imported)
|
|
1525
|
-
function importSessionData(buf, gui) {
|
|
1534
|
+
async function importSessionData(buf, gui) {
|
|
1526
1535
|
if (buf instanceof ArrayBuffer) {
|
|
1527
1536
|
buf = new Uint8Array(buf);
|
|
1528
1537
|
}
|
|
1529
|
-
var data = internal.unpackSession(buf);
|
|
1538
|
+
var data = await internal.unpackSession(buf);
|
|
1530
1539
|
importDatasets(data.datasets, gui);
|
|
1531
1540
|
}
|
|
1532
1541
|
|
|
@@ -1537,11 +1546,16 @@
|
|
|
1537
1546
|
gui.model.updated({select: true, arc_count: true}); // arc_count to refresh display shapes
|
|
1538
1547
|
}
|
|
1539
1548
|
|
|
1540
|
-
function captureSnapshot(gui) {
|
|
1549
|
+
async function captureSnapshot(gui) {
|
|
1541
1550
|
var datasets = gui.model.getDatasets();
|
|
1542
1551
|
var lyr = gui.model.getActiveLayer().layer;
|
|
1552
|
+
// compact: true applies compression to vector coordinates, for ~30% reduction
|
|
1553
|
+
// in file size in a typical polygon or polyline file, but longer processing time
|
|
1554
|
+
var opts = {compact: false};
|
|
1543
1555
|
lyr.active = true;
|
|
1544
|
-
|
|
1556
|
+
// console.time('msx');
|
|
1557
|
+
var obj = await internal.exportDatasetsToPack(datasets, opts);
|
|
1558
|
+
// console.timeEnd('msx')
|
|
1545
1559
|
delete lyr.active;
|
|
1546
1560
|
obj.gui = getGuiState(gui);
|
|
1547
1561
|
return internal.pack(obj);
|
|
@@ -1597,7 +1611,7 @@
|
|
|
1597
1611
|
}
|
|
1598
1612
|
});
|
|
1599
1613
|
// remove old indexed snapshots
|
|
1600
|
-
|
|
1614
|
+
await updateIndex(function(index) {
|
|
1601
1615
|
index.snapshots = index.snapshots.filter(function(snap) {
|
|
1602
1616
|
var msPerDay = 1000 * 60 * 60 * 24;
|
|
1603
1617
|
var daysOld = (Date.now() - snap.created) / msPerDay;
|
|
@@ -1679,17 +1693,24 @@
|
|
|
1679
1693
|
}
|
|
1680
1694
|
|
|
1681
1695
|
function getSessionData() {
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
return data || [];
|
|
1685
|
-
} catch(e) {}
|
|
1686
|
-
return [];
|
|
1696
|
+
var data = JSON.parse(window.localStorage.getItem('session_data'));
|
|
1697
|
+
return data || [];
|
|
1687
1698
|
}
|
|
1688
1699
|
|
|
1689
1700
|
function setSessionData(arr) {
|
|
1690
1701
|
window.localStorage.setItem('session_data', JSON.stringify(arr));
|
|
1691
1702
|
}
|
|
1692
1703
|
|
|
1704
|
+
async function isStorageEnabled() {
|
|
1705
|
+
try {
|
|
1706
|
+
setSessionData(getSessionData());
|
|
1707
|
+
await updateIndex(function() {});
|
|
1708
|
+
return true;
|
|
1709
|
+
} catch(e) {
|
|
1710
|
+
return false;
|
|
1711
|
+
}
|
|
1712
|
+
}
|
|
1713
|
+
|
|
1693
1714
|
// @cb function(<FileList>)
|
|
1694
1715
|
function DropControl(gui, el, cb) {
|
|
1695
1716
|
var area = El(el);
|
|
@@ -1773,16 +1794,16 @@
|
|
|
1773
1794
|
.attr('multiple', 'multiple')
|
|
1774
1795
|
.on('change', onchange);
|
|
1775
1796
|
|
|
1776
|
-
function onchange(e) {
|
|
1797
|
+
async function onchange(e) {
|
|
1777
1798
|
var files = e.target.files;
|
|
1778
1799
|
// files may be undefined (e.g. if user presses 'cancel' after a file has been selected)
|
|
1779
1800
|
if (files) {
|
|
1780
1801
|
// disable the button while files are being processed
|
|
1781
1802
|
btn.addClass('selected');
|
|
1782
1803
|
input.attr('disabled', true);
|
|
1783
|
-
cb(files);
|
|
1804
|
+
await cb(files);
|
|
1784
1805
|
btn.removeClass('selected');
|
|
1785
|
-
input.attr('disabled',
|
|
1806
|
+
input.attr('disabled', null);
|
|
1786
1807
|
}
|
|
1787
1808
|
}
|
|
1788
1809
|
}
|
|
@@ -1940,7 +1961,7 @@
|
|
|
1940
1961
|
}
|
|
1941
1962
|
gui.enterMode('import');
|
|
1942
1963
|
if (useQuickView()) {
|
|
1943
|
-
importQueuedFiles();
|
|
1964
|
+
await importQueuedFiles();
|
|
1944
1965
|
} else {
|
|
1945
1966
|
gui.container.addClass('queued-files');
|
|
1946
1967
|
El('#path-import-options').classed('hidden', !filesMayContainPaths(queuedFiles));
|
|
@@ -1983,7 +2004,7 @@
|
|
|
1983
2004
|
await wait(35);
|
|
1984
2005
|
}
|
|
1985
2006
|
if (group[internal.PACKAGE_EXT]) {
|
|
1986
|
-
importSessionData(group[internal.PACKAGE_EXT].content, gui);
|
|
2007
|
+
await importSessionData(group[internal.PACKAGE_EXT].content, gui);
|
|
1987
2008
|
} else {
|
|
1988
2009
|
importDataset(group, importOpts);
|
|
1989
2010
|
}
|
|
@@ -2113,14 +2134,6 @@
|
|
|
2113
2134
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
2114
2135
|
}
|
|
2115
2136
|
|
|
2116
|
-
function runAsync(fn, arg) {
|
|
2117
|
-
return new Promise((resolve, reject) => {
|
|
2118
|
-
fn(arg, function(err, data) {
|
|
2119
|
-
return err ? reject(err) : resolve(data);
|
|
2120
|
-
});
|
|
2121
|
-
});
|
|
2122
|
-
}
|
|
2123
|
-
|
|
2124
2137
|
async function readKmzFile(file) {
|
|
2125
2138
|
var files = await readZipFile(file);
|
|
2126
2139
|
var name = files[0] && files[0].name;
|
|
@@ -2142,7 +2155,7 @@
|
|
|
2142
2155
|
async function readZipFile(file) {
|
|
2143
2156
|
// Async is up to twice as fast unzipping large files
|
|
2144
2157
|
// var index = internal.unzipSync(file.content);
|
|
2145
|
-
var index = await
|
|
2158
|
+
var index = await utils$1.promisify(internal.unzipAsync)(file.content);
|
|
2146
2159
|
return Object.keys(index).reduce(function(memo, filename) {
|
|
2147
2160
|
if (!/\.txt$/i.test(filename)) {
|
|
2148
2161
|
memo.push({
|
|
@@ -2176,7 +2189,7 @@
|
|
|
2176
2189
|
|
|
2177
2190
|
async function readFileData(file) {
|
|
2178
2191
|
try {
|
|
2179
|
-
var content = await
|
|
2192
|
+
var content = await utils$1.promisify(readContentFileAsync)(file);
|
|
2180
2193
|
return {
|
|
2181
2194
|
content: content,
|
|
2182
2195
|
name: file.name
|
|
@@ -3489,7 +3502,7 @@
|
|
|
3489
3502
|
flags.arc_count || flags.snap || flags.affine || flags.points || flags['merge-layers'];
|
|
3490
3503
|
if (intersectionsMayHaveChanged) {
|
|
3491
3504
|
// delete any cached intersection data, to trigger re-calculation
|
|
3492
|
-
e.dataset.
|
|
3505
|
+
e.dataset._intersections = null;
|
|
3493
3506
|
updateAsync();
|
|
3494
3507
|
} else if (flags.select) {
|
|
3495
3508
|
// new active layer, but no editing commands were run -- use cached intersections (if available)
|
|
@@ -3538,11 +3551,11 @@
|
|
|
3538
3551
|
XX = internal.findSegmentIntersections(arcs, opts);
|
|
3539
3552
|
showBtn = XX.length > 0;
|
|
3540
3553
|
} else { // no simplification
|
|
3541
|
-
XX = dataset.
|
|
3554
|
+
XX = dataset._intersections;
|
|
3542
3555
|
if (!XX) {
|
|
3543
3556
|
// cache intersections at 0 simplification, to avoid recalculating
|
|
3544
3557
|
// every time the simplification slider is set to 100% or the layer is selected at 100%
|
|
3545
|
-
XX = dataset.
|
|
3558
|
+
XX = dataset._intersections = internal.findSegmentIntersections(arcs, opts);
|
|
3546
3559
|
}
|
|
3547
3560
|
showBtn = false;
|
|
3548
3561
|
}
|
|
@@ -3559,7 +3572,7 @@
|
|
|
3559
3572
|
|
|
3560
3573
|
function dismiss() {
|
|
3561
3574
|
var dataset = model.getActiveLayer().dataset;
|
|
3562
|
-
dataset.
|
|
3575
|
+
dataset._intersections = null;
|
|
3563
3576
|
dataset.info.no_intersections = true;
|
|
3564
3577
|
reset();
|
|
3565
3578
|
}
|
|
@@ -3624,8 +3637,6 @@
|
|
|
3624
3637
|
return layers.reverse();
|
|
3625
3638
|
}
|
|
3626
3639
|
|
|
3627
|
-
// import { groupLayersByDataset } from '../dataset/mapshaper-target-utils';
|
|
3628
|
-
|
|
3629
3640
|
// Export buttons and their behavior
|
|
3630
3641
|
var ExportControl = function(gui) {
|
|
3631
3642
|
var model = gui.model;
|
|
@@ -3677,16 +3688,15 @@
|
|
|
3677
3688
|
gui.clearMode();
|
|
3678
3689
|
gui.showProgressMessage('Exporting');
|
|
3679
3690
|
setTimeout(function() {
|
|
3680
|
-
exportMenuSelection(layers
|
|
3681
|
-
if (err) {
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
gui.alert('Export failed for an unknown reason');
|
|
3688
|
-
}
|
|
3691
|
+
exportMenuSelection(layers).catch(function(err) {
|
|
3692
|
+
if (utils$1.isString(err)) {
|
|
3693
|
+
gui.alert(err);
|
|
3694
|
+
} else {
|
|
3695
|
+
// stack seems to change if Error is logged directly
|
|
3696
|
+
console.error(err.stack);
|
|
3697
|
+
gui.alert('Export failed for an unknown reason');
|
|
3689
3698
|
}
|
|
3699
|
+
}).finally(function() {
|
|
3690
3700
|
gui.clearProgressMessage();
|
|
3691
3701
|
});
|
|
3692
3702
|
}, 20);
|
|
@@ -3708,17 +3718,12 @@
|
|
|
3708
3718
|
}
|
|
3709
3719
|
|
|
3710
3720
|
// done: function(string|Error|null)
|
|
3711
|
-
function exportMenuSelection(layers
|
|
3712
|
-
var opts
|
|
3713
|
-
try {
|
|
3714
|
-
opts = getExportOpts();
|
|
3721
|
+
async function exportMenuSelection(layers) {
|
|
3722
|
+
var opts = getExportOpts();
|
|
3715
3723
|
// note: command line "target" option gets ignored
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
return done(e);
|
|
3720
|
-
}
|
|
3721
|
-
internal.writeFiles(files, opts, done);
|
|
3724
|
+
var files = await internal.exportTargetLayers(layers, opts);
|
|
3725
|
+
gui.session.layersExported(getTargetLayerIds(), getExportOptsAsString());
|
|
3726
|
+
await utils$1.promisify(internal.writeFiles)(files, opts);
|
|
3722
3727
|
}
|
|
3723
3728
|
|
|
3724
3729
|
function initLayerItem(o, i) {
|
|
@@ -3838,7 +3843,7 @@
|
|
|
3838
3843
|
}
|
|
3839
3844
|
|
|
3840
3845
|
function initFormatMenu() {
|
|
3841
|
-
var defaults = ['shapefile', 'geojson', 'topojson', 'json', 'dsv', 'kml', 'svg'];
|
|
3846
|
+
var defaults = ['shapefile', 'geojson', 'topojson', 'json', 'dsv', 'kml', 'svg', internal.PACKAGE_EXT];
|
|
3842
3847
|
var formats = utils$1.uniq(defaults.concat(getInputFormats()));
|
|
3843
3848
|
var items = formats.map(function(fmt) {
|
|
3844
3849
|
return utils$1.format('<div><label><input type="radio" name="format" value="%s"' +
|
|
@@ -3966,7 +3971,7 @@
|
|
|
3966
3971
|
clearClass('insert-below');
|
|
3967
3972
|
dragTargetId = layerOrderSlug = null;
|
|
3968
3973
|
if (dragging) {
|
|
3969
|
-
|
|
3974
|
+
renderLayerList(); // in case menu changed...
|
|
3970
3975
|
dragging = false;
|
|
3971
3976
|
}
|
|
3972
3977
|
}
|
|
@@ -4003,6 +4008,32 @@
|
|
|
4003
4008
|
}
|
|
4004
4009
|
|
|
4005
4010
|
function render() {
|
|
4011
|
+
renderLayerList();
|
|
4012
|
+
renderFileList();
|
|
4013
|
+
}
|
|
4014
|
+
|
|
4015
|
+
function renderFileList() {
|
|
4016
|
+
var list = el.findChild('.file-list');
|
|
4017
|
+
var files = [];
|
|
4018
|
+
list.empty();
|
|
4019
|
+
model.forEachLayer(function(lyr, dataset) {
|
|
4020
|
+
var file = internal.getLayerSourceFile(lyr, dataset);
|
|
4021
|
+
if (!file || files.includes(file)) return;
|
|
4022
|
+
files.push(file);
|
|
4023
|
+
var warnings = getWarnings(lyr, dataset);
|
|
4024
|
+
var html = '<div class="layer-item">';
|
|
4025
|
+
html += rowHTML('name', file);
|
|
4026
|
+
if (warnings) {
|
|
4027
|
+
// html += rowHTML('problems', warnings, 'layer-problems');
|
|
4028
|
+
html += rowHTML('', warnings, 'layer-problems');
|
|
4029
|
+
}
|
|
4030
|
+
html += '</div>';
|
|
4031
|
+
list.appendChild(El('div').html(html).firstChild());
|
|
4032
|
+
});
|
|
4033
|
+
|
|
4034
|
+
}
|
|
4035
|
+
|
|
4036
|
+
function renderLayerList() {
|
|
4006
4037
|
var list = el.findChild('.layer-list');
|
|
4007
4038
|
var uniqIds = {};
|
|
4008
4039
|
var pinnableCount = 0;
|
|
@@ -4049,7 +4080,6 @@
|
|
|
4049
4080
|
cache.cleanup();
|
|
4050
4081
|
|
|
4051
4082
|
function renderLayer(lyr, dataset, opts) {
|
|
4052
|
-
var warnings = getWarnings(lyr, dataset);
|
|
4053
4083
|
var classes = 'layer-item';
|
|
4054
4084
|
var entry, html;
|
|
4055
4085
|
|
|
@@ -4059,13 +4089,7 @@
|
|
|
4059
4089
|
|
|
4060
4090
|
html = '<!-- ' + lyr.menu_id + '--><div class="' + classes + '">';
|
|
4061
4091
|
html += rowHTML('name', '<span class="layer-name colored-text dot-underline">' + formatLayerNameForDisplay(lyr.name) + '</span>', 'row1');
|
|
4062
|
-
if (opts.show_source) {
|
|
4063
|
-
html += rowHTML('source file', describeSrc(lyr, dataset) || 'n/a');
|
|
4064
|
-
}
|
|
4065
4092
|
html += rowHTML('contents', describeLyr(lyr));
|
|
4066
|
-
if (warnings) {
|
|
4067
|
-
html += rowHTML('problems', warnings, 'layer-problems');
|
|
4068
|
-
}
|
|
4069
4093
|
html += '<img class="close-btn" draggable="false" src="images/close.png">';
|
|
4070
4094
|
if (opts.pinnable) {
|
|
4071
4095
|
html += '<img class="pin-btn unpinned" draggable="false" src="images/eye.png">';
|
|
@@ -4197,6 +4221,8 @@
|
|
|
4197
4221
|
var file = internal.getLayerSourceFile(lyr, dataset);
|
|
4198
4222
|
var missing = [];
|
|
4199
4223
|
var msg;
|
|
4224
|
+
// show missing file warning for first layer in dataset
|
|
4225
|
+
// (assuming it represents the content of the original file)
|
|
4200
4226
|
if (utils$1.endsWith(file, '.shp') && lyr == dataset.layers[0]) {
|
|
4201
4227
|
if (!lyr.data) {
|
|
4202
4228
|
missing.push('.dbf');
|
|
@@ -5316,6 +5342,27 @@
|
|
|
5316
5342
|
targ.prototype.__super__ = f;
|
|
5317
5343
|
}
|
|
5318
5344
|
|
|
5345
|
+
function promisify(asyncFn) {
|
|
5346
|
+
return function() {
|
|
5347
|
+
var args = toArray(arguments);
|
|
5348
|
+
return new Promise((resolve, reject) => {
|
|
5349
|
+
var cb = function(err, data) {
|
|
5350
|
+
if (err) reject(err);
|
|
5351
|
+
else resolve(data);
|
|
5352
|
+
};
|
|
5353
|
+
args.push(cb);
|
|
5354
|
+
asyncFn.apply(this, args);
|
|
5355
|
+
});
|
|
5356
|
+
};
|
|
5357
|
+
}
|
|
5358
|
+
|
|
5359
|
+
function runAsync(fn, arg) {
|
|
5360
|
+
return new Promise((resolve, reject) => {
|
|
5361
|
+
fn(arg, function(err, data) {
|
|
5362
|
+
return err ? reject(err) : resolve(data);
|
|
5363
|
+
});
|
|
5364
|
+
});
|
|
5365
|
+
}
|
|
5319
5366
|
|
|
5320
5367
|
// Call @iter on each member of an array (similar to Array#reduce(iter))
|
|
5321
5368
|
// iter: function(memo, item, callback)
|
|
@@ -6017,6 +6064,15 @@
|
|
|
6017
6064
|
}
|
|
6018
6065
|
}
|
|
6019
6066
|
|
|
6067
|
+
function toBuffer(src) {
|
|
6068
|
+
if (src instanceof B) return src;
|
|
6069
|
+
if (src instanceof ArrayBuffer) return B.from(src);
|
|
6070
|
+
if (src instanceof Uint8Array) {
|
|
6071
|
+
return B.from(src.buffer, src.byteOffset, src.byteLength);
|
|
6072
|
+
}
|
|
6073
|
+
error('Unexpected argument type');
|
|
6074
|
+
}
|
|
6075
|
+
|
|
6020
6076
|
function expandoBuffer(constructor, rate) {
|
|
6021
6077
|
var capacity = 0,
|
|
6022
6078
|
k = rate >= 1 ? rate : 1.2,
|
|
@@ -11191,11 +11247,14 @@
|
|
|
11191
11247
|
gui.buttons = new SidebarButtons(gui);
|
|
11192
11248
|
gui.map = new MshpMap(gui);
|
|
11193
11249
|
gui.interaction = new InteractionMode(gui);
|
|
11194
|
-
gui.sessionSave = new SessionSnapshots(gui);
|
|
11195
11250
|
gui.session = new SessionHistory(gui);
|
|
11196
11251
|
gui.undo = new Undo(gui);
|
|
11197
11252
|
gui.state = {};
|
|
11198
11253
|
|
|
11254
|
+
if (opts.saveControl) {
|
|
11255
|
+
new SessionSnapshots(gui);
|
|
11256
|
+
}
|
|
11257
|
+
|
|
11199
11258
|
initModeRules(gui);
|
|
11200
11259
|
|
|
11201
11260
|
gui.showProgressMessage = function(msg) {
|