mapshaper 0.6.12 → 0.6.14

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.12";
3
+ var VERSION = "0.6.14";
4
4
 
5
5
 
6
6
  var utils = /*#__PURE__*/Object.freeze({
@@ -7066,15 +7066,6 @@
7066
7066
  transformPoints: transformPoints
7067
7067
  });
7068
7068
 
7069
- function runningInBrowser() {
7070
- return typeof window !== 'undefined' && typeof window.document !== 'undefined';
7071
- }
7072
-
7073
- var Env = /*#__PURE__*/Object.freeze({
7074
- __proto__: null,
7075
- runningInBrowser: runningInBrowser
7076
- });
7077
-
7078
7069
  function getPathSep(path) {
7079
7070
  // TODO: improve
7080
7071
  return path.indexOf('/') == -1 && path.indexOf('\\') != -1 ? '\\' : '/';
@@ -7127,6 +7118,11 @@
7127
7118
  return getPathBase(path) + '.' + ext;
7128
7119
  }
7129
7120
 
7121
+ function toLowerCaseExtension(name) {
7122
+ var ext = getFileExtension(name);
7123
+ return ext ? getPathBase(name) + '.' + ext.toLowerCase() : name;
7124
+ }
7125
+
7130
7126
  function getCommonFileBase(names) {
7131
7127
  return names.reduce(function(memo, name, i) {
7132
7128
  if (i === 0) {
@@ -7150,10 +7146,157 @@
7150
7146
  getFileExtension: getFileExtension,
7151
7147
  getPathBase: getPathBase,
7152
7148
  replaceFileExtension: replaceFileExtension,
7149
+ toLowerCaseExtension: toLowerCaseExtension,
7153
7150
  getCommonFileBase: getCommonFileBase,
7154
7151
  getOutputFileBase: getOutputFileBase
7155
7152
  });
7156
7153
 
7154
+ // Guess the type of a data file from file extension, or return null if not sure
7155
+ function guessInputFileType(file) {
7156
+ var ext = getFileExtension(file || '').toLowerCase(),
7157
+ type = null;
7158
+ if (ext == 'dbf' || ext == 'shp' || ext == 'prj' || ext == 'shx' || ext == 'kml' || ext == 'cpg') {
7159
+ type = ext;
7160
+ } else if (/json$/.test(ext)) {
7161
+ type = 'json';
7162
+ } else if (ext == 'csv' || ext == 'tsv' || ext == 'txt' || ext == 'tab') {
7163
+ type = 'text';
7164
+ }
7165
+ return type;
7166
+ }
7167
+
7168
+ function guessInputContentType(content) {
7169
+ var type = null;
7170
+ if (utils.isString(content)) {
7171
+ type = stringLooksLikeJSON(content) && 'json' ||
7172
+ stringLooksLikeKML(content) && 'kml' || 'text';
7173
+ } else if (utils.isObject(content) && content.type || utils.isArray(content)) {
7174
+ type = 'json';
7175
+ }
7176
+ return type;
7177
+ }
7178
+
7179
+ function guessInputType(file, content) {
7180
+ return guessInputFileType(file) || guessInputContentType(content);
7181
+ }
7182
+
7183
+ function stringLooksLikeJSON(str) {
7184
+ return /^\s*[{[]/.test(String(str));
7185
+ }
7186
+
7187
+ function stringLooksLikeKML(str) {
7188
+ str = String(str);
7189
+ return str.includes('<kml ') && str.includes('xmlns="http://www.opengis.net/kml/');
7190
+ }
7191
+
7192
+ function couldBeDsvFile(name) {
7193
+ var ext = getFileExtension(name).toLowerCase();
7194
+ return /csv|tsv|txt$/.test(ext);
7195
+ }
7196
+
7197
+ function isZipFile(file) {
7198
+ return /\.zip$/i.test(file);
7199
+ }
7200
+
7201
+ function isSupportedOutputFormat(fmt) {
7202
+ var types = ['geojson', 'topojson', 'json', 'dsv', 'dbf', 'shapefile', 'svg'];
7203
+ return types.indexOf(fmt) > -1;
7204
+ }
7205
+
7206
+ function getFormatName(fmt) {
7207
+ return {
7208
+ geojson: 'GeoJSON',
7209
+ topojson: 'TopoJSON',
7210
+ json: 'JSON records',
7211
+ dsv: 'CSV',
7212
+ dbf: 'DBF',
7213
+ shapefile: 'Shapefile',
7214
+ svg: 'SVG'
7215
+ }[fmt] || '';
7216
+ }
7217
+
7218
+ // Assumes file at @path is one of Mapshaper's supported file types
7219
+ function isSupportedBinaryInputType(path) {
7220
+ var ext = getFileExtension(path).toLowerCase();
7221
+ return ext == 'shp' || ext == 'shx' || ext == 'dbf'; // GUI also supports zip files
7222
+ }
7223
+
7224
+ // Detect extensions of some unsupported file types, for cmd line validation
7225
+ function filenameIsUnsupportedOutputType(file) {
7226
+ var rxp = /\.(shx|prj|xls|xlsx|gdb|sbn|sbx|xml|kml)$/i;
7227
+ return rxp.test(file);
7228
+ }
7229
+
7230
+ var FileTypes = /*#__PURE__*/Object.freeze({
7231
+ __proto__: null,
7232
+ guessInputFileType: guessInputFileType,
7233
+ guessInputContentType: guessInputContentType,
7234
+ guessInputType: guessInputType,
7235
+ stringLooksLikeJSON: stringLooksLikeJSON,
7236
+ stringLooksLikeKML: stringLooksLikeKML,
7237
+ couldBeDsvFile: couldBeDsvFile,
7238
+ isZipFile: isZipFile,
7239
+ isSupportedOutputFormat: isSupportedOutputFormat,
7240
+ getFormatName: getFormatName,
7241
+ isSupportedBinaryInputType: isSupportedBinaryInputType,
7242
+ filenameIsUnsupportedOutputType: filenameIsUnsupportedOutputType
7243
+ });
7244
+
7245
+ // input: input file path or a Buffer containing .zip file bytes
7246
+ // cache: destination for extracted file contents
7247
+ function extractFiles(input, cache) {
7248
+ var zip = new require('adm-zip')(input);
7249
+ var files = zip.getEntries().map(function(entry) {
7250
+ // entry.entryName // path, including filename
7251
+ // entry.name // filename
7252
+ var file = toLowerCaseExtension(entry.name);
7253
+ if (file[0] == '.') return ''; // skip hidden system file
7254
+ var type = guessInputFileType(file);
7255
+ if (!type) return ''; // skip unrecognized extensions
7256
+ cache[file] = entry.getData();
7257
+ return file;
7258
+ });
7259
+ // remove auxiliary files from the import list
7260
+ // (these are files that can't be converted into datasets);
7261
+ return files.filter(function(file) {
7262
+ if (!file) return false;
7263
+ var type = guessInputFileType(file);
7264
+ if (type == 'dbf') {
7265
+ // don't import .dbf separately if .shp is present
7266
+ if (replaceFileExtension(file, 'shp') in cache) return false;
7267
+ }
7268
+ return type == 'text' || type == 'json' || type == 'shp' || type == 'dbf';
7269
+ });
7270
+ }
7271
+
7272
+ function convertOutputFiles(files, opts) {
7273
+ var filename = opts.zipfile || 'output.zip';
7274
+ var dirname = parseLocalPath(filename).basename;
7275
+ var zip = new require('adm-zip')();
7276
+ files.forEach(function(o) {
7277
+ var ofile = require('path').join(dirname, o.filename);
7278
+ var buf = Buffer.from(o.content);
7279
+ if (buf instanceof ArrayBuffer) {
7280
+ buf = new Uint8Array(buf);
7281
+ }
7282
+ zip.addFile(ofile, buf);
7283
+ delete o.content; // for gc?
7284
+ });
7285
+ return [{
7286
+ filename: filename,
7287
+ content: zip.toBuffer()
7288
+ }];
7289
+ }
7290
+
7291
+ function runningInBrowser() {
7292
+ return typeof window !== 'undefined' && typeof window.document !== 'undefined';
7293
+ }
7294
+
7295
+ var Env = /*#__PURE__*/Object.freeze({
7296
+ __proto__: null,
7297
+ runningInBrowser: runningInBrowser
7298
+ });
7299
+
7157
7300
  var cli = {};
7158
7301
 
7159
7302
  cli.isFile = function(path, cache) {
@@ -7303,6 +7446,9 @@
7303
7446
  // trigger EAGAIN error, e.g. when piped to less)
7304
7447
  return cli.writeFile('/dev/stdout', exports[0].content, cb);
7305
7448
  } else {
7449
+ if (opts.zip) {
7450
+ exports = convertOutputFiles(exports, opts);
7451
+ }
7306
7452
  var paths = getOutputPaths(utils.pluck(exports, 'filename'), opts);
7307
7453
  var inputFiles = getStashedVar('input_files');
7308
7454
  exports.forEach(function(obj, i) {
@@ -7312,7 +7458,7 @@
7312
7458
  obj.content = cli.convertArrayBuffer(obj.content); // convert to Buffer
7313
7459
  }
7314
7460
  if (opts.gzip) {
7315
- path = path + '.gz';
7461
+ path = /gz$/i.test(path) ? path : path + '.gz';
7316
7462
  obj.content = require$1('zlib').gzipSync(obj.content);
7317
7463
  }
7318
7464
  if (opts.output) {
@@ -17292,97 +17438,6 @@ ${svg}
17292
17438
  exportJSONTable: exportJSONTable
17293
17439
  });
17294
17440
 
17295
- // Guess the type of a data file from file extension, or return null if not sure
17296
- function guessInputFileType(file) {
17297
- var ext = getFileExtension(file || '').toLowerCase(),
17298
- type = null;
17299
- if (ext == 'dbf' || ext == 'shp' || ext == 'prj' || ext == 'shx' || ext == 'kml' || ext == 'cpg') {
17300
- type = ext;
17301
- } else if (/json$/.test(ext)) {
17302
- type = 'json';
17303
- } else if (ext == 'csv' || ext == 'tsv' || ext == 'txt' || ext == 'tab') {
17304
- type = 'text';
17305
- }
17306
- return type;
17307
- }
17308
-
17309
- function guessInputContentType(content) {
17310
- var type = null;
17311
- if (utils.isString(content)) {
17312
- type = stringLooksLikeJSON(content) && 'json' ||
17313
- stringLooksLikeKML(content) && 'kml' || 'text';
17314
- } else if (utils.isObject(content) && content.type || utils.isArray(content)) {
17315
- type = 'json';
17316
- }
17317
- return type;
17318
- }
17319
-
17320
- function guessInputType(file, content) {
17321
- return guessInputFileType(file) || guessInputContentType(content);
17322
- }
17323
-
17324
- function stringLooksLikeJSON(str) {
17325
- return /^\s*[{[]/.test(String(str));
17326
- }
17327
-
17328
- function stringLooksLikeKML(str) {
17329
- str = String(str);
17330
- return str.includes('<kml ') && str.includes('xmlns="http://www.opengis.net/kml/');
17331
- }
17332
-
17333
- function couldBeDsvFile(name) {
17334
- var ext = getFileExtension(name).toLowerCase();
17335
- return /csv|tsv|txt$/.test(ext);
17336
- }
17337
-
17338
- function isZipFile(file) {
17339
- return /\.zip$/i.test(file);
17340
- }
17341
-
17342
- function isSupportedOutputFormat(fmt) {
17343
- var types = ['geojson', 'topojson', 'json', 'dsv', 'dbf', 'shapefile', 'svg'];
17344
- return types.indexOf(fmt) > -1;
17345
- }
17346
-
17347
- function getFormatName(fmt) {
17348
- return {
17349
- geojson: 'GeoJSON',
17350
- topojson: 'TopoJSON',
17351
- json: 'JSON records',
17352
- dsv: 'CSV',
17353
- dbf: 'DBF',
17354
- shapefile: 'Shapefile',
17355
- svg: 'SVG'
17356
- }[fmt] || '';
17357
- }
17358
-
17359
- // Assumes file at @path is one of Mapshaper's supported file types
17360
- function isSupportedBinaryInputType(path) {
17361
- var ext = getFileExtension(path).toLowerCase();
17362
- return ext == 'shp' || ext == 'shx' || ext == 'dbf'; // GUI also supports zip files
17363
- }
17364
-
17365
- // Detect extensions of some unsupported file types, for cmd line validation
17366
- function filenameIsUnsupportedOutputType(file) {
17367
- var rxp = /\.(shx|prj|xls|xlsx|gdb|sbn|sbx|xml|kml)$/i;
17368
- return rxp.test(file);
17369
- }
17370
-
17371
- var FileTypes = /*#__PURE__*/Object.freeze({
17372
- __proto__: null,
17373
- guessInputFileType: guessInputFileType,
17374
- guessInputContentType: guessInputContentType,
17375
- guessInputType: guessInputType,
17376
- stringLooksLikeJSON: stringLooksLikeJSON,
17377
- stringLooksLikeKML: stringLooksLikeKML,
17378
- couldBeDsvFile: couldBeDsvFile,
17379
- isZipFile: isZipFile,
17380
- isSupportedOutputFormat: isSupportedOutputFormat,
17381
- getFormatName: getFormatName,
17382
- isSupportedBinaryInputType: isSupportedBinaryInputType,
17383
- filenameIsUnsupportedOutputType: filenameIsUnsupportedOutputType
17384
- });
17385
-
17386
17441
  function getOutputFormat(dataset, opts) {
17387
17442
  var outFile = opts.file || null,
17388
17443
  inFmt = dataset.info && dataset.info.input_formats && dataset.info.input_formats[0],
@@ -18545,7 +18600,23 @@ ${svg}
18545
18600
  // (cli.writeFile() now creates directories that don't exist)
18546
18601
  // cli.validateOutputDir(o.directory);
18547
18602
  }
18548
- o.file = pathInfo.filename;
18603
+ if (/gz/i.test(pathInfo.extension)) {
18604
+ // handle arguments like -o out.json.gz (the preferred format)
18605
+ if (parseLocalPath(pathInfo.basename).extension) {
18606
+ o.file = pathInfo.basename;
18607
+ } else {
18608
+ // handle arguments like -o out.gz
18609
+ o.file = pathInfo.filename;
18610
+ }
18611
+ o.gzip = true;
18612
+ } else if (/zip/i.test(pathInfo.extension)) {
18613
+ o.file = null;
18614
+ o.zipfile = pathInfo.filename;
18615
+ o.zip = true;
18616
+ } else {
18617
+ o.file = pathInfo.filename;
18618
+ }
18619
+
18549
18620
  if (filenameIsUnsupportedOutputType(o.file)) {
18550
18621
  error("Output file looks like an unsupported file type:", o.file);
18551
18622
  }
@@ -19355,6 +19426,10 @@ ${svg}
19355
19426
  describe: 'apply gzip compression to output files',
19356
19427
  type: 'flag'
19357
19428
  })
19429
+ .option('zip', {
19430
+ describe: 'save all output files in a single .zip file',
19431
+ type: 'flag'
19432
+ })
19358
19433
  .option('dry-run', {
19359
19434
  // describe: 'do not output any files'
19360
19435
  type: 'flag'
@@ -23719,36 +23794,6 @@ ${svg}
23719
23794
  importFileContent: importFileContent
23720
23795
  });
23721
23796
 
23722
- // Import multiple files to a single dataset
23723
- function importFiles(files, opts) {
23724
- var unbuiltTopology = false;
23725
- var datasets = files.map(function(fname) {
23726
- // import without topology or snapping
23727
- var importOpts = utils.defaults({no_topology: true, snap: false, snap_interval: null, files: [fname]}, opts);
23728
- var dataset = importFile(fname, importOpts);
23729
- // check if dataset contains non-topological paths
23730
- // TODO: may also need to rebuild topology if multiple topojson files are merged
23731
- if (dataset.arcs && dataset.arcs.size() > 0 && dataset.info.input_formats[0] != 'topojson') {
23732
- unbuiltTopology = true;
23733
- }
23734
- return dataset;
23735
- });
23736
- var combined = mergeDatasets(datasets);
23737
- // Build topology, if needed
23738
- // TODO: consider updating topology of TopoJSON files instead of concatenating arcs
23739
- // (but problem of mismatched coordinates due to quantization in input files.)
23740
- if (unbuiltTopology && !opts.no_topology) {
23741
- cleanPathsAfterImport(combined, opts);
23742
- buildTopology(combined);
23743
- }
23744
- return combined;
23745
- }
23746
-
23747
- var MergeFiles = /*#__PURE__*/Object.freeze({
23748
- __proto__: null,
23749
- importFiles: importFiles
23750
- });
23751
-
23752
23797
  cmd.importFiles = function(opts) {
23753
23798
  var files = opts.files || [],
23754
23799
  dataset;
@@ -23762,17 +23807,16 @@ ${svg}
23762
23807
  }
23763
23808
 
23764
23809
  verbose("Importing: " + files.join(' '));
23765
-
23766
- if (files.length == 1) {
23810
+ if (files.length == 1 && /\.zip/i.test(files[0])) {
23811
+ dataset = importZipFile(files[0], opts);
23812
+ } else if (files.length == 1) {
23767
23813
  dataset = importFile(files[0], opts);
23768
23814
  } else if (opts.merge_files) {
23769
23815
  // TODO: deprecate and remove this option (use -merge-layers cmd instead)
23770
- dataset = importFiles(files, opts);
23816
+ dataset = importFilesTogether(files, opts);
23771
23817
  dataset.layers = cmd.mergeLayers(dataset.layers);
23772
- } else if (opts.combine_files) {
23773
- dataset = importFiles(files, opts);
23774
23818
  } else {
23775
- stop('Invalid inputs');
23819
+ dataset = importFilesTogether(files, opts);
23776
23820
  }
23777
23821
  return dataset;
23778
23822
  };
@@ -23842,6 +23886,49 @@ ${svg}
23842
23886
  return importContent(input, opts);
23843
23887
  };
23844
23888
 
23889
+
23890
+ function importZipFile(path, opts) {
23891
+ var cache = {};
23892
+ var input;
23893
+ if (opts.input && (path in opts.input)) {
23894
+ // reading from a buffer
23895
+ input = opts.input[path];
23896
+ } else {
23897
+ // reading from a file
23898
+ cli.checkFileExists(path);
23899
+ input = path;
23900
+ }
23901
+ var files = extractFiles(input, cache);
23902
+ var zipOpts = Object.assign({}, opts, {input: cache});
23903
+ return importFilesTogether(files, zipOpts);
23904
+ }
23905
+
23906
+ // Import multiple files to a single dataset
23907
+ function importFilesTogether(files, opts) {
23908
+ var unbuiltTopology = false;
23909
+ var datasets = files.map(function(fname) {
23910
+ // import without topology or snapping
23911
+ var importOpts = utils.defaults({no_topology: true, snap: false, snap_interval: null, files: [fname]}, opts);
23912
+ var dataset = importFile(fname, importOpts);
23913
+ // check if dataset contains non-topological paths
23914
+ // TODO: may also need to rebuild topology if multiple topojson files are merged
23915
+ if (dataset.arcs && dataset.arcs.size() > 0 && dataset.info.input_formats[0] != 'topojson') {
23916
+ unbuiltTopology = true;
23917
+ }
23918
+ return dataset;
23919
+ });
23920
+ var combined = mergeDatasets(datasets);
23921
+ // Build topology, if needed
23922
+ // TODO: consider updating topology of TopoJSON files instead of concatenating arcs
23923
+ // (but problem of mismatched coordinates due to quantization in input files.)
23924
+ if (unbuiltTopology && !opts.no_topology) {
23925
+ cleanPathsAfterImport(combined, opts);
23926
+ buildTopology(combined);
23927
+ }
23928
+ return combined;
23929
+ }
23930
+
23931
+
23845
23932
  function getUnsupportedFileMessage(path) {
23846
23933
  var ext = getFileExtension(path);
23847
23934
  var msg = 'Unable to import ' + path;
@@ -23879,7 +23966,8 @@ ${svg}
23879
23966
  var FileImport = /*#__PURE__*/Object.freeze({
23880
23967
  __proto__: null,
23881
23968
  replaceImportFile: replaceImportFile,
23882
- importFile: importFile
23969
+ importFile: importFile,
23970
+ importFilesTogether: importFilesTogether
23883
23971
  });
23884
23972
 
23885
23973
  function convertSourceName(name, targets) {
@@ -42153,6 +42241,7 @@ ${svg}
42153
42241
 
42154
42242
  // Unified function for processing calls to runCommands() and applyCommands()
42155
42243
  function _runCommands(argv, opts, callback) {
42244
+
42156
42245
  var outputArr = opts.output || null,
42157
42246
  inputObj = opts.input,
42158
42247
  commands;
@@ -42199,6 +42288,7 @@ ${svg}
42199
42288
 
42200
42289
  function done(err, job) {
42201
42290
  err = filterError(err);
42291
+ if (err) printError(err);
42202
42292
  callback(err, job);
42203
42293
  }
42204
42294
  }
@@ -42279,8 +42369,8 @@ ${svg}
42279
42369
  }
42280
42370
 
42281
42371
  function filterError(err) {
42282
- if (err) printError(err);
42283
42372
  if (err && err.name == 'NonFatalError') {
42373
+ printError(err);
42284
42374
  return null;
42285
42375
  }
42286
42376
  return err;
@@ -42771,7 +42861,6 @@ ${svg}
42771
42861
  LayerUtils,
42772
42862
  Lines,
42773
42863
  Logging,
42774
- MergeFiles,
42775
42864
  Merging,
42776
42865
  MosaicIndex$1,
42777
42866
  OptionParsingUtils,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mapshaper",
3
- "version": "0.6.12",
3
+ "version": "0.6.14",
4
4
  "description": "A tool for editing vector datasets for mapping and GIS.",
5
5
  "keywords": [
6
6
  "shapefile",
@@ -42,6 +42,7 @@
42
42
  "dependencies": {
43
43
  "@tmcw/togeojson": "^4.7.0",
44
44
  "@xmldom/xmldom": "^0.8.2",
45
+ "adm-zip": "^0.5.9",
45
46
  "commander": "7.0.0",
46
47
  "cookies": "^0.8.0",
47
48
  "d3-color": "2.0.0",
package/www/basemap.js CHANGED
@@ -1,6 +1,6 @@
1
1
  window.mapboxParams = {
2
- js: 'https://api.mapbox.com/mapbox-gl-js/v2.7.0/mapbox-gl.js',
3
- css: 'https://api.mapbox.com/mapbox-gl-js/v2.7.0/mapbox-gl.css',
2
+ js: 'https://api.mapbox.com/mapbox-gl-js/v2.11.1/mapbox-gl.js',
3
+ css: 'https://api.mapbox.com/mapbox-gl-js/v2.11.1/mapbox-gl.css',
4
4
  key: 'pk.eyJ1IjoiZ3JhbW1hdGEiLCJhIjoiY2wxMzI4b3dqMDNhMjNpcDhzcmU0aGh5diJ9.m1lacx48pTYls-X3FVhG9g',
5
5
  styles: [{
6
6
  name: 'Map',