mapshaper 0.7.49 → 0.7.51

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/www/modules.js CHANGED
@@ -21288,7 +21288,11 @@
21288
21288
  }
21289
21289
 
21290
21290
  function wkt_make_utm_params(P) {
21291
- var lon0 = P.lam0 * 180 / M_PI;
21291
+ // Recover the zone index that pj_utm_zone() encoded into P.lam0 and derive
21292
+ // the central meridian from it. Converting P.lam0 straight back to degrees
21293
+ // leaves rounding debris (zone 15 gives -92.99999999999999).
21294
+ var zone = Math.round((P.lam0 + M_PI) * 30 / M_PI - 0.5);
21295
+ var lon0 = (zone + 0.5) * 6 - 180;
21292
21296
  return [
21293
21297
  ["latitude_of_origin", 0],
21294
21298
  ["central_meridian", lon0],
@@ -22155,6 +22159,20 @@
22155
22159
 
22156
22160
  // --- Geodetic emission tables ----------------------------------------------
22157
22161
 
22162
+ // Realizations of the EPSG:6326 datum ensemble. A datum ensemble is only
22163
+ // meaningful with two or more members, and PROJ rejects a definition that
22164
+ // names fewer ("ensemble should have at least 2 datums").
22165
+ var WKT2_WGS84_ENSEMBLE_MEMBERS = [
22166
+ 'World Geodetic System 1984 (Transit)',
22167
+ 'World Geodetic System 1984 (G730)',
22168
+ 'World Geodetic System 1984 (G873)',
22169
+ 'World Geodetic System 1984 (G1150)',
22170
+ 'World Geodetic System 1984 (G1674)',
22171
+ 'World Geodetic System 1984 (G1762)',
22172
+ 'World Geodetic System 1984 (G2139)',
22173
+ 'World Geodetic System 1984 (G2296)'
22174
+ ];
22175
+
22158
22176
  // Proj4 datum id -> WKT2 emitter metadata. When the datum is not in this
22159
22177
  // table we fall back to DATUM[<wkt1Name-with-spaces>] with no ID.
22160
22178
  var wkt2_datum_emitters = {
@@ -22164,6 +22182,7 @@
22164
22182
  ensemble: true,
22165
22183
  ensembleId: 6326,
22166
22184
  ensembleName: 'World Geodetic System 1984 ensemble',
22185
+ ensembleMembers: WKT2_WGS84_ENSEMBLE_MEMBERS,
22167
22186
  datumName: 'World Geodetic System 1984'
22168
22187
  },
22169
22188
  NAD83: {
@@ -22278,12 +22297,15 @@
22278
22297
  }
22279
22298
 
22280
22299
  function wkt2_wrap_boundcrs(source, towgs84) {
22300
+ var ensemble = ['ENSEMBLE', 'World Geodetic System 1984 ensemble'];
22301
+ WKT2_WGS84_ENSEMBLE_MEMBERS.forEach(function(member) {
22302
+ ensemble.push(['MEMBER', member]);
22303
+ });
22304
+ ensemble.push(['ELLIPSOID', 'WGS 84', 6378137, 298.257223563, WKT2_LENGTHUNIT_M, ['ID', 'EPSG', 7030]]);
22305
+ ensemble.push(['ENSEMBLEACCURACY', 2]);
22306
+ ensemble.push(['ID', 'EPSG', 6326]);
22281
22307
  var target = ['GEOGCRS', 'WGS 84',
22282
- ['ENSEMBLE', 'World Geodetic System 1984 ensemble',
22283
- ['MEMBER', 'World Geodetic System 1984'],
22284
- ['ELLIPSOID', 'WGS 84', 6378137, 298.257223563, WKT2_LENGTHUNIT_M, ['ID', 'EPSG', 7030]],
22285
- ['ENSEMBLEACCURACY', 2],
22286
- ['ID', 'EPSG', 6326]],
22308
+ ensemble,
22287
22309
  ['PRIMEM', 'Greenwich', 0, WKT2_ANGLEUNIT, ['ID', 'EPSG', 8901]],
22288
22310
  ['CS', 'ellipsoidal', 2],
22289
22311
  ['AXIS', 'geodetic latitude (Lat)', 'north', ['ORDER', 1], WKT2_ANGLEUNIT],
@@ -22347,7 +22369,9 @@
22347
22369
  if (emitter && emitter.ensemble) {
22348
22370
  // WKT2:2019 ENSEMBLE form (WGS 84 and a handful of others)
22349
22371
  var ens = ['ENSEMBLE', emitter.ensembleName];
22350
- ens.push(['MEMBER', emitter.datumName]);
22372
+ (emitter.ensembleMembers || [emitter.datumName]).forEach(function(member) {
22373
+ ens.push(['MEMBER', member]);
22374
+ });
22351
22375
  ens.push(ellipsoidNode);
22352
22376
  ens.push(['ENSEMBLEACCURACY', 2]);
22353
22377
  if (emitter.ensembleId) {
@@ -23899,6 +23923,9 @@
23899
23923
  base_crs: wkt2_geogcrs_to_projjson(wkt2_find(node, 'BASEGEOGCRS') || wkt2_find(node, 'BASEGEODCRS')),
23900
23924
  conversion: wkt2_conversion_to_projjson(wkt2_find(node, 'CONVERSION'))
23901
23925
  };
23926
+ if (!out.base_crs.coordinate_system) {
23927
+ out.base_crs.coordinate_system = wkt2_default_ellipsoidal_cs();
23928
+ }
23902
23929
  var cs = wkt2_cs_to_projjson(node);
23903
23930
  if (cs) out.coordinate_system = cs;
23904
23931
  var id = wkt2_id_to_projjson(node);
@@ -24031,16 +24058,101 @@
24031
24058
  return out;
24032
24059
  }
24033
24060
 
24061
+ // WKT2 CS keywords are case-insensitive, but the PROJJSON schema enumerates
24062
+ // exact spellings -- notably "Cartesian" with a capital C.
24063
+ var wkt2_cs_subtypes = {
24064
+ affine: 'affine',
24065
+ cartesian: 'Cartesian',
24066
+ cylindrical: 'cylindrical',
24067
+ ellipsoidal: 'ellipsoidal',
24068
+ linear: 'linear',
24069
+ ordinal: 'ordinal',
24070
+ parametric: 'parametric',
24071
+ polar: 'polar',
24072
+ spherical: 'spherical',
24073
+ vertical: 'vertical',
24074
+ temporalcount: 'TemporalCount',
24075
+ temporaldatetime: 'TemporalDateTime',
24076
+ temporalmeasure: 'TemporalMeasure'
24077
+ };
24078
+
24079
+ // WKT2 packs an axis abbreviation into the name -- "geodetic latitude (Lat)",
24080
+ // or just "(E)" when there is no long name. PROJJSON requires the two to be
24081
+ // separate members.
24082
+ var wkt2_axis_names_by_abbrev = {
24083
+ E: 'Easting',
24084
+ N: 'Northing',
24085
+ Lat: 'Geodetic latitude',
24086
+ Lon: 'Geodetic longitude'
24087
+ };
24088
+
24089
+ var wkt2_axis_abbrevs_by_name = {
24090
+ 'easting': 'E',
24091
+ 'northing': 'N',
24092
+ 'geodetic latitude': 'Lat',
24093
+ 'geodetic longitude': 'Lon'
24094
+ };
24095
+
24096
+ var wkt2_axis_abbrevs_by_direction = {
24097
+ east: 'E',
24098
+ north: 'N',
24099
+ west: 'W',
24100
+ south: 'S',
24101
+ up: 'H',
24102
+ down: 'D'
24103
+ };
24104
+
24105
+ function wkt2_cs_subtype_to_projjson(keyword) {
24106
+ var key = String(keyword == null ? '' : keyword).toLowerCase();
24107
+ if (!key) return 'ellipsoidal';
24108
+ return wkt2_cs_subtypes[key] || key;
24109
+ }
24110
+
24111
+ function wkt2_axis_to_projjson_name(rawName, direction) {
24112
+ var name = String(rawName == null ? '' : rawName).trim();
24113
+ var abbrev = '';
24114
+ var parts = name.match(/^(.*?)\s*\(([^()]+)\)$/);
24115
+ if (parts) {
24116
+ name = parts[1].trim();
24117
+ abbrev = parts[2].trim();
24118
+ }
24119
+ if (!name && abbrev) {
24120
+ name = wkt2_axis_names_by_abbrev[abbrev] || abbrev;
24121
+ }
24122
+ if (!abbrev) {
24123
+ abbrev = wkt2_axis_abbrevs_by_name[name.toLowerCase()] ||
24124
+ wkt2_axis_abbrevs_by_direction[String(direction).toLowerCase()] ||
24125
+ name.charAt(0).toUpperCase();
24126
+ }
24127
+ if (name) name = name.charAt(0).toUpperCase() + name.substr(1);
24128
+ return {name: name || abbrev, abbreviation: abbrev};
24129
+ }
24130
+
24131
+ // WKT2 omits CS[] from BASEGEOGCRS, but PROJJSON requires a coordinate_system
24132
+ // on every CRS object, including the base of a ProjectedCRS.
24133
+ function wkt2_default_ellipsoidal_cs() {
24134
+ return {
24135
+ subtype: 'ellipsoidal',
24136
+ axis: [
24137
+ {name: 'Geodetic latitude', abbreviation: 'Lat', direction: 'north', unit: 'degree'},
24138
+ {name: 'Geodetic longitude', abbreviation: 'Lon', direction: 'east', unit: 'degree'}
24139
+ ]
24140
+ };
24141
+ }
24142
+
24034
24143
  function wkt2_cs_to_projjson(node) {
24035
24144
  var cs = wkt2_find(node, 'CS');
24036
24145
  var axes = wkt2_find_all(node, 'AXIS');
24037
24146
  if (!cs && axes.length === 0) return null;
24038
24147
  var out = {
24039
- subtype: cs && cs[1] ? String(cs[1]).toLowerCase() : 'ellipsoidal',
24148
+ subtype: wkt2_cs_subtype_to_projjson(cs && cs[1]),
24040
24149
  axis: axes.map(function(a) {
24150
+ var direction = wkt2_axis_direction(a);
24151
+ var parsed = wkt2_axis_to_projjson_name(wkt2_name_of(a), direction);
24041
24152
  var ax = {
24042
- name: wkt2_name_of(a),
24043
- direction: wkt2_axis_direction(a)
24153
+ name: parsed.name,
24154
+ abbreviation: parsed.abbreviation,
24155
+ direction: direction
24044
24156
  };
24045
24157
  var unit = wkt2_unit_to_projjson(wkt2_find(a, 'ANGLEUNIT') || wkt2_find(a, 'LENGTHUNIT') || wkt2_find(a, 'SCALEUNIT'));
24046
24158
  if (unit) {