{"_id":"geotiff.js","_rev":"1-a6c799e4ca34ce279fd9390bb7098cad","name":"geotiff.js","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.1":{"name":"geotiff.js","version":"1.0.1","description":"GeoTIFF image decoding in JavaScript","repository":{"type":"git","url":"git+https://github.com/geotiffjs/geotiff.js.git"},"keywords":["TIFF","GeoTIFF","image","raster"],"main":"dist/main.js","dependencies":{"pako":"^1.0.3","xmldom":"0.1.*"},"devDependencies":{"babel-cli":"^6.26.0","babel-core":"^6.26.0","babel-eslint":"^7.1.1","babel-loader":"^7.1.2","babel-plugin-syntax-async-functions":"^6.13.0","babel-plugin-transform-async-to-generator":"^6.16.0","babel-plugin-transform-runtime":"^6.23.0","babel-polyfill":"^6.26.0","babel-preset-env":"^1.6.1","chai":"^3.5.0","detect-node":"^2.0.3","es6-promise":"^4.0.5","eslint":"^4.18.0","eslint-config-airbnb":"^16.1.0","eslint-plugin-import":"^2.8.0","eslint-plugin-jsx-a11y":"^6.0.3","eslint-plugin-react":"^7.7.0","express":"^4.16.3","isomorphic-fetch":"^2.2.1","jsdoc":"^3.5.5","jsdoc-babel":"^0.2.1","jshint-stylish":"^2.2.1","mocha":"^3.1.2","webpack":"^3.10.0","webpack-dev-server":"^2.11.1","worker-loader":"^1.1.1"},"scripts":{"dev":"webpack-dev-server -d -w --content-base test","watch":"webpack -d -w","build:clean":"rm -rf dist/*","bundle:dev":"webpack -d ","bundle:prod":"NODE_ENV=production webpack -p","build:babel":"babel src/ -d dist","build:babel:watch":"babel src/ -d dist -w","build":"npm run build:clean ; npm run bundle:dev ; npm run bundle:prod ; npm run build:babel","test":"mocha --compilers js:babel-core/register --require babel-polyfill","lint":"eslint src","docs":"rm -rf docs/*; jsdoc -c .jsdoc.json -r src README.md -d docs","prepublish":"npm run build","prepare":"npm run build"},"author":{"name":"Fabian Schindler"},"contributors":[{"name":"Fabian Schindler","email":"fabian.schindler@eox.at"}],"license":"MIT","gitHead":"6e98b68040bbf61c9fca73f3db711d9eb1b38569","bugs":{"url":"https://github.com/geotiffjs/geotiff.js/issues"},"homepage":"https://github.com/geotiffjs/geotiff.js#readme","_id":"geotiff.js@1.0.1","_npmVersion":"6.4.1","_nodeVersion":"8.12.0","_npmUser":{"name":"pexraytech","email":"hai.nguyen@pexraytech.com"},"dist":{"integrity":"sha512-zf9unbKZQQnLk/Jq2F0+aCClBLZdiLN29UJreU12QB163HzuY1WjHiAbrig8Hl/FeIhFzd8GBfa/6M/rlaLqMg==","shasum":"32701d218632a47bce39bf21351781aabf39cdb2","tarball":"https://registry.npmjs.org/geotiff.js/-/geotiff.js-1.0.1.tgz","fileCount":54,"unpackedSize":4088668,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdgJ/1CRA9TVsSAnZWagAAtWEP+QGxRjHSgMSGWfPnlmQH\nWLvPPlUX5awT6inf26UgFcAYDL8uRrBwniksnmdevqXvsegABRCBxt3pffB8\n7RlL/VgSJoJQDX7yuuSv3azkitMqTS74e4UpUySFW1OnJO88og+f4deSpEBS\ndHlQ/gbbxoiM8L/JnwQG/0Xd1b1MRZFrU+xdHkO6QlF35J4DAi0uRseNZiou\nrzT2A7i4oH4JbPf+tUYh31wCaZYXx1Qovr3q3Zn0MrBAq9s7S9lTSlFgUdef\niOMpPFsZzo+QLJZQeuWjWJbhk9z5NRo12jxMbxQqJMz97NxwC/Sc/uCLOBn0\nMNls+Y/TiZRr87l2x1ey4I1pKAIvxxmiibxJ7POFiuXbOA1E0KbGyT3zBDbW\nPhvLAGuqG1pgtcJspDHYEjtRRi62gsOQrwyHu9W/WhEvSsyQnPauoA+ikV+G\nM7OzNgvRROEpjChRb4jRiUp2obhW/zD9oepaNx/RYwN9c/9LP4JvJ8j5UdUq\n0F9XkroclmyU0KrogwTXT++1hhjjvF/I0gPZXObwMs/o9bpsNVFf2qdBo/fq\nPLJUFEE144r6rS4ff3ssmMR99i368IA1nnSyBZJKw2utubvFCIH7vTcNtjQA\nRrmlPVulcMPHkULYD29f0D/xbM9CYTy+sV2cv6tQ6WvxTngLtvAx5u/eYSE7\nkAw2\r\n=OeLE\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCiPD9Kvqg0TamvKbeajs++g8ueBcnLyH6te4VbF4ezmwIhAMmepGMozZJbwOUMxfFASw+l8Yc6i6afFSdiPdL0GsFz"}]},"maintainers":[{"name":"pexraytech","email":"hai.nguyen@pexraytech.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/geotiff.js_1.0.1_1568710644667_0.43899321906169275"},"_hasShrinkwrap":false}},"time":{"created":"2019-09-17T08:57:24.666Z","1.0.1":"2019-09-17T08:57:24.907Z","modified":"2022-05-03T14:10:15.602Z"},"maintainers":[{"name":"pexraytech","email":"hai.nguyen@pexraytech.com"}],"description":"GeoTIFF image decoding in JavaScript","homepage":"https://github.com/geotiffjs/geotiff.js#readme","keywords":["TIFF","GeoTIFF","image","raster"],"repository":{"type":"git","url":"git+https://github.com/geotiffjs/geotiff.js.git"},"contributors":[{"name":"Fabian Schindler","email":"fabian.schindler@eox.at"}],"author":{"name":"Fabian Schindler"},"bugs":{"url":"https://github.com/geotiffjs/geotiff.js/issues"},"license":"MIT","readme":"# geotiff.js\n[![Build Status](https://travis-ci.org/geotiffjs/geotiff.js.svg)](https://travis-ci.org/geotiffjs/geotiff.js) [![Dependency Status](https://www.versioneye.com/user/projects/566af91d4e049b0041000083/badge.svg?style=flat)](https://www.versioneye.com/user/projects/566af91d4e049b0041000083) [![npm version](https://badge.fury.io/js/geotiff.svg)](https://badge.fury.io/js/geotiff) [![Gitter chat](https://badges.gitter.im/geotiffjs/geotiff.js.png)](https://gitter.im/geotiffjs/Lobby)\n\nRead (geospatial) metadata and raw array data from a wide variety of different\n(Geo)TIFF files types.\n\n## Features\n\nCurrently available functionality:\n\n  * Parsing TIFFs from various sources:\n    * remote (via `fetch` or XHR)\n    * from a local `ArrayBuffer`\n    * from the filesystem (on Browsers using the `FileReader` and on node using the filesystem functions)\n  * Parsing the headers of all possible TIFF files\n  * Rudimentary extraction of geospatial metadata\n  * Reading raster data from:\n    * stripped images\n    * tiled images\n    * band interleaved images\n    * pixel interleaved images\n  * Supported data-types:\n    * (U)Int8/16/32\n    * Float32/64\n  * Enabled compressions:\n    * no compression\n    * Packbits\n    * LZW\n    * Deflate (with floating point or horizontal predictor support)\n    * JPEG\n  * Automatic selection of overview level to read from\n  * Subsetting via an image window or bounding box and selected bands\n  * Reading of samples into separate arrays or a single pixel-interleaved array\n  * Configurable tile/strip cache\n  * Configurable Pool of workers to increase decoding efficiency\n  * Utility functions for geospatial parameters (Bounding Box, Origin, Resolution)\n  * Limited [bigTIFF](http://bigtiff.org/#FILE_FORMAT) support\n  * Automated testing via PhantomJS\n\nFurther documentation can be found [here](https://geotiffjs.github.io/geotiff.js/).\n\n## Example Usage\n\n* [Slice view using Cesium.js (TAMP project)](http://www.youtube.com/watch?v=E6kFLtKgeJ8)\n\n[![3D slice view](http://img.youtube.com/vi/E6kFLtKgeJ8/0.jpg)](http://www.youtube.com/watch?v=E6kFLtKgeJ8)\n\n* [Contour generation using d3-contour](https://bl.ocks.org/mbostock/83c0be21dba7602ee14982b020b12f51)\n\n[![contour](https://pbs.twimg.com/card_img/850410549196271616/ZKcdfREH?format=jpg&name=600x314)](https://bl.ocks.org/mbostock/83c0be21dba7602ee14982b020b12f51)\n\n## Setup\n\nTo setup the repository do the following steps:\n\n```bash\n# clone repo\ngit clone https://github.com/constantinius/geotiff.js.git\ncd geotiff.js/\n\n# install development dependencies\nnpm install\n```\n\n## Testing and Building\n\nIn order to run the tests you first have to set up the test data. This requires\nthe [GDAL](http://gdal.org/) and [ImageMagick](http://imagemagick.org/) tools.\nInstallation of these tools varies according to the operating system, the\nfollowing listing shows the installation on Ubuntu (using the ubuntugis-unstable\nrepository):\n```bash\nsudo add-apt-repository -y ppa:ubuntugis/ubuntugis-unstable\nsudo apt-get update\nsudo apt-get install -y gdal-bin imagemagick\n```\n\nWhen GDAL and ImageMagick is installed, the test data setup script can be run:\n```bash\ncd test/data\nsh setup_data.sh\ncd -\n```\n\nTo test the library (using PhantomJS, karma, mocha and chai) do the following:\n\n```bash\nnpm test\n```\n\nTo do some in-browser testing do:\n\n```bash\nnpm run dev\n```\n\nand navigate to `http://localhost:8090/`\n\nTo build the library do:\n\n```bash\nnpm run build\n```\n\nThe output is written to `dist/geotiff.browserify.js` and `dist/geotiff.browserify.min.js`.\n\n## Usage\n\ngeotiff.js works with both `require` and the global variable `GeoTIFF`:\n\n```javascript\nconst GeoTIFF = require('geotiff');\n// or\nimport GeoTIFF from 'geotiff';\n```\n\nor:\n\n```html\n<script src=\"dist/geotiff.bundle.js\"></script>\n<!-- or use the minified version:\n  <script src=\"dist/geotiff.bundle.min.js\"></script>\n-->\n<script>\n  console.log(GeoTIFF);\n</script>\n```\n\nTo parse a GeoTIFF, first a data source is required. To help with the development,\nthere are shortcuts available. The following creates a source that reads from a\nremote GeoTIFF referenced by a URL:\n\n```javascript\nGeoTIFF.fromUrl(someUrl)\n  .then(tiff => { /* ... */});\n\n// or when using async/await\n(async function() {\n  const tiff = await GeoTIFF.fromUrl(someUrl);\n  // ...\n})()\n```\n\nNote: the interactions with geotiff.js objects are oftentimes asynchronous. For\nthe sake of brevity we will only show the async/await syntax and not the\n`Promise` based one in the following examples.\n\nAccessing remote images is just one way to open TIFF images with geotiff.js. Other\noptions are reading from a local `ArrayBuffer`:\n\n```javascript\n// using local ArrayBuffer\nconst response = await fetch(someUrl);\nconst arrayBuffer = await response.arrayBuffer();\nconst tiff = await GeoTIFF.fromArrayBuffer(arrayBuffer);\n```\n\nor a `Blob`/`File`:\n\n```html\n<input type=\"file\" id=\"file\">\n<script>\n  const input = document.getElementById('file'):\n  input.onchange = async function() {\n    const tiff = await GeoTIFF.fromBlob(input.files[0]);\n  }\n</script>\n```\n\nNow that we have opened the TIFF file, we can inspect it. The TIFF is structured\nin a small header and a list of one or more images (Image File Directory, IFD to \nuse the TIFF nomenclature). To get one image by index the `getImage()` function\nmust be used. This is again an asynchronous operation, as the IFDs are loaded\nlazily:\n\n```javascript\nconst image = await tiff.getImage(); // by default, the first image is read.\n```\n\nNow that we have obtained a `GeoTIFFImage` object we can inspect its metadata \n(like size, tiling, number of samples, geographical information, etc.). All\nthe metadata is parsed once the IFD is first parsed, thus the access to that\nis synchronous:\n\n```javascript\nconst width = image.getWidth();\nconst height = image.getHeight();\nconst tileWidth = image.getTileWidth();\nconst tileHeight = image.getTileHeight();\nconst samplesPerPixel = image.getSamplesPerPixel();\n\n// when we are actually dealing with geo-data the following methods return\n// meaningful results:\nconst origin = image.getOrigin();\nconst resolution = image.getResolution();\nconst bbox = image.getBoundingBox();\n```\n\nThe actual raster data is not fetched and parsed automatically. This is because\nit is usually much more spacious and the decoding of the pixels can be time\nconsuming due to the necessity of decompression.\n\nTo read a whole image into one big array of arrays the following method call can be used:\n\n```javascript\nconst data = await image.readRasters();\n```\n\nFor convenience the result always has a `width` and `height` attribute:\n\n```javascript\nconst data = await image.readRasters();\nconst { width, height } = data;\n```\n\nBy default, the raster is split to a separate array for each component. For an RGB image\nfor example, we'd get three arrays, one for red, green and blue.\n\n```javascript\nconst [red, green, blue] = await image.readRasters();\n```\n\nIf we want instead all the bands interleaved in one big array, we have to pass the\n`interleave: true` option:\n\n```javascript\nconst [r0, g0, b0, r1, g1, b1, ...] = await image.readRasters({ interleave: true });\n```\n\nIf we are only interested in a specific region of the image, the `window` option can be\nused to limit reading in that bounding box. Note: the bounding box is in 'image coordinates'\nnot geographical ones:\n\n```javascript\nconst left = 50;\nconst top = 10;\nconst right = 150;\nconst bottom = 60;\n\nconst data = await image.readRasters({ window: [left, top, right, bottom] });\n```\n\nThis image window can go beyond the image bounds. In that case it might be usefull to supply\na `fillValue: value` option (can also be an array, one value for each sample).\n\nIt is also possible to just read specific samples for each pixel. For example, we can only\nread the red component from an RGB image:\n\n```javascript\nconst [red] = await image.readRasters({ samples: [0] });\n```\n\nWhen you want your output in a specific size, you can use the `width` and `height` options.\nThis defaults of course to the size of your supplied `window` or the image size if no\n`window` was supplied.\n\nAs the data now needs to be resampled, a `resampleMethod` can be specified. This defaults to\nthe nearest neighbour method, but also the `'bilinear'` method is supported:\n\n```javascript\nconst data = await image.readRasters({ width: 40, height: 40, resampleMethod: 'bilinear' });\n```\n\n### Using decoder pools to improve parsing performance\n\nDecoding compressed images can be a time consuming process. To minimize this\ngeotiff.js provides the `Pool` mechanism which uses WebWorkers to split the amount\nof work on multiple 'threads'.\n\n```javascript\nconst pool = new GeoTIFF.Pool();\nconst data = await image.readRasters({ pool });\n```\n\nIt is possible to provide a pool size (i.e: number of workers), by default the number \nof available processors is used.\n\nBecause of the way WebWorker work (pun intended), there is a considerable overhead\ninvolved when using the `Pool`, as all the data must be copied and cannot be simply be \nshared. But the benefits are two-fold. First: for larger image reads the overall time\nis still likely to be reduced and second: the main thread is relieved which helps to\nuphold responsiveness.\n\nNote: WebWorkers are only available in browsers. For node applications this feature\nis not available out of the box.\n\n### Dealing with visual data\n\nThe TIFF specification provides various ways to encode visual data. In the \nspecification this is called photometric interpretation. The simplest case we\nalready dealt with is the RGB one. Others are grayscale, paletted images, CMYK,\nYCbCr, and CIE L*a*b.\n\ngeotiff.js provides a method to automatically convert these images to RGB:\n`readRGB()`. This method is very similar to the `readRasters` method with\ndistinction that the `interleave` option is now always `true` and the\n`samples` are automatically chosen.\n\n```javascript\nconst rgb = await image.readRGB({\n  // options...\n});\n```\n\n### Automatic image selection (experimental)\n\nWhen dealing with images that have internal (or even external, see the next section) \noverviews, `GeoTIFF` objects provide a separate `readRasters` method. This method\nworks very similar to the method on the `GeoTIFFImage` objects with the same name.\nBy default, it uses the larges image available (highest resolution), but when either\n`width`, `height`, `resX`, or `resY` are specified, then the best fitting image will\nbe used for reading.\n\nAdditionally, it allows the `bbox` instead of the `window` parameter. This works\nsimilarly, but uses geographic coordinates instead of pixel ones.\n\n```javascript\nconst data = await tiff.readRasters({\n  bbox: [10.34, 57.28, 13.34, 60.23],\n  resX: 0.1,\n  resY: 0.1\n});\n```\n\n### External overviews\n\nEspecially for certain kinds of high resolution images it is not uncommon to separate\nthe highest resolution from the lower resolution overviews (usually using the `.ovr`\nextension). With geotiff.js it is possible to use files of this setup, just as you\nwould use single-file images by taking advantage of the `MultiGeoTIFF` objects. They\nbehave exactly the same as the before mentioned `GeoTIFF` objects: you can select\nimages by index or read data using `readRasters`. Toget such a file use the `fromUrls`\nfactory function:\n\n```javascript\nconst multiTiff = await GeoTIFF.fromUrls(\n  'LC08_L1TP_189027_20170403_20170414_01_T1_B3.TIF',\n  ['LC08_L1TP_189027_20170403_20170414_01_T1_B3.TIF.ovr']\n);\n```\n\n### Writing GeoTIFFs (Beta Version)\nYou can create a binary representation of a GeoTIFF using `writeArrayBuffer`.\nThis function returns an ArrayBuffer which you can then save as a .tif file.\n:warning: writeArrayBuffer currently writes the values uncompressed\n```javascript\nimport { writeArrayBuffer } from 'geotiff';\n\nconst values = [1, 2, 3, 4, 5, 6, 7, 8, 9];\nconst metadata = {\n  height: 3,\n  width: 3\n};\nconst arrayBuffer = await writeArrayBuffer(values, metadata);\n```\n\nYou can also customize the metadata using names found in the [TIFF Spec](https://www.loc.gov/preservation/digital/formats/content/tiff_tags.shtml) and [GeoTIFF spec](https://cdn.earthdata.nasa.gov/conduit/upload/6852/geotiff-1.8.1-1995-10-31.pdf).\n```javascript\nimport { writeArrayBuffer } from 'geotiff';\n\nconst values = [1, 2, 3, 4, 5, 6, 7, 8, 9];\nconst metadata = {\n  height: 3,\n  ModelPixelScale: [0.031355, 0.031355, 0],\n  ModelTiepoint: [0, 0, 0, 11.331755000000001, 46.268645, 0],  \n  width: 3\n};\nconst arrayBuffer = await writeArrayBuffer(values, metadata);\n```\n\n## What to do with the data?\n\nThere is a nice HTML 5/WebGL based rendering library called\n[plotty](https://github.com/santilland/plotty), that allows for some really nice\non the fly rendering of the data contained in a GeoTIFF.\n\n```html\n<canvas id=\"plot\"></canvas>\n<script>\n  // ...\n\n  (async function() {\n    const tiff = await GeoTIFF.fromUrl(url);\n    const image = await tiff.getImage();\n    const data = await image.readRasters();\n\n    const canvas = document.getElementById(\"plot\");\n    const plot = new plotty.plot({\n      canvas,\n      data: data[0],\n      width: image.getWidth(),\n      height: image.getHeight(),\n      domain: [0, 256],\n      colorScale: \"viridis\"\n    });\n    plot.render();\n  })();\n</script>\n```\n\n## BigTIFF support\n\ngeotiff.js has a limited support for files in the BigTIFF format. The limitations\noriginate in the capabilities of current JavaScript implementations regarding\n64 bit integer parsers and structures: there are no functions to read 64 bit\nintegers from a stream and no such typed arrays. As BigTIFF relies on 64 bit\noffsets and also allows tag values of those types. In order to still provide\na reasonable support, the following is implemented:\n\n  * 64 bit integers are read as two 32 bit integers and then combined. As\n    numbers in JavaScript are typically implemented as 64 bit floats, there\n    might be inaccuracies for *very* large values.\n  * For 64 bit integer arrays, the default `Array` type is used. This might\n    cause problems for some compression algorithms if those arrays are used for\n    pixel values.\n\n## Planned stuff:\n\n  * Better support of geospatial parameters:\n    * Parsing of EPSG identifiers\n    * WKT representation\n\n## Contribution\n\nIf you have an idea, found a bug or have a remark, please open a ticket, we will\nlook into it ASAP.\n\nPull requests are welcome as well!\n\n## Acknowledgements\n\nThis library was inspired by\n[GeotiffParser](https://github.com/xlhomme/GeotiffParser.js). It provided a\ngreat starting point, but lacked the capabilities to read the raw raster data\nwhich is the aim of geotiff.js.\n","readmeFilename":"README.md"}