Select to view content in your preferred language

HitTest errors with VectorTileLayer and setStyleLayer

46
1
4 hours ago
RyanSutcliffe
Occasional Contributor II

I am trying to create a map with a VectorTileLayer in it that responds to a user click by highlighting the clicked record (via style and filter updates).

To do this I use a combination of the View's hitTest and  the VectorTileLayer's setStyleLayer methods.

I cannot share publicly the source VectorTileServer service used for my VectorTileLayer and I cannot seem to find a publically available VectorTileLayer with a single polygon layer with attributes included in it. So I cannot give a working codepen of the exact problem. 

However the gist of the code is like this:

 

// setup map/mapview

// add VectorTileLayer with my own styles:

 const vtl = new VectorTileLayer({
      style: {
        //...
        layers: [
          {
            "fill-opacity": 0.6,
            id: "Accel/Fill0",
            layout: {},
            "line-opacity": 0.6,
            paint: {
              "fill-color": "rgba(255,255,25, 255)",
              "fill-opacity": 0.4,
            },
            "source-layer": "layer",
            type: "fill",
          },
          {
            "fill-opacity": 1,
            filter: ["==", ["get", "id"], 28428], // want to change this dynamically
            id: "Accel/Linehighlight", // this is the style layer to update
            layout: {},
            "line-opacity": 1,
            paint: {
              "line-color": [249, 137, 0, 255],
              "line-width": 3,
            },
            "source-layer": "layer",
            type: "line",
          },
        ],
      },
    });

map.add(vtl);

view.on("click", (event) => {
    view.hitTest(event).then((response) => {
      try {
        if (response.results.length) {
          console.log("found a layer");
          const vectorLayer = response.results[0].layer;
          const highlightIndex = vectorLayer.getStyleLayerIndex(
            "Accel/Linehighlight"
          );
          const newHighlightStyle = vectorLayer.getStyleLayer(
            "Accel/Linehighlight"
          );

          newHighlightStyle.filter = [
            "==",
            ["get", "id"],
            response.results[0].graphic.attributes.id,
          ];
          vectorLayer.deleteStyleLayer("Accel/Linehighlight");
          vectorLayer.setStyleLayer(newHighlightStyle, highlightIndex);
          
        } else {
          // this happens when clicking a feature inside its geometry.
          console.warn("Nothing found");
        }
      } catch (err) {
// this happens also. see error below.
        console.warn(err);
      }
    });
  });

 

 

The behavior I get is it works initially. The selected feature gets updated and the map redraws accordingly. After that, the subsequent click of another feature fails. Either nothing is returned or this error gets returned:

VectorTileLayerView2D.js:117 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'source')

This will happen a few times. I can make it work again after a few tries, usually in combination with some zoom/pan behavior.

 

If I use the hitTest on the same layer without updating the layerStyles, everything is fine. So its something about how I am trying to update the styles above.

Happy to make a codepen if someone can point me to an appropriate public datasource. 

What I am trying to do is similar to patterns in ESRI's example here. However I don't think they use hitTest there (its in the code example but not working), and they don't use filters on the layers based on attributes of the layers. 

 

Tags (2)
1 Reply
cdbj
by
New Member

👍  I'd also like to know what the best thing to do in this situation is. All I want to do is highlight the selected feature in the VectorTileLayer, but the hittest system is not being helpful by not sharing any geometry information for polygons.

0 Kudos