diff -r 000000000000 -r c73bb834ccbe src/pyams_gis/interfaces/__init__.py --- /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 +# 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")