mapshaper 0.6.43 → 0.6.45

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mapshaper",
3
- "version": "0.6.43",
3
+ "version": "0.6.45",
4
4
  "description": "A tool for editing vector datasets for mapping and GIS.",
5
5
  "keywords": [
6
6
  "shapefile",
@@ -68,7 +68,7 @@
68
68
  "browserify": "^17.0.0",
69
69
  "csv-spectrum": "^1.0.0",
70
70
  "eslint": "^8.16.0",
71
- "mocha": "^10.0.0",
71
+ "mocha": "^10.2.0",
72
72
  "rollup": "^2.73.0",
73
73
  "shell-quote": "^1.7.4",
74
74
  "underscore": "^1.13.1"
package/www/index.html CHANGED
@@ -170,8 +170,8 @@ precision=0.001. Click to see all options.</div></div></div></a>
170
170
  <input id="ofile-name" class="text-input" type="text" placeholder="output file name" />
171
171
  </div> -->
172
172
 
173
- <!-- <div class="cancel-btn btn dialog-btn">Cancel</div> -->
174
173
  <div class="save-btn btn dialog-btn">Export</div>
174
+ <!-- <span id="save-to-clipboard" class="inline-checkbox" style="display: inline-block;"><input type="checkbox"/>save to clipboard</span> -->
175
175
  <span id="save-preference" class="inline-checkbox" style="display: none;"><input type="checkbox"/>choose directory</span>
176
176
 
177
177
  </div>
@@ -5,6 +5,7 @@
5
5
  get default () { return utils; },
6
6
  get getUniqueName () { return getUniqueName; },
7
7
  get isFunction () { return isFunction; },
8
+ get isPromise () { return isPromise; },
8
9
  get isObject () { return isObject; },
9
10
  get clamp () { return clamp; },
10
11
  get isArray () { return isArray; },
@@ -1441,7 +1442,7 @@
1441
1442
  }).text('restore');
1442
1443
  El('span').addClass('save-menu-btn').appendTo(line).on('click', async function(e) {
1443
1444
  var obj = await idb.get(item.id);
1444
- await internal.applyCompression(obj, {consume: true});
1445
+ await internal.compressSnapshotForExport(obj);
1445
1446
  var buf = internal.pack(obj);
1446
1447
  // choose output filename and directory every time
1447
1448
  // saveBlobToLocalFile('mapshaper_snapshot.msx', new Blob([buf]));
@@ -2157,11 +2158,18 @@
2157
2158
  }
2158
2159
 
2159
2160
  function downloadNextFile(memo, item, next) {
2160
- var blob, err;
2161
- fetch(item.url).then(resp => resp.blob()).then(b => {
2162
- blob = b;
2163
- blob.name = item.basename;
2164
- memo.push(blob);
2161
+ var err;
2162
+ fetch(item.url).then(resp => {
2163
+ if (resp.status != 200) {
2164
+ // e.g. 404 because a URL listed in the GUI query string does not exist
2165
+ throw Error();
2166
+ }
2167
+ return resp.blob();
2168
+ }).then(blob => {
2169
+ if (blob) {
2170
+ blob.name = item.basename;
2171
+ memo.push(blob);
2172
+ }
2165
2173
  }).catch(e => {
2166
2174
  err = "Error&nbsp;loading&nbsp;" + item.name + ". Possible causes include: wrong URL, no network connection, server not configured for cross-domain sharing (CORS).";
2167
2175
  }).finally(() => {
@@ -5209,6 +5217,10 @@
5209
5217
  return typeof obj == 'function';
5210
5218
  }
5211
5219
 
5220
+ function isPromise(arg) {
5221
+ return arg ? isFunction(arg.then) : false;
5222
+ }
5223
+
5212
5224
  function isObject(obj) {
5213
5225
  return obj === Object(obj); // via underscore
5214
5226
  }
@@ -6360,6 +6372,61 @@
6360
6372
  arcs.updateVertexData(nn, xx2, yy2, zz2);
6361
6373
  }
6362
6374
 
6375
+ function countFilteredVertices(zz, zlimit) {
6376
+ var count = 0;
6377
+ for (var i=0, n = zz.length; i<n; i++) {
6378
+ if (zz[i] >= zlimit) count++;
6379
+ }
6380
+ return count;
6381
+ }
6382
+
6383
+ function filterVertexData(o, zlimit) {
6384
+ if (!o.zz) error('Expected simplification data');
6385
+ var xx = o.xx,
6386
+ yy = o.yy,
6387
+ zz = o.zz,
6388
+ len2 = countFilteredVertices(zz, zlimit),
6389
+ arcCount = o.nn.length,
6390
+ xx2 = new Float64Array(len2),
6391
+ yy2 = new Float64Array(len2),
6392
+ zz2 = new Float64Array(len2),
6393
+ nn2 = new Int32Array(arcCount),
6394
+ i = 0, i2 = 0,
6395
+ n, n2;
6396
+
6397
+ for (var arcId=0; arcId < arcCount; arcId++) {
6398
+ n2 = 0;
6399
+ n = o.nn[arcId];
6400
+ for (var end = i+n; i < end; i++) {
6401
+ if (zz[i] >= zlimit) {
6402
+ xx2[i2] = xx[i];
6403
+ yy2[i2] = yy[i];
6404
+ zz2[i2] = zz[i];
6405
+ i2++;
6406
+ n2++;
6407
+ }
6408
+ }
6409
+ if (n2 == 1) {
6410
+ error("Collapsed arc");
6411
+ // This should not happen (endpoints should be z == Infinity)
6412
+ // Could handle like this, instead of throwing an error:
6413
+ // n2 = 0;
6414
+ // xx2.pop();
6415
+ // yy2.pop();
6416
+ // zz2.pop();
6417
+ } else if (n2 === 0) {
6418
+ // collapsed arc... ignoring
6419
+ }
6420
+ nn2[arcId] = n2;
6421
+ }
6422
+ return {
6423
+ xx: xx2,
6424
+ yy: yy2,
6425
+ zz: zz2,
6426
+ nn: nn2
6427
+ };
6428
+ }
6429
+
6363
6430
  function getShapeHitTest(displayLayer, ext, interactionMode) {
6364
6431
  var geoType = displayLayer.layer.geometry_type;
6365
6432
  var test;
@@ -8011,14 +8078,13 @@
8011
8078
  });
8012
8079
 
8013
8080
  self.show = function(id, ids, lyr, pinned) {
8014
- var table = lyr.data; // table can be null (e.g. if layer has no attribute data)
8015
8081
  var editable = pinned && gui.interaction.getMode() == 'data';
8016
8082
  var maxHeight = parent.node().clientHeight - 36;
8017
8083
  currId = id;
8018
8084
  // stash a function for refreshing the current popup when data changes
8019
8085
  // while the popup is being displayed (e.g. while dragging a label)
8020
8086
  refresh = function() {
8021
- render(content, id, table, editable);
8087
+ render(content, id, lyr, editable);
8022
8088
  };
8023
8089
  refresh();
8024
8090
  if (ids && ids.length > 1) {
@@ -8057,7 +8123,8 @@
8057
8123
  tab.show();
8058
8124
  }
8059
8125
 
8060
- function render(el, recId, table, editable) {
8126
+ function render(el, recId, lyr, editable) {
8127
+ var table = lyr.data; // table can be null (e.g. if layer has no attribute data)
8061
8128
  var rec = table && (editable ? table.getRecordAt(recId) : table.getReadOnlyRecordAt(recId)) || {};
8062
8129
  var tableEl = El('table').addClass('selectable'),
8063
8130
  rows = 0;
@@ -8099,14 +8166,14 @@
8099
8166
  if (editable) {
8100
8167
  // render "add field" button
8101
8168
  var line = El('div').appendTo(el);
8102
- El('span').addClass('save-menu-btn').appendTo(line).on('click', async function(e) {
8169
+ El('span').addClass('add-field-btn').appendTo(line).on('click', async function(e) {
8103
8170
  // show "add field" dialog
8104
- renderAddFieldPopup(recId, table);
8171
+ renderAddFieldPopup(recId, lyr);
8105
8172
  }).text('+ add field');
8106
8173
  }
8107
8174
  }
8108
8175
 
8109
- function renderAddFieldPopup(recId, table) {
8176
+ function renderAddFieldPopup(recId, lyr) {
8110
8177
  var popup = showPopupAlert('', 'Add field');
8111
8178
  var el = popup.container();
8112
8179
  el.addClass('option-menu');
@@ -8120,6 +8187,7 @@
8120
8187
  var val = el.findChild('.field-value');
8121
8188
  var box = el.findChild('.all');
8122
8189
  var btn = el.findChild('.btn').on('click', function() {
8190
+ var table = internal.getLayerDataTable(lyr); // creates new table if missing
8123
8191
  var all = box.node().checked;
8124
8192
  var nameStr = name.node().value.trim();
8125
8193
  if (!nameStr) return;