def convert_hyperlinks(hyperlinks, layer: QgsVectorLayer): """ Converts hyperlinks to QGIS actions """ script = """from qgis.PyQt.QtWidgets import QMessageBox, QInputDialog from qgis.PyQt.QtGui import QDesktopServices from qgis.PyQt.QtCore import QUrl hyperlinks = { """ features = {} for h in hyperlinks: if h.feature_id not in features: features[h.feature_id] = [] features[h.feature_id].append(h.url) for _id, links in features.items(): script += f""" {_id}: ['{"','".join(links)}'],\n""" script += """} if [% $id %] in hyperlinks: res, ok = QInputDialog.getItem(None, 'Hyperlinks', '', hyperlinks[[% $id %]],0,False) if ok: QDesktopServices.openUrl(QUrl(res)) """ action = QgsAction(QgsAction.GenericPython, 'Open Hyperlinks', script, '', False, 'Hyperlinks', {'Field', 'Feature', 'Layer', 'Canvas'}) layer.actions().addAction(action)
def test_add_styles(self): """Test we can add styles and actions from Processing algorithm.""" lines_layer = QgsVectorLayer(plugin_test_data_path('lines.geojson'), 'lines', 'ogr') self.assertTrue(lines_layer.isValid()) self.assertEqual(len(lines_layer.actions().actions()), 0) params = { 'APPARAEP': '', 'APPARASS': '', 'OUVRAEP': '', 'OUVRASS': '', 'CANALAEP': lines_layer, 'CANALASS': '', 'STYLETYPE': [1, 2] } processing.run('raepa:add_styles', params) self.assertEqual(len(lines_layer.actions().actions()), 5)
def add_relaunch_action(layer: QgsVectorLayer, layer_name: str = ""): """ Add the relaunch action """ actions = layer.actions() title = tr('Reload the query in a new file') reload = QgsAction( QgsAction.GenericPython, title, ACTIONS_PATH + 'Actions.run_reload(layer_name="{layer_name}")'.format( layer_name=layer_name), '', False, title, [Visibility.Layer.value], '') actions.addAction(reload)
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
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
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
def add_actions(layer: QgsVectorLayer, keys: list): """Add actions on layer. :param layer: The layer. :type layer: QgsVectorLayer :param keys: The list of keys in the layer. :type keys: list """ actions = layer.actions() title = tr('OpenStreetMap Browser') osm_browser = QgsAction( QgsAction.OpenUrl, title, 'http://www.openstreetmap.org/browse/[% "osm_type" %]/[% "osm_id" %]', '', False, title, ACTIONS_VISIBILITY, '') actions.addAction(osm_browser) title = 'JOSM' josm = QgsAction(QgsAction.GenericPython, title, ACTIONS_PATH + 'Actions.run("josm","[% "full_id" %]")', resources_path('icons', 'josm_icon.svg'), False, title, ACTIONS_VISIBILITY, '') actions.addAction(josm) title = tr('User default editor') default_editor = QgsAction( QgsAction.OpenUrl, title, 'http://www.openstreetmap.org/edit?[% "osm_type" %]=[% "osm_id" %]', '', False, title, ACTIONS_VISIBILITY, '') actions.addAction(default_editor) for link in [ 'mapillary', 'url', 'website', 'wikipedia', 'wikidata', 'ref:UAI' ]: if link in keys: # Add an image to the action if available image = '' if link == 'wikipedia': image = resources_path('icons', 'wikipedia.png') elif link == 'wikidata': image = resources_path('icons', 'wikidata.png') elif link in ['url', 'website']: image = resources_path('icons', 'external_link.png') elif link == 'mapillary': image = resources_path('icons', 'mapillary_logo.svg') link = link.replace(":", "_") generic = QgsAction( QgsAction.GenericPython, link, (ACTIONS_PATH + 'Actions.run("{link}","[% "{link}" %]")'.format(link=link)), image, False, link, ACTIONS_VISIBILITY, '') actions.addAction(generic) if 'network' in keys and 'ref' in keys: sketch_line = QgsAction( QgsAction.GenericPython, tr('Sketchline'), (ACTIONS_PATH + 'Actions.run_sketch_line("[% "network" %]","[% "ref" %]")'), '', False, '', ACTIONS_VISIBILITY, '') actions.addAction(sketch_line)
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