qgis / QGIS

QGIS is a free, open source, cross platform (lin/win/mac) geographical information system (GIS)
https://qgis.org
GNU General Public License v2.0
9.83k stars 2.9k forks source link

Rubberband/snapping using old nodes if a geometry is modified outside QGIS #57784

Open ismogis opened 2 weeks ago

ismogis commented 2 weeks ago

What is the bug or the crash?

If a geometry is modified in a database after saving layer edits in QGIS the geometry isn't updated in edit/snapping layers.

editbug

In the example case below, there is a PostGIS table with a trigger that makes a translation for each row inserted or updated on the table. The polygon itself is updated in QGIS correctly but the edit/snapping layer has still the old geometry. This causes most probably for example the issue described in #57181.

Steps to reproduce the issue

  1. Create a table with a trigger translating the geometry in each insert or update.
-- create a trigger function to translate polygons
CREATE OR REPLACE FUNCTION public.translate_geom()
RETURNS trigger AS $$
BEGIN
  NEW.geom = ST_Translate(NEW.geom, 1000, 0);
  RETURN NEW;
END; $$ LANGUAGE 'plpgsql';

-- create a test table
CREATE TABLE translated_polygons
(
    id bigserial NOT NULL,
    geom geometry(POLYGON, 3067),
    CONSTRAINT "PK_translated_polygons" PRIMARY KEY (id)
);

-- create a trigger
CREATE TRIGGER translate_geom
BEFORE INSERT OR UPDATE ON translated_polygons
FOR EACH ROW EXECUTE PROCEDURE public.translate_geom();
  1. Open the table in QGIS.

  2. Start editing.

  3. Digitize a polygon.

  4. Save layer edits.

  5. Move one vertex (or modify existing geometry some other way).

  6. Save layer edits.

  7. The polygon is shown correctly but for example the vertex tool and snapping use old coordinates.

Versions

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">

QGIS version | 3.36.3-Maidenhead | QGIS code revision | 2df9655469b -- | -- | -- | -- Qt version | 5.15.3 Python version | 3.10.12 Compiled against GDAL/OGR | 3.4.1 | Running against GDAL/OGR | 3.4.3 PROJ version | 8.2.1 EPSG Registry database version | v10.076 (2022-08-31) Compiled against GEOS | 3.10.2-CAPI-1.16.0 | Running against GEOS | 3.11.1-CAPI-1.17.1 SQLite version | 3.37.2 Compiled against PDAL | 2.3.0 | Running against PDAL | 2.5.0 PostgreSQL client version | 14.11 (Ubuntu 14.11-0ubuntu0.22.04.1) SpatiaLite version | 5.0.1 QWT version | 6.1.4 QScintilla2 version | 2.11.6 OS version | Ubuntu 22.04.4 LTS   |   |   |   Active Python plugins processing | 2.12.99 grassprovider | 2.12.99 db_manager | 0.1.20 MetaSearch | 0.3.6 QGIS version 3.36.3-Maidenhead QGIS code revision [2df9655469b](https://github.com/qgis/QGIS/commit/2df9655469b) Qt version 5.15.3 Python version 3.10.12 Compiled against GDAL/OGR 3.4.1 Running against GDAL/OGR 3.4.3 PROJ version 8.2.1 EPSG Registry database version v10.076 (2022-08-31) Compiled against GEOS 3.10.2-CAPI-1.16.0 Running against GEOS 3.11.1-CAPI-1.17.1 SQLite version 3.37.2 Compiled against PDAL 2.3.0 Running against PDAL 2.5.0 PostgreSQL client version 14.11 (Ubuntu 14.11-0ubuntu0.22.04.1) SpatiaLite version 5.0.1 QWT version 6.1.4 QScintilla2 version 2.11.6 OS version Ubuntu 22.04.4 LTS Active Python plugins processing 2.12.99 grassprovider 2.12.99 db_manager 0.1.20 MetaSearch 0.3.6 ### Supported QGIS version - [X] I'm running a supported QGIS version according to [the roadmap](https://www.qgis.org/en/site/getinvolved/development/roadmap.html#release-schedule). ### New profile - [X] I tried with a new [QGIS profile](https://docs.qgis.org/latest/en/docs/user_manual/introduction/qgis_configuration.html#working-with-user-profiles) ### Additional context It seems that the bug is caused by QgsPointLocator that doesn't get the modified geometry. When a new feature is added the corresponding geometry is added to QgsPointLocator in the function onFeatureAdded(). https://github.com/qgis/QGIS/blob/29bb1944f02704ebad49ad0199fcf7b681bd55fe/src/core/qgspointlocator.cpp#L1261-L1277 When modifying an existing geometry this isn't handled. I'm not sure about the most feasible solution. One solution could be emitting a signal for the changed geometry in QgsVectorLayerEditBuffer::commitChangesChangeAttributes() but still we would need to ensure that QgsPointLocator gets the modified geometry.
uclaros commented 1 week ago

This seems like a duplicate of #31251

Since you're working with PostGIS data, you should be able to overcome that by using the postgres NOTIFY command