src/pyams_gis/interfaces/__init__.py
changeset 0 c73bb834ccbe
child 15 d2f2e0b480e2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_gis/interfaces/__init__.py	Thu May 18 17:23:48 2017 +0200
@@ -0,0 +1,126 @@
+#
+# Copyright (c) 2008-2017 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+
+# import packages
+from pyams_utils.schema import DottedDecimalField
+from zope.interface import invariant, Interface, Invalid, Attribute
+from zope.schema import Choice
+from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
+
+from pyams_gis import _
+
+
+WGS84 = 4326
+WGS84WM = 3857
+RGF93 = 2154
+LAMBERT_IIE = 27572
+UTM_20N = 4559
+UTM_22N = 2972
+UTM_38S = 4471
+UTM_40S = 2975
+
+COORDINATES_PROJECTIONS = {WGS84: _("WGS84 (GPS)"),
+                           WGS84WM: _("WGS84 Web Mercator"),
+                           RGF93: _("Lambert 93 (Metropolitan France)"),
+                           LAMBERT_IIE: _("Extended Lambert II (Metropolitan France)"),
+                           UTM_20N: _("UTM Zone 20N (Martinique, Guadeloupe)"),
+                           UTM_22N: _("UTM Zone 22N (Guyane)"),
+                           UTM_38S: _("UTM Zone 38S (Mayotte)"),
+                           UTM_40S: _("UTM Zone 40S (La RĂ©union)")}
+
+COORDINATES_PROJECTION_VOCABULARY = SimpleVocabulary(sorted([SimpleTerm(v, title=t)
+                                                             for v, t in COORDINATES_PROJECTIONS.items()],
+                                                            key=lambda x: x.title))
+
+LAYER_CRS = {WGS84: 'L.CRS.EPSG4326',
+             WGS84WM: 'L.CRS.EPSG3857',
+             RGF93: 'L.geoportalCRS.EPSG2154',
+             LAMBERT_IIE: 'L.geoportalCRS.EPSG27572'}
+
+LAYER_CRS_VOCABULARY = SimpleVocabulary([SimpleTerm(t, title=COORDINATES_PROJECTIONS[v])
+                                         for v, t in LAYER_CRS.items()])
+
+
+class IGeoPoint(Interface):
+    """GeoPoint attribute interface"""
+
+    longitude = DottedDecimalField(title=_("Longitude"),
+                                   required=False)
+
+    latitude = DottedDecimalField(title=_("Latitude"),
+                                  required=False)
+
+    projection = Choice(title=_("Projection system"),
+                        vocabulary=COORDINATES_PROJECTION_VOCABULARY,
+                        default=WGS84,
+                        required=False)
+
+    @invariant
+    def check_coordinates(self):
+        data = set(map(bool, (self.longitude, self.latitude)))
+        if len(data) == 2:
+            raise Invalid(_("You must set longitude and latitude, or None!"))
+        if self.longitude and not self.projection:
+            raise Invalid(_("You can't set coordinates without setting projection!"))
+
+    def get_coordinates(self, projection=WGS84):
+        """Get coordinates translated to given projection"""
+
+    wgs_coordinates = Attribute("Coordinates tuple in WGS84 projection")
+
+
+class IGeoPointZ(IGeoPoint):
+    """GeoPointZ attribute interface"""
+
+    altitude = DottedDecimalField(title=_("Altitude"),
+                                  required=False)
+
+
+class IGeoArea(Interface):
+    """Geographic area defined by a rectangle"""
+
+    x1 = DottedDecimalField(title=_("West limit"),
+                            required=False)
+
+    y1 = DottedDecimalField(title=_("South limit"),
+                            required=False)
+
+    x2 = DottedDecimalField(title=_("East limit"),
+                            required=False)
+
+    y2 = DottedDecimalField(title=_("North limit"),
+                            required=False)
+
+    projection = Choice(title=_("Projection system"),
+                        vocabulary=COORDINATES_PROJECTION_VOCABULARY,
+                        default=WGS84,
+                        required=False)
+
+    @invariant
+    def check_coordinates(self):
+        data = set(map(bool, (self.x1, self.x2, self.y1, self.y2)))
+        if len(data) == 2:
+            raise Invalid(_("You must set all coordinates or None!"))
+        if self.x1 and not self.projection:
+            raise Invalid(_("You can't set coordinates without setting projection!"))
+
+    def get_coordinates(self, projection=WGS84):
+        """Get coordinates translated to given projection"""
+
+    wgs_coordinates = Attribute("Coordinates in WGS84 projection")