view.hitTest bug with multipoint geometry?

2000
3
Jump to solution
03-28-2017 09:18 AM
BrandonFlessner
Occasional Contributor

At 4.3, view.hitTest() method does not work on a esriGeometryMultipoint service. I set up a demo of the problem, but I couldn't find an ESRI sample service with multipoint geometry, so you'll have to supply your own. My test map service isn't public. Anyway, insert your multipoint geometry map service url and you will see that the cursor stays as the default when hovering over a multipoint feature but works correctly when hovering over a regular point. Or maybe I'm doing something wrong? Rene Rubalcava 

JS Bin - Collaborative JavaScript Debugging 

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
  <meta name="description" content="[Get started with MapView - Create a 2D map - 4.3]">
  <!--
  ArcGIS API for JavaScript, https://js.arcgis.com
  For more information about the get-started-mapview sample, read the original sample description at developers.arcgis.com.
  https://developers.arcgis.com/javascript/latest/get-started-mapview/index.html
  -->
<title>Get started with MapView - Create a 2D map - 4.3</title>
  <style>
    html,
    body,
    #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }
  </style>

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

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

      var map = new Map({
        basemap: "streets"
      });

      var view = new MapView({
        container: "viewDiv",
        map: map,
        center: [-84.511, 39.092],
           zoom: 15
      });
      
      var points = new FeatureLayer({
        url: "https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/0"
      });
      map.add(points); 
      
      //var multipoint = new FeatureLayer({
      //  url: "INSERT MULTIPOINT GEOMETRY SERVICE HERE /0"
      //});
      //map.add(multipoint);
      
      view.on('pointer-move', function(evt){
        view.hitTest({x: evt.x, y: evt.y}).then(changeCursor);
      });

      function changeCursor(response){
        if (response.results.length > 0){
          document.getElementById("viewDiv").style.cursor = "pointer";
        } else {
          document.getElementById("viewDiv").style.cursor = "default";
        }
      }

    });
  </script>
</head>

<body>
  <div id="viewDiv"></div>
</body>
</html>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
1 Solution

Accepted Solutions
ThomasSolow
Occasional Contributor III

It looks to me like hitTest is not working on Multipoint geometries in 2D.  Multipoints aren't supported at all yet in 3D.

Here's a jsbin based on your sample that I used to test: JS Bin - Collaborative JavaScript Debugging .  That just gets a bunch of features from a point feature service and adds them as a single multipoint graphic.  Sure often, hitTest is not returning anything as you mouse over the graphic.

Edit: I should also mention that, because multipoints aren't supported yet in 3D, I've found it useful to just use single point geometries and relate them with some shared attribute field->value.  This isn't a great long term solution but it's what my team is currently doing.

I also changed the jsbin to use a graphics layer.  I'm not sure if hitTest works on view.graphics at all.

View solution in original post

3 Replies
ThomasSolow
Occasional Contributor III

It looks to me like hitTest is not working on Multipoint geometries in 2D.  Multipoints aren't supported at all yet in 3D.

Here's a jsbin based on your sample that I used to test: JS Bin - Collaborative JavaScript Debugging .  That just gets a bunch of features from a point feature service and adds them as a single multipoint graphic.  Sure often, hitTest is not returning anything as you mouse over the graphic.

Edit: I should also mention that, because multipoints aren't supported yet in 3D, I've found it useful to just use single point geometries and relate them with some shared attribute field->value.  This isn't a great long term solution but it's what my team is currently doing.

I also changed the jsbin to use a graphics layer.  I'm not sure if hitTest works on view.graphics at all.

BrandonFlessner
Occasional Contributor

Thanks for confirming Thomas. Looks like I'll have to go with the single point geometry and relate via a field as you suggest. Hopefully this is fixed/supported in the next release.

0 Kudos
ThomasSolow
Occasional Contributor III

I looked into this a little more.  Popups are working on multipoint geometries, which is curious because hitTest doesn't work on multipoints.  I wasn't sure how the view knows that user clicked on a multipoint without hitTest.

I asked a coworker and it turns out that the popupManager uses a spatial query to do this calculation as a fallback if hitTest doesn't return anything.  Basically, when you click on the map, an extent is created for each layer based on the pixel size of the graphics in that layer and that extent is tested against all the graphics in that layer. My feeling is that this method is likely temporary until hitTest matures.

This might affect your use-case a little bit: if you want to do a spatial query to test if the cursor is intersecting a multipoint, you can.  But it will involve creating some geometry to represent where the use clicked and testing that geometry against each graphic in all applicable layers.  These tests will spatial tests (something like Extent.intersects or geometryEngine.intersects), so they'll likely be slower than hitTest and you could definitely run into speed issues as the number of graphics increase.