-
Notifications
You must be signed in to change notification settings - Fork 414
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#9590: COG download metadata by default with abort fetch #9687
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -8,8 +8,10 @@ | |||||
|
||||||
import get from 'lodash/get'; | ||||||
import isEmpty from 'lodash/isEmpty'; | ||||||
import isNil from 'lodash/isNil'; | ||||||
import { Observable } from 'rxjs'; | ||||||
import { fromUrl } from 'geotiff'; | ||||||
import { GeoTIFF } from 'geotiff'; | ||||||
import { makeRemoteSource } from 'geotiff-remote'; | ||||||
|
||||||
import { isValidURL } from '../../utils/URLUtils'; | ||||||
import ConfigUtils from '../../utils/ConfigUtils'; | ||||||
|
@@ -57,8 +59,22 @@ export const getProjectionFromGeoKeys = (image) => { | |||||
|
||||||
return null; | ||||||
}; | ||||||
const abortError = (reject) => reject(new DOMException("Aborted", "AbortError")); | ||||||
/** | ||||||
* getImage with abort fetching of data slices | ||||||
*/ | ||||||
const getImage = (geotiff, signal) => { | ||||||
if (signal?.aborted) { | ||||||
return abortError(Promise.reject); | ||||||
} | ||||||
return new Promise((resolve, reject) => { | ||||||
signal?.addEventListener("abort", () => abortError(reject)); | ||||||
return geotiff.getImage() // Fetch and read first image to get medatadata of the tif | ||||||
.then((image) => resolve(image)) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Basically, as discussed with @dsuren1 , we can canel the pending task to make the user continue operating if the "Save" takes too long, but we can not cancel the effective requests pending This can cause the pending requests to be blocking and slowing down the load on that particular domain in any case (because of bandwitdh and max number of parallel requests allowed to a specific domain by the browser etc...) Please report the known issue notice, or we loose memory of it. I ask @dsuren1 to link the proper issue to github repo of geotiffjs, for completeness.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated note on the function and created an issue in geotiff.js |
||||||
.catch(()=> abortError(reject)); | ||||||
}); | ||||||
}; | ||||||
let capabilitiesCache = {}; | ||||||
|
||||||
export const getRecords = (_url, startPosition, maxRecords, text, info = {}) => { | ||||||
const service = get(info, 'options.service'); | ||||||
let layers = []; | ||||||
|
@@ -73,19 +89,35 @@ export const getRecords = (_url, startPosition, maxRecords, text, info = {}) => | |||||
sources: [{url}], | ||||||
options: service.options || {} | ||||||
}; | ||||||
if (service.fetchMetadata) { | ||||||
const controller = get(info, 'options.controller'); | ||||||
const isSave = get(info, 'options.save', false); | ||||||
// Fetch metadata only on saving the service (skip on search) | ||||||
if ((isNil(service.fetchMetadata) || service.fetchMetadata) && isSave) { | ||||||
const cached = capabilitiesCache[url]; | ||||||
if (cached && new Date().getTime() < cached.timestamp + (ConfigUtils.getConfigProp('cacheExpire') || 60) * 1000) { | ||||||
return {...cached.data}; | ||||||
} | ||||||
return fromUrl(url) | ||||||
.then(geotiff => geotiff.getImage()) | ||||||
const signal = controller?.signal; | ||||||
// geotiff's `fromUrl` & `getImage` function doesn't pass down signal parameter properly. Known issue (https://github.com/geotiffjs/geotiff.js/issues/330) | ||||||
// Hence `fromSource` is called directly with source formulated | ||||||
return GeoTIFF.fromSource(makeRemoteSource(url, {}), {}, signal) | ||||||
.then(geotiff => getImage(geotiff, signal)) | ||||||
.then(image => { | ||||||
const crs = getProjectionFromGeoKeys(image); | ||||||
const extent = image.getBoundingBox(); | ||||||
const isProjectionDefined = isProjectionAvailable(crs); | ||||||
layer = { | ||||||
...layer, | ||||||
sourceMetadata: { | ||||||
crs, | ||||||
extent: extent, | ||||||
width: image.getWidth(), | ||||||
height: image.getHeight(), | ||||||
tileWidth: image.getTileWidth(), | ||||||
tileHeight: image.getTileHeight(), | ||||||
origin: image.getOrigin(), | ||||||
resolution: image.getResolution() | ||||||
}, | ||||||
// skip adding bbox when geokeys or extent is empty | ||||||
...(!isEmpty(extent) && !isEmpty(crs) && isProjectionDefined && { | ||||||
bbox: { | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This solution is a big hack...
Did you try to implement it instead?
Like this as documented here, or better using axios (I'd prefer axios solution, so we have also authentication, proxy etc... out of the box, the doc do not show, for brevity, the solution with Promise) ?
If a solution like this is possible, we can have more control on it, without any hack.
Otherwise I think we have to rely on internal functions as you did in this implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I did check.
fromArrayBuffer
still doesn't handlesignal
parameter correctly. It is lost when the passed down tofromSource
. Reason it cannot handled with axios is becausefromSource
makes bigtiff parsing logic to read tif data and converts to image object with required functions necessary for extracting metadata informations.Maybe we can cancel the promise of
fromUrl
andgetImage
but not the actual fetch request action (which is a compromise) and in the process we can avoid the hack and also this will not impact user performance. Kindly let me know if this okay? @offtherailz