mapshaper 0.6.115 → 0.6.116

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.
Files changed (3) hide show
  1. package/mapshaper.js +199 -28
  2. package/package.json +1 -1
  3. package/www/mapshaper.js +199 -28
package/mapshaper.js CHANGED
@@ -5248,7 +5248,7 @@
5248
5248
  }
5249
5249
 
5250
5250
  function toLngLat(xy, P) {
5251
- return projectPoint(xy, P, parseCrsString('wgs84'));
5251
+ return projectPoint(xy, P, parseCrsString$1('wgs84'));
5252
5252
  }
5253
5253
 
5254
5254
  function projectPoint(xy, crsFrom, crsTo) {
@@ -5335,11 +5335,11 @@
5335
5335
  function getCrsInfo(str) {
5336
5336
  return {
5337
5337
  crs_string: str,
5338
- crs: parseCrsString(str)
5338
+ crs: parseCrsString$1(str)
5339
5339
  };
5340
5340
  }
5341
5341
 
5342
- function parseCrsString(str) {
5342
+ function parseCrsString$1(str) {
5343
5343
  var defn = getProjDefn(str); // defn is a string or a Proj object
5344
5344
  var P;
5345
5345
  if (!utils.isString(defn)) {
@@ -5374,15 +5374,15 @@
5374
5374
  function getDatasetCrsInfo(dataset) {
5375
5375
  var info = copyCrsProperties(dataset.info || {});
5376
5376
  if (!info.crs && info.wkt1) {
5377
- info.crs = parseCrsString(wkt1ToProj(info.wkt1));
5377
+ info.crs = parseCrsString$1(wkt1ToProj(info.wkt1));
5378
5378
  } else if (!info.crs && info.crs_string) {
5379
- info.crs = parseCrsString(info.crs_string);
5379
+ info.crs = parseCrsString$1(info.crs_string);
5380
5380
  }
5381
5381
  if (!info.crs) {
5382
5382
  if (probablyDecimalDegreeBounds(getDatasetBounds(dataset))) {
5383
5383
  // use wgs84 for probable latlong datasets with unknown datums
5384
5384
  info.crs_string = 'wgs84';
5385
- info.crs = parseCrsString(info.crs_string);
5385
+ info.crs = parseCrsString$1(info.crs_string);
5386
5386
  }
5387
5387
  }
5388
5388
  return info;
@@ -5473,7 +5473,7 @@
5473
5473
 
5474
5474
  // Convert contents of a .prj file to a projection object
5475
5475
  function parsePrj(str) {
5476
- return parseCrsString(wkt1ToProj(str));
5476
+ return parseCrsString$1(wkt1ToProj(str));
5477
5477
  }
5478
5478
 
5479
5479
  var Projections = /*#__PURE__*/Object.freeze({
@@ -5499,7 +5499,7 @@
5499
5499
  isWGS84: isWGS84,
5500
5500
  isWebMercator: isWebMercator,
5501
5501
  looksLikeProj4String: looksLikeProj4String,
5502
- parseCrsString: parseCrsString,
5502
+ parseCrsString: parseCrsString$1,
5503
5503
  parsePrj: parsePrj,
5504
5504
  printProjections: printProjections,
5505
5505
  projectPoint: projectPoint,
@@ -24493,22 +24493,28 @@ ${svg}
24493
24493
  }
24494
24494
 
24495
24495
  async function exportLayerToGeoPackage(lyr, dataset, gpkg, opts) {
24496
- var features, fields, columns;
24496
+ var features, fields, columns, tableName, targetSrs;
24497
24497
  if (!lyr.geometry_type) return;
24498
24498
  features = exportLayerAsGeoJSON(lyr, dataset, opts, true, null)
24499
24499
  .filter(feat => !!(feat && feat.geometry));
24500
24500
  if (features.length === 0) return;
24501
24501
  fields = inferFieldTypes(features);
24502
- var tableName = getTableName(lyr.name);
24502
+ tableName = getTableName(lyr.name);
24503
24503
  columns = fields.map(function(field) {
24504
24504
  return {
24505
24505
  name: field.name,
24506
24506
  dataType: field.type
24507
24507
  };
24508
24508
  });
24509
- await gpkg.createFeatureTableFromProperties(tableName, columns);
24509
+ targetSrs = getExportSrs(dataset);
24510
+ await ensureSrsExists(gpkg, targetSrs);
24511
+ // createFeatureTableFromProperties() hardcodes EPSG:4326
24512
+ await gpkg.createFeatureTable(tableName, null, columns, undefined, targetSrs.srs_id);
24510
24513
  var featureDao = gpkg.getFeatureDao(tableName);
24511
- var srs = normalizeSrsForInsert(featureDao && featureDao.srs);
24514
+ // addGeoJSONFeatureToGeoPackageWithFeatureDaoAndSrs() assumes source
24515
+ // GeoJSON is EPSG:4326 and reprojects unless given EPSG:4326 metadata.
24516
+ // Mapshaper output coords are already in target CRS, so suppress reprojection.
24517
+ var srs = getSourceSrsWithoutReprojection(featureDao && featureDao.srs, targetSrs);
24512
24518
  for (var i = 0; i < features.length; i++) {
24513
24519
  var feat = features[i];
24514
24520
  var normalized = normalizeFeature(feat, fields);
@@ -24607,6 +24613,143 @@ ${svg}
24607
24613
  return removeUndefinedValues(output);
24608
24614
  }
24609
24615
 
24616
+ function getExportSrs(dataset) {
24617
+ var info = dataset.info || {};
24618
+ var gpkgCrs = normalizeSrsForInsert(info.geopackage_crs);
24619
+ if (gpkgCrs) {
24620
+ if (!gpkgCrs.definition && info.wkt1) {
24621
+ gpkgCrs.definition = info.wkt1;
24622
+ }
24623
+ return gpkgCrs;
24624
+ }
24625
+ var parsed = parseCrsString(info.crs_string);
24626
+ if (parsed) {
24627
+ if (info.wkt1) parsed.definition = info.wkt1;
24628
+ return parsed;
24629
+ }
24630
+ var fromWkt = parseWktAuthority(info.wkt1);
24631
+ if (fromWkt) {
24632
+ fromWkt.definition = info.wkt1;
24633
+ return fromWkt;
24634
+ }
24635
+ if (info.wkt1) {
24636
+ return buildCustomSrsFromWkt(info.wkt1);
24637
+ }
24638
+ return {
24639
+ srs_id: 4326,
24640
+ organization: 'EPSG',
24641
+ organization_coordsys_id: 4326
24642
+ };
24643
+ }
24644
+
24645
+ function parseCrsString(str) {
24646
+ if (!str || typeof str != 'string') return null;
24647
+ var match = str.match(/^([a-z]+):(\d+)$/i);
24648
+ if (!match) return null;
24649
+ var org = match[1].toUpperCase();
24650
+ var code = +match[2];
24651
+ if (!code) return null;
24652
+ return {
24653
+ srs_id: code,
24654
+ organization: org,
24655
+ organization_coordsys_id: code
24656
+ };
24657
+ }
24658
+
24659
+ function parseWktAuthority(wkt) {
24660
+ if (!wkt || typeof wkt != 'string') return null;
24661
+ var rootAuthority = findTopLevelWktAuthority(wkt);
24662
+ if (!rootAuthority) return null;
24663
+ var org = String(rootAuthority[1]).toUpperCase();
24664
+ var code = +rootAuthority[2];
24665
+ if (!code) return null;
24666
+ return {
24667
+ srs_id: code,
24668
+ organization: org,
24669
+ organization_coordsys_id: code
24670
+ };
24671
+ }
24672
+
24673
+ function findTopLevelWktAuthority(wkt) {
24674
+ var depth = 0;
24675
+ var inQuote = false;
24676
+ for (var i = 0; i < wkt.length; i++) {
24677
+ var c = wkt.charAt(i);
24678
+ if (c == '"') {
24679
+ inQuote = !inQuote;
24680
+ continue;
24681
+ }
24682
+ if (inQuote) continue;
24683
+ if (c == '[') {
24684
+ depth++;
24685
+ continue;
24686
+ }
24687
+ if (c == ']') {
24688
+ depth--;
24689
+ continue;
24690
+ }
24691
+ if (depth != 1) continue;
24692
+ if (wkt.slice(i, i + 10).toUpperCase() == 'AUTHORITY[') {
24693
+ return wkt.slice(i).match(/^AUTHORITY\["([^"]+)","(\d+)"\]/i);
24694
+ }
24695
+ }
24696
+ return null;
24697
+ }
24698
+
24699
+ function buildCustomSrsFromWkt(wkt) {
24700
+ var srsId = getCustomSrsId(wkt);
24701
+ return {
24702
+ srs_id: srsId,
24703
+ srs_name: getWktName(wkt) || 'CUSTOM_CRS',
24704
+ organization: 'NONE',
24705
+ organization_coordsys_id: srsId,
24706
+ definition: wkt,
24707
+ description: 'Custom projection'
24708
+ };
24709
+ }
24710
+
24711
+ function getWktName(wkt) {
24712
+ var match = wkt && String(wkt).match(/^(?:PROJCS|GEOGCS)\["([^"]+)"/i);
24713
+ return match ? match[1] : null;
24714
+ }
24715
+
24716
+ function getCustomSrsId(wkt) {
24717
+ var str = String(wkt || '');
24718
+ var hash = 2166136261; // FNV-1a
24719
+ for (var i = 0; i < str.length; i++) {
24720
+ hash ^= str.charCodeAt(i);
24721
+ hash = (hash * 16777619) >>> 0;
24722
+ }
24723
+ return 100000 + (hash % 900000);
24724
+ }
24725
+
24726
+ async function ensureSrsExists(gpkg, srs) {
24727
+ if (!srs || !srs.srs_id) return;
24728
+ var existing = gpkg.getSrs(srs.srs_id);
24729
+ if (existing) return;
24730
+ if (!srs.definition) {
24731
+ stop$1('Unable to export GeoPackage with missing CRS definition for SRS ' + srs.srs_id);
24732
+ }
24733
+ var geopackage = require$1('@ngageoint/geopackage');
24734
+ var spatialReferenceSystem = new geopackage.SpatialReferenceSystem();
24735
+ spatialReferenceSystem.srs_id = srs.srs_id;
24736
+ spatialReferenceSystem.srs_name = srs.srs_name || (srs.organization + ':' + srs.organization_coordsys_id);
24737
+ spatialReferenceSystem.organization = srs.organization;
24738
+ spatialReferenceSystem.organization_coordsys_id = srs.organization_coordsys_id;
24739
+ spatialReferenceSystem.definition = srs.definition;
24740
+ spatialReferenceSystem.description = srs.description || null;
24741
+ gpkg.createSpatialReferenceSystem(spatialReferenceSystem);
24742
+ }
24743
+
24744
+ function getSourceSrsWithoutReprojection(tableSrs, fallbackSrs) {
24745
+ var target = normalizeSrsForInsert(tableSrs) || normalizeSrsForInsert(fallbackSrs);
24746
+ return {
24747
+ srs_id: target.srs_id,
24748
+ organization: 'EPSG',
24749
+ organization_coordsys_id: 4326
24750
+ };
24751
+ }
24752
+
24610
24753
  function normalizeValue(value, type) {
24611
24754
  if (value === null || value === undefined) return null;
24612
24755
  if (type == 'TEXT' && typeof value != 'string') {
@@ -24664,14 +24807,14 @@ ${svg}
24664
24807
  }
24665
24808
 
24666
24809
  function normalizeSrsForInsert(srs) {
24667
- if (!srs) {
24668
- return {
24669
- srs_id: 4326,
24670
- organization: 'EPSG',
24671
- organization_coordsys_id: 4326
24672
- };
24673
- }
24810
+ if (!srs) return null;
24674
24811
  var normalized = Object.assign({}, srs);
24812
+ if (normalized.srs_id == null && normalized.id != null) {
24813
+ normalized.srs_id = normalized.id;
24814
+ }
24815
+ if (normalized.organization_coordsys_id == null && normalized.code != null) {
24816
+ normalized.organization_coordsys_id = normalized.code;
24817
+ }
24675
24818
  if (normalized.srs_id == null && normalized.srsId != null) {
24676
24819
  normalized.srs_id = normalized.srsId;
24677
24820
  }
@@ -24685,6 +24828,7 @@ ${svg}
24685
24828
  if (!normalized.organization) {
24686
24829
  normalized.organization = 'EPSG';
24687
24830
  }
24831
+ normalized.organization = String(normalized.organization).toUpperCase();
24688
24832
  if (normalized.organization_coordsys_id == null) {
24689
24833
  normalized.organization_coordsys_id = normalized.srs_id || 4326;
24690
24834
  }
@@ -31313,17 +31457,26 @@ ${svg}
31313
31457
  var gpkg;
31314
31458
  var datasets;
31315
31459
  var source;
31460
+ var tmpPath = null;
31316
31461
 
31317
31462
  if (!geopackage || !geopackage.GeoPackageAPI) {
31318
31463
  stop$1('GeoPackage library is not loaded');
31319
31464
  }
31320
31465
 
31321
- source = utils.isString(content) ? content : new Uint8Array(content);
31466
+ if (utils.isString(content)) {
31467
+ source = content;
31468
+ } else if (!runningInBrowser()) {
31469
+ tmpPath = writeGeoPackageTempFile(content);
31470
+ source = tmpPath;
31471
+ } else {
31472
+ source = new Uint8Array(content);
31473
+ }
31322
31474
  gpkg = await geopackage.GeoPackageAPI.open(source);
31323
31475
  try {
31324
31476
  datasets = readFeatureTableDatasets(gpkg, opts);
31325
31477
  } finally {
31326
31478
  gpkg.close();
31479
+ removeTempGeoPackageFile(tmpPath);
31327
31480
  }
31328
31481
 
31329
31482
  if (datasets.length === 0) {
@@ -31338,6 +31491,24 @@ ${svg}
31338
31491
  return mergeDatasets(datasets);
31339
31492
  }
31340
31493
 
31494
+ function writeGeoPackageTempFile(content) {
31495
+ var fs = require$1('fs');
31496
+ var os = require$1('os');
31497
+ var path = require$1('path');
31498
+ var unique = Date.now() + '-' + process.pid + '-' + Math.random().toString(36).slice(2);
31499
+ var tmpPath = path.join(os.tmpdir(), 'mapshaper-gpkg-import-' + unique + '.gpkg');
31500
+ fs.writeFileSync(tmpPath, Buffer.from(new Uint8Array(content)));
31501
+ return tmpPath;
31502
+ }
31503
+
31504
+ function removeTempGeoPackageFile(filepath) {
31505
+ if (!filepath) return;
31506
+ var fs = require$1('fs');
31507
+ if (fs.existsSync(filepath)) {
31508
+ fs.unlinkSync(filepath);
31509
+ }
31510
+ }
31511
+
31341
31512
  // load lookup tables for epsg codes if needed (for browser)
31342
31513
  async function initProjLib(datasets) {
31343
31514
  for (const dataset of datasets) {
@@ -31690,7 +31861,7 @@ ${svg}
31690
31861
  if (o.crs_string) {
31691
31862
  // load external files (e.g. epsg definitions) if needed in GUI
31692
31863
  await initProjLibrary({crs: o.crs_string});
31693
- o.crs = parseCrsString(o.crs_string);
31864
+ o.crs = parseCrsString$1(o.crs_string);
31694
31865
  } else if (o.prj) {
31695
31866
  o.crs = parsePrj(o.prj);
31696
31867
  }
@@ -35072,7 +35243,7 @@ ${svg}
35072
35243
  // Make a single geodetic circle
35073
35244
  function getCircleGeoJSON(center, radius, vertices, opts) {
35074
35245
  var n = 360;
35075
- var geod = getGeodeticSegmentFunction(parseCrsString('wgs84')); // ?
35246
+ var geod = getGeodeticSegmentFunction(parseCrsString$1('wgs84')); // ?
35076
35247
  if (opts.inset) {
35077
35248
  radius -= opts.inset;
35078
35249
  }
@@ -43702,23 +43873,23 @@ ${svg}
43702
43873
  };
43703
43874
 
43704
43875
  function createUnprojectedPolygon(opts) {
43705
- var crs = parseCrsString('wgs84');
43876
+ var crs = parseCrsString$1('wgs84');
43706
43877
  return getPolygonDataset$1(crs, crs, opts);
43707
43878
  }
43708
43879
 
43709
43880
  function createProjectedPolygon(dest, opts) {
43710
- var src = parseCrsString('wgs84');
43881
+ var src = parseCrsString$1('wgs84');
43711
43882
  return getPolygonDataset$1(src, dest, opts);
43712
43883
  }
43713
43884
 
43714
43885
  function createUnprojectedGraticule(opts) {
43715
- var src = parseCrsString('wgs84');
43886
+ var src = parseCrsString$1('wgs84');
43716
43887
  var graticule = importGeoJSON(createGraticule(src, false, opts));
43717
43888
  return graticule;
43718
43889
  }
43719
43890
 
43720
43891
  function createProjectedGraticule(dest, opts) {
43721
- var src = parseCrsString('wgs84');
43892
+ var src = parseCrsString$1('wgs84');
43722
43893
  var outline = getOutlineDataset(src, dest, {});
43723
43894
  var graticule = importGeoJSON(createGraticule(dest, !!outline, opts));
43724
43895
  projectDataset(graticule, src, dest, {no_clip: false}); // TODO: densify?
@@ -46752,7 +46923,7 @@ ${svg}
46752
46923
  stop$1('Missing required radius parameter.');
46753
46924
  }
46754
46925
  var cp = opts.center || [0, 0];
46755
- var radius = opts.radius || getCircleRadiusFromAngle(parseCrsString('wgs84'), opts.radius_angle);
46926
+ var radius = opts.radius || getCircleRadiusFromAngle(parseCrsString$1('wgs84'), opts.radius_angle);
46756
46927
  return getCircleGeoJSON(cp, radius, null, {geometry_type : opts.geometry || 'polygon'});
46757
46928
  }
46758
46929
 
@@ -49343,7 +49514,7 @@ ${svg}
49343
49514
  });
49344
49515
  }
49345
49516
 
49346
- var version = "0.6.115";
49517
+ var version = "0.6.116";
49347
49518
 
49348
49519
  // Parse command line args into commands and run them
49349
49520
  // Function takes an optional Node-style callback. A Promise is returned if no callback is given.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mapshaper",
3
- "version": "0.6.115",
3
+ "version": "0.6.116",
4
4
  "description": "A tool for editing vector datasets for mapping and GIS.",
5
5
  "keywords": [
6
6
  "shapefile",
package/www/mapshaper.js CHANGED
@@ -5248,7 +5248,7 @@
5248
5248
  }
5249
5249
 
5250
5250
  function toLngLat(xy, P) {
5251
- return projectPoint(xy, P, parseCrsString('wgs84'));
5251
+ return projectPoint(xy, P, parseCrsString$1('wgs84'));
5252
5252
  }
5253
5253
 
5254
5254
  function projectPoint(xy, crsFrom, crsTo) {
@@ -5335,11 +5335,11 @@
5335
5335
  function getCrsInfo(str) {
5336
5336
  return {
5337
5337
  crs_string: str,
5338
- crs: parseCrsString(str)
5338
+ crs: parseCrsString$1(str)
5339
5339
  };
5340
5340
  }
5341
5341
 
5342
- function parseCrsString(str) {
5342
+ function parseCrsString$1(str) {
5343
5343
  var defn = getProjDefn(str); // defn is a string or a Proj object
5344
5344
  var P;
5345
5345
  if (!utils.isString(defn)) {
@@ -5374,15 +5374,15 @@
5374
5374
  function getDatasetCrsInfo(dataset) {
5375
5375
  var info = copyCrsProperties(dataset.info || {});
5376
5376
  if (!info.crs && info.wkt1) {
5377
- info.crs = parseCrsString(wkt1ToProj(info.wkt1));
5377
+ info.crs = parseCrsString$1(wkt1ToProj(info.wkt1));
5378
5378
  } else if (!info.crs && info.crs_string) {
5379
- info.crs = parseCrsString(info.crs_string);
5379
+ info.crs = parseCrsString$1(info.crs_string);
5380
5380
  }
5381
5381
  if (!info.crs) {
5382
5382
  if (probablyDecimalDegreeBounds(getDatasetBounds(dataset))) {
5383
5383
  // use wgs84 for probable latlong datasets with unknown datums
5384
5384
  info.crs_string = 'wgs84';
5385
- info.crs = parseCrsString(info.crs_string);
5385
+ info.crs = parseCrsString$1(info.crs_string);
5386
5386
  }
5387
5387
  }
5388
5388
  return info;
@@ -5473,7 +5473,7 @@
5473
5473
 
5474
5474
  // Convert contents of a .prj file to a projection object
5475
5475
  function parsePrj(str) {
5476
- return parseCrsString(wkt1ToProj(str));
5476
+ return parseCrsString$1(wkt1ToProj(str));
5477
5477
  }
5478
5478
 
5479
5479
  var Projections = /*#__PURE__*/Object.freeze({
@@ -5499,7 +5499,7 @@
5499
5499
  isWGS84: isWGS84,
5500
5500
  isWebMercator: isWebMercator,
5501
5501
  looksLikeProj4String: looksLikeProj4String,
5502
- parseCrsString: parseCrsString,
5502
+ parseCrsString: parseCrsString$1,
5503
5503
  parsePrj: parsePrj,
5504
5504
  printProjections: printProjections,
5505
5505
  projectPoint: projectPoint,
@@ -24493,22 +24493,28 @@ ${svg}
24493
24493
  }
24494
24494
 
24495
24495
  async function exportLayerToGeoPackage(lyr, dataset, gpkg, opts) {
24496
- var features, fields, columns;
24496
+ var features, fields, columns, tableName, targetSrs;
24497
24497
  if (!lyr.geometry_type) return;
24498
24498
  features = exportLayerAsGeoJSON(lyr, dataset, opts, true, null)
24499
24499
  .filter(feat => !!(feat && feat.geometry));
24500
24500
  if (features.length === 0) return;
24501
24501
  fields = inferFieldTypes(features);
24502
- var tableName = getTableName(lyr.name);
24502
+ tableName = getTableName(lyr.name);
24503
24503
  columns = fields.map(function(field) {
24504
24504
  return {
24505
24505
  name: field.name,
24506
24506
  dataType: field.type
24507
24507
  };
24508
24508
  });
24509
- await gpkg.createFeatureTableFromProperties(tableName, columns);
24509
+ targetSrs = getExportSrs(dataset);
24510
+ await ensureSrsExists(gpkg, targetSrs);
24511
+ // createFeatureTableFromProperties() hardcodes EPSG:4326
24512
+ await gpkg.createFeatureTable(tableName, null, columns, undefined, targetSrs.srs_id);
24510
24513
  var featureDao = gpkg.getFeatureDao(tableName);
24511
- var srs = normalizeSrsForInsert(featureDao && featureDao.srs);
24514
+ // addGeoJSONFeatureToGeoPackageWithFeatureDaoAndSrs() assumes source
24515
+ // GeoJSON is EPSG:4326 and reprojects unless given EPSG:4326 metadata.
24516
+ // Mapshaper output coords are already in target CRS, so suppress reprojection.
24517
+ var srs = getSourceSrsWithoutReprojection(featureDao && featureDao.srs, targetSrs);
24512
24518
  for (var i = 0; i < features.length; i++) {
24513
24519
  var feat = features[i];
24514
24520
  var normalized = normalizeFeature(feat, fields);
@@ -24607,6 +24613,143 @@ ${svg}
24607
24613
  return removeUndefinedValues(output);
24608
24614
  }
24609
24615
 
24616
+ function getExportSrs(dataset) {
24617
+ var info = dataset.info || {};
24618
+ var gpkgCrs = normalizeSrsForInsert(info.geopackage_crs);
24619
+ if (gpkgCrs) {
24620
+ if (!gpkgCrs.definition && info.wkt1) {
24621
+ gpkgCrs.definition = info.wkt1;
24622
+ }
24623
+ return gpkgCrs;
24624
+ }
24625
+ var parsed = parseCrsString(info.crs_string);
24626
+ if (parsed) {
24627
+ if (info.wkt1) parsed.definition = info.wkt1;
24628
+ return parsed;
24629
+ }
24630
+ var fromWkt = parseWktAuthority(info.wkt1);
24631
+ if (fromWkt) {
24632
+ fromWkt.definition = info.wkt1;
24633
+ return fromWkt;
24634
+ }
24635
+ if (info.wkt1) {
24636
+ return buildCustomSrsFromWkt(info.wkt1);
24637
+ }
24638
+ return {
24639
+ srs_id: 4326,
24640
+ organization: 'EPSG',
24641
+ organization_coordsys_id: 4326
24642
+ };
24643
+ }
24644
+
24645
+ function parseCrsString(str) {
24646
+ if (!str || typeof str != 'string') return null;
24647
+ var match = str.match(/^([a-z]+):(\d+)$/i);
24648
+ if (!match) return null;
24649
+ var org = match[1].toUpperCase();
24650
+ var code = +match[2];
24651
+ if (!code) return null;
24652
+ return {
24653
+ srs_id: code,
24654
+ organization: org,
24655
+ organization_coordsys_id: code
24656
+ };
24657
+ }
24658
+
24659
+ function parseWktAuthority(wkt) {
24660
+ if (!wkt || typeof wkt != 'string') return null;
24661
+ var rootAuthority = findTopLevelWktAuthority(wkt);
24662
+ if (!rootAuthority) return null;
24663
+ var org = String(rootAuthority[1]).toUpperCase();
24664
+ var code = +rootAuthority[2];
24665
+ if (!code) return null;
24666
+ return {
24667
+ srs_id: code,
24668
+ organization: org,
24669
+ organization_coordsys_id: code
24670
+ };
24671
+ }
24672
+
24673
+ function findTopLevelWktAuthority(wkt) {
24674
+ var depth = 0;
24675
+ var inQuote = false;
24676
+ for (var i = 0; i < wkt.length; i++) {
24677
+ var c = wkt.charAt(i);
24678
+ if (c == '"') {
24679
+ inQuote = !inQuote;
24680
+ continue;
24681
+ }
24682
+ if (inQuote) continue;
24683
+ if (c == '[') {
24684
+ depth++;
24685
+ continue;
24686
+ }
24687
+ if (c == ']') {
24688
+ depth--;
24689
+ continue;
24690
+ }
24691
+ if (depth != 1) continue;
24692
+ if (wkt.slice(i, i + 10).toUpperCase() == 'AUTHORITY[') {
24693
+ return wkt.slice(i).match(/^AUTHORITY\["([^"]+)","(\d+)"\]/i);
24694
+ }
24695
+ }
24696
+ return null;
24697
+ }
24698
+
24699
+ function buildCustomSrsFromWkt(wkt) {
24700
+ var srsId = getCustomSrsId(wkt);
24701
+ return {
24702
+ srs_id: srsId,
24703
+ srs_name: getWktName(wkt) || 'CUSTOM_CRS',
24704
+ organization: 'NONE',
24705
+ organization_coordsys_id: srsId,
24706
+ definition: wkt,
24707
+ description: 'Custom projection'
24708
+ };
24709
+ }
24710
+
24711
+ function getWktName(wkt) {
24712
+ var match = wkt && String(wkt).match(/^(?:PROJCS|GEOGCS)\["([^"]+)"/i);
24713
+ return match ? match[1] : null;
24714
+ }
24715
+
24716
+ function getCustomSrsId(wkt) {
24717
+ var str = String(wkt || '');
24718
+ var hash = 2166136261; // FNV-1a
24719
+ for (var i = 0; i < str.length; i++) {
24720
+ hash ^= str.charCodeAt(i);
24721
+ hash = (hash * 16777619) >>> 0;
24722
+ }
24723
+ return 100000 + (hash % 900000);
24724
+ }
24725
+
24726
+ async function ensureSrsExists(gpkg, srs) {
24727
+ if (!srs || !srs.srs_id) return;
24728
+ var existing = gpkg.getSrs(srs.srs_id);
24729
+ if (existing) return;
24730
+ if (!srs.definition) {
24731
+ stop$1('Unable to export GeoPackage with missing CRS definition for SRS ' + srs.srs_id);
24732
+ }
24733
+ var geopackage = require$1('@ngageoint/geopackage');
24734
+ var spatialReferenceSystem = new geopackage.SpatialReferenceSystem();
24735
+ spatialReferenceSystem.srs_id = srs.srs_id;
24736
+ spatialReferenceSystem.srs_name = srs.srs_name || (srs.organization + ':' + srs.organization_coordsys_id);
24737
+ spatialReferenceSystem.organization = srs.organization;
24738
+ spatialReferenceSystem.organization_coordsys_id = srs.organization_coordsys_id;
24739
+ spatialReferenceSystem.definition = srs.definition;
24740
+ spatialReferenceSystem.description = srs.description || null;
24741
+ gpkg.createSpatialReferenceSystem(spatialReferenceSystem);
24742
+ }
24743
+
24744
+ function getSourceSrsWithoutReprojection(tableSrs, fallbackSrs) {
24745
+ var target = normalizeSrsForInsert(tableSrs) || normalizeSrsForInsert(fallbackSrs);
24746
+ return {
24747
+ srs_id: target.srs_id,
24748
+ organization: 'EPSG',
24749
+ organization_coordsys_id: 4326
24750
+ };
24751
+ }
24752
+
24610
24753
  function normalizeValue(value, type) {
24611
24754
  if (value === null || value === undefined) return null;
24612
24755
  if (type == 'TEXT' && typeof value != 'string') {
@@ -24664,14 +24807,14 @@ ${svg}
24664
24807
  }
24665
24808
 
24666
24809
  function normalizeSrsForInsert(srs) {
24667
- if (!srs) {
24668
- return {
24669
- srs_id: 4326,
24670
- organization: 'EPSG',
24671
- organization_coordsys_id: 4326
24672
- };
24673
- }
24810
+ if (!srs) return null;
24674
24811
  var normalized = Object.assign({}, srs);
24812
+ if (normalized.srs_id == null && normalized.id != null) {
24813
+ normalized.srs_id = normalized.id;
24814
+ }
24815
+ if (normalized.organization_coordsys_id == null && normalized.code != null) {
24816
+ normalized.organization_coordsys_id = normalized.code;
24817
+ }
24675
24818
  if (normalized.srs_id == null && normalized.srsId != null) {
24676
24819
  normalized.srs_id = normalized.srsId;
24677
24820
  }
@@ -24685,6 +24828,7 @@ ${svg}
24685
24828
  if (!normalized.organization) {
24686
24829
  normalized.organization = 'EPSG';
24687
24830
  }
24831
+ normalized.organization = String(normalized.organization).toUpperCase();
24688
24832
  if (normalized.organization_coordsys_id == null) {
24689
24833
  normalized.organization_coordsys_id = normalized.srs_id || 4326;
24690
24834
  }
@@ -31313,17 +31457,26 @@ ${svg}
31313
31457
  var gpkg;
31314
31458
  var datasets;
31315
31459
  var source;
31460
+ var tmpPath = null;
31316
31461
 
31317
31462
  if (!geopackage || !geopackage.GeoPackageAPI) {
31318
31463
  stop$1('GeoPackage library is not loaded');
31319
31464
  }
31320
31465
 
31321
- source = utils.isString(content) ? content : new Uint8Array(content);
31466
+ if (utils.isString(content)) {
31467
+ source = content;
31468
+ } else if (!runningInBrowser()) {
31469
+ tmpPath = writeGeoPackageTempFile(content);
31470
+ source = tmpPath;
31471
+ } else {
31472
+ source = new Uint8Array(content);
31473
+ }
31322
31474
  gpkg = await geopackage.GeoPackageAPI.open(source);
31323
31475
  try {
31324
31476
  datasets = readFeatureTableDatasets(gpkg, opts);
31325
31477
  } finally {
31326
31478
  gpkg.close();
31479
+ removeTempGeoPackageFile(tmpPath);
31327
31480
  }
31328
31481
 
31329
31482
  if (datasets.length === 0) {
@@ -31338,6 +31491,24 @@ ${svg}
31338
31491
  return mergeDatasets(datasets);
31339
31492
  }
31340
31493
 
31494
+ function writeGeoPackageTempFile(content) {
31495
+ var fs = require$1('fs');
31496
+ var os = require$1('os');
31497
+ var path = require$1('path');
31498
+ var unique = Date.now() + '-' + process.pid + '-' + Math.random().toString(36).slice(2);
31499
+ var tmpPath = path.join(os.tmpdir(), 'mapshaper-gpkg-import-' + unique + '.gpkg');
31500
+ fs.writeFileSync(tmpPath, Buffer.from(new Uint8Array(content)));
31501
+ return tmpPath;
31502
+ }
31503
+
31504
+ function removeTempGeoPackageFile(filepath) {
31505
+ if (!filepath) return;
31506
+ var fs = require$1('fs');
31507
+ if (fs.existsSync(filepath)) {
31508
+ fs.unlinkSync(filepath);
31509
+ }
31510
+ }
31511
+
31341
31512
  // load lookup tables for epsg codes if needed (for browser)
31342
31513
  async function initProjLib(datasets) {
31343
31514
  for (const dataset of datasets) {
@@ -31690,7 +31861,7 @@ ${svg}
31690
31861
  if (o.crs_string) {
31691
31862
  // load external files (e.g. epsg definitions) if needed in GUI
31692
31863
  await initProjLibrary({crs: o.crs_string});
31693
- o.crs = parseCrsString(o.crs_string);
31864
+ o.crs = parseCrsString$1(o.crs_string);
31694
31865
  } else if (o.prj) {
31695
31866
  o.crs = parsePrj(o.prj);
31696
31867
  }
@@ -35072,7 +35243,7 @@ ${svg}
35072
35243
  // Make a single geodetic circle
35073
35244
  function getCircleGeoJSON(center, radius, vertices, opts) {
35074
35245
  var n = 360;
35075
- var geod = getGeodeticSegmentFunction(parseCrsString('wgs84')); // ?
35246
+ var geod = getGeodeticSegmentFunction(parseCrsString$1('wgs84')); // ?
35076
35247
  if (opts.inset) {
35077
35248
  radius -= opts.inset;
35078
35249
  }
@@ -43702,23 +43873,23 @@ ${svg}
43702
43873
  };
43703
43874
 
43704
43875
  function createUnprojectedPolygon(opts) {
43705
- var crs = parseCrsString('wgs84');
43876
+ var crs = parseCrsString$1('wgs84');
43706
43877
  return getPolygonDataset$1(crs, crs, opts);
43707
43878
  }
43708
43879
 
43709
43880
  function createProjectedPolygon(dest, opts) {
43710
- var src = parseCrsString('wgs84');
43881
+ var src = parseCrsString$1('wgs84');
43711
43882
  return getPolygonDataset$1(src, dest, opts);
43712
43883
  }
43713
43884
 
43714
43885
  function createUnprojectedGraticule(opts) {
43715
- var src = parseCrsString('wgs84');
43886
+ var src = parseCrsString$1('wgs84');
43716
43887
  var graticule = importGeoJSON(createGraticule(src, false, opts));
43717
43888
  return graticule;
43718
43889
  }
43719
43890
 
43720
43891
  function createProjectedGraticule(dest, opts) {
43721
- var src = parseCrsString('wgs84');
43892
+ var src = parseCrsString$1('wgs84');
43722
43893
  var outline = getOutlineDataset(src, dest, {});
43723
43894
  var graticule = importGeoJSON(createGraticule(dest, !!outline, opts));
43724
43895
  projectDataset(graticule, src, dest, {no_clip: false}); // TODO: densify?
@@ -46752,7 +46923,7 @@ ${svg}
46752
46923
  stop$1('Missing required radius parameter.');
46753
46924
  }
46754
46925
  var cp = opts.center || [0, 0];
46755
- var radius = opts.radius || getCircleRadiusFromAngle(parseCrsString('wgs84'), opts.radius_angle);
46926
+ var radius = opts.radius || getCircleRadiusFromAngle(parseCrsString$1('wgs84'), opts.radius_angle);
46756
46927
  return getCircleGeoJSON(cp, radius, null, {geometry_type : opts.geometry || 'polygon'});
46757
46928
  }
46758
46929
 
@@ -49343,7 +49514,7 @@ ${svg}
49343
49514
  });
49344
49515
  }
49345
49516
 
49346
- var version = "0.6.115";
49517
+ var version = "0.6.116";
49347
49518
 
49348
49519
  // Parse command line args into commands and run them
49349
49520
  // Function takes an optional Node-style callback. A Promise is returned if no callback is given.