Select to view content in your preferred language

Slow/Laggy performance when doing map identify with web imagery basemap

1771
4
07-03-2019 11:18 AM
MichaelDavis3
Frequent Contributor

Found this post over in the QT forum from a couple of years ago:

https://community.esri.com/message/705538-identifylayers-is-much-slower-with-basemaptypeimagery-than... 

I'm experiencing this same issue with 100.4/5 - has anyone else experienced this?  Map taps when a web imagery basemap is displayed are very slow and laggy.

0 Kudos
4 Replies
ReedHunter
Regular Contributor

I have experienced something similar at 100.3 and 100.5.  I use a map identify just for offline operational layers, retrieving results in a fraction of a second.  We allow our users to load an online basemap but we don't use any identify results from those online layers.  I recently fixed a "bug" where identify performance slowed at times to more than 10 seconds only when they had one of these basemaps.  Since the Sdk does not yet support a layer exclusion list in the identify function like some other Esri tools have in the past, my solution was to remove any online layer right before the call to identify the layers, and then restore it right after.  

This produced a brief flash in the UI as the map refreshes automatically before and after my change, but it resolved the performance issue.

I'm afraid I didn't test relative performance among online basemaps.

0 Kudos
MichaelDavis3
Frequent Contributor

Ahh sounds like we are basically doing the same thing.  I'm surprise this is still around given the post I referenced was from 2017.  I'll file a bug report through our organization account to see if we can get it prioritized for fixing...

0 Kudos
Nicholas-Furness
Esri Regular Contributor

While we consider ways to improve this experience, the recommended solution is to loop over the AGSMap.operationalLayers and call identifyLayer for each layer where identifyEnabled is true. It's what we do behind the scenes, but excluding the basemap layers.

There do happen to be benefits to this approach for some use cases. In particular, you can provide more granular feedback to your users as each layer's results return. But of course you can also limit the layers being identified against.

To coordinate the results, you could use a DispatchGroup. Create a group. Call enter() before you make each identifyLayer call and leave() when each call returns. Then you can use notify() to execute a block when all the identifies have completed.

Call something like this (I haven't tested it!) from the AGSGeoViewTouchDelegate method:

guard let operationalLayers = mapView.map?.operationalLayers as? [AGSLayer] else { return }

let identifyGroup = DispatchGroup()
var identifyResults: [AGSIdentifyLayerResult] = []

// Here we identify on all the identifiable layers.
for layer in operationalLayers where layer.isIdentifyEnabled {
    identifyGroup.enter()
    mapView.identifyLayer(layer, screenPoint: screenPoint, tolerance: 20, returnPopupsOnly: false) { (result) in
        defer { identifyGroup.leave() }

        guard result.error == nil else {
            print("Error identifying on layer \(result.layerContent.name): \(result.error!)")
            return
        }
        
        identifyResults.append(result)
    }
}

// I've put this on the main queue assuming you want to update the UI.
// But if you need to do heavy processing on the identify results, consider using
// .global(qos: .userInitiated) instead and only dispatching back to main
// with DispatchQueue.main.async {} when you're ready to update the UI.
identifyGroup.notify(queue: .main) {
    for result in identifyResults {
        // Handle the identify results.
    }
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Note that if you call the above code from some non-main thread (unlikely), you'll need to coordinate writing to the identifyResults array to be thread-safe.

Hope this helps.

0 Kudos
MichaelDavis3
Frequent Contributor

Have there been any updates to this in newer versions of the runtime SDK?  I'm still noticing lag when doing map identifies with imagery basemaps.  No lag at all with other vector or tile basemaps.  Only the imagery basemap and imagery/w labels basemap.

0 Kudos