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.
--
Update 2024-09-06:
With the help of Amr at ESRI Support Canada I was able to get a Vector Tile Service example wherein I can reproduce the issue. See this Codepen here. In this example the behavior is more pronounced than I describe above I think. The first click will work. After that the console will show errors or nothing found.
Solved! Go to Solution.
Hi there,
This issue is addressed at version 4.31 which will be released in mid November. You can test the fix using our next version. Here is your codepen updated to point to the next version: https://codepen.io/U_B_U/pen/abgMmpq?editors=1000
👍 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.
Hi there,
I am able to reproduce the issue you described. We will look into it and will update you once we have a fix or solution. Thank you for reporting the issue.
Hi there,
This issue is addressed at version 4.31 which will be released in mid November. You can test the fix using our next version. Here is your codepen updated to point to the next version: https://codepen.io/U_B_U/pen/abgMmpq?editors=1000
Fantastic news! I just tried the codepen and confirmed the behavior now works as expected. I am going to mark this as resolved and look forward to the release of 4.31 and starting to use this pattern in our own applications. Thanks again.