def __init__(self, parent=None): """ OsmFileWidget constructor """ QuickOSMWidget.__init__(self, parent) self.setupUi(self) self.init() # Set UI self.radioButton_osmConf.setChecked(False) self.osm_conf.setEnabled(False) self.label_progress.setText("") self.lineEdit_filePrefix.setDisabled(True) # OSM File self.osm_file.setDialogTitle(tr('Select an OSM file')) self.osm_file.setFilter('OSM file (*.osm *.pbf)') # Set default osm conf self.defaultOsmConf = join( dirname(dirname(abspath(__file__))), 'osmconf.ini') if not isfile(self.defaultOsmConf): self.defaultOsmConf = '' self.osm_conf.setDialogTitle(tr('Select OSM conf file')) self.osm_conf.setFilter('OSM conf (*.ini)') self.osm_conf.fileChanged.connect(self.disable_run_button) self.pushButton_runQuery.setEnabled(False) # Connect self.osm_file.fileChanged.connect(self.disable_run_button) self.output_directory.fileChanged.connect(self.disable_prefix_file) self.radioButton_osmConf.toggled.connect(self.disable_run_button) self.pushButton_runQuery.clicked.connect(self.open_file) self.disable_run_button()
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.""" # Prepare outputs dialog.set_progress_text(tr('Prepare outputs')) # Replace Nominatim or BBOX query = QueryPreparation(query, bbox, nominatim) # Getting the default overpass api and running the query server = get_setting('defaultOAPI') dialog.set_progress_text(tr('Downloading data from Overpass')) QApplication.processEvents() connexion_overpass_api = ConnexionOAPI(url=server, output="xml") osm_file = connexion_overpass_api.query(query.prepare_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_dir=output_dir, prefix_file=prefix_file, config_outputs=config_outputs)
def show_popup_menu(self, point): """ Right click in the tree @param point:Cursor's point @type point:QPoint """ item = self.treeQueries.itemAt(point) if isinstance(item, TreeQueryItem): config = item.query.getContent() # We set the query self.current_query = config['metadata']['query'] # We create the menu popup_menu = QMenu() execute_action = QAction( tr('QuickOSM', 'Execute'), self.treeQueries) # noinspection PyUnresolvedReferences execute_action.triggered.connect(self.open_and_run_query) popup_menu.addAction(execute_action) show_action = QAction( tr('QuickOSM', 'Show query'), self.treeQueries) # noinspection PyUnresolvedReferences show_action.triggered.connect(self.show_query) popup_menu.addAction(show_action) delete_action = QAction( tr('QuickOSM', 'Delete'), self.treeQueries) # noinspection PyUnresolvedReferences delete_action.triggered.connect(self.delete_query) popup_menu.addAction(delete_action) popup_menu.exec_(self.treeQueries.mapToGlobal(point))
def josm_remote(self): map_settings = self.iface.mapCanvas().mapSettings() extent = map_settings.extent() crs_map = map_settings.destinationCrs() if crs_map.authid() != 'EPSG:4326': crs_4326 = QgsCoordinateReferenceSystem(4326) transform = QgsCoordinateTransform(crs_map, crs_4326, QgsProject.instance()) extent = transform.transform(extent) url = 'http://localhost:8111/load_and_zoom?' query_string = 'left=%f&right=%f&top=%f&bottom=%f' % (extent.xMinimum( ), extent.xMaximum(), extent.yMaximum(), extent.yMinimum()) url += query_string try: request = urllib.request.Request(url) result_request = urllib.request.urlopen(request) result = result_request.read() result = result.decode('utf8') if result.strip().upper() != 'OK': self.iface.messageBar().pushCritical(tr('JOSM Remote'), result) else: self.iface.messageBar().pushSuccess( tr('JOSM Remote'), tr('Import done, check JOSM')) except IOError: self.iface.messageBar().pushCritical(tr('JOSM Remote'), tr('Is the remote enabled?'))
def set_ui_query_panel(self): self.combo_query_type_q.addItem(tr('Canvas Extent'), 'canvas') self.combo_query_type_q.addItem(tr('Layer Extent'), 'layer') self.combo_query_type_q.currentIndexChanged.connect( self.query_type_updated_q) highlighter = XMLHighlighter(self.text_query.document()) self.text_query.cursorPositionChanged.connect(highlighter.rehighlight) self.text_query.cursorPositionChanged.connect( self.allow_nominatim_or_extent) self.button_overpass_turbo.setIcon( QIcon(resources_path('icons', 'turbo.png'))) self.button_overpass_turbo.clicked.connect(open_overpass_turbo) # Setup menu for documentation popup_menu = QMenu() map_features_action = QAction('Map Features', self.button_documentation) map_features_action.triggered.connect(open_map_features) popup_menu.addAction(map_features_action) overpass_action = QAction('Overpass', self.button_documentation) overpass_action.triggered.connect(open_doc_overpass) popup_menu.addAction(overpass_action) self.button_documentation.setMenu(popup_menu) self.run_buttons[Panels.File].clicked.connect(self.run_query) self.button_generate_query.clicked.connect(self.generate_query) self.button_box_q.button(QDialogButtonBox.Reset).clicked.connect( self.reset_form) self.allow_nominatim_or_extent() self.query_type_updated_q()
def _set_custom_ui(self, panel): """Function to set custom UI for some panels. :param panel: Name of the panel. :type panel: Panels """ self.output_directories[panel].lineEdit().setPlaceholderText( tr('Save to temporary file')) self.output_directories[panel].setStorageMode( QgsFileWidget.GetDirectory) self.output_directories[panel].setDialogTitle(tr('Select a directory')) # def disable_prefix_file(): # # TODO # def disable_prefix_file(directory, file_prefix): # """If the directory is empty, we disable the file prefix.""" # if directory.filePath(): # file_prefix.setDisabled(False) # else: # file_prefix.setText('') # file_prefix.setDisabled(True) # # self.output_directories[panel].fileChanged.connect( # disable_prefix_file) if panel in self.advanced_panels.keys(): self.advanced_panels[panel].setSaveCollapsedState(False) self.advanced_panels[panel].setCollapsed(True)
def add_bottom_parameters(self): parameter = QgsProcessingParameterNumber( self.TIMEOUT, tr('Timeout'), defaultValue=25, minValue=5) parameter.setFlags( parameter.flags() | QgsProcessingParameterDefinition.FlagAdvanced) self.addParameter(parameter) server = get_setting( 'defaultOAPI', OVERPASS_SERVERS[0]) + 'interpreter' parameter = QgsProcessingParameterString( self.SERVER, tr('Overpass server'), optional=False, defaultValue=server) parameter.setFlags( parameter.flags() | QgsProcessingParameterDefinition.FlagAdvanced) self.addParameter(parameter) self.addOutput( QgsProcessingOutputString( self.OUTPUT_URL, tr('Query as encoded URL'))) self.addOutput( QgsProcessingOutputString( self.OUTPUT_OQL_QUERY, tr('Raw query as OQL')))
def __init__(self, parent=None): """ OsmFileWidget constructor """ QuickOSMWidget.__init__(self, parent) self.setupUi(self) self.init() # Set UI self.radioButton_osmConf.setChecked(False) self.osm_conf.setEnabled(False) self.label_progress.setText("") self.lineEdit_filePrefix.setDisabled(True) # OSM File self.osm_file.setDialogTitle(tr('Select an OSM file')) self.osm_file.setFilter('OSM file (*.osm *.pbf)') # Set default osm conf self.defaultOsmConf = join(dirname(dirname(abspath(__file__))), 'osmconf.ini') if not isfile(self.defaultOsmConf): self.defaultOsmConf = '' self.osm_conf.setDialogTitle(tr('Select OSM conf file')) self.osm_conf.setFilter('OSM conf (*.ini)') self.osm_conf.fileChanged.connect(self.disable_run_button) self.pushButton_runQuery.setEnabled(False) # Connect self.osm_file.fileChanged.connect(self.disable_run_button) self.output_directory.fileChanged.connect(self.disable_prefix_file) self.radioButton_osmConf.toggled.connect(self.disable_run_button) self.pushButton_runQuery.clicked.connect(self.open_file) self.disable_run_button()
def show_popup_menu(self, point): """ Right click in the tree @param point:Cursor's point @type point:QPoint """ item = self.treeQueries.itemAt(point) if isinstance(item, TreeQueryItem): config = item.query.getContent() # We set the query self.current_query = config['metadata']['query'] # We create the menu popup_menu = QMenu() execute_action = QAction(tr('Execute'), self.treeQueries) # noinspection PyUnresolvedReferences execute_action.triggered.connect(self.open_and_run_query) popup_menu.addAction(execute_action) show_action = QAction(tr('Show query'), self.treeQueries) # noinspection PyUnresolvedReferences show_action.triggered.connect(self.show_query) popup_menu.addAction(show_action) delete_action = QAction(tr('Delete'), self.treeQueries) # noinspection PyUnresolvedReferences delete_action.triggered.connect(self.delete_query) popup_menu.addAction(delete_action) popup_menu.exec_(self.treeQueries.mapToGlobal(point))
def josm_remote(self): map_settings = self.iface.mapCanvas().mapSettings() extent = map_settings.extent() crs_map = map_settings.destinationCrs() if crs_map.authid() != 'EPSG:4326': crs_4326 = QgsCoordinateReferenceSystem(4326) transform = QgsCoordinateTransform(crs_map, crs_4326, QgsProject.instance()) extent = transform.transform(extent) url = 'http://localhost:8111/load_and_zoom?' query_string = 'left=%f&right=%f&top=%f&bottom=%f' % ( extent.xMinimum(), extent.xMaximum(), extent.yMaximum(), extent.yMinimum()) url += query_string try: request = urllib.request.Request(url) result_request = urllib.request.urlopen(request) result = result_request.read() result = result.decode('utf8') if result.strip().upper() != 'OK': self.iface.messageBar().pushCritical( tr('JOSM Remote'), result) else: self.iface.messageBar().pushSuccess( tr('JOSM Remote'), tr('Import done, check JOSM')) except IOError: self.iface.messageBar().pushCritical( tr('JOSM Remote'), tr('Is the remote enabled?'))
def add_top_parameters(self): self.addParameter( QgsProcessingParameterString( self.KEY, tr('Key, default to all keys'), optional=True)) self.addParameter( QgsProcessingParameterString( self.VALUE, tr('Value, default to all values'), optional=True))
def initAlgorithm(self, config=None): self.add_top_parameters() self.addParameter( QgsProcessingParameterString( self.AREA, tr('Around the area (Point WKT accepted)'), optional=False)) self.addParameter( QgsProcessingParameterNumber( self.DISTANCE, tr('Distance (meters)'), defaultValue=1000, minValue=1)) self.add_bottom_parameters()
def __init__(self, parent=None): """ QuickQueryWidget constructor """ QuickOSMWidget.__init__(self, parent) self.setupUi(self) # Setup UI self.label_progress.setText("") self.lineEdit_filePrefix.setDisabled(True) self.groupBox.setCollapsed(True) self.fill_layer_combobox() self.groupBox.setCollapsed(True) self.comboBox_in_around.setDisabled(True) self.lineEdit_nominatim.setDisabled(True) self.radioButton_extentMapCanvas.setChecked(True) self.spinBox_distance_point.setDisabled(True) self.label_distance_point.setDisabled(True) # Setup in/around combobox self.comboBox_in_around.insertItem(0, tr('ui_quick_query', u'In')) self.comboBox_in_around.insertItem(1, tr('ui_quick_query', u'Around')) # connect self.pushButton_runQuery.clicked.connect(self.run_query) self.pushButton_showQuery.clicked.connect(self.show_query) self.pushButton_browse_output_file.clicked.connect( self.set_output_directory_path) self.comboBox_key.editTextChanged.connect(self.key_edited) self.lineEdit_browseDir.textEdited.connect(self.disable_prefix_file) self.radioButton_extentLayer.toggled.connect( self.allow_nominatim_or_extent) self.radioButton_extentMapCanvas.toggled.connect( self.allow_nominatim_or_extent) self.radioButton_place.toggled.connect(self.allow_nominatim_or_extent) self.pushButton_refreshLayers.clicked.connect(self.fill_layer_combobox) self.pushButton_mapFeatures.clicked.connect(self.open_map_features) self.buttonBox.button(QDialogButtonBox.Reset).clicked.connect( self.reset_form) self.comboBox_in_around.currentIndexChanged.connect(self.in_or_around) # Setup auto completion map_features_json_file = join(dirname(dirname(abspath(__file__))), 'mapFeatures.json') if isfile(map_features_json_file): self.osmKeys = load(open(map_features_json_file)) keys = self.osmKeys.keys() keys.sort() keys_completer = QCompleter(keys) self.comboBox_key.addItems(keys) self.comboBox_key.setCompleter(keys_completer) self.comboBox_key.completer().setCompletionMode( QCompleter.PopupCompletion) self.key_edited() self.init_nominatim_autofill()
def __init__(self, parent=None): """ QuickQueryWidget constructor """ QuickOSMWidget.__init__(self, parent) self.setupUi(self) # Setup UI self.label_progress.setText("") self.lineEdit_filePrefix.setDisabled(True) self.groupBox.setCollapsed(True) self.fill_layer_combobox() self.groupBox.setCollapsed(True) self.comboBox_in_around.setDisabled(True) self.lineEdit_nominatim.setDisabled(True) self.radioButton_extentMapCanvas.setChecked(True) self.spinBox_distance_point.setDisabled(True) self.label_distance_point.setDisabled(True) # Setup in/around combobox self.comboBox_in_around.insertItem(0, tr('ui_quick_query', u'In')) self.comboBox_in_around.insertItem(1, tr('ui_quick_query', u'Around')) # connect self.pushButton_runQuery.clicked.connect(self.run_query) self.pushButton_showQuery.clicked.connect(self.show_query) self.pushButton_browse_output_file.clicked.connect( self.set_output_directory_path) self.comboBox_key.editTextChanged.connect(self.key_edited) self.lineEdit_browseDir.textEdited.connect(self.disable_prefix_file) self.radioButton_extentLayer.toggled.connect( self.allow_nominatim_or_extent) self.radioButton_extentMapCanvas.toggled.connect( self.allow_nominatim_or_extent) self.radioButton_place.toggled.connect(self.allow_nominatim_or_extent) self.pushButton_refreshLayers.clicked.connect(self.fill_layer_combobox) self.pushButton_mapFeatures.clicked.connect(self.open_map_features) self.buttonBox.button(QDialogButtonBox.Reset).clicked.connect( self.reset_form) self.comboBox_in_around.currentIndexChanged.connect(self.in_or_around) # Setup auto completion map_features_json_file = join( dirname(dirname(abspath(__file__))), 'mapFeatures.json') if isfile(map_features_json_file): self.osmKeys = load(open(map_features_json_file)) keys = self.osmKeys.keys() keys.sort() keys_completer = QCompleter(keys) self.comboBox_key.addItems(keys) self.comboBox_key.setCompleter(keys_completer) self.comboBox_key.completer().setCompletionMode( QCompleter.PopupCompletion) self.key_edited() self.init_nominatim_autofill()
def __init__(self, parent=None): """ QuickQueryWidget constructor """ QuickOSMWidget.__init__(self, parent) self.setupUi(self) self.init() # Setup UI # Query type self.cb_query_type.addItem(tr('In'), 'in') self.cb_query_type.addItem(tr('Around'), 'around') self.cb_query_type.addItem(tr('Canvas Extent'), 'canvas') self.cb_query_type.addItem(tr('Layer Extent'), 'layer') self.cb_query_type.addItem(tr('Not Spatial'), 'attributes') self.cb_query_type.currentIndexChanged.connect(self.query_type_updated) self.label_progress.setText("") self.lineEdit_filePrefix.setDisabled(True) # self.activate_extent_layer() # connect self.pushButton_runQuery.clicked.connect(self.run_query) self.pushButton_showQuery.clicked.connect(self.show_query) self.comboBox_key.editTextChanged.connect(self.key_edited) self.pushButton_mapFeatures.clicked.connect(self.open_map_features) self.buttonBox.button(QDialogButtonBox.Reset).clicked.connect( self.reset_form) # Setup auto completion map_features_json_file = join(dirname(dirname(abspath(__file__))), 'mapFeatures.json') if isfile(map_features_json_file): with open(map_features_json_file) as f: self.osmKeys = load(f) keys = list(self.osmKeys.keys()) keys.append('') # All keys request #118 keys.sort() keys_completer = QCompleter(keys) self.comboBox_key.addItems(keys) self.comboBox_key.setCompleter(keys_completer) self.comboBox_key.completer().setCompletionMode( QCompleter.PopupCompletion) self.comboBox_key.lineEdit().setPlaceholderText( 'Query on all keys') self.comboBox_value.lineEdit().setPlaceholderText( 'Query on all values') self.key_edited() self.query_type_updated() self.init_nominatim_autofill()
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( "QuickOSM", 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("QuickOSM", 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 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("QuickOSM", 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("QuickOSM", 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): """Init after the UI is loaded.""" self.output_directory.lineEdit().setPlaceholderText(tr('Save to temporary file')) self.output_directory.setStorageMode(QgsFileWidget.GetDirectory) self.output_directory.setDialogTitle(tr('Select a directory')) self.output_directory.fileChanged.connect(self.disable_prefix_file) try: self.advanced.setSaveCollapsedState(False) self.advanced.setCollapsed(True) except AttributeError: # OSM File widget does not have this QgsGroupBox pass
def init(self): """Init after the UI is loaded.""" self.output_directory.lineEdit().setPlaceholderText( tr('Save to temporary file')) self.output_directory.setStorageMode(QgsFileWidget.GetDirectory) self.output_directory.setDialogTitle(tr('Select a directory')) self.output_directory.fileChanged.connect(self.disable_prefix_file) try: self.advanced.setSaveCollapsedState(False) self.advanced.setCollapsed(True) except AttributeError: # OSM File widget does not have this QgsGroupBox pass
def process_quick_query(dialog=None, key=None, value=None, bbox=None, area=None, is_around=None, distance=None, osm_objects=None, timeout=25, output_directory=None, prefix_file=None, output_geometry_types=None): """ Generate a query and send it to process_query. """ # TODO # Move this logic UP # Copy/paste in quick_query_dialog.py distance_string = None if is_around and area: query_type = QueryType.AroundArea distance_string = '{}'.format(distance) elif not is_around and area: query_type = QueryType.InArea distance = None elif bbox: query_type = QueryType.BBox else: query_type = QueryType.NotSpatial # End todo LOGGER.info('QueryFactory: the key is "{}" and the value is "{}"'.format( key, value)) # Building the query query_factory = QueryFactory(query_type=query_type, key=key, value=value, area=area, around_distance=distance, osm_objects=osm_objects, timeout=timeout) query = query_factory.make() # Generate layer name as following (if defined) if not key: key = tr('allKeys') expected_name = [key, value, area, distance_string] layer_name = '_'.join([f for f in expected_name if f]) LOGGER.info('Query: {}'.format(layer_name)) # Call process_query with the new query return process_query(dialog=dialog, query=query, area=area, bbox=bbox, output_dir=output_directory, prefix_file=prefix_file, output_geometry_types=output_geometry_types, layer_name=layer_name)
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 QuickOsmException.__init__(self, msg)
def initGui(self): self.initProcessing() # Setup menu self.quickosm_menu = QMenu('QuickOSM') self.quickosm_menu.setIcon( QIcon(resources_path('icons', 'QuickOSM.svg'))) self.vector_menu = self.iface.vectorMenu() self.vector_menu.addMenu(self.quickosm_menu) # Main window self.main_window_action = QAction( QIcon(resources_path('icons', 'QuickOSM.svg')), 'QuickOSM…', self.iface.mainWindow()) # noinspection PyUnresolvedReferences self.main_window_action.triggered.connect(self.open_dialog) self.toolbar.addAction(self.main_window_action) # Action JOSM self.josm_action = QAction( QIcon(resources_path('icons', 'josm_icon.svg')), tr('JOSM Remote'), self.iface.mainWindow()) self.josm_action.triggered.connect(self.josm_remote) self.toolbar.addAction(self.josm_action) # Insert in the good order self.quickosm_menu.addAction(self.main_window_action) self.quickosm_menu.addAction(self.josm_action)
def end_query(self, num_layers): """Display the message at the end of the query. :param num_layers: Number of layers which have been loaded. :rtype num_layers: int """ if num_layers: self.set_progress_text(tr('Successful query')) self.display_message_bar(tr('Successful query'), level=Qgis.Success, duration=5) else: self.set_progress_text(tr('No result')) self.display_message_bar(tr('Successful query, but no result.'), level=Qgis.Warning, duration=7)
def display_message_bar(self, title, message=None, level=Qgis.Info, duration=5, open_logs=False): """Display a message. :param title: Title of the message. :type title: basestring :param message: The message. :type message: basestring :param level: A QGIS error level. :param duration: Duration in second. :type duration: int :param open_logs: If we need to add a button for the log panel. :type open_logs: bool """ widget = self.message_bar.createMessage(title, message) if open_logs: button = QPushButton(widget) button.setText(tr('Report it')) button.pressed.connect(lambda: open_log_panel()) widget.layout().addWidget(button) self.message_bar.pushWidget(widget, level, duration)
def __init__(self, msg=None): if not msg: msg = tr( 'Exception', u"The OSM's driver is not installed. " u"Please install the OSM driver for GDAL " u": http://www.gdal.org/drv_osm.html") QuickOsmException.__init__(self, msg)
def __init__(self, msg=None): if not msg: msg = tr('QuickOSM') self.msg = msg BaseException.__init__(self, msg) self.level = Qgis.Critical self.duration = 7
def __init__(self, parent=None): QDockWidget.__init__(self, parent) self.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) self.setWidget(MyQueriesWidget()) self.setWindowTitle(tr("ui_my_queries", "QuickOSM - My queries")) self.widget().signal_delete_query_successful.connect( self.signal_delete_query_successful.emit)
def __init__(self, parent=None): QDockWidget.__init__(self, parent) self.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) self.setWidget(QueryWidget()) self.setWindowTitle(tr("ui_query", "QuickOSM - Query")) self.widget().signal_new_query_successful.connect( self.signal_new_query_successful.emit)
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 QuickOsmException.__init__(self, msg)
def open_file(self): """Open the osm file with the osmconf.""" try: self._start_process() p = self.gather_values() if p['load_only']: # 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 p['outputs']] osm_parser = OsmParser(p['osm_file'], load_only=True, osm_conf=p['osm_conf'], layers=output_geom_legacy) layers = osm_parser.parse() for item in layers.values(): QgsProject.instance().addMapLayer(item) else: open_file(dialog=self, osm_file=p['osm_file'], output_geom_types=p['outputs'], output_dir=p['output_directory'], prefix_file=p['prefix_file']) self.display_message_bar(tr('Successful query'), level=Qgis.Success, duration=5) except QuickOsmException as e: self.display_geo_algorithm_exception(e) except Exception as e: self.display_exception(e) finally: self._end_process()
def display_message_bar( title, message=None, level=Qgis.Info, duration=5, open_logs=False): """Display the message at the good place. :param title: Title of the message. :type title: basestring :param message: The message. :type message: basestring :param level: A QGIS error level. :param duration: Duration in second. :type duration: int :param open_logs: If we need to add a button for the log panel. :type open_logs: bool """ if iface.QuickOSM_mainWindowDialog.isVisible(): message_bar = iface.QuickOSM_mainWindowDialog.messageBar else: message_bar = iface.QuickOSM_mainWindowDialog.messageBar() widget = message_bar.createMessage(title, message) if open_logs: button = QPushButton(widget) button.setText(tr('Report it!')) button.pressed.connect( lambda: open_log_panel()) widget.layout().addWidget(button) message_bar.pushWidget(widget, level, duration)
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_ogr_version_ok(): raise GDALVersion if not is_osm_driver_enabled(): raise OsmDriverNotFound # Get output's format output_format = get_setting('outputFormat') # Prepare outputs dialog.set_progress_text(tr("QuickOSM", u"Prepare outputs")) # Replace Nominatim or BBOX query = prepare_query(query=query, nominatim_name=nominatim, extent=bbox) # Getting the default overpass api and running the query server = get_setting('defaultOAPI') dialog.set_progress_text(tr("QuickOSM", 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 __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 QuickOsmException.__init__(self, msg)
def set_output_directory_path(self): """ Fill the output directory path """ # noinspection PyTypeChecker output_file = QFileDialog.getExistingDirectory( None, caption=tr("QuickOSM", 'Select directory')) self.lineEdit_browseDir.setText(output_file) self.disable_prefix_file()
def __init__(self, parent=None): """ QuickQueryWidget constructor """ QuickOSMWidget.__init__(self, parent) self.setupUi(self) self.init() # Setup UI # Query type self.cb_query_type.addItem(tr('In'), 'in') self.cb_query_type.addItem(tr('Around'), 'around') self.cb_query_type.addItem(tr('Canvas Extent'), 'canvas') self.cb_query_type.addItem(tr('Layer Extent'), 'layer') self.cb_query_type.addItem(tr('Not Spatial'), 'attributes') # self.cb_query_type.setItemIcon(0, QIcon(resources_path('in.svg'))) # self.cb_query_type.setItemIcon(1, QIcon(resources_path('around.svg'))) # self.cb_query_type.setItemIcon(2, QIcon(resources_path('map_canvas.svg'))) # self.cb_query_type.setItemIcon(3, QIcon(resources_path('extent.svg'))) # self.cb_query_type.setItemIcon(4, QIcon(resources_path('mIconTableLayer.svg'))) self.cb_query_type.currentIndexChanged.connect(self.query_type_updated) self.label_progress.setText("") self.lineEdit_filePrefix.setDisabled(True) # self.activate_extent_layer() # connect self.pushButton_runQuery.clicked.connect(self.run_query) self.pushButton_showQuery.clicked.connect(self.show_query) self.comboBox_key.editTextChanged.connect(self.key_edited) self.pushButton_mapFeatures.clicked.connect(self.open_map_features) self.buttonBox.button(QDialogButtonBox.Reset).clicked.connect( self.reset_form) # Setup auto completion map_features_json_file = join( dirname(dirname(abspath(__file__))), 'mapFeatures.json') if isfile(map_features_json_file): with open(map_features_json_file) as f: self.osmKeys = load(f) keys = list(self.osmKeys.keys()) keys.append('') # All keys request #118 keys.sort() keys_completer = QCompleter(keys) self.comboBox_key.addItems(keys) self.comboBox_key.setCompleter(keys_completer) self.comboBox_key.completer().setCompletionMode( QCompleter.PopupCompletion) self.comboBox_key.lineEdit().setPlaceholderText(tr('Query on all keys')) self.comboBox_value.lineEdit().setPlaceholderText(tr('Query on all values')) self.key_edited() self.query_type_updated() self.init_nominatim_autofill()
def set_osm_file_path(self): """ Fill the osm file """ osm_file = QFileDialog.getOpenFileName( parent=None, caption=tr("QuickOSM", 'Select *.osm or *.pbf'), filter="OSM file (*.osm *.pbf)") self.lineEdit_osmFile.setText(osm_file) self.disable_run_button()
def _check_parameters(self): """Internal function to check that the query can be built.""" if self._query_type not in QueryType: raise QueryFactoryException(tr('Wrong query type')) if len(self._osm_objects) < 1: raise QueryFactoryException(tr('OSM object required')) for osmObject in self._osm_objects: if osmObject not in OsmType: raise QueryFactoryException(tr('Wrong OSM object')) if self._query_type == QueryType.AroundArea and not self._distance_around: raise QueryFactoryException(tr('No distance provided with "around".')) areas = [ QueryType.InArea, QueryType.AroundArea] if self._query_type in areas and not self._area: raise QueryFactoryException(tr('Named area required or WKT.'))
def restore_default_queries(self): """ Overwrite all queries """ text = self.pushButton_restoreQueries.text() self.pushButton_restoreQueries.setText(tr('QuickOSM', 'Copy ...')) get_user_query_folder(over_write=True) self.signal_new_query_successful.emit() # self.my_queries.fill_tree(force=True) self.pushButton_restoreQueries.setText(text)
def add_bottom_parameters(self): parameter = QgsProcessingParameterNumber( self.TIMEOUT, tr('Timeout'), defaultValue=25, minValue=5) parameter.setFlags(parameter.flags() | QgsProcessingParameterDefinition.FlagAdvanced) self.addParameter(parameter) server = get_setting('defaultOAPI', OVERPASS_SERVERS[0]) + 'interpreter' parameter = QgsProcessingParameterString( self.SERVER, tr('Overpass server'), optional=False, defaultValue=server) parameter.setFlags(parameter.flags() | QgsProcessingParameterDefinition.FlagAdvanced) self.addParameter(parameter) self.addOutput( QgsProcessingOutputString( self.OUTPUT_URL, tr('Query as encoded URL'))) self.addOutput( QgsProcessingOutputString( self.OUTPUT_OQL_QUERY, tr('Raw query as OQL')))
def get_timestamp_overpass_api(self): """ Get the timestamp of the current server """ text = self.pushButton_OAPI_timestamp.text() self.pushButton_OAPI_timestamp.setText( tr('QuickOSM', 'Fetching the timestamp ...')) overpass_api = ConnexionOAPI(url=self.defaultServer) self.label_timestamp_oapi.setText(overpass_api.get_timestamp()) self.pushButton_OAPI_timestamp.setText(text)
def _check_parameters(self): """Internal function to check that the query can be built. :raise QueryFactoryException :return True if everything went fine. """ if type(self._query_type) != QueryType: raise QueryFactoryException(tr('Wrong query type.')) for osmObject in self._osm_objects: if type(osmObject) != OsmType: raise QueryFactoryException(tr('Wrong OSM object.')) if self._query_type == QueryType.AroundArea: if not self._distance_around: raise QueryFactoryException( tr('No distance provided with "around".')) try: int(self._distance_around) except ValueError: raise QueryFactoryException( tr('Wrong distance parameter.')) if self._distance_around and self._query_type == QueryType.InArea: raise QueryFactoryException( tr('Distance parameter is incompatible with this query.')) areas = [ QueryType.InArea, QueryType.AroundArea] if self._query_type in areas and not self._area: raise QueryFactoryException(tr('Named area required or WKT.')) if not self._key and self._value: raise QueryFactoryException( tr('Not possible to query a value without a key.')) if len(self._key) > len(self._value): if len(self._key) != 1: raise QueryFactoryException( tr('Missing some values for some keys')) if len(self._key) < len(self._value): raise QueryFactoryException( tr('Missing some keys for some values')) self._checked = True return True
def restore_default_queries(self): """ Overwrite all queries """ text = self.pushButton_restoreQueries.text() self.pushButton_restoreQueries.setText(tr('QuickOSM', 'Copy ...')) get_user_query_folder(over_write=True) self.signal_new_query_successful.emit() self.my_queries.fill_tree(force=True) self.pushButton_restoreQueries.setText(text)
def start_process(self): """ Make some stuff before launching the process """ self.pushButton_runQuery.setDisabled(True) self.pushButton_runQuery.initialText = self.pushButton_runQuery.text() self.pushButton_runQuery.setText(tr('QuickOSM', 'Running query ...')) self.progressBar_execution.setMinimum(0) self.progressBar_execution.setMaximum(0) self.progressBar_execution.setValue(0) self.label_progress.setText('')
def set_osm_conf_path(self): """ Fill the osmConf file """ osm_conf = QFileDialog.getOpenFileName( parent=None, caption=tr("QuickOSM", 'Select osm conf'), filter="OsmConf file (*.ini)") if osm_conf: self.lineEdit_osmConf.setText(osm_conf) self.disable_run_button()
def initAlgorithm(self, config=None): self.addParameter( QgsProcessingParameterString( self.QUERY, tr('Query'), optional=False, multiLine=True)) self.addParameter( QgsProcessingParameterExtent( self.EXTENT, tr('Extent, if "{{bbox}}" in the query'), optional=True)) server = get_setting('defaultOAPI', OVERPASS_SERVERS[0]) + 'interpreter' parameter = QgsProcessingParameterString( self.SERVER, tr('Overpass server'), optional=False, defaultValue=server) parameter.setFlags(parameter.flags() | QgsProcessingParameterDefinition.FlagAdvanced) self.addParameter(parameter) parameter = QgsProcessingParameterString( self.AREA, tr('Area (if you want to override {{geocodeArea}} in the query'), optional=True) parameter.setFlags(parameter.flags() | QgsProcessingParameterDefinition.FlagAdvanced) self.addParameter(parameter) self.addOutput( QgsProcessingOutputString( self.OUTPUT_URL, tr('Query as encoded URL'))) self.addOutput( QgsProcessingOutputString( self.OUTPUT_OQL_QUERY, tr('Raw query as OQL')))
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.""" # Prepare outputs dialog.set_progress_text(tr('Prepare outputs')) # Getting the default overpass api and running the query server = get_setting('defaultOAPI', OVERPASS_SERVERS[0]) + 'interpreter' dialog.set_progress_text( tr('Downloading data from Overpass {}').format(server)) # Replace Nominatim or BBOX query = QueryPreparation(query, bbox, nominatim, server) QApplication.processEvents() final_query = query.prepare_query() url = query.prepare_url() connexion_overpass_api = ConnexionOAPI(url) LOGGER.debug('Encoded URL: {}'.format(url)) osm_file = connexion_overpass_api.run() 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_dir=output_dir, prefix_file=prefix_file, final_query=final_query, config_outputs=config_outputs)
def emit(self, record): """Try to log the message to QGIS if available, otherwise do nothing. :param record: logging record containing whatever info needs to be logged. """ try: QgsMessageLog.logMessage( record.getMessage(), 'QuickOSM', qgis_level(record.levelname)) except MemoryError: message = tr( 'Due to memory limitations on this machine, QuickOSM can not ' 'handle the full log') print(message) QgsMessageLog.logMessage(message, 'QuickOSM', Qgis.Critical)
def display_exception(e): """ Display others exceptions """ exc_type, _, exc_tb = exc_info() f_name = split(exc_tb.tb_frame.f_code.co_filename)[1] print(exc_type, f_name, exc_tb.tb_lineno) _, _, tb = exc_info() import traceback traceback.print_tb(tb) print e display_message_bar( tr('QuickOSM', 'Error in the python console, please report it'), level=QgsMessageBar.CRITICAL, duration=5)
def initGui(self): self.initProcessing() # Setup menu self.quickosm_menu = QMenu('QuickOSM') self.quickosm_menu.setIcon( QIcon(join(dirname(__file__), 'resources', 'QuickOSM.svg'))) self.vector_menu = self.iface.vectorMenu() self.vector_menu.addMenu(self.quickosm_menu) # Main window self.mainWindowAction = QAction( QIcon(join(dirname(__file__), 'resources', 'QuickOSM.svg')), 'QuickOSM…', self.iface.mainWindow()) # noinspection PyUnresolvedReferences self.mainWindowAction.triggered.connect(self.openMainWindow) self.toolbar.addAction(self.mainWindowAction) self.iface.QuickOSM_mainWindowDialog = MainWindowDialog() # Action JOSM self.josmAction = QAction( QIcon(join(dirname(__file__), 'resources', 'josm_icon.svg')), tr('JOSM Remote'), self.iface.mainWindow()) self.josmAction.triggered.connect(self.josm_remote) self.toolbar.addAction(self.josmAction) # Insert in the good order self.quickosm_menu.addAction(self.mainWindowAction) self.quickosm_menu.addAction(self.josmAction) for server in OVERPASS_SERVERS: self.iface.QuickOSM_mainWindowDialog.comboBox_default_OAPI. \ addItem(server) # Read the config file custom_config = join(quickosm_user_folder(), 'custom_config.json') if isfile(custom_config): with open(custom_config) as f: config_json = load(f) for server in config_json.get('overpass_servers'): if server not in OVERPASS_SERVERS: LOGGER.info( 'Custom overpass server list added: {}'.format( server)) self.iface.QuickOSM_mainWindowDialog.\ comboBox_default_OAPI.addItem(server)
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 """ if network == '' or ref == '': iface.messageBar().pushMessage( tr('Sorry, this field is empty for this entity.'), level=Qgis.Warning, duration=7) else: var = QDesktopServices() url = 'http://www.overpass-api.de/api/sketch-line?' \ 'network=' + network + '&ref=' + ref var.openUrl(QUrl(url))
def display_exception(e): """ Display others exceptions """ exc_type, _, exc_tb = exc_info() f_name = split(exc_tb.tb_frame.f_code.co_filename)[1] _, _, tb = exc_info() import traceback traceback.print_tb(tb) LOGGER.critical(exc_type) LOGGER.critical(f_name) LOGGER.critical(e) LOGGER.critical('\n'.join(traceback.format_tb(tb))) display_message_bar( tr('Error in the QGIS Logs, QuickOSM panel, please report it to ' '<a href="https://github.com/3liz/QuickOSM/issues/new?' 'template=1_BUG_REPORT.md">GitHub</a>'), level=Qgis.Critical, duration=10)