Skip to content

Commit 8b39d2b

Browse files
Merge pull request #353 from Pomax/patch-1
Add an example of how to use geotiff to resolve GPS to elevation
2 parents cf05f52 + 9b2a982 commit 8b39d2b

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,64 @@ Further documentation can be found [here](https://geotiffjs.github.io/geotiff.js
4343

4444
## Example Usage
4545

46+
Geotiff gives you access to all GeoTIFF metadata, but does not offer any one specific higher level API (such as GDAL) for things like transforms or data extraction. However, you can write your own higher level API using this library, given your specific dataset needs.
47+
48+
As an example, here is how you would resolve GPS coordinates to elevation in a GeoTIFF that encodes WGS-84 compliant geo data:
49+
50+
```js
51+
import { fromUrl, fromArrayBuffer, fromBlob } from "geotiff";
52+
53+
const lerp = (a, b, t) => (1 - t) * a + t * b;
54+
55+
function transform(a, b, M, roundToInt = false) {
56+
const round = (v) => (roundToInt ? v | 0 : v);
57+
return [
58+
round(M[0] + M[1] * a + M[2] * b),
59+
round(M[3] + M[4] * a + M[5] * b),
60+
];
61+
}
62+
63+
// Load our data tile from url, arraybuffer, or blob, so we can work with it:
64+
const tiff = await fromArrayBuffer(...);
65+
const image = await tiff.getImage(); // by default, the first image is read.
66+
67+
// Construct the WGS-84 forward and inverse affine matrices:
68+
const { ModelPixelScale: s, ModelTiepoint: t } = image.fileDirectory;
69+
let [sx, sy, sz] = s;
70+
let [px, py, k, gx, gy, gz] = t;
71+
sy = -sy; // WGS-84 tiles have a "flipped" y component
72+
73+
const pixelToGPS = [gx, sx, 0, gy, 0, sy];
74+
console.log(`pixel to GPS transform matrix:`, pixelToGPS);
75+
76+
const gpsToPixel = [-gx / sx, 1 / sx, 0, -gy / sy, 0, 1 / sy];
77+
console.log(`GPS to pixel transform matrix:`, gpsToPixel);
78+
79+
// Convert a GPS coordinate to a pixel coordinate in our tile:
80+
const [gx1, gy1, gx2, gy2] = image.getBoundingBox();
81+
const lat = lerp(gy1, gy2, Math.random());
82+
const long = lerp(gx1, gx2, Math.random());
83+
console.log(`Looking up GPS coordinate (${lat.toFixed(6)},${long.toFixed(6)})`);
84+
85+
const [x, y] = transform(long, lat, gpsToPixel, true);
86+
console.log(`Corresponding tile pixel coordinate: [${x}][${y}]`);
87+
88+
// And as each pixel in the tile covers a geographic area, not a single
89+
// GPS coordinate, get the area that this pixel covers:
90+
const gpsBBox = [transform(x, y, pixelToGPS), transform(x + 1, y + 1, pixelToGPS)];
91+
console.log(`Pixel covers the following GPS area:`, gpsBBox);
92+
93+
// Finally, retrieve the elevation associated with this pixel's geographic area:
94+
const rasters = await image.readRasters();
95+
const { width, [0]: raster } = rasters;
96+
const elevation = raster[x + y * width];
97+
console.log(`The elevation at (${lat.toFixed(6)},${long.toFixed(6)}) is ${elevation}m`);
98+
```
99+
100+
## Advanced Example Usage
101+
102+
For more advanced examples of `geotiff` in larger codebases, please have a look at the following projects:
103+
46104
* [Slice view using Cesium.js (TAMP project)](http://www.youtube.com/watch?v=E6kFLtKgeJ8)
47105

48106
[![3D slice view](http://img.youtube.com/vi/E6kFLtKgeJ8/0.jpg)](http://www.youtube.com/watch?v=E6kFLtKgeJ8)

0 commit comments

Comments
 (0)