@dataforsyningen/saul 3.1.3 → 3.3.0
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/config.js.example +4 -3
- package/example.html +1 -1
- package/index.js +4 -3
- package/modules/api.js +45 -3
- package/modules/saul-core.js +28 -7
- package/modules/saul-elevation.js +2 -36
- package/package.json +7 -3
- package/test/saul-combined.test.js +147 -0
- package/test/saul-core.test.js +4 -6
- package/test/saul-elevation.test.js +8 -10
- package/test/saul-projection.test.js +1 -1
package/config.js.example
CHANGED
|
@@ -2,10 +2,11 @@ export default {
|
|
|
2
2
|
|
|
3
3
|
// STAC TOKEN can be aquired from https://dataforsyningen.dk/
|
|
4
4
|
API_STAC_TOKEN: "",
|
|
5
|
-
API_STAC_BASEURL: "https://api.dataforsyningen.dk/
|
|
5
|
+
API_STAC_BASEURL: "https://api.dataforsyningen.dk/skraafoto_api_test/v1.0",
|
|
6
6
|
|
|
7
7
|
// DHM URL and auth can be aquired from https://datafordeler.dk/dataoversigt/danmarks-hoejdemodel-dhm/koter/
|
|
8
|
+
API_DHM_WCS_BASEURL: "https://services.datafordeler.dk/DHMNedboer/dhm_wcs/1.0.0/WCS",
|
|
8
9
|
API_DHM_BASEURL: "https://services.datafordeler.dk/DHMTerraen/DHMKoter/1.0.0/GEOREST/HentKoter",
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
API_DHM_TOKENA: "", // DHM API service username
|
|
11
|
+
API_DHM_TOKENB: "" // DHM API service password
|
|
11
12
|
}
|
package/example.html
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
<script type="module">
|
|
19
19
|
|
|
20
|
-
// You should add your own config.js with proper tokens,
|
|
20
|
+
// You should add your own config.js with proper tokens, etc.
|
|
21
21
|
// Check config.js.example for info on how to set it up
|
|
22
22
|
import auth from './config.js'
|
|
23
23
|
|
package/index.js
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
export {
|
|
4
4
|
image2world,
|
|
5
|
-
world2image,
|
|
5
|
+
world2image, // Deprecated. Use getImageXY
|
|
6
6
|
getWorldXYZ,
|
|
7
|
-
|
|
7
|
+
getImageXY,
|
|
8
|
+
getZ,
|
|
8
9
|
iterate // Deprecated. Use getWorldXYZ
|
|
9
10
|
} from './modules/saul-core.js'
|
|
10
11
|
|
|
@@ -12,6 +13,7 @@ export {
|
|
|
12
13
|
postSTAC,
|
|
13
14
|
getSTAC,
|
|
14
15
|
getDHM,
|
|
16
|
+
getTerrainGeoTIFF,
|
|
15
17
|
get,
|
|
16
18
|
post
|
|
17
19
|
} from './modules/api.js'
|
|
@@ -22,6 +24,5 @@ export {
|
|
|
22
24
|
} from './modules/saul-projection.js'
|
|
23
25
|
|
|
24
26
|
export {
|
|
25
|
-
getTerrainGeoTIFF,
|
|
26
27
|
getElevation
|
|
27
28
|
} from './modules/saul-elevation.js'
|
package/modules/api.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* SAUL API utilities
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import { fromArrayBuffer } from 'geotiff'
|
|
6
|
+
|
|
5
7
|
let error_msg
|
|
6
8
|
let load_stack = []
|
|
7
9
|
|
|
@@ -152,11 +154,11 @@ function post(url, requestbody, token) {
|
|
|
152
154
|
/**
|
|
153
155
|
* API method to fetch data from DHM
|
|
154
156
|
* @param {string} query - DHM API query. Find details at https://datafordeler.dk/dataoversigt/danmarks-hoejdemodel-dhm/koter/
|
|
155
|
-
* @param {{API_DHM_BASEURL: string,
|
|
157
|
+
* @param {{API_DHM_BASEURL: string, API_DHM_TOKENA: string, API_DHM_TOKENB: string}} auth - API autentication data. See ../config.js.example for reference.
|
|
156
158
|
* @returns {object} Response data
|
|
157
159
|
*/
|
|
158
160
|
function getDHM(query, auth) {
|
|
159
|
-
const auth_params = `&username=${auth.
|
|
161
|
+
const auth_params = `&username=${auth.API_DHM_TOKENA}&password=${auth.API_DHM_TOKENB}`
|
|
160
162
|
return get(encodeURI(auth.API_DHM_BASEURL + query + auth_params))
|
|
161
163
|
.then((data) => data)
|
|
162
164
|
}
|
|
@@ -184,10 +186,50 @@ function postSTAC(endpoint, data, auth) {
|
|
|
184
186
|
.then((data) => data)
|
|
185
187
|
}
|
|
186
188
|
|
|
189
|
+
|
|
190
|
+
/** Converts raw GeoTIFF arrayBuffer to image */
|
|
191
|
+
async function consumeGeoTIFF(raw_data) {
|
|
192
|
+
const tiff = await fromArrayBuffer(raw_data)
|
|
193
|
+
const image = await tiff.getImage()
|
|
194
|
+
return image
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
/** Fetches a GeoTIFF with elevation data matching the bounding box of a STAC API item (image)
|
|
199
|
+
* @param {object} stac_item - STAC API item from a featureCollection request
|
|
200
|
+
* @param {{API_DHM_WCS_BASEURL: string, API_DHM_TOKENA: string, API_DHM_TOKENB: string}} auth - API autentication data. See ../config.js.example for reference.
|
|
201
|
+
* @param {number} [resolution] - Resolution (1 - 0.01). Higher number means more pixels and better precision.
|
|
202
|
+
* @returns {object} GeoTiff data
|
|
203
|
+
*/
|
|
204
|
+
function getTerrainGeoTIFF(stac_item, auth, resolution = 0.05) {
|
|
205
|
+
|
|
206
|
+
const bbox = stac_item.bbox
|
|
207
|
+
const width = Math.round( stac_item.properties['proj:shape'][0] * resolution )
|
|
208
|
+
const height = Math.round( stac_item.properties['proj:shape'][1] * resolution )
|
|
209
|
+
|
|
210
|
+
// GET request for DHM WCS data
|
|
211
|
+
let url = auth.API_DHM_WCS_BASEURL
|
|
212
|
+
url += '?SERVICE=WCS&COVERAGE=dhm_terraen&RESPONSE_CRS=epsg:25832&CRS=epsg:25832&FORMAT=GTiff&REQUEST=GetCoverage&VERSION=1.0.0'
|
|
213
|
+
url += `&username=${ auth.API_DHM_TOKENA }&password=${ auth.API_DHM_TOKENB }`
|
|
214
|
+
url += `&height=${ height }`
|
|
215
|
+
url += `&width=${ width }`
|
|
216
|
+
url += `&bbox=${ bbox[0]},${ bbox[1]},${ bbox[2]},${ bbox[3]}`
|
|
217
|
+
|
|
218
|
+
return get(url, {}, false)
|
|
219
|
+
.then((response) => {
|
|
220
|
+
return response.arrayBuffer()
|
|
221
|
+
})
|
|
222
|
+
.then((arrayBuffer) => {
|
|
223
|
+
return consumeGeoTIFF(arrayBuffer)
|
|
224
|
+
})
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
|
|
187
228
|
export {
|
|
188
229
|
get,
|
|
189
230
|
post,
|
|
190
231
|
getSTAC,
|
|
191
232
|
postSTAC,
|
|
192
|
-
getDHM
|
|
233
|
+
getDHM,
|
|
234
|
+
getTerrainGeoTIFF
|
|
193
235
|
}
|
package/modules/saul-core.js
CHANGED
|
@@ -57,18 +57,22 @@ function image2world(image_data, col, row, Z = 0) {
|
|
|
57
57
|
var X = (Z-Z0)*kx + X0
|
|
58
58
|
var Y = (Z-Z0)*ky + Y0
|
|
59
59
|
|
|
60
|
-
return[
|
|
60
|
+
return[
|
|
61
|
+
Math.round(X * 100) / 100,
|
|
62
|
+
Math.round(Y * 100) / 100,
|
|
63
|
+
Z
|
|
64
|
+
]
|
|
61
65
|
}
|
|
62
66
|
|
|
63
67
|
/**
|
|
64
|
-
* Converts lat,lon coordinates to x,y coordinates within a specific image
|
|
68
|
+
* Converts world lat,lon coordinates to x,y coordinates within a specific image
|
|
65
69
|
* @param {Object} image_data - skraafoto-stac-api image data
|
|
66
70
|
* @param {Number} Y - northing
|
|
67
71
|
* @param {Number} X - easting
|
|
68
72
|
* @param {Number} [Z] - elevation (geoide)
|
|
69
73
|
* @returns {array} [x,y] Column/row image coordinate
|
|
70
74
|
*/
|
|
71
|
-
function
|
|
75
|
+
function getImageXY(image_data, X, Y, Z = 0) {
|
|
72
76
|
|
|
73
77
|
// constants pulled from image_data
|
|
74
78
|
const xx0 = image_data.properties['pers:interior_orientation'].principal_point_offset[0]
|
|
@@ -109,7 +113,22 @@ function world2image(image_data, X, Y, Z = 0) {
|
|
|
109
113
|
var col = ((x_dot-xx0)+(dimX))*(-1)/pix
|
|
110
114
|
var row = ((y_dot-yy0)+(dimY))*(-1)/pix
|
|
111
115
|
|
|
112
|
-
return [
|
|
116
|
+
return [
|
|
117
|
+
Math.round(col),
|
|
118
|
+
Math.round(row)
|
|
119
|
+
]
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* (DEPRECATED - Use getImageXY) Converts lat,lon coordinates to x,y coordinates within a specific image
|
|
124
|
+
* @param {Object} image_data - skraafoto-stac-api image data
|
|
125
|
+
* @param {Number} Y - northing
|
|
126
|
+
* @param {Number} X - easting
|
|
127
|
+
* @param {Number} [Z] - elevation (geoide)
|
|
128
|
+
* @returns {array} [x,y] Column/row image coordinate
|
|
129
|
+
*/
|
|
130
|
+
function world2image(image_data, X, Y, Z = 0) {
|
|
131
|
+
return getImageXY(image_data, X, Y, Z)
|
|
113
132
|
}
|
|
114
133
|
|
|
115
134
|
/** Converts degress to radians */
|
|
@@ -198,16 +217,17 @@ async function compareZ(options) {
|
|
|
198
217
|
* @param {array} options.xy - image coordinates
|
|
199
218
|
* @param {object} options.image - STAC API item
|
|
200
219
|
* @param {object} options.terrain - GeoTIFF object from getTerrainGeoTIFF() output
|
|
220
|
+
* @param {number} precision - Precision in meters for "good enough"
|
|
201
221
|
* @returns {array} Array with world coordinates (indexes 0 and 1) and elevation (index 2). Coordinates are EPSG:25832 format.
|
|
202
222
|
*/
|
|
203
|
-
async function getWorldXYZ(options) {
|
|
223
|
+
async function getWorldXYZ(options, precision = 0.3) {
|
|
204
224
|
|
|
205
225
|
const best_world_xyz = compareZ({
|
|
206
226
|
image: options.image,
|
|
207
227
|
terrain: options.terrain,
|
|
208
228
|
xy: options.xy,
|
|
209
229
|
z: 0,
|
|
210
|
-
limit:
|
|
230
|
+
limit: precision,
|
|
211
231
|
iteration: 1
|
|
212
232
|
})
|
|
213
233
|
|
|
@@ -216,8 +236,9 @@ async function getWorldXYZ(options) {
|
|
|
216
236
|
|
|
217
237
|
export {
|
|
218
238
|
image2world,
|
|
219
|
-
getWorldXYZ,
|
|
220
239
|
world2image,
|
|
240
|
+
getWorldXYZ,
|
|
241
|
+
getImageXY,
|
|
221
242
|
getZ,
|
|
222
243
|
iterate
|
|
223
244
|
}
|
|
@@ -1,41 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { get } from './api.js'
|
|
1
|
+
import { getTerrainGeoTIFF } from './api.js'
|
|
3
2
|
|
|
4
|
-
/** Fetches a GeoTIFF with elevation data matching the bounding box of a STAC API item (image)
|
|
5
|
-
* @param {object} stac_item - STAC API item from a featureCollection request
|
|
6
|
-
* @param {{API_DHM_WCS_BASEURL: string, API_DHM_USERNAME: string, API_DHM_PASSWORD: string}} auth - API autentication data. See ../config.js.example for reference.
|
|
7
|
-
* @param {number} [fidelity] - Resolution fidelity. Higher number means more pixels and better precision. Between 1 and 0.01.
|
|
8
|
-
* @returns {object} GeoTiff data
|
|
9
|
-
*/
|
|
10
|
-
function getTerrainGeoTIFF(stac_item, auth, fidelity = 0.05) {
|
|
11
|
-
|
|
12
|
-
const bbox = stac_item.bbox
|
|
13
|
-
const width = Math.round( stac_item.properties['proj:shape'][0] * fidelity )
|
|
14
|
-
const height = Math.round( stac_item.properties['proj:shape'][1] * fidelity )
|
|
15
|
-
|
|
16
|
-
// GET request for DHM WCS data
|
|
17
|
-
let url = auth.API_DHM_WCS_BASEURL
|
|
18
|
-
url += '?SERVICE=WCS&COVERAGE=dhm_terraen&RESPONSE_CRS=epsg:25832&CRS=epsg:25832&FORMAT=GTiff&REQUEST=GetCoverage&VERSION=1.0.0'
|
|
19
|
-
url += `&username=${ auth.API_DHM_USERNAME }&password=${ auth.API_DHM_PASSWORD }` // TODO: Should be auth stuff
|
|
20
|
-
url += `&height=${ height }`
|
|
21
|
-
url += `&width=${ width }`
|
|
22
|
-
url += `&bbox=${ bbox[0]},${ bbox[1]},${ bbox[2]},${ bbox[3]}`
|
|
23
|
-
|
|
24
|
-
return get(url, {}, false)
|
|
25
|
-
.then((response) => {
|
|
26
|
-
return response.arrayBuffer()
|
|
27
|
-
})
|
|
28
|
-
.then((arrayBuffer) => {
|
|
29
|
-
return consumeGeoTIFF(arrayBuffer)
|
|
30
|
-
})
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
async function consumeGeoTIFF(raw_data) {
|
|
34
|
-
const tiff = await fromArrayBuffer(raw_data)
|
|
35
|
-
const image = await tiff.getImage()
|
|
36
|
-
return image
|
|
37
|
-
}
|
|
38
3
|
|
|
4
|
+
/** Constrain coordinates to be within a bounding box */
|
|
39
5
|
function constrainToBbox(bbox, x, y) {
|
|
40
6
|
let new_x = x
|
|
41
7
|
let new_y = y
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dataforsyningen/saul",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
4
4
|
"description": "This is a collection of stand-alone methods for photogrammetry calculations and API interactions for 'Danske Skråfotos'.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"test": "echo 'TESTS WILL ONLY RUN UNDER NODE v18' && node ./test/saul-projection.test.js && node ./test/saul-core.test.js && node ./test/saul-elevation.test.js",
|
|
8
|
+
"test": "echo 'TESTS WILL ONLY RUN UNDER NODE v18' && node ./test/saul-projection.test.js && node ./test/saul-core.test.js && node ./test/saul-combined.test.js && node ./test/saul-elevation.test.js",
|
|
9
9
|
"docs": "jsdoc ./modules/*.js --destination docs"
|
|
10
10
|
},
|
|
11
11
|
"repository": {
|
|
@@ -17,7 +17,11 @@
|
|
|
17
17
|
"SDFI",
|
|
18
18
|
"saul"
|
|
19
19
|
],
|
|
20
|
-
"author":
|
|
20
|
+
"author": {
|
|
21
|
+
"name": "Styrelsen for Dataforsyning og Infrastruktur",
|
|
22
|
+
"email": "support@sdfi.dk",
|
|
23
|
+
"url": "https://sdfi.dk/"
|
|
24
|
+
},
|
|
21
25
|
"license": "MIT",
|
|
22
26
|
"bugs": {
|
|
23
27
|
"url": "https://github.com/SDFIdk/saul/issues"
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// You should add your own config.js with proper tokens, etc.
|
|
2
|
+
// Check config.js.example for info on how to set it up
|
|
3
|
+
import auth from '../config.js'
|
|
4
|
+
import { getSTAC, getTerrainGeoTIFF,getZ, getWorldXYZ, getImageXY } from '../index.js'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
// Vars
|
|
8
|
+
const resolution = 0.005 // Higher number means more points and better precision
|
|
9
|
+
const max_deviation = 0.5
|
|
10
|
+
|
|
11
|
+
/*
|
|
12
|
+
// North
|
|
13
|
+
let item_1 = {
|
|
14
|
+
id: '2021_83_29_2_0019_00003995',
|
|
15
|
+
xy: [1000,1000]
|
|
16
|
+
}
|
|
17
|
+
// East
|
|
18
|
+
let item_2 = {
|
|
19
|
+
id: '2021_83_29_4_0016_00002877'
|
|
20
|
+
}
|
|
21
|
+
// West
|
|
22
|
+
let item_3 = {
|
|
23
|
+
id: '2021_83_29_5_0022_00003276'
|
|
24
|
+
}
|
|
25
|
+
// South
|
|
26
|
+
let item_4 = {
|
|
27
|
+
id: '2021_83_29_3_0019_00003975'
|
|
28
|
+
}
|
|
29
|
+
// Nadir
|
|
30
|
+
let item_5 = {
|
|
31
|
+
id: '2021_83_29_1_0019_00003985'
|
|
32
|
+
}
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
/*
|
|
36
|
+
// North
|
|
37
|
+
let item_1 = {
|
|
38
|
+
id: '2021_83_33_2_0003_00002821',
|
|
39
|
+
xy: [8000,5000]
|
|
40
|
+
}
|
|
41
|
+
// East
|
|
42
|
+
let item_2 = {
|
|
43
|
+
id: '2021_83_33_4_0002_00000845'
|
|
44
|
+
}
|
|
45
|
+
// West
|
|
46
|
+
let item_3 = {
|
|
47
|
+
id: '2021_83_33_5_0005_00003192'
|
|
48
|
+
}
|
|
49
|
+
// South
|
|
50
|
+
let item_4 = {
|
|
51
|
+
id: '2021_83_33_3_0004_00002970'
|
|
52
|
+
}
|
|
53
|
+
// Nadir
|
|
54
|
+
let item_5 = {
|
|
55
|
+
id: '2021_83_33_1_0004_00002965'
|
|
56
|
+
}
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
// North
|
|
60
|
+
let item_1 = {
|
|
61
|
+
id: '2021_83_29_2_0019_00003995',
|
|
62
|
+
xy: [1000,1000]
|
|
63
|
+
}
|
|
64
|
+
// East
|
|
65
|
+
let item_2 = {
|
|
66
|
+
id: '2021_83_29_4_0016_00002877'
|
|
67
|
+
}
|
|
68
|
+
// West
|
|
69
|
+
let item_3 = {
|
|
70
|
+
id: '2021_83_29_5_0022_00003276'
|
|
71
|
+
}
|
|
72
|
+
// South
|
|
73
|
+
let item_4 = {
|
|
74
|
+
id: '2021_83_29_3_0019_00003975'
|
|
75
|
+
}
|
|
76
|
+
// Nadir
|
|
77
|
+
let item_5 = {
|
|
78
|
+
id: '2021_83_29_1_0019_00003985'
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Helper functions
|
|
82
|
+
function is_equalIsh(num1, num2, deviation = max_deviation) {
|
|
83
|
+
if (Math.abs(num1 - num2) > deviation) {
|
|
84
|
+
return false
|
|
85
|
+
} else {
|
|
86
|
+
return true
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function generateSTACurl(stac_item_id) {
|
|
90
|
+
return `/search?limit=1&crs=http://www.opengis.net/def/crs/EPSG/0/25832&ids=${ stac_item_id }`
|
|
91
|
+
}
|
|
92
|
+
async function enrichData(item) {
|
|
93
|
+
let new_item = Object.assign({}, item)
|
|
94
|
+
// add STAC item
|
|
95
|
+
new_item.item = await getSTAC(generateSTACurl(new_item.id), auth)
|
|
96
|
+
new_item.item = new_item.item.features[0]
|
|
97
|
+
// add terrain GeoTIFF
|
|
98
|
+
new_item.terrain = await getTerrainGeoTIFF(new_item.item, auth, resolution)
|
|
99
|
+
// Add imageXY
|
|
100
|
+
new_item.xy = getImageXY(new_item.item, item_1.xyz[0], item_1.xyz[1], item_1.xyz[2])
|
|
101
|
+
// Add world XYZ (from imageYX)
|
|
102
|
+
new_item.xyz = await getWorldXYZ({
|
|
103
|
+
xy: new_item.xy,
|
|
104
|
+
image: new_item.item,
|
|
105
|
+
terrain: new_item.terrain
|
|
106
|
+
})
|
|
107
|
+
// add kote
|
|
108
|
+
new_item.kote = await getZ(new_item.xyz[0], new_item.xyz[1], auth)
|
|
109
|
+
// add resolution info
|
|
110
|
+
new_item.ext_x = Math.round((new_item.item.bbox[2] - new_item.item.bbox[0]) * 100) / 100
|
|
111
|
+
new_item.ext_y = Math.round((new_item.item.bbox[3] - new_item.item.bbox[1]) * 100) / 100
|
|
112
|
+
new_item.z_pr_m_x = Math.round((new_item.item.properties['proj:shape'][0] / new_item.ext_x) * 100 * resolution) / 100
|
|
113
|
+
new_item.z_pr_m_y = Math.round((new_item.item.properties['proj:shape'][1] / new_item.ext_y) * 100 * resolution) / 100
|
|
114
|
+
const width = Math.round( new_item.item.properties['proj:shape'][0] * resolution )
|
|
115
|
+
const height = Math.round( new_item.item.properties['proj:shape'][1] * resolution )
|
|
116
|
+
new_item.z_points = width * height
|
|
117
|
+
return new_item
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Fetch image data and terrain
|
|
121
|
+
item_1.item = await getSTAC(generateSTACurl(item_1.id), auth)
|
|
122
|
+
item_1.item = item_1.item.features[0]
|
|
123
|
+
item_1.terrain = await getTerrainGeoTIFF(item_1.item, auth, resolution)
|
|
124
|
+
|
|
125
|
+
// Given image XY for one image, get world XYZ
|
|
126
|
+
item_1.xyz = await getWorldXYZ({
|
|
127
|
+
xy: item_1.xy,
|
|
128
|
+
image: item_1.item,
|
|
129
|
+
terrain: item_1.terrain
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
item_1.kote = await getZ(item_1.xyz[0], item_1.xyz[1], auth)
|
|
133
|
+
|
|
134
|
+
// Get image and corresponding world coordinates for other images (amongst other things)
|
|
135
|
+
item_2 = await enrichData(item_2)
|
|
136
|
+
item_3 = await enrichData(item_3)
|
|
137
|
+
item_4 = await enrichData(item_4)
|
|
138
|
+
item_5 = await enrichData(item_5)
|
|
139
|
+
|
|
140
|
+
// Compare items
|
|
141
|
+
console.table({
|
|
142
|
+
north: item_1,
|
|
143
|
+
east: item_2,
|
|
144
|
+
west: item_3,
|
|
145
|
+
south: item_4,
|
|
146
|
+
nadir: item_5
|
|
147
|
+
})
|
package/test/saul-core.test.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
// Testing saul-core methods
|
|
2
2
|
|
|
3
|
-
// You should add your own config.js with proper tokens,
|
|
3
|
+
// You should add your own config.js with proper tokens, etc.
|
|
4
4
|
// Check config.js.example for info on how to set it up
|
|
5
5
|
import auth from '../config.js'
|
|
6
6
|
|
|
7
7
|
import assert from 'assert'
|
|
8
|
-
import {getSTAC} from '../
|
|
9
|
-
import {world2image, image2world, getZ, iterate} from '../modules/saul-core.js'
|
|
8
|
+
import {getSTAC, world2image, image2world, getZ, iterate} from '../index.js'
|
|
10
9
|
|
|
11
10
|
/*
|
|
12
11
|
const item = await getSTAC('/collections/skraafotos2019/items/2019_83_37_2_0046_00001113', auth)
|
|
@@ -24,8 +23,7 @@ const image_x = 41839.698939
|
|
|
24
23
|
const image_y = 3204.326930
|
|
25
24
|
const world_elevation = 38.874336
|
|
26
25
|
|
|
27
|
-
function is_equalIsh(num1, num2) {
|
|
28
|
-
const deviation = 0.05
|
|
26
|
+
function is_equalIsh(num1, num2, deviation = 0.05) {
|
|
29
27
|
if (Math.abs(num1 - num2) > deviation) {
|
|
30
28
|
return false
|
|
31
29
|
} else {
|
|
@@ -65,7 +63,7 @@ try {
|
|
|
65
63
|
|
|
66
64
|
let xy = world2image(item, world_x, world_y, world_elevation)
|
|
67
65
|
|
|
68
|
-
assert(is_equalIsh(xy[0], image_x),
|
|
66
|
+
assert(is_equalIsh(xy[0], image_x, 1), `world2image fail: The x coordinate values ${xy[0]} ${image_x} are not equal`)
|
|
69
67
|
assert(is_equalIsh(xy[1], image_y), "world2image fail: The y coordinate values are not equal")
|
|
70
68
|
|
|
71
69
|
console.log("Test world2image OK")
|
|
@@ -1,19 +1,17 @@
|
|
|
1
|
-
// You should add your own config.js with proper tokens,
|
|
1
|
+
// You should add your own config.js with proper tokens, etc.
|
|
2
2
|
// Check config.js.example for info on how to set it up
|
|
3
3
|
import auth from '../config.js'
|
|
4
4
|
|
|
5
5
|
import assert from 'assert'
|
|
6
|
-
import { getTerrainGeoTIFF,
|
|
7
|
-
import { get } from '../modules/api.js'
|
|
8
|
-
import { getZ, getWorldXYZ, world2image } from '../modules/saul-core.js'
|
|
6
|
+
import { getElevation, get, getTerrainGeoTIFF, getZ, getWorldXYZ, world2image } from '../index.js'
|
|
9
7
|
|
|
10
8
|
// Vars
|
|
11
9
|
const stac_item = '2021_83_29_2_0019_00003995'
|
|
12
|
-
const fidelity = 0.
|
|
10
|
+
const fidelity = 0.03 // Higher number means more points and better precision
|
|
13
11
|
const max_deviation = 0.5
|
|
14
12
|
|
|
15
13
|
// STAC API endpoint
|
|
16
|
-
let url_stac = '
|
|
14
|
+
let url_stac = auth.API_STAC_BASEURL + '/search?limit=1&crs=http://www.opengis.net/def/crs/EPSG/0/25832&token=9b554b6c854184c3b0f377ffc7481585'
|
|
17
15
|
url_stac += `&ids=${ stac_item }`
|
|
18
16
|
|
|
19
17
|
function is_equalIsh(num1, num2, deviation = max_deviation) {
|
|
@@ -53,10 +51,10 @@ function testGetWorldXYZAnumberOfTimes(item, terrain, times) {
|
|
|
53
51
|
image: item,
|
|
54
52
|
terrain: terrain
|
|
55
53
|
}).then(world_xy => {
|
|
56
|
-
compareElevations(world_xy[0], world_xy[1], terrain)
|
|
54
|
+
compareElevations(world_xy[0], world_xy[1], terrain)
|
|
57
55
|
const image_coords = world2image(item, world_xy[0], world_xy[1], world_xy[2])
|
|
58
|
-
assert(is_equalIsh(image_coords[0], xy[0],
|
|
59
|
-
assert(is_equalIsh(image_coords[1], xy[1],
|
|
56
|
+
assert(is_equalIsh(image_coords[0], xy[0], 2), `Image x coordinates ${image_coords[0]} / ${xy[0]} do not match`)
|
|
57
|
+
assert(is_equalIsh(image_coords[1], xy[1], 2), `Image y coordinates ${image_coords[1]} / ${xy[1]} do not match`)
|
|
60
58
|
console.log('getWorldXYZ => world2image OK')
|
|
61
59
|
})
|
|
62
60
|
}
|
|
@@ -67,7 +65,7 @@ function compareElevations(x,y,geotiff) {
|
|
|
67
65
|
.then(elevation => {
|
|
68
66
|
getZ(x, y, auth)
|
|
69
67
|
.then(getz_e => {
|
|
70
|
-
assert(is_equalIsh(getz_e, elevation), `Elevations ${elevation} / ${getz_e} at ${x} ${y} do not match`)
|
|
68
|
+
assert(is_equalIsh(getz_e, elevation, 0.5), `Elevations ${elevation} / ${getz_e} at ${x} ${y} do not match`)
|
|
71
69
|
console.log(`Elevation at ${ x } ${ y } with delta ${Math.abs(elevation - getz_e).toFixed(2)} OK`)
|
|
72
70
|
})
|
|
73
71
|
})
|