UNPKG

georaster

Version:

Wrapper around Georeferenced Rasters like GeoTIFF, NetCDF, JPG, and PNG that provides a standard interface

142 lines (117 loc) 5.12 kB
import {fromArrayBuffer, fromUrl} from 'geotiff'; import {getPalette} from 'geotiff-palette'; import {unflatten} from './utils.js'; function processResult(result, debug) { const noDataValue = result.noDataValue; const height = result.height; const width = result.width; return new Promise((resolve, reject) => { result.maxs = []; result.mins = []; result.ranges = []; let max; let min; // console.log("starting to get min, max and ranges"); for (let rasterIndex = 0; rasterIndex < result.numberOfRasters; rasterIndex++) { const rows = result.values[rasterIndex]; if (debug) console.log('[georaster] rows:', rows); for (let rowIndex = 0; rowIndex < height; rowIndex++) { const row = rows[rowIndex]; for (let columnIndex = 0; columnIndex < width; columnIndex++) { const value = row[columnIndex]; if (value != noDataValue && !isNaN(value)) { if (typeof min === 'undefined' || value < min) min = value; else if (typeof max === 'undefined' || value > max) max = value; } } } result.maxs.push(max); result.mins.push(min); result.ranges.push(max - min); } resolve(result); }); } /* We're not using async because trying to avoid dependency on babel's polyfill There can be conflicts when GeoRaster is used in another project that is also using @babel/polyfill */ export default function parseData(data, debug) { return new Promise((resolve, reject) => { try { if (debug) console.log('starting parseData with', data); if (debug) console.log('\tGeoTIFF:', typeof GeoTIFF); const result = {}; let height, width; if (data.rasterType === 'object') { result.values = data.data; result.height = height = data.metadata.height || result.values[0].length; result.width = width = data.metadata.width || result.values[0][0].length; result.pixelHeight = data.metadata.pixelHeight; result.pixelWidth = data.metadata.pixelWidth; result.projection = data.metadata.projection; result.xmin = data.metadata.xmin; result.ymax = data.metadata.ymax; result.noDataValue = data.metadata.noDataValue; result.numberOfRasters = result.values.length; result.xmax = result.xmin + result.width * result.pixelWidth; result.ymin = result.ymax - result.height * result.pixelHeight; result._data = null; resolve(processResult(result)); } else if (data.rasterType === 'geotiff') { result._data = data.data; let initFunction = fromArrayBuffer; if (data.sourceType === 'url') { initFunction = fromUrl; } if (debug) console.log('data.rasterType is geotiff'); resolve(initFunction(data.data).then(geotiff => { if (debug) console.log('geotiff:', geotiff); return geotiff.getImage().then(image => { try { if (debug) console.log('image:', image); const fileDirectory = image.fileDirectory; const { GeographicTypeGeoKey, ProjectedCSTypeGeoKey, } = image.getGeoKeys(); result.projection = ProjectedCSTypeGeoKey || GeographicTypeGeoKey; if (debug) console.log('projection:', result.projection); result.height = height = image.getHeight(); if (debug) console.log('result.height:', result.height); result.width = width = image.getWidth(); if (debug) console.log('result.width:', result.width); const [resolutionX, resolutionY] = image.getResolution(); result.pixelHeight = Math.abs(resolutionY); result.pixelWidth = Math.abs(resolutionX); const [originX, originY] = image.getOrigin(); result.xmin = originX; result.xmax = result.xmin + width * result.pixelWidth; result.ymax = originY; result.ymin = result.ymax - height * result.pixelHeight; result.noDataValue = fileDirectory.GDAL_NODATA ? parseFloat(fileDirectory.GDAL_NODATA) : null; result.numberOfRasters = fileDirectory.SamplesPerPixel; if (fileDirectory.ColorMap) { result.palette = getPalette(image); } if (data.sourceType !== 'url') { return image.readRasters().then(rasters => { result.values = rasters.map(valuesInOneDimension => { return unflatten(valuesInOneDimension, {height, width}); }); return processResult(result); }); } else { return result; } } catch (error) { reject(error); console.error('[georaster] error parsing georaster:', error); } }); })); } } catch (error) { reject(error); console.error('[georaster] error parsing georaster:', error); } }); }