mapshaper 0.6.11 → 0.6.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  (function () {
2
2
 
3
- var VERSION = "0.6.11";
3
+ var VERSION = "0.6.13";
4
4
 
5
5
 
6
6
  var utils = /*#__PURE__*/Object.freeze({
@@ -15644,9 +15644,11 @@ ${svg}
15644
15644
  } else if (buf instanceof ArrayBuffer) {
15645
15645
  // we're good
15646
15646
  } else if (typeof B$3 == 'function' && buf instanceof B$3) {
15647
- // Since node 0.10, DataView constructor doesn't accept Buffers,
15648
- // so need to copy Buffer to ArrayBuffer
15649
- buf = BinArray.toArrayBuffer(buf);
15647
+ if (buf.buffer && buf.buffer.byteLength == buf.length) {
15648
+ buf = buf.buffer;
15649
+ } else {
15650
+ buf = BinArray.copyToArrayBuffer(buf);
15651
+ }
15650
15652
  } else {
15651
15653
  error("BinArray constructor takes an integer, ArrayBuffer or Buffer argument");
15652
15654
  }
@@ -15692,7 +15694,7 @@ ${svg}
15692
15694
  return bytes;
15693
15695
  };
15694
15696
 
15695
- BinArray.toArrayBuffer = function(src) {
15697
+ BinArray.copyToArrayBuffer = function(src) {
15696
15698
  var n = src.length,
15697
15699
  dest = new ArrayBuffer(n),
15698
15700
  view = new Uint8Array(dest);
@@ -18543,7 +18545,13 @@ ${svg}
18543
18545
  // (cli.writeFile() now creates directories that don't exist)
18544
18546
  // cli.validateOutputDir(o.directory);
18545
18547
  }
18546
- o.file = pathInfo.filename;
18548
+ if (pathInfo.extension == 'gz') {
18549
+ o.file = pathInfo.basename;
18550
+ o.gzip = true;
18551
+ } else {
18552
+ o.file = pathInfo.filename;
18553
+ }
18554
+
18547
18555
  if (filenameIsUnsupportedOutputType(o.file)) {
18548
18556
  error("Output file looks like an unsupported file type:", o.file);
18549
18557
  }
@@ -23497,9 +23505,9 @@ ${svg}
23497
23505
 
23498
23506
  if (!content) {
23499
23507
  reader = new FileReader(filename);
23500
- } else if (content instanceof ArrayBuffer) {
23508
+ } else if (content instanceof ArrayBuffer || content instanceof Buffer) {
23501
23509
  // Web API imports JSON as ArrayBuffer, to support larger files
23502
- if (content.byteLength < 1e7) {
23510
+ if ((content.byteLength || content.length) < 1e7) {
23503
23511
  // content = utils.createBuffer(content).toString();
23504
23512
  content = bufferToString(utils.createBuffer(content));
23505
23513
  } else {
@@ -23524,7 +23532,7 @@ ${svg}
23524
23532
  content = JSON.parse(content); // ~3sec for 100MB string
23525
23533
  } catch(e) {
23526
23534
  // stop("Unable to parse JSON");
23527
- stop('JSON parsing error --', e.message);
23535
+ stop('JSON parsing error:', e.message);
23528
23536
  }
23529
23537
  }
23530
23538
  if (opts.json_path) {
@@ -23816,9 +23824,6 @@ ${svg}
23816
23824
  }
23817
23825
  // TODO: consider using a temp file, to support incremental reading
23818
23826
  content = require('zlib').gunzipSync(cli.readFile(pathgz));
23819
- if (fileType == 'json' || fileType == 'text') {
23820
- content = trimBOM(decodeString(content, encoding || 'utf-8'));
23821
- }
23822
23827
 
23823
23828
  } else { // type can't be inferred from filename -- try reading as text
23824
23829
  content = cli.readFile(path, encoding || 'utf-8', cache);
@@ -42154,6 +42159,7 @@ ${svg}
42154
42159
 
42155
42160
  // Unified function for processing calls to runCommands() and applyCommands()
42156
42161
  function _runCommands(argv, opts, callback) {
42162
+
42157
42163
  var outputArr = opts.output || null,
42158
42164
  inputObj = opts.input,
42159
42165
  commands;
@@ -42200,6 +42206,7 @@ ${svg}
42200
42206
 
42201
42207
  function done(err, job) {
42202
42208
  err = filterError(err);
42209
+ if (err) printError(err);
42203
42210
  callback(err, job);
42204
42211
  }
42205
42212
  }
@@ -42280,8 +42287,8 @@ ${svg}
42280
42287
  }
42281
42288
 
42282
42289
  function filterError(err) {
42283
- if (err) printError(err);
42284
42290
  if (err && err.name == 'NonFatalError') {
42291
+ printError(err);
42285
42292
  return null;
42286
42293
  }
42287
42294
  return err;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mapshaper",
3
- "version": "0.6.11",
3
+ "version": "0.6.13",
4
4
  "description": "A tool for editing vector datasets for mapping and GIS.",
5
5
  "keywords": [
6
6
  "shapefile",
package/www/index.html CHANGED
@@ -97,7 +97,10 @@
97
97
  <img class="pin-btn pinned" src="images/eye2.png">
98
98
  </div>
99
99
  <div class="layer-list"></div>
100
- <div><div id="add-file-btn" class="dialog-btn btn">Add a file</div></div>
100
+ <div>
101
+ <div id="add-file-btn" class="dialog-btn btn">Add a file</div>
102
+ <!-- <div id="add-empty-btn" class="dialog-btn btn">Empty layer</div> -->
103
+ </div>
101
104
  </div>
102
105
  </div>
103
106
  </div>
@@ -682,11 +682,10 @@
682
682
  El.setStyle = function(el, name, val) {
683
683
  var jsName = El.toCamelCase(name);
684
684
  if (el.style[jsName] == void 0) {
685
- console.error("[Element.setStyle()] css property:", jsName);
686
685
  return;
687
686
  }
688
687
  var cssVal = val;
689
- if (isFinite(val)) {
688
+ if (isFinite(val) && val !== null) {
690
689
  cssVal = String(val); // problem if converted to scientific notation
691
690
  if (jsName != 'opacity' && jsName != 'zIndex') {
692
691
  cssVal += "px";
@@ -763,16 +762,14 @@
763
762
 
764
763
  // Apply inline css styles to this Element, either as string or object.
765
764
  css: function(css, val) {
766
- if (val != null) {
767
- El.setStyle(this.el, css, val);
768
- }
769
- else if (utils$1.isString(css)) {
770
- addCSS(this.el, css);
771
- }
772
- else if (utils$1.isObject(css)) {
765
+ if (utils$1.isObject(css)) {
773
766
  utils$1.forEachProperty(css, function(val, key) {
774
767
  El.setStyle(this.el, key, val);
775
768
  }, this);
769
+ } else if (val === void 0) {
770
+ addCSS(this.el, css);
771
+ } else {
772
+ El.setStyle(this.el, css, val);
776
773
  }
777
774
  return this;
778
775
  },
@@ -1277,6 +1274,7 @@
1277
1274
  new FileChooser('#file-selection-btn', receiveFiles);
1278
1275
  new FileChooser('#import-buttons .add-btn', receiveFiles);
1279
1276
  new FileChooser('#add-file-btn', receiveFiles);
1277
+ // new SimpleButton('#add-empty-btn').on('click', addEmptyLayer);
1280
1278
  initDropArea('#import-quick-drop', true);
1281
1279
  initDropArea('#import-drop');
1282
1280
  gui.keyboard.onMenuSubmit(El('#import-options'), importQueuedFiles);
@@ -1322,9 +1320,12 @@
1322
1320
  await importFiles(files);
1323
1321
  }
1324
1322
  } catch(e) {
1325
- console.error(e);
1323
+ gui.alert(e.message, 'Import error');
1324
+ }
1325
+ if (gui.getMode() == 'import') {
1326
+ // Mode could also be 'alert' if an error is thrown and handled
1327
+ gui.clearMode();
1326
1328
  }
1327
- gui.clearMode();
1328
1329
  }
1329
1330
 
1330
1331
  function turnOn() {
@@ -1388,10 +1389,20 @@
1388
1389
  }
1389
1390
 
1390
1391
  async function receiveFiles(files) {
1391
- // TODO: show importing message here?
1392
- var expanded = await expandFiles(files);
1392
+ var expanded = [];
1393
+ try {
1394
+ expanded = await expandFiles(files);
1395
+ } catch(e) {
1396
+ gui.alert(e.message, 'Import error');
1397
+ return;
1398
+ }
1393
1399
  addFilesToQueue(expanded);
1394
- if (queuedFiles.length === 0) return;
1400
+ if (queuedFiles.length === 0) {
1401
+ var names = getFileNames(files);
1402
+ var msg = `Unable to import data from: ${names.join(', ')}`;
1403
+ gui.alert(msg, 'Import error');
1404
+ return;
1405
+ }
1395
1406
  gui.enterMode('import');
1396
1407
  if (useQuickView()) {
1397
1408
  importQueuedFiles();
@@ -1402,6 +1413,10 @@
1402
1413
  }
1403
1414
  }
1404
1415
 
1416
+ function getFileNames(files) {
1417
+ return Array.from(files).map(function(f) {return f.name;});
1418
+ }
1419
+
1405
1420
  async function expandFiles(files) {
1406
1421
  var files2 = [], expanded;
1407
1422
  for (var f of files) {
@@ -1442,6 +1457,19 @@
1442
1457
  gui.session.fileImported(group.filename, optStr);
1443
1458
  }
1444
1459
 
1460
+ function addEmptyLayer() {
1461
+ var dataset = {
1462
+ layers: [{
1463
+ name: 'New layer',
1464
+ geometry_type: 'point',
1465
+ shapes: []
1466
+ }],
1467
+ info: {}
1468
+ };
1469
+ model.addDataset(dataset);
1470
+ gui.clearMode();
1471
+ }
1472
+
1445
1473
  function filesMayContainPaths(files) {
1446
1474
  return utils$1.some(files, function(f) {
1447
1475
  var type = internal.guessInputFileType(f.name);
@@ -1497,16 +1525,6 @@
1497
1525
  }
1498
1526
  }
1499
1527
 
1500
- function handleImportError(e, fileName) {
1501
- var msg = utils$1.isString(e) ? e : e.message;
1502
- if (fileName) {
1503
- msg = "Error importing <i>" + fileName + "</i><br>" + msg;
1504
- }
1505
- clearQueuedFiles();
1506
- gui.alert(msg);
1507
- console.error(e);
1508
- }
1509
-
1510
1528
  function prepFilesForDownload(names) {
1511
1529
  var items = names.map(function(name) {
1512
1530
  var isUrl = /:\/\//.test(name);
@@ -1565,7 +1583,7 @@
1565
1583
  }
1566
1584
 
1567
1585
  async function readZipFile(file) {
1568
- var files;
1586
+ var files = [];
1569
1587
  await wait(35); // pause a beat so status message can display
1570
1588
  try {
1571
1589
  files = await runAsync(GUI.readZipFile, file);
@@ -1575,8 +1593,8 @@
1575
1593
  return !/\.txt$/i.test(f.name);
1576
1594
  });
1577
1595
  } catch(e) {
1578
- handleImportError(e, file.name);
1579
- files = [];
1596
+ console.error(e);
1597
+ throw Error(`Unable to unzip ${file.name}`);
1580
1598
  }
1581
1599
  return files;
1582
1600
  }
@@ -1592,9 +1610,9 @@
1592
1610
  type: internal.guessInputType(file.name, content)
1593
1611
  };
1594
1612
  } catch (e) {
1595
- handleImportError("Web browser was unable to load the file.", file.name);
1613
+ console.error(e);
1614
+ throw Error(`Browser was unable to load the file ${file.name}`);
1596
1615
  }
1597
- return null;
1598
1616
  }
1599
1617
 
1600
1618
  async function readFiles(files) {
@@ -2985,15 +3003,19 @@
2985
3003
  var el;
2986
3004
  gui.addMode('alert', function() {}, turnOff);
2987
3005
 
2988
- gui.alert = function(str) {
2989
- var infoBox;
3006
+ gui.alert = function(str, title) {
3007
+ var infoBox, html = '';
2990
3008
  if (!el) {
2991
3009
  el = El('div').appendTo('body').addClass('error-wrapper');
2992
3010
  infoBox = El('div').appendTo(el).addClass('error-box info-box selectable');
2993
- El('p').addClass('error-message').appendTo(infoBox);
3011
+ El('div').appendTo(infoBox).addClass('error-content');
2994
3012
  El('div').addClass("btn dialog-btn").appendTo(infoBox).html('close').on('click', gui.clearMode);
2995
3013
  }
2996
- el.findChild('.error-message').html(str);
3014
+ if (title) {
3015
+ html += `<div class="error-title">${title}</div>`;
3016
+ }
3017
+ html += `<p class="error-message">${str}</p>`;
3018
+ el.findChild('.error-content').html(html);
2997
3019
  gui.enterMode('alert');
2998
3020
  };
2999
3021
 
@@ -6965,6 +6987,7 @@
6965
6987
  handles.forEach(function(handle) {
6966
6988
  handle.el.on('mousedown', function(e) {
6967
6989
  activeHandle = handle;
6990
+ activeHandle.el.css('background', 'black');
6968
6991
  prevXY = {x: e.pageX, y: e.pageY};
6969
6992
  });
6970
6993
  });
@@ -6992,6 +7015,7 @@
6992
7015
 
6993
7016
  document.addEventListener('mouseup', function() {
6994
7017
  if (activeHandle && _on) {
7018
+ activeHandle.el.css('background', null);
6995
7019
  activeHandle = null;
6996
7020
  prevXY = null;
6997
7021
  box.dispatchEvent('handle_up');
@@ -7034,7 +7058,7 @@
7034
7058
  el.css(props);
7035
7059
  el.show();
7036
7060
  if (handles) {
7037
- showHandles(handles, props);
7061
+ showHandles(handles, props, x2 < x1, y2 < y1);
7038
7062
  }
7039
7063
  };
7040
7064
 
@@ -7099,25 +7123,26 @@
7099
7123
  return handles;
7100
7124
  }
7101
7125
 
7102
- function showHandles(handles, props) {
7103
- var scaledSize = Math.ceil(Math.min(props.width, props.height) / 5);
7126
+ function showHandles(handles, props, xinv, yinv) {
7127
+ var scaledSize = Math.ceil(Math.min(props.width, props.height) / 3) - 1;
7104
7128
  var HANDLE_SIZE = Math.min(scaledSize, 7);
7129
+ var OFFS = Math.floor(HANDLE_SIZE / 2) + 1;
7105
7130
  handles.forEach(function(handle) {
7106
7131
  var top = 0,
7107
7132
  left = 0;
7108
7133
  if (handle.col == 'center') {
7109
7134
  left += props.width / 2 - HANDLE_SIZE / 2;
7110
- } else if (handle.col == 'right') {
7111
- left += props.width - HANDLE_SIZE + 1;
7135
+ } else if (handle.col == 'left' && xinv || handle.col == 'right' && !xinv) {
7136
+ left += props.width - HANDLE_SIZE + OFFS;
7112
7137
  } else {
7113
- left -= 1;
7138
+ left -= OFFS;
7114
7139
  }
7115
7140
  if (handle.row == 'center') {
7116
7141
  top += props.height / 2 - HANDLE_SIZE / 2;
7117
- } else if (handle.row == 'bottom') {
7118
- top += props.height - HANDLE_SIZE + 1;
7142
+ } else if (handle.row == 'top' && yinv || handle.row == 'bottom' && !yinv) {
7143
+ top += props.height - HANDLE_SIZE + OFFS;
7119
7144
  } else {
7120
- top -= 1;
7145
+ top -= OFFS;
7121
7146
  }
7122
7147
 
7123
7148
  handle.el.css({
package/www/mapshaper.js CHANGED
@@ -1,6 +1,6 @@
1
1
  (function () {
2
2
 
3
- var VERSION = "0.6.11";
3
+ var VERSION = "0.6.13";
4
4
 
5
5
 
6
6
  var utils = /*#__PURE__*/Object.freeze({
@@ -15644,9 +15644,11 @@ ${svg}
15644
15644
  } else if (buf instanceof ArrayBuffer) {
15645
15645
  // we're good
15646
15646
  } else if (typeof B$3 == 'function' && buf instanceof B$3) {
15647
- // Since node 0.10, DataView constructor doesn't accept Buffers,
15648
- // so need to copy Buffer to ArrayBuffer
15649
- buf = BinArray.toArrayBuffer(buf);
15647
+ if (buf.buffer && buf.buffer.byteLength == buf.length) {
15648
+ buf = buf.buffer;
15649
+ } else {
15650
+ buf = BinArray.copyToArrayBuffer(buf);
15651
+ }
15650
15652
  } else {
15651
15653
  error("BinArray constructor takes an integer, ArrayBuffer or Buffer argument");
15652
15654
  }
@@ -15692,7 +15694,7 @@ ${svg}
15692
15694
  return bytes;
15693
15695
  };
15694
15696
 
15695
- BinArray.toArrayBuffer = function(src) {
15697
+ BinArray.copyToArrayBuffer = function(src) {
15696
15698
  var n = src.length,
15697
15699
  dest = new ArrayBuffer(n),
15698
15700
  view = new Uint8Array(dest);
@@ -18543,7 +18545,13 @@ ${svg}
18543
18545
  // (cli.writeFile() now creates directories that don't exist)
18544
18546
  // cli.validateOutputDir(o.directory);
18545
18547
  }
18546
- o.file = pathInfo.filename;
18548
+ if (pathInfo.extension == 'gz') {
18549
+ o.file = pathInfo.basename;
18550
+ o.gzip = true;
18551
+ } else {
18552
+ o.file = pathInfo.filename;
18553
+ }
18554
+
18547
18555
  if (filenameIsUnsupportedOutputType(o.file)) {
18548
18556
  error("Output file looks like an unsupported file type:", o.file);
18549
18557
  }
@@ -23497,9 +23505,9 @@ ${svg}
23497
23505
 
23498
23506
  if (!content) {
23499
23507
  reader = new FileReader(filename);
23500
- } else if (content instanceof ArrayBuffer) {
23508
+ } else if (content instanceof ArrayBuffer || content instanceof Buffer) {
23501
23509
  // Web API imports JSON as ArrayBuffer, to support larger files
23502
- if (content.byteLength < 1e7) {
23510
+ if ((content.byteLength || content.length) < 1e7) {
23503
23511
  // content = utils.createBuffer(content).toString();
23504
23512
  content = bufferToString(utils.createBuffer(content));
23505
23513
  } else {
@@ -23524,7 +23532,7 @@ ${svg}
23524
23532
  content = JSON.parse(content); // ~3sec for 100MB string
23525
23533
  } catch(e) {
23526
23534
  // stop("Unable to parse JSON");
23527
- stop('JSON parsing error --', e.message);
23535
+ stop('JSON parsing error:', e.message);
23528
23536
  }
23529
23537
  }
23530
23538
  if (opts.json_path) {
@@ -23816,9 +23824,6 @@ ${svg}
23816
23824
  }
23817
23825
  // TODO: consider using a temp file, to support incremental reading
23818
23826
  content = require('zlib').gunzipSync(cli.readFile(pathgz));
23819
- if (fileType == 'json' || fileType == 'text') {
23820
- content = trimBOM(decodeString(content, encoding || 'utf-8'));
23821
- }
23822
23827
 
23823
23828
  } else { // type can't be inferred from filename -- try reading as text
23824
23829
  content = cli.readFile(path, encoding || 'utf-8', cache);
@@ -42154,6 +42159,7 @@ ${svg}
42154
42159
 
42155
42160
  // Unified function for processing calls to runCommands() and applyCommands()
42156
42161
  function _runCommands(argv, opts, callback) {
42162
+
42157
42163
  var outputArr = opts.output || null,
42158
42164
  inputObj = opts.input,
42159
42165
  commands;
@@ -42200,6 +42206,7 @@ ${svg}
42200
42206
 
42201
42207
  function done(err, job) {
42202
42208
  err = filterError(err);
42209
+ if (err) printError(err);
42203
42210
  callback(err, job);
42204
42211
  }
42205
42212
  }
@@ -42280,8 +42287,8 @@ ${svg}
42280
42287
  }
42281
42288
 
42282
42289
  function filterError(err) {
42283
- if (err) printError(err);
42284
42290
  if (err && err.name == 'NonFatalError') {
42291
+ printError(err);
42285
42292
  return null;
42286
42293
  }
42287
42294
  return err;
package/www/page.css CHANGED
@@ -251,6 +251,11 @@ body {
251
251
  left: 0;
252
252
  }
253
253
 
254
+ .error-title {
255
+ font-weight: bold;
256
+ margin-bottom: 4px;
257
+ }
258
+
254
259
  div.error-box {
255
260
  margin-top: 55px;
256
261
  overflow: auto;