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

Can't resolve 'fs' in dist #98

Open Ilheu opened 5 years ago

Ilheu commented 5 years ago

Hi, I installed geotiff with "npm i geotiff --save", and I keep getting the following error: image

I've seen this issue ( https://github.com/geotiffjs/geotiff.js/issues/51) but it hasn't fixed my problem ... The webpack has image

constantinius commented 5 years ago

Hi @Ilheu

This only fixes the problem when you are using webpack to bundle your application. Maybe you can share your full webpack configuration and versions, to maybe find a solution. For the next version we hopefully have a fix for that issue.

DanielJDufour commented 5 years ago

I agree with @constantinius . Happy to help resolve this issue with you if you share a sample of your configuration and versions :-)

Ilheu commented 5 years ago

Hi, thank you for the quick answer ! My webpack configuration is this one :

const path = require('path');

const isProduction = (process.env.NODE_ENV === 'production');

module.exports = {
  entry: './src/main',

  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: isProduction ? 'geotiff.bundle.min.js' : 'geotiff.bundle.js',
    library: 'GeoTIFF',
    libraryTarget: 'umd',
  },

  module: {
    rules: [
      {
        test: /\.worker\.js$/,
        use: {
          loader: 'worker-loader',
          options: {
            name: isProduction ? '[hash].decoder.worker.min.js' : '[hash].decoder.worker.js',
            inline: true,
            fallback: true,
          },
        },
      }, {
        test: /\.js$/,
        exclude: /node_modules/,
        use: 'babel-loader',
      },
    ],
  },

  node: {
    fs: 'empty',
    buffer: 'empty',
    http: 'empty',
  },

  devServer: {
    host: '0.0.0.0',
    port: 8090,
    inline: true,
    disableHostCheck: true,
    watchContentBase: true,
    overlay: {
      warnings: true,
      errors: true,
    },
  },
  cache: true,
};

Is this what you asked ? Or need something more ?

Ilheu commented 5 years ago

@constantinius, @DanielJDufour ?

DanielJDufour commented 5 years ago

What are you using to bundle your Angular Application? If you are using webpack, could you provide the webpack configuration for your Angular application? Thanks!

Ilheu commented 5 years ago

Hi @DanielJDufour , I am using angular 8 and I used angular cli to create my app. I read that the webpack config is hidden ... Do you think that this could be the problem ?

Should I do this (https://blog.angularindepth.com/customizing-angular-cli-build-an-alternative-to-ng-eject-v2-c655768b48cc) do customize the webpack ?!

Ilheu commented 5 years ago

My main objective with your software, is to get coordinates from a tiff image so I can put an image on an openlayers' map. Is there any easier way ?

DanielJDufour commented 5 years ago

Option 1 I'd definitely recommend checking out cog-explorer, which puts a cloud optimized geotiff on an OpenLayers Map: https://github.com/geotiffjs/cog-explorer

Here's some other somewhat inferior workarounds:

Option 2 Load the library using a script tag

<script src="https://unpkg.com/geotiff@1.0.0-beta.6/dist/geotiff.bundle.min.js"></script>

And then later on access it through the global window.GeoTIFF

Option 3 Use georaster to pull out the values and then hand-write the code to get it on the map

Option 4 Switch to Leaflet and use https://github.com/GeoTIFF/georaster-layer-for-leaflet. Honestly this is a backup and might not make sense depending on your situation. I think OpenLayers and it's class system is great for Angular projects!

Hope this helps and let me know how it goes!

Ilheu commented 5 years ago

@DanielJDufour Thanks for the availability and help.

Ilheu commented 5 years ago

Hi @DanielJDufour , I've been reading some stuff and I think I had a wrong notion of how to do what I want ...

I have several .tiff format images. I wanted to show these images at their coordinates on the front end using angular 8. I was just wondering if I could just ask the images to my backend via a request get and overlay on the openlayers map, can I do it this way? or need to use a server for sharing geospatial data like mapserver or geoserver ?

constantinius commented 5 years ago

@Ilheu if you have your images available somewhere public (behind a URL) you can try to use the COG explorer and enter the URL to load them. This should display the image at the correct coordinates. With this approach you just need a simple file server, and there is no need for a service like MapServer. Alternatively, if you have a MapServer or equivalent available and don't need fancy client side rendering, you can also publish a WMS layer of your TIFFs. The benefits of using geotiff.js is to have the full data available at the client.

philip-firstorder commented 5 years ago

I also receive this error on Angular 8, tried #51 but it didn't solve the issue.

philip-firstorder commented 5 years ago

@Ilheu How did you manage to solve the error on Angular 8.

Ilheu commented 5 years ago

I did not solved it yet, this project is in stand by ... I'm still trying to find a solution that fits in.

philip-firstorder commented 5 years ago

I managed to find 2 simple solutions that both work:

  1. Import and use it like this in your.component.ts
    
    import { fromUrl } from 'geotiff/dist/geotiff.bundle.min.js';

fromUrl('yourtiff') .then(tiff => { // ... });

2. Or use this https://github.com/angular-guru/electron-builder

Either solution can serve, build, ssr and prerender Angular Universal.

I tried a lot of other things that didn't work like:
- added in `package.json`
```json
"browser" {
  "fs": false
}
philip-firstorder commented 4 years ago

Tested with latest changes: https://github.com/PacoDu/geotiff.js.git#change-main-entrypoint

The problem is that './source.js' is included in "dist-browser/" with these 3 lines: https://github.com/geotiffjs/geotiff.js/blob/2ea5af8642ad1fd01515ff0f8357baf587142b2f/src/source.js#L2-L4

A workaround until now was to add these lines to package.json in our own projects, but this is NOT the proper solution.

  "browser": {
    "fs": false,
    "http": false,
    "https": false
  },

Instead a browser check needs to be done by geotiff.js so that we don't get this errors anymore when using the library.

PacoDu commented 4 years ago

I agree with the addition of the browser field to geotiff.js. But I've tested the solution with your repo yesterday and it continues to throw an error for fs because of txml (https://github.com/TobiasNickel/tXml/issues/9), you will need to add "browser": { "fs": false } at least to your package.

Also, I think we need to understand better why angular SSR build is using the main entry point to resolve the imports and then uses the dist-browser in the build process. It will not produce an optimised build, I feel like we are missing something else here ...

PacoDu commented 4 years ago

It resolves to dist-node not dist-browser now that we removed the browser field from geotiff.js' package.json.

TobiasNickel commented 4 years ago

Thanks @PacoDu for pointing out the browser field in the package json, I just published version 3.1.3. and I tested to build it using webpack.

Joselarcu commented 3 years ago

I had the same problem but I resolved it with the solution @philip-firstorder mentioned. But I need to use pool to open big tiffs, on the line image.readRasters({pool}); I get this error:

`GET http://localhost:4200/decoder.worker.js 404 (Not Found)

39core.js:6210 ERROR Error: Timeout: Did not receive an init message from worker after 10000ms. Make sure the worker calls expose(). at spawn.js:29 at timer (zone-evergreen.js:2561) at ZoneDelegate.invokeTask (zone-evergreen.js:406) at Object.onInvokeTask (core.js:28540) at ZoneDelegate.invokeTask (zone-evergreen.js:405) at Zone.runTask (zone-evergreen.js:178) at invokeTask (zone-evergreen.js:487) at ZoneTask.invoke (zone-evergreen.js:476) at data.args. (zone-evergreen.js:2541)`

I guess the problem is that I need to install threads-plugin, but I don't know how to use it on angular

philip-firstorder commented 3 years ago

With v.1.0.4 I still get the following errors:

import { fromUrl, fromUrls, Pool } from 'geotiff/dist-browser/geotiff';
./node_modules/geotiff/dist-browser/geotiff.js:1:292-296 - Warning: Critical dependency: the request of a dependency is an expression
import { fromUrl, fromUrls, Pool } from 'geotiff'; // as described in the README.md
import * as GeoTIFF from 'geotiff';
import GeoTIFF from 'geotiff';
./node_modules/geotiff/src/source/client/http.js:1:0-24 - Error: Module not found: Error: Can't resolve 'http' in '/Users/philip/Projects/FairFleet/ff3-fe/node_modules/geotiff/src/source/client'
Did you mean './http'?
Requests that should resolve in the current directory need to start with './'.
Requests that start with a name are treated as module requests and resolve within module directories (/Users/philip/Projects/FairFleet/ff3-fe, node_modules).
If changing the source code is not an option there is also a resolve options called 'preferRelative' which tries to resolve these kind of requests in the current directory too.

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
        - add a fallback 'resolve.fallback: { "http": require.resolve("stream-http") }'
        - install 'stream-http'
If you don't want to include a polyfill, you can use an empty module like this:
        resolve.fallback: { "http": false }

./node_modules/geotiff/src/source/client/http.js:2:0-26 - Error: Module not found: Error: Can't resolve 'https' in '/Users/philip/Projects/FairFleet/ff3-fe/node_modules/geotiff/src/source/client'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
        - add a fallback 'resolve.fallback: { "https": require.resolve("https-browserify") }'
        - install 'https-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
        resolve.fallback: { "https": false }

./node_modules/geotiff/src/source/file.js:1:0-39 - Error: Module not found: Error: Can't resolve 'fs' in '/Users/philip/Projects/FairFleet/ff3-fe/node_modules/geotiff/src/source'

So even after 2 years this is still a time consuming problem for us, a fix is needed and I would gladly be available to test on the latest angular 12.

Christoph142 commented 3 years ago

Thanks @philip-firstorder for this update. I just installed the lib via npm and got the same issue you mentioned.

But in my case while import { fromUrl } from 'geotiff/dist-browser/geotiff'; makes the project build, it still doesn't work. I'm getting Uncaught ReferenceError: parcelRequire is not defined at push.665.parcelRequire.QVnC in the browser's console when trying to use fromUrl and that's it.

Any ideas and / or solutions?