mapshaper 0.5.109 → 0.5.112

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mapshaper",
3
- "version": "0.5.109",
3
+ "version": "0.5.112",
4
4
  "description": "A tool for editing vector datasets for mapping and GIS.",
5
5
  "keywords": [
6
6
  "shapefile",
@@ -27,7 +27,7 @@
27
27
  "prepublishOnly": "npm test; ./pre-publish",
28
28
  "postpublish": "./release_web_ui; ./release_github_version",
29
29
  "browserify_old": "browserify -r sync-request -r mproj -r buffer -r iconv-lite -r fs -r flatbush -r rw -r path -r d3-scale-chromatic -r d3-color -r d3-interpolate -o www/modules.js",
30
- "browserify": "browserify -r sync-request -r mproj -r buffer -r iconv-lite -r fs -r flatbush -r rw -r path -r d3-scale-chromatic -r d3-color -r d3-interpolate -r kdbush -o www/modules.js",
30
+ "browserify": "browserify -r sync-request -r mproj -r buffer -r iconv-lite -r fs -r flatbush -r rw -r path -r d3-scale-chromatic -r d3-color -r d3-interpolate -r kdbush -r @tmcw/togeojson -o www/modules.js",
31
31
  "watch": "rollup --config --watch",
32
32
  "dev": "rollup --config --watch"
33
33
  },
@@ -41,6 +41,8 @@
41
41
  "!.DS_Store"
42
42
  ],
43
43
  "dependencies": {
44
+ "@tmcw/togeojson": "^4.7.0",
45
+ "@xmldom/xmldom": "^0.8.2",
44
46
  "commander": "7.0.0",
45
47
  "cookies": "^0.8.0",
46
48
  "d3-color": "2.0.0",
package/www/index.html CHANGED
@@ -156,6 +156,9 @@
156
156
  <div class="basemap-styles"></div>
157
157
  <div>
158
158
  <div class="close-btn btn dialog-btn">Close</div>
159
+ <div class="clear-btn btn dialog-btn disabled">Clear</div>
160
+ <div class="fade-btn btn dialog-btn disabled">Fade</div>
161
+ <!-- <div class="hide-btn btn dialog-btn disabled">Hide</div> -->
159
162
  </div>
160
163
  </div>
161
164
  </div>
@@ -1107,7 +1107,7 @@
1107
1107
 
1108
1108
  utils$1.inherit(Checkbox, EventDispatcher);
1109
1109
 
1110
- function SimpleButton(ref) {
1110
+ function xSimpleButton(ref) {
1111
1111
  var _el = El(ref),
1112
1112
  _self = this,
1113
1113
  _active = !_el.hasClass('disabled');
@@ -1134,7 +1134,31 @@
1134
1134
  }
1135
1135
  }
1136
1136
 
1137
- utils$1.inherit(SimpleButton, EventDispatcher);
1137
+ //utils.inherit(SimpleButton, EventDispatcher);
1138
+
1139
+ function SimpleButton(ref) {
1140
+ var _el = El(ref),
1141
+ _active = !_el.hasClass('disabled');
1142
+
1143
+ _el.active = function(a) {
1144
+ if (a === void 0) return _active;
1145
+ if (a !== _active) {
1146
+ _active = a;
1147
+ _el.toggleClass('disabled');
1148
+ }
1149
+ return _el;
1150
+ };
1151
+
1152
+ // this.node = function() {return _el.node();};
1153
+
1154
+ function isVisible() {
1155
+ var el = _el.node();
1156
+ return el.offsetParent !== null;
1157
+ }
1158
+ return _el;
1159
+ }
1160
+
1161
+ // utils.inherit(SimpleButton, EventDispatcher);
1138
1162
 
1139
1163
  // @cb function(<FileList>)
1140
1164
  function DropControl(gui, el, cb) {
@@ -1376,7 +1400,7 @@
1376
1400
  async function expandFiles(files) {
1377
1401
  var files2 = [], expanded;
1378
1402
  for (var f of files) {
1379
- if (internal.isZipFile(f.name)) {
1403
+ if (internal.isZipFile(f.name) || /\.kmz$/.test(f.name)) {
1380
1404
  expanded = await readZipFile(f);
1381
1405
  files2 = files2.concat(expanded);
1382
1406
  } else {
@@ -2861,8 +2885,9 @@
2861
2885
  prevArcs = active.dataset.arcs,
2862
2886
  prevTable = active.layer.data,
2863
2887
  prevTableSize = prevTable ? prevTable.size() : 0,
2864
- prevArcCount = prevArcs ? prevArcs.size() : 0;
2865
- internal.runParsedCommands(commands, model, function(err) {
2888
+ prevArcCount = prevArcs ? prevArcs.size() : 0,
2889
+ job = new internal.Job(model);
2890
+ internal.runParsedCommands(commands, job, function(err) {
2866
2891
  var flags = getCommandFlags(commands),
2867
2892
  active2 = model.getActiveLayer(),
2868
2893
  postArcs = active2.dataset.arcs,
@@ -2872,10 +2897,6 @@
2872
2897
  sameTable = prevTable == postTable && prevTableSize == postTableSize,
2873
2898
  sameArcs = prevArcs == postArcs && postArcCount == prevArcCount;
2874
2899
 
2875
- // restore default logging options, in case they were changed by the command
2876
- internal.setStateVar('QUIET', false);
2877
- internal.setStateVar('VERBOSE', false);
2878
-
2879
2900
  // kludge to signal map that filtered arcs need refreshing
2880
2901
  // TODO: find a better solution, outside the console
2881
2902
  if (!sameArcs) {
@@ -2922,7 +2943,7 @@
2922
2943
 
2923
2944
  function consoleMessage() {
2924
2945
  var msg = GUI.formatMessageArgs(arguments);
2925
- if (internal.loggingEnabled() && !internal.getStateVar('QUIET')) {
2946
+ if (internal.loggingEnabled()) {
2926
2947
  toLog(msg, 'console-message');
2927
2948
  }
2928
2949
  }
@@ -4396,51 +4417,28 @@
4396
4417
 
4397
4418
  var Buffer = require('buffer').Buffer; // works with browserify
4398
4419
 
4399
- var context = createContext(); // command context (persist for the current command cycle)
4400
-
4401
- function runningInBrowser() {
4402
- return typeof window !== 'undefined' && typeof window.document !== 'undefined';
4403
- }
4404
-
4405
- function getStateVar(key) {
4406
- return context[key];
4407
- }
4420
+ // This module provides a way for multiple jobs to run together asynchronously
4421
+ // while keeping job-level context variables (like "defs") separate.
4408
4422
 
4409
- function setStateVar(key, val) {
4410
- context[key] = val;
4411
- }
4423
+ var stash = {};
4412
4424
 
4413
- function createContext() {
4414
- return {
4415
- DEBUG: false,
4416
- QUIET: false,
4417
- VERBOSE: false,
4418
- defs: {},
4419
- input_files: []
4420
- };
4425
+ function stashVar(key, val) {
4426
+ if (key in stash) {
4427
+ error('Tried to replace a stashed variable:', key);
4428
+ }
4429
+ stash[key] = val;
4421
4430
  }
4422
4431
 
4423
- // Install a new set of context variables, clear them when an async callback is called.
4424
- // @cb callback function to wrap
4425
- // returns wrapped callback function
4426
- function createAsyncContext(cb) {
4427
- context = createContext();
4428
- return function() {
4429
- cb.apply(null, utils.toArray(arguments));
4430
- // clear context after cb(), so output/errors can be handled in current context
4431
- context = createContext();
4432
- };
4432
+ function getStashedVar(key) {
4433
+ if (key in stash === false) {
4434
+ return undefined; // to support running commands in tests
4435
+ // error('Tried to read a nonexistent variable from the stash:', key);
4436
+ }
4437
+ return stash[key];
4433
4438
  }
4434
4439
 
4435
- // Save the current context, restore it when an async callback is called
4436
- // @cb callback function to wrap
4437
- // returns wrapped callback function
4438
- function preserveContext(cb) {
4439
- var ctx = context;
4440
- return function() {
4441
- context = ctx;
4442
- cb.apply(null, utils.toArray(arguments));
4443
- };
4440
+ function clearStash() {
4441
+ stash = {};
4444
4442
  }
4445
4443
 
4446
4444
  var LOGGING = false;
@@ -4522,13 +4520,13 @@
4522
4520
 
4523
4521
  function verbose() {
4524
4522
  // verbose can be set globally with the -verbose command or separately for each command
4525
- if (getStateVar('VERBOSE') || getStateVar('verbose')) {
4523
+ if (getStashedVar('VERBOSE')) {
4526
4524
  message.apply(null, arguments);
4527
4525
  }
4528
4526
  }
4529
4527
 
4530
4528
  function debug() {
4531
- if (getStateVar('DEBUG') || getStateVar('debug')) {
4529
+ if (getStashedVar('DEBUG')) {
4532
4530
  logArgs(arguments);
4533
4531
  }
4534
4532
  }
@@ -4608,7 +4606,7 @@
4608
4606
 
4609
4607
  function messageArgs(args) {
4610
4608
  var arr = utils.toArray(args);
4611
- var cmd = getStateVar('current_command');
4609
+ var cmd = getStashedVar('current_command');
4612
4610
  if (cmd && cmd != 'help') {
4613
4611
  arr.unshift('[' + cmd + ']');
4614
4612
  }
@@ -4616,7 +4614,7 @@
4616
4614
  }
4617
4615
 
4618
4616
  function logArgs(args) {
4619
- if (!LOGGING || getStateVar('QUIET') || !utils.isArrayLike(args)) return;
4617
+ if (!LOGGING || getStashedVar('QUIET') || !utils.isArrayLike(args)) return;
4620
4618
  var msg = formatLogArgs(args);
4621
4619
  if (STDOUT) console.log(msg);
4622
4620
  else console.error(msg);
@@ -5994,13 +5992,13 @@
5994
5992
  var records = lyr.data.getRecords();
5995
5993
  var symbols = lyr.shapes.map(function(shp, i) {
5996
5994
  var d = records[i];
5997
- var obj = type == 'label' ? internal.svg.importStyledLabel(d) :
5998
- internal.svg.importSymbol(d['svg-symbol']);
5995
+ var obj = internal.svg.renderPoint(d);
5999
5996
  if (!obj || !shp) return null;
5997
+ obj.properties.class = 'mapshaper-svg-symbol';
6000
5998
  obj.properties.transform = getSvgSymbolTransform(shp[0], ext);
6001
5999
  obj.properties['data-id'] = i;
6002
6000
  return obj;
6003
- });
6001
+ }).filter(Boolean);
6004
6002
  var obj = internal.getEmptyLayerForSVG(lyr, {});
6005
6003
  obj.children = symbols;
6006
6004
  return internal.svg.stringify(obj);
@@ -7585,7 +7583,10 @@
7585
7583
  if (!active(e)) return;
7586
7584
  var textNode = getTextTarget3(e);
7587
7585
  var table = hit.getTargetDataTable();
7588
- if (!textNode || !table) return false;
7586
+ if (!textNode || !table) {
7587
+ activeId = -1;
7588
+ return false;
7589
+ }
7589
7590
  activeId = e.id;
7590
7591
  activeRecord = getLabelRecordById(activeId);
7591
7592
  downEvt = e;
@@ -7593,7 +7594,7 @@
7593
7594
  });
7594
7595
 
7595
7596
  hit.on('drag', function(e) {
7596
- if (!active(e)) return;
7597
+ if (!active(e) || activeId == -1) return;
7597
7598
  if (e.id != activeId) {
7598
7599
  error$1("Mismatched hit ids:", e.id, activeId);
7599
7600
  }
@@ -7613,7 +7614,7 @@
7613
7614
  });
7614
7615
 
7615
7616
  hit.on('dragend', function(e) {
7616
- if (!active(e)) return;
7617
+ if (!active(e) || activeId == -1) return;
7617
7618
  gui.dispatchEvent('label_dragend', {FID: e.id});
7618
7619
  activeId = -1;
7619
7620
  activeRecord = null;
@@ -7686,7 +7687,7 @@
7686
7687
 
7687
7688
  // update symbol by re-rendering it
7688
7689
  function updateSymbol2(node, d, id) {
7689
- var o = internal.svg.importStyledLabel(d); // TODO: symbol support
7690
+ var o = internal.svg.renderStyledLabel(d); // TODO: symbol support
7690
7691
  var activeLayer = hit.getHitTarget().layer;
7691
7692
  var xy = activeLayer.shapes[id][0];
7692
7693
  var g = document.createElementNS('http://www.w3.org/2000/svg', 'g');
@@ -8898,8 +8899,7 @@
8898
8899
  if (mapScale < 0.5) {
8899
8900
  s *= Math.pow(mapScale + 0.5, 0.35);
8900
8901
  } else if (mapScale > 100) {
8901
- if (!internal.getStateVar('DEBUG')) // thin lines for debugging
8902
- s *= Math.pow(mapScale - 99, 0.10);
8902
+ s *= Math.pow(mapScale - 99, 0.10);
8903
8903
  }
8904
8904
  return s;
8905
8905
  }
@@ -9238,12 +9238,14 @@
9238
9238
  function reposition(target, type, ext) {
9239
9239
  var container = el.findChild('.' + target.svg_id).node();
9240
9240
  var elements;
9241
- if (type == 'label' || type == 'symbol') {
9242
- elements = type == 'label' ? container.getElementsByTagName('text') :
9243
- El.findAll('.mapshaper-svg-symbol', container);
9241
+ if (type == 'symbol') {
9242
+ elements = El.findAll('.mapshaper-svg-symbol', container);
9244
9243
  repositionSymbols(elements, target.layer, ext);
9245
9244
  } else if (type == 'furniture') {
9246
9245
  repositionFurniture(container, target.layer, ext);
9246
+ } else {
9247
+ // container.getElementsByTagName('text')
9248
+ error('Unsupported symbol type:', type);
9247
9249
  }
9248
9250
  }
9249
9251
 
@@ -9273,14 +9275,15 @@
9273
9275
  _svg.clear();
9274
9276
  }
9275
9277
  layers.forEach(function(lyr) {
9276
- var svgType = getSvgLayerType(lyr.layer);
9277
- if (!svgType || svgType == 'label') { // svg labels may have canvas dots
9278
+ var isSvgLayer = internal.layerHasSvgSymbols(lyr.layer) || internal.layerHasLabels(lyr.layer);
9279
+ //if (!svgType || svgType == 'label') { // svg labels may have canvas dots
9280
+ if (!isSvgLayer) { // svg labels may have canvas dots
9278
9281
  drawCanvasLayer(lyr, _mainCanv);
9279
9282
  }
9280
- if (svgType && action == 'nav') {
9281
- _svg.reposition(lyr, svgType);
9282
- } else if (svgType) {
9283
- _svg.drawLayer(lyr, svgType);
9283
+ if (isSvgLayer && action == 'nav') {
9284
+ _svg.reposition(lyr, 'symbol');
9285
+ } else if (isSvgLayer) {
9286
+ _svg.drawLayer(lyr, 'symbol');
9284
9287
  }
9285
9288
  });
9286
9289
  };
@@ -9332,9 +9335,9 @@
9332
9335
 
9333
9336
  function getSvgLayerType(layer) {
9334
9337
  var type = null;
9335
- if (internal.layerHasLabels(layer)) {
9336
- type = 'label';
9337
- } else if (internal.layerHasSvgSymbols(layer)) {
9338
+ if (internal.layerHasSvgSymbols(layer)) {
9339
+ type = 'symbol'; // also label + symbol
9340
+ } else if (internal.layerHasLabels(layer)) {
9338
9341
  type = 'symbol';
9339
9342
  }
9340
9343
  return type;
@@ -9753,6 +9756,10 @@
9753
9756
 
9754
9757
  function Basemap(gui, ext) {
9755
9758
  var menu = gui.container.findChild('.basemap-options');
9759
+ // var hideBtn = new SimpleButton(menu.findChild('.hide-btn'));
9760
+ var fadeBtn = new SimpleButton(menu.findChild('.fade-btn'));
9761
+ var closeBtn = new SimpleButton(menu.findChild('.close-btn'));
9762
+ var clearBtn = new SimpleButton(menu.findChild('.clear-btn'));
9756
9763
  var list = menu.findChild('.basemap-styles');
9757
9764
  var container = gui.container.findChild('.basemap-container');
9758
9765
  var basemapBtn = gui.container.findChild('.basemap-btn');
@@ -9764,6 +9771,7 @@
9764
9771
  var map;
9765
9772
  var activeStyle;
9766
9773
  var loading = false;
9774
+ var faded = false;
9767
9775
 
9768
9776
  if (params) {
9769
9777
  init();
@@ -9774,11 +9782,35 @@
9774
9782
  function init() {
9775
9783
  gui.addMode('basemap', turnOn, turnOff, basemapBtn);
9776
9784
 
9777
- new SimpleButton(menu.findChild('.close-btn')).on('click', function() {
9785
+ closeBtn.on('click', function() {
9778
9786
  gui.clearMode();
9779
9787
  turnOff();
9780
9788
  });
9781
9789
 
9790
+ // hideBtn.on('mousedown', function() {
9791
+ // if (activeStyle) {
9792
+ // mapEl.css('visibility', 'hidden');
9793
+ // hidden = true;
9794
+ // }
9795
+ // })
9796
+ clearBtn.on('click', function() {
9797
+ if (activeStyle) {
9798
+ updateStyle(null);
9799
+ updateButtons();
9800
+ }
9801
+ });
9802
+ fadeBtn.on('click', function() {
9803
+ if (faded) {
9804
+ mapEl.css('opacity', 1);
9805
+ faded = false;
9806
+ fadeBtn.text('Fade');
9807
+ } else if (activeStyle) {
9808
+ mapEl.css('opacity', 0.35);
9809
+ faded = true;
9810
+ fadeBtn.text('Unfade');
9811
+ }
9812
+ });
9813
+
9782
9814
  gui.on('map_click', function() {
9783
9815
  // close menu if user click on the map
9784
9816
  if (gui.getMode() == 'basemap') gui.clearMode();
@@ -9801,13 +9833,14 @@
9801
9833
  // gui.state.dark_basemap = style && style.dark || false;
9802
9834
  if (!style) {
9803
9835
  gui.map.setDisplayCRS(null);
9804
- hide();
9836
+ refresh();
9805
9837
  } else if (map) {
9806
9838
  map.setStyle(style.url);
9807
9839
  refresh();
9808
9840
  } else {
9809
9841
  initMap();
9810
9842
  }
9843
+
9811
9844
  }
9812
9845
 
9813
9846
  function updateButtons() {
@@ -9917,12 +9950,15 @@
9917
9950
  }
9918
9951
 
9919
9952
  function refresh() {
9920
- if (!enabled() || !map || loading || !activeStyle) return;
9921
9953
  var crs = gui.map.getDisplayCRS();
9922
- if (!crsIsUsable(crs)) {
9954
+ var off = !crs || !enabled() || !map || loading || !activeStyle;
9955
+ fadeBtn.active(!off);
9956
+ clearBtn.active(!off);
9957
+ if (off) {
9923
9958
  hide();
9924
9959
  return;
9925
9960
  }
9961
+
9926
9962
  if (!internal.isWebMercator(crs)) {
9927
9963
  gui.map.setDisplayCRS(internal.getCRS('webmercator'));
9928
9964
  }