1

My leaflet maps were rendering too slow, I found pixiOverlay an alternative for that but I just cant make it run. Any example would help.

following is my component

<template>
  <div ref="mapElement" style="height: 400px;"></div>
</template>

<script>
  // import {
  //   LMap,
  //   LTileLayer
  // } from 'vue2-leaflet';
  import * as PIXI from 'pixi.js';
  import 'leaflet-pixi-overlay';
  import L from 'leaflet';

  export default {
    name: 'HelloWorld',
    components: {
      // LMap,
      // LTileLayer,
    },
    data() {
      return {
        // url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
        // zoom: 3,
        // center: [47.413220, -1.219482],
        // bounds: null,
        map: L.map
      };
    },
    methods: {
      draw() {
        // this.map = L.map('map', {
        //   center: [30, 30],
        //   zoom: 13,
        // });

        var loader = new PIXI.loaders.Loader();
        loader.add('marker', 'img/marker-icon.png');
        loader.load(function(loader, resources) {
          var markerTexture = resources.marker.texture;
          var markerLatLng = [51.505, -0.09];
          var marker = new PIXI.Sprite(markerTexture);
          marker.anchor.set(0.5, 1);

          var pixiContainer = new PIXI.Container();
          pixiContainer.addChild(marker);

          var firstDraw = true;
          var prevZoom;

          var pixiOverlay = L.pixiOverlay(function(utils) {
            var zoom = utils.getMap().getZoom();
            var container = utils.getContainer();
            var renderer = utils.getRenderer();
            var project = utils.latLngToLayerPoint;
            var scale = utils.getScale();

            if (firstDraw) {
              var markerCoords = project(markerLatLng);
              marker.x = markerCoords.x;
              marker.y = markerCoords.y;
            }

            if (firstDraw || prevZoom !== zoom) {
              marker.scale.set(1 / scale);
            }

            firstDraw = true;
            prevZoom = zoom;
            renderer.render(container);
          }, pixiContainer);

          pixiOverlay.addTo(this.map);
        });
      },
      zoomUpdated(zoom) {
        this.zoom = zoom;
      },
      centerUpdated(center) {
        this.center = center;
      },
      boundsUpdated(bounds) {
        this.bounds = bounds;
      },
    },
    mounted() {
      this.map = L.map(this.$refs['mapElement']).setView([51.505, -0.09], 13);

      L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxZoom: 18,
      }).addTo(this.map);

      this.draw();
    },
  }
</script>

I tried using lifecycle hooks. The error I got previously was Container not found (now solved). The error now I am getting is "cannot read property of null"

Error

Update 1

<template>
<div ref="map" style="height: 400px;">

</div>
</template>

<script>

import * as PIXI from 'pixi.js';
import 'leaflet-pixi-overlay';
import L from 'leaflet';

export default {
    name: 'HelloWorld',
    
    data() {
        return {
            
            map: L.map
        };
    },
    methods: {
        draw() {
            let loader = new PIXI.Loader()
            loader.add('marker', 'https://pixijs.io/examples/examples/assets/bunny.png')
            loader.load((loader, resources) => {
                let markerTexture = resources.marker.texture
                let markerLatLng = [51.505, -0.09]
                let marker = new PIXI.Sprite(markerTexture)
                marker.anchor.set(0.5, 1)

                let pixiContainer = new PIXI.Container()
                pixiContainer.addChild(marker)

                let firstDraw = true
                let prevZoom

                let pixiOverlay = L.pixiOverlay(utils => {
                    let zoom = utils.getMap().getZoom()
                    let container = utils.getContainer()
                    let renderer = utils.getRenderer()
                    let project = utils.latLngToLayerPoint
                    let scale = utils.getScale()

                    if (firstDraw) {
                        let markerCoords = project(markerLatLng)
                        marker.x = markerCoords.x
                        marker.y = markerCoords.y
                    }

                    if (firstDraw || prevZoom !== zoom) {
                        marker.scale.set(1 / scale)
                    }

                    firstDraw = true
                    prevZoom = zoom
                    renderer.render(container)
                }, pixiContainer)

                pixiOverlay.addTo(this.map)
            })
        },
       
        zoomUpdated(zoom) {
            this.zoom = zoom;
        },
        centerUpdated(center) {
            this.center = center;
        },
        boundsUpdated(bounds) {
            this.bounds = bounds;
        },

    },
    mounted() {
        this.map = L.map(this.$refs.map).setView([51.505, -0.09], 13)

        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            maxZoom: 18,
        }).addTo(this.map)

        this.draw()
    }

}
</script>

Error

majid
  • 75
  • 6

1 Answers1

1

I think the problematic line is:

pixiOverlay.addTo(this.map);

Because you call this inside another function so that this is not reference to your component which means it's probably undefined or has another value.

You can solve this by using arrow function:

...
  loader.load((loader, resources) => {
    ...
    var pixiOverlay = L.pixiOverlay((utils) => {
        ...
    }, pixiContainer)

    pixiOverlay.addTo(this.map);
  });
...

JSFiddle

User 28
  • 4,863
  • 1
  • 20
  • 35
  • Its working in JSFiddle but I am getting: webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:620 [Vue warn]: Error in mounted hook: "TypeError: pixi_js__WEBPACK_IMPORTED_MODULE_2__.Loader is not a constructor" – majid Oct 16 '20 at 09:37
  • @majid Could you update your latest code? So I can see what's causing that error. – User 28 Oct 16 '20 at 09:44
  • 1
    @majid Which version of pixi.js are you using? For `new PIXI.Loader()` it must be at least 5.x. – User 28 Oct 16 '20 at 11:48
  • at last with your help. it is working now. my pixi.js was outdated, installed now with `npm install pixi.js`. its all good now. please if you know any good tutorial for pixi, leaflet integration do let me know. I need to make some interactive pixi graphics from geojson. Thankyou – majid Oct 16 '20 at 11:57