def run(field, value): """ Run an action with only one value as parameter @param field:Type of the action @type field:str @param value:Value of the field for one entity @type value:str """ if value == '': iface.messageBar().pushMessage( tr("OSMData", u"Sorry man, this field is empty for this entity."), level=QgsMessageBar.WARNING, duration=7) else: field = unicode(field, "UTF-8") value = unicode(value, "UTF-8") if field in ["url", "website", "wikipedia"]: var = QDesktopServices() url = None if field == "url" or field == "website": url = value if field == "ref_UAI": url = "http://www.education.gouv.fr/pid24302/annuaire-" \ "resultat-recherche.html?lycee_name=" + value if field == "wikipedia": url = "http://en.wikipedia.org/wiki/" + value var.openUrl(QUrl(url)) elif field == "josm": import urllib2 try: url = "http://localhost:8111/load_object?objects=" + value urllib2.urlopen(url).read() except urllib2.URLError: iface.messageBar().pushMessage( tr("OSMData", u"The JOSM remote seems to be disabled."), level=QgsMessageBar.CRITICAL, duration=7) # NOT USED elif field == "rawedit": url = QUrl("http://rawedit.openstreetmap.fr/edit/" + value) web_browser = QWebView(None) web_browser.load(url) web_browser.show()
def __init__(self, msg=None, suffix=None): if not msg: msg = tr('Exception', u'The output file already exist, set a prefix') if suffix: msg = msg + " " + suffix OsmDataException.__init__(self, msg)
def __init__(self, msg=None, suffix=None): if not msg: msg = tr( 'Exception', u'The order must be node-way-relation. ' u'Check the print statement.') if suffix: msg = msg + " " + suffix OsmDataException.__init__(self, msg)
def process_query( dialog=None, query=None, nominatim=None, bbox=None, output_dir=None, prefix_file=None, output_geometry_types=None, layer_name="OsmQuery", white_list_values=None, config_outputs=None): """execute a query and send the result file to open_file.""" # Check OGR if not is_osm_driver_enabled(): raise OsmDriver # Get output's format output_format = get_setting('outputFormat') # Prepare outputs dialog.set_progress_text(tr("OSMData", u"Prepare outputs")) # Replace Nominatim or BBOX query = prepare_query(query=query, extent=bbox) # Getting the default overpass api and running the query server = get_setting('defaultOAPI') dialog.set_progress_text(tr("OSMData", u"Downloading data from Overpass")) QApplication.processEvents() connexion_overpass_api = ConnexionOAPI(url=server, output="xml") osm_file = connexion_overpass_api.get_file_from_query(query) return open_file( dialog=dialog, osm_file=osm_file, output_geom_types=output_geometry_types, white_list_column=white_list_values, layer_name=layer_name, output_format=output_format, output_dir=output_dir, prefix_file=prefix_file, config_outputs=config_outputs)
def process_query(dialog=None, query=None, nominatim=None, bbox=None, output_dir=None, prefix_file=None, output_geometry_types=None, layer_name="OsmQuery", white_list_values=None, config_outputs=None): """execute a query and send the result file to open_file.""" # Check OGR if not is_osm_driver_enabled(): raise OsmDriver # Get output's format output_format = get_setting('outputFormat') # Prepare outputs dialog.set_progress_text(tr("OSMData", u"Prepare outputs")) # Replace Nominatim or BBOX query = prepare_query(query=query, extent=bbox) # Getting the default overpass api and running the query server = get_setting('defaultOAPI') dialog.set_progress_text(tr("OSMData", u"Downloading data from Overpass")) QApplication.processEvents() connexion_overpass_api = ConnexionOAPI(url=server, output="xml") osm_file = connexion_overpass_api.get_file_from_query(query) return open_file(dialog=dialog, osm_file=osm_file, output_geom_types=output_geometry_types, white_list_column=white_list_values, layer_name=layer_name, output_format=output_format, output_dir=output_dir, prefix_file=prefix_file, config_outputs=config_outputs)
def run_sketch_line(network, ref): """ Run an action with two values for sketchline @param network:network of the bus @type network:str @param ref:ref of the bus @type ref:str """ network = unicode(network, "UTF-8") ref = unicode(ref, "UTF-8") if network == '' or ref == '': iface.messageBar().pushMessage( tr("OSMData", u"Sorry man, this field is empty for this entity."), level=QgsMessageBar.WARNING, duration=7) else: var = QDesktopServices() url = "http://www.overpass-api.de/api/sketch-line?" \ "network=" + network + "&ref=" + ref var.openUrl(QUrl(url))
def __init__(self, msg=None): if not msg: msg = tr( 'Exception', u"The OSM's driver is not installed. " u"You must have GDAL/OGR >= 1.10.") OsmDataException.__init__(self, msg)
def __init__(self, msg=None, suffix=None): if not msg: msg = tr("Exception", u"Error while building the query") if suffix: msg = msg + " : " + suffix OsmDataException.__init__(self, msg)
def __init__(self, msg=None): if not msg: msg = tr("Exception", u"No nominatim area") OsmDataException.__init__(self, msg)
def __init__(self, msg=None): if not msg: msg = tr('Exception', u'OverpassAPI timeout') OsmDataException.__init__(self, msg)
def __init__(self, msg=None, suffix=None): if not msg: msg = tr("Exception", u"Network error") if suffix: msg = msg + " with " + suffix OsmDataException.__init__(self, msg)
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("OSMData", 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 OSMData.CoreOSMData.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 OSMData.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 OSMData.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 __init__(self, msg=None): if not msg: msg = tr('Exception', u'Bad request OverpassAPI') OsmDataException.__init__(self, msg)
def __init__(self, msg=None, suffix=None): if not msg: msg = tr("Exception", u"A parameter is missing :") if suffix: msg = msg + " " + suffix OsmDataException.__init__(self, msg)
def __init__(self, msg=None): if not msg: msg = tr("Exception", u"No osm objects selected") OsmDataException.__init__(self, msg)
def __init__(self, msg=None): if not msg: msg = tr("Exception", u"Output not available") OsmDataException.__init__(self, msg)
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("OSMData", 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 OSMData.CoreOSMData.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 OSMData.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 OSMData.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 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("OSMData", 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("OSMData", 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
def __init__(self, msg=None): if not msg: msg = tr('Exception', u'The output directory does not exist.') OsmDataException.__init__(self, msg)
def __init__(self, msg=None, suffix=None): if not msg: msg = tr("Exception", u"The file doesn't exist") if suffix: msg = msg + " " + suffix OsmDataException.__init__(self, msg)
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("OSMData", 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("OSMData", 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
def __init__(self, msg=None): if not msg: msg = tr('Exception', u'No outputs selected') OsmDataException.__init__(self, msg)
def __init__(self, msg=None): if not msg: msg = tr("Exception", u"This query already exists") OsmDataException.__init__(self, msg)
def __init__(self, msg=None): if not msg: msg = tr("Exception", u"Error with ogr2ogr") OsmDataException.__init__(self, msg)