JS API 4.x view.hitTest issue

6157
11
Jump to solution
11-01-2016 08:45 AM
RobertScheitlin__GISP
MVP Emeritus

I am seeing behavior that does not seem to be what is documented. When using points or lines in a featurelayer and using the view.hitTest, I never get any more that one graphic in the hitTest promise results even know I am sure I am click on more than one.

Here is a JS API sample that demos this (notice the console reports only one graphic even if you click where one or more hurricane tracks intersect):

ubatsukh-esristaff

odoe

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
  <title>Access features with click events - 4.1</title>

  <style>
    html,
    body,
    #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }

    #info {
      background-color: black;
      opacity: 0.75;
      color: orange;
      font-size: 18pt;
      padding: 8px;
      visibility: hidden;
    }
  </style>

  <link rel="stylesheet" href="https://js.arcgis.com/4.1/esri/css/main.css">
  <script src="https://js.arcgis.com/4.1/"></script>

  <script>
    require([
      "esri/Map",
      "esri/views/MapView",
      "esri/layers/FeatureLayer",
      "esri/renderers/UniqueValueRenderer",
      "esri/symbols/SimpleLineSymbol",
      "dojo/dom",
      "dojo/domReady!"
    ], function(
      Map,
      MapView,
      FeatureLayer,
      UniqueValueRenderer,
      SimpleLineSymbol,
      dom
    ) {

      var layer = new FeatureLayer({
        url: "https://sampleserver6.arcgisonline.com/arcgis/rest/services/Hurricanes/MapServer/1",
        outFields: ["*"]
      });

      var map = new Map({
        basemap: "dark-gray",
        layers: [layer]
      });

      var view = new MapView({
        container: "viewDiv",
        map: map,
        center: [-61.125537, 35.863534],
        zoom: 4
      });

      view.ui.add("info", "top-right");

      // Set up a click event handler and retrieve the screen point
      view.on("click", function(evt) {
        var screenPoint = evt.screenPoint;

        // the hitTest() checks to see if any graphics in the view
        // intersect the given screen point
        view.hitTest(screenPoint)
          .then(getGraphics);
      });

      function getGraphics(response) {
        // the topmost graphic from the click location
        // and display select attribute values from the
        // graphic to the user
        console.info(response.results)
//the hit test never returns any more than one graphic even if you definitely click on two or more lines.        
        var graphic = response.results[0].graphic;
        var attributes = graphic.attributes;
        var category = attributes.CAT;
        var wind = attributes.WIND_KTS;
        var name = attributes.NAME;

        dom.byId("info").style.visibility = "visible";
        dom.byId("name").innerHTML = name;
        dom.byId("category").innerHTML = "Category " + category;
        dom.byId("wind").innerHTML = wind + " kts";

        // symbolize all line segments with the given
        // storm name with the same symbol
        var renderer = new UniqueValueRenderer({
          field: "NAME",
          defaultSymbol: layer.renderer.symbol || layer.renderer.defaultSymbol,
          uniqueValueInfos: [{
            value: name,
            symbol: new SimpleLineSymbol({
              color: "orange",
              width: 5
            })
          }]
        });
        layer.renderer = renderer;
      }

      view.then(function() {
        layer.then(function() {
          // update the default renderer's
          // symbol when the layer loads
          var renderer = layer.renderer.clone();
          renderer.symbol.width = 4;
          renderer.symbol.color = [255, 255, 255, 0.4]
          layer.renderer = renderer;
        });
      });
    });
  </script>
</head>

<body>
  <div id="viewDiv"></div>
  <div id="info">
    <span id="name"></span><br>
    <span id="category"></span><br>
    <span id="wind"></span>
  </div>
</body>

</html>
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
1 Solution

Accepted Solutions
ReneRubalcava
Frequent Contributor

view.hitTest will return the topmost feature per layer, so a self-intersecting layer will only return one feature. We'll update the documentation to make this clear.

Thanks!

View solution in original post

11 Replies
ReneRubalcava
Frequent Contributor

view.hitTest will return the topmost feature per layer, so a self-intersecting layer will only return one feature. We'll update the documentation to make this clear.

Thanks!

RobertScheitlin__GISP
MVP Emeritus

Rene,

   So is there anything in the 4.1 api that will allow you to click on coindident graphics and get an array of the graphics clicked. Currently the popup does not offer paging of graphics otb like the 3.x api so what alternative is there to get the graphics when you have two overlaping polygons in the same layer and you click on the overlap and want to know what graphics were under the click?

SethPatrich2
New Contributor II

Rene--

Is there any alternative function we can use in 4.2 to capture all graphics that intersect with a click event?

0 Kudos
ReneRubalcava
Frequent Contributor

If you have a layer(s) that can have overlapping features, your best bet is to use the mapPoint you get from the view click and do a QueryTask on each layer. You can use dojo/promise/all to wait for all the queries to finish and do it that way.

SethPatrich2
New Contributor II

Unfortunately, that does not work either.  I have been trying to use a FeatureLayerView to do a client-side query on the graphics that intersect with a mouse click event.  After stepping through the code, it appears that a client-side query will only work with a list of ObjectIDs or an extent.  I tried artificially creating an "extent" around the mouse click location, but that has not worked either.

0 Kudos
UndralBatsukh
Esri Regular Contributor

Hi Seth, 

As Rene mentioned, you should be able to use QueryTask with different Query parameters.

Also as you pointed out in your post, when calling FeatureLayerView.queryFeatures(), the query only accepts Extent as a geometry and also can only do "intersects". 

simple test app that shows FeatureLayerVIew.queryFeatures(): JS Bin - Collaborative JavaScript Debugging 

0 Kudos
DavidColey
Frequent Contributor

Hi Rene  - but this really doesn't address the issues surrounding the paging issues of the popup at 4.x now.  While we have managed to solve getting a graphic return from our feature layers using hitTest, we continue to confounded by the inability of the popup to page fetures -  except when a user performs a click on the basemap and two or more features intersect the popups otb tolerance graphic.

This tolerance graphic seems to be a bit of a black box - we can't get at it but it's obvious that there is some paging functionality present.

Yes, we could return a query from each feature layer, but thaht's like going back to old 3.x identify method using a map service.  

Thanks,

David

MichaelVolz
Esteemed Contributor

Seth:

Is the new EnerGov js api application being built off of the 4.x api as opposed to the 3.x api?

0 Kudos
MichaelVolz
Esteemed Contributor

Robert:

Is this a large issue for a tool such as the eSearch widget against the jsapi 4.x that you are currently working with?  If so, what impact does it have on this incredibly useful widget?

0 Kudos