Skip to content

Commit

Permalink
[Fixes #11256] Assign regions based on contains and overlaps (#11257)
Browse files Browse the repository at this point in the history
* Assign regions based on contains and overlaps

* tests

* fix E501
  • Loading branch information
giohappy committed Jul 12, 2023
1 parent 3169cc0 commit dbc282a
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 10 deletions.
17 changes: 16 additions & 1 deletion geonode/base/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
from django.contrib.auth import get_user_model
from django.db.models.fields.json import JSONField
from django.utils.functional import cached_property, classproperty
from django.contrib.gis.geos import Polygon, Point
from django.contrib.gis.geos import GEOSGeometry, Polygon, Point
from django.contrib.gis.db.models import PolygonField
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _
Expand Down Expand Up @@ -204,6 +204,21 @@ def geographic_bounding_box(self):
"""BBOX is in the format: [x0,x1,y0,y1]."""
return bbox_to_wkt(self.bbox_x0, self.bbox_x1, self.bbox_y0, self.bbox_y1, srid=self.srid)

@property
def geom(self):
srid, wkt = self.geographic_bounding_box.split(";")
srid = re.findall(r"\d+", srid)
geom = GEOSGeometry(wkt, srid=int(srid[0]))
geom.transform(4326)
return geom

def is_assignable_to_geom(self, extent_geom: GEOSGeometry):
region_geom = self.geom

if region_geom.contains(extent_geom) or region_geom.overlaps(extent_geom):
return True
return False

class Meta:
ordering = ("name",)
verbose_name_plural = "Metadata Regions"
Expand Down
41 changes: 40 additions & 1 deletion geonode/base/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,14 @@
Menu,
MenuItem,
Configuration,
Region,
TopicCategory,
Thesaurus,
ThesaurusKeyword,
generate_thesaurus_reference,
)
from django.conf import settings
from django.contrib.gis.geos import Polygon
from django.contrib.gis.geos import Polygon, GEOSGeometry
from django.template import Template, Context
from django.contrib.auth import get_user_model
from geonode.storage.manager import storage_manager
Expand Down Expand Up @@ -1124,3 +1125,41 @@ def test_keyword_raise_db_error(self, add_root_mocked):
"Error during the keyword creation for keyword: keyword2",
[x.message for x in _log.records],
)


class TestRegions(GeoNodeBaseTestSupport):
def setUp(self):
self.dataset_inside_region = GEOSGeometry(
"POLYGON ((-4.01799226543944599 57.18451093931114571, 8.89409253052255622 56.91828238681708285, \
9.29343535926363984 47.73339732577194638, -3.75176371294537603 48.13274015451304422, \
-4.01799226543944599 57.18451093931114571))",
srid=4326,
)

self.dataset_overlapping_region = GEOSGeometry(
"POLYGON ((15.28357779038003628 33.6232840435866791, 28.19566258634203848 33.35705549109261625, \
28.5950054150831221 24.17217043004747978, 15.54980634287410624 24.57151325878857762, \
15.28357779038003628 33.6232840435866791))",
srid=4326,
)

self.dataset_outside_region = GEOSGeometry(
"POLYGON ((-3.75176371294537603 23.10725622007123548, 9.16032108301662618 22.84102766757717262, \
9.5596639117577098 13.65614260653203615, -3.48553516045130607 14.05548543527313399, \
-3.75176371294537603 23.10725622007123548))",
srid=4326,
)

def test_region_assignment_for_extent(self):
region = Region.objects.get(code="EUR")

self.assertTrue(
region.is_assignable_to_geom(self.dataset_inside_region), "Extent inside a region shouldn't be assigned"
)
self.assertTrue(
region.is_assignable_to_geom(self.dataset_overlapping_region),
"Extent overlapping a region should be assigned",
)
self.assertFalse(
region.is_assignable_to_geom(self.dataset_outside_region), "Extent outside a region should be assigned"
)
10 changes: 2 additions & 8 deletions geonode/resource/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,13 +483,7 @@ def metadata_post_save(instance, *args, **kwargs):
regions_to_add = []
for region in queryset:
try:
srid2, wkt2 = region.geographic_bounding_box.split(";")
srid2 = re.findall(r"\d+", srid2)

poly2 = GEOSGeometry(wkt2, srid=int(srid2[0]))
poly2.transform(4326)

if not poly2.intersection(poly1).empty:
if region.is_assignable_to_geom(poly1):
regions_to_add.append(region)
if region.level == 0 and region.parent is None:
global_regions.append(region)
Expand All @@ -498,7 +492,7 @@ def metadata_post_save(instance, *args, **kwargs):
if tb:
logger.debug(tb)
if regions_to_add or global_regions:
if regions_to_add and len(regions_to_add) > 0 and len(regions_to_add) <= 30:
if regions_to_add:
instance.regions.add(*regions_to_add)
else:
instance.regions.add(*global_regions)
Expand Down

0 comments on commit dbc282a

Please sign in to comment.