xhluca / dash_leaflet

React-leaflet in Python
Other
1 stars 0 forks source link

Problems with loading Icons #1

Open xhluca opened 5 years ago

xhluca commented 5 years ago

Description

At the moment, there is a known ongoing issue for both react-leaflet and leaflet concerning the icons. The problem with leaflet is that L.Icon.Default has a wrong URL, whereas for react-leaflet building the webpack leads to loading the wrong names for the icons (i.e. marker, and marker shadow), therefore the icons do not appear. The following fix seems to work correctly for react apps, but not for the webpack configuration of dash_leaflet:

import L from 'leaflet';

import 'leaflet/dist/leaflet.css';

// stupid hack so that leaflet's images work after going through webpack
import marker from 'leaflet/dist/images/marker-icon.png';
import marker2x from 'leaflet/dist/images/marker-icon-2x.png';
import markerShadow from 'leaflet/dist/images/marker-shadow.png';

delete L.Icon.Default.prototype._getIconUrl;

L.Icon.Default.mergeOptions({
    iconRetinaUrl: marker2x,
    iconUrl: marker,
    shadowUrl: markerShadow
});

and the following is added to webpack.config:

module: {
...
    {
        test: /\.(png|svg|jpg|gif)$/,
        use: [{
            loader: 'file-loader'
        }]
    }]
},

Instead, what I have done is to create an L.Icon item, and pass in the base64 encoding of the icons retrieved from the package distribution. Please refer to the source code for how I did this.

To do

We need to find either an alternative to the currently used icon, or find a better way to serve it (i.e. webpack fix). The current solution is a hack and not correctly tested.

Links

xhluca commented 5 years ago

Update

Would need to investigate more, but I believe that the icon issue can be easily solved for react apps by simply changing the default icon names. Furthermore, the problem can be solved for webpacks by using file-loader, as mentioned in #255. This means that webpack will create the image assets when we run npm run build:all, similar to this:

> dash_leaflet@0.0.1 build:js-dev C:\Users\xingh\git\dash_leaflet
> webpack --mode development

Hash: e42c9a25ad6f79f355cd
Version: webpack 4.28.2
Time: 3447ms
Built at: 12/25/2018 4:37:58 PM
                 Asset       Size  Chunks             Chunk Names
   dash_leaflet.dev.js    2.2 MiB    main  [emitted]  main
     img/layers-2x.png   1.23 KiB          [emitted]
        img/layers.png  696 bytes          [emitted]
img/marker-icon-2x.png   2.41 KiB          [emitted]
   img/marker-icon.png   1.43 KiB          [emitted]
 img/marker-shadow.png  618 bytes          [emitted]
Entrypoint main = dash_leaflet.dev.js
[./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {main} [built]
[./node_modules/webpack/buildin/harmony-module.js] (webpack)/buildin/harmony-module.js 573 bytes {main} [built]
[./src/lib/index.js] 849 bytes {main} [built]
[react] external "React" 42 bytes {main} [built]
[react-dom] external "ReactDOM" 42 bytes {main} [built]
    + 241 hidden modules

> dash_leaflet@0.0.1 build:py C:\Users\xingh\git\dash_leaflet
> venv\Scripts\activate && venv\Scripts\dash-generate-components ./src/lib/components dash_leaflet

Generated Map.py
Generated Marker.py
Generated Popup.py
Generated TileLayer.py

Where all the icon images are stored in the directory img. Then, for normal webpack apps (not to be confused with react app that do not use webpack, e.g. create-react-app), the dash_leaflet.min.js will load the images at runtime and display the icon.

For some unknown reason this does not work with Dash. I've tried investigating this issue, but to no avail. Furthermore, I tried loading the files from a path by instantiating a File object using new File(path), as described in the docs, but it seems that loading from path has been deprecated. Instead, the new way to do it seems to be rather complex and browser-dependent, as mentioned in this thread.

Temporary Fix

I had to hardcode the images as b64 inside the Marker.react.js file. This is meant to be an absolutely TEMPORARY fix, and needs to be changed ASAP.