mapshaper 0.6.23 → 0.6.25
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 +398 -153
- package/package.json +2 -3
- package/www/index.html +1 -0
- package/www/mapshaper-gui.js +67 -38
- package/www/mapshaper.js +398 -153
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mapshaper",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.25",
|
|
4
4
|
"description": "A tool for editing vector datasets for mapping and GIS.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"shapefile",
|
|
@@ -44,7 +44,6 @@
|
|
|
44
44
|
"@tmcw/togeojson": "^5.6.0",
|
|
45
45
|
"@xmldom/xmldom": "^0.8.6",
|
|
46
46
|
"adm-zip": "^0.5.9",
|
|
47
|
-
"bson": "^4.7.0",
|
|
48
47
|
"commander": "7.0.0",
|
|
49
48
|
"cookies": "^0.8.0",
|
|
50
49
|
"d3-color": "3.1.0",
|
|
@@ -58,7 +57,7 @@
|
|
|
58
57
|
"idb-keyval": "^6.2.0",
|
|
59
58
|
"kdbush": "^3.0.0",
|
|
60
59
|
"mproj": "0.0.35",
|
|
61
|
-
"msgpackr": "^1.8.
|
|
60
|
+
"msgpackr": "^1.8.5",
|
|
62
61
|
"opn": "^5.3.0",
|
|
63
62
|
"rw": "~1.3.3",
|
|
64
63
|
"sync-request": "5.0.0",
|
package/www/index.html
CHANGED
|
@@ -118,6 +118,7 @@
|
|
|
118
118
|
<div>
|
|
119
119
|
<div class="select-btn btn dialog-btn">Select</div>
|
|
120
120
|
<div class="clip-btn btn dialog-btn">Clip</div>
|
|
121
|
+
<div class="erase-btn btn dialog-btn">Erase</div>
|
|
121
122
|
<div class="info-btn btn dialog-btn">Info</div>
|
|
122
123
|
<!-- <div class="zoom-btn btn dialog-btn">Zoom In</div>
|
|
123
124
|
<div class="rectangle-btn btn dialog-btn">Rectangle</div> -->
|
package/www/mapshaper-gui.js
CHANGED
|
@@ -1437,7 +1437,9 @@
|
|
|
1437
1437
|
closeMenu(100);
|
|
1438
1438
|
}).text('restore');
|
|
1439
1439
|
El('span').addClass('save-menu-btn').appendTo(line).on('click', async function(e) {
|
|
1440
|
-
var
|
|
1440
|
+
var obj = await idb.get(item.id);
|
|
1441
|
+
await internal.applyCompression(obj, {consume: true});
|
|
1442
|
+
var buf = internal.pack(obj);
|
|
1441
1443
|
saveBlobToLocalFile('mapshaper_snapshot.msx', new Blob([buf]));
|
|
1442
1444
|
}).text('export');
|
|
1443
1445
|
El('span').addClass('save-menu-btn').appendTo(line).on('click', async function(e) {
|
|
@@ -1485,20 +1487,24 @@
|
|
|
1485
1487
|
}
|
|
1486
1488
|
|
|
1487
1489
|
async function saveSnapshot(gui) {
|
|
1488
|
-
var
|
|
1490
|
+
var obj = await captureSnapshot(gui);
|
|
1491
|
+
// storing an unpacked object is usually a bit faster (~20%)
|
|
1492
|
+
// note: we don't know the size of unpacked snapshot objects
|
|
1493
|
+
// obj = internal.pack(obj);
|
|
1489
1494
|
var entryId = String(++snapshotCount).padStart(3, '0');
|
|
1490
1495
|
var snapshotId = sessionId + '_' + entryId; // e.g. session_d89fw_001
|
|
1496
|
+
var size = obj.length;
|
|
1491
1497
|
var entry = {
|
|
1492
1498
|
created: Date.now(),
|
|
1493
1499
|
session: sessionId,
|
|
1494
1500
|
id: snapshotId,
|
|
1495
1501
|
name: snapshotCount + '.',
|
|
1496
1502
|
number: snapshotCount,
|
|
1497
|
-
size:
|
|
1498
|
-
display_size: formatSize(
|
|
1503
|
+
size: size,
|
|
1504
|
+
display_size: formatSize(size)
|
|
1499
1505
|
};
|
|
1500
1506
|
|
|
1501
|
-
await idb.set(entry.id,
|
|
1507
|
+
await idb.set(entry.id, obj);
|
|
1502
1508
|
await addToIndex(entry);
|
|
1503
1509
|
renderMenu();
|
|
1504
1510
|
}
|
|
@@ -1507,9 +1513,8 @@
|
|
|
1507
1513
|
function formatSize(bytes) {
|
|
1508
1514
|
var kb = Math.round(bytes / 1000);
|
|
1509
1515
|
var mb = (bytes / 1e6).toFixed(1);
|
|
1510
|
-
if (kb
|
|
1511
|
-
|
|
1512
|
-
}
|
|
1516
|
+
if (!kb) return '';
|
|
1517
|
+
if (kb < 990) return kb + 'kB';
|
|
1513
1518
|
return mb + 'MB';
|
|
1514
1519
|
}
|
|
1515
1520
|
|
|
@@ -1531,13 +1536,13 @@
|
|
|
1531
1536
|
}
|
|
1532
1537
|
|
|
1533
1538
|
async function restoreSnapshotById(id, gui) {
|
|
1534
|
-
var
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1539
|
+
var data;
|
|
1540
|
+
try {
|
|
1541
|
+
data = await internal.restoreSessionData(await idb.get(id));
|
|
1542
|
+
} catch(e) {
|
|
1543
|
+
console.error(e);
|
|
1544
|
+
stop$1('Snapshot is not available');
|
|
1538
1545
|
}
|
|
1539
|
-
var data = await internal.unpackSession(buf);
|
|
1540
|
-
buf = null;
|
|
1541
1546
|
gui.model.clear();
|
|
1542
1547
|
importDatasets(data.datasets, gui);
|
|
1543
1548
|
gui.clearMode();
|
|
@@ -1550,7 +1555,7 @@
|
|
|
1550
1555
|
if (buf instanceof ArrayBuffer) {
|
|
1551
1556
|
buf = new Uint8Array(buf);
|
|
1552
1557
|
}
|
|
1553
|
-
var data = await internal.
|
|
1558
|
+
var data = await internal.unpackSessionData(buf);
|
|
1554
1559
|
importDatasets(data.datasets, gui);
|
|
1555
1560
|
}
|
|
1556
1561
|
|
|
@@ -1573,7 +1578,7 @@
|
|
|
1573
1578
|
// console.timeEnd('msx')
|
|
1574
1579
|
delete lyr.active;
|
|
1575
1580
|
obj.gui = getGuiState(gui);
|
|
1576
|
-
return
|
|
1581
|
+
return obj;
|
|
1577
1582
|
}
|
|
1578
1583
|
|
|
1579
1584
|
// TODO: capture gui state information to allow restoring more of the UI
|
|
@@ -3040,21 +3045,13 @@
|
|
|
3040
3045
|
}
|
|
3041
3046
|
|
|
3042
3047
|
function getHistory() {
|
|
3043
|
-
|
|
3044
|
-
try {
|
|
3045
|
-
hist = JSON.parse(window.localStorage.getItem('console_history'));
|
|
3046
|
-
} catch(e) {
|
|
3047
|
-
}
|
|
3048
|
-
return hist && hist.length > 0 ? hist : [];
|
|
3048
|
+
return GUI.getSavedValue('console_history') || [];
|
|
3049
3049
|
}
|
|
3050
3050
|
|
|
3051
3051
|
function saveHistory() {
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
window.localStorage.setItem('console_history', JSON.stringify(history.slice(-50)));
|
|
3056
|
-
}
|
|
3057
|
-
} catch(e) {
|
|
3052
|
+
history = history.filter(Boolean); // TODO: fix condition that leaves a blank line on the history
|
|
3053
|
+
if (history.length > 0) {
|
|
3054
|
+
GUI.setSavedValue('console_history', history.slice(-100));
|
|
3058
3055
|
}
|
|
3059
3056
|
}
|
|
3060
3057
|
|
|
@@ -3678,7 +3675,13 @@
|
|
|
3678
3675
|
gui.addMode('export', turnOn, turnOff, exportBtn);
|
|
3679
3676
|
gui.keyboard.onMenuSubmit(menu, onExportClick);
|
|
3680
3677
|
if (window.showSaveFilePicker) {
|
|
3681
|
-
menu.findChild('#save-preference')
|
|
3678
|
+
menu.findChild('#save-preference')
|
|
3679
|
+
.css('display', 'inline-block')
|
|
3680
|
+
.findChild('input')
|
|
3681
|
+
.on('change', function() {
|
|
3682
|
+
GUI.setSavedValue('choose-save-dir', this.checked);
|
|
3683
|
+
})
|
|
3684
|
+
.attr('checked', GUI.getSavedValue('choose-save-dir') || null);
|
|
3682
3685
|
}
|
|
3683
3686
|
|
|
3684
3687
|
function turnOn() {
|
|
@@ -3702,8 +3705,6 @@
|
|
|
3702
3705
|
|
|
3703
3706
|
function onExportClick() {
|
|
3704
3707
|
var layers = getSelectedLayers();
|
|
3705
|
-
var chooseDir = menu.findChild('#save-preference input').node().checked;
|
|
3706
|
-
GUI.setSavedValue('choose-save-dir', chooseDir);
|
|
3707
3708
|
if (layers.length === 0) {
|
|
3708
3709
|
return gui.alert('No layers were selected');
|
|
3709
3710
|
}
|
|
@@ -8054,8 +8055,14 @@
|
|
|
8054
8055
|
}
|
|
8055
8056
|
});
|
|
8056
8057
|
|
|
8058
|
+
// add new field form
|
|
8059
|
+
if (editable) {
|
|
8060
|
+
renderNewRow(tableEl, rec, table);
|
|
8061
|
+
}
|
|
8062
|
+
|
|
8063
|
+
tableEl.appendTo(el);
|
|
8057
8064
|
if (rows > 0) {
|
|
8058
|
-
tableEl.appendTo(el);
|
|
8065
|
+
// tableEl.appendTo(el);
|
|
8059
8066
|
|
|
8060
8067
|
tableEl.on('copy', function(e) {
|
|
8061
8068
|
// remove leading or trailing tabs that sometimes get copied when
|
|
@@ -8075,15 +8082,26 @@
|
|
|
8075
8082
|
el.html(utils$1.format('<div class="note">This %s is missing attribute data.</div>',
|
|
8076
8083
|
table && table.getFields().length > 0 ? 'feature': 'layer'));
|
|
8077
8084
|
}
|
|
8085
|
+
|
|
8086
|
+
if (editable) {
|
|
8087
|
+
var line = El('div').appendTo(el);
|
|
8088
|
+
El('span').addClass('save-menu-btn').appendTo(line).on('click', async function(e) {
|
|
8089
|
+
|
|
8090
|
+
}).text('add field');
|
|
8091
|
+
}
|
|
8092
|
+
}
|
|
8093
|
+
|
|
8094
|
+
function renderNewRow(el, rec, table) {
|
|
8095
|
+
|
|
8078
8096
|
}
|
|
8079
8097
|
|
|
8080
8098
|
function renderRow(table, rec, key, type, editable) {
|
|
8081
|
-
var rowHtml = '<td class="field-name">%s</td><td><span class="value">%s</span> </td>';
|
|
8082
8099
|
var val = rec[key];
|
|
8083
8100
|
var str = formatInspectorValue(val, type);
|
|
8101
|
+
var rowHtml = `<td class="field-name">${key}</td><td><span class="value">${utils$1.htmlEscape(str)}</span> </td>`;
|
|
8084
8102
|
var cell = El('tr')
|
|
8085
8103
|
.appendTo(table)
|
|
8086
|
-
.html(
|
|
8104
|
+
.html(rowHtml)
|
|
8087
8105
|
.findChild('.value');
|
|
8088
8106
|
setFieldClass(cell, val, type);
|
|
8089
8107
|
if (editable) {
|
|
@@ -9797,19 +9815,26 @@
|
|
|
9797
9815
|
bx = t.bx,
|
|
9798
9816
|
by = t.by;
|
|
9799
9817
|
var x, y, xp, yp;
|
|
9818
|
+
var count = 0;
|
|
9800
9819
|
if (!vec.hasNext()) return;
|
|
9801
|
-
x =
|
|
9802
|
-
y =
|
|
9820
|
+
x = round(vec.x * mx + bx);
|
|
9821
|
+
y = round(vec.y * my + by);
|
|
9803
9822
|
ctx.moveTo(x, y);
|
|
9804
9823
|
while (vec.hasNext()) {
|
|
9824
|
+
xp = x;
|
|
9825
|
+
yp = y;
|
|
9805
9826
|
x = round(vec.x * mx + bx);
|
|
9806
9827
|
y = round(vec.y * my + by);
|
|
9807
9828
|
if (x != xp || y != yp) {
|
|
9808
9829
|
ctx.lineTo(x, y);
|
|
9809
|
-
|
|
9810
|
-
yp = y;
|
|
9830
|
+
count++;
|
|
9811
9831
|
}
|
|
9812
9832
|
}
|
|
9833
|
+
if (count === 0) {
|
|
9834
|
+
// draw a tiny line if all coords round to the same location,
|
|
9835
|
+
// so tiny shapes with strokes will consistently be drawn as dots,
|
|
9836
|
+
ctx.lineTo(x + 0.1, y);
|
|
9837
|
+
}
|
|
9813
9838
|
}
|
|
9814
9839
|
|
|
9815
9840
|
function roundToPix(x) {
|
|
@@ -10187,6 +10212,10 @@
|
|
|
10187
10212
|
runCommand('-clip bbox=' + box.getDataCoords().join(','));
|
|
10188
10213
|
});
|
|
10189
10214
|
|
|
10215
|
+
new SimpleButton(popup.findChild('.erase-btn')).on('click', function() {
|
|
10216
|
+
runCommand('-erase bbox=' + box.getDataCoords().join(','));
|
|
10217
|
+
});
|
|
10218
|
+
|
|
10190
10219
|
gui.addMode('box_tool', turnOn, turnOff);
|
|
10191
10220
|
|
|
10192
10221
|
gui.on('interaction_mode_change', function(e) {
|