4

I'm working on QGIS with SpatiaLite layers. The geometry of the layer I'm working with is of type "Multigeometry."

When I attempt to merge several multipart polygons, I sometimes encounter an error message:

Unable to validate changes to HABITATS_POLY layer Errors: ERROR: 6 entities not added - geometry type not compatible with current layer.

When I check the geometry structure using this expression:

geom_to_wkt($geometry) 

I get these results in the attribute table:

  • MultiPolygon((...
  • GeometryCollection (Polygon (...

I believe this is the issue, but I have no idea how to automatically prevent it.

I don’t know how to update the geometry before this constraint is checked, as it is executed immediately after saving.

I tried on a Shapefile layer, I don't have the same issue. Edit: Shapefile ended up not working properly too

2
  • I guess that with some geometries the result of merge cannot be expressed as a MultiPolygon but it yields a GeometryCollection. SpatiaLite can handle that case if the geometry column is defined as a generic "geometry". Then it can have all kind of geometries in a same table. If the geometry type is MultiPolygon then GeometryCollections cannot be saved into that table. But even if situation is OK for SpatiaLite it may not be OK for QGIS that cannot handle different geometry types on a same layer. Maybe you have different data on the shapefile layer and merging does not produce geomcollections. Commented Jan 16 at 8:37
  • Actually, I did some tests later on the Shapefile layer, but it wasn't working properly. I could see the changes, but after saving to another file, they disappeared. Occasionally, the layer wouldn't display correctly after some time. Commented Jan 16 at 8:56

1 Answer 1

4

This issue was reported by a colleague. We are not supposed to work with multipart geometries, as most of the time colleagues have issues with them, they take more time to process in my QGIS project due to numerous spatial queries, and now they are causing additional problems...

Rather than trying to make multipart geometries work, I added a BEFORE UPDATE trigger to ensure that only single-part polygons are created. Multipart ones are processed but not inserted.

Here is the trigger:

CREATE TRIGGER split_multipolygon BEFORE INSERT ON HABITATS_POLY FOR EACH ROW WHEN ST_NumGeometries(NEW.geom) > 1 BEGIN INSERT INTO log_triggers (trigger_name, action) VALUES ('split_multipolygon','INSERT'); UPDATE TABLE_VARIABLES SET split_multi = 1 WHERE id = 1; -- Insert every single parts of the multipolygon INSERT INTO HABITATS_POLY ( visibilite, lib_physio, eunis_1, eunis_2, eunis_3, eunis_4, code_eunis, enjeu_hab, etat_cons, typicite, comment, annee, surf_hab, num_etude, corine_1, corine_2, corine_3, corine_4, cde_corine, eunis22_1, eunis22_2, eunis22_3, eunis22_4, cde_eun22, eur28_1, eur28_2, eur28_3, eur28_4, cde_eur28, chn2000_1, chn2000_2, chn2000_3, chn2000_4, cde_chn2k, pvf2_1, pvf2_2, pvf2_3, pvf2_4, cde_pvf2, zh_1, zh_2, zh_3, zh_4, cde_zh, hab_prio, cat_hab, date_hab, couleur, rel_ehp, rel_zh, compart, user, data_prop, liaison_zh, date_updt, lab_eur28, context_zh, bal, geom ) WITH RECURSIVE split_parts(part_number, part_geom) AS ( SELECT 1, ST_Multi(ST_GeometryN(NEW.geom, 1)) AS part_geom UNION ALL SELECT part_number + 1, ST_Multi(ST_GeometryN(NEW.geom, part_number + 1)) FROM split_parts WHERE part_number + 1 <= ST_NumGeometries(NEW.geom) ) SELECT NEW.visibilite, NEW.lib_physio, NEW.eunis_1, NEW.eunis_2, NEW.eunis_3, NEW.eunis_4, NEW.code_eunis, NEW.enjeu_hab, NEW.etat_cons, NEW.typicite, NEW.comment, NEW.annee, NEW.surf_hab, NEW.num_etude, NEW.corine_1, NEW.corine_2, NEW.corine_3, NEW.corine_4, NEW.cde_corine, NEW.eunis22_1, NEW.eunis22_2, NEW.eunis22_3, NEW.eunis22_4, NEW.cde_eun22, NEW.eur28_1, NEW.eur28_2, NEW.eur28_3, NEW.eur28_4, NEW.cde_eur28, NEW.chn2000_1, NEW.chn2000_2, NEW.chn2000_3, NEW.chn2000_4, NEW.cde_chn2k, NEW.pvf2_1, NEW.pvf2_2, NEW.pvf2_3, NEW.pvf2_4, NEW.cde_pvf2, NEW.zh_1, NEW.zh_2, NEW.zh_3, NEW.zh_4, NEW.cde_zh, NEW.hab_prio, NEW.cat_hab, NEW.date_hab, NEW.couleur, NEW.rel_ehp, NEW.rel_zh, NEW.compart, NEW.user, NEW.data_prop, NEW.liaison_zh, NEW.date_updt, NEW.lab_eur28, NEW.context_zh, NEW.bal, part_geom AS geom FROM split_parts; UPDATE TABLE_VARIABLES SET split_multi = 0 WHERE id = 1; SELECT RAISE(IGNORE); --avoid insert into the table END; 

It works fine now.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.