ArcGIS Runtime SDK for Qt

Identify features

Maps and scenes often combine multiple sources of information such as feature layers, image layers, and graphics. Labels and legends don't always provide enough information to work out what the map or scene is displaying. Use the identify methods to quickly answer the question 'what is this item here?', allowing your users to easily explore and learn about the map or scene content by tapping or clicking on them. Information returned can be shown in pop-ups or other UI components in your app.

You can identify the visible items at a specific point on screen:

  • Within all the layers in the map or scene, or only within a specific layer
  • Within all the graphics overlays in the view or only within a specific graphics overlay
  • Returning only the topmost item or all the items at that location
  • Returning the feature, graphic, or other item at that location, or by returning pop-ups for pop-up-enabled layers

Identify methods are asynchronous, so that the UI thread of your application is not blocked waiting for results. This is especially important when working with data which resides on a server, as results do not return immediately. The results of an identify take into account:

  • Symbology—tapping on a large marker symbol used to draw a point, or a wide line symbol used to draw a polyline or outline of a polygon will include those items in the results; it's not just the geometry that is used.
  • Visibility—the visibility of a graphics overlay or layer, and of an individual feature or graphic is checked, and results will only include the visible items. The opacity of a layer or graphic is ignored.
  • Visible extent—only items within the currently visible map or scene extent are included in identify results.

Identify is supported on feature layers, map image layers, Web Map Service (WMS) layers, graphics overlays, scene layers, and also on tiled layers that are based on map services that support identify.

Note:

If time-based filtering is being used (a time extent has been set on the displaying map or scene view), identify will only return features that are within the time extent set on the geo view.

The sections below show you how to identify different items in the map or scene in different ways, but these approaches can be combined to provide general identify functionality if required.

Identify features in a feature layer

The steps below show you how to identify the features within a specific feature layer in the map or scene. Later in this topic, these steps are adapted to identify graphics.

  1. Listen to a tap or click event on the map or scene view, and get the point representing the center of the tap or click.
  2. Call the required identify method, passing in the screen point from the previous step.
    1. Choose either to identify against a specific layer, or to identify against all layers.
    2. Specify a tolerance for the search radius of the identify operation. A tolerance of 0 identifies only items at the single pixel at the screen point. However, typically this level of precision is hard to achieve, so you can supply a tolerance around the screen point. A suitable tolerance for a tap operation on a touch screen should be equivalent to the size of the tip of a finger, and a smaller tolerance should be considered for mouse pointers.
    3. Specify whether to include pop-up information on the geo-elements returned. (If no pop-ups are defined for a layer or graphics overlay, pop-ups will not be included in the results regardless of this parameter value).
    4. Optionally, specify the maximum number of results per-layer to return. This may be especially useful if identifying on service layers, as you can limit the amount of information returned to the client (the maximum results will also be limited by the server).
  3. Results consist of layer content information about the layer the results are from, and a list of GeoElement. Each GeoElement represents a feature identified at the given screen point. Iterate the results, access the geometry and attributes of the identified features, and use them as required. In the example below, each identified feature is selected.

    // lambda expression for the mouse press event on the mapview... do an identify operation
    connect(m_mapView, &MapQuickView::mouseClicked, this, [this](QMouseEvent& mouseEvent)
    {
      constexpr double tolerance = 22.0;
      constexpr bool returnPopupsOnly = false;
      constexpr int maximumResults = 1000;
      const double screenX = mouseEvent.x();
      const double screenY = mouseEvent.y();
      m_mapView->identifyLayer(m_featureLayer, screenX, screenY, tolerance, returnPopupsOnly, maximumResults);
    });
    
    // once the identify is done
    connect(m_mapView, &MapQuickView::identifyLayerCompleted, this, [this](QUuid, Esri::ArcGISRuntime::IdentifyLayerResult* rawIdentifyResult)
    {
      QScopedPointer<IdentifyLayerResult> identifyResult(rawIdentifyResult);
    
      if (!identifyResult)
        return;
    
      // clear any existing selection
      m_featureLayer->clearSelection();
    
      // create a list to store the identified elements
      QList<Feature*> identifiedFeatures;
      for (int i = 0; i < identifyResult->geoElements().size(); i++)
      {
        GeoElement* element = identifyResult->geoElements().at(i);
        if (nullptr != element)
        {
          // add the element to the list and take ownership of it.
          Feature* feature = static_cast<Feature*>(element);
          feature->setParent(this);
          identifiedFeatures.append(feature);
        }
      }
    
      // select the identified features
      m_featureLayer->selectFeatures(identifiedFeatures);
      // update the member with the number of selected features
      int count = identifiedFeatures.length();
      m_selectedFeatureText = count > 1 ? QString::number(count) + " features selected." : QString::number(count) + " feature selected.";
      emit selectedFeatureTextChanged();
    });

    Tip:

    Features are loadable, but when using identify methods, they are always returned already loaded.

Identify features in all feature layers

When you do not know which specific layer to identify on, you can identify items in any layer in the map or scene. Change the first workflow above so that you do not specify the layer to identify. This time, the results are returned as a list of IdentifyLayerResult instead of a single result.

Layers that do not support identify or do not have any results based on the inputs are not included in the returned list.

Identify topmost item only

To identify only the topmost item at the screen point (or the topmost item per layer, if identifying against all layers) change the first workflow above by removing the maximum number of results parameter. GeoElements are still returned as a list, but the list will have only zero or one items.

// call identify on the map view
constexpr double tolerance = 5.0;
constexpr int maxResults = 1;
const double screenX = mouseEvent.x();
const double screenY = mouseEvent.y();
constexpr bool returnPopupsOnly = false;
m_mapView->identifyLayer(m_featureLayer, screenX, screenY, tolerance, returnPopupsOnly, maxResults);

Identify on map image layers

Identifying against map image layers and tiled map layers follows the same workflow as shown for feature layers. The difference when identifying against map image layers are:

  • Results are returned as Features; unlike other features however, they will not have a reference to a FeatureTable.
  • Map image layers may have one or more sublayers—identify results from map image layers reflect this structure, and return results for each sublayer separately. (Note that if you have specified a maximum number of results to return, this value applies per sublayer.)

Return pop-ups as results

Some types of layer support pop-ups. You can use an identify method to return pop-ups for map content at a screen point.

Identify features in a WMS layer

WMS layers differ from other layers as they do not support returning individual attributes or geometry for a feature. WMS services perform identification on the server and return HTML documents describing identified features. You can access the returned HTML document string through the "HTML" entry in the feature's attributes. This HTML string is suitable for display in a web view.

It is impossible to get the geometry for an identified (or any other) WMS feature. An identified WMS feature's geometry will always be null. Consequently, WMS layers do not support feature selection/highlight.

Identify graphics

Graphics are identified using methods different than those used for layers. You can choose to return graphics in a specific graphic overlay or for all graphics overlays; you can also limit results to only the topmost graphic in each graphics overlay.

// connect to the mouse clicked signal on the MapQuickView
connect(m_mapView, &MapQuickView::mouseClicked, this, [this](QMouseEvent& mouseEvent)
{
  // call identify on the map view
  constexpr double tolerance = 5.0;
  constexpr bool returnPopupsOnly = false;
  constexpr int maximumResults = 1;

  m_mapView->identifyGraphicsOverlay(m_graphicsOverlay, mouseEvent.x(), mouseEvent.y(), tolerance, returnPopupsOnly, maximumResults);
});

// connect to the identifyLayerCompleted signal on the map view
connect(m_mapView, &MapQuickView::identifyGraphicsOverlayCompleted, this, [this](QUuid, IdentifyGraphicsOverlayResult* rawIdentifyResult)
{
  // Delete rawIdentifyResult on leaving scope.
  QScopedPointer<IdentifyGraphicsOverlayResult> identifyResult(rawIdentifyResult);
      if (identifyResult)
  {
    m_identifiedGraphicsCount = identifyResult->graphics().size();
    emit identifiedGraphicsCountChanged();
  }
});