Select to view content in your preferred language

How to make a Popup show only one feature when the mouse clicks on a spot where multiple features meet

243
1
08-20-2024 01:37 PM
andrewc213
Emerging Contributor

I have a Layer containing land parcels that are drawn with purple lines. Ideally, a single click right on a parcel (regardless if the mouse clicks on a spot right on or near the purple border) should activate a Popup that shows only that parcel:
andrewc213_2-1724185699161.png

However, clicking right on a point (or clicking right next to a purple line) where multiple parcels touch will fetch multiple parcels.

No Popup appears when clicking right on the point where Aragon Ave and Maceo St intersect:
andrewc213_0-1724179948430.png

However, when I zoom out as far as possible and click on the exact same spot, four parcels are yielded (the four parcels at the four corners of the intersection):
andrewc213_1-1724180014659.png

So it seems that what's going on is this: the area of effect of a mouse click is not a single pixel point on the screen, but rather a small circle, and the size of that circle is fixed regardless of how close or far the MapView is zoomed (basically the map's scale doesn't seem to matter; the circular area of effect is the same physical size on the screen). Whichever parcel(s) are touched by that circular area of effect will be accounted for in the Popup. What I would like to do is have the Popup consider only one of the potentially multiple parcels that are gathered. The one parcel I want taken into account is the one closest to the mouse click point.

0 Kudos
1 Reply
andrewc213
Emerging Contributor

I tried this, but it doesn't seem to work:

 

    reactiveUtils.when(() => view.ready, () => {
      view.on('click', async (event) => {
        const response = await view.hitTest(event);
  
        if (response.results.length > 0) {
          // Filter results to only those from the assessorParcelsMap
          const parcelResults = response.results.filter((result) => {
            return result.type === 'graphic' && result.graphic.layer === assessorParcelsMap;
          }) as __esri.GraphicHit[];
  
          if (parcelResults.length > 0) {
            const clickedPoint = view.toMap({ x: event.x, y: event.y }) as Point;
  
            // Find the closest parcel using the geometryEngine.distance method
            const closestFeature = parcelResults.reduce(
              (closest, feature) => {
                const geometry = feature.graphic.geometry;
                const distance = geometryEngine.distance(geometry, clickedPoint);
  
                return distance !== null && distance < closest.distance
                  ? { graphic: feature.graphic, distance }
                  : closest;
              },
              { graphic: null as Graphic | null, distance: Infinity }
            );
  
            if (closestFeature.graphic) {
              view.popup.open({
                features: [closestFeature.graphic],
                location: closestFeature.graphic.geometry as __esri.Geometry,
              });
            }
          }
        }
      });
    });

 

0 Kudos