Ejemplo n.º 1
0
def load_path_raster_layer(path, **kwargs):
    """Return the test raster layer.

    :param path: Path to the raster layer.
    :type path: str

    :param kwargs: It can be :
        clone=True if you want to copy the layer first to a temporary file.

        with_keywords=False if you do not want keywords. "clone" is
            required.

    :return: The raster layer.
    :rtype: QgsRasterLayer

    .. versionadded:: 4.0
    """
    if not exists(path):
        raise Exception('%s do not exist.' % path)

    name = splitext(basename(path))[0]
    extension = splitext(path)[1]

    extensions = [
        '.tiff', '.tif', '.asc', '.xml', '.qml']

    if kwargs.get('with_keywords'):
        if not kwargs.get('clone'):
            raise Exception('with_keywords needs a clone')

    if not kwargs.get('with_keywords', True):
        index = extensions.index('.xml')
        extensions.pop(index)

    if kwargs.get('clone', False):
        target_directory = mkdtemp()
        current_path = splitext(path)[0]
        path = join(target_directory, name + extension)

        for ext in extensions:
            src_path = current_path + ext
            if exists(src_path):
                target_path = join(target_directory, name + ext)
                shutil.copy2(src_path, target_path)

    name = os.path.basename(path)
    layer = QgsRasterLayer(path, name)

    if not layer.isValid():
        raise Exception('%s is not a valid layer.' % name)

    monkey_patch_keywords(layer)

    return layer
Ejemplo n.º 2
0
def load_path_raster_layer(path, **kwargs):
    """Return the test raster layer.

    :param path: Path to the raster layer.
    :type path: str

    :param kwargs: It can be :
        clone=True if you want to copy the layer first to a temporary file.

        with_keywords=False if you do not want keywords. "clone" is
            required.

    :return: The raster layer.
    :rtype: QgsRasterLayer

    .. versionadded:: 4.0
    """
    if not exists(path):
        raise Exception('%s do not exist.' % path)

    name = splitext(basename(path))[0]
    extension = splitext(path)[1]

    extensions = [
        '.tiff', '.tif', '.asc', '.xml', '.qml']

    if kwargs.get('with_keywords'):
        if not kwargs.get('clone'):
            raise Exception('with_keywords needs a clone')

    if not kwargs.get('with_keywords', True):
        index = extensions.index('.xml')
        extensions.pop(index)

    if kwargs.get('clone', False):
        target_directory = mkdtemp()
        current_path = splitext(path)[0]
        path = join(target_directory, name + extension)

        for ext in extensions:
            src_path = current_path + ext
            if exists(src_path):
                target_path = join(target_directory, name + ext)
                shutil.copy2(src_path, target_path)

    name = os.path.basename(path)
    layer = QgsRasterLayer(path, name)

    if not layer.isValid():
        raise Exception('%s is not a valid layer.' % name)

    monkey_patch_keywords(layer)

    return layer
Ejemplo n.º 3
0
def clone_raster_layer(
        name,
        extension,
        include_keywords,
        source_directory,
        target_directory='test'):
    """Helper function that copies a test raster.

    :param name: The default name for the raster layer.
    :type name: str

    :param extension: The extension of the raster file.
    :type extension: str

    :param include_keywords: Include keywords file if True.
    :type include_keywords: bool

    :param source_directory: Directory where the file is located.
    :type source_directory: str

    :param target_directory: Subdirectory in InaSAFE temp dir that we want to
        put the files into. Default to 'testing'.
    :type target_directory: str
    """
    extensions = ['.prj', '.sld', '.qml', extension]
    if include_keywords:
        extensions.append('.xml')
    temp_path = unique_filename(dir=temp_dir(target_directory))
    # copy to temp file
    for ext in extensions:
        src_path = os.path.join(source_directory, name + ext)
        if os.path.exists(src_path):
            trg_path = temp_path + ext
            shutil.copy2(src_path, trg_path)

    raster_path = '%s%s' % (temp_path, extension)
    if not os.path.exists(raster_path):
        raise Exception('Path not found : %s' % raster_path)

    layer = QgsRasterLayer(raster_path, os.path.basename(raster_path))
    if not layer.isValid:
        raise Exception('Layer is not valid.')

    monkey_patch_keywords(layer)

    return layer
Ejemplo n.º 4
0
def clone_raster_layer(
        name,
        extension,
        include_keywords,
        source_directory,
        target_directory='test'):
    """Helper function that copies a test raster.

    :param name: The default name for the raster layer.
    :type name: str

    :param extension: The extension of the raster file.
    :type extension: str

    :param include_keywords: Include keywords file if True.
    :type include_keywords: bool

    :param source_directory: Directory where the file is located.
    :type source_directory: str

    :param target_directory: Subdirectory in InaSAFE temp dir that we want to
        put the files into. Default to 'testing'.
    :type target_directory: str
    """
    extensions = ['.prj', '.sld', '.qml', extension]
    if include_keywords:
        extensions.append('.xml')
    temp_path = unique_filename(dir=temp_dir(target_directory))
    # copy to temp file
    for ext in extensions:
        src_path = os.path.join(source_directory, name + ext)
        if os.path.exists(src_path):
            trg_path = temp_path + ext
            shutil.copy2(src_path, trg_path)

    raster_path = '%s%s' % (temp_path, extension)
    if not os.path.exists(raster_path):
        raise Exception('Path not found : %s' % raster_path)

    layer = QgsRasterLayer(raster_path, os.path.basename(raster_path))
    if not layer.isValid:
        raise Exception('Layer is not valid.')

    monkey_patch_keywords(layer)

    return layer
Ejemplo n.º 5
0
def load_layer(layer_path):
    """Helper to load and return a single QGIS layer

    :param layer_path: Path name to raster or vector file.
    :type layer_path: str

    :returns: tuple containing layer and its layer_purpose.
    :rtype: (QgsMapLayer, str)

    """
    # Extract basename and absolute path
    file_name = os.path.split(layer_path)[-1]  # In case path was absolute
    base_name, extension = os.path.splitext(file_name)

    # Determine if layer is hazard or exposure
    layer_purpose = 'undefined'
    try:
        keywords = read_iso19115_metadata(layer_path)
        if 'layer_purpose' in keywords:
            layer_purpose = keywords['layer_purpose']
    except NoKeywordsFoundError:
        pass

    # Create QGis Layer Instance
    if extension in ['.asc', '.tif', '.tiff']:
        layer = QgsRasterLayer(layer_path, base_name)
    elif extension in ['.shp', '.geojson', '.gpkg']:
        layer = QgsVectorLayer(layer_path, base_name, 'ogr')
    else:
        message = 'File %s had illegal extension' % layer_path
        raise Exception(message)

    # noinspection PyUnresolvedReferences
    message = 'Layer "%s" is not valid' % layer.source()
    # noinspection PyUnresolvedReferences
    if not layer.isValid():
        LOGGER.debug(message)
        raise Exception(message)

    monkey_patch_keywords(layer)

    return layer, layer_purpose
Ejemplo n.º 6
0
def load_layer(layer_path):
    """Helper to load and return a single QGIS layer

    :param layer_path: Path name to raster or vector file.
    :type layer_path: str

    :returns: tuple containing layer and its layer_purpose.
    :rtype: (QgsMapLayer, str)

    """
    # Extract basename and absolute path
    file_name = os.path.split(layer_path)[-1]  # In case path was absolute
    base_name, extension = os.path.splitext(file_name)

    # Determine if layer is hazard or exposure
    layer_purpose = 'undefined'
    try:
        keywords = read_iso19115_metadata(layer_path)
        if 'layer_purpose' in keywords:
            layer_purpose = keywords['layer_purpose']
    except NoKeywordsFoundError:
        pass

    # Create QGis Layer Instance
    if extension in ['.asc', '.tif', '.tiff']:
        layer = QgsRasterLayer(layer_path, base_name)
    elif extension in ['.shp', '.geojson', '.gpkg']:
        layer = QgsVectorLayer(layer_path, base_name, 'ogr')
    else:
        message = 'File %s had illegal extension' % layer_path
        raise Exception(message)

    # noinspection PyUnresolvedReferences
    message = 'Layer "%s" is not valid' % layer.source()
    # noinspection PyUnresolvedReferences
    if not layer.isValid():
        LOGGER.debug(message)
        raise Exception(message)

    monkey_patch_keywords(layer)

    return layer, layer_purpose
Ejemplo n.º 7
0
    def layer(self, layer_name):
        """Get QGIS layer.

        :param layer_name: The name of the layer to fetch.
        :type layer_name: str

        :return: The QGIS layer.
        :rtype: QgsMapLayer

        .. versionadded:: 4.0
        """
        uri = self.layer_uri(layer_name)
        layer = QgsVectorLayer(uri, layer_name, 'ogr')
        if not layer.isValid():
            layer = QgsRasterLayer(uri, layer_name)
            if not layer.isValid():
                return False

        monkey_patch_keywords(layer)

        return layer
Ejemplo n.º 8
0
    def layer(self, layer_name):
        """Get QGIS layer.

        :param layer_name: The name of the layer to fetch.
        :type layer_name: str

        :return: The QGIS layer.
        :rtype: QgsMapLayer

        .. versionadded:: 4.0
        """
        uri = self.layer_uri(layer_name)
        layer = QgsVectorLayer(uri, layer_name, 'ogr')
        if not layer.isValid():
            layer = QgsRasterLayer(uri, layer_name)
            if not layer.isValid():
                return False

        monkey_patch_keywords(layer)

        return layer
Ejemplo n.º 9
0
def load_layer_from_registry(layer_path):
    """Helper method to load a layer from registry if its already there.

    If the layer is not loaded yet, it will create the QgsMapLayer on the fly.

    :param layer_path: Layer source path.
    :type layer_path: str

    :return: Vector layer
    :rtype: QgsVectorLayer

    .. versionadded: 4.3.0
    """
    # reload the layer in case the layer path has no provider information
    the_layer = load_layer(layer_path)[0]
    layers = QgsProject.instance().mapLayers()
    for _, layer in list(layers.items()):
        if full_layer_uri(layer) == full_layer_uri(the_layer):
            monkey_patch_keywords(layer)
            return layer

    return the_layer
Ejemplo n.º 10
0
def load_layer_from_registry(layer_path):
    """Helper method to load a layer from registry if its already there.

    If the layer is not loaded yet, it will create the QgsMapLayer on the fly.

    :param layer_path: Layer source path.
    :type layer_path: str

    :return: Vector layer
    :rtype: QgsVectorLayer

    .. versionadded: 4.3.0
    """
    # reload the layer in case the layer path has no provider information
    the_layer = load_layer(layer_path)[0]
    layers = QgsProject.instance().mapLayers()
    for _, layer in list(layers.items()):
        if full_layer_uri(layer) == full_layer_uri(the_layer):
            monkey_patch_keywords(layer)
            return layer

    return the_layer
Ejemplo n.º 11
0
def clone_shp_layer(
        name,
        include_keywords,
        source_directory,
        target_directory='test'):
    """Helper function that copies a test shp layer and returns it.

    :param name: The default name for the shp layer.
    :type name: str

    :param include_keywords: Include keywords file if True.
    :type include_keywords: bool

    :param source_directory: Directory where the file is located.
    :type source_directory: str

    :param target_directory: Subdirectory in InaSAFE temp dir that we want to
        put the files into. Default to 'test'.
    :type target_directory: str
    """
    extensions = ['.shp', '.shx', '.dbf', '.prj']
    if include_keywords:
        extensions.append('.xml')
    temp_path = unique_filename(dir=temp_dir(target_directory))
    # copy to temp file
    for ext in extensions:
        src_path = os.path.join(source_directory, name + ext)
        if os.path.exists(src_path):
            target_path = temp_path + ext
            shutil.copy2(src_path, target_path)

    shp_path = '%s.shp' % temp_path
    layer = QgsVectorLayer(shp_path, os.path.basename(shp_path), 'ogr')

    monkey_patch_keywords(layer)

    return layer
Ejemplo n.º 12
0
def clone_shp_layer(
        name,
        include_keywords,
        source_directory,
        target_directory='test'):
    """Helper function that copies a test shp layer and returns it.

    :param name: The default name for the shp layer.
    :type name: str

    :param include_keywords: Include keywords file if True.
    :type include_keywords: bool

    :param source_directory: Directory where the file is located.
    :type source_directory: str

    :param target_directory: Subdirectory in InaSAFE temp dir that we want to
        put the files into. Default to 'test'.
    :type target_directory: str
    """
    extensions = ['.shp', '.shx', '.dbf', '.prj']
    if include_keywords:
        extensions.append('.xml')
    temp_path = unique_filename(dir=temp_dir(target_directory))
    # copy to temp file
    for ext in extensions:
        src_path = os.path.join(source_directory, name + ext)
        if os.path.exists(src_path):
            target_path = temp_path + ext
            shutil.copy2(src_path, target_path)

    shp_path = '%s.shp' % temp_path
    layer = QgsVectorLayer(shp_path, os.path.basename(shp_path), 'ogr')

    monkey_patch_keywords(layer)

    return layer
Ejemplo n.º 13
0
def load_path_vector_layer(path, **kwargs):
    """Return the test vector layer.

    :param path: Path to the vector layer.
    :type path: str

    :param kwargs: It can be :
        clone=True if you want to copy the layer first to a temporary file.

        clone_to_memory=True if you want to create a memory layer.

        with_keywords=False if you do not want keywords. "clone_to_memory" is
            required.

    :type kwargs: dict

    :return: The vector layer.
    :rtype: QgsVectorLayer

    .. versionadded:: 4.0
    """
    if not exists(path):
        raise Exception('%s do not exist.' % path)

    path = os.path.normcase(os.path.abspath(path))
    name = splitext(basename(path))[0]
    extension = splitext(path)[1]

    extensions = [
        '.shp', '.shx', '.dbf', '.prj', '.gpkg', '.geojson', '.xml', '.qml'
    ]

    if kwargs.get('with_keywords'):
        if not kwargs.get('clone_to_memory'):
            raise Exception('with_keywords needs a clone_to_memory')

    if kwargs.get('clone', False):
        target_directory = mkdtemp()
        current_path = splitext(path)[0]
        path = join(target_directory, name + extension)

        for ext in extensions:
            src_path = current_path + ext
            if exists(src_path):
                target_path = join(target_directory, name + ext)
                shutil.copy2(src_path, target_path)

    if path.endswith('.csv'):
        # Explicitly use URI with delimiter or tests fail in Windows. TS.
        uri = 'file:///%s?delimiter=%s' % (path, ',')
        layer = QgsVectorLayer(uri, name, 'delimitedtext')
    else:
        layer = QgsVectorLayer(path, name, 'ogr')

    if not layer.isValid():
        raise Exception('%s is not a valid layer.' % name)

    monkey_patch_keywords(layer)

    if kwargs.get('clone_to_memory', False):
        keywords = layer.keywords.copy()
        memory_layer = create_memory_layer(name, layer.geometryType(),
                                           layer.crs(), layer.fields())
        copy_layer(layer, memory_layer)
        if kwargs.get('with_keywords', True):
            memory_layer.keywords = keywords
        return memory_layer
    else:
        return layer
Ejemplo n.º 14
0
def load_layer(full_layer_uri_string, name=None, provider=None):
    """Helper to load and return a single QGIS layer based on our layer URI.

    :param provider: The provider name to use if known to open the layer.
        Default to None, we will try to guess it, but it's much better if you
        can provide it.
    :type provider:

    :param name: The name of the layer. If not provided, it will be computed
        based on the URI.
    :type name: basestring

    :param full_layer_uri_string: Layer URI, with provider type.
    :type full_layer_uri_string: str

    :returns: tuple containing layer and its layer_purpose.
    :rtype: (QgsMapLayer, str)
    """
    if provider:
        # Cool !
        layer_path = full_layer_uri_string
    else:
        #  Let's check if the driver is included in the path
        layer_path, provider = decode_full_layer_uri(full_layer_uri_string)

        if not provider:
            # Let's try to check if it's file based and look for a extension
            if '|' in layer_path:
                clean_uri = layer_path.split('|')[0]
            else:
                clean_uri = layer_path
            is_file_based = os.path.exists(clean_uri)
            if is_file_based:
                # Extract basename and absolute path
                file_name = os.path.split(layer_path)[
                    -1]  # If path was absolute
                extension = os.path.splitext(file_name)[1]
                if extension in OGR_EXTENSIONS:
                    provider = 'ogr'
                elif extension in GDAL_EXTENSIONS:
                    provider = 'gdal'
                else:
                    provider = None

    if not provider:
        layer = load_layer_without_provider(layer_path)
    else:
        layer = load_layer_with_provider(layer_path, provider)

    if not layer or not layer.isValid():
        message = 'Layer "%s" is not valid' % layer_path
        LOGGER.debug(message)
        raise InvalidLayerError(message)

    # Define the name
    if not name:
        source = layer.source()
        if '|' in source:
            clean_uri = source.split('|')[0]
        else:
            clean_uri = source
        is_file_based = os.path.exists(clean_uri)
        if is_file_based:
            # Extract basename and absolute path
            file_name = os.path.split(layer_path)[-1]  # If path was absolute
            name = os.path.splitext(file_name)[0]
        else:
            # Might be a DB, take the DB name
            source = QgsDataSourceUri(source)
            name = source.table()

    if not name:
        name = 'default'

    if qgis_version() >= 21800:
        layer.setName(name)
    else:
        layer.setLayerName(name)

    # update the layer keywords
    monkey_patch_keywords(layer)
    layer_purpose = layer.keywords.get('layer_purpose')

    return layer, layer_purpose
Ejemplo n.º 15
0
def load_path_vector_layer(path, **kwargs):
    """Return the test vector layer.

    :param path: Path to the vector layer.
    :type path: str

    :param kwargs: It can be :
        clone=True if you want to copy the layer first to a temporary file.

        clone_to_memory=True if you want to create a memory layer.

        with_keywords=False if you do not want keywords. "clone_to_memory" is
            required.

    :type kwargs: dict

    :return: The vector layer.
    :rtype: QgsVectorLayer

    .. versionadded:: 4.0
    """
    if not exists(path):
        raise Exception('%s do not exist.' % path)

    path = os.path.normcase(os.path.abspath(path))
    name = splitext(basename(path))[0]
    extension = splitext(path)[1]

    extensions = [
        '.shp', '.shx', '.dbf', '.prj', '.gpkg', '.geojson', '.xml', '.qml']

    if kwargs.get('with_keywords'):
        if not kwargs.get('clone_to_memory'):
            raise Exception('with_keywords needs a clone_to_memory')

    if kwargs.get('clone', False):
        target_directory = mkdtemp()
        current_path = splitext(path)[0]
        path = join(target_directory, name + extension)

        for ext in extensions:
            src_path = current_path + ext
            if exists(src_path):
                target_path = join(target_directory, name + ext)
                shutil.copy2(src_path, target_path)

    if path.endswith('.csv'):
        # Explicitly use URI with delimiter or tests fail in Windows. TS.
        uri = 'file:///%s?delimiter=%s' % (path, ',')
        layer = QgsVectorLayer(uri, name, 'delimitedtext')
    else:
        layer = QgsVectorLayer(path, name, 'ogr')

    if not layer.isValid():
        raise Exception('%s is not a valid layer.' % name)

    monkey_patch_keywords(layer)

    if kwargs.get('clone_to_memory', False):
        keywords = layer.keywords.copy()
        memory_layer = create_memory_layer(
            name, layer.geometryType(), layer.crs(), layer.fields())
        copy_layer(layer, memory_layer)
        if kwargs.get('with_keywords', True):
            memory_layer.keywords = keywords
        return memory_layer
    else:
        return layer
Ejemplo n.º 16
0
def load_layer(full_layer_uri_string, name=None, provider=None):
    """Helper to load and return a single QGIS layer based on our layer URI.

    :param provider: The provider name to use if known to open the layer.
        Default to None, we will try to guess it, but it's much better if you
        can provide it.
    :type provider:

    :param name: The name of the layer. If not provided, it will be computed
        based on the URI.
    :type name: basestring

    :param full_layer_uri_string: Layer URI, with provider type.
    :type full_layer_uri_string: str

    :returns: tuple containing layer and its layer_purpose.
    :rtype: (QgsMapLayer, str)
    """
    if provider:
        # Cool !
        layer_path = full_layer_uri_string
    else:
        #  Let's check if the driver is included in the path
        layer_path, provider = decode_full_layer_uri(full_layer_uri_string)

        if not provider:
            # Let's try to check if it's file based and look for a extension
            if '|' in layer_path:
                clean_uri = layer_path.split('|')[0]
            else:
                clean_uri = layer_path
            is_file_based = os.path.exists(clean_uri)
            if is_file_based:
                # Extract basename and absolute path
                file_name = os.path.split(layer_path)[
                    -1]  # If path was absolute
                extension = os.path.splitext(file_name)[1]
                if extension in OGR_EXTENSIONS:
                    provider = 'ogr'
                elif extension in GDAL_EXTENSIONS:
                    provider = 'gdal'
                else:
                    provider = None

    if not provider:
        layer = load_layer_without_provider(layer_path)
    else:
        layer = load_layer_with_provider(layer_path, provider)

    if not layer or not layer.isValid():
        message = 'Layer "%s" is not valid' % layer_path
        LOGGER.debug(message)
        raise InvalidLayerError(message)

    # Define the name
    if not name:
        source = layer.source()
        if '|' in source:
            clean_uri = source.split('|')[0]
        else:
            clean_uri = source
        is_file_based = os.path.exists(clean_uri)
        if is_file_based:
            # Extract basename and absolute path
            file_name = os.path.split(layer_path)[-1]  # If path was absolute
            name = os.path.splitext(file_name)[0]
        else:
            # Might be a DB, take the DB name
            source = QgsDataSourceUri(source)
            name = source.table()

    if not name:
        name = 'default'

    if qgis_version() >= 21800:
        layer.setName(name)
    else:
        layer.setLayerName(name)

    # update the layer keywords
    monkey_patch_keywords(layer)
    layer_purpose = layer.keywords.get('layer_purpose')

    return layer, layer_purpose