# coding=utf-8
"""Module to manage 3D space restrictions"""
[docs]class Box(object):
"""
Represents a box in the 3D space.
Also allows easy conversion from the coordinate values to significant string
representations
Parameters
----------
depth_in_meters: bool, optional
If True, depth is given in meters. If False, it correspond to levels
"""
def __init__(self, depth_in_meters=False):
self.depth_in_meters = depth_in_meters
"""
If True, treats the depth as if it is given in meters. If False, as it is given in levels
:rtype: bool
"""
self._max_lat = None
self._min_lat = None
self._max_lon = None
self._min_lon = None
self.max_depth = None
"""
Maximum depth
:rtype: float
"""
self.min_depth = None
"""
Minimum depth
:rtype: float
"""
def __eq__(self, other):
return self.depth_in_meters == other.depth_in_meters and self.max_lat == other.max_lat and \
self.min_lat == other.min_lat and self.max_lon == other.max_lon and self.min_lon == other.min_lon and \
self.max_depth == other.max_depth and self.min_depth == other.min_depth
def __str__(self):
return self.get_lat_str() + self.get_lon_str() + self.get_depth_str()
@property
def max_lat(self):
"""
Maximum latitude
:rtype: float
"""
return self._max_lat
@max_lat.setter
def max_lat(self, value):
if value > 90 or value < -90:
raise ValueError('{0} is not a valid latitude. Must be between -90 and -90'.format(value))
self._max_lat = value
@property
def min_lat(self):
"""
Minimum latitude
:rtype: float
"""
return self._min_lat
@min_lat.setter
def min_lat(self, value):
if value > 90 or value < -90:
raise ValueError('{0} is not a valid latitude. Must be between -90 and 90'.format(value))
self._min_lat = value
@property
def max_lon(self):
"""
Maximum longitude
:rtype: float
"""
return self._max_lon
@max_lon.setter
def max_lon(self, value):
if value >= 360 or value <= -360:
raise ValueError('{0} is not a valid longitude. Must be between -360 and 360'.format(value))
self._max_lon = value
@property
def min_lon(self):
"""
Minimum longitude
:rtype: float
"""
return self._min_lon
@min_lon.setter
def min_lon(self, value):
if value >= 360 or value <= -360:
raise ValueError('{0} is not a valid longitude. Must be between -360 and 360'.format(value))
self._min_lon = value
[docs] def get_lat_str(self):
"""
Get a string representation of the latitude in the format XX{N/S}.
If min_lat is different from max_lat, it concatenates the two values
:return: string representation for latitude
:rtype: str
"""
if self.max_lat is None or self.min_lat is None:
return ''
if self.min_lat < 0:
direction = 'S'
else:
direction = 'N'
string = str(abs(self.min_lat)) + direction
if self.max_lat != self.min_lat:
if self.max_lat < 0:
direction = 'S'
else:
direction = 'N'
string += str(abs(self.max_lat)) + direction
return string
[docs] def get_lon_str(self):
"""
Get a string representation of the longitude in the format XX{E/W}.
If min_lon is different from max_lon, it concatenates the two values
:return: string representation for longitude
:rtype: str
"""
if self.max_lon is None or self.min_lon is None:
return ''
if self.min_lon < 0:
direction = 'W'
else:
direction = 'E'
string = str(abs(self.min_lon)) + direction
if self.max_lon != self.min_lon:
if self.max_lon < 0:
direction = 'W'
else:
direction = 'E'
string += str(abs(self.max_lon)) + direction
return string
[docs] def get_depth_str(self):
"""
Get a string representation of depth.
For depth expressed in meters, it adds the character 'm' to the end
If min_depth is different from max_depth, it concatenates the two values
:return: string representation for depth
:rtype: str
"""
if self.max_depth is None or self.min_depth is None:
return ''
if self.depth_in_meters:
suffix = 'm'
else:
suffix = ''
if self.min_depth != self.max_depth:
string = '{0:d}-{1:d}{2}'.format(int(abs(self.min_depth)), int(abs(self.max_depth)), suffix)
else:
string = '{0:d}{1}'.format(int(abs(self.max_depth)), suffix)
return string