0

I'm using MapBox GL JS and the mapbox-gl-draw plugin.

I need to show a little buffer around my clicked points during my edit session.

All seems working fine but I obtain a "Uncaught TypeError: Cannot read property 'style' of undefined" in my browser console.

Here you are a little sample that show how to replicate the error ...

<!DOCTYPE html>
<html>
 <head>
    <meta charset='utf-8' />
    <title></title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.18.0/mapbox-gl.js'></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.18.0/mapbox-gl.css' rel='stylesheet' />
    <style>
        body { margin:0; padding:0; }
        #map { position:absolute; top:0; bottom:0; width:100%; }
        }
    </style>
    <script src='https://api.tiles.mapbox.com/mapbox.js/plugins/turf/v3.0.11/turf.min.js'></script>
    <script src="mapbox-gl-draw.js"></script>
    <link href='mapbox-gl-draw.css' rel='stylesheet' />
</head>
 <body>
  <div id='map'></div>

  <script>
    var theCoords;

    mapboxgl.accessToken = 'pk.eyJ1IjoiZGFuc3dpY2siLCJhIjoieUZiWmwtVSJ9.0cPQywdbPVmvHiHJ6NwdXA';
    var map = new mapboxgl.Map({
        container: 'map', // container id
        style: 'mapbox://styles/mapbox/streets-v9', //stylesheet location
        center: [9.10349459743145,39.20711996956351], // starting position
        zoom: 13 // starting zoom
    });

    var Draw = mapboxgl.Draw({
      displayControlsDefault: false,
      controls: {
        'point': true,
        'trash': true
      }
    });

    map.addControl(Draw);

    map.on('mousedown', function (e) {
      //alert("MouseDown!!");
      console.log("MouseDown!!")

      pixelCoords = e.point;
      geoCoords = e.lngLat;

      x = pixelCoords.x;
      y = pixelCoords.y;

      lng = Number(geoCoords.lng.toFixed(5));
      lat = Number(geoCoords.lat.toFixed(5));

     var feature = { type: 'Point', coordinates: [lat, lng] };

     currentPoint = {
       "type": "Feature",
       "properties": {},
       "geometry": {
         "type": "Point",
         "coordinates": [Number(lng), Number(lat)]
       }
     };

     bufferCurrentPoint = turf.buffer(currentPoint, 100, 'meters');

     addBufferPointToMap(bufferCurrentPoint)
    });



    function addBufferPointToMap(bufferCurrentPoint) {
      try {
        map.removeSource("buffer");
        map.removeLayer("buffer");
      }
      catch(err) {
        console.log("The source and layer \"buffer\" are not defined");
      }

      map.addSource('buffer', {
          'type': 'geojson',
          'data': bufferCurrentPoint
      });

      map.addLayer({
             'id': 'buffer',
             'type': 'fill',
             'source': 'buffer',
             'layout': {},
             'paint': {
                 'fill-color': '#088',
                 'fill-opacity': 0.5
             }
      });
    }


  </script>
 </body>
</html>

If you try to execute, starting the edit session clicking on the pinpoint at the hight left corner, then clicking on the map, you'll see something like this ...

enter image description here

Note that, instead, if you use this code ....

<!DOCTYPE html>
<html>
 <head>
    <meta charset='utf-8' />
    <title></title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.18.0/mapbox-gl.js'></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.18.0/mapbox-gl.css' rel='stylesheet' />
    <style>
        body { margin:0; padding:0; }
        #map { position:absolute; top:0; bottom:0; width:100%; }
        }
    </style>
    <script src='https://api.tiles.mapbox.com/mapbox.js/plugins/turf/v3.0.11/turf.min.js'></script>
    <script src="mapbox-gl-draw.js"></script>
    <link href='mapbox-gl-draw.css' rel='stylesheet' />
</head>
 <body>
  <div id='map'></div>

  <script>
    var theCoords;

    mapboxgl.accessToken = 'pk.eyJ1IjoiZGFuc3dpY2siLCJhIjoieUZiWmwtVSJ9.0cPQywdbPVmvHiHJ6NwdXA';
    var map = new mapboxgl.Map({
        container: 'map', // container id
        style: 'mapbox://styles/mapbox/streets-v9', //stylesheet location
        center: [9.10349459743145,39.20711996956351], // starting position
        zoom: 13 // starting zoom
    });

/*
    var Draw = mapboxgl.Draw({
      displayControlsDefault: false,
      controls: {
        'point': true,
        'trash': true
      }
    });

    map.addControl(Draw);
*/
    map.on('mousedown', function (e) {
      //alert("MouseDown!!");
      console.log("MouseDown!!")

      pixelCoords = e.point;
      geoCoords = e.lngLat;

      x = pixelCoords.x;
      y = pixelCoords.y;

      lng = Number(geoCoords.lng.toFixed(5));
      lat = Number(geoCoords.lat.toFixed(5));

     var feature = { type: 'Point', coordinates: [lat, lng] };

     currentPoint = {
       "type": "Feature",
       "properties": {},
       "geometry": {
         "type": "Point",
         "coordinates": [Number(lng), Number(lat)]
       }
     };

     bufferCurrentPoint = turf.buffer(currentPoint, 100, 'meters');

     addBufferPointToMap(bufferCurrentPoint)
    });



    function addBufferPointToMap(bufferCurrentPoint) {
      try {
        map.removeSource("buffer");
        map.removeLayer("buffer");
      }
      catch(err) {
        console.log("The source and layer \"buffer\" are not defined");
      }

      map.addSource('buffer', {
          'type': 'geojson',
          'data': bufferCurrentPoint
      });

      map.addLayer({
             'id': 'buffer',
             'type': 'fill',
             'source': 'buffer',
             'layout': {},
             'paint': {
                 'fill-color': '#088',
                 'fill-opacity': 0.5
             }
      });
    }


  </script>
 </body>
</html>

... where I've commented the code portion where I load the mapbox-gl-draw plugin, and you try to click on the map, all works fine....

How may I avoid this error?

1 Answer 1

2

I don't have an explanation as to why you're seeing that error when drawing tools are hooked up to the map. Maybe a bug with that version of mapbox-gl-js? If you switch to v0.22.0 the error goes away.

The error goes also goes away using 0.18.0 if you take a different approach: re-use your source instead of removing and adding a new one on each click. Try this:

<!DOCTYPE html>
<html>
 <head>
    <meta charset='utf-8' />
    <title></title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.18.0/mapbox-gl.js'></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.18.0/mapbox-gl.css' rel='stylesheet' />
    <style>
        body { margin:0; padding:0; }
        #map { position:absolute; top:0; bottom:0; width:100%; }
        }
    </style>
    <script src='https://api.tiles.mapbox.com/mapbox.js/plugins/turf/v3.0.11/turf.min.js'></script>
    <script src="mapbox-gl-js-draw/mapbox-gl-draw.js"></script>
    <link href='mapbox-gl-js-draw/mapbox-gl-draw.css' rel='stylesheet' />
</head>
<body>
  <div id='map'></div>
  <script>
    var theCoords;
    var bufferId = 'buffer';

    mapboxgl.accessToken = 'pk.eyJ1IjoiZGFuc3dpY2siLCJhIjoieUZiWmwtVSJ9.0cPQywdbPVmvHiHJ6NwdXA';
    var map = new mapboxgl.Map({
      container: 'map', // container id
      style: 'mapbox://styles/mapbox/streets-v9', //stylesheet location
      center: [9.10349459743145, 39.20711996956351], // starting position
      zoom: 13 // starting zoom
    });
    var draw = mapboxgl.Draw({
      displayControlsDefault: false,
      controls: {
        'point': true,
        'trash': true
      }
    });

    map.on('load', function() {
      // Add the source and layer, with some dummy data in the source.
      map.addSource(bufferId, {
        'type': 'geojson',
        'data': { type: 'Feature', geometry: { type: 'Point', coordinates: [null, null] } }
      });
      map.addLayer({
        'id': bufferId,
        'type': 'fill',
        'source': bufferId,
        'layout': {},
        'paint': {
          'fill-color': '#088',
          'fill-opacity': 0.5
        }
      });
    })
    map.addControl(draw);
    map.on('mousedown', function(e) {
      console.log("MouseDown!!")

      pixelCoords = e.point;
      geoCoords = e.lngLat;

      x = pixelCoords.x;
      y = pixelCoords.y;

      lng = Number(geoCoords.lng.toFixed(5));
      lat = Number(geoCoords.lat.toFixed(5));

      var feature = {
        type: 'Point',
        coordinates: [lat, lng]
      };

      currentPoint = {
        "type": "Feature",
        "properties": {},
        "geometry": {
          "type": "Point",
          "coordinates": [Number(lng), Number(lat)]
        }
      };

      bufferCurrentPoint = turf.buffer(currentPoint, 100, 'meters');
      var source = map.getSource(bufferId);
      source.setData(bufferCurrentPoint);
    });
  </script>
 </body>
</html>
1
  • I've tried and works fine. I think that your solution is better than mine so I'll adopt and I'll update the mapbox-gl.js reference cdn ... Do you have also a sample for this question gis.stackexchange.com/questions/209411/… ?:-)
    – Cesare
    Sep 10, 2016 at 10:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.