What is the best way to select features from multiple layers in 4.x?

800
4
Jump to solution
03-08-2021 09:16 AM
MattStayner
Occasional Contributor

I have a map that contains features services, map services and graphic layers. What is the best way to select multiple features from multiple layers? For example, I want a user to be able to select a point in a mass of features from multiple layers and cycle through the features in a custom side panel to find the feature they are interested in.

I tried using hitTest, but that only returns the first feature from each layer. Too bad. 

I found this example for 3.x. Would this be the best approach in 4.x as well? Any chance I could get one of your awesome working codepen examples using 4.x?

Query and QuertyTask are kind of pain because the buffer needs to change based on the zoom level. I know the API is already accounting for that using hitTest and other methods. Are there any other approaches we should consider? For example, in 3.x, we used var popup = map.infoWindow and connect.connect(popup, "onSetFeatures", function() {}) to trigger the custom panel based on a click on the map. Is there an equivalent approach in 4.x?

0 Kudos
1 Solution
4 Replies
MattStayner
Occasional Contributor

The Esri widget Popup looks like it is what we are looking for. We will give it a try. Thanks!

0 Kudos
jkumartry1980
New Contributor II

Hi Matt,

Have you tried this option, I need solution for similar task. Could you please share the idea?

 

0 Kudos
MattStayner
Occasional Contributor

@jkumartry1980 Yes, I got it working, but it took a bit to get everything in place.

First, I added the popupTemplate to all the feature layers in my map

layerToAdd = new FeatureLayer(layer.service_url, {
  outFields: ['*'],
  id: layerName,
  popupTemplate: {}, // required to trigger info panel
  visible
})

Then I listened for a click on the view, and looked at all of the results:

this.view.on('click', async (event) => {
  // Use popup to select features on the map. Only features with popupTemplate enabled will be selected
  const resp = await view.popup.fetchFeatures(event)
  const results = await resp.allGraphicsPromise
  if (Array.isArray(results)) {
    if (results.length === 0) {
      this.$emit('pointer-clicked-outside')
      return
    }
    const popupResults = results.filter((r) => {
      //do something with results, like highlight the selected feature
      await this.highlightItem(r)
    })
  }
})

Lastly, I highlighted the selected graphic

async highlightItem (gisInfo) {
    const { view } = this
    if (gisInfo.layer) {
      const layerView = await view.whenLayerView(gisInfo.layer)
      const selected = layerView.highlight(gisInfo)
      this.highlightSelect.push(selected)
    } else if (gisInfo?.sourceLayer?.layer) {
      const layerView = await view.whenLayerView(
        gisInfo.sourceLayer.layer
      )
      const selected = layerView.highlight(gisInfo)
      this.highlightSelect.push(selected)
    }
}

I stripped out the code that wasn't applicable. I'm not sure if what I have above will work exactly as-is, but hopefully it gets you on the right track.