Skip to content

Commit

Permalink
Merge pull request #79 from jcphill/read-on-demand
Browse files Browse the repository at this point in the history
add readOnDemand option for faster File/Blob loading
  • Loading branch information
DanielJDufour authored Aug 6, 2023
2 parents 53e26d9 + fadcb07 commit 741923b
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 26 deletions.
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ fs.readFile("data/GeogToWGS84GeoKey5.tif", (error, data) => {
});
```

# load from File (or other Blob) on front-end
```javascript
const parseGeoraster = require("georaster");
document.querySelector("input").addEventListener("change", e => {
const file = e.target.files[0];
parseGeoraster(file)
.then(georaster => {
console.log("georaster:", georaster);
});
});
```

# load from simple object on front-end
```javascript
const parseGeoraster = require("georaster");
Expand All @@ -37,7 +49,8 @@ const georaster = parseGeoraster(values, metadata);
```

# load [cloud optimized geotiff](https://www.cogeo.org/)
This option allows you to basically load the pixels only when you need them versus the other options
This option (and File with readOnDemand, below) allows you to basically
load the pixels only when you need them versus the other options
that require you to load the whole image into memory. It will also attempt to automatically discover any available overview files.

*where to clip*
Expand Down Expand Up @@ -72,6 +85,19 @@ that require you to load the whole image into memory. It will also attempt to a
});
```

# load from File on demand
By default, a File or ArrayBuffer will be read and parsed completely
at full resolution in a worker thread (if available) before
the promise returned by parseGeoraster() is resolved.
If less data is required (such as when the file includes overviews),
then the readOnDemand option allows reading and parsing to be deferred
until getValues() is called.
```javascript
parseGeoraster(file, { readOnDemand: true })
.then(georaster => georaster.getValues(options))
.then(values => ...
```
# required properties
| name | description |
| ---- | ----------- |
Expand Down
45 changes: 21 additions & 24 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,14 @@ class GeoRaster {
data = new Buffer(data);
}

this.readOnDemand = false;
if (typeof data === 'string') {
if (debug) console.log('data is a url');
this._data = data;
this._url = data;
this.rasterType = 'geotiff';
this.sourceType = 'url';
this.readOnDemand = true;
} else if (typeof Blob !== 'undefined' && data instanceof Blob) {
this._data = data;
this.rasterType = 'geotiff';
Expand All @@ -80,6 +82,9 @@ class GeoRaster {
this.rasterType = 'object';
this._metadata = metadata;
}
if ( metadata && metadata.readOnDemand !== undefined ) {
this.readOnDemand = metadata.readOnDemand;
}

if (debug) console.log('this after construction:', this);
}
Expand Down Expand Up @@ -112,16 +117,23 @@ class GeoRaster {
if (debug) console.log('this', this);

if (this.rasterType === 'object' || this.rasterType === 'geotiff' || this.rasterType === 'tiff') {
if (this._web_worker_is_available) {
const parseDataArgs = {
data: this._data,
rasterType: this.rasterType,
sourceType: this.sourceType,
readOnDemand: this.readOnDemand,
metadata: this._metadata,
};
if (this._web_worker_is_available && ! this.readOnDemand) {
const worker = new Worker();
worker.onmessage = (e) => {
if (debug) console.log('main thread received message:', e);
const data = e.data;
for (const key in data) {
this[key] = data[key];
}
if (this._url) {
this._geotiff = geotiff;
if (this.readOnDemand) {
if (this._url) this._geotiff = geotiff;
this.getValues = function(options) {
return getValues(this._geotiff, options);
};
Expand All @@ -133,31 +145,16 @@ class GeoRaster {
};
if (debug) console.log('about to postMessage');
if (this._data instanceof ArrayBuffer) {
worker.postMessage({
data: this._data,
rasterType: this.rasterType,
sourceType: this.sourceType,
metadata: this._metadata,
}, [this._data]);
worker.postMessage(parseDataArgs, [this._data]);
} else {
worker.postMessage({
data: this._data,
rasterType: this.rasterType,
sourceType: this.sourceType,
metadata: this._metadata,
});
worker.postMessage(parseDataArgs);
}
} else {
if (debug) console.log('web worker is not available');
parseData({
data: this._data,
rasterType: this.rasterType,
sourceType: this.sourceType,
metadata: this._metadata,
}, debug).then(result => {
if (debug && ! this._web_worker_is_available) console.log('web worker is not available');
parseData(parseDataArgs, debug).then(result => {
if (debug) console.log('result:', result);
if (this._url) {
result._geotiff = geotiff;
if (this.readOnDemand) {
if (this._url) result._geotiff = geotiff;
result.getValues = function(options) {
return getValues(this._geotiff, options);
};
Expand Down
3 changes: 2 additions & 1 deletion src/parseData.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,15 @@ export default function parseData(data, debug) {
result.palette = getPalette(image);
}

if (data.sourceType !== 'url') {
if (! data.readOnDemand) {
return image.readRasters().then(rasters => {
result.values = rasters.map(valuesInOneDimension => {
return unflatten(valuesInOneDimension, {height, width});
});
return processResult(result);
});
} else {
result._geotiff = geotiff;
return result;
}
} catch (error) {
Expand Down

0 comments on commit 741923b

Please sign in to comment.