Слои Mapbox не отображаются с изменениями стиля - PullRequest
0 голосов
/ 31 октября 2018

Я разрабатываю карту с помощью Mapbox GL JS, которая отображает данные координат в виде геоджона и отображает различные слои среды в виде слоев Mapbox Studio или слоя WMS.

Однако я только что столкнулся с проблемой. Все мои точки и слои отображаются правильно при загрузке. Но когда я нажимаю «спутник», чтобы изменить базовую карту, слои Wetlands, Aquifers и Floodzone перестают работать. Кнопки не работают вообще, и я получаю ошибку:

style.js:788 Uncaught TypeError: Cannot read property 'getLayoutProperty' of undefined
    at i.getLayoutProperty (style.js:788)
    at o.getLayoutProperty (map.js:1315)
    at HTMLAnchorElement.link.onclick ((index):1309)
i.getLayoutProperty @ style.js:788
o.getLayoutProperty @ map.js:1315
link.onclick @ (index):1309

Вы можете увидеть работающую демонстрацию здесь. https://bl.ocks.org/dyavromEPA/raw/4576726c459e654ff5e2664f096aaba1/

И весь код ниже:

<!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.50.0/mapbox-gl.js'></script>
        <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.css' rel='stylesheet' />
        <script src='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v2.2.0/mapbox-gl-geocoder.min.js'></script>
        <link rel='stylesheet' href='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v2.2.0/mapbox-gl-geocoder.css' type='text/css' />
        <link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
        <link href="https://fonts.googleapis.com/css?family=Inconsolata" rel="stylesheet">
            <style>
                body {
                  margin: 0;
                  padding: 0;
                }
                #map {
                  position: absolute;
                  top: 0;
                  bottom: 0;
                  width: 100%;
                  height: 100%;
                }
            </style>
            </head>
            <body>
            <style>
                .marker {
                  background-image: url('data/marker.svg');
                  background-size: cover;
                  width:20px;
                  height: 20px;
                  cursor: pointer;
                  padding: 0px;
                }

                .markerUnit {
                  background-image: url('https://cdn.rawgit.com/dyavromEPA/a71f02aca7cade0d26a90344e61738f4/raw/aca54e7f1f8eb8c87c6719feb23c8fe2198baea3/map.svg');
                  background-size: cover;
                  width:20px;
                  height: 20px;
                  cursor: pointer;
                  padding: 0px;
                }
                .mapboxgl-popup {
                  max-width: 300px;
                }
                .mapboxgl-popup-content {
                  text-align: center;
                  font-family: 'Open Sans', sans-serif;
                }

                  #infoButton {
                    position: fixed;
                    right:10px;
                    top: 10px;
                        width: 30px;
                        height: 20px;
                        box-shadow:0px 0px 3px rgba(0, 0, 0, 0.10);
                        border: none;
                        border-radius: 3px;
                        font-size: 12px;
                         font-family: 'Inconsolata';
                        color: #fff;
                        background: #ee8a65;
                        cursor:pointer;
                    }

                    #centerMap {
                      position: fixed;
                      right: 45px;
                      top: 10px;
                          width: 80px;
                          height: 20px;
                          box-shadow:0px 0px 3px rgba(0, 0, 0, 0.10);
                          border: none;
                          border-radius: 3px;
                          font-size: 12px;
                           font-family: 'Inconsolata';
                           text-align: center;

                          color: #fff;
                          background: #ee8a65;
                          cursor:pointer;
                      }

                        /* The Modal (background) */
                        .modal {
                            display: none;
                            position: fixed;
                            z-index: 1;
                            left: 0;
                            top: 0;
                            width: 100%;
                            height: 100%;
                            overflow: auto;
                            background-color: rgb(0,0,0);
                            background-color: rgba(0,0,0,0.4);

                        }

                        /* Modal Content/Box */
                        .modal-content {
                            background-color: #fefefe;
                            margin: 15% auto;
                            padding: 20px;
                            border-radius: 4px;
                            width: 60%;
                            font-family: 'Open Sans', sans-serif;
                            font-size: 14px;
                            animation-name: animatetop;
                            animation-duration: 0.4s;

                        }

                        @keyframes animatetop {
                            from {top: -300px; opacity: 0}
                            to {top: 0; opacity: 1}
                        }


                        /* The Close Button */
                        .close {
                            color: #aaa;
                            float: right;
                            font-size: 28px;
                            font-weight: bold;
                        }

                        .close:hover,
                        .close:focus {
                            color: black;
                            text-decoration: none;
                            cursor: pointer;
                        }

                        #menu {
                           background: #fff;
                           position: absolute;
                           z-index: 1;
                           top: 60px;
                           left: 10px;
                           width: 120px;
                           box-shadow:0px 0px 3px rgba(0, 0, 0, 0.10);
                           border-radius: 3px;
                           font-size: 12px;
                            font-family: 'Inconsolata';
                           color: #fff;
                           cursor:pointer;
                       }

                       #menu a {
                           font-size: 13px;
                           color: #404040;
                           display: block;
                           margin: 0;
                           padding: 0;
                           padding: 10px;
                           text-decoration: none;
                           border-bottom: 1px solid rgba(0,0,0,0.25);
                           text-align: center;
                       }

                       #menu a:last-child {
                           border: none;
                       }

                       #menu a:hover {
                           background-color: #f8f8f8;
                           color: #404040;
                       }

                       #menu a.active {
                           background-color: #3887be;
                           color: #ffffff;
                       }

                       #menu a.active:hover {
                           background: #3074a4;
                       }
                       #menuLayer {
                         position: fixed;
                         bottom:10px;
                         right:45px;
                         height: 15px;
                         width: 140px;
                         box-shadow:0px 0px 3px rgba(0, 0, 0, 0.10);
                         border-radius: 3px;
                         background: #fff;
                         padding: 10px;
                         font-family: 'Inconsolata';
                         font-size: 12px;
                         text-align: center;
                       }

    </style>
    <div id='map'></div>

    <div id='menuLayer'>
      <input id='cjneuzsr492wx2tqw6ngm0zug' type='radio' name='rtoggle' value='light' checked='checked'>
       <label for='light'>light</label>
        <input id='cjnxbj1503m302sp7bkpcxt4w' type='radio' name='rtoggle' value='satellite'>
        <label for='satellite'>satellite</label>
    </div>

    <nav id="menu"></nav>

    <div class='map-overlay top'>
        <div class='map-overlay-inner'>
        </div>
    </div>

    <button id="centerMap">Center Map</button>
    <button id="infoButton">i</button>
    <div id="myModal" class="modal">

      <div class="modal-content">
        <span class="close">&times;</span>
        <h4>Insert text </h4>

      </div>
    </div>



    <script>

    mapboxgl.accessToken = 'pk.eyJ1IjoiZHlhdnJvbSIsImEiOiJjamZsZGl0dnIwMHUwMnhvNDB4N2o0cnB6In0.AqxOgFJXuLgFMiwkPutaLA';
    var bounds = [
    [-137.3,14.3], // west-south coordinates
    [-41.6, 67.4]  // Northeast coordinates
    ];

            if (!mapboxgl.supported()) {
                alert('Your browser does not support Mapbox GL. Please try and different browser.');
            } else {
                  var map = new mapboxgl.Map({
                    container: 'map',
                    style: 'mapbox://styles/dyavrom/cjneuzsr492wx2tqw6ngm0zug',
                    center: [-105, 47],
                    zoom: 2.75,
                    // maxBounds: bounds,
                    attributionControl:false
                    });
            }


        //add second layer of data
    map.on('load', function() {

          // Floodzome Mapbox Studio layer
                map.addLayer({
                    "id": "Floodzones",
                    "type": "fill",
                    "source": {
                        type: 'vector',
                        url: 'mapbox://dyavrom.d7g97071'
                      },
                    'source-layer': 'selected_layer',
                    'minzoom':8,
                    'layout': {
                      'visibility': 'none'
                      },
                    "paint": {
                      "fill-color": "#2ee6da",
                      "fill-opacity": .5
                    }
                });

          //Aquifer Mapbox Studio layer
                map.addLayer({
                    "id": "Aquifers",
                    "type": "fill",
                    "source": {
                        type: 'vector',
                        url: 'mapbox://dyavrom.6i5kjh12'
                      },
                    'source-layer': 'aquifersSingleColor-9baxdg',
                    'minzoom':5,
                    'layout': {
                        'visibility': 'none'
                      },
                    "paint": {
                      "fill-color": "#7e5cee",
                      "fill-opacity": .25
                    }
                });


          // wetlands WMS layer
                map.addLayer({
                   'id': 'Wetlands',
                   'type': 'raster',
                   'source': {
                       'type': 'raster',
                       'tiles': [
                             'https://www.fws.gov/wetlands/arcgis/rest/services/Wetlands/MapServer/export?bbox={bbox-epsg-3857}&bboxSR=EPSG%3A3857&layers=28&layerDefs=&size=256%2c256&imageSR=&format=png&transparent=true&dpi=&time=&layerTimeOptions=&dynamicLayers=&gdbVersion=&mapScale=&f=image'
                       ],
                       'tileSize': 256,

                   },
                   'minzoom':5,
                   'layout': {
                       'visibility': 'none'
                     }
               });
    });


    var layerList = document.getElementById('menuLayer');
    var inputs = layerList.getElementsByTagName('input');

        function switchLayer(layer) {
          var layerId = layer.target.id;
          map.setStyle('mapbox://styles/dyavrom/' + layerId);
          }

        for (var i = 0; i < inputs.length; i++) {
          inputs[i].onclick = switchLayer;
          }

        //fit to center button
        document.getElementById('centerMap').addEventListener('click', function() {
            map.fitBounds([[
                -167.3,14.3
            ], [
                -41.6,67.4
            ]]);

        });

      var geojsonUnit = {
      "type": "FeatureCollection",
          "name": "latlon2",
          "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
          "features": [
          { "type": "Feature", "properties": { "Code": -999, "Name": "Place", "address": "xxx", "city": "xxx", "state": "xx", "zip": 12345, "lat": 38.79381, "lon": -91.9854, "unitType": "xxx" }, "geometry": { "type": "Point", "coordinates": [ -91.9854, 38.79381 ] } }
                ]
          }



          //add markers to map
        geojsonUnit.features.forEach(function(markerUnit) {

            // create a HTML element for each feature
            var el = document.createElement('div');
              el.className = 'markerUnit';

            // make a marker for each feature and add to the map
            new mapboxgl.Marker(el)
              .setLngLat(markerUnit.geometry.coordinates)
              .addTo(map);

            //add popups
            new mapboxgl.Marker(el)
              .setLngLat(markerUnit.geometry.coordinates)
              .setPopup(new mapboxgl.Popup({ offset: 25,
              closeButton: (true) })
              .setHTML('<h3>' + markerUnit.properties.plantName + '</h3><h5>' +
              markerUnit.properties.address +
              ', ' +
              markerUnit.properties.city +
              ' ' +
              markerUnit.properties.state +
                ', ' +
              markerUnit.properties.zip +
              '</h5><h5>'+
              'Type: '+
              markerUnit.properties.unitType +
              '</h5>'))
              .addTo(map);
            });

        // Add Geocoder and buttons
        map.addControl(new MapboxGeocoder({
            accessToken: mapboxgl.accessToken,
          }), 'top-left');


          // Add zoom and rotation controls to the map.
          map.addControl(new mapboxgl.NavigationControl({
              showCompass: (false),
          }), 'bottom-right');

          // Add geolocate control to the map.
          map.addControl(new mapboxgl.GeolocateControl({
              positionOptions: {
                  enableHighAccuracy: true
              },
              trackUserLocation: true,
              fitBoundsOptions: {maxZoom:11},

          }), 'bottom-right');

        // Info button
        var modal = document.getElementById('myModal');

                // Get the button that opens the modal
                var btn = document.getElementById("infoButton");

                // Get the <span> element that closes the modal
                var span = document.getElementsByClassName("close")[0];

                // When the user clicks on the button, open the modal
                btn.onclick = function() {
                    modal.style.display = "block";
                }

                // When the user clicks on <span> (x), close the modal
                span.onclick = function() {
                    modal.style.display = "none";
                }

                // When the user clicks anywhere outside of the modal, close it
                window.onclick = function(event) {
                    if (event.target == modal) {
                        modal.style.display = "none";
                    }
                }

            //toggle layers
          var toggleableLayerIds = [ 'Wetlands', 'Floodzones', 'Aquifers' ];

              for (var i = 0; i < toggleableLayerIds.length; i++) {
                  var id = toggleableLayerIds[i];

                  var link = document.createElement('a');
                  link.href = '#';
                  link.className = '';
                  link.textContent = id;

                  link.onclick = function (e) {
                      var clickedLayer = this.textContent;
                      e.preventDefault();
                      e.stopPropagation();

                      var visibility = map.getLayoutProperty(clickedLayer, 'visibility');

                      if (visibility === 'visible') {
                          map.setLayoutProperty(clickedLayer, 'visibility', 'none');
                          this.className = '';
                      } else {
                          this.className = 'active';
                          map.setLayoutProperty(clickedLayer, 'visibility', 'visible');
                      }
                  };

                  var layers = document.getElementById('menu');
                  layers.appendChild(link);
              }

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