Source code for pyprom.lib.containers.multipoint

"""
pyProm: Copyright 2016.

This software is distributed under a license that is described in
the LICENSE file that accompanies it.

This library contains a container class for storing Multipoint
type location objects as well as a number of functions.
"""

from ..locations.base_coordinate import BaseCoordinate
from ..locations.base_gridpoint import isBaseGridPoint, BaseGridPoint
from ..locations.gridpoint import GridPoint
from .perimeter import Perimeter


[docs]class MultiPoint: """ | A MultiPoint Container. This is a special kind of feature which contains | multiple :class:`pyprom.lib.locations.base_gridpoint.BaseGridPoint`s. | These points are all of equal elevation and neighbor each other | Orthogonally or Diagonally. | | [4][3][4][6][4] | [3][5][5][5][6] | [2][3][5][6][3] | [3][5][4][3] | [6][7][6] | | In the above example, all [5] points represent a valid MultiPoint. | All non [5] points are Perimeter Points, that is, they neighbor | MultiPoint members Diagonally or Orthogonally. | | ``[5][5][5]`` | ``[5] <- Without Perimeter`` | ``[5]`` | | | ``[4][3][4][6][4]`` | ``[3] [6] <- Just the Perimeter.`` | ``[2][3] [6][3]`` | ``[3] [4][3]`` | ``[6][7][6]`` """
[docs] def __init__(self, points, elevation, datamap, perimeter=None): """ :param points: list of :class:`pyprom.lib.locations.base_gridpoint.BaseGridPoint` objects. These are the inside points that make up a Multipoint. :type points: list(:class:`pyprom.lib.locations.base_gridpoint.BaseGridPoint`) :param elevation: elevation in meters :type elevation: int, float :param datamap: datamap which this MultiPoint uses. :type datamap: :class:`pyprom.lib.datamap.DataMap` :param perimeter: Perimeter of MultiPoint. These are the points that make up the orthogonally/diagonally connected border of the multipoint outside of the multipoint. :type perimeter: :class:`pyprom.lib.containers.perimeter.Perimeter` """ super(MultiPoint, self).__init__() self.points = points # BaseGridPoint Objects. self.elevation = elevation self.datamap = datamap # data analysis object. self.perimeter = perimeter
[docs] def to_dict(self): """ Create the dictionary representation of this object. :return: dict() representation of :class:`MultiPoint` :rtype: dict() """ multiPointDict = dict() multiPointDict['points'] = [x.to_dict() for x in self.points] multiPointDict['perimeter'] = self.perimeter.to_dict() multiPointDict['elevation'] = self.elevation return multiPointDict
[docs] @classmethod def from_dict(cls, multiPointDict, datamap=None): """ Create this object from dictionary representation :param multiPointDict: dict() representation of this :class:`MultiPoint`. :param datamap: datamap which this MultiPoint uses. :type datamap: :class:`pyprom.lib.datamap.DataMap` :return: a new Multipoint. :rtype: :class:`MultiPoint` """ points = [BaseGridPoint(x['x'], x['y']) for x in multiPointDict['points']] perimeter = Perimeter.from_dict(multiPointDict['perimeter'], datamap) elevation = multiPointDict['elevation'] return cls(points, elevation, datamap, perimeter=perimeter)
@property def pointsLatLong(self): """ Returns list() of Container :class:`pyprom.lib.locations.base_gridpoint.BaseGridPoint` as :class:`pyprom.lib.locations.base_coordinate.BaseCoordinate` :return: List of All blob points with lat/long instead of x/y :rtype: list(:class:`pyprom.lib.locations.base_coordinate.BaseCoordinate`) """ return [BaseCoordinate(*self.datamap.xy_to_latlong(coord.x, coord.y)) for coord in self.points]
[docs] def append(self, point): """ Add a BaseGridPoint to this container. :param point: BaseGridPoint to add. :type point: :class:`pyprom.lib.locations.base_gridpoint.BaseGridPoint` :raises: TypeError if point not of :class:`pyprom.lib.locations.base_gridpoint.BaseGridPoint` """ isBaseGridPoint(point) self.points.append(point)
[docs] def closestPoint(self, gridPoint, asSpotElevation=False): """ Returns the closest point in this container to the GridPoint passed in. :param gridPoint: GridPoint to check. :type gridPoint: :class:`pyprom.lib.locations.gridpoint.GridPoint` :param bool asSpotElevation: If True, returns SpotElevation object. :return: GridPoint if asSpotElevation == False SpotElevation if asSpotElevation == True :rtype :class:`pyprom.lib.locations.gridpoint.GridPoint`, :class:`pyprom.lib.locations.spot_elevation.SpotElevation` """ closestDistance = gridPoint.distance(self.points[0]) closest = self.points[0] for point in self.points[1:]: distance = gridPoint.distance(point) # well, can't get closer than that. mark it and bail. if distance == 0: closest = point break if distance < closestDistance: closest = point closestDistance = distance gp = GridPoint(closest.x, closest.y, self.elevation) if asSpotElevation: return gp.toSpotElevation(self.datamap) return gp
[docs] def __len__(self): """ :return: number of items in `self.points` :rtype: int """ return len(self.points)
[docs] def __setitem__(self, idx, point): """ Gives MultiPoint list like set capabilities :param int idx: index value :param point: BaseGridPoint for setitem. :type point: :class:`pyprom.lib.locations.base_gridpoint.BaseGridPoint` :raises: TypeError if point not of :class:`BaseGridPoint` """ isBaseGridPoint(point) self.points[idx] = point
[docs] def __getitem__(self, idx): """ Gives MultiPoint list like get capabilities :param int idx: index value :return: :class:`pyprom.lib.locations.base_gridpoint.BaseGridPoint` self.point at idx """ return self.points[idx]
[docs] def __eq__(self, other): """ Determines if this object is equal to another. :param other: other :class:`MultiPoint` to check. :type: :class:`MultiPoint` :return: equality :rtype: bool :raises: TypeError if other not of :class:`MultiPoint` """ _isMultiPoint(other) return sorted([x for x in self.points]) == \ sorted([x for x in other.points])
[docs] def __ne__(self, other): """ Determines if this object is not equal to another. :param other: other :class:`MultiPoint` to check. :type: :class:`MultiPoint` :return: inequality :rtype: bool :raises: TypeError if other not of :class:`MultiPoint` """ _isMultiPoint(other) return sorted([x for x in self.points]) != \ sorted([x for x in other.points])
[docs] def __iter__(self): """ :return: `self.points` as iterator """ for point in self.points: yield point
[docs] def __repr__(self): """ :return: String representation of this object """ return "<Multipoint> elevation(m): {}, points {}". \ format(self.elevation, len(self.points))
__unicode__ = __str__ = __repr__
def _isMultiPoint(mp): """ Check if passed in object is a :class:`MultiPoint` :param mp: object under scrutiny :raises: TypeError if other not of :class:`MultiPoint` """ if not isinstance(mp, MultiPoint): raise TypeError("MultiPoint expected")