mapshaper 0.6.100 → 0.6.102
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 +122 -94
- package/package.json +2 -2
- package/www/mapshaper-gui.js +5 -4
- package/www/mapshaper.js +122 -94
- package/www/modules.js +60 -0
package/mapshaper.js
CHANGED
|
@@ -267,6 +267,7 @@
|
|
|
267
267
|
});
|
|
268
268
|
}
|
|
269
269
|
|
|
270
|
+
|
|
270
271
|
function defaults(dest) {
|
|
271
272
|
for (var i=1, n=arguments.length; i<n; i++) {
|
|
272
273
|
var src = arguments[i] || {};
|
|
@@ -13762,7 +13763,7 @@
|
|
|
13762
13763
|
convertIntervalParam(opt[1], crs)];
|
|
13763
13764
|
}
|
|
13764
13765
|
|
|
13765
|
-
// Accepts a single value or a list of four values. List order is l,b,t
|
|
13766
|
+
// Accepts a single value or a list of four values. List order is l,b,r,t
|
|
13766
13767
|
function convertFourSides(opt, crs, bounds) {
|
|
13767
13768
|
var arr = opt.includes(',') ? opt.split(',') : opt.split(' ');
|
|
13768
13769
|
if (arr.length == 1) {
|
|
@@ -13776,7 +13777,7 @@
|
|
|
13776
13777
|
tmp = parseFloat(param) / 100 || 0;
|
|
13777
13778
|
return tmp * (i == 1 || i == 3 ? bounds.height() : bounds.width());
|
|
13778
13779
|
}
|
|
13779
|
-
return convertIntervalParam(
|
|
13780
|
+
return convertIntervalParam(param, crs);
|
|
13780
13781
|
});
|
|
13781
13782
|
}
|
|
13782
13783
|
|
|
@@ -18486,18 +18487,30 @@
|
|
|
18486
18487
|
type: 'frame'
|
|
18487
18488
|
}
|
|
18488
18489
|
*/
|
|
18490
|
+
|
|
18491
|
+
|
|
18489
18492
|
function getFrameData(dataset, exportOpts) {
|
|
18490
18493
|
var frameLyr = findFrameLayerInDataset(dataset);
|
|
18491
|
-
var
|
|
18494
|
+
var data;
|
|
18492
18495
|
if (frameLyr) {
|
|
18493
|
-
|
|
18496
|
+
data = getFrameLayerData(frameLyr, dataset.arcs);
|
|
18494
18497
|
} else {
|
|
18495
|
-
|
|
18498
|
+
data = calcFrameData(dataset, exportOpts);
|
|
18496
18499
|
}
|
|
18497
|
-
|
|
18498
|
-
|
|
18500
|
+
data.invert_y = !!exportOpts.invert_y;
|
|
18501
|
+
data.crs = getDatasetCRS(dataset);
|
|
18502
|
+
return data;
|
|
18499
18503
|
}
|
|
18500
18504
|
|
|
18505
|
+
function fitDatasetToFrame(dataset, frame) {
|
|
18506
|
+
var bounds = new Bounds(frame.bbox);
|
|
18507
|
+
var bounds2 = frame.bbox2 ? new Bounds(frame.bbox2) : new Bounds(0, 0, frame.width, frame.height);
|
|
18508
|
+
bounds.fillOut(bounds2.width() / bounds2.height());
|
|
18509
|
+
var fwd = bounds.getTransform(bounds2, frame.invert_y);
|
|
18510
|
+
transformPoints(dataset, function(x, y) {
|
|
18511
|
+
return fwd.transform(x, y);
|
|
18512
|
+
});
|
|
18513
|
+
}
|
|
18501
18514
|
|
|
18502
18515
|
function getFrameLayerData(lyr, arcs) {
|
|
18503
18516
|
var bounds = getLayerBounds(lyr, arcs);
|
|
@@ -18515,24 +18528,25 @@
|
|
|
18515
18528
|
|
|
18516
18529
|
|
|
18517
18530
|
function calcFrameData(dataset, opts) {
|
|
18518
|
-
var
|
|
18531
|
+
var inputBounds, outputBounds;
|
|
18519
18532
|
if (opts.svg_bbox) {
|
|
18520
|
-
|
|
18533
|
+
inputBounds = new Bounds(opts.svg_bbox);
|
|
18521
18534
|
opts = Object.assign({margin: 0}, opts); // prevent default pixel margin around content
|
|
18522
18535
|
} else {
|
|
18523
|
-
|
|
18536
|
+
inputBounds = getDatasetBounds(dataset);
|
|
18524
18537
|
}
|
|
18525
|
-
|
|
18538
|
+
// side effect: inputBounds may be expanded to add margins
|
|
18539
|
+
outputBounds = calcOutputBounds(inputBounds, opts);
|
|
18526
18540
|
return {
|
|
18527
|
-
bbox:
|
|
18528
|
-
bbox2:
|
|
18529
|
-
width: Math.round(
|
|
18530
|
-
height: Math.round(
|
|
18541
|
+
bbox: inputBounds.toArray(),
|
|
18542
|
+
bbox2: outputBounds.toArray(),
|
|
18543
|
+
width: Math.round(outputBounds.width()),
|
|
18544
|
+
height: Math.round(outputBounds.height()) || 1,
|
|
18531
18545
|
type: 'frame'
|
|
18532
18546
|
};
|
|
18533
18547
|
}
|
|
18534
18548
|
|
|
18535
|
-
// Used by mapshaper-frame
|
|
18549
|
+
// Used by mapshaper-frame TODO: refactor
|
|
18536
18550
|
function getFrameSize(bounds, opts) {
|
|
18537
18551
|
var aspectRatio = bounds.width() / bounds.height();
|
|
18538
18552
|
var height, width;
|
|
@@ -18601,9 +18615,9 @@
|
|
|
18601
18615
|
|
|
18602
18616
|
|
|
18603
18617
|
// bounds: Bounds object containing bounds of content in geographic coordinates
|
|
18604
|
-
// returns Bounds object containing bounds
|
|
18618
|
+
// returns Bounds object containing output bounds
|
|
18605
18619
|
// side effect: bounds param is modified to match the output frame
|
|
18606
|
-
function
|
|
18620
|
+
function calcOutputBounds(bounds, opts) {
|
|
18607
18621
|
var padX = 0,
|
|
18608
18622
|
padY = 0,
|
|
18609
18623
|
offX = 0,
|
|
@@ -18616,65 +18630,59 @@
|
|
|
18616
18630
|
// TODO: add option to tweak alignment of content when both width and height are given
|
|
18617
18631
|
wx = 0.5, // how padding is distributed horizontally (0: left aligned, 0.5: centered, 1: right aligned)
|
|
18618
18632
|
wy = 0.5, // vertical padding distribution
|
|
18619
|
-
|
|
18633
|
+
width2, height2, size2, kx, ky;
|
|
18620
18634
|
|
|
18621
18635
|
if (opts.fit_bbox) {
|
|
18622
18636
|
// scale + shift content to fit within a bbox
|
|
18623
18637
|
offX = opts.fit_bbox[0];
|
|
18624
18638
|
offY = opts.fit_bbox[1];
|
|
18625
|
-
|
|
18626
|
-
|
|
18627
|
-
if (width / height > widthPx / heightPx) {
|
|
18628
|
-
// data is wider than fit box...
|
|
18629
|
-
// scale the data to fit widthwise
|
|
18630
|
-
heightPx = 0;
|
|
18631
|
-
} else {
|
|
18632
|
-
widthPx = 0; // fit the data to the height
|
|
18633
|
-
}
|
|
18639
|
+
width2 = opts.fit_bbox[2] - offX;
|
|
18640
|
+
height2 = opts.fit_bbox[3] - offY;
|
|
18634
18641
|
marginX = marginY = 0; // TODO: support margins
|
|
18635
18642
|
|
|
18636
18643
|
} else if (opts.svg_scale > 0) {
|
|
18637
18644
|
// alternative to using a fixed width (e.g. when generating multiple files
|
|
18638
18645
|
// at a consistent geographic scale)
|
|
18639
|
-
|
|
18640
|
-
|
|
18646
|
+
width2 = width / opts.svg_scale + marginX;
|
|
18647
|
+
height2 = 0;
|
|
18641
18648
|
} else if (+opts.pixels) {
|
|
18642
|
-
|
|
18643
|
-
|
|
18644
|
-
|
|
18649
|
+
size2 = getFrameSize(bounds, opts);
|
|
18650
|
+
width2 = size2[0];
|
|
18651
|
+
height2 = size2[1];
|
|
18645
18652
|
} else {
|
|
18646
|
-
|
|
18647
|
-
|
|
18653
|
+
height2 = opts.height || 0;
|
|
18654
|
+
width2 = opts.width || (height2 > 0 ? 0 : 800); // 800 is default width
|
|
18648
18655
|
}
|
|
18649
18656
|
|
|
18650
|
-
if (
|
|
18657
|
+
if (height2 > 0) {
|
|
18651
18658
|
// vertical meters per pixel to fit height param
|
|
18652
|
-
ky = (height || width || 1) / (
|
|
18659
|
+
ky = (height || width || 1) / (height2 - marginY);
|
|
18653
18660
|
}
|
|
18654
|
-
if (
|
|
18661
|
+
if (width2 > 0) {
|
|
18655
18662
|
// horizontal meters per pixel to fit width param
|
|
18656
|
-
kx = (width || height || 1) / (
|
|
18663
|
+
kx = (width || height || 1) / (width2 - marginX);
|
|
18657
18664
|
}
|
|
18658
18665
|
|
|
18659
|
-
if (!
|
|
18666
|
+
if (!width2) { // height2 and ky are defined, set width to match
|
|
18660
18667
|
kx = ky;
|
|
18661
|
-
|
|
18662
|
-
} else if (!
|
|
18668
|
+
width2 = width > 0 ? marginX + width / kx : height2; // export square graphic if content has 0 width (reconsider this?)
|
|
18669
|
+
} else if (!height2) { // width2 and kx are set, set height to match
|
|
18663
18670
|
ky = kx;
|
|
18664
|
-
|
|
18671
|
+
height2 = height > 0 ? marginY + height / ky : width2;
|
|
18665
18672
|
// limit height if max_height is defined
|
|
18666
|
-
if (opts.max_height > 0 &&
|
|
18667
|
-
ky = kx *
|
|
18668
|
-
|
|
18673
|
+
if (opts.max_height > 0 && height2 > opts.max_height) {
|
|
18674
|
+
ky = kx * height2 / opts.max_height;
|
|
18675
|
+
height2 = opts.max_height;
|
|
18669
18676
|
}
|
|
18670
18677
|
}
|
|
18671
18678
|
|
|
18679
|
+
// add padding, if needed
|
|
18672
18680
|
if (kx > ky) { // content is wide -- need to pad vertically
|
|
18673
18681
|
ky = kx;
|
|
18674
|
-
padY = ky * (
|
|
18682
|
+
padY = ky * (height2 - marginY) - height;
|
|
18675
18683
|
} else if (ky > kx) { // content is tall -- need to pad horizontally
|
|
18676
18684
|
kx = ky;
|
|
18677
|
-
padX = kx * (
|
|
18685
|
+
padX = kx * (width2 - marginX) - width;
|
|
18678
18686
|
}
|
|
18679
18687
|
|
|
18680
18688
|
bounds.padBounds(
|
|
@@ -18683,14 +18691,14 @@
|
|
|
18683
18691
|
margins[2] * kx + padX * (1 - wx),
|
|
18684
18692
|
margins[3] * ky + padY * (1 - wy));
|
|
18685
18693
|
|
|
18686
|
-
if (!(
|
|
18694
|
+
if (!(width2 > 0 && height2 > 0)) {
|
|
18687
18695
|
error("Missing valid height and width parameters");
|
|
18688
18696
|
}
|
|
18689
18697
|
if (!(kx === ky && kx > 0)) {
|
|
18690
18698
|
error("Missing valid margin parameters");
|
|
18691
18699
|
}
|
|
18692
18700
|
|
|
18693
|
-
return new Bounds(offX, offY,
|
|
18701
|
+
return new Bounds(offX, offY, width2 + offX, height2 + offY);
|
|
18694
18702
|
}
|
|
18695
18703
|
|
|
18696
18704
|
function parseMarginOption(opt) {
|
|
@@ -18701,14 +18709,16 @@
|
|
|
18701
18709
|
if (margins.length == 3) margins.push(margins[2]);
|
|
18702
18710
|
return margins.map(function(str) {
|
|
18703
18711
|
var px = parseFloat(str);
|
|
18704
|
-
return isNaN(px) ?
|
|
18712
|
+
return isNaN(px) ? 0 : px; // 0 is default
|
|
18705
18713
|
});
|
|
18706
18714
|
}
|
|
18707
18715
|
|
|
18708
|
-
var
|
|
18716
|
+
var FrameUtils = /*#__PURE__*/Object.freeze({
|
|
18709
18717
|
__proto__: null,
|
|
18710
18718
|
getFrameData: getFrameData,
|
|
18719
|
+
fitDatasetToFrame: fitDatasetToFrame,
|
|
18711
18720
|
getFrameLayerData: getFrameLayerData,
|
|
18721
|
+
calcFrameData: calcFrameData,
|
|
18712
18722
|
getFrameSize: getFrameSize,
|
|
18713
18723
|
isFrameLayer: isFrameLayer,
|
|
18714
18724
|
findFrameLayerInDataset: findFrameLayerInDataset,
|
|
@@ -18717,7 +18727,7 @@
|
|
|
18717
18727
|
findFrame: findFrame,
|
|
18718
18728
|
getFrameLayerBounds: getFrameLayerBounds,
|
|
18719
18729
|
getMapFrameMetersPerPixel: getMapFrameMetersPerPixel,
|
|
18720
|
-
|
|
18730
|
+
calcOutputBounds: calcOutputBounds,
|
|
18721
18731
|
parseMarginOption: parseMarginOption
|
|
18722
18732
|
});
|
|
18723
18733
|
|
|
@@ -18772,6 +18782,9 @@
|
|
|
18772
18782
|
geometry_type: 'point', shapes: targetPoints}, {geometry_type: 'polyline',
|
|
18773
18783
|
shapes: targetShapes}]}, opts);
|
|
18774
18784
|
transform = getAffineTransform(rotateArg, scaleArg, shiftArg, anchorArg);
|
|
18785
|
+
if (opts.fit_bbox) {
|
|
18786
|
+
transform = getFitBoxTransform(opts.fit_bbox, targetPoints, targetShapes, arcs);
|
|
18787
|
+
}
|
|
18775
18788
|
if (targetShapes.length > 0) {
|
|
18776
18789
|
targetFlags = new Uint8Array(arcs.size());
|
|
18777
18790
|
otherFlags = new Uint8Array(arcs.size());
|
|
@@ -18821,6 +18834,33 @@
|
|
|
18821
18834
|
};
|
|
18822
18835
|
}
|
|
18823
18836
|
|
|
18837
|
+
function getFitBoxTransform(bbox, points, shapes, arcs) {
|
|
18838
|
+
var dataset = {
|
|
18839
|
+
arcs: arcs,
|
|
18840
|
+
info: {},
|
|
18841
|
+
layers: []
|
|
18842
|
+
};
|
|
18843
|
+
if (points && points.length) {
|
|
18844
|
+
dataset.layers.push({
|
|
18845
|
+
geometry_type: 'point',
|
|
18846
|
+
shapes: points
|
|
18847
|
+
});
|
|
18848
|
+
}
|
|
18849
|
+
if (shapes && shapes.length) {
|
|
18850
|
+
dataset.layers.push({
|
|
18851
|
+
geometry_type: 'polyline',
|
|
18852
|
+
shapes: shapes
|
|
18853
|
+
});
|
|
18854
|
+
}
|
|
18855
|
+
var frame = calcFrameData(dataset, {fit_bbox: bbox});
|
|
18856
|
+
var fromBounds = new Bounds(frame.bbox);
|
|
18857
|
+
var toBounds = new Bounds(frame.bbox2);
|
|
18858
|
+
var fwd = fromBounds.getTransform(toBounds, false);
|
|
18859
|
+
return function(x, y) {
|
|
18860
|
+
return fwd.transform(x, y);
|
|
18861
|
+
};
|
|
18862
|
+
}
|
|
18863
|
+
|
|
18824
18864
|
function applyArrayMask(destArr, maskArr) {
|
|
18825
18865
|
for (var i=0, n=destArr.length; i<n; i++) {
|
|
18826
18866
|
if (maskArr[i] === 0) destArr[i] = 0;
|
|
@@ -20120,27 +20160,6 @@
|
|
|
20120
20160
|
renderFurnitureLayer: renderFurnitureLayer
|
|
20121
20161
|
});
|
|
20122
20162
|
|
|
20123
|
-
function transformDatasetToPixels(dataset, opts) {
|
|
20124
|
-
var frame = getFrameData(dataset, opts);
|
|
20125
|
-
fitDatasetToFrame(dataset, frame, opts);
|
|
20126
|
-
return [frame.width, frame.height];
|
|
20127
|
-
}
|
|
20128
|
-
|
|
20129
|
-
function fitDatasetToFrame(dataset, frame, opts) {
|
|
20130
|
-
var bounds = new Bounds(frame.bbox);
|
|
20131
|
-
var bounds2 = frame.bbox2 ? new Bounds(frame.bbox2) : new Bounds(0, 0, frame.width, frame.height);
|
|
20132
|
-
var fwd = bounds.getTransform(bounds2, opts.invert_y);
|
|
20133
|
-
transformPoints(dataset, function(x, y) {
|
|
20134
|
-
return fwd.transform(x, y);
|
|
20135
|
-
});
|
|
20136
|
-
}
|
|
20137
|
-
|
|
20138
|
-
var PixelTransform = /*#__PURE__*/Object.freeze({
|
|
20139
|
-
__proto__: null,
|
|
20140
|
-
transformDatasetToPixels: transformDatasetToPixels,
|
|
20141
|
-
fitDatasetToFrame: fitDatasetToFrame
|
|
20142
|
-
});
|
|
20143
|
-
|
|
20144
20163
|
function stringify(obj) {
|
|
20145
20164
|
var svg, joinStr;
|
|
20146
20165
|
if (!obj || !obj.tag) return '';
|
|
@@ -20428,10 +20447,11 @@
|
|
|
20428
20447
|
dataset = copyDataset(dataset); // Modify a copy of the dataset
|
|
20429
20448
|
}
|
|
20430
20449
|
|
|
20431
|
-
// invert_y setting for screen coordinates and geojson polygon generation
|
|
20432
|
-
|
|
20450
|
+
// use invert_y: 0 setting for screen coordinates and geojson polygon generation
|
|
20451
|
+
// use 1px default margin so typical strokes don't get cut off on the sides
|
|
20452
|
+
opts = Object.assign({invert_y: true, margin: "1"}, opts);
|
|
20433
20453
|
frame = getFrameData(dataset, opts);
|
|
20434
|
-
fitDatasetToFrame(dataset, frame
|
|
20454
|
+
fitDatasetToFrame(dataset, frame);
|
|
20435
20455
|
setCoordinatePrecision(dataset, opts.precision || 0.0001);
|
|
20436
20456
|
|
|
20437
20457
|
// error if one or more svg_data fields are not present in any layers
|
|
@@ -22067,10 +22087,14 @@ ${svg}
|
|
|
22067
22087
|
}
|
|
22068
22088
|
|
|
22069
22089
|
if (opts.width > 0 || opts.height > 0) {
|
|
22090
|
+
// these options create a TopoJSON with pixel coordinates, including
|
|
22091
|
+
// origin (0,0) in the top left corner of the viewport, generally for
|
|
22092
|
+
// direct conversion to SVG (many online examples using d3 are like this)
|
|
22093
|
+
//
|
|
22070
22094
|
opts = utils.defaults({invert_y: true}, opts);
|
|
22071
|
-
|
|
22095
|
+
fitDatasetToFrame(dataset, getFrameData(dataset, opts));
|
|
22072
22096
|
} else if (opts.fit_bbox) {
|
|
22073
|
-
|
|
22097
|
+
fitDatasetToFrame(dataset, getFrameData(dataset, {fit_bbox: opts.fit_bbox}));
|
|
22074
22098
|
}
|
|
22075
22099
|
|
|
22076
22100
|
if (opts.precision && opts.no_quantization) {
|
|
@@ -24279,7 +24303,7 @@ ${svg}
|
|
|
24279
24303
|
describe: 'aspect ratio as a number or range (e.g. 2 0.8,1.6 ,2)'
|
|
24280
24304
|
},
|
|
24281
24305
|
offsetOpt = {
|
|
24282
|
-
describe: '
|
|
24306
|
+
describe: 'offset distance or pct of h/w (single value or l,b,r,t list)',
|
|
24283
24307
|
type: 'distance'
|
|
24284
24308
|
};
|
|
24285
24309
|
|
|
@@ -24609,6 +24633,10 @@ ${svg}
|
|
|
24609
24633
|
type: 'numbers',
|
|
24610
24634
|
describe: 'center of rotation/scaling (default is center of selected shapes)'
|
|
24611
24635
|
})
|
|
24636
|
+
.option('fit-bbox', {
|
|
24637
|
+
type: 'bbox',
|
|
24638
|
+
describe: 'scale and shift coordinates to fit a bbox'
|
|
24639
|
+
})
|
|
24612
24640
|
.option('where', whereOpt)
|
|
24613
24641
|
.option('target', targetOpt);
|
|
24614
24642
|
|
|
@@ -39317,7 +39345,7 @@ ${svg}
|
|
|
39317
39345
|
// TODO: consider projections that may or may not be aligned,
|
|
39318
39346
|
// depending on parameters
|
|
39319
39347
|
if (inList(P, 'cassini,gnom,bertin1953,chamb,ob_tran,tpeqd,healpix,rhealpix,' +
|
|
39320
|
-
'ocea,omerc,tmerc,etmerc')) {
|
|
39348
|
+
'ocea,omerc,tmerc,etmerc,nicol')) {
|
|
39321
39349
|
return false;
|
|
39322
39350
|
}
|
|
39323
39351
|
if (isAzimuthal(P)) {
|
|
@@ -39892,7 +39920,7 @@ ${svg}
|
|
|
39892
39920
|
}
|
|
39893
39921
|
|
|
39894
39922
|
function isCircleClippedProjection(P) {
|
|
39895
|
-
return inList(P, 'stere,sterea,ups,ortho,gnom,laea,nsper,tpers,geos');
|
|
39923
|
+
return inList(P, 'stere,sterea,ups,ortho,gnom,laea,nsper,tpers,geos,nicol');
|
|
39896
39924
|
}
|
|
39897
39925
|
|
|
39898
39926
|
function getPerspectiveClipAngle(P) {
|
|
@@ -39917,6 +39945,7 @@ ${svg}
|
|
|
39917
39945
|
laea: 179,
|
|
39918
39946
|
//ortho: 89.9, // projection errors betwen lat +/-35 to 55
|
|
39919
39947
|
ortho: 89.85, // TODO: investigate
|
|
39948
|
+
nicol: 89.85,
|
|
39920
39949
|
stere: 142,
|
|
39921
39950
|
sterea: 142,
|
|
39922
39951
|
ups: 10.5 // TODO: should be 6.5 deg at north pole
|
|
@@ -44521,6 +44550,7 @@ ${svg}
|
|
|
44521
44550
|
if (!size) return null;
|
|
44522
44551
|
var stemLen = size.stemLen,
|
|
44523
44552
|
headLen = size.headLen,
|
|
44553
|
+
totalLen = stickArrow ? Math.max(stemLen, headLen) : stemLen + headLen,
|
|
44524
44554
|
headDx = size.headWidth / 2,
|
|
44525
44555
|
stemDx = size.stemWidth / 2,
|
|
44526
44556
|
baseDx = stemDx * (1 - stemTaper),
|
|
@@ -44573,11 +44603,10 @@ ${svg}
|
|
|
44573
44603
|
}
|
|
44574
44604
|
|
|
44575
44605
|
if (d.anchor == 'end') {
|
|
44576
|
-
scaleAndShiftCoords(coords, 1, [-dx, -
|
|
44606
|
+
scaleAndShiftCoords(coords, 1, [-dx, -totalLen]);
|
|
44577
44607
|
} else if (d.anchor == 'middle') {
|
|
44578
44608
|
// shift midpoint away from the head a bit for a more balanced placement
|
|
44579
|
-
|
|
44580
|
-
scaleAndShiftCoords(coords, 1, [-dx * 0.5, -dy * 0.5 - headLen * 0.25]);
|
|
44609
|
+
scaleAndShiftCoords(coords, 1, [-dx * 0.5, -dy * 0.5 - totalLen * 0.25]);
|
|
44581
44610
|
}
|
|
44582
44611
|
|
|
44583
44612
|
rotateCoords(coords, direction);
|
|
@@ -44594,15 +44623,16 @@ ${svg}
|
|
|
44594
44623
|
|
|
44595
44624
|
function calcArrowSize(d, stickArrow) {
|
|
44596
44625
|
// don't display arrows with negative length
|
|
44597
|
-
var
|
|
44598
|
-
|
|
44599
|
-
|
|
44626
|
+
var o = initArrowSize(d), // calc several parameters
|
|
44627
|
+
dataLen = Math.max(d.radius || d.length || d.r || 0),
|
|
44628
|
+
totalLen = Math.max(dataLen, o.headLen, 0),
|
|
44629
|
+
scale = 1;
|
|
44600
44630
|
if (totalLen >= 0) {
|
|
44601
44631
|
scale = calcScale(totalLen, o.headLen, d);
|
|
44602
44632
|
o.stemWidth *= scale;
|
|
44603
44633
|
o.headWidth *= scale;
|
|
44604
44634
|
o.headLen *= scale;
|
|
44605
|
-
o.stemLen = stickArrow ?
|
|
44635
|
+
o.stemLen = stickArrow ? dataLen : totalLen - o.headLen;
|
|
44606
44636
|
}
|
|
44607
44637
|
|
|
44608
44638
|
if (o.headWidth < o.stemWidth && o.headWidth > 0) {
|
|
@@ -44651,13 +44681,11 @@ ${svg}
|
|
|
44651
44681
|
return o;
|
|
44652
44682
|
}
|
|
44653
44683
|
|
|
44654
|
-
|
|
44655
44684
|
// Returns ratio of head length to head width
|
|
44656
44685
|
function getHeadSizeRatio(headAngle) {
|
|
44657
44686
|
return 1 / Math.tan(Math.PI * headAngle / 180 / 2) / 2;
|
|
44658
44687
|
}
|
|
44659
44688
|
|
|
44660
|
-
|
|
44661
44689
|
// ax, ay: point on the base
|
|
44662
44690
|
// bx, by: point on the stem
|
|
44663
44691
|
function getCurvedStemCoords(ax, ay, bx, by) {
|
|
@@ -45870,7 +45898,7 @@ ${svg}
|
|
|
45870
45898
|
});
|
|
45871
45899
|
}
|
|
45872
45900
|
|
|
45873
|
-
var version = "0.6.
|
|
45901
|
+
var version = "0.6.102";
|
|
45874
45902
|
|
|
45875
45903
|
// Parse command line args into commands and run them
|
|
45876
45904
|
// Function takes an optional Node-style callback. A Promise is returned if no callback is given.
|
|
@@ -46563,7 +46591,7 @@ ${svg}
|
|
|
46563
46591
|
FileTypes,
|
|
46564
46592
|
FilterGeom,
|
|
46565
46593
|
Frame,
|
|
46566
|
-
|
|
46594
|
+
FrameUtils,
|
|
46567
46595
|
Furniture,
|
|
46568
46596
|
Geodesic,
|
|
46569
46597
|
GeojsonExport,
|
|
@@ -46598,7 +46626,7 @@ ${svg}
|
|
|
46598
46626
|
PathImport,
|
|
46599
46627
|
PathRepair,
|
|
46600
46628
|
PathUtils,
|
|
46601
|
-
PixelTransform,
|
|
46629
|
+
// PixelTransform,
|
|
46602
46630
|
PointPolygonJoin,
|
|
46603
46631
|
Points,
|
|
46604
46632
|
PointToGrid,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mapshaper",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.102",
|
|
4
4
|
"description": "A tool for editing vector datasets for mapping and GIS.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"shapefile",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"iconv-lite": "^0.6.3",
|
|
57
57
|
"idb-keyval": "^6.2.0",
|
|
58
58
|
"kdbush": "^3.0.0",
|
|
59
|
-
"mproj": "0.0.
|
|
59
|
+
"mproj": "0.0.40",
|
|
60
60
|
"msgpackr": "^1.10.1",
|
|
61
61
|
"opn": "^5.3.0",
|
|
62
62
|
"rw": "~1.3.3",
|
package/www/mapshaper-gui.js
CHANGED
|
@@ -6843,6 +6843,7 @@
|
|
|
6843
6843
|
});
|
|
6844
6844
|
}
|
|
6845
6845
|
|
|
6846
|
+
|
|
6846
6847
|
function defaults(dest) {
|
|
6847
6848
|
for (var i=1, n=arguments.length; i<n; i++) {
|
|
6848
6849
|
var src = arguments[i] || {};
|
|
@@ -12974,7 +12975,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12974
12975
|
function calcFullBounds() {
|
|
12975
12976
|
var b;
|
|
12976
12977
|
if (isPreviewView()) {
|
|
12977
|
-
b = new Bounds(
|
|
12978
|
+
b = new Bounds(getFrameLayerData().bbox);
|
|
12978
12979
|
} else {
|
|
12979
12980
|
b = getContentLayerBounds();
|
|
12980
12981
|
}
|
|
@@ -13014,10 +13015,10 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13014
13015
|
|
|
13015
13016
|
// Preview view: symbols are scaled based on display size of frame layer
|
|
13016
13017
|
function isPreviewView() {
|
|
13017
|
-
return !isTableView() && !!
|
|
13018
|
+
return !isTableView() && !!getFrameLayerData();
|
|
13018
13019
|
}
|
|
13019
13020
|
|
|
13020
|
-
function
|
|
13021
|
+
function getFrameLayerData() {
|
|
13021
13022
|
var lyr = findFrameLayer();
|
|
13022
13023
|
return lyr && internal.getFrameLayerData(lyr, lyr.gui.displayArcs) || null;
|
|
13023
13024
|
}
|
|
@@ -13138,7 +13139,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13138
13139
|
}
|
|
13139
13140
|
if (layersMayHaveChanged) {
|
|
13140
13141
|
// kludge to handle layer visibility toggling
|
|
13141
|
-
_ext.setFrameData(isPreviewView() ?
|
|
13142
|
+
_ext.setFrameData(isPreviewView() ? getFrameLayerData() : null);
|
|
13142
13143
|
updateFullBounds();
|
|
13143
13144
|
updateLayerStyles(contentLayers);
|
|
13144
13145
|
updateLayerStackOrder(model.getLayers());// update menu_order property of all layers
|
package/www/mapshaper.js
CHANGED
|
@@ -267,6 +267,7 @@
|
|
|
267
267
|
});
|
|
268
268
|
}
|
|
269
269
|
|
|
270
|
+
|
|
270
271
|
function defaults(dest) {
|
|
271
272
|
for (var i=1, n=arguments.length; i<n; i++) {
|
|
272
273
|
var src = arguments[i] || {};
|
|
@@ -13762,7 +13763,7 @@
|
|
|
13762
13763
|
convertIntervalParam(opt[1], crs)];
|
|
13763
13764
|
}
|
|
13764
13765
|
|
|
13765
|
-
// Accepts a single value or a list of four values. List order is l,b,t
|
|
13766
|
+
// Accepts a single value or a list of four values. List order is l,b,r,t
|
|
13766
13767
|
function convertFourSides(opt, crs, bounds) {
|
|
13767
13768
|
var arr = opt.includes(',') ? opt.split(',') : opt.split(' ');
|
|
13768
13769
|
if (arr.length == 1) {
|
|
@@ -13776,7 +13777,7 @@
|
|
|
13776
13777
|
tmp = parseFloat(param) / 100 || 0;
|
|
13777
13778
|
return tmp * (i == 1 || i == 3 ? bounds.height() : bounds.width());
|
|
13778
13779
|
}
|
|
13779
|
-
return convertIntervalParam(
|
|
13780
|
+
return convertIntervalParam(param, crs);
|
|
13780
13781
|
});
|
|
13781
13782
|
}
|
|
13782
13783
|
|
|
@@ -18486,18 +18487,30 @@
|
|
|
18486
18487
|
type: 'frame'
|
|
18487
18488
|
}
|
|
18488
18489
|
*/
|
|
18490
|
+
|
|
18491
|
+
|
|
18489
18492
|
function getFrameData(dataset, exportOpts) {
|
|
18490
18493
|
var frameLyr = findFrameLayerInDataset(dataset);
|
|
18491
|
-
var
|
|
18494
|
+
var data;
|
|
18492
18495
|
if (frameLyr) {
|
|
18493
|
-
|
|
18496
|
+
data = getFrameLayerData(frameLyr, dataset.arcs);
|
|
18494
18497
|
} else {
|
|
18495
|
-
|
|
18498
|
+
data = calcFrameData(dataset, exportOpts);
|
|
18496
18499
|
}
|
|
18497
|
-
|
|
18498
|
-
|
|
18500
|
+
data.invert_y = !!exportOpts.invert_y;
|
|
18501
|
+
data.crs = getDatasetCRS(dataset);
|
|
18502
|
+
return data;
|
|
18499
18503
|
}
|
|
18500
18504
|
|
|
18505
|
+
function fitDatasetToFrame(dataset, frame) {
|
|
18506
|
+
var bounds = new Bounds(frame.bbox);
|
|
18507
|
+
var bounds2 = frame.bbox2 ? new Bounds(frame.bbox2) : new Bounds(0, 0, frame.width, frame.height);
|
|
18508
|
+
bounds.fillOut(bounds2.width() / bounds2.height());
|
|
18509
|
+
var fwd = bounds.getTransform(bounds2, frame.invert_y);
|
|
18510
|
+
transformPoints(dataset, function(x, y) {
|
|
18511
|
+
return fwd.transform(x, y);
|
|
18512
|
+
});
|
|
18513
|
+
}
|
|
18501
18514
|
|
|
18502
18515
|
function getFrameLayerData(lyr, arcs) {
|
|
18503
18516
|
var bounds = getLayerBounds(lyr, arcs);
|
|
@@ -18515,24 +18528,25 @@
|
|
|
18515
18528
|
|
|
18516
18529
|
|
|
18517
18530
|
function calcFrameData(dataset, opts) {
|
|
18518
|
-
var
|
|
18531
|
+
var inputBounds, outputBounds;
|
|
18519
18532
|
if (opts.svg_bbox) {
|
|
18520
|
-
|
|
18533
|
+
inputBounds = new Bounds(opts.svg_bbox);
|
|
18521
18534
|
opts = Object.assign({margin: 0}, opts); // prevent default pixel margin around content
|
|
18522
18535
|
} else {
|
|
18523
|
-
|
|
18536
|
+
inputBounds = getDatasetBounds(dataset);
|
|
18524
18537
|
}
|
|
18525
|
-
|
|
18538
|
+
// side effect: inputBounds may be expanded to add margins
|
|
18539
|
+
outputBounds = calcOutputBounds(inputBounds, opts);
|
|
18526
18540
|
return {
|
|
18527
|
-
bbox:
|
|
18528
|
-
bbox2:
|
|
18529
|
-
width: Math.round(
|
|
18530
|
-
height: Math.round(
|
|
18541
|
+
bbox: inputBounds.toArray(),
|
|
18542
|
+
bbox2: outputBounds.toArray(),
|
|
18543
|
+
width: Math.round(outputBounds.width()),
|
|
18544
|
+
height: Math.round(outputBounds.height()) || 1,
|
|
18531
18545
|
type: 'frame'
|
|
18532
18546
|
};
|
|
18533
18547
|
}
|
|
18534
18548
|
|
|
18535
|
-
// Used by mapshaper-frame
|
|
18549
|
+
// Used by mapshaper-frame TODO: refactor
|
|
18536
18550
|
function getFrameSize(bounds, opts) {
|
|
18537
18551
|
var aspectRatio = bounds.width() / bounds.height();
|
|
18538
18552
|
var height, width;
|
|
@@ -18601,9 +18615,9 @@
|
|
|
18601
18615
|
|
|
18602
18616
|
|
|
18603
18617
|
// bounds: Bounds object containing bounds of content in geographic coordinates
|
|
18604
|
-
// returns Bounds object containing bounds
|
|
18618
|
+
// returns Bounds object containing output bounds
|
|
18605
18619
|
// side effect: bounds param is modified to match the output frame
|
|
18606
|
-
function
|
|
18620
|
+
function calcOutputBounds(bounds, opts) {
|
|
18607
18621
|
var padX = 0,
|
|
18608
18622
|
padY = 0,
|
|
18609
18623
|
offX = 0,
|
|
@@ -18616,65 +18630,59 @@
|
|
|
18616
18630
|
// TODO: add option to tweak alignment of content when both width and height are given
|
|
18617
18631
|
wx = 0.5, // how padding is distributed horizontally (0: left aligned, 0.5: centered, 1: right aligned)
|
|
18618
18632
|
wy = 0.5, // vertical padding distribution
|
|
18619
|
-
|
|
18633
|
+
width2, height2, size2, kx, ky;
|
|
18620
18634
|
|
|
18621
18635
|
if (opts.fit_bbox) {
|
|
18622
18636
|
// scale + shift content to fit within a bbox
|
|
18623
18637
|
offX = opts.fit_bbox[0];
|
|
18624
18638
|
offY = opts.fit_bbox[1];
|
|
18625
|
-
|
|
18626
|
-
|
|
18627
|
-
if (width / height > widthPx / heightPx) {
|
|
18628
|
-
// data is wider than fit box...
|
|
18629
|
-
// scale the data to fit widthwise
|
|
18630
|
-
heightPx = 0;
|
|
18631
|
-
} else {
|
|
18632
|
-
widthPx = 0; // fit the data to the height
|
|
18633
|
-
}
|
|
18639
|
+
width2 = opts.fit_bbox[2] - offX;
|
|
18640
|
+
height2 = opts.fit_bbox[3] - offY;
|
|
18634
18641
|
marginX = marginY = 0; // TODO: support margins
|
|
18635
18642
|
|
|
18636
18643
|
} else if (opts.svg_scale > 0) {
|
|
18637
18644
|
// alternative to using a fixed width (e.g. when generating multiple files
|
|
18638
18645
|
// at a consistent geographic scale)
|
|
18639
|
-
|
|
18640
|
-
|
|
18646
|
+
width2 = width / opts.svg_scale + marginX;
|
|
18647
|
+
height2 = 0;
|
|
18641
18648
|
} else if (+opts.pixels) {
|
|
18642
|
-
|
|
18643
|
-
|
|
18644
|
-
|
|
18649
|
+
size2 = getFrameSize(bounds, opts);
|
|
18650
|
+
width2 = size2[0];
|
|
18651
|
+
height2 = size2[1];
|
|
18645
18652
|
} else {
|
|
18646
|
-
|
|
18647
|
-
|
|
18653
|
+
height2 = opts.height || 0;
|
|
18654
|
+
width2 = opts.width || (height2 > 0 ? 0 : 800); // 800 is default width
|
|
18648
18655
|
}
|
|
18649
18656
|
|
|
18650
|
-
if (
|
|
18657
|
+
if (height2 > 0) {
|
|
18651
18658
|
// vertical meters per pixel to fit height param
|
|
18652
|
-
ky = (height || width || 1) / (
|
|
18659
|
+
ky = (height || width || 1) / (height2 - marginY);
|
|
18653
18660
|
}
|
|
18654
|
-
if (
|
|
18661
|
+
if (width2 > 0) {
|
|
18655
18662
|
// horizontal meters per pixel to fit width param
|
|
18656
|
-
kx = (width || height || 1) / (
|
|
18663
|
+
kx = (width || height || 1) / (width2 - marginX);
|
|
18657
18664
|
}
|
|
18658
18665
|
|
|
18659
|
-
if (!
|
|
18666
|
+
if (!width2) { // height2 and ky are defined, set width to match
|
|
18660
18667
|
kx = ky;
|
|
18661
|
-
|
|
18662
|
-
} else if (!
|
|
18668
|
+
width2 = width > 0 ? marginX + width / kx : height2; // export square graphic if content has 0 width (reconsider this?)
|
|
18669
|
+
} else if (!height2) { // width2 and kx are set, set height to match
|
|
18663
18670
|
ky = kx;
|
|
18664
|
-
|
|
18671
|
+
height2 = height > 0 ? marginY + height / ky : width2;
|
|
18665
18672
|
// limit height if max_height is defined
|
|
18666
|
-
if (opts.max_height > 0 &&
|
|
18667
|
-
ky = kx *
|
|
18668
|
-
|
|
18673
|
+
if (opts.max_height > 0 && height2 > opts.max_height) {
|
|
18674
|
+
ky = kx * height2 / opts.max_height;
|
|
18675
|
+
height2 = opts.max_height;
|
|
18669
18676
|
}
|
|
18670
18677
|
}
|
|
18671
18678
|
|
|
18679
|
+
// add padding, if needed
|
|
18672
18680
|
if (kx > ky) { // content is wide -- need to pad vertically
|
|
18673
18681
|
ky = kx;
|
|
18674
|
-
padY = ky * (
|
|
18682
|
+
padY = ky * (height2 - marginY) - height;
|
|
18675
18683
|
} else if (ky > kx) { // content is tall -- need to pad horizontally
|
|
18676
18684
|
kx = ky;
|
|
18677
|
-
padX = kx * (
|
|
18685
|
+
padX = kx * (width2 - marginX) - width;
|
|
18678
18686
|
}
|
|
18679
18687
|
|
|
18680
18688
|
bounds.padBounds(
|
|
@@ -18683,14 +18691,14 @@
|
|
|
18683
18691
|
margins[2] * kx + padX * (1 - wx),
|
|
18684
18692
|
margins[3] * ky + padY * (1 - wy));
|
|
18685
18693
|
|
|
18686
|
-
if (!(
|
|
18694
|
+
if (!(width2 > 0 && height2 > 0)) {
|
|
18687
18695
|
error("Missing valid height and width parameters");
|
|
18688
18696
|
}
|
|
18689
18697
|
if (!(kx === ky && kx > 0)) {
|
|
18690
18698
|
error("Missing valid margin parameters");
|
|
18691
18699
|
}
|
|
18692
18700
|
|
|
18693
|
-
return new Bounds(offX, offY,
|
|
18701
|
+
return new Bounds(offX, offY, width2 + offX, height2 + offY);
|
|
18694
18702
|
}
|
|
18695
18703
|
|
|
18696
18704
|
function parseMarginOption(opt) {
|
|
@@ -18701,14 +18709,16 @@
|
|
|
18701
18709
|
if (margins.length == 3) margins.push(margins[2]);
|
|
18702
18710
|
return margins.map(function(str) {
|
|
18703
18711
|
var px = parseFloat(str);
|
|
18704
|
-
return isNaN(px) ?
|
|
18712
|
+
return isNaN(px) ? 0 : px; // 0 is default
|
|
18705
18713
|
});
|
|
18706
18714
|
}
|
|
18707
18715
|
|
|
18708
|
-
var
|
|
18716
|
+
var FrameUtils = /*#__PURE__*/Object.freeze({
|
|
18709
18717
|
__proto__: null,
|
|
18710
18718
|
getFrameData: getFrameData,
|
|
18719
|
+
fitDatasetToFrame: fitDatasetToFrame,
|
|
18711
18720
|
getFrameLayerData: getFrameLayerData,
|
|
18721
|
+
calcFrameData: calcFrameData,
|
|
18712
18722
|
getFrameSize: getFrameSize,
|
|
18713
18723
|
isFrameLayer: isFrameLayer,
|
|
18714
18724
|
findFrameLayerInDataset: findFrameLayerInDataset,
|
|
@@ -18717,7 +18727,7 @@
|
|
|
18717
18727
|
findFrame: findFrame,
|
|
18718
18728
|
getFrameLayerBounds: getFrameLayerBounds,
|
|
18719
18729
|
getMapFrameMetersPerPixel: getMapFrameMetersPerPixel,
|
|
18720
|
-
|
|
18730
|
+
calcOutputBounds: calcOutputBounds,
|
|
18721
18731
|
parseMarginOption: parseMarginOption
|
|
18722
18732
|
});
|
|
18723
18733
|
|
|
@@ -18772,6 +18782,9 @@
|
|
|
18772
18782
|
geometry_type: 'point', shapes: targetPoints}, {geometry_type: 'polyline',
|
|
18773
18783
|
shapes: targetShapes}]}, opts);
|
|
18774
18784
|
transform = getAffineTransform(rotateArg, scaleArg, shiftArg, anchorArg);
|
|
18785
|
+
if (opts.fit_bbox) {
|
|
18786
|
+
transform = getFitBoxTransform(opts.fit_bbox, targetPoints, targetShapes, arcs);
|
|
18787
|
+
}
|
|
18775
18788
|
if (targetShapes.length > 0) {
|
|
18776
18789
|
targetFlags = new Uint8Array(arcs.size());
|
|
18777
18790
|
otherFlags = new Uint8Array(arcs.size());
|
|
@@ -18821,6 +18834,33 @@
|
|
|
18821
18834
|
};
|
|
18822
18835
|
}
|
|
18823
18836
|
|
|
18837
|
+
function getFitBoxTransform(bbox, points, shapes, arcs) {
|
|
18838
|
+
var dataset = {
|
|
18839
|
+
arcs: arcs,
|
|
18840
|
+
info: {},
|
|
18841
|
+
layers: []
|
|
18842
|
+
};
|
|
18843
|
+
if (points && points.length) {
|
|
18844
|
+
dataset.layers.push({
|
|
18845
|
+
geometry_type: 'point',
|
|
18846
|
+
shapes: points
|
|
18847
|
+
});
|
|
18848
|
+
}
|
|
18849
|
+
if (shapes && shapes.length) {
|
|
18850
|
+
dataset.layers.push({
|
|
18851
|
+
geometry_type: 'polyline',
|
|
18852
|
+
shapes: shapes
|
|
18853
|
+
});
|
|
18854
|
+
}
|
|
18855
|
+
var frame = calcFrameData(dataset, {fit_bbox: bbox});
|
|
18856
|
+
var fromBounds = new Bounds(frame.bbox);
|
|
18857
|
+
var toBounds = new Bounds(frame.bbox2);
|
|
18858
|
+
var fwd = fromBounds.getTransform(toBounds, false);
|
|
18859
|
+
return function(x, y) {
|
|
18860
|
+
return fwd.transform(x, y);
|
|
18861
|
+
};
|
|
18862
|
+
}
|
|
18863
|
+
|
|
18824
18864
|
function applyArrayMask(destArr, maskArr) {
|
|
18825
18865
|
for (var i=0, n=destArr.length; i<n; i++) {
|
|
18826
18866
|
if (maskArr[i] === 0) destArr[i] = 0;
|
|
@@ -20120,27 +20160,6 @@
|
|
|
20120
20160
|
renderFurnitureLayer: renderFurnitureLayer
|
|
20121
20161
|
});
|
|
20122
20162
|
|
|
20123
|
-
function transformDatasetToPixels(dataset, opts) {
|
|
20124
|
-
var frame = getFrameData(dataset, opts);
|
|
20125
|
-
fitDatasetToFrame(dataset, frame, opts);
|
|
20126
|
-
return [frame.width, frame.height];
|
|
20127
|
-
}
|
|
20128
|
-
|
|
20129
|
-
function fitDatasetToFrame(dataset, frame, opts) {
|
|
20130
|
-
var bounds = new Bounds(frame.bbox);
|
|
20131
|
-
var bounds2 = frame.bbox2 ? new Bounds(frame.bbox2) : new Bounds(0, 0, frame.width, frame.height);
|
|
20132
|
-
var fwd = bounds.getTransform(bounds2, opts.invert_y);
|
|
20133
|
-
transformPoints(dataset, function(x, y) {
|
|
20134
|
-
return fwd.transform(x, y);
|
|
20135
|
-
});
|
|
20136
|
-
}
|
|
20137
|
-
|
|
20138
|
-
var PixelTransform = /*#__PURE__*/Object.freeze({
|
|
20139
|
-
__proto__: null,
|
|
20140
|
-
transformDatasetToPixels: transformDatasetToPixels,
|
|
20141
|
-
fitDatasetToFrame: fitDatasetToFrame
|
|
20142
|
-
});
|
|
20143
|
-
|
|
20144
20163
|
function stringify(obj) {
|
|
20145
20164
|
var svg, joinStr;
|
|
20146
20165
|
if (!obj || !obj.tag) return '';
|
|
@@ -20428,10 +20447,11 @@
|
|
|
20428
20447
|
dataset = copyDataset(dataset); // Modify a copy of the dataset
|
|
20429
20448
|
}
|
|
20430
20449
|
|
|
20431
|
-
// invert_y setting for screen coordinates and geojson polygon generation
|
|
20432
|
-
|
|
20450
|
+
// use invert_y: 0 setting for screen coordinates and geojson polygon generation
|
|
20451
|
+
// use 1px default margin so typical strokes don't get cut off on the sides
|
|
20452
|
+
opts = Object.assign({invert_y: true, margin: "1"}, opts);
|
|
20433
20453
|
frame = getFrameData(dataset, opts);
|
|
20434
|
-
fitDatasetToFrame(dataset, frame
|
|
20454
|
+
fitDatasetToFrame(dataset, frame);
|
|
20435
20455
|
setCoordinatePrecision(dataset, opts.precision || 0.0001);
|
|
20436
20456
|
|
|
20437
20457
|
// error if one or more svg_data fields are not present in any layers
|
|
@@ -22067,10 +22087,14 @@ ${svg}
|
|
|
22067
22087
|
}
|
|
22068
22088
|
|
|
22069
22089
|
if (opts.width > 0 || opts.height > 0) {
|
|
22090
|
+
// these options create a TopoJSON with pixel coordinates, including
|
|
22091
|
+
// origin (0,0) in the top left corner of the viewport, generally for
|
|
22092
|
+
// direct conversion to SVG (many online examples using d3 are like this)
|
|
22093
|
+
//
|
|
22070
22094
|
opts = utils.defaults({invert_y: true}, opts);
|
|
22071
|
-
|
|
22095
|
+
fitDatasetToFrame(dataset, getFrameData(dataset, opts));
|
|
22072
22096
|
} else if (opts.fit_bbox) {
|
|
22073
|
-
|
|
22097
|
+
fitDatasetToFrame(dataset, getFrameData(dataset, {fit_bbox: opts.fit_bbox}));
|
|
22074
22098
|
}
|
|
22075
22099
|
|
|
22076
22100
|
if (opts.precision && opts.no_quantization) {
|
|
@@ -24279,7 +24303,7 @@ ${svg}
|
|
|
24279
24303
|
describe: 'aspect ratio as a number or range (e.g. 2 0.8,1.6 ,2)'
|
|
24280
24304
|
},
|
|
24281
24305
|
offsetOpt = {
|
|
24282
|
-
describe: '
|
|
24306
|
+
describe: 'offset distance or pct of h/w (single value or l,b,r,t list)',
|
|
24283
24307
|
type: 'distance'
|
|
24284
24308
|
};
|
|
24285
24309
|
|
|
@@ -24609,6 +24633,10 @@ ${svg}
|
|
|
24609
24633
|
type: 'numbers',
|
|
24610
24634
|
describe: 'center of rotation/scaling (default is center of selected shapes)'
|
|
24611
24635
|
})
|
|
24636
|
+
.option('fit-bbox', {
|
|
24637
|
+
type: 'bbox',
|
|
24638
|
+
describe: 'scale and shift coordinates to fit a bbox'
|
|
24639
|
+
})
|
|
24612
24640
|
.option('where', whereOpt)
|
|
24613
24641
|
.option('target', targetOpt);
|
|
24614
24642
|
|
|
@@ -39317,7 +39345,7 @@ ${svg}
|
|
|
39317
39345
|
// TODO: consider projections that may or may not be aligned,
|
|
39318
39346
|
// depending on parameters
|
|
39319
39347
|
if (inList(P, 'cassini,gnom,bertin1953,chamb,ob_tran,tpeqd,healpix,rhealpix,' +
|
|
39320
|
-
'ocea,omerc,tmerc,etmerc')) {
|
|
39348
|
+
'ocea,omerc,tmerc,etmerc,nicol')) {
|
|
39321
39349
|
return false;
|
|
39322
39350
|
}
|
|
39323
39351
|
if (isAzimuthal(P)) {
|
|
@@ -39892,7 +39920,7 @@ ${svg}
|
|
|
39892
39920
|
}
|
|
39893
39921
|
|
|
39894
39922
|
function isCircleClippedProjection(P) {
|
|
39895
|
-
return inList(P, 'stere,sterea,ups,ortho,gnom,laea,nsper,tpers,geos');
|
|
39923
|
+
return inList(P, 'stere,sterea,ups,ortho,gnom,laea,nsper,tpers,geos,nicol');
|
|
39896
39924
|
}
|
|
39897
39925
|
|
|
39898
39926
|
function getPerspectiveClipAngle(P) {
|
|
@@ -39917,6 +39945,7 @@ ${svg}
|
|
|
39917
39945
|
laea: 179,
|
|
39918
39946
|
//ortho: 89.9, // projection errors betwen lat +/-35 to 55
|
|
39919
39947
|
ortho: 89.85, // TODO: investigate
|
|
39948
|
+
nicol: 89.85,
|
|
39920
39949
|
stere: 142,
|
|
39921
39950
|
sterea: 142,
|
|
39922
39951
|
ups: 10.5 // TODO: should be 6.5 deg at north pole
|
|
@@ -44521,6 +44550,7 @@ ${svg}
|
|
|
44521
44550
|
if (!size) return null;
|
|
44522
44551
|
var stemLen = size.stemLen,
|
|
44523
44552
|
headLen = size.headLen,
|
|
44553
|
+
totalLen = stickArrow ? Math.max(stemLen, headLen) : stemLen + headLen,
|
|
44524
44554
|
headDx = size.headWidth / 2,
|
|
44525
44555
|
stemDx = size.stemWidth / 2,
|
|
44526
44556
|
baseDx = stemDx * (1 - stemTaper),
|
|
@@ -44573,11 +44603,10 @@ ${svg}
|
|
|
44573
44603
|
}
|
|
44574
44604
|
|
|
44575
44605
|
if (d.anchor == 'end') {
|
|
44576
|
-
scaleAndShiftCoords(coords, 1, [-dx, -
|
|
44606
|
+
scaleAndShiftCoords(coords, 1, [-dx, -totalLen]);
|
|
44577
44607
|
} else if (d.anchor == 'middle') {
|
|
44578
44608
|
// shift midpoint away from the head a bit for a more balanced placement
|
|
44579
|
-
|
|
44580
|
-
scaleAndShiftCoords(coords, 1, [-dx * 0.5, -dy * 0.5 - headLen * 0.25]);
|
|
44609
|
+
scaleAndShiftCoords(coords, 1, [-dx * 0.5, -dy * 0.5 - totalLen * 0.25]);
|
|
44581
44610
|
}
|
|
44582
44611
|
|
|
44583
44612
|
rotateCoords(coords, direction);
|
|
@@ -44594,15 +44623,16 @@ ${svg}
|
|
|
44594
44623
|
|
|
44595
44624
|
function calcArrowSize(d, stickArrow) {
|
|
44596
44625
|
// don't display arrows with negative length
|
|
44597
|
-
var
|
|
44598
|
-
|
|
44599
|
-
|
|
44626
|
+
var o = initArrowSize(d), // calc several parameters
|
|
44627
|
+
dataLen = Math.max(d.radius || d.length || d.r || 0),
|
|
44628
|
+
totalLen = Math.max(dataLen, o.headLen, 0),
|
|
44629
|
+
scale = 1;
|
|
44600
44630
|
if (totalLen >= 0) {
|
|
44601
44631
|
scale = calcScale(totalLen, o.headLen, d);
|
|
44602
44632
|
o.stemWidth *= scale;
|
|
44603
44633
|
o.headWidth *= scale;
|
|
44604
44634
|
o.headLen *= scale;
|
|
44605
|
-
o.stemLen = stickArrow ?
|
|
44635
|
+
o.stemLen = stickArrow ? dataLen : totalLen - o.headLen;
|
|
44606
44636
|
}
|
|
44607
44637
|
|
|
44608
44638
|
if (o.headWidth < o.stemWidth && o.headWidth > 0) {
|
|
@@ -44651,13 +44681,11 @@ ${svg}
|
|
|
44651
44681
|
return o;
|
|
44652
44682
|
}
|
|
44653
44683
|
|
|
44654
|
-
|
|
44655
44684
|
// Returns ratio of head length to head width
|
|
44656
44685
|
function getHeadSizeRatio(headAngle) {
|
|
44657
44686
|
return 1 / Math.tan(Math.PI * headAngle / 180 / 2) / 2;
|
|
44658
44687
|
}
|
|
44659
44688
|
|
|
44660
|
-
|
|
44661
44689
|
// ax, ay: point on the base
|
|
44662
44690
|
// bx, by: point on the stem
|
|
44663
44691
|
function getCurvedStemCoords(ax, ay, bx, by) {
|
|
@@ -45870,7 +45898,7 @@ ${svg}
|
|
|
45870
45898
|
});
|
|
45871
45899
|
}
|
|
45872
45900
|
|
|
45873
|
-
var version = "0.6.
|
|
45901
|
+
var version = "0.6.102";
|
|
45874
45902
|
|
|
45875
45903
|
// Parse command line args into commands and run them
|
|
45876
45904
|
// Function takes an optional Node-style callback. A Promise is returned if no callback is given.
|
|
@@ -46563,7 +46591,7 @@ ${svg}
|
|
|
46563
46591
|
FileTypes,
|
|
46564
46592
|
FilterGeom,
|
|
46565
46593
|
Frame,
|
|
46566
|
-
|
|
46594
|
+
FrameUtils,
|
|
46567
46595
|
Furniture,
|
|
46568
46596
|
Geodesic,
|
|
46569
46597
|
GeojsonExport,
|
|
@@ -46598,7 +46626,7 @@ ${svg}
|
|
|
46598
46626
|
PathImport,
|
|
46599
46627
|
PathRepair,
|
|
46600
46628
|
PathUtils,
|
|
46601
|
-
PixelTransform,
|
|
46629
|
+
// PixelTransform,
|
|
46602
46630
|
PointPolygonJoin,
|
|
46603
46631
|
Points,
|
|
46604
46632
|
PointToGrid,
|
package/www/modules.js
CHANGED
|
@@ -20279,6 +20279,7 @@ function pj_phi2(ts, e) {
|
|
|
20279
20279
|
|
|
20280
20280
|
|
|
20281
20281
|
pj_add(pj_merc, 'merc', 'Mercator', 'Cyl, Sph&Ell\nlat_ts=');
|
|
20282
|
+
pj_add(pj_webmerc, 'webmerc', 'Web Mercator / Pseudo Mercator', 'Cyl, Ell');
|
|
20282
20283
|
|
|
20283
20284
|
function pj_merc(P) {
|
|
20284
20285
|
var EPS10 = 1e-10;
|
|
@@ -20333,6 +20334,26 @@ function pj_merc(P) {
|
|
|
20333
20334
|
}
|
|
20334
20335
|
}
|
|
20335
20336
|
|
|
20337
|
+
function pj_webmerc(P) {
|
|
20338
|
+
P.k0 = 1;
|
|
20339
|
+
P.inv = s_inv;
|
|
20340
|
+
P.fwd = s_fwd;
|
|
20341
|
+
|
|
20342
|
+
function s_fwd(lp, xy) {
|
|
20343
|
+
if (fabs(fabs(lp.phi) - M_HALFPI) <= EPS10) {
|
|
20344
|
+
f_error();
|
|
20345
|
+
}
|
|
20346
|
+
xy.x = P.k0 * lp.lam;
|
|
20347
|
+
xy.y = P.k0 * log(tan(M_FORTPI + 0.5 * lp.phi));
|
|
20348
|
+
}
|
|
20349
|
+
|
|
20350
|
+
function s_inv(xy, lp) {
|
|
20351
|
+
lp.phi = M_HALFPI - 2 * atan(exp(-xy.y / P.k0));
|
|
20352
|
+
lp.lam = xy.x / P.k0;
|
|
20353
|
+
}
|
|
20354
|
+
}
|
|
20355
|
+
|
|
20356
|
+
|
|
20336
20357
|
|
|
20337
20358
|
pj_add(pj_mill, 'mill', 'Miller Cylindrical', 'Cyl, Sph');
|
|
20338
20359
|
|
|
@@ -20790,6 +20811,45 @@ var NITER = 9,
|
|
|
20790
20811
|
}
|
|
20791
20812
|
|
|
20792
20813
|
|
|
20814
|
+
pj_add(pj_nicol, 'nicol', 'Nicolosi Globular', 'Misc Sph, no inv');
|
|
20815
|
+
|
|
20816
|
+
function pj_nicol(P) {
|
|
20817
|
+
P.es = 0;
|
|
20818
|
+
P.fwd = s_fwd;
|
|
20819
|
+
|
|
20820
|
+
function s_fwd(lp, xy) {
|
|
20821
|
+
var EPS = 1e-10;
|
|
20822
|
+
if (fabs(lp.lam) < EPS) {
|
|
20823
|
+
xy.x = 0;
|
|
20824
|
+
xy.y = lp.phi;
|
|
20825
|
+
} else if (fabs(lp.phi) < EPS) {
|
|
20826
|
+
xy.x = lp.lam;
|
|
20827
|
+
xy.y = 0;
|
|
20828
|
+
} else if (fabs(fabs(lp.lam) - M_HALFPI) < EPS) {
|
|
20829
|
+
xy.x = lp.lam * cos(lp.phi);
|
|
20830
|
+
xy.y = M_HALFPI * sin(lp.phi);
|
|
20831
|
+
} else if (fabs(fabs(lp.phi) - M_HALFPI) < EPS) {
|
|
20832
|
+
xy.x = 0;
|
|
20833
|
+
xy.y = lp.phi;
|
|
20834
|
+
} else {
|
|
20835
|
+
var tb = M_HALFPI / lp.lam - lp.lam / M_HALFPI;
|
|
20836
|
+
var c = lp.phi / M_HALFPI;
|
|
20837
|
+
var sp = sin(lp.phi);
|
|
20838
|
+
var d = (1 - c * c) / (sp - c);
|
|
20839
|
+
var r2 = tb / d;
|
|
20840
|
+
r2 *= r2;
|
|
20841
|
+
var m = (tb * sp / d - 0.5 * tb) / (1 + r2);
|
|
20842
|
+
var n = (sp / r2 + 0.5 * d) / (1 + 1 / r2);
|
|
20843
|
+
xy.x = cos(lp.phi);
|
|
20844
|
+
xy.x = sqrt(m * m + xy.x * xy.x / (1 + r2));
|
|
20845
|
+
xy.x = M_HALFPI * (m + (lp.lam < 0. ? -xy.x : xy.x));
|
|
20846
|
+
xy.y = sqrt(n * n - (sp * sp / r2 + d * sp - 1) / (1 + 1 / r2));
|
|
20847
|
+
xy.y = M_HALFPI * (n + (lp.phi < 0. ? xy.y : -xy.y));
|
|
20848
|
+
}
|
|
20849
|
+
}
|
|
20850
|
+
}
|
|
20851
|
+
|
|
20852
|
+
|
|
20793
20853
|
pj_add(pj_nsper, 'nsper', 'Near-sided perspective', 'Azi, Sph\nh=');
|
|
20794
20854
|
pj_add(pj_tpers, 'tpers', 'Tilted perspective', 'Azi, Sph\ntilt= azi= h=');
|
|
20795
20855
|
|