covutils
Version:
Utilities for creating, transforming, and handling Coverage Data objects.
169 lines (144 loc) • 6.31 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
exports.reproject = reproject;
var _util = require('../util.js');
var _constants = require('../constants.js');
var _referencing = require('../domain/referencing.js');
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
/**
* Reproject a coverage.
*
* Reprojecting means returning a new coverage where the horizontal CRS is replaced
* and the horizontal domain coordinates are reprojected.
*
* Current limitations:
* - only point-type coverage domains are supported (Tuple only)
* - only horizontal CRSs (2-dimensional) are supported
* - non-lat/lon CRSs have to be pre-cached with loadProjection()
*
* @param {Coverage} cov The Coverage object to reproject.
* @param {Domain} refDomain The reference domain from which the horizontal CRS is used.
* @returns {Promise<Coverage>} A promise with the reprojected Coverage object as result.
*/
function reproject(cov, refDomain) {
return cov.loadDomain().then(function (sourceDomain) {
var sourceRef = (0, _referencing.getHorizontalCRSReferenceObject)(sourceDomain);
if (sourceRef.coordinates.length > 2) {
throw new Error('Reprojection not supported for >2D CRSs');
}
// check that the CRS coordinate IDs don't refer to grid axes
if (sourceRef.coordinates.some(sourceDomain.axes.has)) {
throw new Error('Grid reprojection not supported yet');
}
var _sourceRef$coordinate = _slicedToArray(sourceRef.coordinates, 2);
var xComp = _sourceRef$coordinate[0];
var yComp = _sourceRef$coordinate[1];
// TODO reproject bounds
// find the composite axis that contains the horizontal coordinates
var axes = [].concat(_toConsumableArray(sourceDomain.axes.values()));
var axis = axes.find(function (axis) {
return sourceRef.coordinates.every(function (comp) {
return axis.coordinates.indexOf(comp) !== -1;
});
});
var xCompIdx = axis.coordinates.indexOf(xComp);
var yCompIdx = axis.coordinates.indexOf(yComp);
// find the target CRS and get the projection
var sourceProjection = (0, _referencing.getProjection)(sourceDomain);
var targetProjection = (0, _referencing.getProjection)(refDomain);
// reproject the x/y part of every axis value
// this is done by unprojecting to lon/lat, followed by projecting to the target x/y
var values = void 0;
if (axis.dataType === _constants.COVJSON_DATATYPE_TUPLE) {
// make a deep copy of the axis values and replace x,y values by the reprojected ones
values = axis.values.map(function (tuple) {
return tuple.slice();
});
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = values[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var tuple = _step.value;
var sourceX = tuple[xCompIdx];
var sourceY = tuple[yCompIdx];
var latlon = sourceProjection.unproject({ x: sourceX, y: sourceY });
var _targetProjection$pro = targetProjection.project(latlon);
var x = _targetProjection$pro.x;
var y = _targetProjection$pro.y;
tuple[xCompIdx] = x;
tuple[yCompIdx] = y;
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
} else {
throw new Error('Unsupported data type: ' + axis.dataType);
}
// assemble reprojected coverage
var newAxes = new Map(sourceDomain.axes);
var newAxis = (0, _util.shallowcopy)(axis);
delete newAxis.bounds;
newAxis.values = values;
newAxes.set(axis.key, newAxis);
var targetRef = (0, _referencing.getHorizontalCRSReferenceObject)(refDomain);
if (targetRef.coordinates.length > 2) {
throw new Error('Reprojection not supported for >2D CRSs');
}
var newReferencing = sourceDomain.referencing.map(function (ref) {
if (ref === sourceRef) {
return {
coordinates: sourceRef.coordinates,
system: targetRef.system
};
} else {
return ref;
}
});
var newDomain = {
type: _constants.DOMAIN,
domainType: sourceDomain.domainType,
axes: newAxes,
referencing: newReferencing
};
var newCoverage = {
type: _constants.COVERAGE,
domainType: cov.domainType,
parameters: cov.parameters,
loadDomain: function loadDomain() {
return Promise.resolve(newDomain);
},
loadRange: function loadRange(paramKey) {
return cov.loadRange(paramKey);
},
loadRanges: function loadRanges(paramKeys) {
return cov.loadRanges(paramKeys);
},
subsetByIndex: function subsetByIndex(constraints) {
return cov.subsetByIndex(constraints).then(function (sub) {
return reproject(sub, refDomain);
});
},
subsetByValue: function subsetByValue(constraints) {
return cov.subsetByValue(constraints).then(function (sub) {
return reproject(sub, refDomain);
});
}
};
return newCoverage;
});
}