Ejemplo n.º 1
0
def get_bounding_boxes(haz_metadata, exp_metadata, req_bbox):
    """Check and get appropriate bounding boxes for input layers

    Input
        haz_metadata: Metadata for hazard layer
        exp_metadata: Metadata for exposure layer
        req_bbox: Bounding box (string) as requested by HTML POST.

    Output
        haz_bbox: Bounding box to be used for hazard layer.
        exp_bbox: Bounding box to be used for exposure layer
        imp_bbox: Bounding box to be used for resulting impact layer

    Note exp_bbox and imp_bbox are the same and calculated as the
         intersection among hazard, exposure and viewport bounds.
         haz_bbox may be grown by one pixel size in case exposure data
         is vector data to make sure points always can be interpolated
    """

    # Input checks
    msg = ('Invalid bounding box %s (%s). '
           'It must be a string' % (str(req_bbox), type(req_bbox)))
    assert isinstance(req_bbox, basestring), msg
    check_bbox_string(req_bbox)

    # Get bounding boxes for layers and viewport
    haz_bbox = haz_metadata['bounding_box']
    exp_bbox = exp_metadata['bounding_box']
    vpt_bbox = bboxstring2list(req_bbox)

    # New bounding box for data common to hazard, exposure and viewport
    # Download only data within this intersection
    intersection_bbox = bbox_intersection(vpt_bbox, haz_bbox, exp_bbox)
    if intersection_bbox is None:
        # Bounding boxes did not overlap
        msg = ('Bounding boxes of hazard data [%s], exposure data [%s] '
               'and viewport [%s] 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.' %
               (bboxlist2string(haz_bbox, decimals=3),
                bboxlist2string(exp_bbox, decimals=3),
                bboxlist2string(vpt_bbox, decimals=3)))
        logger.info(msg)
        raise Exception(msg)

    # Grow hazard bbox to buffer this common bbox in case where
    # hazard is raster and exposure is vector
    if (haz_metadata['layer_type'] == 'raster'
            and exp_metadata['layer_type'] == 'vector'):

        haz_res = haz_metadata['resolution']
        haz_bbox = buffered_bounding_box(intersection_bbox, haz_res)
    else:
        haz_bbox = intersection_bbox

    # Usually the intersection bbox is used for both exposure layer and result
    exp_bbox = imp_bbox = intersection_bbox

    return haz_bbox, exp_bbox, imp_bbox
Ejemplo n.º 2
0
Archivo: core.py Proyecto: AIFDR/riab
def get_bounding_boxes(haz_metadata, exp_metadata, req_bbox):
    """Check and get appropriate bounding boxes for input layers

    Input
        haz_metadata: Metadata for hazard layer
        exp_metadata: Metadata for exposure layer
        req_bbox: Bounding box (string) as requested by HTML POST.

    Output
        haz_bbox: Bounding box to be used for hazard layer.
        exp_bbox: Bounding box to be used for exposure layer
        imp_bbox: Bounding box to be used for resulting impact layer

    Note exp_bbox and imp_bbox are the same and calculated as the
         intersection among hazard, exposure and viewport bounds.
         haz_bbox may be grown by one pixel size in case exposure data
         is vector data to make sure points always can be interpolated
    """

    # Input checks
    msg = ('Invalid bounding box %s (%s). '
           'It must be a string' % (str(req_bbox), type(req_bbox)))
    assert isinstance(req_bbox, basestring), msg
    check_bbox_string(req_bbox)

    # Get bounding boxes for layers and viewport
    haz_bbox = haz_metadata['bounding_box']
    exp_bbox = exp_metadata['bounding_box']
    vpt_bbox = bboxstring2list(req_bbox)

    # New bounding box for data common to hazard, exposure and viewport
    # Download only data within this intersection
    intersection_bbox = bbox_intersection(vpt_bbox, haz_bbox, exp_bbox)
    if intersection_bbox is None:
        # Bounding boxes did not overlap
        msg = ('Bounding boxes of hazard data [%s], exposure data [%s] '
               'and viewport [%s] 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.'
               % (bboxlist2string(haz_bbox, decimals=3),
                  bboxlist2string(exp_bbox, decimals=3),
                  bboxlist2string(vpt_bbox, decimals=3)))
        logger.info(msg)
        raise Exception(msg)

    # Grow hazard bbox to buffer this common bbox in case where
    # hazard is raster and exposure is vector
    if (haz_metadata['layer_type'] == 'raster' and
        exp_metadata['layer_type'] == 'vector'):

        haz_res = haz_metadata['resolution']
        haz_bbox = buffered_bounding_box(intersection_bbox, haz_res)
    else:
        haz_bbox = intersection_bbox

    # Usually the intersection bbox is used for both exposure layer and result
    exp_bbox = imp_bbox = intersection_bbox

    return haz_bbox, exp_bbox, imp_bbox
Ejemplo n.º 3
0
def calculate(request, save_output=save_to_geonode):
    start = datetime.datetime.now()

    if request.method == 'GET':
        # FIXME: Add a basic form here to be able to generate the POST request.
        return HttpResponse('This should be accessed by robots, not humans.'
                            'In other words using HTTP POST instead of GET.')
    elif request.method == 'POST':
        data = request.POST
        impact_function_name = data['impact_function']
        hazard_server = data['hazard_server']
        hazard_layer = data['hazard']
        exposure_server = data['exposure_server']
        exposure_layer = data['exposure']
        bbox = data['bbox']
        keywords = data['keywords']

    if request.user.is_anonymous():
        theuser = get_valid_user()
    else:
        theuser = request.user

    # Create entry in database
    calculation = Calculation(user=theuser,
                              run_date=start,
                              hazard_server=hazard_server,
                              hazard_layer=hazard_layer,
                              exposure_server=exposure_server,
                              exposure_layer=exposure_layer,
                              impact_function=impact_function_name,
                              success=False)

    try:

        # Input checks
        msg = 'This cannot happen :-)'
        assert isinstance(bbox, basestring), msg

        check_bbox_string(bbox)

        # Find the intersection of bounding boxes for viewport,
        # hazard and exposure.
        vpt_bbox = bboxstring2list(bbox)
        haz_bbox = get_metadata(hazard_server,
                                hazard_layer)['bounding_box']
        exp_bbox = get_metadata(exposure_server,
                                exposure_layer)['bounding_box']

        # Impose minimum bounding box size (as per issue #101).
        # FIXME (Ole): This will need to be revisited in conjunction with
        # raster resolutions at some point.
        min_res = 0.00833334
        eps = 1.0e-1
        vpt_bbox = minimal_bounding_box(vpt_bbox, min_res, eps=eps)
        haz_bbox = minimal_bounding_box(haz_bbox, min_res, eps=eps)
        exp_bbox = minimal_bounding_box(exp_bbox, min_res, eps=eps)

        # New bounding box for data common to hazard, exposure and viewport
        # Download only data within this intersection
        intersection = bbox_intersection(vpt_bbox, haz_bbox, exp_bbox)
        if intersection is None:
            # Bounding boxes did not overlap
            msg = ('Bounding boxes of hazard data, exposure data and '
                   'viewport did not overlap, so no computation was '
                   'done. Please try again.')
            logger.info(msg)
            raise Exception(msg)

        bbox = bboxlist2string(intersection)

        plugin_list = get_plugins(impact_function_name)
        _, impact_function = plugin_list[0].items()[0]
        impact_function_source = inspect.getsource(impact_function)

        calculation.impact_function_source = impact_function_source
        calculation.bbox = bbox

        calculation.save()

        msg = 'Performing requested calculation'
        logger.info(msg)

        # Download selected layer objects
        msg = ('- Downloading hazard layer %s from %s' % (hazard_layer,
                                                      hazard_server))
        logger.info(msg)

        H = download(hazard_server, hazard_layer, bbox)

        msg = ('- Downloading exposure layer %s from %s' % (exposure_layer,
                                                        exposure_server))
        logger.info(msg)
        E = download(exposure_server, exposure_layer, bbox)

        # Calculate result using specified impact function
        msg = ('- Calculating impact using %s' % impact_function)
        logger.info(msg)

        impact_filename = calculate_impact(layers=[H, E],
                                           impact_fcn=impact_function)

        # Upload result to internal GeoServer
        msg = ('- Uploading impact layer %s' % impact_filename)
        logger.info(msg)
        result = save_output(impact_filename,
                         title='output_%s' % start.isoformat(),
                         user=theuser)
    except Exception, e:
        #FIXME: Reimplement error saving for calculation
        logger.error(e)
        errors = e.__str__()
        trace = exception_format(e)
        calculation.errors = errors
        calculation.stacktrace = trace
        calculation.save()
        jsondata = json.dumps({'errors': errors, 'stacktrace': trace})
        return HttpResponse(jsondata, mimetype='application/json')
Ejemplo n.º 4
0
    def test_bounding_box_intersection(self):
        """Intersections of bounding boxes work
        """

        west_java = [105, -7, 108, -5]
        jakarta = [106.5, -6.5, 107, -6]

        # Test commutative law
        assert numpy.allclose(bbox_intersection(west_java, jakarta),
                              bbox_intersection(jakarta, west_java))

        # Test inclusion
        assert numpy.allclose(bbox_intersection(west_java, jakarta), jakarta)

        # Realistic ones
        bbox1 = [94.972335, -11.009721, 141.014, 6.073612333333]
        bbox2 = [105.3, -8.5, 110.0, -5.5]
        bbox3 = [105.6, -7.8, 110.5, -5.1]

        ref1 = [max(bbox1[0], bbox2[0]),
                max(bbox1[1], bbox2[1]),
                min(bbox1[2], bbox2[2]),
                min(bbox1[3], bbox2[3])]
        assert numpy.allclose(bbox_intersection(bbox1, bbox2), ref1)
        assert numpy.allclose(bbox_intersection(bbox1, bbox2), bbox2)

        ref2 = [max(bbox3[0], bbox2[0]),
                max(bbox3[1], bbox2[1]),
                min(bbox3[2], bbox2[2]),
                min(bbox3[3], bbox2[3])]
        assert numpy.allclose(bbox_intersection(bbox3, bbox2), ref2)
        assert numpy.allclose(bbox_intersection(bbox2, bbox3), ref2)

        # Multiple boxes
        assert numpy.allclose(bbox_intersection(bbox1, bbox2, bbox3),
                              bbox_intersection(ref1, ref2))

        assert numpy.allclose(bbox_intersection(bbox1, bbox2, bbox3,
                                                west_java, jakarta),
                              jakarta)

        # From actual example
        b1 = [94.972335000000001, -11.009721000000001,
              141.014002, 6.0736119999999998]
        b2 = (95.059660952000002, -10.997409961000001,
              141.00132578099999, 5.9109226959999983)
        b3 = (94.972335000000001, -11.009721000000001,
              141.0140016666665, 6.0736123333332639)

        res = bbox_intersection(b1, b2, b3)

        # Empty intersection should return None
        assert bbox_intersection(bbox2, [50, 2, 53, 4]) is None

        # Deal with invalid boxes
        try:
            bbox_intersection(bbox1, [53, 2, 40, 4])
        except AssertionError:
            pass
        else:
            msg = 'Should have raised exception'
            raise Exception(msg)

        try:
            bbox_intersection(bbox1, [50, 7, 53, 4])
        except AssertionError:
            pass
        else:
            msg = 'Should have raised exception'
            raise Exception(msg)

        try:
            bbox_intersection(bbox1, 'blko ho skrle')
        except AssertionError:
            pass
        else:
            msg = 'Should have raised exception'
            raise Exception(msg)

        try:
            bbox_intersection(bbox1)
        except AssertionError:
            pass
        else:
            msg = 'Should have raised exception'
            raise Exception(msg)

        try:
            bbox_intersection('')
        except AssertionError:
            pass
        else:
            msg = 'Should have raised exception'
            raise Exception(msg)

        try:
            bbox_intersection()
        except AssertionError:
            pass
        else:
            msg = 'Should have raised exception'
            raise Exception(msg)