Example #1
0
def check_data_integrity(layer_objects):
    """Check list of layer objects

    Input
        layer_objects: List of InaSAFE layer instances

    Output
        Nothing

    Raises
        Exceptions for a range of errors

    This function checks that
    * Layers have correct keywords
    * That they have the same georeferences
    """

    # Link to documentation
    manpage = ('http://risiko_dev.readthedocs.org/en/latest/usage/'
               'plugins/development.html')
    instructions = ('Please add keywords as <keyword>:<value> pairs '
                    ' in the .keywords file. For more information '
                    'please read the sections on impact functions '
                    'and keywords in the manual: %s' % manpage)

    # Set default values for projection and geotransform.
    # Enforce DEFAULT (WGS84).
    # Choosing 'None' will use value of first layer.
    reference_projection = Projection(DEFAULT_PROJECTION)
    geotransform = None

    for layer in layer_objects:

        # Check that critical keywords exist and are non empty
        keywords = layer.get_keywords()
        for kw in REQUIRED_KEYWORDS:
            msg = ('Layer %s did not have required keyword "%s". '
                   '%s' % (layer.name, kw, instructions))
            verify(kw in keywords, msg)

            val = keywords[kw]
            msg = ('No value found for keyword "%s" in layer %s. '
                   '%s' % (kw, layer.name, instructions))
            verify(val, msg)

        # Ensure that projection is consistent across all layers
        if reference_projection is None:
            reference_projection = layer.projection
        else:
            msg = ('Projections in input layer %s is not as expected:\n'
                   'projection: %s\n'
                   'default:    %s'
                   '' % (layer, layer.projection, reference_projection))
            verify(reference_projection == layer.projection, msg)

        # FIXME (Ariel): Make this configurable by the frontend choice?
        # Relax tolerance requirements to have GeoNode compatibility
        # tolerance = 10e-12
        tolerance = 10e-7

        # Ensure that geotransform and dimensions is consistent across
        # all *raster* layers
        if layer.is_raster:
            if geotransform is None:
                geotransform = layer.get_geotransform()
            else:
                msg = ('Geotransforms in input raster layers are different:\n'
                       '%s\n%s' % (geotransform, layer.get_geotransform()))
                verify(numpy.allclose(geotransform,
                                      layer.get_geotransform(),
                                      rtol=tolerance), msg)

        # In case of vector layers, we just check that they are non-empty
        # FIXME (Ole): Not good as nasty error is raised in cases where
        # there are no buildings in the hazard area. Need to be more graceful
        # See e.g. shakemap dated 20120227190230
        if layer.is_vector:
            msg = ('There are no vector data features. '
                   'Perhaps zoom out or pan to the study area '
                   'and try again')
            verify(len(layer) > 0, msg)

    # Check that arrays are aligned.

    refname = None
    for layer in layer_objects:
        if layer.is_raster:

            if refname is None:
                refname = layer.get_name()
                M = layer.rows
                N = layer.columns

            msg = ('Rasters are not aligned!\n'
                   'Raster %s has %i rows but raster %s has %i rows\n'
                   'Refer to issue #102' % (layer.get_name(),
                                            layer.rows,
                                            refname, M))
            verify(layer.rows == M, msg)

            msg = ('Rasters are not aligned!\n'
                   'Raster %s has %i columns but raster %s has %i columns\n'
                   'Refer to issue #102' % (layer.get_name(),
                                            layer.columns,
                                            refname, N))
            verify(layer.columns == N, msg)
Example #2
0
def check_data_integrity(layer_objects):
    """Check list of layer objects

    :param layer_objects: List of InaSAFE layer instances
    :type layer_objects: list

    :raises: Exceptions for a range of errors

    This function checks that
    * Layers have correct keywords
    * That they have the same georeferences
    """

    # Link to documentation
    inasafe_url = 'http://inasafe.org/en/developer-docs/'
    instructions = (
        'Please add keywords as <keyword>:<value> pairs  in the .xml '
        'file. For more information please read the sections on impact '
        'functions and keywords in the InaSAFE website: %s' % inasafe_url)

    # Set default values for projection and geo_transform.
    # Enforce DEFAULT (WGS84).
    # Choosing 'None' will use value of first layer.
    reference_projection = Projection(DEFAULT_PROJECTION)
    geo_transform = None

    for safe_layer in layer_objects:
        # Check that critical keywords exist and are non empty
        keywords = safe_layer.keywords
        for keyword in REQUIRED_KEYWORDS:
            message = (
                'Layer %s did not have required keyword "%s". %s' % (
                    safe_layer.name, keyword, instructions))
            verify(keyword in keywords, message)

            value = keywords[keyword]
            message = (
                'No value found for keyword "%s" in layer %s. %s' % (
                    keyword, safe_layer.name, instructions))
            verify(value, message)

        # Ensure that projection is consistent across all layers
        if reference_projection is None:
            reference_projection = safe_layer.projection
        else:
            message = (
                'Projections in input layer %s is not as expected:\n'
                'projection: %s\n default: %s' % (
                    safe_layer,
                    safe_layer.layer.projection,
                    reference_projection))
            verify(
                reference_projection == safe_layer.layer.projection, message)

        # FIXME (Ariel): Make this configurable by the frontend choice?
        # Relax tolerance requirements to have GeoNode compatibility
        # tolerance = 10e-12
        tolerance = 10e-7

        # Ensure that geo_transform and dimensions is consistent across
        # all *raster* layers
        if safe_layer.layer.is_raster:
            if geo_transform is None:
                geo_transform = safe_layer.layer.get_geotransform()
            else:
                message = (
                    'Geotransforms in input raster layers are different:\n'
                    '%s\n%s' % (
                        geo_transform, safe_layer.layer.get_geotransform()))
                verify(
                    numpy.allclose(
                        geo_transform,
                        safe_layer.layer.get_geotransform(),
                        rtol=tolerance),
                    message)

        # In case of vector layers, we just check that they are non-empty
        # FIXME (Ole): Not good as nasty error is raised in cases where
        # there are no buildings in the hazard area. Need to be more graceful
        # See e.g. shakemap dated 20120227190230
        if safe_layer.layer.is_vector:
            message = (
                'There are no vector data features. Perhaps zoom out or pan '
                'to the study area and try again')
            verify(len(safe_layer.layer) > 0, message)

    # Check that arrays are aligned.
    refname = None
    for safe_layer in layer_objects:
        if safe_layer.layer.is_raster:
            if refname is None:
                refname = safe_layer.name
                layer_rows = safe_layer.layer.rows
                layer_columns = safe_layer.layer.columns

            message = (
                'Rasters are not aligned!\n'
                'Raster %s has %i rows but raster %s has %i rows\n'
                'Refer to issue #102' % (
                    safe_layer.name,
                    safe_layer.layer.rows,
                    refname,
                    layer_rows))
            verify(safe_layer.layer.rows == layer_rows, message)

            message = (
                'Rasters are not aligned!\n'
                'Raster %s has %i columns but raster %s has %i columns\n'
                'Refer to issue #102' % (
                    safe_layer.name,
                    safe_layer.layer.columns,
                    refname,
                    layer_columns))
            verify(safe_layer.layer.columns == layer_columns, message)