Example #1
0
 def test_datatype2(self):
     poly_set = PolygonSet(dtype=np.float32)
     poly_set.append(p1)
     poly_set.append(p2)
     print poly_set[0]
     print poly_set[0].dtype
     assert poly_set[0].dtype == np.float32
Example #2
0
    def test_append(self):

        # this passes as long as there is no error!

        poly_set = PolygonSet()
        poly_set.append(p1)
        poly_set.append(p2)
Example #3
0
 def test_datatype2(self):
     poly_set = PolygonSet(dtype=np.float32)
     poly_set.append(p1)
     poly_set.append(p2)
     print poly_set[0]
     print poly_set[0].dtype
     assert poly_set[0].dtype == np.float32
Example #4
0
    def test_bbox(self):
        poly_set = PolygonSet()
        poly_set.append(p1)
        poly_set.append(p2)
        bb = np.array(((1., 2.), (35., 40.)), dtype=np.float)

        assert np.array_equal(poly_set.bounding_box, bb)
Example #5
0
    def test_bbox(self):
        poly_set = PolygonSet()
        poly_set.append(p1)
        poly_set.append(p2)
        bb = np.array(((1., 2.), (35., 40.)), dtype=np.float)

        assert np.array_equal(poly_set.bounding_box, bb)
Example #6
0
 def deserialize(self, cstruct):
     appstruct = super(PolygonSetSchema, self).deserialize(cstruct)
     if len(appstruct) == 0:
         appstruct = [(-360, -90), (-360, 90),
                      (360, 90), (360, -90)]
     ps = PolygonSet()
     for poly in appstruct:
         ps.append(poly)
     return ps
Example #7
0
 def _polygon_set_from_points(self, poly):
     '''
     create PolygonSet() object from list of polygons which in turn is a
     list of points
     :returns: PolygonSet() object
     '''
     x = PolygonSet()
     for p in poly:
         x.append(p)
     return x
Example #8
0
 def _polygon_set_from_points(self, poly):
     '''
     create PolygonSet() object from list of polygons which in turn is a
     list of points
     :returns: PolygonSet() object
     '''
     x = PolygonSet()
     for p in poly:
         x.append(p)
     return x
Example #9
0
def test_basemap_square3(dump):
    p1 = Polygon([[0, 45], [1, 45], [1, 46], [0, 46]], metadata=('name'
                 , 'land', '1'))

    poly_set = PolygonSet()
    poly_set.append(p1)

    gmap = map_canvas.MapCanvas((300, 100), land_polygons=poly_set)
    gmap.draw_background()
    gmap.save_background(os.path.join(dump, 'background_square3.png'))
    assert True
def test_basemap_square():
    p1 = Polygon([[0, 45], [1, 45], [1, 46], [0, 46]], metadata=('name'
                 , 'land', '1'))

    poly_set = PolygonSet()
    poly_set.append(p1)

    gmap = map_canvas.MapCanvas((300, 300), land_polygons=poly_set)
    gmap.draw_background()
    gmap.save_background(os.path.join(basedir, 'background_square.png'))
    assert True
Example #11
0
    def spillable_area_update_from_dict(self, poly_set):
        'convert list of tuples back to numpy array'
        # since metadata will not match, let's create a new PolygonSet,
        # check equality on _PointsArray and update if not equal
        ps = PolygonSet()
        for poly in poly_set:
            ps.append(poly)

        if not np.array_equal(self.spillable_area._PointsArray,
                              ps._PointsArray):
            self.spillable_area = ps
            return True

        return False
Example #12
0
    def spillable_area_update_from_dict(self, poly_set):
        'convert list of tuples back to numpy array'
        # since metadata will not match, let's create a new PolygonSet,
        # check equality on _PointsArray and update if not equal
        ps = PolygonSet()
        for poly in poly_set:
            ps.append(poly)

        if not np.array_equal(self.spillable_area._PointsArray,
                              ps._PointsArray):
            self.spillable_area = ps
            return True

        return False
Example #13
0
    def deserialize(self, cstruct):
        appstruct = super(PolygonSetSchema, self).deserialize(cstruct)

        if len(appstruct) == 0:
            appstruct = [(-360, -90),
                         (-360,  90),
                         (360,   90),
                         (360,  -90)]
        ps = PolygonSet()

        for poly in appstruct:
            ps.append(poly)

        return ps
Example #14
0
 def deserialize(self, cstruct):
     if cstruct is None:
         return None
     else:
         appstruct = super(PolygonSetSchema, self).deserialize(cstruct)
         if len(appstruct) == 0:
             # empty --should be None
             return None
         # fixme: is there any need to for a PolygonSet here?
         #        a list of lists would work fine.
         #        a PolygonSet is created in the spillable_area.setter anyway.
         ps = PolygonSet()
         for poly in appstruct:
             ps.append(poly)
         return ps
Example #15
0
    def test_zero_length_false(self):
        """
        A length-zero Polygon set should be Falsey
        """
        poly_set = PolygonSet()

        assert not poly_set
Example #16
0
    def test_append(self):

        # this passes as long as there is no error!

        poly_set = PolygonSet()
        poly_set.append(p1)
        poly_set.append(p2)
        poly_set.append(p3)
Example #17
0
    def __init__(self, map_bounds=None, spillable_area=None, name=None):
        """
        This __init__ will be different for other implementations

        Optional parameters (kwargs)

        :param map_bounds: The polygon bounding the map -- could be larger
                           or smaller than the land raster

        :param spillable_area: The PolygonSet bounding the spillable_area.
        :type spillable_area: Either a PolygonSet object or a list of lists
            from which a polygon set can be created. Each element in the list
            is a list of points defining a polygon.

        Note on 'map_bounds':
            ( (x1,y1), (x2,y2),(x3,y3),..)
            An NX2 array of points that describe a polygon
            if no map bounds is provided -- the whole world is valid
        """
        if map_bounds is not None:
            self.map_bounds = np.asarray(map_bounds,
                                         dtype=np.float64).reshape(-1, 2)
        else:
            # using -360 to 360 to allow stuff to cross the dateline..
            self.map_bounds = np.array(
                ((-360, 90), (360, 90), (360, -90), (-360, -90)),
                dtype=np.float64)

        if spillable_area is None:
            #self.spillable_area = self.map_bounds
            self.spillable_area = PolygonSet()
            self.spillable_area.append(self.map_bounds)
        else:
            if not isinstance(spillable_area, PolygonSet):
                spillable_area = self._polygon_set_from_points(spillable_area)

            self.spillable_area = spillable_area
Example #18
0
    def __init__(self, map_bounds=None, spillable_area=None, name=None):
        """
        This __init__ will be different for other implementations

        Optional parameters (kwargs)

        :param map_bounds: The polygon bounding the map -- could be larger
                           or smaller than the land raster

        :param spillable_area: The PolygonSet bounding the spillable_area.
        :type spillable_area: Either a PolygonSet object or a list of lists
            from which a polygon set can be created. Each element in the list
            is a list of points defining a polygon.

        Note on 'map_bounds':
            ( (x1,y1), (x2,y2),(x3,y3),..)
            An NX2 array of points that describe a polygon
            if no map bounds is provided -- the whole world is valid
        """
        if map_bounds is not None:
            self.map_bounds = np.asarray(map_bounds,
                    dtype=np.float64).reshape(-1, 2)
        else:
            # using -360 to 360 to allow stuff to cross the dateline..
            self.map_bounds = np.array(((-360, 90),
                                        (360, 90),
                                        (360, -90),
                                        (-360, -90)),
                                       dtype=np.float64)

        if spillable_area is None:
            #self.spillable_area = self.map_bounds
            self.spillable_area = PolygonSet()
            self.spillable_area.append(self.map_bounds)
        else:
            if not isinstance(spillable_area, PolygonSet):
                spillable_area = self._polygon_set_from_points(spillable_area)

            self.spillable_area = spillable_area
Example #19
0
File: map.py Project: kthyng/GNOME2
    def __init__(self, filename, refloat_halflife, raster_size=1024 * 1024,
                 **kwargs):
        """
        Creates a GnomeMap (specifically a RasterMap) from a bna file.
        It is expected that you will get the spillable area and map bounds
        from the BNA -- if they exist

        Required arguments:

        :param bna_file: full path to a bna file
        :param refloat_halflife: the half-life (in hours) for the re-floating.
        :param raster_size: the total number of pixels (bytes) to make the
                            raster -- the actual size will match the
                            aspect ratio of the bounding box of the land

        Optional arguments (kwargs):

        :param map_bounds: The polygon bounding the map -- could be larger or
                           smaller than the land raster
        :param spillable_area: The polygon bounding the spillable_area
        :param id: unique ID of the object. Using UUID as a string.
                   This is only used when loading object from save file.
        :type id: string
        """
        self.filename = filename
        polygons = haz_files.ReadBNA(filename, 'PolygonSet')
        map_bounds = None
        spillable_area = None

        # find the spillable area and map bounds:
        # and create a new polygonset without them
        #  fixme -- adding a "pop" method to PolygonSet might be better
        #      or a gnome_map_data object...

        just_land = PolygonSet()  # and lakes....

        for p in polygons:
            if p.metadata[1].lower() == 'spillablearea':
                spillable_area = p
            elif p.metadata[1].lower() == 'map bounds':
                map_bounds = p
            else:
                just_land.append(p)

        # now draw the raster map with a map_canvas:
        # determine the size:

        BB = just_land.bounding_box

        # create spillable area and  bounds if they weren't in the BNA
        if map_bounds is None:
            map_bounds = BB.AsPoly()

        if spillable_area is None:
            spillable_area = map_bounds

        # user defined spillable_area, map_bounds overrides data obtained
        # from polygons

        spillable_area = kwargs.pop('spillable_area', spillable_area)
        map_bounds = kwargs.pop('map_bounds', map_bounds)

        # stretch the bounding box, to get approximate aspect ratio in
        # projected coords.

        aspect_ratio = np.cos(BB.Center[1] * np.pi / 180) \
                     * (BB.Width / BB.Height)
        w = int(np.sqrt(raster_size * aspect_ratio))
        h = int(raster_size / w)

        canvas = BW_MapCanvas((w, h), land_polygons=just_land)
        canvas.draw_background()

        # canvas.save_background("raster_map_test.png")

        # # get the bitmap as a numpy array:

        bitmap_array = canvas.as_array()

        # __init__ the  RasterMap

        # hours
        RasterMap.__init__(self, refloat_halflife, bitmap_array,
                           canvas.projection,
                           map_bounds=map_bounds,
                           spillable_area=spillable_area,
                           **kwargs)

        return None
Example #20
0
    assert thinned == poly3


def test_thin32():
    """ some scaling should remove one point """
    thinned = poly3.thin(scale=(5.1, 5.1))

    assert len(thinned) == 3
    # start and end points should still be same
    assert np.array_equal(thinned[0], thinned[-1])


## test on PolygonSet:

pset = PolygonSet()
pset.append(poly1)
pset.append(poly2)
pset.append(poly3)


def test_thin_set():
    thinned = pset.thin(scale=(0.1, 0.1))

    assert len(thinned) == 2
    assert thinned[0] == poly1.thin(scale=(0.1, 0.1))
    assert thinned[1] == poly2.thin(scale=(0.1, 0.1))


def test_larger():
    filename = os.path.join(
Example #21
0
class GnomeMap(Serializable):
    """
    The very simplest map for GNOME -- all water
    with only a bounding box for the map bounds.

    This also serves as a description of the interface
    """
    _update = ['map_bounds', 'spillable_area']
    _create = []
    _create.extend(_update)
    _state = copy.deepcopy(Serializable._state)
    _state.add(save=_create, update=_update)
    _schema = GnomeMapSchema

    refloat_halflife = None  # note -- no land, so never used

    def __init__(self, map_bounds=None, spillable_area=None, name=None):
        """
        This __init__ will be different for other implementations

        Optional parameters (kwargs)

        :param map_bounds: The polygon bounding the map -- could be larger
                           or smaller than the land raster

        :param spillable_area: The PolygonSet bounding the spillable_area.
        :type spillable_area: Either a PolygonSet object or a list of lists
            from which a polygon set can be created. Each element in the list
            is a list of points defining a polygon.

        Note on 'map_bounds':
            ( (x1,y1), (x2,y2),(x3,y3),..)
            An NX2 array of points that describe a polygon
            if no map bounds is provided -- the whole world is valid
        """
        if map_bounds is not None:
            self.map_bounds = np.asarray(map_bounds,
                    dtype=np.float64).reshape(-1, 2)
        else:
            # using -360 to 360 to allow stuff to cross the dateline..
            self.map_bounds = np.array(((-360, 90),
                                        (360, 90),
                                        (360, -90),
                                        (-360, -90)),
                                       dtype=np.float64)

        if spillable_area is None:
            #self.spillable_area = self.map_bounds
            self.spillable_area = PolygonSet()
            self.spillable_area.append(self.map_bounds)
        else:
            if not isinstance(spillable_area, PolygonSet):
                spillable_area = self._polygon_set_from_points(spillable_area)

            self.spillable_area = spillable_area

    def _polygon_set_from_points(self, poly):
        '''
        create PolygonSet() object from list of polygons which in turn is a
        list of points
        :returns: PolygonSet() object
        '''
        x = PolygonSet()
        for p in poly:
            x.append(p)
        return x

    def _attr_array_to_dict(self, np_array):
        '''convert np_array to list of tuples, used for map_bounds,
        spillable_area'''
        return map(tuple, np_array.tolist())

    def _attr_from_list_to_array(self, l_):
        '''
        dict returned as list of tuples to be converted to numpy array
        Again used to update_from_dict map_bounds and spillable_area
        '''
        return np.asarray(l_, dtype=np.float64).reshape(-1, 2)

    def map_bounds_to_dict(self):
        'convert numpy array to a list for serializing'
        return self._attr_array_to_dict(self.map_bounds)

    def map_bounds_update_from_dict(self, val):
        'convert list of tuples back to numpy array'
        new_arr = self._attr_from_list_to_array(val)
        if np.any(self.map_bounds != new_arr):
            self.map_bounds = new_arr
            return True

        return False

    def spillable_area_to_dict(self):
        'convert numpy array to a list for serializing'
        #return self._attr_array_to_dict(self.spillable_area)
        x = []
        for poly in self.spillable_area:
            x.append(poly.points.tolist())
        return x

    def spillable_area_update_from_dict(self, poly_set):
        'convert list of tuples back to numpy array'
        # since metadata will not match, let's create a new PolygonSet,
        # check equality on _PointsArray and update if not equal
        ps = PolygonSet()
        for poly in poly_set:
            ps.append(poly)

        if not np.array_equal(self.spillable_area._PointsArray,
                              ps._PointsArray):
            self.spillable_area = ps
            return True

        return False

    def on_map(self, coords):
        """
        :param coords: location for test.
        :type coords: 3-tuple of floats: (long, lat, depth) or a
                                         NX3 numpy array

        :return: bool array: True if the location is on the map,
                             False otherwise

        Note:
          coord is 3-d, but the concept of "on the map" is 2-d in this context,
          so depth is ignored.
        """
        coords = np.asarray(coords, dtype=world_point_type)
        on_map_mask = points_in_poly(self.map_bounds, coords)
        return on_map_mask

    def on_land(self, coord):
        """
        :param coord: location for test.
        :type coord: 3-tuple of floats: (long, lat, depth)

        :return:
         - Always returns False-- no land in this implementation
        """
        return False

    def in_water(self, coords):
        """
        :param coords: location for test.
        :type coords: 3-tuple of floats: (long, lat, depth)
                      or an Nx3 array

        :returns:
         - True if the point is in the water,
         - False if the point is on land (or off map?)

         This implementation has no land, so always True in on the map.
        """
        return self.on_map(coords)

    def allowable_spill_position(self, coord):
        """
        :param coord: location for test.
        :type coord: 3-tuple of floats: (long, lat, depth)

        :return:
         - True if the point is an allowable spill position
         - False if the point is not an allowable spill position

        .. note:: it could be either off the map, or in a location that
                  spills aren't allowed
        """
        for poly in self.spillable_area:
            if points_in_poly(poly.points, coord):
                return True

        return False

    def _set_off_map_status(self, spill):
        """
        Determines which LEs moved off the map

        Called by beach_elements after checking for land-hits

        :param spill: current SpillContainer
        :type spill:  :class:`gnome.spill_container.SpillContainer`
        """
        next_positions = spill['next_positions']
        status_codes = spill['status_codes']
        off_map = np.logical_not(self.on_map(next_positions))

        # let model decide if we want to remove elements marked as off-map
        status_codes[off_map] = oil_status.off_maps

    def beach_elements(self, spill):
        """
        Determines which LEs were or weren't beached or moved off_map.
        status_code is changed to oil_status.off_maps if off the map.

        Called by the model in the main time loop, after all movers have acted.

        :param spill: current SpillContainer
        :type spill:  :class:`gnome.spill_container.SpillContainer`

        This map class has no land, so only the map check and
        resurface_airborn elements is done: noting else changes.

        subclasses that override this probably want to make sure that:

        self.resurface_airborne_elements(spill)
        self._set_off_map_status(spill)

        are called.
        """
        self.resurface_airborne_elements(spill)
        self._set_off_map_status(spill)

    def refloat_elements(self, spill_container, time_step):
        """
        This method performs the re-float logic -- changing the element
        status flag, and moving the element to the last known water position

        :param spill_container: current SpillContainer
        :type spill_container:  :class:`gnome.spill_container.SpillContainer`

        .. note::
            This map class has no land, and so is a no-op.
        """
        pass

    def resurface_airborne_elements(self, spill_container):
        """
        Takes any elements that are left above the water surface (z < 0.0)
        and puts them on the surface (z == 0.0)

        :param spill_container: current SpillContainer
        :type spill_container:  :class:`gnome.spill_container.SpillContainer`

        .. note::
            While this shouldn't occur according to the physics we're modeling,
            some movers may push elements up too high, or multiple movers may
            add vertical movement that adds up to over the surface. e.g rise
            velocity.
        """
        next_positions = spill_container['next_positions']

        np.maximum(next_positions[:, 2], 0.0, out=next_positions[:, 2])
        return None
Example #22
0
class GnomeMap(Serializable):
    """
    The very simplest map for GNOME -- all water
    with only a bounding box for the map bounds.

    This also serves as a description of the interface
    """
    _update = ['map_bounds', 'spillable_area']
    _create = []
    _create.extend(_update)
    _state = copy.deepcopy(Serializable._state)
    _state.add(save=_create, update=_update)
    _schema = GnomeMapSchema

    refloat_halflife = None  # note -- no land, so never used

    def __init__(self, map_bounds=None, spillable_area=None, name=None):
        """
        This __init__ will be different for other implementations

        Optional parameters (kwargs)

        :param map_bounds: The polygon bounding the map -- could be larger
                           or smaller than the land raster

        :param spillable_area: The PolygonSet bounding the spillable_area.
        :type spillable_area: Either a PolygonSet object or a list of lists
            from which a polygon set can be created. Each element in the list
            is a list of points defining a polygon.

        Note on 'map_bounds':
            ( (x1,y1), (x2,y2),(x3,y3),..)
            An NX2 array of points that describe a polygon
            if no map bounds is provided -- the whole world is valid
        """
        if map_bounds is not None:
            self.map_bounds = np.asarray(map_bounds,
                                         dtype=np.float64).reshape(-1, 2)
        else:
            # using -360 to 360 to allow stuff to cross the dateline..
            self.map_bounds = np.array(
                ((-360, 90), (360, 90), (360, -90), (-360, -90)),
                dtype=np.float64)

        if spillable_area is None:
            #self.spillable_area = self.map_bounds
            self.spillable_area = PolygonSet()
            self.spillable_area.append(self.map_bounds)
        else:
            if not isinstance(spillable_area, PolygonSet):
                spillable_area = self._polygon_set_from_points(spillable_area)

            self.spillable_area = spillable_area

    def _polygon_set_from_points(self, poly):
        '''
        create PolygonSet() object from list of polygons which in turn is a
        list of points
        :returns: PolygonSet() object
        '''
        x = PolygonSet()
        for p in poly:
            x.append(p)
        return x

    def _attr_array_to_dict(self, np_array):
        '''convert np_array to list of tuples, used for map_bounds,
        spillable_area'''
        return map(tuple, np_array.tolist())

    def _attr_from_list_to_array(self, l_):
        '''
        dict returned as list of tuples to be converted to numpy array
        Again used to update_from_dict map_bounds and spillable_area
        '''
        return np.asarray(l_, dtype=np.float64).reshape(-1, 2)

    def map_bounds_to_dict(self):
        'convert numpy array to a list for serializing'
        return self._attr_array_to_dict(self.map_bounds)

    def map_bounds_update_from_dict(self, val):
        'convert list of tuples back to numpy array'
        new_arr = self._attr_from_list_to_array(val)
        if np.any(self.map_bounds != new_arr):
            self.map_bounds = new_arr
            return True

        return False

    def spillable_area_to_dict(self):
        'convert numpy array to a list for serializing'
        #return self._attr_array_to_dict(self.spillable_area)
        x = []
        for poly in self.spillable_area:
            x.append(poly.points.tolist())
        return x

    def spillable_area_update_from_dict(self, poly_set):
        'convert list of tuples back to numpy array'
        # since metadata will not match, let's create a new PolygonSet,
        # check equality on _PointsArray and update if not equal
        ps = PolygonSet()
        for poly in poly_set:
            ps.append(poly)

        if not np.array_equal(self.spillable_area._PointsArray,
                              ps._PointsArray):
            self.spillable_area = ps
            return True

        return False

    def on_map(self, coords):
        """
        :param coords: location for test.
        :type coords: 3-tuple of floats: (long, lat, depth) or a
                                         NX3 numpy array

        :return: bool array: True if the location is on the map,
                             False otherwise

        Note:
          coord is 3-d, but the concept of "on the map" is 2-d in this context,
          so depth is ignored.
        """
        coords = np.asarray(coords, dtype=world_point_type)
        on_map_mask = points_in_poly(self.map_bounds, coords)
        return on_map_mask

    def on_land(self, coord):
        """
        :param coord: location for test.
        :type coord: 3-tuple of floats: (long, lat, depth)

        :return:
         - Always returns False-- no land in this implementation
        """
        return False

    def in_water(self, coords):
        """
        :param coords: location for test.
        :type coords: 3-tuple of floats: (long, lat, depth)
                      or an Nx3 array

        :returns:
         - True if the point is in the water,
         - False if the point is on land (or off map?)

         This implementation has no land, so always True in on the map.
        """
        return self.on_map(coords)

    def allowable_spill_position(self, coord):
        """
        :param coord: location for test.
        :type coord: 3-tuple of floats: (long, lat, depth)

        :return:
         - True if the point is an allowable spill position
         - False if the point is not an allowable spill position

        .. note:: it could be either off the map, or in a location that
                  spills aren't allowed
        """
        for poly in self.spillable_area:
            if points_in_poly(poly.points, coord):
                return True

        return False

    def _set_off_map_status(self, spill):
        """
        Determines which LEs moved off the map

        Called by beach_elements after checking for land-hits

        :param spill: current SpillContainer
        :type spill:  :class:`gnome.spill_container.SpillContainer`
        """
        next_positions = spill['next_positions']
        status_codes = spill['status_codes']
        off_map = np.logical_not(self.on_map(next_positions))

        # let model decide if we want to remove elements marked as off-map
        status_codes[off_map] = oil_status.off_maps

    def beach_elements(self, spill):
        """
        Determines which LEs were or weren't beached or moved off_map.
        status_code is changed to oil_status.off_maps if off the map.

        Called by the model in the main time loop, after all movers have acted.

        :param spill: current SpillContainer
        :type spill:  :class:`gnome.spill_container.SpillContainer`

        This map class has no land, so only the map check and
        resurface_airborn elements is done: noting else changes.

        subclasses that override this probably want to make sure that:

        self.resurface_airborne_elements(spill)
        self._set_off_map_status(spill)

        are called.
        """
        self.resurface_airborne_elements(spill)
        self._set_off_map_status(spill)

    def refloat_elements(self, spill_container, time_step):
        """
        This method performs the re-float logic -- changing the element
        status flag, and moving the element to the last known water position

        :param spill_container: current SpillContainer
        :type spill_container:  :class:`gnome.spill_container.SpillContainer`

        .. note::
            This map class has no land, and so is a no-op.
        """
        pass

    def resurface_airborne_elements(self, spill_container):
        """
        Takes any elements that are left above the water surface (z < 0.0)
        and puts them on the surface (z == 0.0)

        :param spill_container: current SpillContainer
        :type spill_container:  :class:`gnome.spill_container.SpillContainer`

        .. note::
            While this shouldn't occur according to the physics we're modeling,
            some movers may push elements up too high, or multiple movers may
            add vertical movement that adds up to over the surface. e.g rise
            velocity.
        """
        next_positions = spill_container['next_positions']

        np.maximum(next_positions[:, 2], 0.0, out=next_positions[:, 2])
        return None
Example #23
0
    def __init__(self, filename, raster_size=1024 * 1024, **kwargs):
        """
        Creates a GnomeMap (specifically a RasterMap) from a bna file.
        It is expected that you will get the spillable area and map bounds
        from the BNA -- if they exist

        Required arguments:

        :param bna_file: full path to a bna file
        :param refloat_halflife: the half-life (in hours) for the re-floating.
        :param raster_size: the total number of pixels (bytes) to make the
                            raster -- the actual size will match the
                            aspect ratio of the bounding box of the land

        Optional arguments (kwargs):

        :param map_bounds: The polygon bounding the map -- could be larger or
                           smaller than the land raster
        :param spillable_area: The polygon bounding the spillable_area
        :param id: unique ID of the object. Using UUID as a string.
                   This is only used when loading object from save file.
        :type id: string
        """
        self.filename = filename
        polygons = haz_files.ReadBNA(filename, 'PolygonSet')
        map_bounds = None
        self.name = kwargs.pop('name', os.path.split(filename)[1])

        # find the spillable area and map bounds:
        # and create a new polygonset without them
        #  fixme -- adding a "pop" method to PolygonSet might be better
        #      or a gnome_map_data object...

        just_land = PolygonSet()  # and lakes....
        spillable_area = PolygonSet()

        for p in polygons:
            if p.metadata[1].lower() == 'spillablearea':
                spillable_area.append(p)

            elif p.metadata[1].lower() == 'map bounds':
                map_bounds = p
            else:
                just_land.append(p)

        # now draw the raster map with a map_canvas:
        # determine the size:

        BB = just_land.bounding_box

        # create spillable area and  bounds if they weren't in the BNA
        if map_bounds is None:
            map_bounds = BB.AsPoly()

        if len(spillable_area) == 0:
            spillable_area.append(map_bounds)

        # user defined spillable_area, map_bounds overrides data obtained
        # from polygons

        # todo: should there be a check between spillable_area read from BNA
        # versus what the user entered. if this is within spillable_area for
        # BNA, then include it? else ignore
        #spillable_area = kwargs.pop('spillable_area', spillable_area)
        spillable_area = kwargs.pop('spillable_area', spillable_area)
        map_bounds = kwargs.pop('map_bounds', map_bounds)

        # stretch the bounding box, to get approximate aspect ratio in
        # projected coords.

        aspect_ratio = (np.cos(BB.Center[1] * np.pi / 180) *
                        (BB.Width / BB.Height))
        w = int(np.sqrt(raster_size * aspect_ratio))
        h = int(raster_size / w)

        canvas = BW_MapCanvas((w, h), land_polygons=just_land)
        canvas.draw_background()

        # canvas.save_background("raster_map_test.png")

        # # get the bitmap as a numpy array:

        bitmap_array = canvas.as_array()

        # __init__ the  RasterMap

        # hours
        RasterMap.__init__(self,
                           bitmap_array,
                           canvas.projection,
                           map_bounds=map_bounds,
                           spillable_area=spillable_area,
                           **kwargs)

        return None
Example #24
0
 def test_datatype(self):
     poly_set = PolygonSet(dtype=np.float32)
     poly_set.append(p1)
     poly_set.append(p2)
     assert poly_set.dtype == np.float32
Example #25
0
    def test_zero_length(self):
        poly_set = PolygonSet()

        assert len(poly_set) == 0
Example #26
0
 def test_datatype(self):
     poly_set = PolygonSet(dtype=np.float32)
     poly_set.append(p1)
     poly_set.append(p2)
     assert poly_set.dtype == np.float32
    """ just enough scaling shouldn't change it """
    thinned = poly3.thin(scale=(10, 10) )

    assert thinned == poly3

def test_thin32():
    """ some scaling should remove one point """
    thinned = poly3.thin(scale=(5.1, 5.1) )

    assert len(thinned) == 3
    # start and end points should still be same
    assert np.array_equal( thinned[0], thinned[-1] )

## test on PolygonSet:

pset = PolygonSet()
pset.append(poly1)
pset.append(poly2)
pset.append(poly3)

def test_thin_set():
    thinned = pset.thin( scale=(0.1, 0.1) )

    assert len(thinned) == 2
    assert thinned[0] == poly1.thin( scale=(0.1, 0.1) )
    assert thinned[1] == poly2.thin( scale=(0.1, 0.1) )

def test_larger():
    filename = os.path.join( os.path.split(__file__)[0],'00439polys_013685pts.bna' )

    polys439 = ReadBNA(filename, polytype = "PolygonSet")