geotiffjs / geotiff.js

geotiff.js is a small library to parse TIFF files for visualization or analysis. It is written in pure JavaScript, and is usable in both the browser and node.js applications.
https://geotiffjs.github.io/
MIT License
878 stars 183 forks source link

Uncaught (in promise): TypeError: Cannot read properties of undefined (reading 'offset') blockedsource.js #262

Open casper5822 opened 2 years ago

casper5822 commented 2 years ago

Hello i have a problem reading a simple tif in angular 11 app with fromUrl.

This is my code:

fromUrl("http://localhost:4200/assets/img/test.tif") .then( tiff =>{ console.log(tiff) })

Version: geotiff 1.0.8

But i get this error:

ERROR Error: Uncaught (in promise): TypeError: Cannot read properties of undefined (reading 'offset') TypeError: Cannot read properties of undefined (reading 'offset') at blockedsource.js:276 at Array.map () at BlockedSource.readSliceData (blockedsource.js:267) at BlockedSource._callee$ (blockedsource.js:171) at tryCatch (runtime.js:63) at Generator.invoke [as _invoke] (runtime.js:294) at Generator.next (runtime.js:119) at asyncGeneratorStep (asyncToGenerator.js:3) at _next (asyncToGenerator.js:25) at ZoneDelegate.invoke (zone.js:400) at resolvePromise (zone.js:1255) at resolvePromise (zone.js:1209) at zone.js:1321 at ZoneDelegate.invokeTask (zone.js:434) at Object.onInvokeTask (core.js:28578) at ZoneDelegate.invokeTask (zone.js:433) at Zone.runTask (zone.js:205) at drainMicroTaskQueue (zone.js:620) at ZoneTask.invokeTask (zone.js:520) at ZoneTask.invoke (zone.js:505)


In lib code where the error begins i notice this comment: // TODO: satisfy each slice return this.readSliceData(slices, requiredBlocks);

I debug this line and the requiredBlocks is this map (size 1): 0: {0 => undefined}

Can you help me? Thank you.

constantinius commented 2 years ago

Hi @casper5822

I think the URL should read http://localhost:4200/assets/img/test.tif, right? Not http:localhost:4200/assets/img/test.tif

Maybe this is the issue already. Please let me know if this helps.

casper5822 commented 2 years ago

@constantinius the url error is only a typing error here on my github message, thanks i just fix it. In my code the url is correct. So it's not the problem.

casper5822 commented 2 years ago

I made some progress. I change my code in this:

  this.http.get("http://localhost:4200/assets/img/ponte.tif",{ responseType: 'blob' })
      .subscribe(
        blob =>{
          fromBlob(blob)
          .then(
            tiff =>{
              tiff.getImage()
              .then(
                img =>{
                    const image = img;
                })
            })
        })

the file is read correctly and fromBlob works as expected. So the problem is the fromUrl

constantinius commented 2 years ago

I see. Can you provide this image somehow? Otherwise it is hard to debug.

casper5822 commented 2 years ago

Sorry i'm late @constantinius. Yes you can download the geotiff file from here: https://drive.google.com/file/d/1noC9MvPPa9v5w0yL12GmwrIux5PyLoPJ/view?usp=sharing

jhudson commented 2 years ago

Hi @casper5822, I'm facing this same issue loading a COG Geotiff in an Angular 12. In what library and which file did you change the above to fix this?

casper5822 commented 2 years ago

@jhudson i didn't fix this bug because i think it's a library problem. I made a workaround downloading the file directly with the standard angular http.get and use fromBlob as you can see in my previous comment. After this workaround, i had another problem due to the big size of Geotiff file (4GB) so i changed all the logic using the zyx mosaic geotiff splitting and using the map tiles layer to display the geotif on leaflet map. Hope this can help you.

jhudson commented 2 years ago

Thanks @casper5822. Just to add some more information to this bug report, my use case is -> I have an angular 12 application which is using openlayers to consume a cloud optimized geotiff. If I find a resolution to this bug i'll update this post.

sboag commented 2 years ago

Hi @casper5822 I have found a fix to this bug. In the blockedsource.js file the line let results = await Promise.allSettled((blockRequests.values()); doesn't wait for the blockedRequests Promises to return as .values() returns an IterableIterator not a list. The fix is to wrap the blockRequests.values() in Array.from() as seen here let results = await Promise.allSettled(Array.from(blockRequests.values()));.

Note1: This issue appears to also be present in 2 spots in geotiff.js file. Note2: .values() is used in 2 locations in blockedsource.js the first one is missing the Array.from while the second isn't.

constantinius commented 2 years ago

@sboag Thanks for the investigation. I will make a patch with that now.

constantinius commented 2 years ago

@casper5822 Can you try with the latest commit to see if the issue is now resolved?

sboag commented 2 years ago

@constantinius can you release the patch?

constantinius commented 2 years ago

@sboag v1.0.9 is now released

HGS-jonathanantal commented 2 years ago

I've updated to 1.0.9 to address having this same issue. However, now when I npm start my ui, I get:

Failed to compile.

./node_modules/geotiff/src/decoder.worker.js (./node_modules/threads-plugin/dist/loader.js?{"name":"0"}!./node_modules/geotiff/src/decoder.worker.js)
ChunkRenderError: Conflict: Multiple chunks emit assets to the same filename static/js/0.chunk.worker.js (chunks 0 and 0)

I've made sure all dependencies (threads, threads-plugin) are up to date and good. Can anyone point me in the right direction? Thanks.

zipporaSay commented 1 year ago

I would like it to be fixed for now I use

I made some progress.

I change my code in this:

  this.http.get("http://localhost:4200/assets/img/ponte.tif",{ responseType: 'blob' })
      .subscribe(
        blob =>{
          fromBlob(blob)
          .then(
            tiff =>{
              tiff.getImage()
              .then(
                img =>{
                    const image = img;
                })
            })
        })

the file is read correctly and fromBlob works as expected. So the problem is the fromUrl

and it works for me thanks

zipporaSay commented 1 year ago

This caused performance problems using the above A really significant problem use: this.http.get("http://localhost:4200/assets/img/ponte.tif",{ responseType: 'blob' }).....