summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archaeological_finds/tests.py90
-rw-r--r--ishtar_common/models.py5
-rw-r--r--ishtar_common/utils.py96
3 files changed, 147 insertions, 44 deletions
diff --git a/archaeological_finds/tests.py b/archaeological_finds/tests.py
index a56c997eb..00a45ba6a 100644
--- a/archaeological_finds/tests.py
+++ b/archaeological_finds/tests.py
@@ -1596,6 +1596,18 @@ class GeomaticTest(FindInit, TestCase):
self.assertEqual(base_find.point_source_item,
unicode(models.BaseFind._meta.verbose_name))
+ # re-save do not change sources
+ base_find.save()
+ base_find = models.BaseFind.objects.get(pk=base_find.pk)
+ self.assertIsNotNone(base_find.point)
+ self.assertIsNotNone(base_find.point_2d)
+ self.assertIsNotNone(base_find.x)
+ self.assertIsNotNone(base_find.y)
+ self.assertIsNotNone(base_find.z)
+ self.assertEqual(base_find.point_source, 'P') # precise
+ self.assertEqual(base_find.point_source_item,
+ unicode(models.BaseFind._meta.verbose_name))
+
# form input
base_find.x = 2
base_find.y = 3
@@ -1608,6 +1620,14 @@ class GeomaticTest(FindInit, TestCase):
self.assertEqual(base_find.point_source, 'P') # precise
self.assertEqual(base_find.point_source_item,
unicode(models.BaseFind._meta.verbose_name))
+ # re-save do not change sources
+ base_find.save()
+ base_find = models.BaseFind.objects.get(pk=base_find.pk)
+ self.assertIsNotNone(base_find.point_2d)
+ self.assertIsNotNone(base_find.point)
+ self.assertEqual(base_find.point_source, 'P') # precise
+ self.assertEqual(base_find.point_source_item,
+ unicode(models.BaseFind._meta.verbose_name))
# reinit
base_find.x = None
@@ -1637,7 +1657,24 @@ class GeomaticTest(FindInit, TestCase):
cr = ContextRecord.objects.get(pk=base_find.context_record.pk)
base_find = models.BaseFind.objects.get(pk=base_find.pk)
base_find.save()
- self.assertEqual(base_find.point_2d, cr.town.center)
+ base_find = models.BaseFind.objects.get(pk=base_find.pk)
+ bfp = GEOSGeometry(base_find.point_2d.ewkt)
+ bfp.transform(4326)
+ tp = GEOSGeometry(cr.town.center.ewkt)
+ tp.transform(4326)
+ self.assertTrue(bfp.distance(tp) < 0.0001)
+ self.assertEqual(base_find.multi_polygon, cr.town.limit)
+ self.assertEqual(base_find.point_source, 'T') # town
+ self.assertEqual(base_find.point_source_item,
+ unicode(ContextRecord._meta.verbose_name))
+ # re-save do not change sources
+ base_find.save()
+ base_find = models.BaseFind.objects.get(pk=base_find.pk)
+ bfp = GEOSGeometry(base_find.point_2d.ewkt)
+ bfp.transform(4326)
+ tp = GEOSGeometry(cr.town.center.ewkt)
+ tp.transform(4326)
+ self.assertTrue(bfp.distance(tp) < 0.0001)
self.assertEqual(base_find.multi_polygon, cr.town.limit)
self.assertEqual(base_find.point_source, 'T') # town
self.assertEqual(base_find.point_source_item,
@@ -1658,4 +1695,55 @@ class GeomaticTest(FindInit, TestCase):
self.assertEqual(base_find.point_source, 'P') # precise
self.assertEqual(base_find.point_source_item,
unicode(models.BaseFind._meta.verbose_name))
+ # re-save do not change sources
+ base_find.save()
+ base_find = models.BaseFind.objects.get(pk=base_find.pk)
+ self.assertIsNotNone(base_find.point_2d)
+ self.assertIsNotNone(base_find.point)
+ self.assertEqual(base_find.point_2d.wkt, 'POINT (5 6)')
+ self.assertEqual(base_find.point_source, 'P') # precise
+ self.assertEqual(base_find.point_source_item,
+ unicode(models.BaseFind._meta.verbose_name))
+
+ def test_post_save_polygon(self):
+ find = self.finds[0]
+ base_find = find.base_finds.all()[0]
+ srs, __ = SpatialReferenceSystem.objects.get_or_create(
+ txt_idx='wgs84', defaults={"srid": 4326, "label": 'WGS84',
+ 'auth_name': 'EPSG'}
+ )
+
+ base_find = models.BaseFind.objects.get(pk=base_find.pk)
+
+ # get centroid geom from poly
+ limit = 'MULTIPOLYGON(((1 1,5 1,5 5,1 5,1 1),(2 2,2 3,3 3,3 2,2 2)),' \
+ '((6 3,9 2,9 4,6 3)))'
+ base_find.multi_polygon = 'SRID=4326;' + limit
+ base_find.point_source = None
+ base_find.point_2d = None
+ base_find.point = None
+ base_find.save()
+
+ base_find = models.BaseFind.objects.get(pk=base_find.pk)
+ self.assertIsNotNone(base_find.point_2d)
+ self.assertEqual(base_find.point_source, 'M') # from multi polygon
+ # resaving do not change source
+ base_find.save()
+ base_find = models.BaseFind.objects.get(pk=base_find.pk)
+ self.assertIsNotNone(base_find.point_2d)
+ self.assertEqual(base_find.point_source, 'M') # from multi polygon
+ base_find = models.BaseFind.objects.get(pk=base_find.pk)
+ base_find.point_source = None
+ base_find.spatial_reference_system = srs
+ base_find.x = "42"
+ base_find.y = "3"
+ base_find.save()
+ base_find = models.BaseFind.objects.get(pk=base_find.pk)
+ self.assertEqual(base_find.point_2d.ewkt, "SRID=4326;POINT (42 3)")
+ self.assertEqual(base_find.point_source, 'P')
+ # resaving do not change source
+ base_find.save()
+ base_find = models.BaseFind.objects.get(pk=base_find.pk)
+ self.assertEqual(base_find.point_2d.ewkt, "SRID=4326;POINT (42 3)")
+ self.assertEqual(base_find.point_source, 'P')
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index 57283e8f4..f802b434c 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -1671,7 +1671,10 @@ post_delete.connect(post_save_cache, sender=SpatialReferenceSystem)
class GeoItem(models.Model):
- GEO_SOURCE = ('T', _(u"Town")), ('P', _(u"Precise"))
+ GEO_SOURCE = (
+ ('T', _(u"Town")), ('P', _(u"Precise")),
+ ('M', _("Polygon"))
+ )
# gis
x = models.FloatField(_(u'X'), blank=True, null=True)
diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py
index 83627cafc..7a51936b1 100644
--- a/ishtar_common/utils.py
+++ b/ishtar_common/utils.py
@@ -497,8 +497,45 @@ def post_save_geo(sender, **kwargs):
current_source = "default"
if hasattr(instance.__class__, "_meta"):
current_source = unicode(instance.__class__._meta.verbose_name)
- if instance.point_source_item and \
- instance.point_source_item != current_source: # refetch
+
+ profile = get_current_profile()
+ modified = False
+
+ if hasattr(instance, 'multi_polygon'):
+ if instance.multi_polygon_source_item and \
+ instance.multi_polygon_source_item != current_source: # refetch
+ instance.multi_polygon = None
+ instance.multi_polygon_source = None
+
+ if instance.multi_polygon and not instance.multi_polygon_source:
+ # should be a db source
+ instance.multi_polygon_source = 'P'
+ instance.multi_polygon_source_item = current_source
+ modified = True
+ elif instance.multi_polygon_source != 'P':
+ precise_poly = instance.get_precise_polygons()
+ if precise_poly:
+ poly, source_item = precise_poly
+ instance.multi_polygon = poly
+ instance.multi_polygon_source = 'P'
+ instance.multi_polygon_source_item = source_item
+ modified = True
+ elif profile.use_town_for_geo:
+ poly = instance.get_town_polygons()
+ if poly:
+ poly, poly_source = poly
+ if poly != instance.multi_polygon:
+ instance.multi_polygon_source_item = poly_source
+ instance.multi_polygon_source = 'T' # town
+ try:
+ instance.multi_polygon = poly
+ modified = True
+ except TypeError:
+ print(instance, instance.pk)
+
+ if (instance.point_source_item and
+ instance.point_source_item != current_source) or (
+ instance.point_source == 'M' and modified): # refetch
csrs = instance.spatial_reference_system
if instance.x and instance.y:
@@ -512,8 +549,6 @@ def post_save_geo(sender, **kwargs):
point = instance.point
point_2d = instance.point_2d
- profile = get_current_profile()
- modified = False
if (point or point_2d) and instance.x is None and not \
instance.point_source: # db source
@@ -579,13 +614,22 @@ def post_save_geo(sender, **kwargs):
srs = get_srid_obj_from_point(point_2d)
instance.spatial_reference_system = srs
modified = True
-
- elif profile.use_town_for_geo: # try to get from parent
- centroid = instance.get_town_centroid()
- if centroid and centroid[0]:
- instance.point_2d, instance.point_source_item = centroid
+ else:
+ centroid, source, point_source = None, None, None
+ if instance.multi_polygon and instance.multi_polygon_source == 'P':
+ source = current_source
+ centroid = instance.multi_polygon.centroid
+ point_source = 'M'
+ if not centroid and profile.use_town_for_geo: # try to get from
+ # parent
+ town_centroid = instance.get_town_centroid()
+ if town_centroid:
+ centroid, source = town_centroid
+ point_source = 'T'
+ if centroid:
+ instance.point_2d, instance.point_source_item = centroid, source
instance.point = None
- instance.point_source = 'T'
+ instance.point_source = point_source
instance.x = instance.point_2d.x
instance.y = instance.point_2d.y
srs = get_srid_obj_from_point(instance.point_2d)
@@ -597,38 +641,6 @@ def post_save_geo(sender, **kwargs):
instance.point_source = None
modified = True
- if hasattr(instance, 'multi_polygon'):
- if instance.multi_polygon_source_item and \
- instance.multi_polygon_source_item != current_source: # refetch
- instance.multi_polygon = None
- instance.multi_polygon_source = None
-
- if instance.multi_polygon and not instance.multi_polygon_source:
- # should be a db source
- instance.multi_polygon_source = 'P'
- instance.multi_polygon_source_item = current_source
- modified = True
- elif instance.multi_polygon_source != 'P':
- precise_poly = instance.get_precise_polygons()
- if precise_poly:
- poly, source_item = precise_poly
- instance.multi_polygon = poly
- instance.multi_polygon_source = 'P'
- instance.multi_polygon_source_item = source_item
- modified = True
- elif profile.use_town_for_geo:
- poly = instance.get_town_polygons()
- if poly:
- poly, poly_source = poly
- if poly != instance.multi_polygon:
- instance.multi_polygon_source_item = poly_source
- instance.multi_polygon_source = 'T' # town
- try:
- instance.multi_polygon = poly
- modified = True
- except TypeError:
- print(instance, instance.pk)
-
if modified:
instance.skip_history_when_saving = True
instance._post_saved_geo = True