Ejemplo n.º 1
0
def open_file(
        dialog=None,
        osm_file=None,
        output_geom_types=None,
        white_list_column=None,
        layer_name="OsmFile",
        config_outputs=None,
        output_dir=None,
        final_query=None,
        prefix_file=None):
    """
    Open an osm file.

    Memory layer if no output directory is set, or Geojson in the output directory.

    :param final_query: The query where the file comes from. Might be empty if
    it's a local OSM file.
    :type final_query: basestring
    """
    outputs = {}
    if output_dir:
        for layer in ['points', 'lines', 'multilinestrings', 'multipolygons']:
            if not prefix_file:
                prefix_file = layer_name

            outputs[layer] = join(
                output_dir, prefix_file + "_" + layer + ".geojson")

            if isfile(outputs[layer]):
                raise FileOutPutException(suffix='(' + outputs[layer] + ')')

    # Legacy, waiting to remove the OsmParser for QGIS >= 3.6
    # Change in osm_file_dialog.py L131 too
    output_geom_legacy = [l.value.lower() for l in output_geom_types]
    if not white_list_column:
        white_list_column = {}
    white_list_legacy = (
        {l.value.lower(): csv for l, csv in white_list_column.items()}
    )

    LOGGER.info('The OSM file is: {}'.format(osm_file))

    # Parsing the file
    osm_parser = OsmParser(
        osm_file=osm_file,
        layers=output_geom_legacy,
        white_list_column=white_list_legacy)

    osm_parser.signalText.connect(dialog.set_progress_text)
    osm_parser.signalPercentage.connect(dialog.set_progress_percentage)

    start_time = time.time()
    layers = osm_parser.parse()
    elapsed_time = time.time() - start_time
    parser_time = time.strftime("%Hh %Mm %Ss", time.gmtime(elapsed_time))
    LOGGER.info('The OSM parser took: {}'.format(parser_time))

    # Finishing the process with geojson or memory layer
    num_layers = 0

    for i, (layer, item) in enumerate(layers.items()):
        dialog.set_progress_percentage(i / len(layers) * 100)
        QApplication.processEvents()
        if item['featureCount'] and LayerType(layer.capitalize()) in output_geom_types:

            final_layer_name = layer_name
            # If configOutputs is not None (from My Queries)
            if config_outputs:
                if config_outputs[layer]['namelayer']:
                    final_layer_name = config_outputs[layer]['namelayer']

            if output_dir:
                dialog.set_progress_text(tr('From memory to GeoJSON: ' + layer))
                # Transforming the vector file
                osm_geometries = {
                    'points': QgsWkbTypes.Point,
                    'lines': QgsWkbTypes.LineString,
                    'multilinestrings': QgsWkbTypes.MultiLineString,
                    'multipolygons': QgsWkbTypes.MultiPolygon}
                memory_layer = item['vector_layer']

                encoding = get_default_encoding()
                writer = QgsVectorFileWriter(
                    outputs[layer],
                    encoding,
                    memory_layer.fields(),
                    osm_geometries[layer],
                    memory_layer.crs(),
                    "GeoJSON")

                for f in memory_layer.getFeatures():
                    writer.addFeature(f)

                del writer

                # Loading the final vector file
                new_layer = QgsVectorLayer(outputs[layer], final_layer_name, "ogr")
            else:
                new_layer = item['vector_layer']
                new_layer.setName(final_layer_name)

            # Try to set styling if defined
            if config_outputs and config_outputs[layer]['style']:
                new_layer.loadNamedStyle(config_outputs[layer]['style'])
            else:
                # Loading default styles
                if layer == "multilinestrings" or layer == "lines":
                    if "colour" in item['tags']:
                        new_layer.loadNamedStyle(
                            join(dirname(dirname(abspath(__file__))),
                                 "styles",
                                 layer + "_colour.qml"))

            # Add action about OpenStreetMap
            add_actions(new_layer, item['tags'])

            if final_query:
                QgsExpressionContextUtils.setLayerVariable(
                    new_layer, 'quickosm_query', final_query)

            QgsProject.instance().addMapLayer(new_layer)
            num_layers += 1

    return num_layers
Ejemplo n.º 2
0
    def parse(self):
        """
        Start parsing the osm file
        """

        # Configuration for OGR
        gdal.SetConfigOption('OSM_CONFIG_FILE', self._osm_conf)
        gdal.SetConfigOption('OSM_USE_CUSTOM_INDEXING', 'NO')

        if not isfile(self.__osmFile):
            raise GeoAlgorithmExecutionException("File doesn't exist")

        uri = self.__osmFile + "|layername="
        layers = {}

        # If loadOnly, no parsing required:
        # It's used only when we ask to open an osm file
        if self.__loadOnly:
            file_name = basename(self.__osmFile)
            for layer in self.__layers:
                layers[layer] = QgsVectorLayer(
                    uri + layer, file_name + " " + layer, "ogr")

                if not layers[layer].isValid():
                    print "Error on the layer", layers[layer].lastError()

            return layers

        # Check if the order is node before way,relation
        # We don't check way before relation,
        # because we can have only nodes and relations
        with open(self.__osmFile) as f:
            for line in f:
                if re.search(r'node', line):
                    break
                if re.search(r'(way|relation)', line):
                    raise WrongOrderOSMException

        # Foreach layers
        for layer in self.__layers:
            self.signalText.emit(tr("QuickOSM", u"Parsing layer : " + layer))
            layers[layer] = {}

            # Reading it with a QgsVectorLayer
            layers[layer]['vectorLayer'] = QgsVectorLayer(
                uri + layer, "test_" + layer, "ogr")

            if not layers[layer]['vectorLayer'].isValid():
                msg = "Error on the layer : " + \
                      layers[layer]['vectorLayer'].lastError()
                raise GeoAlgorithmExecutionException(msg)

            # Set some default tags
            layers[layer]['tags'] = ['full_id', 'osm_id', 'osm_type']

            # Save the geometry type of the layer
            layers[layer]['geomType'] = layers[layer]['vectorLayer'].wkbType()

            # Set a featureCount
            layers[layer]['featureCount'] = 0

            # Get the other_tags
            fields = layers[layer]['vectorLayer'].pendingFields()
            field_names = [field.name() for field in fields]
            other_tags_index = field_names.index('other_tags')

            features = layers[layer]['vectorLayer'].getFeatures()
            for i, feature in enumerate(features):
                layers[layer]['featureCount'] += 1

                # Improve the parsing if comma in whitelist,
                # we skip the parsing of tags, but featureCount is needed
                if self.__whiteListColumn[layer] == ',':
                    continue

                # Get the "others_tags" field
                attributes = feature.attributes()[other_tags_index]

                if attributes:
                    h_store = pghstore.loads(attributes)
                    for key in h_store:
                        if key not in layers[layer]['tags']:
                            # If the key in OSM is not already in the table
                            if self.__whiteListColumn[layer]:
                                if key in self.__whiteListColumn[layer]:
                                    layers[layer]['tags'].append(key)
                            else:
                                layers[layer]['tags'].append(key)

                percent = int(100 / len(self.__layers) * (i + 1))
                self.signalPercentage.emit(percent)

        # Delete empty layers if this option is set to True
        if self.__deleteEmptyLayers:
            delete_layers = []
            for keys, values in layers.iteritems():
                if values['featureCount'] < 1:
                    delete_layers.append(keys)
            for layer in delete_layers:
                del layers[layer]

        # Creating GeoJSON files for each layers
        for layer in self.__layers:
            msg = tr("QuickOSM", u"Creating GeoJSON file : " + layer)
            self.signalText.emit(msg)
            self.signalPercentage.emit(0)

            # Creating the temp file
            tf = tempfile.NamedTemporaryFile(
                delete=False, suffix="_" + layer + ".geojson")
            layers[layer]['geojsonFile'] = tf.name
            tf.flush()
            tf.close()

            # Adding the attribute table
            fields = QgsFields()
            for key in layers[layer]['tags']:
                fields.append(QgsField(key, QVariant.String))

            encoding = get_default_encoding()
            file_writer = QgsVectorFileWriter(
                layers[layer]['geojsonFile'],
                encoding,
                fields,
                layers[layer]['geomType'],
                layers[layer]['vectorLayer'].crs(),
                'GeoJSON')

            # Foreach feature in the layer
            features = layers[layer]['vectorLayer'].getFeatures()
            for i, feature in enumerate(features):
                fet = QgsFeature()
                fet.setGeometry(feature.geometry())

                new_attributes = []
                attributes = feature.attributes()

                if layer in ['points', 'lines', 'multilinestrings']:
                    if layer == 'points':
                        osm_type = "node"
                    elif layer == 'lines':
                        osm_type = "way"
                    elif layer == 'multilinestrings':
                        osm_type = 'relation'

                    new_attributes.append(
                        self.DIC_OSM_TYPE[osm_type] + str(attributes[0]))
                    new_attributes.append(attributes[0])
                    new_attributes.append(osm_type)

                    if attributes[1]:
                        h_store = pghstore.loads(attributes[1])
                        for tag in layers[layer]['tags'][3:]:
                            if unicode(tag) in h_store:
                                new_attributes.append(h_store[tag])
                            else:
                                new_attributes.append("")
                        fet.setAttributes(new_attributes)
                        file_writer.addFeature(fet)

                elif layer == 'multipolygons':
                    if attributes[0]:
                        osm_type = "relation"
                        new_attributes.append(
                            self.DIC_OSM_TYPE[osm_type] + str(attributes[0]))
                        new_attributes.append(str(attributes[0]))
                    else:
                        osm_type = "way"
                        new_attributes.append(
                            self.DIC_OSM_TYPE[osm_type] + str(attributes[1]))
                        new_attributes.append(attributes[1])
                    new_attributes.append(osm_type)

                    h_store = pghstore.loads(attributes[2])
                    for tag in layers[layer]['tags'][3:]:
                        if unicode(tag) in h_store:
                            new_attributes.append(h_store[tag])
                        else:
                            new_attributes.append("")
                    fet.setAttributes(new_attributes)
                    file_writer.addFeature(fet)

                    percentage = int(
                        100 / layers[layer]['featureCount'] * (i + 1))
                    self.signalPercentage.emit(percentage)

            del file_writer

        return layers
Ejemplo n.º 3
0
def open_file(dialog=None,
              osm_file=None,
              output_geom_types=None,
              white_list_column=None,
              output_format=None,
              layer_name="OsmFile",
              config_outputs=None,
              output_dir=None,
              prefix_file=None):
    """
    open an osm file
    """
    outputs = get_outputs(output_dir, output_format, prefix_file, layer_name)

    # Parsing the file
    osm_parser = OsmParser(osm_file=osm_file,
                           layers=output_geom_types,
                           white_list_column=white_list_column)

    osm_parser.signalText.connect(dialog.set_progress_text)
    osm_parser.signalPercentage.connect(dialog.set_progress_percentage)
    layers = osm_parser.parse()

    # Finishing the process with geojson or shapefile
    num_layers = 0
    if output_format == "shape":
        dialog.set_progress_text(tr("QuickOSM", u"From GeoJSON to Shapefile"))

    for i, (layer, item) in enumerate(layers.iteritems()):
        dialog.set_progress_percentage(i / len(layers) * 100)
        QApplication.processEvents()
        if item['featureCount'] and layer in output_geom_types:

            final_layer_name = layer_name
            # If configOutputs is not None (from My Queries)
            if config_outputs:
                if config_outputs[layer]['namelayer']:
                    final_layer_name = config_outputs[layer]['namelayer']

            # Transforming the vector file
            osm_geometries = {
                'points': QGis.WKBPoint,
                'lines': QGis.WKBLineString,
                'multilinestrings': QGis.WKBMultiLineString,
                'multipolygons': QGis.WKBMultiPolygon
            }
            geojson_layer = QgsVectorLayer(item['geojsonFile'], "temp", "ogr")

            encoding = get_default_encoding()
            if output_format == "shape":
                writer = QgsVectorFileWriter(outputs[layer], encoding,
                                             geojson_layer.pendingFields(),
                                             osm_geometries[layer],
                                             geojson_layer.crs(),
                                             "ESRI Shapefile")
            else:
                writer = QgsVectorFileWriter(outputs[layer], encoding,
                                             geojson_layer.pendingFields(),
                                             osm_geometries[layer],
                                             geojson_layer.crs(), "GeoJSON")

            for f in geojson_layer.getFeatures():
                writer.addFeature(f)

            del writer

            # Loading the final vector file
            new_layer = QgsVectorLayer(outputs[layer], final_layer_name, "ogr")

            # Try to set styling if defined
            if config_outputs and config_outputs[layer]['style']:
                new_layer.loadNamedStyle(config_outputs[layer]['style'])
            else:
                # Loading default styles
                if layer == "multilinestrings" or layer == "lines":
                    if "colour" in item['tags']:
                        new_layer.loadNamedStyle(
                            join(dirname(dirname(abspath(__file__))), "styles",
                                 layer + "_colour.qml"))

            # Add action about OpenStreetMap
            actions = new_layer.actions()
            actions.addAction(
                QgsAction.OpenUrl, "OpenStreetMap Browser",
                'http://www.openstreetmap.org/browse/'
                '[% "osm_type" %]/[% "osm_id" %]', False)
            actions.addAction(
                QgsAction.GenericPython, 'JOSM',
                'from QuickOSM.CoreQuickOSM.Actions import Actions;'
                'Actions.run("josm","[% "full_id" %]")', False)
            actions.addAction(
                QgsAction.OpenUrl, "User default editor",
                'http://www.openstreetmap.org/edit?'
                '[% "osm_type" %]=[% "osm_id" %]', False)

            for link in ['url', 'website', 'wikipedia', 'ref:UAI']:
                if link in item['tags']:
                    link = link.replace(":", "_")
                    actions.addAction(
                        QgsAction.GenericPython, link,
                        'from QuickOSM.core.actions import Actions;'
                        'Actions.run("' + link + '","[% "' + link + '" %]")',
                        False)

            if 'network' in item['tags'] and 'ref' in item['tags']:
                actions.addAction(
                    QgsAction.GenericPython, "Sketchline",
                    'from QuickOSM.core.actions import Actions;'
                    'Actions.run_sketch_line("[% "network" %]","[% "ref" %]")',
                    False)

            # Add index if possible
            if output_format == "shape":
                new_layer.dataProvider().createSpatialIndex()

            QgsMapLayerRegistry.instance().addMapLayer(new_layer)
            num_layers += 1

    return num_layers
Ejemplo n.º 4
0
def open_file(
        dialog=None,
        osm_file=None,
        output_geom_types=None,
        white_list_column=None,
        output_format=None,
        layer_name="OsmFile",
        config_outputs=None,
        output_dir=None,
        prefix_file=None):
    """
    open an osm file
    """
    outputs = get_outputs(output_dir, output_format, prefix_file, layer_name)

    # Parsing the file
    osm_parser = OsmParser(
        osm_file=osm_file,
        layers=output_geom_types,
        white_list_column=white_list_column)

    osm_parser.signalText.connect(dialog.set_progress_text)
    osm_parser.signalPercentage.connect(dialog.set_progress_percentage)
    layers = osm_parser.parse()

    # Finishing the process with geojson or shapefile
    num_layers = 0
    if output_format == "shape":
        dialog.set_progress_text(tr("QuickOSM", u"From GeoJSON to Shapefile"))
    if output_format == "spatialite":
        dialog.set_progress_text(tr("QuickOSM", u"From GeoJSON to SpatiaLite"))
        # create spatialite DB
        conn = sqlitedb.connect(outputs['file'])
        cur = conn.cursor()
        cur.execute("SELECT initSpatialMetadata(1)")
        conn.close()

    for i, (layer, item) in enumerate(layers.iteritems()):
        dialog.set_progress_percentage(i / len(layers) * 100)
        QApplication.processEvents()
        if item['featureCount'] and layer in output_geom_types:

            final_layer_name = layer_name
            # If configOutputs is not None (from My Queries)
            if config_outputs:
                if config_outputs[layer]['namelayer']:
                    final_layer_name = config_outputs[layer]['namelayer']

            # Transforming the vector file
            osm_geometries = {
                'points': QGis.WKBPoint,
                'lines': QGis.WKBLineString,
                'multilinestrings': QGis.WKBMultiLineString,
                'multipolygons': QGis.WKBMultiPolygon}
            geojson_layer = QgsVectorLayer(item['geojsonFile'], "temp", "ogr")

            encoding = get_default_encoding()
            if output_format == "shape":
                provider = "ESRI Shapefile"
            elif output_format == "geojson":
                provider = "GeoJSON"
               
            if output_format == "spatialite":
                uri = QgsDataSourceURI()
                uri.setDatabase(outputs['file'])
                uri.setDataSource('', outputs[layer], 'geom')
                layer_source = uri.uri()
                layer_provider = 'spatialite'
                writer = QgsVectorLayerImport(
                    layer_source,
                    layer_provider,
                    geojson_layer.pendingFields(),
                    osm_geometries[layer],
                    geojson_layer.crs())
            else:
                layer_source = outputs[layer]
                layer_provider = 'ogr'
                writer = QgsVectorFileWriter(
                    layer_source,
                    encoding,
                    geojson_layer.pendingFields(),
                    osm_geometries[layer],
                    geojson_layer.crs(),
                    provider)

            for f in geojson_layer.getFeatures():
                writer.addFeature(f)

            del writer

            # Loading the final vector file
            new_layer = QgsVectorLayer(layer_source, final_layer_name, layer_provider)

            # Try to set styling if defined
            if config_outputs and config_outputs[layer]['style']:
                new_layer.loadNamedStyle(config_outputs[layer]['style'])
            else:
                # Loading default styles
                if layer == "multilinestrings" or layer == "lines":
                    if "colour" in item['tags']:
                        new_layer.loadNamedStyle(
                            join(dirname(dirname(abspath(__file__))),
                                 "styles",
                                 layer + "_colour.qml"))

            # Add action about OpenStreetMap
            actions = new_layer.actions()
            actions.addAction(
                QgsAction.OpenUrl,
                "OpenStreetMap Browser",
                'http://www.openstreetmap.org/browse/'
                '[% "osm_type" %]/[% "osm_id" %]',
                False)
            actions.addAction(
                QgsAction.GenericPython,
                'JOSM',
                'from QuickOSM.CoreQuickOSM.Actions import Actions;'
                'Actions.run("josm","[% "full_id" %]")',
                False)
            actions.addAction(
                QgsAction.OpenUrl,
                "User default editor",
                'http://www.openstreetmap.org/edit?'
                '[% "osm_type" %]=[% "osm_id" %]',
                False)

            for link in ['url', 'website', 'wikipedia', 'ref:UAI']:
                if link in item['tags']:
                    link = link.replace(":", "_")
                    actions.addAction(
                        QgsAction.GenericPython,
                        link,
                        'from QuickOSM.core.actions import Actions;'
                        'Actions.run("' + link + '","[% "' + link + '" %]")',
                        False)

            if 'network' in item['tags'] and 'ref' in item['tags']:
                actions.addAction(
                    QgsAction.GenericPython,
                    "Sketchline",
                    'from QuickOSM.core.actions import Actions;'
                    'Actions.run_sketch_line("[% "network" %]","[% "ref" %]")',
                    False)

            # Add index if possible
            if output_format == "shape" or output_format == "spatialite":
                new_layer.dataProvider().createSpatialIndex()

            QgsMapLayerRegistry.instance().addMapLayer(new_layer)
            num_layers += 1

    return num_layers
Ejemplo n.º 5
0
def open_file(
    dialog=None,
    osm_file=None,
    output_geom_types=None,
    white_list_column=None,
    output_format=None,
    layer_name="OsmFile",
    config_outputs=None,
    output_dir=None,
    prefix_file=None,
):
    """
    open an osm file
    """
    outputs = get_outputs(output_dir, output_format, prefix_file, layer_name)

    # Parsing the file
    osm_parser = OsmParser(osm_file=osm_file, layers=output_geom_types, white_list_column=white_list_column)

    osm_parser.signalText.connect(dialog.set_progress_text)
    osm_parser.signalPercentage.connect(dialog.set_progress_percentage)
    layers = osm_parser.parse()

    # Finishing the process with geojson or shapefile
    num_layers = 0
    if output_format == "shape":
        dialog.set_progress_text(tr("QuickOSM", u"From GeoJSON to Shapefile"))

    for i, (layer, item) in enumerate(layers.iteritems()):
        dialog.set_progress_percentage(i / len(layers) * 100)
        QApplication.processEvents()
        if item["featureCount"] and layer in output_geom_types:

            final_layer_name = layer_name
            # If configOutputs is not None (from My Queries)
            if config_outputs:
                if config_outputs[layer]["namelayer"]:
                    final_layer_name = config_outputs[layer]["namelayer"]

            # Transforming the vector file
            osm_geometries = {
                "points": QGis.WKBPoint,
                "lines": QGis.WKBLineString,
                "multilinestrings": QGis.WKBMultiLineString,
                "multipolygons": QGis.WKBMultiPolygon,
            }
            geojson_layer = QgsVectorLayer(item["geojsonFile"], "temp", "ogr")

            encoding = get_default_encoding()
            if output_format == "shape":
                writer = QgsVectorFileWriter(
                    outputs[layer],
                    encoding,
                    geojson_layer.pendingFields(),
                    osm_geometries[layer],
                    geojson_layer.crs(),
                    "ESRI Shapefile",
                )
            else:
                writer = QgsVectorFileWriter(
                    outputs[layer],
                    encoding,
                    geojson_layer.pendingFields(),
                    osm_geometries[layer],
                    geojson_layer.crs(),
                    "GeoJSON",
                )

            for f in geojson_layer.getFeatures():
                writer.addFeature(f)

            del writer

            # Loading the final vector file
            new_layer = QgsVectorLayer(outputs[layer], final_layer_name, "ogr")

            # Try to set styling if defined
            if config_outputs and config_outputs[layer]["style"]:
                new_layer.loadNamedStyle(config_outputs[layer]["style"])
            else:
                # Loading default styles
                if layer == "multilinestrings" or layer == "lines":
                    if "colour" in item["tags"]:
                        new_layer.loadNamedStyle(
                            join(dirname(dirname(abspath(__file__))), "styles", layer + "_colour.qml")
                        )

            # Add action about OpenStreetMap
            actions = new_layer.actions()
            actions.addAction(
                QgsAction.OpenUrl,
                "OpenStreetMap Browser",
                "http://www.openstreetmap.org/browse/" '[% "osm_type" %]/[% "osm_id" %]',
                False,
            )
            actions.addAction(
                QgsAction.GenericPython,
                "JOSM",
                "from QuickOSM.CoreQuickOSM.Actions import Actions;" 'Actions.run("josm","[% "full_id" %]")',
                False,
            )
            actions.addAction(
                QgsAction.OpenUrl,
                "User default editor",
                "http://www.openstreetmap.org/edit?" '[% "osm_type" %]=[% "osm_id" %]',
                False,
            )

            for link in ["url", "website", "wikipedia", "ref:UAI"]:
                if link in item["tags"]:
                    link = link.replace(":", "_")
                    actions.addAction(
                        QgsAction.GenericPython,
                        link,
                        "from QuickOSM.core.actions import Actions;"
                        'Actions.run("' + link + '","[% "' + link + '" %]")',
                        False,
                    )

            if "network" in item["tags"] and "ref" in item["tags"]:
                actions.addAction(
                    QgsAction.GenericPython,
                    "Sketchline",
                    "from QuickOSM.core.actions import Actions;"
                    'Actions.run_sketch_line("[% "network" %]","[% "ref" %]")',
                    False,
                )

            # Add index if possible
            if output_format == "shape":
                new_layer.dataProvider().createSpatialIndex()

            QgsMapLayerRegistry.instance().addMapLayer(new_layer)
            num_layers += 1

    return num_layers
Ejemplo n.º 6
0
def open_file(dialog=None,
              osm_file=None,
              output_geom_types=None,
              white_list_column=None,
              layer_name="OsmFile",
              config_outputs=None,
              output_dir=None,
              prefix_file=None):
    """
    Open an osm file.

    Memory layer if no output directory is set, or Geojson in the output directory.
    """
    outputs = {}
    if output_dir:
        for layer in ['points', 'lines', 'multilinestrings', 'multipolygons']:
            if not prefix_file:
                prefix_file = layer_name

            outputs[layer] = join(output_dir,
                                  prefix_file + "_" + layer + ".geojson")

            if isfile(outputs[layer]):
                raise FileOutPutException(suffix='(' + outputs[layer] + ')')

    # Parsing the file
    osm_parser = OsmParser(osm_file=osm_file,
                           layers=output_geom_types,
                           white_list_column=white_list_column)

    osm_parser.signalText.connect(dialog.set_progress_text)
    osm_parser.signalPercentage.connect(dialog.set_progress_percentage)

    start_time = time.time()
    layers = osm_parser.parse()
    elapsed_time = time.time() - start_time
    parser_time = time.strftime("%Hh %Mm %Ss", time.gmtime(elapsed_time))
    LOGGER.info('The OSM parser took: {}'.format(parser_time))

    # Finishing the process with geojson or memory layer
    num_layers = 0

    for i, (layer, item) in enumerate(layers.items()):
        dialog.set_progress_percentage(i / len(layers) * 100)
        QApplication.processEvents()
        if item['featureCount'] and layer in output_geom_types:

            final_layer_name = layer_name
            # If configOutputs is not None (from My Queries)
            if config_outputs:
                if config_outputs[layer]['namelayer']:
                    final_layer_name = config_outputs[layer]['namelayer']

            if output_dir:
                dialog.set_progress_text(tr('From memory to GeoJSON: ' +
                                            layer))
                # Transforming the vector file
                osm_geometries = {
                    'points': QgsWkbTypes.Point,
                    'lines': QgsWkbTypes.LineString,
                    'multilinestrings': QgsWkbTypes.MultiLineString,
                    'multipolygons': QgsWkbTypes.MultiPolygon
                }
                memory_layer = item['vector_layer']

                encoding = get_default_encoding()
                writer = QgsVectorFileWriter(outputs[layer], encoding,
                                             memory_layer.fields(),
                                             osm_geometries[layer],
                                             memory_layer.crs(), "GeoJSON")

                for f in memory_layer.getFeatures():
                    writer.addFeature(f)

                del writer

                # Loading the final vector file
                new_layer = QgsVectorLayer(outputs[layer], final_layer_name,
                                           "ogr")
            else:
                new_layer = item['vector_layer']
                new_layer.setName(final_layer_name)

            # Try to set styling if defined
            if config_outputs and config_outputs[layer]['style']:
                new_layer.loadNamedStyle(config_outputs[layer]['style'])
            else:
                # Loading default styles
                if layer == "multilinestrings" or layer == "lines":
                    if "colour" in item['tags']:
                        new_layer.loadNamedStyle(
                            join(dirname(dirname(abspath(__file__))), "styles",
                                 layer + "_colour.qml"))

            # Add action about OpenStreetMap
            add_actions(new_layer, item['tags'])

            QgsProject.instance().addMapLayer(new_layer)
            num_layers += 1

    return num_layers
Ejemplo n.º 7
0
def open_file(dialog=None,
              osm_file=None,
              output_geom_types=None,
              white_list_column=None,
              layer_name="OsmFile",
              config_outputs=None,
              output_dir=None,
              prefix_file=None):
    """
    Open an osm file.

    Memory layer if no output directory is set, or Geojson in the output directory.
    """
    outputs = {}
    if output_dir:
        for layer in ['points', 'lines', 'multilinestrings', 'multipolygons']:
            if not prefix_file:
                prefix_file = layer_name

            outputs[layer] = join(output_dir,
                                  prefix_file + "_" + layer + ".geojson")

            if isfile(outputs[layer]):
                raise FileOutPutException(suffix='(' + outputs[layer] + ')')

    # Parsing the file
    osm_parser = OsmParser(osm_file=osm_file,
                           layers=output_geom_types,
                           white_list_column=white_list_column)

    osm_parser.signalText.connect(dialog.set_progress_text)
    osm_parser.signalPercentage.connect(dialog.set_progress_percentage)
    layers = osm_parser.parse()

    # Finishing the process with geojson or memory layer
    num_layers = 0

    for i, (layer, item) in enumerate(layers.items()):
        dialog.set_progress_percentage(i / len(layers) * 100)
        QApplication.processEvents()
        if item['featureCount'] and layer in output_geom_types:

            final_layer_name = layer_name
            # If configOutputs is not None (from My Queries)
            if config_outputs:
                if config_outputs[layer]['namelayer']:
                    final_layer_name = config_outputs[layer]['namelayer']

            if output_dir:
                dialog.set_progress_text(
                    tr("QuickOSM", u"From memory to GeoJSON: " + layer))
                # Transforming the vector file
                osm_geometries = {
                    'points': QgsWkbTypes.Point,
                    'lines': QgsWkbTypes.LineString,
                    'multilinestrings': QgsWkbTypes.MultiLineString,
                    'multipolygons': QgsWkbTypes.MultiPolygon
                }
                memory_layer = item['vector_layer']

                encoding = get_default_encoding()
                writer = QgsVectorFileWriter(outputs[layer], encoding,
                                             memory_layer.fields(),
                                             osm_geometries[layer],
                                             memory_layer.crs(), "GeoJSON")

                for f in memory_layer.getFeatures():
                    writer.addFeature(f)

                del writer

                # Loading the final vector file
                new_layer = QgsVectorLayer(outputs[layer], final_layer_name,
                                           "ogr")
            else:
                new_layer = item['vector_layer']
                new_layer.setName(final_layer_name)

            # Try to set styling if defined
            if config_outputs and config_outputs[layer]['style']:
                new_layer.loadNamedStyle(config_outputs[layer]['style'])
            else:
                # Loading default styles
                if layer == "multilinestrings" or layer == "lines":
                    if "colour" in item['tags']:
                        new_layer.loadNamedStyle(
                            join(dirname(dirname(abspath(__file__))), "styles",
                                 layer + "_colour.qml"))

            # Add action about OpenStreetMap
            actions = new_layer.actions()
            actions.addAction(
                QgsAction.OpenUrl, "OpenStreetMap Browser",
                'http://www.openstreetmap.org/browse/'
                '[% "osm_type" %]/[% "osm_id" %]', False)
            actions.addAction(
                QgsAction.GenericPython, 'JOSM',
                'from QuickOSM.CoreQuickOSM.Actions import Actions;'
                'Actions.run("josm","[% "full_id" %]")', False)
            actions.addAction(
                QgsAction.OpenUrl, "User default editor",
                'http://www.openstreetmap.org/edit?'
                '[% "osm_type" %]=[% "osm_id" %]', False)

            for link in ['url', 'website', 'wikipedia', 'ref:UAI']:
                if link in item['tags']:
                    link = link.replace(":", "_")
                    actions.addAction(
                        QgsAction.GenericPython, link,
                        'from QuickOSM.core.actions import Actions;'
                        'Actions.run("' + link + '","[% "' + link + '" %]")',
                        False)

            if 'network' in item['tags'] and 'ref' in item['tags']:
                actions.addAction(
                    QgsAction.GenericPython, "Sketchline",
                    'from QuickOSM.core.actions import Actions;'
                    'Actions.run_sketch_line("[% "network" %]","[% "ref" %]")',
                    False)

            QgsProject.instance().addMapLayer(new_layer)
            num_layers += 1

    return num_layers