mapshaper 0.7.15 → 0.7.17
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 +953 -86
- package/package.json +1 -1
- package/www/index.html +8 -32
- package/www/mapshaper-gui.js +2803 -577
- package/www/mapshaper.js +953 -86
- package/www/page.css +406 -18
package/www/mapshaper.js
CHANGED
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
return obj === Object(obj); // via underscore
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
function clamp(val, min, max) {
|
|
81
|
+
function clamp$1(val, min, max) {
|
|
82
82
|
return val < min ? min : (val > max ? max : val);
|
|
83
83
|
}
|
|
84
84
|
|
|
@@ -751,7 +751,7 @@
|
|
|
751
751
|
function findValueByRank(arr, rank) {
|
|
752
752
|
if (!arr.length || rank < 1 || rank > arr.length) error$1("[findValueByRank()] invalid input");
|
|
753
753
|
|
|
754
|
-
rank = clamp(rank | 0, 1, arr.length);
|
|
754
|
+
rank = clamp$1(rank | 0, 1, arr.length);
|
|
755
755
|
var k = rank - 1, // conv. rank to array index
|
|
756
756
|
n = arr.length,
|
|
757
757
|
l = 0,
|
|
@@ -1125,7 +1125,7 @@
|
|
|
1125
1125
|
// self-import and the resulting Rollup circular-dependency warning.
|
|
1126
1126
|
var utils = {
|
|
1127
1127
|
addThousandsSep, addslashes, arrayToIndex,
|
|
1128
|
-
clamp, cleanNumericString, contains, copyElements, countValues, createBuffer,
|
|
1128
|
+
clamp: clamp$1, cleanNumericString, contains, copyElements, countValues, createBuffer,
|
|
1129
1129
|
defaults, difference,
|
|
1130
1130
|
endsWith, every, expandoBuffer, extend: extend$1, extendBuffer,
|
|
1131
1131
|
find: find$1, findMedian, findQuantile, findRankByValue, findStringPrefix,
|
|
@@ -1298,7 +1298,7 @@
|
|
|
1298
1298
|
}
|
|
1299
1299
|
}
|
|
1300
1300
|
|
|
1301
|
-
function timeEnd(slug) {
|
|
1301
|
+
function timeEnd$1(slug) {
|
|
1302
1302
|
if (useDebug()) {
|
|
1303
1303
|
console.timeEnd(slug);
|
|
1304
1304
|
}
|
|
@@ -1424,7 +1424,7 @@
|
|
|
1424
1424
|
setLoggingFunctions: setLoggingFunctions,
|
|
1425
1425
|
stop: stop$1,
|
|
1426
1426
|
time: time,
|
|
1427
|
-
timeEnd: timeEnd,
|
|
1427
|
+
timeEnd: timeEnd$1,
|
|
1428
1428
|
truncateString: truncateString,
|
|
1429
1429
|
useDebug: useDebug,
|
|
1430
1430
|
useVerbose: useVerbose,
|
|
@@ -4776,7 +4776,18 @@
|
|
|
4776
4776
|
pathIsRectangle: pathIsRectangle
|
|
4777
4777
|
});
|
|
4778
4778
|
|
|
4779
|
+
function runningInBrowser() {
|
|
4780
|
+
return typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
4781
|
+
}
|
|
4782
|
+
|
|
4783
|
+
var Env = /*#__PURE__*/Object.freeze({
|
|
4784
|
+
__proto__: null,
|
|
4785
|
+
runningInBrowser: runningInBrowser
|
|
4786
|
+
});
|
|
4787
|
+
|
|
4779
4788
|
var DEFAULT_MAX_PREVIEW_PIXELS = 4e6;
|
|
4789
|
+
var MAX_EXACT_AVERAGE_PIXELS = 256;
|
|
4790
|
+
var MAX_APPROX_AVERAGE_STEPS = 16;
|
|
4780
4791
|
|
|
4781
4792
|
function getRasterGrid(raster) {
|
|
4782
4793
|
return raster && (raster.grid || raster);
|
|
@@ -4922,6 +4933,13 @@
|
|
|
4922
4933
|
});
|
|
4923
4934
|
}
|
|
4924
4935
|
|
|
4936
|
+
function renderRasterExportPreview(raster, bbox, width, height, opts) {
|
|
4937
|
+
var grid = getRasterGrid(raster);
|
|
4938
|
+
var recipe = getRasterViewRecipe(grid, raster.view && raster.view.recipe, opts);
|
|
4939
|
+
var stats = getRasterViewScalingStats(raster, recipe);
|
|
4940
|
+
return renderRasterGridPreview(grid, recipe, width, height, stats, bbox, getRasterExportResamplingMethod(grid, bbox, width, height));
|
|
4941
|
+
}
|
|
4942
|
+
|
|
4925
4943
|
function getRasterScalingStats(grid, recipe) {
|
|
4926
4944
|
recipe = getRasterViewRecipe(grid, recipe);
|
|
4927
4945
|
return getScalingStats(grid.samples, grid.bands, grid.nodata, recipe);
|
|
@@ -4946,7 +4964,7 @@
|
|
|
4946
4964
|
return stats;
|
|
4947
4965
|
}
|
|
4948
4966
|
|
|
4949
|
-
function renderRasterGridPreview(grid, recipe, width, height, statsArg, sourceBbox) {
|
|
4967
|
+
function renderRasterGridPreview(grid, recipe, width, height, statsArg, sourceBbox, resamplingMethod) {
|
|
4950
4968
|
var samples = grid.samples;
|
|
4951
4969
|
var bands = grid.bands;
|
|
4952
4970
|
var noData = grid.nodata;
|
|
@@ -4954,23 +4972,29 @@
|
|
|
4954
4972
|
var stats = statsArg || getScalingStats(samples, bands, noData, recipe);
|
|
4955
4973
|
var sourceRange = recipe.scaling == 'none' ? getPixelTypeRange(grid.pixelType) : null;
|
|
4956
4974
|
var displayRange = getDisplayRange(recipe.scaleRange);
|
|
4957
|
-
var src, dest, val, isNoData, j;
|
|
4975
|
+
var src, dest, val, isNoData, j, sample;
|
|
4958
4976
|
for (var y = 0; y < height; y++) {
|
|
4959
4977
|
for (var x = 0; x < width; x++) {
|
|
4960
|
-
src = getPreviewSourceOffset(grid, sourceBbox, x, y, width, height, bands);
|
|
4961
4978
|
dest = (y * width + x) * 4;
|
|
4962
|
-
|
|
4979
|
+
if (resamplingMethod) {
|
|
4980
|
+
sample = getResampledRasterSample(grid, sourceBbox, x, y, width, height, resamplingMethod);
|
|
4981
|
+
isNoData = !sample.valid;
|
|
4982
|
+
} else {
|
|
4983
|
+
src = getPreviewSourceOffset(grid, sourceBbox, x, y, width, height, bands);
|
|
4984
|
+
sample = null;
|
|
4985
|
+
isNoData = noData !== null && noData !== undefined && allSamplesAreNoData(samples, src, bands, noData);
|
|
4986
|
+
}
|
|
4963
4987
|
if (bands == 1) {
|
|
4964
|
-
val = scaleSample(samples[src], stats && stats[0], sourceRange, displayRange);
|
|
4988
|
+
val = scaleSample(sample ? sample.values[0] : samples[src], stats && stats[0], sourceRange, displayRange);
|
|
4965
4989
|
pixels[dest] = val;
|
|
4966
4990
|
pixels[dest + 1] = val;
|
|
4967
4991
|
pixels[dest + 2] = val;
|
|
4968
4992
|
pixels[dest + 3] = isNoData ? 0 : 255;
|
|
4969
4993
|
} else {
|
|
4970
4994
|
for (j = 0; j < 3; j++) {
|
|
4971
|
-
pixels[dest + j] = scaleSample(samples[src + j], stats && stats[j], sourceRange, displayRange);
|
|
4995
|
+
pixels[dest + j] = scaleSample(sample ? sample.values[j] : samples[src + j], stats && stats[j], sourceRange, displayRange);
|
|
4972
4996
|
}
|
|
4973
|
-
pixels[dest + 3] = isNoData ? 0 : bands >= 4 ? scaleSample(samples[src + 3], stats && stats[3], sourceRange, [0, 255]) : 255;
|
|
4997
|
+
pixels[dest + 3] = isNoData ? 0 : bands >= 4 ? scaleSample(sample ? sample.values[3] : samples[src + 3], stats && stats[3], sourceRange, [0, 255]) : 255;
|
|
4974
4998
|
}
|
|
4975
4999
|
}
|
|
4976
5000
|
}
|
|
@@ -4984,6 +5008,156 @@
|
|
|
4984
5008
|
};
|
|
4985
5009
|
}
|
|
4986
5010
|
|
|
5011
|
+
function getRasterExportResamplingMethod(grid, bbox, width, height) {
|
|
5012
|
+
var srcSize = getRasterSourcePixelSize(grid, bbox);
|
|
5013
|
+
return width < srcSize.width || height < srcSize.height ? 'average' : 'bilinear';
|
|
5014
|
+
}
|
|
5015
|
+
|
|
5016
|
+
function getRasterSourcePixelSize(grid, bbox) {
|
|
5017
|
+
var rb = grid.bbox;
|
|
5018
|
+
return {
|
|
5019
|
+
width: Math.abs((bbox[2] - bbox[0]) / (rb[2] - rb[0]) * grid.width),
|
|
5020
|
+
height: Math.abs((bbox[3] - bbox[1]) / (rb[3] - rb[1]) * grid.height)
|
|
5021
|
+
};
|
|
5022
|
+
}
|
|
5023
|
+
|
|
5024
|
+
function getResampledRasterSample(grid, bbox, x, y, width, height, method) {
|
|
5025
|
+
return method == 'average' ?
|
|
5026
|
+
getAverageRasterSample(grid, bbox, x, y, width, height) :
|
|
5027
|
+
getBilinearRasterSample(grid, bbox, x, y, width, height);
|
|
5028
|
+
}
|
|
5029
|
+
|
|
5030
|
+
function getAverageRasterSample(grid, bbox, x, y, width, height) {
|
|
5031
|
+
var bounds = getRasterSourcePixelBounds(grid, bbox, x, y, width, height);
|
|
5032
|
+
if (getSourcePixelBoundsArea(bounds) > MAX_EXACT_AVERAGE_PIXELS) {
|
|
5033
|
+
return getApproxAverageRasterSample(grid, bounds);
|
|
5034
|
+
}
|
|
5035
|
+
var samples = grid.samples;
|
|
5036
|
+
var bands = grid.bands;
|
|
5037
|
+
var values = new Array(bands).fill(0);
|
|
5038
|
+
var total = 0;
|
|
5039
|
+
var src, weight;
|
|
5040
|
+
var x0 = Math.max(0, Math.floor(bounds.x0));
|
|
5041
|
+
var x1 = Math.min(grid.width, Math.ceil(bounds.x1));
|
|
5042
|
+
var y0 = Math.max(0, Math.floor(bounds.y0));
|
|
5043
|
+
var y1 = Math.min(grid.height, Math.ceil(bounds.y1));
|
|
5044
|
+
for (var sy = y0; sy < y1; sy++) {
|
|
5045
|
+
for (var sx = x0; sx < x1; sx++) {
|
|
5046
|
+
weight = getIntervalOverlap(bounds.x0, bounds.x1, sx, sx + 1) *
|
|
5047
|
+
getIntervalOverlap(bounds.y0, bounds.y1, sy, sy + 1);
|
|
5048
|
+
if (weight <= 0) continue;
|
|
5049
|
+
src = (sy * grid.width + sx) * bands;
|
|
5050
|
+
if (sampleIsNoData(samples, src, bands, grid.nodata)) continue;
|
|
5051
|
+
for (var band = 0; band < bands; band++) {
|
|
5052
|
+
values[band] += samples[src + band] * weight;
|
|
5053
|
+
}
|
|
5054
|
+
total += weight;
|
|
5055
|
+
}
|
|
5056
|
+
}
|
|
5057
|
+
if (total <= 0) return {valid: false, values: values};
|
|
5058
|
+
for (var i = 0; i < bands; i++) values[i] /= total;
|
|
5059
|
+
return {valid: true, values: values};
|
|
5060
|
+
}
|
|
5061
|
+
|
|
5062
|
+
function getApproxAverageRasterSample(grid, bounds) {
|
|
5063
|
+
var samples = grid.samples;
|
|
5064
|
+
var bands = grid.bands;
|
|
5065
|
+
var values = new Array(bands).fill(0);
|
|
5066
|
+
var xSteps = Math.min(MAX_APPROX_AVERAGE_STEPS, Math.max(1, Math.ceil(Math.abs(bounds.x1 - bounds.x0))));
|
|
5067
|
+
var ySteps = Math.min(MAX_APPROX_AVERAGE_STEPS, Math.max(1, Math.ceil(Math.abs(bounds.y1 - bounds.y0))));
|
|
5068
|
+
var count = 0;
|
|
5069
|
+
var sx, sy, src;
|
|
5070
|
+
for (var y = 0; y < ySteps; y++) {
|
|
5071
|
+
for (var x = 0; x < xSteps; x++) {
|
|
5072
|
+
sx = Math.max(0, Math.min(grid.width - 1, Math.floor(bounds.x0 + (x + 0.5) / xSteps * (bounds.x1 - bounds.x0))));
|
|
5073
|
+
sy = Math.max(0, Math.min(grid.height - 1, Math.floor(bounds.y0 + (y + 0.5) / ySteps * (bounds.y1 - bounds.y0))));
|
|
5074
|
+
src = (sy * grid.width + sx) * bands;
|
|
5075
|
+
if (sampleIsNoData(samples, src, bands, grid.nodata)) continue;
|
|
5076
|
+
for (var band = 0; band < bands; band++) {
|
|
5077
|
+
values[band] += samples[src + band];
|
|
5078
|
+
}
|
|
5079
|
+
count++;
|
|
5080
|
+
}
|
|
5081
|
+
}
|
|
5082
|
+
if (count === 0) return {valid: false, values: values};
|
|
5083
|
+
for (var i = 0; i < bands; i++) values[i] /= count;
|
|
5084
|
+
return {valid: true, values: values};
|
|
5085
|
+
}
|
|
5086
|
+
|
|
5087
|
+
function getBilinearRasterSample(grid, bbox, x, y, width, height) {
|
|
5088
|
+
var p = getRasterSourcePixelCenter(grid, bbox, x, y, width, height);
|
|
5089
|
+
var x0 = Math.max(0, Math.min(grid.width - 1, Math.floor(p.x)));
|
|
5090
|
+
var y0 = Math.max(0, Math.min(grid.height - 1, Math.floor(p.y)));
|
|
5091
|
+
var x1 = Math.max(0, Math.min(grid.width - 1, x0 + 1));
|
|
5092
|
+
var y1 = Math.max(0, Math.min(grid.height - 1, y0 + 1));
|
|
5093
|
+
var tx = Math.max(0, Math.min(1, p.x - x0));
|
|
5094
|
+
var ty = Math.max(0, Math.min(1, p.y - y0));
|
|
5095
|
+
var samples = grid.samples;
|
|
5096
|
+
var bands = grid.bands;
|
|
5097
|
+
var values = new Array(bands).fill(0);
|
|
5098
|
+
var offsets = [
|
|
5099
|
+
(y0 * grid.width + x0) * bands,
|
|
5100
|
+
(y0 * grid.width + x1) * bands,
|
|
5101
|
+
(y1 * grid.width + x0) * bands,
|
|
5102
|
+
(y1 * grid.width + x1) * bands
|
|
5103
|
+
];
|
|
5104
|
+
var weights = [
|
|
5105
|
+
(1 - tx) * (1 - ty),
|
|
5106
|
+
tx * (1 - ty),
|
|
5107
|
+
(1 - tx) * ty,
|
|
5108
|
+
tx * ty
|
|
5109
|
+
];
|
|
5110
|
+
var total = 0;
|
|
5111
|
+
offsets.forEach(function(src, i) {
|
|
5112
|
+
if (weights[i] <= 0 || sampleIsNoData(samples, src, bands, grid.nodata)) return;
|
|
5113
|
+
for (var band = 0; band < bands; band++) {
|
|
5114
|
+
values[band] += samples[src + band] * weights[i];
|
|
5115
|
+
}
|
|
5116
|
+
total += weights[i];
|
|
5117
|
+
});
|
|
5118
|
+
if (total <= 0) return {valid: false, values: values};
|
|
5119
|
+
for (var j = 0; j < bands; j++) values[j] /= total;
|
|
5120
|
+
return {valid: true, values: values};
|
|
5121
|
+
}
|
|
5122
|
+
|
|
5123
|
+
function getRasterSourcePixelBounds(grid, bbox, x, y, width, height) {
|
|
5124
|
+
return {
|
|
5125
|
+
x0: mapXToRasterPixel(grid, bbox[0] + x / width * (bbox[2] - bbox[0])),
|
|
5126
|
+
x1: mapXToRasterPixel(grid, bbox[0] + (x + 1) / width * (bbox[2] - bbox[0])),
|
|
5127
|
+
y0: mapYToRasterPixel(grid, bbox[3] - y / height * (bbox[3] - bbox[1])),
|
|
5128
|
+
y1: mapYToRasterPixel(grid, bbox[3] - (y + 1) / height * (bbox[3] - bbox[1]))
|
|
5129
|
+
};
|
|
5130
|
+
}
|
|
5131
|
+
|
|
5132
|
+
function getRasterSourcePixelCenter(grid, bbox, x, y, width, height) {
|
|
5133
|
+
var mapX = bbox[0] + (x + 0.5) / width * (bbox[2] - bbox[0]);
|
|
5134
|
+
var mapY = bbox[3] - (y + 0.5) / height * (bbox[3] - bbox[1]);
|
|
5135
|
+
return {
|
|
5136
|
+
x: mapXToRasterPixel(grid, mapX) - 0.5,
|
|
5137
|
+
y: mapYToRasterPixel(grid, mapY) - 0.5
|
|
5138
|
+
};
|
|
5139
|
+
}
|
|
5140
|
+
|
|
5141
|
+
function mapXToRasterPixel(grid, x) {
|
|
5142
|
+
return (x - grid.bbox[0]) / (grid.bbox[2] - grid.bbox[0]) * grid.width;
|
|
5143
|
+
}
|
|
5144
|
+
|
|
5145
|
+
function mapYToRasterPixel(grid, y) {
|
|
5146
|
+
return (grid.bbox[3] - y) / (grid.bbox[3] - grid.bbox[1]) * grid.height;
|
|
5147
|
+
}
|
|
5148
|
+
|
|
5149
|
+
function getIntervalOverlap(a0, a1, b0, b1) {
|
|
5150
|
+
return Math.max(0, Math.min(Math.max(a0, a1), b1) - Math.max(Math.min(a0, a1), b0));
|
|
5151
|
+
}
|
|
5152
|
+
|
|
5153
|
+
function getSourcePixelBoundsArea(bounds) {
|
|
5154
|
+
return Math.abs((bounds.x1 - bounds.x0) * (bounds.y1 - bounds.y0));
|
|
5155
|
+
}
|
|
5156
|
+
|
|
5157
|
+
function sampleIsNoData(samples, offset, bands, noData) {
|
|
5158
|
+
return noData !== null && noData !== undefined && allSamplesAreNoData(samples, offset, bands, noData);
|
|
5159
|
+
}
|
|
5160
|
+
|
|
4987
5161
|
function renderRawEightBitPreview(grid, width, height, sourceBbox) {
|
|
4988
5162
|
var samples = grid.samples;
|
|
4989
5163
|
var bands = grid.bands;
|
|
@@ -5048,7 +5222,12 @@
|
|
|
5048
5222
|
noteLayerWillChange(lyr, {operation: 'clipRasterToBBox', unit: 'raster'});
|
|
5049
5223
|
raster.grid = cropRasterGrid(grid, crop, clipBbox);
|
|
5050
5224
|
raster.view = raster.view || {};
|
|
5051
|
-
raster.view.
|
|
5225
|
+
delete raster.view.scalingStats;
|
|
5226
|
+
if (runningInBrowser()) {
|
|
5227
|
+
raster.view.preview = createRasterPreview(raster, opts || {});
|
|
5228
|
+
} else {
|
|
5229
|
+
delete raster.view.preview;
|
|
5230
|
+
}
|
|
5052
5231
|
clearLegacyRasterFields(raster);
|
|
5053
5232
|
markLayerChanged(lyr, {operation: 'clipRasterToBBox', unit: 'raster'});
|
|
5054
5233
|
return true;
|
|
@@ -5393,6 +5572,7 @@
|
|
|
5393
5572
|
getRasterViewScalingStats: getRasterViewScalingStats,
|
|
5394
5573
|
getRasterWidth: getRasterWidth,
|
|
5395
5574
|
intersectBboxes: intersectBboxes,
|
|
5575
|
+
renderRasterExportPreview: renderRasterExportPreview,
|
|
5396
5576
|
renderRasterPreview: renderRasterPreview,
|
|
5397
5577
|
renderRasterViewportPreview: renderRasterViewportPreview,
|
|
5398
5578
|
requireRasterLayer: requireRasterLayer
|
|
@@ -10775,15 +10955,6 @@
|
|
|
10775
10955
|
return files;
|
|
10776
10956
|
}
|
|
10777
10957
|
|
|
10778
|
-
function runningInBrowser() {
|
|
10779
|
-
return typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
10780
|
-
}
|
|
10781
|
-
|
|
10782
|
-
var Env = /*#__PURE__*/Object.freeze({
|
|
10783
|
-
__proto__: null,
|
|
10784
|
-
runningInBrowser: runningInBrowser
|
|
10785
|
-
});
|
|
10786
|
-
|
|
10787
10958
|
// input: A file path or a buffer
|
|
10788
10959
|
function unzipSync(input) {
|
|
10789
10960
|
if (input instanceof ArrayBuffer) {
|
|
@@ -18424,6 +18595,7 @@
|
|
|
18424
18595
|
icon: null,
|
|
18425
18596
|
'icon-color': 'color',
|
|
18426
18597
|
'icon-size': 'number',
|
|
18598
|
+
'label-pos': 'labelposition',
|
|
18427
18599
|
'label-text': null, // leaving this null
|
|
18428
18600
|
'letter-spacing': 'measure',
|
|
18429
18601
|
'line-height': 'measure',
|
|
@@ -18475,6 +18647,20 @@
|
|
|
18475
18647
|
'fill,font-family,font-size,text-anchor,font-weight,font-style,font-stretch,letter-spacing,dominant-baseline'.split(',')))
|
|
18476
18648
|
};
|
|
18477
18649
|
|
|
18650
|
+
var labelPositionFields = ['label-pos', 'dx', 'dy', 'text-anchor'];
|
|
18651
|
+
|
|
18652
|
+
var labelPositionStyles = {
|
|
18653
|
+
n: {dx: 0, dy: '-0.45em', 'text-anchor': 'middle'},
|
|
18654
|
+
s: {dx: 0, dy: '1.05em', 'text-anchor': 'middle'},
|
|
18655
|
+
e: {dx: '0.4em', dy: '0.25em', 'text-anchor': 'start'},
|
|
18656
|
+
w: {dx: '-0.4em', dy: '0.25em', 'text-anchor': 'end'},
|
|
18657
|
+
ne: {dx: '0.35em', dy: '-0.15em', 'text-anchor': 'start'},
|
|
18658
|
+
se: {dx: '0.35em', dy: '0.7em', 'text-anchor': 'start'},
|
|
18659
|
+
nw: {dx: '-0.35em', dy: '-0.15em', 'text-anchor': 'end'},
|
|
18660
|
+
sw: {dx: '-0.35em', dy: '0.7em', 'text-anchor': 'end'},
|
|
18661
|
+
c: {dx: 0, dy: '0.25em', 'text-anchor': 'middle'}
|
|
18662
|
+
};
|
|
18663
|
+
|
|
18478
18664
|
// symType: point, polygon, polyline, label
|
|
18479
18665
|
function applyStyleAttributes(svgObj, symType, rec, filter) {
|
|
18480
18666
|
var fields = findStylePropertiesBySymbolGeom(Object.keys(rec || {}), symType);
|
|
@@ -18606,6 +18792,8 @@
|
|
|
18606
18792
|
val = parseBoolean(strVal);
|
|
18607
18793
|
} else if (type == 'inlinecss') {
|
|
18608
18794
|
val = strVal; // TODO: validate
|
|
18795
|
+
} else if (type == 'labelposition') {
|
|
18796
|
+
val = parseLabelPosition(strVal);
|
|
18609
18797
|
}
|
|
18610
18798
|
// else {
|
|
18611
18799
|
// // unknown type -- assume literal value
|
|
@@ -18637,6 +18825,26 @@
|
|
|
18637
18825
|
return null;
|
|
18638
18826
|
}
|
|
18639
18827
|
|
|
18828
|
+
function parseLabelPosition(str) {
|
|
18829
|
+
var pos = String(str).trim();
|
|
18830
|
+
return /^(n|s|e|w|ne|se|nw|sw|c)$/i.test(pos) ? pos : null;
|
|
18831
|
+
}
|
|
18832
|
+
|
|
18833
|
+
function getLabelPositionStyle(pos) {
|
|
18834
|
+
pos = parseLabelPosition(pos);
|
|
18835
|
+
if (!pos) return null;
|
|
18836
|
+
return Object.assign({'label-pos': pos}, labelPositionStyles[pos.toLowerCase()]);
|
|
18837
|
+
}
|
|
18838
|
+
|
|
18839
|
+
function setLabelPositionStyle(rec, pos) {
|
|
18840
|
+
var style = getLabelPositionStyle(pos);
|
|
18841
|
+
if (!style) return false;
|
|
18842
|
+
labelPositionFields.forEach(function(field) {
|
|
18843
|
+
rec[field] = style[field];
|
|
18844
|
+
});
|
|
18845
|
+
return true;
|
|
18846
|
+
}
|
|
18847
|
+
|
|
18640
18848
|
function isSvgMeasure(o) {
|
|
18641
18849
|
return utils.isFiniteNumber(o) || utils.isString(o) && /^-?[.0-9]+[a-z]*$/.test(o);
|
|
18642
18850
|
}
|
|
@@ -18655,6 +18863,7 @@
|
|
|
18655
18863
|
__proto__: null,
|
|
18656
18864
|
applyStyleAttributes: applyStyleAttributes,
|
|
18657
18865
|
findStylePropertiesBySymbolGeom: findStylePropertiesBySymbolGeom,
|
|
18866
|
+
getLabelPositionStyle: getLabelPositionStyle,
|
|
18658
18867
|
getSymbolDataAccessor: getSymbolDataAccessor,
|
|
18659
18868
|
getSymbolPropertyAccessor: getSymbolPropertyAccessor,
|
|
18660
18869
|
isSupportedSvgStyleProperty: isSupportedSvgStyleProperty,
|
|
@@ -18662,9 +18871,12 @@
|
|
|
18662
18871
|
isSvgColor: isSvgColor,
|
|
18663
18872
|
isSvgMeasure: isSvgMeasure,
|
|
18664
18873
|
isSvgNumber: isSvgNumber,
|
|
18874
|
+
labelPositionFields: labelPositionFields,
|
|
18665
18875
|
mightBeExpression: mightBeExpression,
|
|
18666
18876
|
parseBoolean: parseBoolean,
|
|
18667
|
-
|
|
18877
|
+
parseLabelPosition: parseLabelPosition,
|
|
18878
|
+
parseSvgMeasure: parseSvgMeasure,
|
|
18879
|
+
setLabelPositionStyle: setLabelPositionStyle
|
|
18668
18880
|
});
|
|
18669
18881
|
|
|
18670
18882
|
function toLabelString(val) {
|
|
@@ -18786,7 +18998,7 @@
|
|
|
18786
18998
|
|
|
18787
18999
|
function renderIcon(d) {
|
|
18788
19000
|
var type = d.icon || 'circle';
|
|
18789
|
-
var r = getIconRadius(d);
|
|
19001
|
+
var r = getIconRadius(d, type);
|
|
18790
19002
|
if (r > 0 === false) return empty();
|
|
18791
19003
|
if (type == 'circle') return circle(getIconStyleData(d, r));
|
|
18792
19004
|
if (type == 'square') return square(getIconStyleData(d, r), 0, 0);
|
|
@@ -18796,10 +19008,18 @@
|
|
|
18796
19008
|
return empty();
|
|
18797
19009
|
}
|
|
18798
19010
|
|
|
18799
|
-
function getIconRadius(d) {
|
|
18800
|
-
|
|
18801
|
-
if (d
|
|
18802
|
-
|
|
19011
|
+
function getIconRadius(d, type) {
|
|
19012
|
+
var size;
|
|
19013
|
+
if (d['icon-size'] > 0 === false) {
|
|
19014
|
+
return d.r > 0 ? d.r : 5;
|
|
19015
|
+
}
|
|
19016
|
+
size = d['icon-size'];
|
|
19017
|
+
if (type == 'circle' || type == 'ring') {
|
|
19018
|
+
size -= 1;
|
|
19019
|
+
} else if (type == 'star') {
|
|
19020
|
+
size += 1;
|
|
19021
|
+
}
|
|
19022
|
+
return size / 2;
|
|
18803
19023
|
}
|
|
18804
19024
|
|
|
18805
19025
|
function getIconStyleData(d, r) {
|
|
@@ -19819,15 +20039,15 @@ ${svg}
|
|
|
19819
20039
|
|
|
19820
20040
|
function exportRasterLayerForSVG(lyr, frame, opts) {
|
|
19821
20041
|
var raster = lyr.raster;
|
|
19822
|
-
var
|
|
19823
|
-
var bbox = transformRasterBboxForSVG(
|
|
20042
|
+
var rendered = renderRasterForSVG(raster, frame, opts);
|
|
20043
|
+
var bbox = transformRasterBboxForSVG(rendered.bbox, frame);
|
|
19824
20044
|
var href;
|
|
19825
20045
|
var layerObj = getEmptyLayerForSVG(lyr, opts);
|
|
19826
|
-
if (!
|
|
20046
|
+
if (!rendered.preview.width || !rendered.preview.height) {
|
|
19827
20047
|
layerObj.children = [];
|
|
19828
20048
|
return layerObj;
|
|
19829
20049
|
}
|
|
19830
|
-
href = encodeRasterPreview(
|
|
20050
|
+
href = encodeRasterPreview(rendered.preview, opts);
|
|
19831
20051
|
layerObj.children = [{
|
|
19832
20052
|
tag: 'image',
|
|
19833
20053
|
properties: {
|
|
@@ -19842,50 +20062,47 @@ ${svg}
|
|
|
19842
20062
|
return layerObj;
|
|
19843
20063
|
}
|
|
19844
20064
|
|
|
19845
|
-
function
|
|
20065
|
+
function renderRasterForSVG(raster, frame, opts) {
|
|
19846
20066
|
var rasterBbox = getRasterBBox(raster);
|
|
19847
|
-
var preview = getRasterPreview(raster);
|
|
19848
20067
|
var rasterBounds = new Bounds(rasterBbox);
|
|
19849
20068
|
var clipBounds = new Bounds(frame.bbox);
|
|
19850
20069
|
var bbox = intersectBboxes(rasterBounds.toArray(), clipBounds.toArray()) || [0, 0, 0, 0];
|
|
19851
|
-
var
|
|
20070
|
+
var svgBbox = transformRasterBboxForSVG(bbox, frame);
|
|
20071
|
+
var size = getSvgRasterOutputSize(raster, bbox, svgBbox, opts);
|
|
19852
20072
|
return {
|
|
19853
20073
|
bbox: bbox,
|
|
19854
|
-
preview:
|
|
20074
|
+
preview: size.width > 0 && size.height > 0 ?
|
|
20075
|
+
renderRasterExportPreview(raster, bbox, size.width, size.height, opts) :
|
|
20076
|
+
{width: 0, height: 0, pixels: new Uint8ClampedArray(0)}
|
|
19855
20077
|
};
|
|
19856
20078
|
}
|
|
19857
20079
|
|
|
19858
|
-
function
|
|
19859
|
-
var
|
|
19860
|
-
var
|
|
19861
|
-
var
|
|
19862
|
-
var
|
|
19863
|
-
var
|
|
19864
|
-
var
|
|
20080
|
+
function getSvgRasterOutputSize(raster, bbox, svgBbox, opts) {
|
|
20081
|
+
var res = getSvgRasterResolution(opts);
|
|
20082
|
+
var sourceSize = getRasterSourceSize(raster, bbox);
|
|
20083
|
+
var svgWidth = Math.abs(svgBbox[2] - svgBbox[0]);
|
|
20084
|
+
var svgHeight = Math.abs(svgBbox[3] - svgBbox[1]);
|
|
20085
|
+
var width = svgWidth > 0 ? Math.max(1, Math.round(svgWidth * res)) : 0;
|
|
20086
|
+
var height = svgHeight > 0 ? Math.max(1, Math.round(svgHeight * res)) : 0;
|
|
19865
20087
|
return {
|
|
19866
|
-
|
|
19867
|
-
|
|
19868
|
-
width: Math.max(0, x1 - x0),
|
|
19869
|
-
height: Math.max(0, y1 - y0)
|
|
20088
|
+
width: Math.max(0, Math.min(Math.max(1, Math.ceil(sourceSize.width)), width)),
|
|
20089
|
+
height: Math.max(0, Math.min(Math.max(1, Math.ceil(sourceSize.height)), height))
|
|
19870
20090
|
};
|
|
19871
20091
|
}
|
|
19872
20092
|
|
|
19873
|
-
function
|
|
19874
|
-
|
|
19875
|
-
|
|
19876
|
-
|
|
19877
|
-
|
|
19878
|
-
|
|
19879
|
-
|
|
19880
|
-
|
|
19881
|
-
|
|
19882
|
-
|
|
19883
|
-
|
|
19884
|
-
|
|
19885
|
-
|
|
19886
|
-
height: crop.height,
|
|
19887
|
-
pixels: pixels
|
|
19888
|
-
});
|
|
20093
|
+
function getSvgRasterResolution(opts) {
|
|
20094
|
+
var res = opts.raster_res || opts.rasterRes || 1;
|
|
20095
|
+
if (res > 0 === false) stop$1('Expected raster-res= to be a positive number');
|
|
20096
|
+
return res;
|
|
20097
|
+
}
|
|
20098
|
+
|
|
20099
|
+
function getRasterSourceSize(raster, bbox) {
|
|
20100
|
+
var grid = raster.grid;
|
|
20101
|
+
var rb = getRasterBBox(raster);
|
|
20102
|
+
return {
|
|
20103
|
+
width: Math.abs((bbox[2] - bbox[0]) / (rb[2] - rb[0]) * grid.width),
|
|
20104
|
+
height: Math.abs((bbox[3] - bbox[1]) / (rb[3] - rb[1]) * grid.height)
|
|
20105
|
+
};
|
|
19889
20106
|
}
|
|
19890
20107
|
|
|
19891
20108
|
function transformRasterBboxForSVG(bbox, frame) {
|
|
@@ -23424,20 +23641,11 @@ ${svg}
|
|
|
23424
23641
|
}
|
|
23425
23642
|
if (raster.view) {
|
|
23426
23643
|
copy.view = Object.assign({}, raster.view);
|
|
23427
|
-
|
|
23428
|
-
|
|
23429
|
-
delete copy.view.preview.canvas;
|
|
23430
|
-
if (raster.view.preview.pixels) {
|
|
23431
|
-
copy.view.preview.pixels = typedArrayToBuffer(raster.view.preview.pixels);
|
|
23432
|
-
}
|
|
23433
|
-
}
|
|
23644
|
+
delete copy.view.preview;
|
|
23645
|
+
delete copy.view.scalingStats;
|
|
23434
23646
|
}
|
|
23435
23647
|
if (raster.preview) {
|
|
23436
|
-
copy.preview
|
|
23437
|
-
delete copy.preview.canvas;
|
|
23438
|
-
if (raster.preview.pixels) {
|
|
23439
|
-
copy.preview.pixels = typedArrayToBuffer(raster.preview.pixels);
|
|
23440
|
-
}
|
|
23648
|
+
delete copy.preview;
|
|
23441
23649
|
}
|
|
23442
23650
|
if (raster.pixels) {
|
|
23443
23651
|
copy.pixels = typedArrayToBuffer(raster.pixels);
|
|
@@ -28669,6 +28877,10 @@ ${svg}
|
|
|
28669
28877
|
error('precision= option should be a positive number');
|
|
28670
28878
|
}
|
|
28671
28879
|
|
|
28880
|
+
if (o.raster_type && o.raster_type != 'image' && o.raster_type != 'categorical') {
|
|
28881
|
+
error('Unsupported raster-type:', o.raster_type);
|
|
28882
|
+
}
|
|
28883
|
+
|
|
28672
28884
|
if (o.encoding) {
|
|
28673
28885
|
o.encoding = validateEncoding(o.encoding);
|
|
28674
28886
|
}
|
|
@@ -28682,9 +28894,13 @@ ${svg}
|
|
|
28682
28894
|
}
|
|
28683
28895
|
|
|
28684
28896
|
function validateProjOpts(cmd) {
|
|
28897
|
+
var resampling = cmd.options.resampling;
|
|
28685
28898
|
if (!(cmd.options.crs || cmd.options.match || cmd.options.init)) {
|
|
28686
28899
|
stop$1('Missing projection data');
|
|
28687
28900
|
}
|
|
28901
|
+
if (resampling && resampling != 'nearest' && resampling != 'bilinear') {
|
|
28902
|
+
stop$1('Unsupported resampling method:', resampling);
|
|
28903
|
+
}
|
|
28688
28904
|
}
|
|
28689
28905
|
|
|
28690
28906
|
function validateGridOpts(cmd) {
|
|
@@ -29964,6 +30180,9 @@ ${svg}
|
|
|
29964
30180
|
.option('percentile-range', {
|
|
29965
30181
|
describe: '[raster] input percentile range for percentile scaling, e.g. 2,98'
|
|
29966
30182
|
})
|
|
30183
|
+
.option('raster-type', {
|
|
30184
|
+
describe: '[raster] image or categorical (default is image)'
|
|
30185
|
+
})
|
|
29967
30186
|
.option('rendition', {
|
|
29968
30187
|
describe: '[GeoTIFF] import a GeoTIFF rendition: full,overview-1,etc.'
|
|
29969
30188
|
})
|
|
@@ -30185,6 +30404,10 @@ ${svg}
|
|
|
30185
30404
|
describe: '[SVG] bounding box of SVG map in projected map units',
|
|
30186
30405
|
type: 'bbox'
|
|
30187
30406
|
})
|
|
30407
|
+
.option('raster-res', {
|
|
30408
|
+
describe: '[SVG] raster pixels per SVG pixel (default is 1)',
|
|
30409
|
+
type: 'number'
|
|
30410
|
+
})
|
|
30188
30411
|
.option('fit-extent', {
|
|
30189
30412
|
describe: '[SVG] layer to use for the map extent'
|
|
30190
30413
|
})
|
|
@@ -31206,6 +31429,12 @@ ${svg}
|
|
|
31206
31429
|
describe: 'clip to a lat-long bounding box before projecting',
|
|
31207
31430
|
type: 'bbox'
|
|
31208
31431
|
})
|
|
31432
|
+
.option('nodata-color', {
|
|
31433
|
+
describe: '[raster] color for uncovered pixels after reprojection'
|
|
31434
|
+
})
|
|
31435
|
+
.option('resampling', {
|
|
31436
|
+
describe: '[raster] nearest or bilinear (default is bilinear)'
|
|
31437
|
+
})
|
|
31209
31438
|
.option('target', targetOpt)
|
|
31210
31439
|
.validate(validateProjOpts);
|
|
31211
31440
|
|
|
@@ -31489,6 +31718,9 @@ ${svg}
|
|
|
31489
31718
|
.option('label-text', {
|
|
31490
31719
|
describe: 'label text (set this to export points as labels)'
|
|
31491
31720
|
})
|
|
31721
|
+
.option('label-pos', {
|
|
31722
|
+
describe: 'label position; one of: n, s, e, w, ne, se, nw, sw, c'
|
|
31723
|
+
})
|
|
31492
31724
|
.option('text-anchor', {
|
|
31493
31725
|
describe: 'label alignment; one of: start, end, middle (default)'
|
|
31494
31726
|
})
|
|
@@ -35774,6 +36006,7 @@ ${svg}
|
|
|
35774
36006
|
var sourceId = getSourceId(input);
|
|
35775
36007
|
var raster = {
|
|
35776
36008
|
sourceId: sourceId,
|
|
36009
|
+
interpretation: getRasterInterpretation$1(opts),
|
|
35777
36010
|
grid: {
|
|
35778
36011
|
width: width,
|
|
35779
36012
|
height: height,
|
|
@@ -35798,13 +36031,19 @@ ${svg}
|
|
|
35798
36031
|
}
|
|
35799
36032
|
};
|
|
35800
36033
|
raster.view.recipe = getRasterViewRecipe(raster.grid, raster.view.recipe, opts);
|
|
35801
|
-
|
|
36034
|
+
if (runningInBrowser()) {
|
|
36035
|
+
raster.view.preview = createRasterPreview(raster, opts);
|
|
36036
|
+
}
|
|
35802
36037
|
return {
|
|
35803
36038
|
raster: raster,
|
|
35804
36039
|
source: getSourceInfo$1(input, sourceId, sourceImage)
|
|
35805
36040
|
};
|
|
35806
36041
|
}
|
|
35807
36042
|
|
|
36043
|
+
function getRasterInterpretation$1(opts) {
|
|
36044
|
+
return opts.raster_type || opts.rasterType || 'image';
|
|
36045
|
+
}
|
|
36046
|
+
|
|
35808
36047
|
async function selectGeoTIFFImportImage(tiff, sourceImage, opts) {
|
|
35809
36048
|
var maxPixels = getMaxImportPixels(opts);
|
|
35810
36049
|
var renditions = await getGeoTIFFRenditions(tiff, sourceImage);
|
|
@@ -36187,6 +36426,7 @@ ${svg}
|
|
|
36187
36426
|
bbox = getWorldFileBBox(transform, decoded.width, decoded.height);
|
|
36188
36427
|
raster = {
|
|
36189
36428
|
sourceId: sourceId,
|
|
36429
|
+
interpretation: getRasterInterpretation(opts),
|
|
36190
36430
|
grid: {
|
|
36191
36431
|
width: decoded.width,
|
|
36192
36432
|
height: decoded.height,
|
|
@@ -36211,7 +36451,9 @@ ${svg}
|
|
|
36211
36451
|
}
|
|
36212
36452
|
};
|
|
36213
36453
|
raster.view.recipe = getRasterViewRecipe(raster.grid, raster.view.recipe, opts);
|
|
36214
|
-
|
|
36454
|
+
if (runningInBrowser()) {
|
|
36455
|
+
raster.view.preview = createRasterPreview(raster, opts);
|
|
36456
|
+
}
|
|
36215
36457
|
dataset = {
|
|
36216
36458
|
info: {
|
|
36217
36459
|
raster_sources: [getSourceInfo(imageInput, sourceId, imageType, input)]
|
|
@@ -36226,6 +36468,10 @@ ${svg}
|
|
|
36226
36468
|
return dataset;
|
|
36227
36469
|
}
|
|
36228
36470
|
|
|
36471
|
+
function getRasterInterpretation(opts) {
|
|
36472
|
+
return opts.raster_type || opts.rasterType || 'image';
|
|
36473
|
+
}
|
|
36474
|
+
|
|
36229
36475
|
async function decodeImage(input, imageType) {
|
|
36230
36476
|
if (runningInBrowser()) {
|
|
36231
36477
|
return decodeImageInBrowser(input.content, imageType);
|
|
@@ -40821,7 +41067,7 @@ ${svg}
|
|
|
40821
41067
|
if (!opts.debug_points) {
|
|
40822
41068
|
dissolveBufferDataset2(dataset2, opts);
|
|
40823
41069
|
}
|
|
40824
|
-
timeEnd('buffer');
|
|
41070
|
+
timeEnd$1('buffer');
|
|
40825
41071
|
return dataset2;
|
|
40826
41072
|
}
|
|
40827
41073
|
|
|
@@ -50828,6 +51074,581 @@ ${svg}
|
|
|
50828
51074
|
getUtmParams: getUtmParams
|
|
50829
51075
|
});
|
|
50830
51076
|
|
|
51077
|
+
var DEFAULT_MESH_INTERVAL = 32;
|
|
51078
|
+
var DEFAULT_MAX_EDGE_FACTOR = 20;
|
|
51079
|
+
|
|
51080
|
+
function projectRasterGridForward(raster, srcCRS, destCRS, optsArg) {
|
|
51081
|
+
var opts = optsArg || {};
|
|
51082
|
+
var grid = getRasterGrid(raster);
|
|
51083
|
+
var interval = opts.raster_mesh_interval || opts.rasterMeshInterval || DEFAULT_MESH_INTERVAL;
|
|
51084
|
+
var transform = getProjTransform2(srcCRS, destCRS);
|
|
51085
|
+
var timing = opts.timing;
|
|
51086
|
+
var mesh, bbox, outSize, outGrid;
|
|
51087
|
+
validateRasterGridForProjection(grid);
|
|
51088
|
+
timeStart(timing, 'mesh');
|
|
51089
|
+
mesh = buildProjectedRasterMesh(grid, transform, interval);
|
|
51090
|
+
classifyProjectedMeshCells(mesh, opts);
|
|
51091
|
+
timeEnd(timing, 'mesh');
|
|
51092
|
+
bbox = opts.output_bbox || opts.outputBbox || getProjectedMeshBBox(mesh);
|
|
51093
|
+
if (!bbox) stop$1('Unable to project raster layer');
|
|
51094
|
+
outSize = getOutputGridSize(grid, bbox, opts);
|
|
51095
|
+
outGrid = createProjectedRasterGrid(grid, bbox, outSize.width, outSize.height, opts);
|
|
51096
|
+
timeStart(timing, 'rasterize');
|
|
51097
|
+
rasterizeProjectedMesh(grid, outGrid, mesh, getRasterProjectionSampleMethod(raster, opts));
|
|
51098
|
+
timeEnd(timing, 'rasterize');
|
|
51099
|
+
if (timing) {
|
|
51100
|
+
timing.outputWidth = outGrid.width;
|
|
51101
|
+
timing.outputHeight = outGrid.height;
|
|
51102
|
+
timing.meshVertices = mesh.vertices.length;
|
|
51103
|
+
timing.meshCells = mesh.cells.length;
|
|
51104
|
+
timing.meshSkippedCells = mesh.skippedCellCount;
|
|
51105
|
+
}
|
|
51106
|
+
return outGrid;
|
|
51107
|
+
}
|
|
51108
|
+
|
|
51109
|
+
function getRasterProjectionSampleMethod(raster, opts) {
|
|
51110
|
+
var method = opts.resampling || opts.sample_method || opts.sampleMethod || getDefaultRasterProjectionSampleMethod(raster);
|
|
51111
|
+
if (method != 'nearest' && method != 'bilinear') {
|
|
51112
|
+
stop$1('Unsupported resampling method:', method);
|
|
51113
|
+
}
|
|
51114
|
+
return method;
|
|
51115
|
+
}
|
|
51116
|
+
|
|
51117
|
+
function getDefaultRasterProjectionSampleMethod(raster) {
|
|
51118
|
+
return rasterAppearsCategorical(raster) ? 'nearest' : 'bilinear';
|
|
51119
|
+
}
|
|
51120
|
+
|
|
51121
|
+
function rasterAppearsCategorical(raster) {
|
|
51122
|
+
var grid = getRasterGrid(raster);
|
|
51123
|
+
var recipe = raster && raster.view && raster.view.recipe || {};
|
|
51124
|
+
var derivation = raster && raster.derivation || {};
|
|
51125
|
+
return raster && raster.interpretation == 'categorical' ||
|
|
51126
|
+
grid && grid.colorModel == 'palette' ||
|
|
51127
|
+
recipe.type == 'palette' ||
|
|
51128
|
+
recipe.type == 'categorical' ||
|
|
51129
|
+
derivation.type == 'palette' ||
|
|
51130
|
+
derivation.type == 'categorical';
|
|
51131
|
+
}
|
|
51132
|
+
|
|
51133
|
+
function getProjectedRasterGridBBox(raster, srcCRS, destCRS, optsArg) {
|
|
51134
|
+
var opts = optsArg || {};
|
|
51135
|
+
var grid = getRasterGrid(raster);
|
|
51136
|
+
var interval = opts.raster_mesh_interval || opts.rasterMeshInterval || DEFAULT_MESH_INTERVAL;
|
|
51137
|
+
var transform = getProjTransform2(srcCRS, destCRS);
|
|
51138
|
+
var mesh, bbox;
|
|
51139
|
+
validateRasterGridForProjection(grid);
|
|
51140
|
+
mesh = buildProjectedRasterMesh(grid, transform, interval);
|
|
51141
|
+
classifyProjectedMeshCells(mesh, opts);
|
|
51142
|
+
bbox = getProjectedMeshBBox(mesh);
|
|
51143
|
+
return bbox;
|
|
51144
|
+
}
|
|
51145
|
+
|
|
51146
|
+
function getProjectedRasterMeshBBox(mesh, optsArg) {
|
|
51147
|
+
classifyProjectedMeshCells(mesh, optsArg || {});
|
|
51148
|
+
return getProjectedMeshBBox(mesh);
|
|
51149
|
+
}
|
|
51150
|
+
|
|
51151
|
+
function buildProjectedRasterMesh(grid, transform, interval) {
|
|
51152
|
+
var xs = getMeshStops(grid.width, interval);
|
|
51153
|
+
var ys = getMeshStops(grid.height, interval);
|
|
51154
|
+
var vertices = [];
|
|
51155
|
+
for (var y = 0; y < ys.length; y++) {
|
|
51156
|
+
for (var x = 0; x < xs.length; x++) {
|
|
51157
|
+
vertices.push(projectRasterMeshVertex(grid, xs[x], ys[y], transform));
|
|
51158
|
+
}
|
|
51159
|
+
}
|
|
51160
|
+
return {
|
|
51161
|
+
xs: xs,
|
|
51162
|
+
ys: ys,
|
|
51163
|
+
vertices: vertices
|
|
51164
|
+
};
|
|
51165
|
+
}
|
|
51166
|
+
|
|
51167
|
+
function classifyProjectedMeshCells(mesh, opts) {
|
|
51168
|
+
var cols = mesh.xs.length;
|
|
51169
|
+
var cells = [];
|
|
51170
|
+
var lengths = [];
|
|
51171
|
+
var maxEdge, skipped;
|
|
51172
|
+
for (var y = 0; y < mesh.ys.length - 1; y++) {
|
|
51173
|
+
for (var x = 0; x < mesh.xs.length - 1; x++) {
|
|
51174
|
+
var cell = getMeshCell(mesh, cols, x, y);
|
|
51175
|
+
cell.maxEdge = getCellMaxEdge(cell);
|
|
51176
|
+
cells.push(cell);
|
|
51177
|
+
if (cell.valid) lengths.push(cell.maxEdge);
|
|
51178
|
+
}
|
|
51179
|
+
}
|
|
51180
|
+
maxEdge = getProjectedMeshMaxEdge(lengths, opts);
|
|
51181
|
+
skipped = 0;
|
|
51182
|
+
cells.forEach(function(cell) {
|
|
51183
|
+
if (!cell.valid || cell.maxEdge > maxEdge) {
|
|
51184
|
+
cell.valid = false;
|
|
51185
|
+
skipped++;
|
|
51186
|
+
}
|
|
51187
|
+
});
|
|
51188
|
+
if (opts.raster_component_filter || opts.rasterComponentFilter) {
|
|
51189
|
+
skipped += keepLargestValidCellComponent(cells, mesh.xs.length - 1, mesh.ys.length - 1);
|
|
51190
|
+
}
|
|
51191
|
+
mesh.cells = cells;
|
|
51192
|
+
mesh.maxEdge = maxEdge;
|
|
51193
|
+
mesh.skippedCellCount = skipped;
|
|
51194
|
+
}
|
|
51195
|
+
|
|
51196
|
+
function keepLargestValidCellComponent(cells, cols, rows) {
|
|
51197
|
+
var componentIds = new Int32Array(cells.length);
|
|
51198
|
+
var components = [];
|
|
51199
|
+
var componentId = 0;
|
|
51200
|
+
var largestId = -1;
|
|
51201
|
+
var largestSize = 0;
|
|
51202
|
+
var skipped = 0;
|
|
51203
|
+
componentIds.fill(-1);
|
|
51204
|
+
for (var i = 0; i < cells.length; i++) {
|
|
51205
|
+
if (!cells[i].valid || componentIds[i] != -1) continue;
|
|
51206
|
+
components[componentId] = floodFillCellComponent(cells, componentIds, cols, rows, i, componentId);
|
|
51207
|
+
if (components[componentId].size > largestSize) {
|
|
51208
|
+
largestSize = components[componentId].size;
|
|
51209
|
+
largestId = componentId;
|
|
51210
|
+
}
|
|
51211
|
+
componentId++;
|
|
51212
|
+
}
|
|
51213
|
+
if (largestId == -1) return 0;
|
|
51214
|
+
cells.forEach(function(cell, i) {
|
|
51215
|
+
if (cell.valid && !componentShouldBeKept(components[componentIds[i]], components[largestId])) {
|
|
51216
|
+
cell.valid = false;
|
|
51217
|
+
skipped++;
|
|
51218
|
+
}
|
|
51219
|
+
});
|
|
51220
|
+
return skipped;
|
|
51221
|
+
}
|
|
51222
|
+
|
|
51223
|
+
function floodFillCellComponent(cells, componentIds, cols, rows, start, componentId) {
|
|
51224
|
+
var stack = [start];
|
|
51225
|
+
var component = {
|
|
51226
|
+
size: 0,
|
|
51227
|
+
bbox: [Infinity, Infinity, -Infinity, -Infinity]
|
|
51228
|
+
};
|
|
51229
|
+
while (stack.length > 0) {
|
|
51230
|
+
var id = stack.pop();
|
|
51231
|
+
var x, y;
|
|
51232
|
+
if (!cells[id].valid || componentIds[id] != -1) continue;
|
|
51233
|
+
componentIds[id] = componentId;
|
|
51234
|
+
component.size++;
|
|
51235
|
+
expandComponentBBox(component, cells[id]);
|
|
51236
|
+
x = id % cols;
|
|
51237
|
+
y = Math.floor(id / cols);
|
|
51238
|
+
if (x > 0) stack.push(id - 1);
|
|
51239
|
+
if (x < cols - 1) stack.push(id + 1);
|
|
51240
|
+
if (y > 0) stack.push(id - cols);
|
|
51241
|
+
if (y < rows - 1) stack.push(id + cols);
|
|
51242
|
+
}
|
|
51243
|
+
return component;
|
|
51244
|
+
}
|
|
51245
|
+
|
|
51246
|
+
function componentShouldBeKept(component, mainComponent) {
|
|
51247
|
+
if (component == mainComponent) return true;
|
|
51248
|
+
// A valid antimeridian split can create multiple disconnected source-grid
|
|
51249
|
+
// components whose projected bboxes overlap. Remote components are more
|
|
51250
|
+
// likely to be projection discontinuities that would create spiky triangles.
|
|
51251
|
+
return bboxesOverlap(component.bbox, mainComponent.bbox);
|
|
51252
|
+
}
|
|
51253
|
+
|
|
51254
|
+
function expandComponentBBox(component, cell) {
|
|
51255
|
+
[cell.v00, cell.v10, cell.v01, cell.v11].forEach(function(p) {
|
|
51256
|
+
if (p.x < component.bbox[0]) component.bbox[0] = p.x;
|
|
51257
|
+
if (p.y < component.bbox[1]) component.bbox[1] = p.y;
|
|
51258
|
+
if (p.x > component.bbox[2]) component.bbox[2] = p.x;
|
|
51259
|
+
if (p.y > component.bbox[3]) component.bbox[3] = p.y;
|
|
51260
|
+
});
|
|
51261
|
+
}
|
|
51262
|
+
|
|
51263
|
+
function bboxesOverlap(a, b) {
|
|
51264
|
+
return a[0] <= b[2] && a[2] >= b[0] && a[1] <= b[3] && a[3] >= b[1];
|
|
51265
|
+
}
|
|
51266
|
+
|
|
51267
|
+
function getMeshCell(mesh, cols, x, y) {
|
|
51268
|
+
var v = y * cols + x;
|
|
51269
|
+
var v00 = mesh.vertices[v];
|
|
51270
|
+
var v10 = mesh.vertices[v + 1];
|
|
51271
|
+
var v01 = mesh.vertices[v + cols];
|
|
51272
|
+
var v11 = mesh.vertices[v + cols + 1];
|
|
51273
|
+
return {
|
|
51274
|
+
v00: v00,
|
|
51275
|
+
v10: v10,
|
|
51276
|
+
v01: v01,
|
|
51277
|
+
v11: v11,
|
|
51278
|
+
valid: vertexIsValid(v00) && vertexIsValid(v10) && vertexIsValid(v01) && vertexIsValid(v11)
|
|
51279
|
+
};
|
|
51280
|
+
}
|
|
51281
|
+
|
|
51282
|
+
function getCellMaxEdge(cell) {
|
|
51283
|
+
if (!cell.valid) return Infinity;
|
|
51284
|
+
return Math.max(
|
|
51285
|
+
getProjectedEdgeLength(cell.v00, cell.v10),
|
|
51286
|
+
getProjectedEdgeLength(cell.v10, cell.v11),
|
|
51287
|
+
getProjectedEdgeLength(cell.v11, cell.v01),
|
|
51288
|
+
getProjectedEdgeLength(cell.v01, cell.v00)
|
|
51289
|
+
);
|
|
51290
|
+
}
|
|
51291
|
+
|
|
51292
|
+
function getProjectedEdgeLength(a, b) {
|
|
51293
|
+
var dx = a.x - b.x;
|
|
51294
|
+
var dy = a.y - b.y;
|
|
51295
|
+
return Math.sqrt(dx * dx + dy * dy);
|
|
51296
|
+
}
|
|
51297
|
+
|
|
51298
|
+
function getProjectedMeshMaxEdge(lengths, opts) {
|
|
51299
|
+
var factor = opts.raster_max_edge_factor || opts.rasterMaxEdgeFactor || DEFAULT_MAX_EDGE_FACTOR;
|
|
51300
|
+
if (lengths.length === 0) return 0;
|
|
51301
|
+
lengths.sort(function(a, b) { return a - b; });
|
|
51302
|
+
return lengths[Math.floor(lengths.length / 2)] * factor;
|
|
51303
|
+
}
|
|
51304
|
+
|
|
51305
|
+
function validateRasterGridForProjection(grid) {
|
|
51306
|
+
var t = grid && grid.transform;
|
|
51307
|
+
if (!grid || !grid.samples || !grid.bbox) stop$1('Raster layer is missing required projection data');
|
|
51308
|
+
if (t && (t[1] !== 0 || t[3] !== 0)) {
|
|
51309
|
+
stop$1('Raster reprojection does not support rotated or skewed rasters');
|
|
51310
|
+
}
|
|
51311
|
+
}
|
|
51312
|
+
|
|
51313
|
+
function getMeshStops(size, interval) {
|
|
51314
|
+
var stops = [];
|
|
51315
|
+
var i;
|
|
51316
|
+
interval = Math.max(1, interval | 0);
|
|
51317
|
+
for (i = 0; i < size; i += interval) {
|
|
51318
|
+
stops.push(i);
|
|
51319
|
+
}
|
|
51320
|
+
if (stops[stops.length - 1] != size) stops.push(size);
|
|
51321
|
+
return stops;
|
|
51322
|
+
}
|
|
51323
|
+
|
|
51324
|
+
function projectRasterMeshVertex(grid, px, py, transform) {
|
|
51325
|
+
var xy = rasterPixelToMapXY(grid, px, py);
|
|
51326
|
+
var p = transform(xy[0], xy[1]);
|
|
51327
|
+
return {
|
|
51328
|
+
sx: px,
|
|
51329
|
+
sy: py,
|
|
51330
|
+
x: p && isFinite(p[0]) ? p[0] : NaN,
|
|
51331
|
+
y: p && isFinite(p[1]) ? p[1] : NaN
|
|
51332
|
+
};
|
|
51333
|
+
}
|
|
51334
|
+
|
|
51335
|
+
function rasterPixelToMapXY(grid, px, py) {
|
|
51336
|
+
var t = grid.transform;
|
|
51337
|
+
var bbox = grid.bbox;
|
|
51338
|
+
if (t) {
|
|
51339
|
+
return [
|
|
51340
|
+
t[0] * px + t[1] * py + t[2],
|
|
51341
|
+
t[3] * px + t[4] * py + t[5]
|
|
51342
|
+
];
|
|
51343
|
+
}
|
|
51344
|
+
return [
|
|
51345
|
+
bbox[0] + px / grid.width * (bbox[2] - bbox[0]),
|
|
51346
|
+
bbox[3] - py / grid.height * (bbox[3] - bbox[1])
|
|
51347
|
+
];
|
|
51348
|
+
}
|
|
51349
|
+
|
|
51350
|
+
function getProjectedMeshBBox(mesh) {
|
|
51351
|
+
var xmin = Infinity, ymin = Infinity, xmax = -Infinity, ymax = -Infinity;
|
|
51352
|
+
mesh.cells.forEach(function(cell) {
|
|
51353
|
+
if (!cell.valid) return;
|
|
51354
|
+
[cell.v00, cell.v10, cell.v01, cell.v11].forEach(function(p) {
|
|
51355
|
+
if (p.x < xmin) xmin = p.x;
|
|
51356
|
+
if (p.x > xmax) xmax = p.x;
|
|
51357
|
+
if (p.y < ymin) ymin = p.y;
|
|
51358
|
+
if (p.y > ymax) ymax = p.y;
|
|
51359
|
+
});
|
|
51360
|
+
});
|
|
51361
|
+
return xmin < Infinity && xmax > xmin && ymax > ymin ? [xmin, ymin, xmax, ymax] : null;
|
|
51362
|
+
}
|
|
51363
|
+
|
|
51364
|
+
function createProjectedRasterGrid(grid, bbox, widthArg, heightArg, opts) {
|
|
51365
|
+
var width = widthArg || grid.width;
|
|
51366
|
+
var height = heightArg || grid.height;
|
|
51367
|
+
var bands = getOutputBandCount(grid, opts);
|
|
51368
|
+
var samples = new grid.samples.constructor(width * height * bands);
|
|
51369
|
+
var coverage = new Uint8Array(width * height);
|
|
51370
|
+
fillProjectedRasterSamples(samples, bands, grid, opts || {});
|
|
51371
|
+
return Object.assign({}, grid, {
|
|
51372
|
+
width: width,
|
|
51373
|
+
height: height,
|
|
51374
|
+
bands: bands,
|
|
51375
|
+
samples: samples,
|
|
51376
|
+
coverage: coverage,
|
|
51377
|
+
bbox: bbox,
|
|
51378
|
+
transform: [
|
|
51379
|
+
(bbox[2] - bbox[0]) / width,
|
|
51380
|
+
0,
|
|
51381
|
+
bbox[0],
|
|
51382
|
+
0,
|
|
51383
|
+
-(bbox[3] - bbox[1]) / height,
|
|
51384
|
+
bbox[3]
|
|
51385
|
+
]
|
|
51386
|
+
});
|
|
51387
|
+
}
|
|
51388
|
+
|
|
51389
|
+
function getOutputGridSize(grid, bbox, opts) {
|
|
51390
|
+
var width = opts.output_width || opts.outputWidth;
|
|
51391
|
+
var height = opts.output_height || opts.outputHeight;
|
|
51392
|
+
var pixels, aspect;
|
|
51393
|
+
if (width || height) {
|
|
51394
|
+
return {
|
|
51395
|
+
width: width || Math.max(1, Math.round(grid.width * height / grid.height)),
|
|
51396
|
+
height: height || Math.max(1, Math.round(grid.height * width / grid.width))
|
|
51397
|
+
};
|
|
51398
|
+
}
|
|
51399
|
+
pixels = grid.width * grid.height;
|
|
51400
|
+
aspect = (bbox[2] - bbox[0]) / (bbox[3] - bbox[1]);
|
|
51401
|
+
if (!isFinite(aspect) || aspect <= 0) return {width: grid.width, height: grid.height};
|
|
51402
|
+
width = Math.max(1, Math.round(Math.sqrt(pixels * aspect)));
|
|
51403
|
+
height = Math.max(1, Math.round(pixels / width));
|
|
51404
|
+
return {width: width, height: height};
|
|
51405
|
+
}
|
|
51406
|
+
|
|
51407
|
+
function getOutputBandCount(grid, opts) {
|
|
51408
|
+
var color = getNoDataColor(opts);
|
|
51409
|
+
return color && color.a === 0 && grid.bands > 1 && grid.bands < 4 ? 4 : grid.bands;
|
|
51410
|
+
}
|
|
51411
|
+
|
|
51412
|
+
function fillProjectedRasterSamples(samples, bands, grid, opts) {
|
|
51413
|
+
var color = getNoDataColor(opts);
|
|
51414
|
+
var noData = grid.nodata;
|
|
51415
|
+
if (color) {
|
|
51416
|
+
fillProjectedRasterColor(samples, bands, color);
|
|
51417
|
+
return;
|
|
51418
|
+
}
|
|
51419
|
+
if (noData === null || noData === undefined || !isFinite(noData)) return;
|
|
51420
|
+
samples.fill(noData);
|
|
51421
|
+
}
|
|
51422
|
+
|
|
51423
|
+
function getNoDataColor(opts) {
|
|
51424
|
+
var arg = opts.nodata_color || opts.nodataColor;
|
|
51425
|
+
var color;
|
|
51426
|
+
if (arg == null || arg === '') return null;
|
|
51427
|
+
if (String(arg).toLowerCase() == 'transparent') {
|
|
51428
|
+
return {r: 0, g: 0, b: 0, a: 0};
|
|
51429
|
+
}
|
|
51430
|
+
color = parseColor(arg);
|
|
51431
|
+
if (!color) stop$1('Unsupported nodata-color:', arg);
|
|
51432
|
+
return color;
|
|
51433
|
+
}
|
|
51434
|
+
|
|
51435
|
+
function fillProjectedRasterColor(samples, bands, color) {
|
|
51436
|
+
var gray = Math.round(0.299 * color.r + 0.587 * color.g + 0.114 * color.b);
|
|
51437
|
+
var alpha = Math.round((color.a == null ? 1 : color.a) * 255);
|
|
51438
|
+
for (var i = 0; i < samples.length; i += bands) {
|
|
51439
|
+
if (bands == 1) {
|
|
51440
|
+
samples[i] = gray;
|
|
51441
|
+
} else {
|
|
51442
|
+
samples[i] = color.r;
|
|
51443
|
+
samples[i + 1] = color.g;
|
|
51444
|
+
samples[i + 2] = color.b;
|
|
51445
|
+
if (bands > 3) samples[i + 3] = alpha;
|
|
51446
|
+
}
|
|
51447
|
+
}
|
|
51448
|
+
}
|
|
51449
|
+
|
|
51450
|
+
function rasterizeProjectedMesh(srcGrid, destGrid, mesh, sampleMethod) {
|
|
51451
|
+
mesh.cells.forEach(function(cell) {
|
|
51452
|
+
if (!cell.valid) return;
|
|
51453
|
+
rasterizeProjectedTriangle(srcGrid, destGrid, cell.v00, cell.v10, cell.v11, sampleMethod);
|
|
51454
|
+
rasterizeProjectedTriangle(srcGrid, destGrid, cell.v00, cell.v11, cell.v01, sampleMethod);
|
|
51455
|
+
});
|
|
51456
|
+
}
|
|
51457
|
+
|
|
51458
|
+
function rasterizeProjectedTriangle(srcGrid, destGrid, a, b, c, sampleMethod) {
|
|
51459
|
+
var bbox, x0, x1, y0, y1, det, w1, w2, w3, sx, sy, ap, bp, cp;
|
|
51460
|
+
if (!vertexIsValid(a) || !vertexIsValid(b) || !vertexIsValid(c)) return;
|
|
51461
|
+
ap = vertexToDestPixel(destGrid, a);
|
|
51462
|
+
bp = vertexToDestPixel(destGrid, b);
|
|
51463
|
+
cp = vertexToDestPixel(destGrid, c);
|
|
51464
|
+
det = triangleDet(ap, bp, cp);
|
|
51465
|
+
if (det === 0) return;
|
|
51466
|
+
bbox = getTrianglePixelBounds(destGrid, ap, bp, cp);
|
|
51467
|
+
x0 = bbox[0]; y0 = bbox[1]; x1 = bbox[2]; y1 = bbox[3];
|
|
51468
|
+
for (var y = y0; y <= y1; y++) {
|
|
51469
|
+
for (var x = x0; x <= x1; x++) {
|
|
51470
|
+
w1 = edgeFunction(bp, cp, x + 0.5, y + 0.5) / det;
|
|
51471
|
+
w2 = edgeFunction(cp, ap, x + 0.5, y + 0.5) / det;
|
|
51472
|
+
w3 = 1 - w1 - w2;
|
|
51473
|
+
if (w1 < -1e-9 || w2 < -1e-9 || w3 < -1e-9) continue;
|
|
51474
|
+
sx = w1 * a.sx + w2 * b.sx + w3 * c.sx;
|
|
51475
|
+
sy = w1 * a.sy + w2 * b.sy + w3 * c.sy;
|
|
51476
|
+
copyRasterSample(srcGrid, destGrid, sx, sy, x, y, sampleMethod);
|
|
51477
|
+
}
|
|
51478
|
+
}
|
|
51479
|
+
}
|
|
51480
|
+
|
|
51481
|
+
function vertexToDestPixel(grid, vertex) {
|
|
51482
|
+
var p = mapXYToRasterPixel(grid, vertex.x, vertex.y);
|
|
51483
|
+
return {
|
|
51484
|
+
x: p[0],
|
|
51485
|
+
y: p[1],
|
|
51486
|
+
sx: vertex.sx,
|
|
51487
|
+
sy: vertex.sy
|
|
51488
|
+
};
|
|
51489
|
+
}
|
|
51490
|
+
|
|
51491
|
+
function getTrianglePixelBounds(grid, p1, p2, p3) {
|
|
51492
|
+
return [
|
|
51493
|
+
clamp(Math.floor(Math.min(p1.x, p2.x, p3.x)), 0, grid.width - 1),
|
|
51494
|
+
clamp(Math.floor(Math.min(p1.y, p2.y, p3.y)), 0, grid.height - 1),
|
|
51495
|
+
clamp(Math.ceil(Math.max(p1.x, p2.x, p3.x)), 0, grid.width - 1),
|
|
51496
|
+
clamp(Math.ceil(Math.max(p1.y, p2.y, p3.y)), 0, grid.height - 1)
|
|
51497
|
+
];
|
|
51498
|
+
}
|
|
51499
|
+
|
|
51500
|
+
function mapXYToRasterPixel(grid, x, y) {
|
|
51501
|
+
var bbox = grid.bbox;
|
|
51502
|
+
return [
|
|
51503
|
+
(x - bbox[0]) / (bbox[2] - bbox[0]) * grid.width,
|
|
51504
|
+
(bbox[3] - y) / (bbox[3] - bbox[1]) * grid.height
|
|
51505
|
+
];
|
|
51506
|
+
}
|
|
51507
|
+
|
|
51508
|
+
function copyRasterSample(srcGrid, destGrid, sx, sy, dx, dy, sampleMethod) {
|
|
51509
|
+
if (sampleMethod == 'bilinear') {
|
|
51510
|
+
copyBilinearRasterSample(srcGrid, destGrid, sx, sy, dx, dy);
|
|
51511
|
+
} else {
|
|
51512
|
+
copyNearestRasterSample(srcGrid, destGrid, sx, sy, dx, dy);
|
|
51513
|
+
}
|
|
51514
|
+
}
|
|
51515
|
+
|
|
51516
|
+
function copyNearestRasterSample(srcGrid, destGrid, sx, sy, dx, dy) {
|
|
51517
|
+
var srcX = clamp(Math.floor(sx), 0, srcGrid.width - 1);
|
|
51518
|
+
var srcY = clamp(Math.floor(sy), 0, srcGrid.height - 1);
|
|
51519
|
+
var src = (srcY * srcGrid.width + srcX) * srcGrid.bands;
|
|
51520
|
+
var dest = (dy * destGrid.width + dx) * destGrid.bands;
|
|
51521
|
+
if (!rasterSourcePixelIsCovered(srcGrid, srcX, srcY)) return;
|
|
51522
|
+
for (var band = 0; band < srcGrid.bands; band++) {
|
|
51523
|
+
destGrid.samples[dest + band] = srcGrid.samples[src + band];
|
|
51524
|
+
}
|
|
51525
|
+
if (destGrid.bands > srcGrid.bands) destGrid.samples[dest + 3] = 255;
|
|
51526
|
+
if (destGrid.coverage) destGrid.coverage[dy * destGrid.width + dx] = 1;
|
|
51527
|
+
}
|
|
51528
|
+
|
|
51529
|
+
function copyBilinearRasterSample(srcGrid, destGrid, sx, sy, dx, dy) {
|
|
51530
|
+
var srcX = clamp(Math.floor(sx - 0.5), 0, srcGrid.width - 1);
|
|
51531
|
+
var srcY = clamp(Math.floor(sy - 0.5), 0, srcGrid.height - 1);
|
|
51532
|
+
var srcX2 = clamp(srcX + 1, 0, srcGrid.width - 1);
|
|
51533
|
+
var srcY2 = clamp(srcY + 1, 0, srcGrid.height - 1);
|
|
51534
|
+
var tx = clamp(sx - 0.5 - srcX, 0, 1);
|
|
51535
|
+
var ty = clamp(sy - 0.5 - srcY, 0, 1);
|
|
51536
|
+
var src00 = (srcY * srcGrid.width + srcX) * srcGrid.bands;
|
|
51537
|
+
var src10 = (srcY * srcGrid.width + srcX2) * srcGrid.bands;
|
|
51538
|
+
var src01 = (srcY2 * srcGrid.width + srcX) * srcGrid.bands;
|
|
51539
|
+
var src11 = (srcY2 * srcGrid.width + srcX2) * srcGrid.bands;
|
|
51540
|
+
var dest = (dy * destGrid.width + dx) * destGrid.bands;
|
|
51541
|
+
if (!srcGrid.coverage) {
|
|
51542
|
+
copyBilinearRasterSampleFast(srcGrid, destGrid, src00, src10, src01, src11, dest, tx, ty);
|
|
51543
|
+
if (destGrid.coverage) destGrid.coverage[dy * destGrid.width + dx] = 1;
|
|
51544
|
+
return;
|
|
51545
|
+
}
|
|
51546
|
+
if (copyBilinearRasterSampleWithCoverage(srcGrid, destGrid, srcX, srcY, srcX2, srcY2, src00, src10, src01, src11, dest, tx, ty)) {
|
|
51547
|
+
if (destGrid.coverage) destGrid.coverage[dy * destGrid.width + dx] = 1;
|
|
51548
|
+
}
|
|
51549
|
+
}
|
|
51550
|
+
|
|
51551
|
+
function copyBilinearRasterSampleFast(srcGrid, destGrid, src00, src10, src01, src11, dest, tx, ty) {
|
|
51552
|
+
if (srcGrid.bands == 3) {
|
|
51553
|
+
copyBilinearRgbSample(srcGrid.samples, destGrid.samples, src00, src10, src01, src11, dest, tx, ty);
|
|
51554
|
+
} else if (srcGrid.bands == 4) {
|
|
51555
|
+
copyBilinearRgbaSample(srcGrid.samples, destGrid.samples, src00, src10, src01, src11, dest, tx, ty);
|
|
51556
|
+
} else {
|
|
51557
|
+
copyBilinearGenericSample(srcGrid.samples, destGrid.samples, srcGrid.bands, src00, src10, src01, src11, dest, tx, ty);
|
|
51558
|
+
}
|
|
51559
|
+
if (destGrid.bands > srcGrid.bands) destGrid.samples[dest + 3] = 255;
|
|
51560
|
+
}
|
|
51561
|
+
|
|
51562
|
+
function copyBilinearRgbSample(src, destArr, src00, src10, src01, src11, dest, tx, ty) {
|
|
51563
|
+
copyBilinearBand(src, destArr, src00, src10, src01, src11, dest, 0, tx, ty);
|
|
51564
|
+
copyBilinearBand(src, destArr, src00, src10, src01, src11, dest, 1, tx, ty);
|
|
51565
|
+
copyBilinearBand(src, destArr, src00, src10, src01, src11, dest, 2, tx, ty);
|
|
51566
|
+
}
|
|
51567
|
+
|
|
51568
|
+
function copyBilinearRgbaSample(src, destArr, src00, src10, src01, src11, dest, tx, ty) {
|
|
51569
|
+
copyBilinearRgbSample(src, destArr, src00, src10, src01, src11, dest, tx, ty);
|
|
51570
|
+
copyBilinearBand(src, destArr, src00, src10, src01, src11, dest, 3, tx, ty);
|
|
51571
|
+
}
|
|
51572
|
+
|
|
51573
|
+
function copyBilinearGenericSample(src, destArr, bands, src00, src10, src01, src11, dest, tx, ty) {
|
|
51574
|
+
for (var band = 0; band < bands; band++) {
|
|
51575
|
+
copyBilinearBand(src, destArr, src00, src10, src01, src11, dest, band, tx, ty);
|
|
51576
|
+
}
|
|
51577
|
+
}
|
|
51578
|
+
|
|
51579
|
+
function copyBilinearBand(src, destArr, src00, src10, src01, src11, dest, band, tx, ty) {
|
|
51580
|
+
var a = src[src00 + band] * (1 - tx) + src[src10 + band] * tx;
|
|
51581
|
+
var b = src[src01 + band] * (1 - tx) + src[src11 + band] * tx;
|
|
51582
|
+
destArr[dest + band] = Math.round(a * (1 - ty) + b * ty);
|
|
51583
|
+
}
|
|
51584
|
+
|
|
51585
|
+
function copyBilinearRasterSampleWithCoverage(srcGrid, destGrid, srcX, srcY, srcX2, srcY2, src00, src10, src01, src11, dest, tx, ty) {
|
|
51586
|
+
var coords = [
|
|
51587
|
+
[srcX, srcY, src00, (1 - tx) * (1 - ty)],
|
|
51588
|
+
[srcX2, srcY, src10, tx * (1 - ty)],
|
|
51589
|
+
[srcX, srcY2, src01, (1 - tx) * ty],
|
|
51590
|
+
[srcX2, srcY2, src11, tx * ty]
|
|
51591
|
+
];
|
|
51592
|
+
var total = 0;
|
|
51593
|
+
var val, item;
|
|
51594
|
+
for (var band = 0; band < srcGrid.bands; band++) {
|
|
51595
|
+
val = 0;
|
|
51596
|
+
total = 0;
|
|
51597
|
+
for (var i = 0; i < coords.length; i++) {
|
|
51598
|
+
item = coords[i];
|
|
51599
|
+
if (item[3] <= 0 || !rasterSourcePixelIsCovered(srcGrid, item[0], item[1])) continue;
|
|
51600
|
+
val += srcGrid.samples[item[2] + band] * item[3];
|
|
51601
|
+
total += item[3];
|
|
51602
|
+
}
|
|
51603
|
+
if (total <= 0) return false;
|
|
51604
|
+
destGrid.samples[dest + band] = Math.round(val / total);
|
|
51605
|
+
}
|
|
51606
|
+
if (destGrid.bands > srcGrid.bands) destGrid.samples[dest + 3] = 255;
|
|
51607
|
+
return true;
|
|
51608
|
+
}
|
|
51609
|
+
|
|
51610
|
+
function rasterSourcePixelIsCovered(grid, x, y) {
|
|
51611
|
+
return !grid.coverage || grid.coverage[y * grid.width + x] > 0;
|
|
51612
|
+
}
|
|
51613
|
+
|
|
51614
|
+
function timeStart(timing, name) {
|
|
51615
|
+
if (!timing) return;
|
|
51616
|
+
timing[name + 'Start'] = getTimer();
|
|
51617
|
+
}
|
|
51618
|
+
|
|
51619
|
+
function timeEnd(timing, name) {
|
|
51620
|
+
if (!timing) return;
|
|
51621
|
+
timing[name + 'Ms'] = getTimer() - timing[name + 'Start'];
|
|
51622
|
+
}
|
|
51623
|
+
|
|
51624
|
+
function getTimer() {
|
|
51625
|
+
return typeof performance != 'undefined' && performance.now ? performance.now() : Date.now();
|
|
51626
|
+
}
|
|
51627
|
+
|
|
51628
|
+
function vertexIsValid(p) {
|
|
51629
|
+
return p && isFinite(p.x) && isFinite(p.y);
|
|
51630
|
+
}
|
|
51631
|
+
|
|
51632
|
+
function triangleDet(a, b, c) {
|
|
51633
|
+
return edgeFunction(a, b, c.x, c.y);
|
|
51634
|
+
}
|
|
51635
|
+
|
|
51636
|
+
function edgeFunction(a, b, x, y) {
|
|
51637
|
+
return (x - a.x) * (b.y - a.y) - (y - a.y) * (b.x - a.x);
|
|
51638
|
+
}
|
|
51639
|
+
|
|
51640
|
+
function clamp(val, min, max) {
|
|
51641
|
+
return val < min ? min : val > max ? max : val;
|
|
51642
|
+
}
|
|
51643
|
+
|
|
51644
|
+
var RasterReprojection = /*#__PURE__*/Object.freeze({
|
|
51645
|
+
__proto__: null,
|
|
51646
|
+
buildProjectedRasterMesh: buildProjectedRasterMesh,
|
|
51647
|
+
getProjectedRasterGridBBox: getProjectedRasterGridBBox,
|
|
51648
|
+
getProjectedRasterMeshBBox: getProjectedRasterMeshBBox,
|
|
51649
|
+
projectRasterGridForward: projectRasterGridForward
|
|
51650
|
+
});
|
|
51651
|
+
|
|
50831
51652
|
cmd.proj = function(dataset, catalog, opts, targetLayers) {
|
|
50832
51653
|
var srcInfo, destInfo, destStr;
|
|
50833
51654
|
var implicitlyProjectedNames = getImplicitlyTargetedLayerNames(dataset, targetLayers, layerHasGeometry);
|
|
@@ -50864,7 +51685,7 @@ ${svg}
|
|
|
50864
51685
|
stop$1("Missing projection data");
|
|
50865
51686
|
}
|
|
50866
51687
|
|
|
50867
|
-
if (!datasetHasGeometry(dataset)) {
|
|
51688
|
+
if (!datasetHasGeometry(dataset) && !datasetHasRaster(dataset)) {
|
|
50868
51689
|
// still set the crs of datasets that are missing geometry
|
|
50869
51690
|
setDatasetCrsInfo(dataset, destInfo);
|
|
50870
51691
|
return false;
|
|
@@ -50918,6 +51739,7 @@ ${svg}
|
|
|
50918
51739
|
return a.name != b.name ||
|
|
50919
51740
|
a.geometry_type != b.geometry_type ||
|
|
50920
51741
|
a.data !== b.data ||
|
|
51742
|
+
a.raster !== b.raster ||
|
|
50921
51743
|
!arraysAreEqual(a.shapes, b.shapes);
|
|
50922
51744
|
}
|
|
50923
51745
|
|
|
@@ -50965,6 +51787,8 @@ ${svg}
|
|
|
50965
51787
|
dataset.layers.forEach(function(lyr) {
|
|
50966
51788
|
if (layerHasPoints(lyr)) {
|
|
50967
51789
|
badPoints += projectPointLayer(lyr, proj); // v2 compatible (invalid points are removed)
|
|
51790
|
+
} else if (layerHasRaster(lyr)) {
|
|
51791
|
+
projectRasterLayer(lyr, src, dest, opts);
|
|
50968
51792
|
}
|
|
50969
51793
|
});
|
|
50970
51794
|
if (dataset.arcs) {
|
|
@@ -50990,6 +51814,18 @@ ${svg}
|
|
|
50990
51814
|
dataset.info.crs = dest;
|
|
50991
51815
|
}
|
|
50992
51816
|
|
|
51817
|
+
function projectRasterLayer(lyr, src, dest, opts) {
|
|
51818
|
+
var raster = lyr.raster;
|
|
51819
|
+
raster.grid = projectRasterGridForward(raster, src, dest, opts || {});
|
|
51820
|
+
raster.view = raster.view || {};
|
|
51821
|
+
delete raster.view.scalingStats;
|
|
51822
|
+
if (runningInBrowser()) {
|
|
51823
|
+
raster.view.preview = createRasterPreview(raster, opts || {});
|
|
51824
|
+
} else {
|
|
51825
|
+
delete raster.view.preview;
|
|
51826
|
+
}
|
|
51827
|
+
}
|
|
51828
|
+
|
|
50993
51829
|
// * Heals cuts in previously split-apart polygons
|
|
50994
51830
|
// * Removes line intersections
|
|
50995
51831
|
// * TODO: what if a layer contains polygons with desired overlaps? should
|
|
@@ -55865,9 +56701,7 @@ ${svg}
|
|
|
55865
56701
|
lyr.data.getFields().filter(isSupportedSvgStyleProperty).forEach(lyr.data.deleteField, lyr.data);
|
|
55866
56702
|
}
|
|
55867
56703
|
table = getLayerDataTable(lyr);
|
|
55868
|
-
fields =
|
|
55869
|
-
return optName.replace('_', '-');
|
|
55870
|
-
}).filter(isSupportedSvgStyleProperty);
|
|
56704
|
+
fields = getStyleFields(opts);
|
|
55871
56705
|
hasNewFields = fields.some(function(field) {
|
|
55872
56706
|
return !table.fieldExists(field);
|
|
55873
56707
|
});
|
|
@@ -55888,11 +56722,14 @@ ${svg}
|
|
|
55888
56722
|
table.getRecords().forEach(function(rec, i) {
|
|
55889
56723
|
if (filterFn && !filterFn(i)) {
|
|
55890
56724
|
// make sure field exists if record is excluded by filter
|
|
55891
|
-
|
|
55892
|
-
rec[svgName] = undefined;
|
|
55893
|
-
}
|
|
56725
|
+
setUndefinedFields(rec, svgName == 'label-pos' ? labelPositionFields : [svgName]);
|
|
55894
56726
|
} else {
|
|
55895
56727
|
rec[svgName] = accessor(i);
|
|
56728
|
+
if (svgName == 'label-pos') {
|
|
56729
|
+
if (!setLabelPositionStyle(rec, rec['label-pos'])) {
|
|
56730
|
+
stop$1('Unexpected value for label-pos:', rec['label-pos']);
|
|
56731
|
+
}
|
|
56732
|
+
}
|
|
55896
56733
|
}
|
|
55897
56734
|
});
|
|
55898
56735
|
});
|
|
@@ -55905,6 +56742,35 @@ ${svg}
|
|
|
55905
56742
|
}
|
|
55906
56743
|
};
|
|
55907
56744
|
|
|
56745
|
+
function getStyleFields(opts) {
|
|
56746
|
+
var fields = [];
|
|
56747
|
+
Object.keys(opts).forEach(function(optName) {
|
|
56748
|
+
var svgName = optName.replace('_', '-');
|
|
56749
|
+
if (!isSupportedSvgStyleProperty(svgName)) return;
|
|
56750
|
+
addField(fields, svgName);
|
|
56751
|
+
if (svgName == 'label-pos') {
|
|
56752
|
+
labelPositionFields.forEach(function(field) {
|
|
56753
|
+
addField(fields, field);
|
|
56754
|
+
});
|
|
56755
|
+
}
|
|
56756
|
+
});
|
|
56757
|
+
return fields;
|
|
56758
|
+
}
|
|
56759
|
+
|
|
56760
|
+
function addField(fields, field) {
|
|
56761
|
+
if (fields.indexOf(field) == -1) {
|
|
56762
|
+
fields.push(field);
|
|
56763
|
+
}
|
|
56764
|
+
}
|
|
56765
|
+
|
|
56766
|
+
function setUndefinedFields(rec, fields) {
|
|
56767
|
+
fields.forEach(function(field) {
|
|
56768
|
+
if (field in rec === false) {
|
|
56769
|
+
rec[field] = undefined;
|
|
56770
|
+
}
|
|
56771
|
+
});
|
|
56772
|
+
}
|
|
56773
|
+
|
|
55908
56774
|
var roundCoord$1 = getRoundingFunction(0.01);
|
|
55909
56775
|
|
|
55910
56776
|
function getSymbolFillColor(d) {
|
|
@@ -57382,7 +58248,7 @@ ${svg}
|
|
|
57382
58248
|
});
|
|
57383
58249
|
}
|
|
57384
58250
|
|
|
57385
|
-
var version = "0.7.
|
|
58251
|
+
var version = "0.7.17";
|
|
57386
58252
|
|
|
57387
58253
|
// Parse command line args into commands and run them
|
|
57388
58254
|
// Function takes an optional Node-style callback. A Promise is returned if no callback is given.
|
|
@@ -58911,6 +59777,7 @@ ${svg}
|
|
|
58911
59777
|
Lines,
|
|
58912
59778
|
Logging,
|
|
58913
59779
|
Profile,
|
|
59780
|
+
RasterReprojection,
|
|
58914
59781
|
RasterUtils,
|
|
58915
59782
|
Merging,
|
|
58916
59783
|
MosaicIndex$1,
|