Geometry checker cache does not work properly with memory layers.
refreshCache now handles a list of updated features to be thread-safe.
Also, fixes a locker mode, and correctly remove features from spatial
index.
This replaces the existing logic in `QgsRasterLayerRenderer` which
calls `QgsRasterLayer::refreshRendererIfNeeded()` to refresh the
renderer associated `QgsRasterLayerRenderer` and the raster associated
with `QgsRasterLayer`. It also makes GUI updates.
With this approach, the following new logic is done:
1. `QgsRasterRenderer::needsRefresh()` is called to check if
`rasterRenderer` needs to be updated.
2. If a refresh is needed, the new min/max values are computed by
calling `QgsRasterLayer::computeMinMax()`
3. The min/max values are used to refresh `rasterRenderer`
4. The min/max values are stored in a `QgsRenderedLayerStatistics`
and propagated to `QgisApp`
5. In QgisApp, `QgsRenderedLayerStatistics` is used to refresh the
renderer of `QgsRasterLayer` and force a refresh of the style and the
legend if the change comes from the main canvas.
This is similar to what is achieved in
`QgsRasterLayer::refreshRenderer()` to refresh the renderer according
to an extent. Contrary to the first one, this method does not perform
any GUI update or emit any signal.
It is not used at the moment. This will replace the logic to refresh a
renderer in the following commits.
This is similar to what is achieved in
`QgsRasterLayer::refreshRendererIfNeeded()` to check if the renderer
needs to be refresh according to an extent. It does not perform any
refresh.
It is not used at the moment. This will replace the logic to refresh a
renderer in the following commits.
We need to ensure that the link method is ONLY ever called from
the QgsO2 object's thread, because it involves creation of
child items and that is explicitly prohibited from external
threads by Qt.
We have to take care that we don't directly create QgsO2 objects
on the thread where the authentication request is occurring,
as QgsO2 objects are long running but the thread requesting
authentication may be short-lived. If we create QgsO2 objects
on a short-running thread, then when we later try to
authenticate using the same oauth2 authentication method we
will get a deadlock, as the O2 reply server will no longer
have an active thread or an event loop running.
This was especially evident in browser items which use oauth2
authentication. Since these are usually populated using very
short-life threads, we'd often hit this situation:
1. The connection would be expanded. Browser would create a thread
to populate the connection. The oauth2 objects would then be created
on this same thread, and everything would initially work OK. The
user could complete the authentication since the browser population
thread was blocked until this was done.
2. The browser item got populated, and then the thread populating
it was destroyed
3. Later, something else would request authentication using the
same oauth2 config. This may be eg the user expanding out a
different folder on the browser connection.
4. If the oauth2 token had expired, then we'd try to refresh it.
But this relied on event-based logic, and the event loop for the
QgsO2 object was no longer around to handle this. The authentication
request would dead-lock.
Fix this by ensuring that all QgsO2 objects are created and run on
an instance of a new QgsOAuth2Factory QThread. This thread is created
on demand, and will then exist for the life of the QGIS session.
This ensures that all QgsO2 objects will run on a thread with an
application-long lifetime, so there's no issue if they later
require event-loop based logic (such as token refresh)