1 | import { shallowcopy } from '../util.js'
|
2 | import { COVJSON_DATATYPE_TUPLE, COVERAGE, DOMAIN } from '../constants.js'
|
3 | import { getHorizontalCRSReferenceObject, getProjection } from '../domain/referencing.js'
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 | export function reproject (cov, refDomain) {
|
21 | return cov.loadDomain().then(sourceDomain => {
|
22 | let sourceRef = getHorizontalCRSReferenceObject(sourceDomain)
|
23 | if (sourceRef.coordinates.length > 2) {
|
24 | throw new Error('Reprojection not supported for >2D CRSs')
|
25 | }
|
26 |
|
27 | if (sourceRef.coordinates.some(sourceDomain.axes.has)) {
|
28 | throw new Error('Grid reprojection not supported yet')
|
29 | }
|
30 | let [xComp, yComp] = sourceRef.coordinates
|
31 |
|
32 |
|
33 |
|
34 |
|
35 | let axes = [...sourceDomain.axes.values()]
|
36 | let axis = axes.find(axis => sourceRef.coordinates.every(comp => axis.coordinates.indexOf(comp) !== -1))
|
37 | let [xCompIdx, yCompIdx] = [axis.coordinates.indexOf(xComp), axis.coordinates.indexOf(yComp)]
|
38 |
|
39 |
|
40 | let sourceProjection = getProjection(sourceDomain)
|
41 | let targetProjection = getProjection(refDomain)
|
42 |
|
43 |
|
44 |
|
45 | let values
|
46 | if (axis.dataType === COVJSON_DATATYPE_TUPLE) {
|
47 |
|
48 | values = axis.values.map(tuple => tuple.slice())
|
49 | for (let tuple of values) {
|
50 | let [sourceX, sourceY] = [tuple[xCompIdx], tuple[yCompIdx]]
|
51 | let latlon = sourceProjection.unproject({x: sourceX, y: sourceY})
|
52 | let {x, y} = targetProjection.project(latlon)
|
53 | tuple[xCompIdx] = x
|
54 | tuple[yCompIdx] = y
|
55 | }
|
56 | } else {
|
57 | throw new Error('Unsupported data type: ' + axis.dataType)
|
58 | }
|
59 |
|
60 |
|
61 | let newAxes = new Map(sourceDomain.axes)
|
62 | let newAxis = shallowcopy(axis)
|
63 | delete newAxis.bounds
|
64 | newAxis.values = values
|
65 | newAxes.set(axis.key, newAxis)
|
66 |
|
67 | let targetRef = getHorizontalCRSReferenceObject(refDomain)
|
68 | if (targetRef.coordinates.length > 2) {
|
69 | throw new Error('Reprojection not supported for >2D CRSs')
|
70 | }
|
71 | let newReferencing = sourceDomain.referencing.map(ref => {
|
72 | if (ref === sourceRef) {
|
73 | return {
|
74 | coordinates: sourceRef.coordinates,
|
75 | system: targetRef.system
|
76 | }
|
77 | } else {
|
78 | return ref
|
79 | }
|
80 | })
|
81 |
|
82 | let newDomain = {
|
83 | type: DOMAIN,
|
84 | domainType: sourceDomain.domainType,
|
85 | axes: newAxes,
|
86 | referencing: newReferencing
|
87 | }
|
88 |
|
89 | let newCoverage = {
|
90 | type: COVERAGE,
|
91 | domainType: cov.domainType,
|
92 | parameters: cov.parameters,
|
93 | loadDomain: () => Promise.resolve(newDomain),
|
94 | loadRange: paramKey => cov.loadRange(paramKey),
|
95 | loadRanges: paramKeys => cov.loadRanges(paramKeys),
|
96 | subsetByIndex: constraints => cov.subsetByIndex(constraints).then(sub => reproject(sub, refDomain)),
|
97 | subsetByValue: constraints => cov.subsetByValue(constraints).then(sub => reproject(sub, refDomain))
|
98 | }
|
99 | return newCoverage
|
100 | })
|
101 | }
|