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

🐛 Force simple geometrycollection on sites #3399

Merged
merged 8 commits into from
Jan 9, 2023
2 changes: 2 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ In preparation for HD Views developments (PR #3298)
**Bug fixes**

- Recreate cache folders if missing. (#3384)
- Modify site's geometry before saving to avoid edition and export of shapefiles (#3399)


2.94.0 (2022-12-12)
-----------------------
Expand Down
16 changes: 16 additions & 0 deletions geotrek/common/templates/common/sql/post_10_utilities.sql
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,19 @@ BEGIN
RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Possible to have collection of GeometryCollection
-- we need to flatten the geometrycollection to avoid problem with export and edition (#3397)

CREATE FUNCTION {{ schema_geotrek }}.flatten_geometrycollection_iu() RETURNS trigger SECURITY DEFINER AS $$
DECLARE
geoms geometry[];
geom geometry;
BEGIN
FOR geom IN SELECT (ST_Dump(NEW.geom)).geom LOOP
geoms := array_append(geoms, geom);
END LOOP;
NEW.geom := ST_ForceCollection(ST_COLLECT(geoms));
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
1 change: 1 addition & 0 deletions geotrek/common/templates/common/sql/pre_10_cleanup.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ DROP TABLE IF EXISTS south_migrationhistory; -- legacy, replaced by django_migr
DROP FUNCTION IF EXISTS ft_date_insert() CASCADE;
DROP FUNCTION IF EXISTS ft_date_update() CASCADE;
DROP FUNCTION IF EXISTS ft_uuid_insert() CASCADE;
DROP FUNCTION IF EXISTS flatten_geometrycollection_iu() CASCADE;
21 changes: 21 additions & 0 deletions geotrek/outdoor/migrations/0042_flatten_geometrycollection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Generated by Django 3.1.7 on 2021-03-15 15:12

from django.db import migrations


def flatten_geometrycollection(apps, schema_editor):
Site = apps.get_model('outdoor', 'Site')
Course = apps.get_model('outdoor', 'Course')
Site.objects.bulk_update(Site.objects.all(), ['geom'])
Course.objects.bulk_update(Course.objects.all(), ['geom'])


class Migration(migrations.Migration):

dependencies = [
('outdoor', '0041_auto_20221110_1128'),
]

operations = [
migrations.RunPython(flatten_geometrycollection, migrations.RunPython.noop),
]
4 changes: 4 additions & 0 deletions geotrek/outdoor/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,10 @@ def site_interventions(self):
qs |= Q(target_id__in=topologies) & ~Q(target_type__in=not_topology_content_types)
return Intervention.objects.existing().filter(qs).distinct('pk')

def save(self, *args, **kwargs):
super().save(*args, **kwargs)
self.refresh_from_db()


Path.add_property('sites', lambda self: intersecting(Site, self), _("Sites"))
Topology.add_property('sites', lambda self: intersecting(Site, self), _("Sites"))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-------------------------------------------------------------------------------
-- Compute elevation and elevation-based indicators
-------------------------------------------------------------------------------


CREATE TRIGGER outdoor_site_30_geometrycollection_flatten_iu_tgr
BEFORE INSERT OR UPDATE OF geom ON outdoor_site
FOR EACH ROW EXECUTE PROCEDURE flatten_geometrycollection_iu();

CREATE TRIGGER outdoor_course_30_geometrycollection_flatten_iu_tgr
BEFORE INSERT OR UPDATE OF geom ON outdoor_course
FOR EACH ROW EXECUTE PROCEDURE flatten_geometrycollection_iu();
27 changes: 26 additions & 1 deletion geotrek/outdoor/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from django.contrib.gis.geos import Polygon
from django.contrib.gis.geos.collections import GeometryCollection
from django.contrib.gis.geos.point import Point
from django.contrib.gis.geos.point import Point, GEOSGeometry
from django.test import TestCase, override_settings

from geotrek.common.tests.factories import OrganismFactory
Expand All @@ -25,6 +25,31 @@ def test_published_children_by_lang(self):
SiteFactory(name='child3', parent=parent, published_fr=True)
self.assertQuerysetEqual(parent.published_children, ['<Site: child2>', '<Site: child3>'])

def test_validate_collection_geometrycollection(self):
site_simple = SiteFactory.create(name='site',
geom='GEOMETRYCOLLECTION(POINT(0 0), POLYGON((1 1, 2 2, 1 2, 1 1))))')
self.assertEqual(site_simple.geom.wkt,
GEOSGeometry('GEOMETRYCOLLECTION(POINT(0 0), POLYGON((1 1, 2 2, 1 2, 1 1)))').wkt
)
site_complex_geom = SiteFactory.create(name='site',
geom='GEOMETRYCOLLECTION(MULTIPOINT(0 0, 1 1), '
'POLYGON((1 1, 2 2, 1 2, 1 1))))')
self.assertEqual(site_complex_geom.geom.wkt,
GEOSGeometry('GEOMETRYCOLLECTION(POINT(0 0), POINT(1 1), POLYGON((1 1, 2 2, 1 2, 1 1)))').wkt
)
site_multiple_point = SiteFactory.create(name='site',
geom='GEOMETRYCOLLECTION(POINT(0 0), POINT(1 1), POINT(1 2))')
self.assertEqual(site_multiple_point.geom.wkt,
GEOSGeometry('GEOMETRYCOLLECTION(POINT(0 0), POINT(1 1), POINT(1 2)))').wkt
)
site_multiple_geomcollection = SiteFactory.create(name='site',
geom='GEOMETRYCOLLECTION('
'GEOMETRYCOLLECTION(POINT(0 0)),'
'GEOMETRYCOLLECTION(POINT(1 1)), '
'GEOMETRYCOLLECTION(POINT(1 2)))')
self.assertEqual(site_multiple_geomcollection.geom.wkt,
'GEOMETRYCOLLECTION (POINT (0 0), POINT (1 1), POINT (1 2))')


class SiteSuperTest(TestCase):
@classmethod
Expand Down