mapshaper 0.6.66 → 0.6.67

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
@@ -13397,10 +13397,11 @@
13397
13397
 
13398
13398
  // str: display size in px, pt or in
13399
13399
  // using: 72pt per inch, 1pt per pixel.
13400
- function parseSizeParam(str) {
13401
- var num = parseFloat(str),
13402
- units = /px$/.test(str) && 'px' || /pt$/.test(str) && 'pt' ||
13403
- /in$/.test(str) && 'in' || !isNaN(+str) && 'px' || null;
13400
+ function parseSizeParam(p) {
13401
+ var str = String(p),
13402
+ num = parseFloat(str),
13403
+ units = /px|pix/.test(str) && 'px' || /pt|point/.test(str) && 'pt' ||
13404
+ /in/.test(str) && 'in' || !isNaN(+str) && 'px' || null;
13404
13405
  if (isNaN(num) || !units) {
13405
13406
  stop('Invalid size:', str);
13406
13407
  }
@@ -18228,7 +18229,7 @@
18228
18229
  var frameLyr = findFrameLayerInDataset(dataset);
18229
18230
  var frameData;
18230
18231
  if (frameLyr) {
18231
- frameData = getFrameLayerData(frameLyr, dataset);
18232
+ frameData = getFrameLayerData(frameLyr, dataset.arcs);
18232
18233
  } else {
18233
18234
  frameData = calcFrameData(dataset, exportOpts);
18234
18235
  }
@@ -18237,8 +18238,8 @@
18237
18238
  }
18238
18239
 
18239
18240
 
18240
- function getFrameLayerData(lyr, dataset) {
18241
- var bounds = getLayerBounds(lyr, dataset.arcs);
18241
+ function getFrameLayerData(lyr, arcs) {
18242
+ var bounds = getLayerBounds(lyr, arcs);
18242
18243
  var d = lyr.data.getReadOnlyRecordAt(0);
18243
18244
  var w = d.width || 800;
18244
18245
  var h = w * bounds.height() / bounds.width();
@@ -18250,10 +18251,6 @@
18250
18251
  };
18251
18252
  }
18252
18253
 
18253
- // export function getFrameLayerData(lyr) {
18254
- // return lyr.data && lyr.data.getReadOnlyRecordAt(0);
18255
- // }
18256
-
18257
18254
 
18258
18255
  function calcFrameData(dataset, opts) {
18259
18256
  var bounds;
@@ -18287,31 +18284,34 @@
18287
18284
 
18288
18285
 
18289
18286
  // @lyr dataset layer
18290
- function isFrameLayer(lyr, dataset) {
18287
+ function isFrameLayer(lyr, arcs) {
18291
18288
  return getFurnitureLayerType(lyr) == 'frame' &&
18292
- layerIsRectangle(lyr, dataset.arcs);
18289
+ layerIsRectangle(lyr, arcs);
18293
18290
  }
18294
18291
 
18295
18292
  function findFrameLayerInDataset(dataset) {
18296
18293
  return utils.find(dataset.layers, function(lyr) {
18297
- return isFrameLayer(lyr, dataset);
18294
+ return isFrameLayer(lyr, dataset.arcs);
18298
18295
  });
18299
18296
  }
18300
18297
 
18298
+ // TODO: handle multiple frames in catalog
18301
18299
  function findFrameDataset(catalog) {
18302
- var target = utils.find(catalog.getLayers(), function(o) {
18303
- return isFrameLayer(o.layer, o.dataset);
18304
- });
18305
- return target ? target.dataset : null;
18300
+ var target = findFrame(catalog);
18301
+ return target && target.dataset || null;
18306
18302
  }
18307
18303
 
18308
18304
  function findFrameLayer(catalog) {
18309
- var target = utils.find(catalog.getLayers(), function(o) {
18310
- return isFrameLayer(o.layer, o.dataset);
18311
- });
18305
+ var target = findFrame(catalog);
18312
18306
  return target && target.layer || null;
18313
18307
  }
18314
18308
 
18309
+ function findFrame(catalog) {
18310
+ return utils.find(catalog.getLayers(), function(o) {
18311
+ return isFrameLayer(o.layer, o.dataset.arcs);
18312
+ });
18313
+ }
18314
+
18315
18315
  function getFrameLayerBounds(lyr) {
18316
18316
  return new Bounds(getFurnitureLayerData(lyr).bbox);
18317
18317
  }
@@ -18445,10 +18445,13 @@
18445
18445
  var FrameData = /*#__PURE__*/Object.freeze({
18446
18446
  __proto__: null,
18447
18447
  getFrameData: getFrameData,
18448
+ getFrameLayerData: getFrameLayerData,
18448
18449
  getFrameSize: getFrameSize,
18450
+ isFrameLayer: isFrameLayer,
18449
18451
  findFrameLayerInDataset: findFrameLayerInDataset,
18450
18452
  findFrameDataset: findFrameDataset,
18451
18453
  findFrameLayer: findFrameLayer,
18454
+ findFrame: findFrame,
18452
18455
  getFrameLayerBounds: getFrameLayerBounds,
18453
18456
  getMapFrameMetersPerPixel: getMapFrameMetersPerPixel,
18454
18457
  calcOutputSizeInPixels: calcOutputSizeInPixels,
@@ -18888,6 +18891,7 @@
18888
18891
  'font-family': null,
18889
18892
  'font-size': null,
18890
18893
  'font-style': null,
18894
+ 'font-stretch': null,
18891
18895
  'font-weight': null,
18892
18896
  'label-text': null, // leaving this null
18893
18897
  'letter-spacing': 'measure',
@@ -18937,7 +18941,7 @@
18937
18941
  polyline: utils.arrayToIndex(commonProperties.concat('stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit')),
18938
18942
  point: utils.arrayToIndex(commonProperties.concat('fill', 'r')),
18939
18943
  label: utils.arrayToIndex(commonProperties.concat(
18940
- 'fill,font-family,font-size,text-anchor,font-weight,font-style,letter-spacing,dominant-baseline'.split(',')))
18944
+ 'fill,font-family,font-size,text-anchor,font-weight,font-style,font-stretch,letter-spacing,dominant-baseline'.split(',')))
18941
18945
  };
18942
18946
 
18943
18947
  // symType: point, polygon, polyline, label
@@ -19725,84 +19729,9 @@
19725
19729
  parseScalebarLabelToKm: parseScalebarLabelToKm
19726
19730
  });
19727
19731
 
19728
- cmd.frame = function(catalog, source, opts) {
19729
- var size, bounds, tmp, dataset;
19730
- if (+opts.width > 0 === false && +opts.pixels > 0 === false) {
19731
- stop("Missing a width or area");
19732
- }
19733
- if (opts.width && opts.height) {
19734
- opts = utils.extend({}, opts);
19735
- // Height is a string containing either a number or a
19736
- // comma-sep. pair of numbers (range); here we convert height to
19737
- // an aspect-ratio parameter for the rectangle() function
19738
- opts.aspect_ratio = getAspectRatioArg(opts.width, opts.height);
19739
- // TODO: currently returns max,min aspect ratio, should return in min,max order
19740
- // (rectangle() function should handle max,min argument correctly now anyway)
19741
- }
19742
- tmp = cmd.rectangle(source, opts);
19743
- bounds = getDatasetBounds(tmp);
19744
- if (probablyDecimalDegreeBounds(bounds)) {
19745
- stop('Frames require projected, not geographical coordinates');
19746
- } else if (!getDatasetCRS(tmp)) {
19747
- message('Warning: missing projection data. Assuming coordinates are meters and k (scale factor) is 1');
19748
- }
19749
- size = getFrameSize(bounds, opts);
19750
- if (size[0] > 0 === false) {
19751
- stop('Missing a valid frame width');
19752
- }
19753
- if (size[1] > 0 === false) {
19754
- stop('Missing a valid frame height');
19755
- }
19756
- dataset = {info: {}, layers:[{
19757
- name: opts.name || 'frame',
19758
- data: new DataTable([{
19759
- width: size[0],
19760
- height: size[1],
19761
- bbox: bounds.toArray(),
19762
- type: 'frame'
19763
- }])
19764
- }]};
19765
- catalog.addDataset(dataset);
19766
- };
19767
-
19768
-
19769
- // Convert width and height args to aspect ratio arg for the rectangle() function
19770
- function getAspectRatioArg(widthArg, heightArg) {
19771
- // heightArg is a string containing either a number or a
19772
- // comma-sep. pair of numbers (range);
19773
- return heightArg.split(',').map(function(opt) {
19774
- var height = Number(opt),
19775
- width = Number(widthArg);
19776
- if (!opt) return '';
19777
- return width / height;
19778
- }).reverse().join(',');
19779
- }
19780
-
19781
-
19782
- function renderFrame(d) {
19783
- var lineWidth = 1,
19784
- // inset stroke by half of line width
19785
- off = lineWidth / 2,
19786
- obj = importPolygon([[[off, off], [off, d.height - off],
19787
- [d.width - off, d.height - off],
19788
- [d.width - off, off], [off, off]]]);
19789
- utils.extend(obj.properties, {
19790
- fill: 'none',
19791
- stroke: d.stroke || 'black',
19792
- 'stroke-width': d['stroke-width'] || lineWidth
19793
- });
19794
- return [obj];
19795
- }
19796
-
19797
- var Frame = /*#__PURE__*/Object.freeze({
19798
- __proto__: null,
19799
- getAspectRatioArg: getAspectRatioArg,
19800
- renderFrame: renderFrame
19801
- });
19802
-
19803
19732
  var furnitureRenderers = {
19804
- scalebar: renderScalebar,
19805
- frame: renderFrame
19733
+ scalebar: renderScalebar
19734
+ // frame: renderFrame
19806
19735
  };
19807
19736
 
19808
19737
  // @lyr a layer in a dataset
@@ -25185,15 +25114,15 @@ ${svg}
25185
25114
  .validate(validateProjOpts);
25186
25115
 
25187
25116
  parser.command('rectangle')
25188
- .describe('create a rectangle from a bbox or target layer extent')
25117
+ .describe('create a rectangle from a bbox or target layer')
25189
25118
  .option('bbox', {
25190
25119
  describe: 'rectangle coordinates (xmin,ymin,xmax,ymax)',
25191
25120
  type: 'bbox'
25192
25121
  })
25193
25122
  .option('offset', offsetOpt)
25194
25123
  .option('width', {
25195
- // describe: 'set viewport width in pixels',
25196
- type: 'number'
25124
+ describe: 'set width of map in pixels, use rectangle as frame'
25125
+ // type: 'number' // use string, to allow units (e.g. in, px, pt)
25197
25126
  })
25198
25127
  .option('aspect-ratio', aspectRatioOpt)
25199
25128
  .option('source', {
@@ -25470,7 +25399,10 @@ ${svg}
25470
25399
  .option('font-style', {
25471
25400
  describe: 'CSS font style property of labels (e.g. italic)'
25472
25401
  })
25473
- .option('letter-spacing', {
25402
+ .option('font-stretch', {
25403
+ describe: 'CSS font stretch property of labels (e.g. condensed)'
25404
+ })
25405
+ .option('letter-spacing', {
25474
25406
  describe: 'CSS letter-spacing property of labels'
25475
25407
  })
25476
25408
  .option('line-height', {
@@ -25762,20 +25694,20 @@ ${svg}
25762
25694
  describe: 'frame coordinates (xmin,ymin,xmax,ymax)',
25763
25695
  type: 'bbox'
25764
25696
  })
25765
- .option('offset', offsetOpt)
25697
+ // .option('offset', offsetOpt)
25766
25698
  .option('width', {
25767
- describe: 'pixel width of output (default is 800)'
25768
- })
25769
- .option('height', {
25770
- describe: 'pixel height of output (may be a range)'
25771
- })
25772
- .option('pixels', {
25773
- describe: 'area of output in pixels (alternative to width and height)',
25774
- type: 'number'
25775
- })
25776
- .option('source', {
25777
- describe: 'name of layer to enclose'
25699
+ describe: 'width of output (default is 800px)'
25778
25700
  })
25701
+ // .option('height', {
25702
+ // describe: 'pixel height of output (may be a range)'
25703
+ // })
25704
+ // .option('pixels', {
25705
+ // describe: 'area of output in pixels (alternative to width and height)',
25706
+ // type: 'number'
25707
+ // })
25708
+ // .option('source', {
25709
+ // describe: 'name of layer to enclose'
25710
+ // })
25779
25711
  .option('name', nameOpt);
25780
25712
 
25781
25713
  parser.command('fuzzy-join')
@@ -37774,6 +37706,79 @@ ${svg}
37774
37706
  return parsed[0];
37775
37707
  }
37776
37708
 
37709
+ cmd.frame = function(catalog, source, opts) {
37710
+ var size, bounds, tmp, dataset;
37711
+ if (+opts.width > 0 === false && +opts.pixels > 0 === false) {
37712
+ stop("Missing a width or area");
37713
+ }
37714
+ if (opts.width && opts.height) {
37715
+ opts = utils.extend({}, opts);
37716
+ // Height is a string containing either a number or a
37717
+ // comma-sep. pair of numbers (range); here we convert height to
37718
+ // an aspect-ratio parameter for the rectangle() function
37719
+ opts.aspect_ratio = getAspectRatioArg(opts.width, opts.height);
37720
+ // TODO: currently returns max,min aspect ratio, should return in min,max order
37721
+ // (rectangle() function should handle max,min argument correctly now anyway)
37722
+ }
37723
+ tmp = cmd.rectangle(source, opts);
37724
+ bounds = getDatasetBounds(tmp);
37725
+ if (probablyDecimalDegreeBounds(bounds)) {
37726
+ stop('Frames require projected, not geographical coordinates');
37727
+ } else if (!getDatasetCRS(tmp)) {
37728
+ message('Warning: missing projection data. Assuming coordinates are meters and k (scale factor) is 1');
37729
+ }
37730
+ size = getFrameSize(bounds, opts);
37731
+ if (size[0] > 0 === false) {
37732
+ stop('Missing a valid frame width');
37733
+ }
37734
+ if (size[1] > 0 === false) {
37735
+ stop('Missing a valid frame height');
37736
+ }
37737
+ dataset = {info: {}, layers:[{
37738
+ name: opts.name || 'frame',
37739
+ data: new DataTable([{
37740
+ width: size[0],
37741
+ height: size[1],
37742
+ bbox: bounds.toArray(),
37743
+ type: 'frame'
37744
+ }])
37745
+ }]};
37746
+ catalog.addDataset(dataset);
37747
+ };
37748
+
37749
+
37750
+ // Convert width and height args to aspect ratio arg for the rectangle() function
37751
+ function getAspectRatioArg(widthArg, heightArg) {
37752
+ // heightArg is a string containing either a number or a
37753
+ // comma-sep. pair of numbers (range);
37754
+ return heightArg.split(',').map(function(opt) {
37755
+ var height = Number(opt),
37756
+ width = Number(widthArg);
37757
+ if (!opt) return '';
37758
+ return width / height;
37759
+ }).reverse().join(',');
37760
+ }
37761
+
37762
+ // export function renderFrame(d) {
37763
+ // var lineWidth = 1,
37764
+ // // inset stroke by half of line width
37765
+ // off = lineWidth / 2,
37766
+ // obj = importPolygon([[[off, off], [off, d.height - off],
37767
+ // [d.width - off, d.height - off],
37768
+ // [d.width - off, off], [off, off]]]);
37769
+ // utils.extend(obj.properties, {
37770
+ // fill: 'none',
37771
+ // stroke: d.stroke || 'black',
37772
+ // 'stroke-width': d['stroke-width'] || lineWidth
37773
+ // });
37774
+ // return [obj];
37775
+ // }
37776
+
37777
+ var Frame = /*#__PURE__*/Object.freeze({
37778
+ __proto__: null,
37779
+ getAspectRatioArg: getAspectRatioArg
37780
+ });
37781
+
37777
37782
  cmd.filterIslands = function(lyr, dataset, optsArg) {
37778
37783
  var opts = utils.extend({sliver_control: 0}, optsArg); // no sliver control
37779
37784
  var arcs = dataset.arcs;
@@ -38540,6 +38545,13 @@ ${svg}
38540
38545
  // Create rectangles around one or more target layers
38541
38546
  //
38542
38547
  cmd.rectangle2 = function(target, opts) {
38548
+ // if target layer is a rectangle and we're applying frame properties,
38549
+ // turn the target into a frame instead of creating a new rectangle
38550
+ if (target.layers.length == 1 && opts.width &&
38551
+ layerIsRectangle(target.layers[0], target.dataset.arcs)) {
38552
+ applyFrameProperties(target.layers[0], opts);
38553
+ return;
38554
+ }
38543
38555
  var datasets = target.layers.map(function(lyr) {
38544
38556
  var dataset = cmd.rectangle({layer: lyr, dataset: target.dataset}, opts);
38545
38557
  setOutputLayerName(dataset.layers[0], lyr, null, opts);
@@ -38569,16 +38581,21 @@ ${svg}
38569
38581
  properties: {},
38570
38582
  geometry: bboxToPolygon(bounds.toArray(), opts)
38571
38583
  };
38572
- if (opts.width > 0) {
38573
- feature.properties.width = opts.width;
38574
- feature.properties.type = 'frame';
38575
- }
38576
38584
  var dataset = importGeoJSON(feature, {});
38585
+ applyFrameProperties(dataset.layers[0], opts);
38577
38586
  dataset.layers[0].name = opts.name || 'rectangle';
38578
38587
  setDatasetCrsInfo(dataset, crsInfo);
38579
38588
  return dataset;
38580
38589
  };
38581
38590
 
38591
+ function applyFrameProperties(lyr, opts) {
38592
+ if (!opts.width) return;
38593
+ if (!lyr.data) initDataTable(lyr);
38594
+ var d = lyr.data.getRecords()[0] || {};
38595
+ d.width = parseSizeParam(opts.width);
38596
+ d.type = 'frame';
38597
+ }
38598
+
38582
38599
  function applyRectangleOptions(bounds, crs, opts) {
38583
38600
  var isGeoBox = probablyDecimalDegreeBounds(bounds);
38584
38601
  if (opts.offset) {
@@ -45207,7 +45224,7 @@ ${svg}
45207
45224
  });
45208
45225
  }
45209
45226
 
45210
- var version = "0.6.66";
45227
+ var version = "0.6.67";
45211
45228
 
45212
45229
  // Parse command line args into commands and run them
45213
45230
  // 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.66",
3
+ "version": "0.6.67",
4
4
  "description": "A tool for editing vector datasets for mapping and GIS.",
5
5
  "keywords": [
6
6
  "shapefile",