#
# 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()])
[docs]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=True)
@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")
[docs]class IGeoPointZ(IGeoPoint):
"""GeoPointZ attribute interface"""
altitude = DottedDecimalField(title=_("Altitude"),
required=False)
[docs]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=True)
@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")