Пример #1
0
def bboxlist2string(bbox, decimals=6):
    """Convert bounding box list to comma separated string

    Args:
        * bbox: List of coordinates of the form [W, S, E, N]

    Returns:
        * bbox_string: Format 'W,S,E,N' - each will have 6 decimal points
    """

    msg = 'Got string %s, but expected bounding box as a list' % str(bbox)
    verify(not isinstance(bbox, basestring), msg)

    try:
        bbox = list(bbox)
    except:
        msg = 'Could not coerce bbox %s into a list' % str(bbox)
        raise BoundingBoxError(msg)

    msg = ('Bounding box must have 4 coordinates [W, S, E, N]. '
           'I got %s' % str(bbox))
    try:
        verify(len(bbox) == 4, msg)
    except VerificationError:
        raise BoundingBoxError(msg)

    for x in bbox:
        try:
            float(x)
        except ValueError, e:
            msg = ('Bounding box %s contained non-numeric entry %s, '
                   'original error was "%s".' % (bbox, x, e))
            raise BoundingBoxError(msg)
Пример #2
0
def bboxstring2list(bbox_string):
    """Convert bounding box string to list

    Args:
        * bbox_string: String of bounding box coordinates of the form 'W,S,E,N'

    Returns:
        * bbox: List of floating point numbers with format [W, S, E, N]
    """

    msg = ('Bounding box must be a string with coordinates following the '
           'format 105.592,-7.809,110.159,-5.647\n'
           'Instead I got %s of type %s.' % (str(bbox_string),
                                             type(bbox_string)))
    verify(isinstance(bbox_string, basestring), msg)

    fields = bbox_string.split(',')
    msg = ('Bounding box string must have 4 coordinates in the form '
           '"W,S,E,N". I got bbox == "%s"' % bbox_string)
    try:
        verify(len(fields) == 4, msg)
    except VerificationError:
        raise BoundingBoxError(msg)

    for x in fields:
        try:
            float(x)
        except ValueError, e:
            msg = ('Bounding box %s contained non-numeric entry %s, '
                   'original error was "%s".' % (bbox_string, x, e))
            raise BoundingBoxError(msg)
Пример #3
0
def bbox_intersection(*args):
    """Compute intersection between two or more bounding boxes

    Args:
        * args: two or more bounding boxes.
              Each is assumed to be a list or a tuple with
              four coordinates (W, S, E, N)

    Returns:
        * result: The minimal common bounding box

    """

    msg = 'Function bbox_intersection must take at least 2 arguments.'
    verify(len(args) > 1, msg)

    result = [-180, -90, 180, 90]
    for a in args:
        if a is None:
            continue

        msg = ('Bounding box expected to be a list of the '
               'form [W, S, E, N]. '
               'Instead i got "%s"' % str(a))

        try:
            box = list(a)
        except:
            raise Exception(msg)

        if not len(box) == 4:
            raise BoundingBoxError(msg)

        msg = ('Western boundary must be less than or equal to eastern. '
               'I got %s' % box)
        if not box[0] <= box[2]:
            raise BoundingBoxError(msg)

        msg = ('Southern boundary must be less than or equal to northern. '
               'I got %s' % box)
        if not box[1] <= box[3]:
            raise BoundingBoxError(msg)

        # Compute intersection

        # West and South
        for i in [0, 1]:
            result[i] = max(result[i], box[i])

        # East and North
        for i in [2, 3]:
            result[i] = min(result[i], box[i])

    # Check validity and return
    if result[0] <= result[2] and result[1] <= result[3]:
        return result
    else:
        return None
Пример #4
0
def get_optimal_extent(hazard_geo_extent,
                       exposure_geo_extent,
                       viewport_geo_extent=None):
    """A helper function to determine what the optimal extent is.

    Optimal extent should be considered as the intersection between
    the three inputs. The inasafe library will perform various checks
    to ensure that the extent is tenable, includes data from both
    etc.

    This is a thin wrapper around safe.storage.utilities.bbox_intersection

    Typically the result of this function will be used to clip
    input layers to a common extent before processing.

    :param hazard_geo_extent: An array representing the hazard layer
        extents in the form [xmin, ymin, xmax, ymax]. It is assumed that
        the coordinates are in EPSG:4326 although currently no checks are
        made to enforce this.
    :type hazard_geo_extent: list

    :param exposure_geo_extent: An array representing the exposure layer
        extents in the form [xmin, ymin, xmax, ymax]. It is assumed that
        the coordinates are in EPSG:4326 although currently no checks are
        made to enforce this.
    :type exposure_geo_extent: list

    :param viewport_geo_extent: (optional) An array representing the
        viewport extents in the form [xmin, ymin, xmax, ymax]. It is
        assumed that the coordinates are in EPSG:4326 although currently
        no checks are made to enforce this.

        ..note:: We do minimal checking as the inasafe library takes care
        of it for us.

    :returns: An array containing an extent in the form
        [xmin, ymin, xmax, ymax]
        e.g.::
        [100.03, -1.14, 100.81, -0.73]
    :rtype: list

    :raises: Any exceptions raised by the InaSAFE library will be
        propagated.
    """

    message = tr(
        'theHazardGeoExtent or theExposureGeoExtent cannot be None.Found: '
        '/ntheHazardGeoExtent: %s /ntheExposureGeoExtent: %s' %
        (hazard_geo_extent, exposure_geo_extent))

    if (hazard_geo_extent is None) or (exposure_geo_extent is None):
        raise BoundingBoxError(message)

    # .. note:: The bbox_intersection function below assumes that
    # all inputs are in EPSG:4326
    optimal_extent = bbox_intersection(hazard_geo_extent, exposure_geo_extent,
                                       viewport_geo_extent)

    if optimal_extent is None:
        # Bounding boxes did not overlap
        message = tr(
            'Bounding boxes of hazard data, exposure data and viewport '
            'did not overlap, so no computation was done. Please make '
            'sure you pan to where the data is and that hazard and '
            'exposure data overlaps.')
        raise InsufficientOverlapError(message)

    return optimal_extent