Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
2 tasks done
ismogis opened this issue Jun 17, 2024 · 5 comments · Fixed by #58528
Closed
2 tasks done

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

ismogis opened this issue Jun 17, 2024 · 5 comments · Fixed by #58528
Assignees
Labels
Bug Either a bug report, or a bug fix. Let's hope for the latter! Digitizing Related to feature digitizing map tools or functionality

Comments

@ismogis
Copy link
Contributor

ismogis commented Jun 17, 2024

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

<style type="text/css"> p, li { white-space: pre-wrap; } </style>
QGIS version 3.36.3-Maidenhead QGIS code revision 2df9655
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 [2df9655](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

  • I'm running a supported QGIS version according to the roadmap.

New profile

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().

const QgsRectangle bbox = f.geometry().boundingBox();
if ( bbox.isFinite() )
{
const SpatialIndex::Region r( rect2region( bbox ) );
mRTree->insertData( 0, nullptr, r, f.id() );
auto it = mGeoms.find( f.id() );
if ( it != mGeoms.end() )
{
delete *it;
*it = new QgsGeometry( f.geometry() );
}
else
{
mGeoms[fid] = new QgsGeometry( f.geometry() );
}
}

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.

@ismogis ismogis added the Bug Either a bug report, or a bug fix. Let's hope for the latter! label Jun 17, 2024
@agiudiceandrea agiudiceandrea added the Digitizing Related to feature digitizing map tools or functionality label Jun 18, 2024
@uclaros
Copy link
Contributor

uclaros commented Jun 19, 2024

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

@Djedouas
Copy link
Member

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.

In fact, there is no way to know when the underlying data provider has changed the geometry on his side... QGIS can't emit a signal, because nothing is triggered in QGIS by this specific underlying change.

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

+1 with using postgres NOTIFY command, see details on my comment here

@Djedouas
Copy link
Member

Another solution is to check the layer itself in Dependencies section of the layer properties.

In this way, every change on the layer will trigger a full refresh of the data, caches, and rubber bands.

@ismogis
Copy link
Contributor Author

ismogis commented Aug 28, 2024

Thank you for your replies!

If we use a PostGIS data source using NOTIFY in the trigger function is indeed an option.

@Djedouas I wasn't able to make this dependency solution work in 3.38.2. I would have assumed that QGIS can't get a trigger when data changes underneath. Is there something I'm missing?

@Djedouas Djedouas reopened this Aug 29, 2024
@Djedouas
Copy link
Member

@Djedouas I wasn't able to make this dependency solution work in 3.38.2. I would have assumed that QGIS can't get a trigger when data changes underneath. Is there something I'm missing?

🤔 Hmm there is potentially a bug here. I reopen the issue, because I can reproduce the problem, I can't get the dependency working as it should (i.e. reload data and refresh cache and everything each time the layer is saved).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Either a bug report, or a bug fix. Let's hope for the latter! Digitizing Related to feature digitizing map tools or functionality
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants