Source code for pyprom.lib.logic.equalheight

"""
pyProm: Copyright 2018.

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

from collections import defaultdict

from ..containers.multipoint import MultiPoint
from ..containers.perimeter import Perimeter



[docs]def equalHeightBlob(datamap, x, y, elevation): """ This function generates a :class:`pyprom.lib.containers.multipoint.MultiPoint` which contains a list of :class:`pyprom.lib.locations.gridpoint.GridPoint` of equal elevation which are diagonally & orthogonally connected. :param int x: x coordinate :param int y: y coordinate :param elevation: elevation to search neighbors for. :type elevation: int, float :return: MultiPoint Object containing all x,y coordinates and elevation :rtype: :class:`pyprom.lib.containers.multipoint.MultiPoint` """ masterGridPoint = (x, y, elevation) exploredEqualHeight = defaultdict(dict) memberPoint = list() _add_member_point(x, y, exploredEqualHeight, memberPoint) perimeterPointHash = defaultdict(dict) perimeterPoints = list() toBeAnalyzed = [masterGridPoint] shoreMapEdge = set() multipointEdges = [] if datamap.is_map_edge(x, y): multipointEdges.append((x, y, elevation)) # Loop until pool of equalHeight neighbors has been exhausted. edge = False while toBeAnalyzed: gridPoint = toBeAnalyzed.pop() neighbors = datamap.iterateFull(gridPoint[0], gridPoint[1]) # Determine if edge or not. if not edge: if datamap.is_map_edge(gridPoint[0], gridPoint[1]): edge = True for _x, _y, elevation in neighbors: if elevation is None or elevation == datamap.nodata: continue elif elevation == masterGridPoint[2] and\ not exploredEqualHeight[_x].get(_y, False): branch = (_x, _y, elevation) _add_member_point(_x, _y, exploredEqualHeight, memberPoint) if datamap.is_map_edge(_x, _y): multipointEdges.append((_x, _y, elevation)) toBeAnalyzed.append(branch) # If elevation > master grid point, stash away as # a perimeter point. Only keep track of edgepoints # higher! elif elevation != masterGridPoint[2]: if not perimeterPointHash[_x].get(_y, False): if elevation > masterGridPoint[2]: _add_perimeter_point(_x, _y, (_x, _y, elevation), perimeterPointHash, perimeterPoints) if datamap.is_map_edge(_x, _y): shoreMapEdge.add((_x, _y, elevation)) return MultiPoint(memberPoint, masterGridPoint[2], datamap, perimeter=Perimeter( pointList=perimeterPoints, pointIndex=perimeterPointHash, datamap=datamap, mapEdge=edge, mapEdgePoints=list(shoreMapEdge))),\ multipointEdges
def _add_member_point(x, y, hash, list): """ Adds point to list and to hash :param x: x coordinate :param y: y coordinate :param hash: hash to add to :param list: list to add to :return: """ hash[x][y] = True list.append((x, y)) def _add_perimeter_point(x, y, val, hash, list): """ Adds point to list and to hash :param x: x coordinate :param y: y coordinate :param hash: hash to add to :param list: list to add to :return: """ hash[x][y] = val list.append(val)