@dataforsyningen/saul 3.3.4 → 3.5.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.
Binary file
Binary file
package/index.js CHANGED
@@ -14,6 +14,7 @@ export {
14
14
  getSTAC,
15
15
  getDHM,
16
16
  getTerrainGeoTIFF,
17
+ getDenmarkGeoTiff,
17
18
  get,
18
19
  post
19
20
  } from './modules/api.js'
@@ -24,5 +25,6 @@ export {
24
25
  } from './modules/saul-projection.js'
25
26
 
26
27
  export {
27
- getElevation
28
+ getElevation,
29
+ visualizeGeotiff
28
30
  } from './modules/saul-elevation.js'
package/modules/api.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * SAUL API utilities
2
+ * SAUL API utilities
3
3
  */
4
4
 
5
5
  import { fromArrayBuffer } from 'geotiff'
@@ -160,7 +160,7 @@ function post(url, requestbody, token) {
160
160
  */
161
161
  function getDHM(query, auth) {
162
162
  const auth_params = `&username=${auth.API_DHM_TOKENA}&password=${auth.API_DHM_TOKENB}`
163
- return get(encodeURI(auth.API_DHM_BASEURL + query + auth_params))
163
+ return get(encodeURI(auth.API_DHM_BASEURL + query + auth_params), {cache: 'force-cache'})
164
164
  .then((data) => data)
165
165
  }
166
166
 
@@ -202,6 +202,11 @@ async function consumeGeoTIFF(raw_data) {
202
202
  return image
203
203
  }
204
204
 
205
+ function calcSizeRatio(sizeX, bbox) {
206
+ const ratio = ( bbox[0] - bbox[2] ) / ( bbox[1] - bbox[3] )
207
+ return Math.round(sizeX * ratio)
208
+ }
209
+
205
210
 
206
211
  /** Fetches a GeoTIFF with elevation data matching the bounding box of a STAC API item (image)
207
212
  * @param {object} stac_item - STAC API item from a featureCollection request
@@ -209,11 +214,12 @@ async function consumeGeoTIFF(raw_data) {
209
214
  * @param {number} [resolution] - Resolution (1 - 0.01). Higher number means more pixels and better precision.
210
215
  * @returns {object} GeoTiff data
211
216
  */
212
- function getTerrainGeoTIFF(stac_item, auth, resolution = 0.05) {
217
+ function getTerrainGeoTIFF(stac_item, auth, resolution = 0.05, sizeX = 300) {
213
218
 
214
219
  const bbox = stac_item.bbox
215
- const width = Math.round( stac_item.properties['proj:shape'][0] * resolution )
216
- const height = Math.round( stac_item.properties['proj:shape'][1] * resolution )
220
+ const sizeY = calcSizeRatio(sizeX, stac_item.bbox)
221
+ const width = stac_item.properties ? Math.round( stac_item.properties['proj:shape'][0] * resolution ) : sizeX
222
+ const height = stac_item.properties ? Math.round( stac_item.properties['proj:shape'][1] * resolution ) : sizeY
217
223
 
218
224
  // GET request for DHM WCS data
219
225
  let url = auth.API_DHM_WCS_BASEURL
@@ -232,6 +238,25 @@ function getTerrainGeoTIFF(stac_item, auth, resolution = 0.05) {
232
238
  })
233
239
  }
234
240
 
241
+ /**
242
+ * Fetches a geoTIFF with elevation data covering all of Denmark
243
+ * @param {Object} options
244
+ * @param {Object} options.src - URL to download a pre-generated GeoTiff.
245
+ * @param {Object} options.auth - API autentication data. See ../config.js.example for reference.
246
+ * @param {Number} options.size - Width of the geoTiff image to return
247
+ * @returns GeoTIFF raster with elevation data
248
+ */
249
+ function getDenmarkGeoTiff(options) {
250
+ if (options.src) {
251
+ return fetch(options.src)
252
+ .then(response => response.arrayBuffer())
253
+ .then(arrayBuffer => consumeGeoTIFF(arrayBuffer))
254
+ } else {
255
+ const auth = options.auth
256
+ const size = options.size ? options.size : 1000
257
+ return getTerrainGeoTIFF({bbox: [430000,6040000,900000,6413000]}, auth, null, size)
258
+ }
259
+ }
235
260
 
236
261
  export {
237
262
  get,
@@ -239,5 +264,7 @@ export {
239
264
  getSTAC,
240
265
  postSTAC,
241
266
  getDHM,
242
- getTerrainGeoTIFF
267
+ getTerrainGeoTIFF,
268
+ getDenmarkGeoTiff,
269
+ consumeGeoTIFF
243
270
  }
@@ -202,8 +202,8 @@ async function compareZ(options) {
202
202
  const delta = Math.abs(world_xyz[2] - options.z)
203
203
 
204
204
  // Check delta vs. limit. If the difference is too big, try building coordinates with the new z
205
- // Make sure the recursive loop ends at some point (iteration = 50) even if no precise z is found
206
- if (options.iteration < 50 && delta > options.limit) {
205
+ // Make sure the recursive loop ends after 20 iterations even if no precise z is found
206
+ if (options.iteration < 20 && delta > options.limit) {
207
207
  options.iteration++
208
208
  options.z = world_xyz[2]
209
209
  return compareZ(options)
@@ -1,52 +1,106 @@
1
- import { getTerrainGeoTIFF } from './api.js'
1
+ /**
2
+ * Maps a coordinate from the one coordinate system to another based on GeoTiff image dimensions.
3
+ * @param {Array} coord - EPSG:25832 X,Y coordinate pair
4
+ * @param {Array} bbox - Bounding box within input coordinate systtem. Consists of 2 EPSG:25832 coordinate pairs. Example: [x1,y1,x2,y2]
5
+ * @param {Array} imageDimensions - Width and height of a GeoTiff image. This will set the bounding box of the output coordinate system. Note: This coordinate system will have 0,0 set in the top right position of the image.
6
+ */
7
+ function convertCoordinate(coord, bbox1, imageDimensions) {
8
+
9
+ // Extract the coordinates from the bounding boxes
10
+ const [x1_min, y1_min, x1_max, y1_max] = bbox1
2
11
 
12
+ // Extract the coordinate to convert
13
+ const [x1, y1] = coord
3
14
 
4
- /** Constrain coordinates to be within a bounding box */
5
- function constrainToBbox(bbox, x, y) {
6
- let new_x = x
7
- let new_y = y
8
- if (x < bbox[0]) {
9
- new_x = bbox[0] + 1
10
- } else if (bbox[2] < x) {
11
- new_x = bbox[2] - 1
12
- }
13
- if (y < bbox[1]) {
14
- new_y = bbox[1] + 1
15
- } else if (bbox[3] < y) {
16
- new_y = bbox[3] - 1
17
- }
18
- return [new_x, new_y]
15
+ // Calculate the width and height of both bounding boxes
16
+ const width1 = x1_max - x1_min
17
+ const height1 = y1_max - y1_min
18
+ const width2 = imageDimensions[0]
19
+ const height2 = imageDimensions[1]
20
+
21
+ // Calculate the relative position in the first coordinate system
22
+ const x_relative = (x1 - x1_min) / width1
23
+ const y_relative = (y1 - y1_min) / height1
24
+
25
+ // Calculate the new position in the second coordinate system
26
+ const x2 = Math.abs(x_relative * width2)
27
+ const y2 = height2 - Math.abs(y_relative * height2)
28
+
29
+ return [x2, y2]
19
30
  }
20
31
 
21
- /** Calculates nearest elevation for given coordinate using geoTIFF terrain data
22
- * Heavily inspired by https://towardsdatascience.com/geotiff-coordinate-querying-with-javascript-5e6caaaf88cf
32
+ /**
33
+ * Calculates nearest elevation for given coordinate using geoTIFF terrain data
23
34
  * @param {number} x - EPSG:25832 X coordinate
24
35
  * @param {number} y - EPSG:25832 Y coordinate
25
- * @param {object} geoTiff - GeoTiff data output from getTerrainGeoTIFF() method
36
+ * @param {object} geoTiff - GeoTiff data output from getTerrainGeoTIFF() or getDenmarkGeoTiff() method
26
37
  * @returns {number} Elevation in meters
27
38
  */
28
39
  async function getElevation(x, y, geoTiff) {
29
-
40
+
30
41
  const bbox = geoTiff.getBoundingBox()
31
42
  const height = geoTiff.getHeight()
32
43
  const width = geoTiff.getWidth()
33
- const bboxWidth = bbox[2] - bbox[0]
34
- const bboxHeight = bbox[3] - bbox[1]
35
44
 
36
- const xy = constrainToBbox(bbox, x, y)
37
-
38
- const widthPct = ( xy[0] - bbox[0] ) / bboxWidth
39
- const heightPct = ( xy[1] - bbox[1] ) / bboxHeight
40
- const xPx = Math.floor( width * widthPct )
41
- const yPx = Math.floor( height * ( 1 - heightPct ) )
45
+ // Convert lat/lon to geotiff x/y
46
+ const [xPx, yPx] = convertCoordinate([x,y], bbox, [width, height])
47
+
48
+ // Fetch window of raster values around x/y
49
+ const window = [
50
+ Math.floor(xPx),
51
+ Math.floor(yPx),
52
+ Math.ceil(xPx),
53
+ Math.ceil(yPx)
54
+ ]
55
+
56
+ // Fetch elevation value from geoTiff rasters
57
+ const elevation_data = await geoTiff.readRasters({
58
+ window: window,
59
+ fillValue: 0
60
+ })
61
+
62
+ return elevation_data[0][0]
63
+ }
42
64
 
43
- const window = [ xPx, yPx, xPx + 1, yPx + 1 ]
44
- const elevation_data = await geoTiff.readRasters( {window} )
65
+ /** Creates an ASCII visualization of a terrain GeoTiff. Useful for display in a terminal.
66
+ * NOTE: You may want to use a downsmapled GeoTiff to fit within your terminal window. A GeoTiff pixel is represented by 3 characters each.
67
+ * @param {object} gTiff - GeoTiff output from getTerrainGeoTIFF() or getDenmarkGeoTiff() method
68
+ */
69
+ async function visualizeGeotiff(gTiff) {
70
+ console.log('--- GTIFF visualization ---')
71
+ const float32Arr = await gTiff.readRasters()
72
+ const tiffWidth = gTiff.getWidth()
73
+ const rasters = float32Arr[0]
74
+ let lines = []
75
+ let line = ''
76
+ for (let i = 0; i < rasters.length; i++) {
77
+ if (i % tiffWidth === 0) {
78
+ lines.push(line)
79
+ line = ''
80
+ }
81
+ line += zeroPadNumber(rasters[i])
82
+ }
83
+ for (const l of lines) {
84
+ console.log(l)
85
+ }
86
+ }
45
87
 
46
- return Math.round( elevation_data[0][0] * 10) / 10
88
+ /** Converts numbers to strings in a 3-letter format. Ex. `002`, `0-3` (for negative numbers), or `123` */
89
+ function zeroPadNumber(input) {
90
+ if (input === 0) {
91
+ return "..."
92
+ } else if (input < 0) {
93
+ return `0${input.toFixed(0)}`
94
+ } else if (input < 10) {
95
+ return `00${Math.floor(input)}`
96
+ } else if (input < 100) {
97
+ return `0${Math.floor(input)}`
98
+ } else {
99
+ return `${Math.floor(input)}`
100
+ }
47
101
  }
48
102
 
49
103
  export {
50
- getTerrainGeoTIFF,
51
- getElevation
104
+ getElevation,
105
+ visualizeGeotiff
52
106
  }
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@dataforsyningen/saul",
3
- "version": "3.3.4",
3
+ "version": "3.5.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-combined.test.js && node ./test/saul-elevation.test.js",
8
+ "test": "echo 'Tests require Node.js >= 18.0.0' && 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": {
@@ -0,0 +1,250 @@
1
+ import auth from '../config.js'
2
+ import { getElevation, visualizeGeotiff } from '../modules/saul-elevation.js'
3
+ import { getImageXY, getWorldXYZ } from '../modules/saul-core.js'
4
+ import { getDenmarkGeoTiff, consumeGeoTIFF } from '../modules/api.js'
5
+
6
+ const geoTiffResolution = 1000
7
+
8
+ const worldxy = [533344, 6172951] // World XY Point in all images near Vejle
9
+ const image1xy = [8566,4105] // Point/Image XY in `image1`
10
+ const image1 = '2023_83_29_2_0019_00001130' // Vejle N
11
+ const image2 = '2023_83_29_4_0017_00001752' // Vejle E
12
+ const image3 = '2023_83_29_3_0019_00001149' // Veje S
13
+ const image4 = '2023_83_29_5_0022_00002826' // Vejle W
14
+ const image0 = '2023_83_29_1_0019_00001139' // Vejle Nadir
15
+
16
+ const point1 = [724400, 6175773] // Rådhuspladsen
17
+ const point2 = [595686, 6170394] // In the sea
18
+ const point3 = [542656, 6217825] // Near Himmelbjerg
19
+ const point4 = [480770, 6087529] // Marshes in the west
20
+ const point5 = [533394, 6173015] // Steep street in Vejle
21
+ const point6 = [533381, 6173108] // Vejle 2
22
+ const point7 = [533339, 6172860] // Vejle 3
23
+
24
+ const pointn = [596610, 6402161] // Skagen
25
+ const points = [692008, 6049902] // Gedser
26
+ const pointø = [892999, 6147725] // Christians Ø
27
+ const pointv = [441977, 6157385] // Blåvands hug
28
+
29
+ function fetchKote(worldXY) {
30
+ return fetch(`https://services.datafordeler.dk/DHMTerraen/DHMKoter/1.0.0/GEOREST/HentKoter?geop=POINT(${worldXY[0]} ${worldXY[1]})&elevationmodel=dtm&username=${auth.API_DHM_TOKENA}&password=${auth.API_DHM_TOKENB}`)
31
+ .then((response) => {
32
+ return response.json()
33
+ })
34
+ .then((kote) => {
35
+ return kote.HentKoterRespons.data[0].kote
36
+ })
37
+ }
38
+
39
+ function fetchImageData(imageId) {
40
+ return fetch(`https://api.dataforsyningen.dk/rest/skraafoto_api/v1.0/search?limit=1&crs=http://www.opengis.net/def/crs/EPSG/0/25832&ids=${imageId}&token=e88d7be6754140025ebeb63d57e991ae`)
41
+ .then((response) => response.json())
42
+ .then((data) => {
43
+ return data.features[0]
44
+ })
45
+ }
46
+
47
+ /*
48
+ * Example request to get terrain data for all of DK
49
+ * https://services.datafordeler.dk/DHMNedboer/dhm_wcs/1.0.0/WCS?SERVICE=WCS&COVERAGE=dhm_terraen&RESPONSE_CRS=epsg:25832&CRS=epsg:25832&FORMAT=GTiff&REQUEST=GetCoverage&VERSION=1.0.0&username=QKJBQATHVS&password=ytxCA8UGM5n0Z*zi&height=1000&width=1000&bbox=430000,6040000,900000,6413000
50
+ */
51
+
52
+ console.log('-------------------------------------------------------')
53
+ console.log('-- Experiments with pan-Danish GeoTiff terrain model --')
54
+ console.log('-------------------------------------------------------')
55
+
56
+ /*
57
+ It should
58
+ - fetch geotiff from all of DK
59
+ - fetch image data from several images covering the same area
60
+ - should simulate a click in one image (img1 at [8566,4105])
61
+ - should calculate worldxyz 1 from that click
62
+ - should calculate imagexy in another image
63
+ - should calculate worldxyz 2 from that imagexy
64
+ - should compare worldxyz 1 and worldxyz 2
65
+ - should compare worldxyz 1 z and worldxyz 2 z and kote
66
+ */
67
+
68
+ // Get GTiff from API
69
+ // const DKGeoTiff = await getDenmarkGeoTiff({auth: auth, size: geoTiffResolution})
70
+
71
+ // Get big GTiff
72
+ const DKGeoTiff = await getDenmarkGeoTiff({src: 'http://localhost:7701/dk-terrain.tiff'})
73
+
74
+ // Get tiny GTiff
75
+ //const DKGeoTiff = await getDenmarkGeoTiff({src: 'http://localhost:7701/tiny-dk-terrain.tiff'})
76
+
77
+ const imgData0 = await fetchImageData(image0)
78
+ const imgData1 = await fetchImageData(image1)
79
+ const imgData2 = await fetchImageData(image2)
80
+ const imgData3 = await fetchImageData(image3)
81
+ const imgData4 = await fetchImageData(image4)
82
+
83
+ // Simulate click in image north at [8566,4105]
84
+ const calcdWorldXYZ1 = await getWorldXYZ({
85
+ xy: image1xy,
86
+ image: imgData1,
87
+ terrain: DKGeoTiff
88
+ })
89
+ const calcdImageXY2 = getImageXY(imgData2, ...calcdWorldXYZ1)
90
+ const calcdWorldXYZ2 = await getWorldXYZ({
91
+ xy: calcdImageXY2,
92
+ image: imgData2,
93
+ terrain: DKGeoTiff
94
+ })
95
+ const calcdImageXY3 = getImageXY(imgData3, ...calcdWorldXYZ2)
96
+ const calcdWorldXYZ3 = await getWorldXYZ({
97
+ xy: calcdImageXY3,
98
+ image: imgData3,
99
+ terrain: DKGeoTiff
100
+ })
101
+ const calcdImageXY4 = getImageXY(imgData4, ...calcdWorldXYZ3)
102
+ const calcdWorldXYZ4 = await getWorldXYZ({
103
+ xy: calcdImageXY4,
104
+ image: imgData4,
105
+ terrain: DKGeoTiff
106
+ })
107
+ const calcdImageXY0 = getImageXY(imgData0, ...calcdWorldXYZ4)
108
+ const calcdWorldXYZ0 = await getWorldXYZ({
109
+ xy: calcdImageXY0,
110
+ image: imgData0,
111
+ terrain: DKGeoTiff
112
+ })
113
+ const calcdImageXY10 = getImageXY(imgData1, ...calcdWorldXYZ0)
114
+ const calcdWorldXYZ10 = await getWorldXYZ({
115
+ xy: calcdImageXY10,
116
+ image: imgData1,
117
+ terrain: DKGeoTiff
118
+ })
119
+
120
+ function getRandomPoint() {
121
+ const bbox = [430000,6040000,900000,6413000]
122
+ const width = bbox[2] - bbox[0]
123
+ const height = bbox[3] - bbox[1]
124
+ const randomX = bbox[0] + (Math.random() * width)
125
+ const randomY = bbox[1] + (Math.random() * height)
126
+ return [randomX, randomY]
127
+ }
128
+
129
+ const randomPoint1 = getRandomPoint()
130
+ const randomPoint2 = getRandomPoint()
131
+ const randomPoint3 = getRandomPoint()
132
+ const randomPoint4 = getRandomPoint()
133
+ const randomPoint5 = getRandomPoint()
134
+ const randomPoint6 = getRandomPoint()
135
+ const randomPoint7 = getRandomPoint()
136
+ const randomPoint8 = getRandomPoint()
137
+ const randomPoint9 = getRandomPoint()
138
+ const randomPoint10 = getRandomPoint()
139
+
140
+ console.log('From origin, use world coordinate to calculate image coordinate.')
141
+ console.log('Then uses that image coordinate to calculate world coordinate and feed it into the next image calculations.')
142
+ console.table({
143
+ origins: {worldxyz: worldxy, imagexy: image1xy},
144
+ image1: {worldxyz: calcdWorldXYZ1, imagexy: image1xy},
145
+ image2: {worldxyz: calcdWorldXYZ2, imagexy: calcdImageXY2},
146
+ image3: {worldxyz: calcdWorldXYZ3, imagexy: calcdImageXY3},
147
+ image4: {worldxyz: calcdWorldXYZ4, imagexy: calcdImageXY4},
148
+ image0: {worldxyz: calcdWorldXYZ0, imagexy: calcdImageXY0},
149
+ back_to_image1: {worldxyz: calcdWorldXYZ10, imagexy: calcdImageXY10}
150
+ })
151
+
152
+ console.log('Using image px coordinate to calculate a world coordinate and back again.')
153
+ console.table({
154
+ imageXY: {
155
+ original: [8566,4105],
156
+ 'round-trip': getImageXY(imgData1, ...calcdWorldXYZ0)
157
+ }
158
+ })
159
+
160
+ console.log('Samle elevations fetched from kote API or calculated from GeoTiff:')
161
+ console.table({
162
+ 'Rådhuspladsen': {
163
+ kote: await fetchKote(point1),
164
+ gtiff: await getElevation(...point1, DKGeoTiff)
165
+ },
166
+ 'In the sea': {
167
+ kote: await fetchKote(point2),
168
+ gtiff: await getElevation(...point2, DKGeoTiff)
169
+ },
170
+ 'Near Himmelbjerg': {
171
+ kote: await fetchKote(point3),
172
+ gtiff: await getElevation(...point3, DKGeoTiff)
173
+ },
174
+ 'Marshes in the west': {
175
+ kote: await fetchKote(point4),
176
+ gtiff: await getElevation(...point4, DKGeoTiff)
177
+ },
178
+ 'Vejle 1': {
179
+ kote: await fetchKote(point5),
180
+ gtiff: await getElevation(...point5, DKGeoTiff)
181
+ },
182
+ 'Vejle 2': {
183
+ kote: await fetchKote(point6),
184
+ gtiff: await getElevation(...point6, DKGeoTiff)
185
+ },
186
+ 'Vejle 3': {
187
+ kote: await fetchKote(point7),
188
+ gtiff: await getElevation(...point7, DKGeoTiff)
189
+ },
190
+ 'Skagen': {
191
+ kote: await fetchKote(pointn),
192
+ gtiff: await getElevation(...pointn, DKGeoTiff)
193
+ },
194
+ 'Gedser': {
195
+ kote: await fetchKote(points),
196
+ gtiff: await getElevation(...points, DKGeoTiff)
197
+ },
198
+ 'Blåvand': {
199
+ kote: await fetchKote(pointv),
200
+ gtiff: await getElevation(...pointv, DKGeoTiff)
201
+ },
202
+ 'Chr. Ø': {
203
+ kote: await fetchKote(pointø),
204
+ gtiff: await getElevation(...pointø, DKGeoTiff)
205
+ },
206
+ 'Random 1': {
207
+ kote: await fetchKote(randomPoint1),
208
+ gtiff: await getElevation(...randomPoint1, DKGeoTiff)
209
+ },
210
+ 'Random 2': {
211
+ kote: await fetchKote(randomPoint2),
212
+ gtiff: await getElevation(...randomPoint2, DKGeoTiff)
213
+ },
214
+ 'Random 3': {
215
+ kote: await fetchKote(randomPoint3),
216
+ gtiff: await getElevation(...randomPoint3, DKGeoTiff)
217
+ },
218
+ 'Random 4': {
219
+ kote: await fetchKote(randomPoint4),
220
+ gtiff: await getElevation(...randomPoint4, DKGeoTiff)
221
+ },
222
+ 'Random 5': {
223
+ kote: await fetchKote(randomPoint5),
224
+ gtiff: await getElevation(...randomPoint5, DKGeoTiff)
225
+ },
226
+ 'Random 6': {
227
+ kote: await fetchKote(randomPoint6),
228
+ gtiff: await getElevation(...randomPoint6, DKGeoTiff)
229
+ },
230
+ 'Random 7': {
231
+ kote: await fetchKote(randomPoint7),
232
+ gtiff: await getElevation(...randomPoint7, DKGeoTiff)
233
+ },
234
+ 'Random 8': {
235
+ kote: await fetchKote(randomPoint8),
236
+ gtiff: await getElevation(...randomPoint8, DKGeoTiff)
237
+ },
238
+ 'Random 9': {
239
+ kote: await fetchKote(randomPoint9),
240
+ gtiff: await getElevation(...randomPoint9, DKGeoTiff)
241
+ },
242
+ 'Random 10': {
243
+ kote: await fetchKote(randomPoint10),
244
+ gtiff: await getElevation(...randomPoint10, DKGeoTiff)
245
+ }
246
+ })
247
+
248
+ console.log('got DKGeotiff', (DKGeoTiff.source.arrayBuffer.byteLength / 1024), 'Kb', pointø)
249
+
250
+ //visualizeGeotiff(DKGeoTiff)
@@ -3,6 +3,9 @@
3
3
  import auth from '../config.js'
4
4
  import { getSTAC, getTerrainGeoTIFF,getZ, getWorldXYZ, getImageXY } from '../index.js'
5
5
 
6
+ console.log('---------------')
7
+ console.log('Combined tests ')
8
+ console.log('---------------')
6
9
 
7
10
  // Vars
8
11
  const resolution = 0.005 // Higher number means more points and better precision
@@ -86,9 +89,11 @@ function is_equalIsh(num1, num2, deviation = max_deviation) {
86
89
  return true
87
90
  }
88
91
  }
92
+
89
93
  function generateSTACurl(stac_item_id) {
90
94
  return `/search?limit=1&crs=http://www.opengis.net/def/crs/EPSG/0/25832&ids=${ stac_item_id }`
91
95
  }
96
+
92
97
  async function enrichData(item) {
93
98
  let new_item = Object.assign({}, item)
94
99
  // add STAC item
@@ -7,6 +7,10 @@ import auth from '../config.js'
7
7
  import assert from 'assert'
8
8
  import {getSTAC, world2image, image2world, getZ, iterate} from '../index.js'
9
9
 
10
+ console.log('---------------')
11
+ console.log(' Core tests ')
12
+ console.log('---------------')
13
+
10
14
  /*
11
15
  const item = await getSTAC('/collections/skraafotos2019/items/2019_83_37_2_0046_00001113', auth)
12
16
  const world_x = 580341
@@ -64,7 +68,7 @@ try {
64
68
  let xy = world2image(item, world_x, world_y, world_elevation)
65
69
 
66
70
  assert(is_equalIsh(xy[0], image_x, 1), `world2image fail: The x coordinate values ${xy[0]} ${image_x} are not equal`)
67
- assert(is_equalIsh(xy[1], image_y), "world2image fail: The y coordinate values are not equal")
71
+ assert(is_equalIsh(xy[1], image_y, 1), `world2image fail: The y coordinate values ${xy[1]} ${image_y} are not equal`)
68
72
 
69
73
  console.log("Test world2image OK")
70
74
 
@@ -5,6 +5,10 @@ import auth from '../config.js'
5
5
  import assert from 'assert'
6
6
  import { getElevation, get, getTerrainGeoTIFF, getZ, getWorldXYZ, world2image } from '../index.js'
7
7
 
8
+ console.log('---------------')
9
+ console.log('Elevation tests')
10
+ console.log('---------------')
11
+
8
12
  // Vars
9
13
  const stac_item = '2021_83_29_2_0019_00003995'
10
14
  const fidelity = 0.03 // Higher number means more points and better precision
@@ -65,7 +69,7 @@ function compareElevations(x,y,geotiff) {
65
69
  .then(elevation => {
66
70
  getZ(x, y, auth)
67
71
  .then(getz_e => {
68
- assert(is_equalIsh(getz_e, elevation, 0.5), `Elevations ${elevation} / ${getz_e} at ${x} ${y} do not match`)
72
+ assert(is_equalIsh(getz_e, elevation, 2.7), `Elevations ${elevation} / ${getz_e} at ${x} ${y} are way apart`)
69
73
  console.log(`Elevation at ${ x } ${ y } with delta ${Math.abs(elevation - getz_e).toFixed(2)} OK`)
70
74
  })
71
75
  })
@@ -4,6 +4,10 @@ import assert from 'assert'
4
4
  import proj4 from 'proj4'
5
5
  import {epsg25832proj, createTranslator} from '../index.js'
6
6
 
7
+ console.log('----------------')
8
+ console.log('Projection tests')
9
+ console.log('----------------')
10
+
7
11
  // Test epsg25832proj
8
12
  try {
9
13