mapshaper 0.7.10 → 0.7.12

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/mapshaper.js CHANGED
@@ -17021,7 +17021,8 @@
17021
17021
  var groups = groupPolygonRings(obj.pathData, arcs, opts.invert_y);
17022
17022
  // invert_y is used internally for SVG generation
17023
17023
  // mapshaper's internal winding order is the opposite of RFC 7946
17024
- var reverse = opts.rfc7946 && !opts.invert_y;
17024
+ var rfc7946 = opts.rfc7946 === true;
17025
+ var reverse = rfc7946 !== !!opts.reverse_winding && !opts.invert_y;
17025
17026
  var coords = groups.map(function(paths) {
17026
17027
  return paths.map(function(path) {
17027
17028
  if (reverse) path.points.reverse();
@@ -26408,37 +26409,25 @@ ${svg}
26408
26409
  async function loadZstdLib() {
26409
26410
  var mod;
26410
26411
  if (runningInBrowser()) {
26411
- mod = require$1('zstd-codec');
26412
+ mod = require$1('@bokuweb/zstd-wasm');
26412
26413
  } else {
26413
26414
  if (!zstdPromise) {
26414
- zstdPromise = dynamicImportModule$1('zstd-codec');
26415
+ zstdPromise = dynamicImportModule$1('@bokuweb/zstd-wasm');
26415
26416
  }
26416
26417
  mod = await zstdPromise;
26417
26418
  }
26418
- if (mod && mod.default && !mod.ZstdCodec) {
26419
+ if (mod && mod.default && !mod.compress) {
26419
26420
  mod = mod.default;
26420
26421
  }
26421
- if (!mod || !mod.ZstdCodec || typeof mod.ZstdCodec.run != 'function') {
26422
+ if (!mod || typeof mod.init != 'function' || typeof mod.compress != 'function') {
26422
26423
  stop$1('GeoParquet ZSTD compressor is not loaded');
26423
26424
  }
26424
- return initZstdCodec(mod.ZstdCodec);
26425
+ await mod.init();
26426
+ return initZstdCodec(mod);
26425
26427
  }
26426
26428
 
26427
26429
  function initZstdCodec(codec) {
26428
- return new Promise(function(resolve, reject) {
26429
- try {
26430
- codec.run(function(zstd) {
26431
- var simple = new zstd.Simple();
26432
- resolve({
26433
- compress: function(bytes, level) {
26434
- return simple.compress(bytes, level);
26435
- }
26436
- });
26437
- });
26438
- } catch (e) {
26439
- reject(e);
26440
- }
26441
- });
26430
+ return codec;
26442
26431
  }
26443
26432
 
26444
26433
  function getOutputFormat(dataset, opts) {
@@ -29145,6 +29134,10 @@ ${svg}
29145
29134
  describe: '[GeoJSON] use original GeoJSON spec (not RFC 7946)',
29146
29135
  type: 'flag'
29147
29136
  })
29137
+ .option('reverse-winding', {
29138
+ describe: '[GeoJSON] reverse polygon winding order',
29139
+ type: 'flag'
29140
+ })
29148
29141
  .option('rfc7946', {
29149
29142
  // dummy option so old commands do not break
29150
29143
  type: 'flag'
@@ -34623,8 +34616,8 @@ ${svg}
34623
34616
  var candidates = getGeoParquetCrsStrings(crs);
34624
34617
  for (var i = 0; i < candidates.length; i++) {
34625
34618
  try {
34626
- parseCrsString$1(candidates[i]);
34627
34619
  await initProjLibrary({crs: candidates[i]});
34620
+ parseCrsString$1(candidates[i]);
34628
34621
  return candidates[i];
34629
34622
  } catch (e) {
34630
34623
  // Keep trying candidates; if none initialize, caller will warn.
@@ -48771,7 +48764,7 @@ ${svg}
48771
48764
  return layerHasGeometry(lyr) && !layerIsFullyEnclosed(lyr, dataset, clipData);
48772
48765
  });
48773
48766
  if (layers.length > 0) {
48774
- clipLayersInPlace(layers, clipData, dataset, 'clip');
48767
+ clipLayersInPlace(layers, clipData, dataset, 'clip', getInternalClipOpts());
48775
48768
  return true;
48776
48769
  }
48777
48770
  return false;
@@ -48810,13 +48803,21 @@ ${svg}
48810
48803
  }
48811
48804
 
48812
48805
  function datasetCrossesLon(dataset, lon) {
48813
- var crosses = 0;
48814
- dataset.arcs.forEachSegment(function(i, j, xx, yy) {
48815
- var ax = xx[i],
48816
- bx = xx[j];
48817
- if (ax <= lon && bx >= lon || ax >= lon && bx <= lon) crosses++;
48806
+ var crosses = false;
48807
+ dataset.layers.filter(layerHasPaths).forEach(function(lyr) {
48808
+ if (crosses) return;
48809
+ lyr.shapes.forEach(function(shp) {
48810
+ if (crosses || !shp) return;
48811
+ forEachSegmentInShape(shp, dataset.arcs, function(i, j, xx, yy) {
48812
+ var ax = xx[i],
48813
+ bx = xx[j];
48814
+ if (ax <= lon && bx >= lon || ax >= lon && bx <= lon) {
48815
+ crosses = true;
48816
+ }
48817
+ });
48818
+ });
48818
48819
  });
48819
- return crosses > 0;
48820
+ return crosses;
48820
48821
  }
48821
48822
 
48822
48823
  function insertVerticalCut(dataset, lon) {
@@ -48827,29 +48828,38 @@ ${svg}
48827
48828
  // densify (so cut line can curve, e.g. Cupola projection)
48828
48829
  var geojson = bboxToPolygon(bbox, {interval: 0.5});
48829
48830
  var clip = importGeoJSON(geojson);
48830
- clipLayersInPlace(pathLayers, clip, dataset, 'erase');
48831
+ clipLayersInPlace(pathLayers, clip, dataset, 'erase', getInternalClipOpts());
48832
+ }
48833
+
48834
+ function getInternalClipOpts() {
48835
+ return {no_cleanup: true, no_warn: true};
48831
48836
  }
48832
48837
 
48833
- // Converts a Proj.4 projection name (e.g. lcc, tmerc) to a Proj.4 string
48838
+ // Converts a Proj.4 projection name (e.g. lcc, tmerc, utm) to a Proj.4 string
48834
48839
  // by picking parameters that are appropriate to the extent of the dataset
48835
48840
  // being projected (e.g. standard parallels, longitude of origin)
48836
- // Works for lcc, aea, tmerc, etc.
48841
+ // Works for lcc, aea, tmerc, utm, etc.
48837
48842
  // TODO: add more projections
48838
48843
  //
48839
48844
  function expandProjDefn(str, dataset, targetLayers) {
48840
48845
  var mproj = require$1('mproj');
48841
- var proj4, params, bbox, isConic2SP, isCentered, decimals;
48846
+ var proj4, params, bbox, isConic2SP, isCentered, isUtm, decimals;
48842
48847
  if (str in mproj.internal.pj_list === false) {
48843
48848
  // not a bare projection code -- assume valid projection string in other format
48844
48849
  return str;
48845
48850
  }
48846
48851
  isConic2SP = ['lcc', 'aea'].includes(str);
48847
48852
  isCentered = ['tmerc', 'etmerc'].includes(str);
48853
+ isUtm = str == 'utm';
48848
48854
  proj4 = '+proj=' + str;
48849
- if (isConic2SP || isCentered) {
48855
+ if (isConic2SP || isCentered || isUtm) {
48850
48856
  bbox = getBBox(dataset, targetLayers); // TODO: support projected datasets
48851
48857
  decimals = getBoundsPrecisionForDisplay(bbox);
48852
- params = isCentered ? getCenterParams(bbox, decimals) : getConicParams(bbox, decimals);
48858
+ if (isUtm) {
48859
+ params = getUtmParams(bbox);
48860
+ } else {
48861
+ params = isCentered ? getCenterParams(bbox, decimals) : getConicParams(bbox, decimals);
48862
+ }
48853
48863
  proj4 += ' ' + params;
48854
48864
  message(`Converted "${str}" to "${proj4}"`);
48855
48865
  }
@@ -48865,7 +48875,77 @@ ${svg}
48865
48875
  if (!isLatLngCRS(getDatasetCRS(dataset))) {
48866
48876
  stop$1('Expected unprojected data');
48867
48877
  }
48868
- return getDatasetBounds(source).toArray();
48878
+ return getAutoFitBBox(source);
48879
+ }
48880
+
48881
+ function getAutoFitBBox(dataset) {
48882
+ var bbox = getDatasetBounds(dataset).toArray();
48883
+ if (bbox[2] - bbox[0] > 180) {
48884
+ bbox = getWrappedBBox(dataset, bbox) || bbox;
48885
+ }
48886
+ return bbox;
48887
+ }
48888
+
48889
+ function getWrappedBBox(dataset, bbox) {
48890
+ var xmaxW = -Infinity,
48891
+ xminE = Infinity, xmaxE = -Infinity,
48892
+ ymin = bbox[1], ymax = bbox[3],
48893
+ gap;
48894
+
48895
+ // Detect dateline clustering with a streaming east/west split. The gap
48896
+ // between the two boxes can only shrink as more coordinates are scanned.
48897
+ forEachDatasetCoord(dataset, function(x) {
48898
+ if (x < 0) {
48899
+ if (x > xmaxW) xmaxW = x;
48900
+ } else {
48901
+ if (x < xminE) xminE = x;
48902
+ if (x > xmaxE) xmaxE = x;
48903
+ }
48904
+ if (xmaxW > -Infinity && xmaxE > -Infinity) {
48905
+ gap = xminE - xmaxW;
48906
+ return gap > 180;
48907
+ }
48908
+ });
48909
+
48910
+ if (xmaxW == -Infinity || xmaxE == -Infinity) return null;
48911
+ if (xminE - xmaxW <= 180) return null;
48912
+ return [xminE, ymin, xmaxW + 360, ymax];
48913
+ }
48914
+
48915
+ function forEachDatasetCoord(dataset, cb) {
48916
+ var arcs = dataset.arcs;
48917
+ var usedArcs = arcs ? new Uint8Array(arcs.size()) : null;
48918
+ var keepGoing = true;
48919
+ dataset.layers.forEach(function(lyr) {
48920
+ if (!keepGoing) return;
48921
+ if (lyr.geometry_type == 'point') {
48922
+ keepGoing = scanPointCoords(lyr.shapes, cb);
48923
+ } else if (arcs && (lyr.geometry_type == 'polygon' || lyr.geometry_type == 'polyline')) {
48924
+ forEachArcId(lyr.shapes, function(id) {
48925
+ var absId, iter;
48926
+ if (!keepGoing) return;
48927
+ absId = id < 0 ? ~id : id;
48928
+ if (usedArcs[absId]) return;
48929
+ usedArcs[absId] = 1;
48930
+ iter = arcs.getArcIter(absId);
48931
+ while (keepGoing && iter.hasNext()) {
48932
+ keepGoing = cb(iter.x, iter.y) !== false;
48933
+ }
48934
+ });
48935
+ }
48936
+ });
48937
+ }
48938
+
48939
+ function scanPointCoords(shapes, cb) {
48940
+ var shp, p;
48941
+ for (var i=0, n=shapes.length; i<n; i++) {
48942
+ shp = shapes[i];
48943
+ for (var j=0, m=shp ? shp.length : 0; j<m; j++) {
48944
+ p = shp[j];
48945
+ if (cb(p[0], p[1]) === false) return false;
48946
+ }
48947
+ }
48948
+ return true;
48869
48949
  }
48870
48950
 
48871
48951
  // See: Savric & Jenny, "Automating the selection of standard parallels for conic map projections"
@@ -48884,11 +48964,21 @@ ${svg}
48884
48964
  return `+lon_0=${ cx.toFixed(decimals) } +lat_0=${ cy.toFixed(decimals) }`;
48885
48965
  }
48886
48966
 
48967
+ function getUtmParams(bbox) {
48968
+ var cx = (bbox[0] + bbox[2]) / 2;
48969
+ var cy = (bbox[1] + bbox[3]) / 2;
48970
+ var zone = Math.floor((cx + 180) / 6) + 1;
48971
+ zone = Math.max(1, Math.min(60, zone));
48972
+ return `+zone=${ zone }` + (cy < 0 ? ' +south' : '');
48973
+ }
48974
+
48887
48975
  var ProjectionParams = /*#__PURE__*/Object.freeze({
48888
48976
  __proto__: null,
48889
48977
  expandProjDefn: expandProjDefn,
48978
+ getAutoFitBBox: getAutoFitBBox,
48890
48979
  getCenterParams: getCenterParams,
48891
- getConicParams: getConicParams
48980
+ getConicParams: getConicParams,
48981
+ getUtmParams: getUtmParams
48892
48982
  });
48893
48983
 
48894
48984
  cmd.proj = function(dataset, catalog, opts, targetLayers) {
@@ -55438,7 +55528,7 @@ ${svg}
55438
55528
  });
55439
55529
  }
55440
55530
 
55441
- var version = "0.7.10";
55531
+ var version = "0.7.12";
55442
55532
 
55443
55533
  // Parse command line args into commands and run them
55444
55534
  // Function takes an optional Node-style callback. A Promise is returned if no callback is given.
@@ -55496,8 +55586,10 @@ ${svg}
55496
55586
  var child = require$1('child_process').exec(command, {}, function(err, stdout, stderr) {
55497
55587
  opts.callback(err);
55498
55588
  });
55499
- child.stdout.pipe(process.stdout);
55500
- child.stderr.pipe(process.stderr);
55589
+ if (loggingEnabled()) {
55590
+ child.stdout.pipe(process.stdout);
55591
+ child.stderr.pipe(process.stderr);
55592
+ }
55501
55593
  if (opts.promise) return opts.promise;
55502
55594
  }
55503
55595
 
package/www/page.css CHANGED
@@ -13,6 +13,17 @@
13
13
  src: url('assets/iosevka-light.woff2') format('woff2');
14
14
  }
15
15
 
16
+ :root {
17
+ --bg-col: #eaf2f4; /* #f8fdff */
18
+ --xlt-theme-col: #f4f8f9;
19
+ --accent-col: #ffa; /* yellow logo text */
20
+ --theme-col: #1385B7; /* blue header / btn col */
21
+ --dk-theme-col: #1A6A96; /* btn hover col */
22
+ --lt-theme-col: #e6f7ff;
23
+ --colored-text: #10699b;
24
+ --normal-text: #333;
25
+ }
26
+
16
27
 
17
28
  html, body {
18
29
  height: 100%;
@@ -23,7 +34,7 @@ html, body {
23
34
 
24
35
  body {
25
36
  overflow: hidden;
26
- background-color: #f8fdff;
37
+ background-color: var(--bg-col);
27
38
  font: 14px/1.4 'SourceSans3', Arial, sans-serif;
28
39
  font-weight: 400;
29
40
  color: #444;
@@ -63,7 +74,7 @@ body.map-view {
63
74
  .page-header,
64
75
  .dialog-btn,
65
76
  .sidebar-btn {
66
- background-color: #1385B7;
77
+ background-color: var(--theme-col);
67
78
  }
68
79
 
69
80
  .colored-text,
@@ -73,11 +84,11 @@ body.map-view {
73
84
  .add-field-btn,
74
85
  .nav-menu-item,
75
86
  .edit-data-btn {
76
- color: #10699b;
87
+ color: var(--colored-text);
77
88
  }
78
89
 
79
90
  .dot-underline {
80
- border-color: #10699b;
91
+ border-color: var(--colored-text);
81
92
  }
82
93
 
83
94
  .dot-underline {
@@ -89,11 +100,11 @@ body.map-view {
89
100
  }
90
101
 
91
102
  /*.nav-btn * {
92
- fill: #1385B7;
103
+ fill: var(--theme-col);
93
104
  }*/
94
105
 
95
106
  .nav-btn * {
96
- fill: #1385B7;
107
+ fill: var(--theme-col);
97
108
  }
98
109
 
99
110
  .alert-btn + .alert-btn {
@@ -115,7 +126,7 @@ body.map-view {
115
126
  .btn.header-btn:hover,
116
127
  .dialog-btn.default-btn,
117
128
  .dialog-btn.selected-btn {
118
- background-color: #1A6A96;
129
+ background-color: var(--dk-theme-col);
119
130
  }
120
131
 
121
132
  .dialog-btn.disabled {
@@ -123,15 +134,15 @@ body.map-view {
123
134
  }
124
135
 
125
136
  .colored-text::selection {
126
- background-color: #e6f7ff;
137
+ background-color: var(--lt-theme-col);
127
138
  }
128
139
 
129
140
  .colored-text::-moz-selection {
130
- background-color: #e6f7ff;
141
+ background-color: var(--lt-theme-col);
131
142
  }
132
143
 
133
144
  .layer-item.active {
134
- background-color: #e6f7ff;
145
+ background-color: var(--lt-theme-col);
135
146
  }
136
147
 
137
148
  /* --- Page header --------------- */
@@ -153,7 +164,7 @@ body.map-view {
153
164
  }
154
165
 
155
166
  .mapshaper-logo .logo-highlight {
156
- color: #ffa;
167
+ color: var(--accent-col);
157
168
  }
158
169
 
159
170
  .page-header a {
@@ -212,7 +223,7 @@ body.map-view {
212
223
  }
213
224
 
214
225
  #sponsor-btn {
215
- color: #ffa;
226
+ color: var(--accent-col);
216
227
  }
217
228
 
218
229
  #sponsor-btn svg {
@@ -245,7 +256,7 @@ body.map-view {
245
256
  right: 0;
246
257
  min-width: 180px;
247
258
  background-color: #fff;
248
- color: #333;
259
+ color: var(--normal-text);
249
260
  border: 1px solid #ccc;
250
261
  border-radius: 3px;
251
262
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
@@ -260,7 +271,7 @@ body.map-view {
260
271
  .header-menu-item {
261
272
  display: block;
262
273
  padding: 4px 14px;
263
- color: #333;
274
+ color: var(--normal-text);
264
275
  font-size: 14px;
265
276
  line-height: 1.3;
266
277
  text-decoration: none;
@@ -270,7 +281,7 @@ body.map-view {
270
281
 
271
282
  .header-menu-item:hover,
272
283
  .header-menu-item:focus {
273
- background-color: #e6f7ff;
284
+ background-color: var(--lt-theme-col);
274
285
  color: #1A6A96;
275
286
  outline: none;
276
287
  }
@@ -286,7 +297,7 @@ body.map-view {
286
297
  }
287
298
 
288
299
  .history-menu-item {
289
- color: #333;
300
+ color: var(--normal-text);
290
301
  cursor: pointer;
291
302
  padding: 2px 0;
292
303
  white-space: nowrap;
@@ -475,7 +486,7 @@ div.alert-box {
475
486
  padding: 9px 11px 6px 11px;
476
487
  margin: 9px -1px 3px -1px;
477
488
  min-height: 130px;
478
- background: #f8fdff;
489
+ background: var(--xlt-theme-col);
479
490
  }
480
491
 
481
492
  .catalog-mode .file-catalog {
@@ -498,7 +509,7 @@ div.alert-box {
498
509
  overflow: hidden;
499
510
  border: 1.5px solid #aaa;
500
511
  border-radius: 19px;
501
- background-color: #f8fdff;
512
+ background-color: var(--bg-col);
502
513
  }
503
514
 
504
515
  .file-catalog table {
@@ -752,7 +763,7 @@ input[type="checkbox"]
752
763
  font-size: 15px;
753
764
  color: black;
754
765
  background-color: rgba(255, 255, 222, 0.85);
755
- border: 1px solid #333;
766
+ border: 1px solid var(--normal-text);
756
767
  }
757
768
 
758
769
  /* === Editing interface ========== */
@@ -820,7 +831,7 @@ body.console-open .map-area {
820
831
  z-index: 25;
821
832
  writing-mode: vertical-rl;
822
833
  transform: rotate(180deg);
823
- background-color: #1385B7;
834
+ background-color: var(--theme-col);
824
835
  color: white;
825
836
  padding: 9px 4px;
826
837
  border-radius: 5px 0 0 5px;
@@ -1500,7 +1511,7 @@ img.close-btn:hover,
1500
1511
  }
1501
1512
 
1502
1513
  .message-item .message-dismiss:hover {
1503
- color: #333;
1514
+ color: var(--normal-text);
1504
1515
  background-color: rgba(0, 0, 0, 0.05);
1505
1516
  }
1506
1517
 
@@ -1847,7 +1858,7 @@ body.pan.panning .map-layers:not(.drawing) {
1847
1858
  .contextmenu-item:hover,
1848
1859
  .nav-btn:hover .nav-sub-menu:not(.active):not(:hover) .nav-menu-item[data-name=info] {
1849
1860
  color: black;
1850
- background: #e6f7ff;
1861
+ background: var(--lt-theme-col);
1851
1862
  }
1852
1863
 
1853
1864
  .nav-menu-item.selected {
@@ -2007,12 +2018,12 @@ body.pan.panning .map-layers:not(.drawing) {
2007
2018
  }
2008
2019
 
2009
2020
  .floating-toolbar-btn svg * {
2010
- fill: #1385B7;
2021
+ fill: var(--theme-col);
2011
2022
  transition: fill 100ms ease;
2012
2023
  }
2013
2024
 
2014
2025
  .floating-toolbar-btn:hover:not(.disabled) {
2015
- background-color: #e6f7ff;
2026
+ background-color: var(--lt-theme-col);
2016
2027
  }
2017
2028
 
2018
2029
  .floating-toolbar-btn:hover:not(.disabled) svg * {
package/www/zstd.wasm ADDED
Binary file