src/pyams_gis/interfaces/__init__.py
changeset 0 c73bb834ccbe
child 15 d2f2e0b480e2
equal deleted inserted replaced
-1:000000000000 0:c73bb834ccbe
       
     1 #
       
     2 # Copyright (c) 2008-2017 Thierry Florac <tflorac AT ulthar.net>
       
     3 # All Rights Reserved.
       
     4 #
       
     5 # This software is subject to the provisions of the Zope Public License,
       
     6 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
       
     7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
       
     8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
     9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
       
    10 # FOR A PARTICULAR PURPOSE.
       
    11 #
       
    12 
       
    13 __docformat__ = 'restructuredtext'
       
    14 
       
    15 
       
    16 # import standard library
       
    17 
       
    18 # import interfaces
       
    19 
       
    20 # import packages
       
    21 from pyams_utils.schema import DottedDecimalField
       
    22 from zope.interface import invariant, Interface, Invalid, Attribute
       
    23 from zope.schema import Choice
       
    24 from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
       
    25 
       
    26 from pyams_gis import _
       
    27 
       
    28 
       
    29 WGS84 = 4326
       
    30 WGS84WM = 3857
       
    31 RGF93 = 2154
       
    32 LAMBERT_IIE = 27572
       
    33 UTM_20N = 4559
       
    34 UTM_22N = 2972
       
    35 UTM_38S = 4471
       
    36 UTM_40S = 2975
       
    37 
       
    38 COORDINATES_PROJECTIONS = {WGS84: _("WGS84 (GPS)"),
       
    39                            WGS84WM: _("WGS84 Web Mercator"),
       
    40                            RGF93: _("Lambert 93 (Metropolitan France)"),
       
    41                            LAMBERT_IIE: _("Extended Lambert II (Metropolitan France)"),
       
    42                            UTM_20N: _("UTM Zone 20N (Martinique, Guadeloupe)"),
       
    43                            UTM_22N: _("UTM Zone 22N (Guyane)"),
       
    44                            UTM_38S: _("UTM Zone 38S (Mayotte)"),
       
    45                            UTM_40S: _("UTM Zone 40S (La RĂ©union)")}
       
    46 
       
    47 COORDINATES_PROJECTION_VOCABULARY = SimpleVocabulary(sorted([SimpleTerm(v, title=t)
       
    48                                                              for v, t in COORDINATES_PROJECTIONS.items()],
       
    49                                                             key=lambda x: x.title))
       
    50 
       
    51 LAYER_CRS = {WGS84: 'L.CRS.EPSG4326',
       
    52              WGS84WM: 'L.CRS.EPSG3857',
       
    53              RGF93: 'L.geoportalCRS.EPSG2154',
       
    54              LAMBERT_IIE: 'L.geoportalCRS.EPSG27572'}
       
    55 
       
    56 LAYER_CRS_VOCABULARY = SimpleVocabulary([SimpleTerm(t, title=COORDINATES_PROJECTIONS[v])
       
    57                                          for v, t in LAYER_CRS.items()])
       
    58 
       
    59 
       
    60 class IGeoPoint(Interface):
       
    61     """GeoPoint attribute interface"""
       
    62 
       
    63     longitude = DottedDecimalField(title=_("Longitude"),
       
    64                                    required=False)
       
    65 
       
    66     latitude = DottedDecimalField(title=_("Latitude"),
       
    67                                   required=False)
       
    68 
       
    69     projection = Choice(title=_("Projection system"),
       
    70                         vocabulary=COORDINATES_PROJECTION_VOCABULARY,
       
    71                         default=WGS84,
       
    72                         required=False)
       
    73 
       
    74     @invariant
       
    75     def check_coordinates(self):
       
    76         data = set(map(bool, (self.longitude, self.latitude)))
       
    77         if len(data) == 2:
       
    78             raise Invalid(_("You must set longitude and latitude, or None!"))
       
    79         if self.longitude and not self.projection:
       
    80             raise Invalid(_("You can't set coordinates without setting projection!"))
       
    81 
       
    82     def get_coordinates(self, projection=WGS84):
       
    83         """Get coordinates translated to given projection"""
       
    84 
       
    85     wgs_coordinates = Attribute("Coordinates tuple in WGS84 projection")
       
    86 
       
    87 
       
    88 class IGeoPointZ(IGeoPoint):
       
    89     """GeoPointZ attribute interface"""
       
    90 
       
    91     altitude = DottedDecimalField(title=_("Altitude"),
       
    92                                   required=False)
       
    93 
       
    94 
       
    95 class IGeoArea(Interface):
       
    96     """Geographic area defined by a rectangle"""
       
    97 
       
    98     x1 = DottedDecimalField(title=_("West limit"),
       
    99                             required=False)
       
   100 
       
   101     y1 = DottedDecimalField(title=_("South limit"),
       
   102                             required=False)
       
   103 
       
   104     x2 = DottedDecimalField(title=_("East limit"),
       
   105                             required=False)
       
   106 
       
   107     y2 = DottedDecimalField(title=_("North limit"),
       
   108                             required=False)
       
   109 
       
   110     projection = Choice(title=_("Projection system"),
       
   111                         vocabulary=COORDINATES_PROJECTION_VOCABULARY,
       
   112                         default=WGS84,
       
   113                         required=False)
       
   114 
       
   115     @invariant
       
   116     def check_coordinates(self):
       
   117         data = set(map(bool, (self.x1, self.x2, self.y1, self.y2)))
       
   118         if len(data) == 2:
       
   119             raise Invalid(_("You must set all coordinates or None!"))
       
   120         if self.x1 and not self.projection:
       
   121             raise Invalid(_("You can't set coordinates without setting projection!"))
       
   122 
       
   123     def get_coordinates(self, projection=WGS84):
       
   124         """Get coordinates translated to given projection"""
       
   125 
       
   126     wgs_coordinates = Attribute("Coordinates in WGS84 projection")