In the ArcGIS Server JavaScript API v4x, is it possible to simulate or programatically trigger a click on the map at a given location?
I've seen Simulate a mouse-click inside an ArcGIS Online JavaScript Application as a workaround, but in my case I'd like to trigger the view's hitTest function, which runs after the user clicks. This is a shorthand way to get all visible features on the map, without having to iterate through them all and manually run a QueryTask
.
Edit: to illustrate why this is useful, I have a map with 7 layers. When I manually click on the map, the view's hitTest
function instantly returns the attribute values of all features at the location clicked. See the response.results
object in the debugger:
There was no need for me to run 7 asynchronous QueryTask
operations then collate the responses after waiting for each to return - the view handles this without requiring a single network request. The view also handles changing layer visibility automatically, so if (eg) one layer was switched off when I clicked, then only 6 graphics would be returned, etc.
Given a known coordinate, is it possible to trigger a click at that location?
-
1 idea: I understand it's not precisely what you are looking for, however in UI testing ESRI js API apps, we use Selenium to generate a screen click and assert on the js API watch behavior. Can you update your question to explain why you want a "shorthand way to get all visible features on the map?" 2nd idea: We use the js API TOC Dom elements as a cache of current layers and their visibility; then inquiry into that element stack when we need to interrogate the map display layers. -- would this work in your case?JasonInVegas– JasonInVegas2020年11月04日 01:08:37 +00:00Commented Nov 4, 2020 at 1:08
-
@JasonInVegas thanks for the suggestions. I updated the question to explain why programatically triggering a click would be so advantageous. Selenium is great but doesn't fit into the use-case here unfortunately. Knowing which layers are visible isn't the issue, the goal is to avoid having to manually manage the various queries, and collating their asynchronous responses in the popupStephen Lead– Stephen Lead2020年11月04日 02:32:15 +00:00Commented Nov 4, 2020 at 2:32
-
FYI we discussed the arbitrary async returns with ESRI API team and requested an improvement so that the returns are collated relative to the layer stack before async response. They thought it was presumptious to predetermine return order and wanted to give client side the opportunity to sort it however it was beneficial to specific use-cases. We wrote a parser all queries go through to align returns with layer stack....all returns run (crawl) through it every time.JasonInVegas– JasonInVegas2020年11月05日 16:36:14 +00:00Commented Nov 5, 2020 at 16:36
-
@JasonInVegas cool thanks for the tip, that sounds handyStephen Lead– Stephen Lead2020年11月05日 21:31:17 +00:00Commented Nov 5, 2020 at 21:31
1 Answer 1
Given the coordinate as you stated, you could use the Mapview.toScreen
function to get the screen point and then use hitTest
which takes either a mouseEvent or a screen point.
Something like this should work.
var mapPoint = {
x: -49.97,
y: 41.73,
spatialReference:{
wkid: 4326
}
};
var screenPoint = view.toScreen(mapPoint);
view.hitTest(screenPoint).then(function (response) {
if (response.results.length) {
var graphic = response.results.filter(function (result) {
// check if the graphic belongs to the layer of interest
return result.graphic.layer === myLayer;
})[0].graphic;
// do something with the result graphic
console.log(graphic.attributes);
}
});
Edit
Just in case anyone is looking for other web mapping frameworks to this with,
I got to this solution because I knew of leaflet.js' map.latLngToContainerPoint
function which does the same thing as MapView.toScreen
-
1Genius - many thanks. I didn't realise that you could call the
view.hitTest
method like that. I can't award the bounty until tomorrow, but I'll happily sling it your way thenStephen Lead– Stephen Lead2020年11月04日 08:57:54 +00:00Commented Nov 4, 2020 at 8:57 -
I didn't know either, I actually needed this last year and was stuck for days. If you didn't add the links to the reference I doubt I would have found it.Dror Bogin– Dror Bogin2020年11月04日 09:05:53 +00:00Commented Nov 4, 2020 at 9:05
-
1best 100 imaginary internet points I ever spentStephen Lead– Stephen Lead2020年11月04日 09:06:27 +00:00Commented Nov 4, 2020 at 9:06
-
2Wow, I am impressed where the API got to in the last couple of years. This is perfect answer, deleting mine as it is nowhere helpful as this solution.Miro– Miro2020年11月04日 09:55:50 +00:00Commented Nov 4, 2020 at 9:55