mapshaper 0.6.101 → 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 +77 -84
- package/package.json +2 -2
- package/www/mapshaper-gui.js +5 -4
- package/www/mapshaper.js +77 -84
- 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,17 +18528,17 @@
|
|
|
18515
18528
|
|
|
18516
18529
|
|
|
18517
18530
|
function calcFrameData(dataset, opts) {
|
|
18518
|
-
var
|
|
18519
|
-
|
|
18520
|
-
|
|
18521
|
-
bounds = new Bounds(outputBbox);
|
|
18531
|
+
var inputBounds, outputBounds;
|
|
18532
|
+
if (opts.svg_bbox) {
|
|
18533
|
+
inputBounds = new Bounds(opts.svg_bbox);
|
|
18522
18534
|
opts = Object.assign({margin: 0}, opts); // prevent default pixel margin around content
|
|
18523
18535
|
} else {
|
|
18524
|
-
|
|
18536
|
+
inputBounds = getDatasetBounds(dataset);
|
|
18525
18537
|
}
|
|
18526
|
-
|
|
18538
|
+
// side effect: inputBounds may be expanded to add margins
|
|
18539
|
+
outputBounds = calcOutputBounds(inputBounds, opts);
|
|
18527
18540
|
return {
|
|
18528
|
-
bbox:
|
|
18541
|
+
bbox: inputBounds.toArray(),
|
|
18529
18542
|
bbox2: outputBounds.toArray(),
|
|
18530
18543
|
width: Math.round(outputBounds.width()),
|
|
18531
18544
|
height: Math.round(outputBounds.height()) || 1,
|
|
@@ -18533,7 +18546,7 @@
|
|
|
18533
18546
|
};
|
|
18534
18547
|
}
|
|
18535
18548
|
|
|
18536
|
-
// Used by mapshaper-frame
|
|
18549
|
+
// Used by mapshaper-frame TODO: refactor
|
|
18537
18550
|
function getFrameSize(bounds, opts) {
|
|
18538
18551
|
var aspectRatio = bounds.width() / bounds.height();
|
|
18539
18552
|
var height, width;
|
|
@@ -18602,9 +18615,9 @@
|
|
|
18602
18615
|
|
|
18603
18616
|
|
|
18604
18617
|
// bounds: Bounds object containing bounds of content in geographic coordinates
|
|
18605
|
-
// returns Bounds object containing bounds
|
|
18618
|
+
// returns Bounds object containing output bounds
|
|
18606
18619
|
// side effect: bounds param is modified to match the output frame
|
|
18607
|
-
function
|
|
18620
|
+
function calcOutputBounds(bounds, opts) {
|
|
18608
18621
|
var padX = 0,
|
|
18609
18622
|
padY = 0,
|
|
18610
18623
|
offX = 0,
|
|
@@ -18617,65 +18630,59 @@
|
|
|
18617
18630
|
// TODO: add option to tweak alignment of content when both width and height are given
|
|
18618
18631
|
wx = 0.5, // how padding is distributed horizontally (0: left aligned, 0.5: centered, 1: right aligned)
|
|
18619
18632
|
wy = 0.5, // vertical padding distribution
|
|
18620
|
-
|
|
18633
|
+
width2, height2, size2, kx, ky;
|
|
18621
18634
|
|
|
18622
18635
|
if (opts.fit_bbox) {
|
|
18623
18636
|
// scale + shift content to fit within a bbox
|
|
18624
18637
|
offX = opts.fit_bbox[0];
|
|
18625
18638
|
offY = opts.fit_bbox[1];
|
|
18626
|
-
|
|
18627
|
-
|
|
18628
|
-
if (width / height > widthPx / heightPx) {
|
|
18629
|
-
// data is wider than fit box...
|
|
18630
|
-
// scale the data to fit widthwise
|
|
18631
|
-
heightPx = 0;
|
|
18632
|
-
} else {
|
|
18633
|
-
widthPx = 0; // fit the data to the height
|
|
18634
|
-
}
|
|
18639
|
+
width2 = opts.fit_bbox[2] - offX;
|
|
18640
|
+
height2 = opts.fit_bbox[3] - offY;
|
|
18635
18641
|
marginX = marginY = 0; // TODO: support margins
|
|
18636
18642
|
|
|
18637
18643
|
} else if (opts.svg_scale > 0) {
|
|
18638
18644
|
// alternative to using a fixed width (e.g. when generating multiple files
|
|
18639
18645
|
// at a consistent geographic scale)
|
|
18640
|
-
|
|
18641
|
-
|
|
18646
|
+
width2 = width / opts.svg_scale + marginX;
|
|
18647
|
+
height2 = 0;
|
|
18642
18648
|
} else if (+opts.pixels) {
|
|
18643
|
-
|
|
18644
|
-
|
|
18645
|
-
|
|
18649
|
+
size2 = getFrameSize(bounds, opts);
|
|
18650
|
+
width2 = size2[0];
|
|
18651
|
+
height2 = size2[1];
|
|
18646
18652
|
} else {
|
|
18647
|
-
|
|
18648
|
-
|
|
18653
|
+
height2 = opts.height || 0;
|
|
18654
|
+
width2 = opts.width || (height2 > 0 ? 0 : 800); // 800 is default width
|
|
18649
18655
|
}
|
|
18650
18656
|
|
|
18651
|
-
if (
|
|
18657
|
+
if (height2 > 0) {
|
|
18652
18658
|
// vertical meters per pixel to fit height param
|
|
18653
|
-
ky = (height || width || 1) / (
|
|
18659
|
+
ky = (height || width || 1) / (height2 - marginY);
|
|
18654
18660
|
}
|
|
18655
|
-
if (
|
|
18661
|
+
if (width2 > 0) {
|
|
18656
18662
|
// horizontal meters per pixel to fit width param
|
|
18657
|
-
kx = (width || height || 1) / (
|
|
18663
|
+
kx = (width || height || 1) / (width2 - marginX);
|
|
18658
18664
|
}
|
|
18659
18665
|
|
|
18660
|
-
if (!
|
|
18666
|
+
if (!width2) { // height2 and ky are defined, set width to match
|
|
18661
18667
|
kx = ky;
|
|
18662
|
-
|
|
18663
|
-
} 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
|
|
18664
18670
|
ky = kx;
|
|
18665
|
-
|
|
18671
|
+
height2 = height > 0 ? marginY + height / ky : width2;
|
|
18666
18672
|
// limit height if max_height is defined
|
|
18667
|
-
if (opts.max_height > 0 &&
|
|
18668
|
-
ky = kx *
|
|
18669
|
-
|
|
18673
|
+
if (opts.max_height > 0 && height2 > opts.max_height) {
|
|
18674
|
+
ky = kx * height2 / opts.max_height;
|
|
18675
|
+
height2 = opts.max_height;
|
|
18670
18676
|
}
|
|
18671
18677
|
}
|
|
18672
18678
|
|
|
18679
|
+
// add padding, if needed
|
|
18673
18680
|
if (kx > ky) { // content is wide -- need to pad vertically
|
|
18674
18681
|
ky = kx;
|
|
18675
|
-
padY = ky * (
|
|
18682
|
+
padY = ky * (height2 - marginY) - height;
|
|
18676
18683
|
} else if (ky > kx) { // content is tall -- need to pad horizontally
|
|
18677
18684
|
kx = ky;
|
|
18678
|
-
padX = kx * (
|
|
18685
|
+
padX = kx * (width2 - marginX) - width;
|
|
18679
18686
|
}
|
|
18680
18687
|
|
|
18681
18688
|
bounds.padBounds(
|
|
@@ -18684,14 +18691,14 @@
|
|
|
18684
18691
|
margins[2] * kx + padX * (1 - wx),
|
|
18685
18692
|
margins[3] * ky + padY * (1 - wy));
|
|
18686
18693
|
|
|
18687
|
-
if (!(
|
|
18694
|
+
if (!(width2 > 0 && height2 > 0)) {
|
|
18688
18695
|
error("Missing valid height and width parameters");
|
|
18689
18696
|
}
|
|
18690
18697
|
if (!(kx === ky && kx > 0)) {
|
|
18691
18698
|
error("Missing valid margin parameters");
|
|
18692
18699
|
}
|
|
18693
18700
|
|
|
18694
|
-
return new Bounds(offX, offY,
|
|
18701
|
+
return new Bounds(offX, offY, width2 + offX, height2 + offY);
|
|
18695
18702
|
}
|
|
18696
18703
|
|
|
18697
18704
|
function parseMarginOption(opt) {
|
|
@@ -18702,13 +18709,14 @@
|
|
|
18702
18709
|
if (margins.length == 3) margins.push(margins[2]);
|
|
18703
18710
|
return margins.map(function(str) {
|
|
18704
18711
|
var px = parseFloat(str);
|
|
18705
|
-
return isNaN(px) ?
|
|
18712
|
+
return isNaN(px) ? 0 : px; // 0 is default
|
|
18706
18713
|
});
|
|
18707
18714
|
}
|
|
18708
18715
|
|
|
18709
|
-
var
|
|
18716
|
+
var FrameUtils = /*#__PURE__*/Object.freeze({
|
|
18710
18717
|
__proto__: null,
|
|
18711
18718
|
getFrameData: getFrameData,
|
|
18719
|
+
fitDatasetToFrame: fitDatasetToFrame,
|
|
18712
18720
|
getFrameLayerData: getFrameLayerData,
|
|
18713
18721
|
calcFrameData: calcFrameData,
|
|
18714
18722
|
getFrameSize: getFrameSize,
|
|
@@ -18719,7 +18727,7 @@
|
|
|
18719
18727
|
findFrame: findFrame,
|
|
18720
18728
|
getFrameLayerBounds: getFrameLayerBounds,
|
|
18721
18729
|
getMapFrameMetersPerPixel: getMapFrameMetersPerPixel,
|
|
18722
|
-
|
|
18730
|
+
calcOutputBounds: calcOutputBounds,
|
|
18723
18731
|
parseMarginOption: parseMarginOption
|
|
18724
18732
|
});
|
|
18725
18733
|
|
|
@@ -20152,27 +20160,6 @@
|
|
|
20152
20160
|
renderFurnitureLayer: renderFurnitureLayer
|
|
20153
20161
|
});
|
|
20154
20162
|
|
|
20155
|
-
function transformDatasetToPixels(dataset, opts) {
|
|
20156
|
-
var frame = getFrameData(dataset, opts);
|
|
20157
|
-
fitDatasetToFrame(dataset, frame, opts);
|
|
20158
|
-
return [frame.width, frame.height];
|
|
20159
|
-
}
|
|
20160
|
-
|
|
20161
|
-
function fitDatasetToFrame(dataset, frame, opts) {
|
|
20162
|
-
var bounds = new Bounds(frame.bbox);
|
|
20163
|
-
var bounds2 = frame.bbox2 ? new Bounds(frame.bbox2) : new Bounds(0, 0, frame.width, frame.height);
|
|
20164
|
-
var fwd = bounds.getTransform(bounds2, opts.invert_y);
|
|
20165
|
-
transformPoints(dataset, function(x, y) {
|
|
20166
|
-
return fwd.transform(x, y);
|
|
20167
|
-
});
|
|
20168
|
-
}
|
|
20169
|
-
|
|
20170
|
-
var PixelTransform = /*#__PURE__*/Object.freeze({
|
|
20171
|
-
__proto__: null,
|
|
20172
|
-
transformDatasetToPixels: transformDatasetToPixels,
|
|
20173
|
-
fitDatasetToFrame: fitDatasetToFrame
|
|
20174
|
-
});
|
|
20175
|
-
|
|
20176
20163
|
function stringify(obj) {
|
|
20177
20164
|
var svg, joinStr;
|
|
20178
20165
|
if (!obj || !obj.tag) return '';
|
|
@@ -20460,10 +20447,11 @@
|
|
|
20460
20447
|
dataset = copyDataset(dataset); // Modify a copy of the dataset
|
|
20461
20448
|
}
|
|
20462
20449
|
|
|
20463
|
-
// invert_y setting for screen coordinates and geojson polygon generation
|
|
20464
|
-
|
|
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);
|
|
20465
20453
|
frame = getFrameData(dataset, opts);
|
|
20466
|
-
fitDatasetToFrame(dataset, frame
|
|
20454
|
+
fitDatasetToFrame(dataset, frame);
|
|
20467
20455
|
setCoordinatePrecision(dataset, opts.precision || 0.0001);
|
|
20468
20456
|
|
|
20469
20457
|
// error if one or more svg_data fields are not present in any layers
|
|
@@ -22099,10 +22087,14 @@ ${svg}
|
|
|
22099
22087
|
}
|
|
22100
22088
|
|
|
22101
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
|
+
//
|
|
22102
22094
|
opts = utils.defaults({invert_y: true}, opts);
|
|
22103
|
-
|
|
22095
|
+
fitDatasetToFrame(dataset, getFrameData(dataset, opts));
|
|
22104
22096
|
} else if (opts.fit_bbox) {
|
|
22105
|
-
|
|
22097
|
+
fitDatasetToFrame(dataset, getFrameData(dataset, {fit_bbox: opts.fit_bbox}));
|
|
22106
22098
|
}
|
|
22107
22099
|
|
|
22108
22100
|
if (opts.precision && opts.no_quantization) {
|
|
@@ -24311,7 +24303,7 @@ ${svg}
|
|
|
24311
24303
|
describe: 'aspect ratio as a number or range (e.g. 2 0.8,1.6 ,2)'
|
|
24312
24304
|
},
|
|
24313
24305
|
offsetOpt = {
|
|
24314
|
-
describe: '
|
|
24306
|
+
describe: 'offset distance or pct of h/w (single value or l,b,r,t list)',
|
|
24315
24307
|
type: 'distance'
|
|
24316
24308
|
};
|
|
24317
24309
|
|
|
@@ -39353,7 +39345,7 @@ ${svg}
|
|
|
39353
39345
|
// TODO: consider projections that may or may not be aligned,
|
|
39354
39346
|
// depending on parameters
|
|
39355
39347
|
if (inList(P, 'cassini,gnom,bertin1953,chamb,ob_tran,tpeqd,healpix,rhealpix,' +
|
|
39356
|
-
'ocea,omerc,tmerc,etmerc')) {
|
|
39348
|
+
'ocea,omerc,tmerc,etmerc,nicol')) {
|
|
39357
39349
|
return false;
|
|
39358
39350
|
}
|
|
39359
39351
|
if (isAzimuthal(P)) {
|
|
@@ -39928,7 +39920,7 @@ ${svg}
|
|
|
39928
39920
|
}
|
|
39929
39921
|
|
|
39930
39922
|
function isCircleClippedProjection(P) {
|
|
39931
|
-
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');
|
|
39932
39924
|
}
|
|
39933
39925
|
|
|
39934
39926
|
function getPerspectiveClipAngle(P) {
|
|
@@ -39953,6 +39945,7 @@ ${svg}
|
|
|
39953
39945
|
laea: 179,
|
|
39954
39946
|
//ortho: 89.9, // projection errors betwen lat +/-35 to 55
|
|
39955
39947
|
ortho: 89.85, // TODO: investigate
|
|
39948
|
+
nicol: 89.85,
|
|
39956
39949
|
stere: 142,
|
|
39957
39950
|
sterea: 142,
|
|
39958
39951
|
ups: 10.5 // TODO: should be 6.5 deg at north pole
|
|
@@ -45905,7 +45898,7 @@ ${svg}
|
|
|
45905
45898
|
});
|
|
45906
45899
|
}
|
|
45907
45900
|
|
|
45908
|
-
var version = "0.6.
|
|
45901
|
+
var version = "0.6.102";
|
|
45909
45902
|
|
|
45910
45903
|
// Parse command line args into commands and run them
|
|
45911
45904
|
// Function takes an optional Node-style callback. A Promise is returned if no callback is given.
|
|
@@ -46598,7 +46591,7 @@ ${svg}
|
|
|
46598
46591
|
FileTypes,
|
|
46599
46592
|
FilterGeom,
|
|
46600
46593
|
Frame,
|
|
46601
|
-
|
|
46594
|
+
FrameUtils,
|
|
46602
46595
|
Furniture,
|
|
46603
46596
|
Geodesic,
|
|
46604
46597
|
GeojsonExport,
|
|
@@ -46633,7 +46626,7 @@ ${svg}
|
|
|
46633
46626
|
PathImport,
|
|
46634
46627
|
PathRepair,
|
|
46635
46628
|
PathUtils,
|
|
46636
|
-
PixelTransform,
|
|
46629
|
+
// PixelTransform,
|
|
46637
46630
|
PointPolygonJoin,
|
|
46638
46631
|
Points,
|
|
46639
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,17 +18528,17 @@
|
|
|
18515
18528
|
|
|
18516
18529
|
|
|
18517
18530
|
function calcFrameData(dataset, opts) {
|
|
18518
|
-
var
|
|
18519
|
-
|
|
18520
|
-
|
|
18521
|
-
bounds = new Bounds(outputBbox);
|
|
18531
|
+
var inputBounds, outputBounds;
|
|
18532
|
+
if (opts.svg_bbox) {
|
|
18533
|
+
inputBounds = new Bounds(opts.svg_bbox);
|
|
18522
18534
|
opts = Object.assign({margin: 0}, opts); // prevent default pixel margin around content
|
|
18523
18535
|
} else {
|
|
18524
|
-
|
|
18536
|
+
inputBounds = getDatasetBounds(dataset);
|
|
18525
18537
|
}
|
|
18526
|
-
|
|
18538
|
+
// side effect: inputBounds may be expanded to add margins
|
|
18539
|
+
outputBounds = calcOutputBounds(inputBounds, opts);
|
|
18527
18540
|
return {
|
|
18528
|
-
bbox:
|
|
18541
|
+
bbox: inputBounds.toArray(),
|
|
18529
18542
|
bbox2: outputBounds.toArray(),
|
|
18530
18543
|
width: Math.round(outputBounds.width()),
|
|
18531
18544
|
height: Math.round(outputBounds.height()) || 1,
|
|
@@ -18533,7 +18546,7 @@
|
|
|
18533
18546
|
};
|
|
18534
18547
|
}
|
|
18535
18548
|
|
|
18536
|
-
// Used by mapshaper-frame
|
|
18549
|
+
// Used by mapshaper-frame TODO: refactor
|
|
18537
18550
|
function getFrameSize(bounds, opts) {
|
|
18538
18551
|
var aspectRatio = bounds.width() / bounds.height();
|
|
18539
18552
|
var height, width;
|
|
@@ -18602,9 +18615,9 @@
|
|
|
18602
18615
|
|
|
18603
18616
|
|
|
18604
18617
|
// bounds: Bounds object containing bounds of content in geographic coordinates
|
|
18605
|
-
// returns Bounds object containing bounds
|
|
18618
|
+
// returns Bounds object containing output bounds
|
|
18606
18619
|
// side effect: bounds param is modified to match the output frame
|
|
18607
|
-
function
|
|
18620
|
+
function calcOutputBounds(bounds, opts) {
|
|
18608
18621
|
var padX = 0,
|
|
18609
18622
|
padY = 0,
|
|
18610
18623
|
offX = 0,
|
|
@@ -18617,65 +18630,59 @@
|
|
|
18617
18630
|
// TODO: add option to tweak alignment of content when both width and height are given
|
|
18618
18631
|
wx = 0.5, // how padding is distributed horizontally (0: left aligned, 0.5: centered, 1: right aligned)
|
|
18619
18632
|
wy = 0.5, // vertical padding distribution
|
|
18620
|
-
|
|
18633
|
+
width2, height2, size2, kx, ky;
|
|
18621
18634
|
|
|
18622
18635
|
if (opts.fit_bbox) {
|
|
18623
18636
|
// scale + shift content to fit within a bbox
|
|
18624
18637
|
offX = opts.fit_bbox[0];
|
|
18625
18638
|
offY = opts.fit_bbox[1];
|
|
18626
|
-
|
|
18627
|
-
|
|
18628
|
-
if (width / height > widthPx / heightPx) {
|
|
18629
|
-
// data is wider than fit box...
|
|
18630
|
-
// scale the data to fit widthwise
|
|
18631
|
-
heightPx = 0;
|
|
18632
|
-
} else {
|
|
18633
|
-
widthPx = 0; // fit the data to the height
|
|
18634
|
-
}
|
|
18639
|
+
width2 = opts.fit_bbox[2] - offX;
|
|
18640
|
+
height2 = opts.fit_bbox[3] - offY;
|
|
18635
18641
|
marginX = marginY = 0; // TODO: support margins
|
|
18636
18642
|
|
|
18637
18643
|
} else if (opts.svg_scale > 0) {
|
|
18638
18644
|
// alternative to using a fixed width (e.g. when generating multiple files
|
|
18639
18645
|
// at a consistent geographic scale)
|
|
18640
|
-
|
|
18641
|
-
|
|
18646
|
+
width2 = width / opts.svg_scale + marginX;
|
|
18647
|
+
height2 = 0;
|
|
18642
18648
|
} else if (+opts.pixels) {
|
|
18643
|
-
|
|
18644
|
-
|
|
18645
|
-
|
|
18649
|
+
size2 = getFrameSize(bounds, opts);
|
|
18650
|
+
width2 = size2[0];
|
|
18651
|
+
height2 = size2[1];
|
|
18646
18652
|
} else {
|
|
18647
|
-
|
|
18648
|
-
|
|
18653
|
+
height2 = opts.height || 0;
|
|
18654
|
+
width2 = opts.width || (height2 > 0 ? 0 : 800); // 800 is default width
|
|
18649
18655
|
}
|
|
18650
18656
|
|
|
18651
|
-
if (
|
|
18657
|
+
if (height2 > 0) {
|
|
18652
18658
|
// vertical meters per pixel to fit height param
|
|
18653
|
-
ky = (height || width || 1) / (
|
|
18659
|
+
ky = (height || width || 1) / (height2 - marginY);
|
|
18654
18660
|
}
|
|
18655
|
-
if (
|
|
18661
|
+
if (width2 > 0) {
|
|
18656
18662
|
// horizontal meters per pixel to fit width param
|
|
18657
|
-
kx = (width || height || 1) / (
|
|
18663
|
+
kx = (width || height || 1) / (width2 - marginX);
|
|
18658
18664
|
}
|
|
18659
18665
|
|
|
18660
|
-
if (!
|
|
18666
|
+
if (!width2) { // height2 and ky are defined, set width to match
|
|
18661
18667
|
kx = ky;
|
|
18662
|
-
|
|
18663
|
-
} 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
|
|
18664
18670
|
ky = kx;
|
|
18665
|
-
|
|
18671
|
+
height2 = height > 0 ? marginY + height / ky : width2;
|
|
18666
18672
|
// limit height if max_height is defined
|
|
18667
|
-
if (opts.max_height > 0 &&
|
|
18668
|
-
ky = kx *
|
|
18669
|
-
|
|
18673
|
+
if (opts.max_height > 0 && height2 > opts.max_height) {
|
|
18674
|
+
ky = kx * height2 / opts.max_height;
|
|
18675
|
+
height2 = opts.max_height;
|
|
18670
18676
|
}
|
|
18671
18677
|
}
|
|
18672
18678
|
|
|
18679
|
+
// add padding, if needed
|
|
18673
18680
|
if (kx > ky) { // content is wide -- need to pad vertically
|
|
18674
18681
|
ky = kx;
|
|
18675
|
-
padY = ky * (
|
|
18682
|
+
padY = ky * (height2 - marginY) - height;
|
|
18676
18683
|
} else if (ky > kx) { // content is tall -- need to pad horizontally
|
|
18677
18684
|
kx = ky;
|
|
18678
|
-
padX = kx * (
|
|
18685
|
+
padX = kx * (width2 - marginX) - width;
|
|
18679
18686
|
}
|
|
18680
18687
|
|
|
18681
18688
|
bounds.padBounds(
|
|
@@ -18684,14 +18691,14 @@
|
|
|
18684
18691
|
margins[2] * kx + padX * (1 - wx),
|
|
18685
18692
|
margins[3] * ky + padY * (1 - wy));
|
|
18686
18693
|
|
|
18687
|
-
if (!(
|
|
18694
|
+
if (!(width2 > 0 && height2 > 0)) {
|
|
18688
18695
|
error("Missing valid height and width parameters");
|
|
18689
18696
|
}
|
|
18690
18697
|
if (!(kx === ky && kx > 0)) {
|
|
18691
18698
|
error("Missing valid margin parameters");
|
|
18692
18699
|
}
|
|
18693
18700
|
|
|
18694
|
-
return new Bounds(offX, offY,
|
|
18701
|
+
return new Bounds(offX, offY, width2 + offX, height2 + offY);
|
|
18695
18702
|
}
|
|
18696
18703
|
|
|
18697
18704
|
function parseMarginOption(opt) {
|
|
@@ -18702,13 +18709,14 @@
|
|
|
18702
18709
|
if (margins.length == 3) margins.push(margins[2]);
|
|
18703
18710
|
return margins.map(function(str) {
|
|
18704
18711
|
var px = parseFloat(str);
|
|
18705
|
-
return isNaN(px) ?
|
|
18712
|
+
return isNaN(px) ? 0 : px; // 0 is default
|
|
18706
18713
|
});
|
|
18707
18714
|
}
|
|
18708
18715
|
|
|
18709
|
-
var
|
|
18716
|
+
var FrameUtils = /*#__PURE__*/Object.freeze({
|
|
18710
18717
|
__proto__: null,
|
|
18711
18718
|
getFrameData: getFrameData,
|
|
18719
|
+
fitDatasetToFrame: fitDatasetToFrame,
|
|
18712
18720
|
getFrameLayerData: getFrameLayerData,
|
|
18713
18721
|
calcFrameData: calcFrameData,
|
|
18714
18722
|
getFrameSize: getFrameSize,
|
|
@@ -18719,7 +18727,7 @@
|
|
|
18719
18727
|
findFrame: findFrame,
|
|
18720
18728
|
getFrameLayerBounds: getFrameLayerBounds,
|
|
18721
18729
|
getMapFrameMetersPerPixel: getMapFrameMetersPerPixel,
|
|
18722
|
-
|
|
18730
|
+
calcOutputBounds: calcOutputBounds,
|
|
18723
18731
|
parseMarginOption: parseMarginOption
|
|
18724
18732
|
});
|
|
18725
18733
|
|
|
@@ -20152,27 +20160,6 @@
|
|
|
20152
20160
|
renderFurnitureLayer: renderFurnitureLayer
|
|
20153
20161
|
});
|
|
20154
20162
|
|
|
20155
|
-
function transformDatasetToPixels(dataset, opts) {
|
|
20156
|
-
var frame = getFrameData(dataset, opts);
|
|
20157
|
-
fitDatasetToFrame(dataset, frame, opts);
|
|
20158
|
-
return [frame.width, frame.height];
|
|
20159
|
-
}
|
|
20160
|
-
|
|
20161
|
-
function fitDatasetToFrame(dataset, frame, opts) {
|
|
20162
|
-
var bounds = new Bounds(frame.bbox);
|
|
20163
|
-
var bounds2 = frame.bbox2 ? new Bounds(frame.bbox2) : new Bounds(0, 0, frame.width, frame.height);
|
|
20164
|
-
var fwd = bounds.getTransform(bounds2, opts.invert_y);
|
|
20165
|
-
transformPoints(dataset, function(x, y) {
|
|
20166
|
-
return fwd.transform(x, y);
|
|
20167
|
-
});
|
|
20168
|
-
}
|
|
20169
|
-
|
|
20170
|
-
var PixelTransform = /*#__PURE__*/Object.freeze({
|
|
20171
|
-
__proto__: null,
|
|
20172
|
-
transformDatasetToPixels: transformDatasetToPixels,
|
|
20173
|
-
fitDatasetToFrame: fitDatasetToFrame
|
|
20174
|
-
});
|
|
20175
|
-
|
|
20176
20163
|
function stringify(obj) {
|
|
20177
20164
|
var svg, joinStr;
|
|
20178
20165
|
if (!obj || !obj.tag) return '';
|
|
@@ -20460,10 +20447,11 @@
|
|
|
20460
20447
|
dataset = copyDataset(dataset); // Modify a copy of the dataset
|
|
20461
20448
|
}
|
|
20462
20449
|
|
|
20463
|
-
// invert_y setting for screen coordinates and geojson polygon generation
|
|
20464
|
-
|
|
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);
|
|
20465
20453
|
frame = getFrameData(dataset, opts);
|
|
20466
|
-
fitDatasetToFrame(dataset, frame
|
|
20454
|
+
fitDatasetToFrame(dataset, frame);
|
|
20467
20455
|
setCoordinatePrecision(dataset, opts.precision || 0.0001);
|
|
20468
20456
|
|
|
20469
20457
|
// error if one or more svg_data fields are not present in any layers
|
|
@@ -22099,10 +22087,14 @@ ${svg}
|
|
|
22099
22087
|
}
|
|
22100
22088
|
|
|
22101
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
|
+
//
|
|
22102
22094
|
opts = utils.defaults({invert_y: true}, opts);
|
|
22103
|
-
|
|
22095
|
+
fitDatasetToFrame(dataset, getFrameData(dataset, opts));
|
|
22104
22096
|
} else if (opts.fit_bbox) {
|
|
22105
|
-
|
|
22097
|
+
fitDatasetToFrame(dataset, getFrameData(dataset, {fit_bbox: opts.fit_bbox}));
|
|
22106
22098
|
}
|
|
22107
22099
|
|
|
22108
22100
|
if (opts.precision && opts.no_quantization) {
|
|
@@ -24311,7 +24303,7 @@ ${svg}
|
|
|
24311
24303
|
describe: 'aspect ratio as a number or range (e.g. 2 0.8,1.6 ,2)'
|
|
24312
24304
|
},
|
|
24313
24305
|
offsetOpt = {
|
|
24314
|
-
describe: '
|
|
24306
|
+
describe: 'offset distance or pct of h/w (single value or l,b,r,t list)',
|
|
24315
24307
|
type: 'distance'
|
|
24316
24308
|
};
|
|
24317
24309
|
|
|
@@ -39353,7 +39345,7 @@ ${svg}
|
|
|
39353
39345
|
// TODO: consider projections that may or may not be aligned,
|
|
39354
39346
|
// depending on parameters
|
|
39355
39347
|
if (inList(P, 'cassini,gnom,bertin1953,chamb,ob_tran,tpeqd,healpix,rhealpix,' +
|
|
39356
|
-
'ocea,omerc,tmerc,etmerc')) {
|
|
39348
|
+
'ocea,omerc,tmerc,etmerc,nicol')) {
|
|
39357
39349
|
return false;
|
|
39358
39350
|
}
|
|
39359
39351
|
if (isAzimuthal(P)) {
|
|
@@ -39928,7 +39920,7 @@ ${svg}
|
|
|
39928
39920
|
}
|
|
39929
39921
|
|
|
39930
39922
|
function isCircleClippedProjection(P) {
|
|
39931
|
-
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');
|
|
39932
39924
|
}
|
|
39933
39925
|
|
|
39934
39926
|
function getPerspectiveClipAngle(P) {
|
|
@@ -39953,6 +39945,7 @@ ${svg}
|
|
|
39953
39945
|
laea: 179,
|
|
39954
39946
|
//ortho: 89.9, // projection errors betwen lat +/-35 to 55
|
|
39955
39947
|
ortho: 89.85, // TODO: investigate
|
|
39948
|
+
nicol: 89.85,
|
|
39956
39949
|
stere: 142,
|
|
39957
39950
|
sterea: 142,
|
|
39958
39951
|
ups: 10.5 // TODO: should be 6.5 deg at north pole
|
|
@@ -45905,7 +45898,7 @@ ${svg}
|
|
|
45905
45898
|
});
|
|
45906
45899
|
}
|
|
45907
45900
|
|
|
45908
|
-
var version = "0.6.
|
|
45901
|
+
var version = "0.6.102";
|
|
45909
45902
|
|
|
45910
45903
|
// Parse command line args into commands and run them
|
|
45911
45904
|
// Function takes an optional Node-style callback. A Promise is returned if no callback is given.
|
|
@@ -46598,7 +46591,7 @@ ${svg}
|
|
|
46598
46591
|
FileTypes,
|
|
46599
46592
|
FilterGeom,
|
|
46600
46593
|
Frame,
|
|
46601
|
-
|
|
46594
|
+
FrameUtils,
|
|
46602
46595
|
Furniture,
|
|
46603
46596
|
Geodesic,
|
|
46604
46597
|
GeojsonExport,
|
|
@@ -46633,7 +46626,7 @@ ${svg}
|
|
|
46633
46626
|
PathImport,
|
|
46634
46627
|
PathRepair,
|
|
46635
46628
|
PathUtils,
|
|
46636
|
-
PixelTransform,
|
|
46629
|
+
// PixelTransform,
|
|
46637
46630
|
PointPolygonJoin,
|
|
46638
46631
|
Points,
|
|
46639
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
|
|