class Cadastre(object): def __init__(self, iface): # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = str(Path(__file__).resolve().parent) # initialize locale locale = QSettings().value("locale/userLocale")[0:2] localePath = os.path.join(self.plugin_dir, 'i18n', 'cadastre_{}.qm'.format(locale)) if os.path.exists(localePath): self.translator = QTranslator() self.translator.load(localePath) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) def initGui(self): # Create action that will start plugin configuration self.action = QAction( QIcon(":/plugins/cadastre/icon.png"), u"Cadastre", self.iface.mainWindow()) # connect the action to the run method self.action.triggered.connect(self.run) # Add toolbar button and menu item self.iface.addToolBarIcon(self.action) self.iface.addPluginToMenu(u"&Cadastre", self.action) def unload(self): # Remove the plugin menu item and icon self.iface.removePluginMenu(u"&Cadastre", self.action) self.iface.removeToolBarIcon(self.action)
class QScatterPlugin: def __init__(self, iface): self.iface = iface overrideLocale = QSettings().value('locale/overrideFlag', False, bool) if not overrideLocale: locale = QLocale.system().name()[:2] else: locale = QSettings().value('locale/userLocale', '') qmPath = '{}/i18n/qscatter_{}.qm'.format(pluginPath, locale) if os.path.exists(qmPath): self.translator = QTranslator() self.translator.load(qmPath) QCoreApplication.installTranslator(self.translator) def initGui(self): self.actionRun = QAction( self.tr('QScatter'), self.iface.mainWindow()) self.actionRun.setIcon( QIcon(os.path.join(pluginPath, 'icons', 'qscatter.svg'))) self.actionRun.setWhatsThis( self.tr('Interactive scatter plot')) self.actionRun.setObjectName('runQScatter') self.actionAbout = QAction( self.tr('About...'), self.iface.mainWindow()) self.actionAbout.setIcon( QgsApplication.getThemeIcon('/mActionHelpContents.svg')) self.actionAbout.setWhatsThis(self.tr('About QScatter')) self.actionRun.setObjectName('aboutQScatter') self.iface.addPluginToVectorMenu( self.tr('QScatter'), self.actionRun) self.iface.addPluginToVectorMenu( self.tr('QScatter'), self.actionAbout) self.iface.addVectorToolBarIcon(self.actionRun) self.actionRun.triggered.connect(self.run) self.actionAbout.triggered.connect(self.about) def unload(self): self.iface.removePluginVectorMenu( self.tr('QScatter'), self.actionRun) self.iface.removePluginVectorMenu( self.tr('QScatter'), self.actionAbout) self.iface.removeVectorToolBarIcon(self.actionRun) def run(self): dlg = QScatterDialog(self.iface) dlg.show() dlg.exec_() def about(self): dlg = AboutDialog() dlg.exec_() def tr(self, text): return QCoreApplication.translate('QScatter', text)
def getTranslate(namePlugin, nameDir=None): if nameDir is None: nameDir = namePlugin pluginPath = os.path.join('python', 'plugins', nameDir) userPath = QFileInfo(QgsApplication.qgisUserDatabaseFilePath()).path() userPluginPath = os.path.join(userPath, pluginPath) systemPath = QgsApplication.prefixPath() systemPluginPath = os.path.join(systemPath, pluginPath) overrideLocale = QSettings().value('locale/overrideFlag', False, type=bool) localeFullName = QLocale.system().name() if not overrideLocale else QSettings().value('locale/userLocale', '') qmPathFile = os.path.join('i18n', '{0}_{1}.qm'.format(namePlugin, localeFullName)) pp = userPluginPath if QFileInfo(userPluginPath).exists() else systemPluginPath translationFile = os.path.join(pp, qmPathFile) if QFileInfo(translationFile).exists(): translator = QTranslator() translator.load(translationFile) QCoreApplication.installTranslator(translator) QgsApplication.messageLog().logMessage(('Installed translation file {}'.format(translationFile)), 'Midvatten', level=Qgis.Info) return translator else: QgsApplication.messageLog().logMessage( ("translationFile {} didn't exist, no translation file installed!".format(translationFile)), 'Midvatten', level=Qgis.Info)
class geopunt4QgisAboutDialog(QDialog): def __init__(self): QDialog.__init__(self, None) self.setWindowFlags( self.windowFlags() & ~Qt.WindowContextHelpButtonHint ) self.setWindowFlags( self.windowFlags() | Qt.WindowStaysOnTopHint) # initialize locale locale = QSettings().value("locale/userLocale", "en") if not locale: locale == 'en' else: locale = locale[0:2] localePath = os.path.join(os.path.dirname(__file__), 'i18n', 'geopunt4qgis_{}.qm'.format(locale)) if os.path.exists(localePath): self.translator = QTranslator() self.translator.load(localePath) QCoreApplication.installTranslator(self.translator) if 'en' in locale: self.htmlFile = os.path.join(os.path.dirname(__file__), 'i18n', 'about-en.html') else: #dutch is default self.htmlFile = os.path.join(os.path.dirname(__file__), 'i18n', 'about-nl.html') self._initGui() def _initGui(self): # Set up the user interface from Designer. self.ui = Ui_aboutDlg() self.ui.setupUi(self) self.ui.buttonBox.addButton( QPushButton("Sluiten"), QDialogButtonBox.RejectRole ) with open(self.htmlFile,'r', encoding="utf-8") as html: self.ui.aboutText.setHtml( html.read() )
class QConsolidatePlugin: def __init__(self, iface): self.iface = iface locale = QgsApplication.locale() qmPath = '{}/i18n/qconsolidate_{}.qm'.format(pluginPath, locale) if os.path.exists(qmPath): self.translator = QTranslator() self.translator.load(qmPath) QCoreApplication.installTranslator(self.translator) def initGui(self): self.actionRun = QAction(self.tr('QConsolidate'), self.iface.mainWindow()) self.actionRun.setIcon(QIcon(os.path.join(pluginPath, 'icons', 'qconsolidate.svg'))) self.actionRun.setObjectName('runQConsolidate') self.actionAbout = QAction(self.tr('About QConsolidate…'), self.iface.mainWindow()) self.actionAbout.setIcon(QgsApplication.getThemeIcon('/mActionHelpContents.svg')) self.actionRun.setObjectName('aboutQConsolidate') self.iface.addPluginToMenu(self.tr('QConsolidate'), self.actionRun) self.iface.addPluginToMenu(self.tr('QConsolidate'), self.actionAbout) self.iface.addToolBarIcon(self.actionRun) self.actionRun.triggered.connect(self.run) self.actionAbout.triggered.connect(self.about) self.taskManager = QgsApplication.taskManager() def unload(self): self.iface.removePluginMenu(self.tr('QConsolidate'), self.actionRun) self.iface.removePluginMenu(self.tr('QConsolidate'), self.actionAbout) self.iface.removeToolBarIcon(self.actionRun) def run(self): dlg = QConsolidateDialog() if dlg.exec_(): task = dlg.task() task.consolidateComplete.connect(self.completed) task.errorOccurred.connect(self.errored) self.taskManager.addTask(task) def about(self): d = AboutDialog() d.exec_() def tr(self, text): return QCoreApplication.translate('QConsolidate', text) def completed(self): self.iface.messageBar().pushSuccess(self.tr('QConsolidate'), self.tr('Project consolidated successfully.')) def errored(self, error): self.iface.messageBar().pushWarning(self.tr('QConsolidate'), error)
def test_qgis_translations(self): """Test that translations work.""" parent_path = os.path.join(__file__, os.pardir, os.pardir, os.pardir) dir_path = os.path.abspath(parent_path) file_path = os.path.join(dir_path, 'i18n', 'it.qm') translator = QTranslator() translator.load(file_path) QCoreApplication.installTranslator(translator) expected_message = 'Buon giorno' real_message = QCoreApplication.translate("@default", 'Good morning') self.assertEqual(real_message, expected_message)
class SeptimaGeoSearch(object): def __init__(self, iface): # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = QFileInfo(QgsApplication.qgisUserDatabaseFilePath()).path() + "/python/plugins/" + __package__ # initialize locale. Default to Danish self.config = QSettings() localePath = "" try: locale = self.config.value("locale/userLocale")[0:2] except: locale = 'da' if QFileInfo(self.plugin_dir).exists(): localePath = self.plugin_dir + "/i18n/" + locale + ".qt.qm" if QFileInfo(localePath).exists(): self.translator = QTranslator() self.translator.load(localePath) if qVersion() > '4.3.3': QgsApplication.installTranslator(self.translator) # new config method self.settings = Settings() self.options_factory = OptionsFactory(self.settings) self.options_factory.setTitle('Geosearch DK') iface.registerOptionsWidgetFactory(self.options_factory) def initGui(self): # create the widget to display information self.searchwidget = SearchBox(self.iface) # create the dockwidget with the correct parent and add the valuewidget self.searchdockwidget = QDockWidget( "Geosearch DK", self.iface.mainWindow() ) self.searchdockwidget.setObjectName("Geosearch DK") self.searchdockwidget.setWidget(self.searchwidget) # add the dockwidget to iface self.iface.addDockWidget( Qt.TopDockWidgetArea, self.searchdockwidget ) # Make changed settings apply immediately self.settings.settings_updated.connect(self.searchwidget.readconfig) def unload(self): self.searchwidget.unload() # try to avoid processing events, when QGIS is closing self.iface.removeDockWidget(self.searchdockwidget) self.iface.unregisterOptionsWidgetFactory(self.options_factory)
class Photo2ShapePlugin: def __init__(self, iface): self.iface = iface locale = QgsApplication.locale() qmPath = "{}/i18n/photo2shape_{}.qm".format(pluginPath, locale) if os.path.exists(qmPath): self.translator = QTranslator() self.translator.load(qmPath) QCoreApplication.installTranslator(self.translator) def initGui(self): self.actionRun = QAction(self.tr("Photo2Shape"), self.iface.mainWindow()) self.actionRun.setIcon( QIcon(os.path.join(pluginPath, "icons", "photo2shape.png"))) self.actionRun.setObjectName("runPhoto2Shape") self.actionAbout = QAction(self.tr("About Photo2Shape…"), self.iface.mainWindow()) self.actionAbout.setIcon( QgsApplication.getThemeIcon("/mActionHelpContents.svg")) self.actionRun.setObjectName("aboutPhoto2Shape") self.iface.addPluginToVectorMenu(self.tr("Photo2Shape"), self.actionRun) self.iface.addPluginToVectorMenu(self.tr("Photo2Shape"), self.actionAbout) self.iface.addVectorToolBarIcon(self.actionRun) self.actionRun.triggered.connect(self.run) self.actionAbout.triggered.connect(self.about) def unload(self): self.iface.removePluginVectorMenu(self.tr("Photo2Shape"), self.actionRun) self.iface.removePluginVectorMenu(self.tr("Photo2Shape"), self.actionAbout) self.iface.removeVectorToolBarIcon(self.actionRun) def run(self): dlg = Photo2ShapeDialog(self.iface) dlg.show() dlg.exec_() def about(self): d = AboutDialog() d.exec_() def tr(self, text): return QCoreApplication.translate("Photo2Shape", text)
def test_qgis_translations(self): """Test that translations work.""" parent_path = os.path.join(__file__, os.path.pardir, os.path.pardir) dir_path = os.path.abspath(parent_path) file_path = os.path.join( dir_path, 'i18n', 'af.qm') translator = QTranslator() translator.load(file_path) QCoreApplication.installTranslator(translator) expected_message = 'Goeie more' real_message = QCoreApplication.translate("@default", 'Good morning') self.assertEqual(real_message, expected_message)
def test_qgis_translations(self): """Test that translations work.""" parent_path = os.path.join(__file__, os.path.pardir, os.path.pardir) dir_path = os.path.abspath(parent_path) file_path = os.path.join(dir_path, "i18n", "isogeo_search_engine_fr.qm") translator = QTranslator() translator.load(file_path) QCoreApplication.installTranslator(translator) expected_message = "Recherches rapides" real_message = QCoreApplication.translate("Isogeo", "Quicksearches") self.assertEqual(real_message, expected_message)
def test_qgis_translations(self): """Test for qgis translations.""" file_path = safe_dir('i18n/inasafe_id.qm') translator = QTranslator() translator.load(file_path) QCoreApplication.installTranslator(translator) expected_message = ( 'Tidak ada informasi gaya yang ditemukan pada lapisan %s') real_message = QCoreApplication.translate( '@default', 'No styleInfo was found for layer %s') message = 'expected %s but got %s' % (expected_message, real_message) self.assertEqual(expected_message, real_message, message)
class NavTablePlugin(QObject): def __init__(self, iface): super().__init__() # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value("locale/userLocale")[0:2] localePath = os.path.join(self.plugin_dir, 'i18n', 'navtable_{}.qm'.format(locale)) if os.path.exists(localePath): self.translator = QTranslator() self.translator.load(localePath) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) def initGui(self): # Create action that will start plugin configuration icon_path = os.path.join(self.plugin_dir, 'icon', 'icon.png') self.action = QAction( QIcon(icon_path), u"Navtable", self.iface.mainWindow()) # connect the action to the run method self.action.triggered.connect(self.run) # Add toolbar button and menu item self.iface.addToolBarIcon(self.action) self.iface.addPluginToMenu(u"&Navtable", self.action) def unload(self): # Remove the plugin menu item and icon self.iface.removePluginMenu(u"&Navtable", self.action) self.iface.removeToolBarIcon(self.action) def run(self): self.layer = self.iface.activeLayer() # Comprobamos si existe alguna capa y si esta es vectorial if self.layer is None or not isinstance(self.layer, QgsVectorLayer): self.iface.messageBar().pushMessage("Invalid Layer", "NavTable only works on a vector layer", level=Qgis.Warning) else: self.dlg = NTMainPanel(self.iface, self.layer) self.dlg.show() self.dlg.exec_()
class GeoHealthPlugin(object): def __init__(self, iface): self.iface = iface self.plugin_dir = dirname(__file__) # initialize locale locale = QSettings().value("locale/userLocale")[0:2] locale_path = join(self.plugin_dir, 'i18n', 'GeoHealth_{}.qm'.format(locale)) if exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': # noinspection PyCallByClass,PyTypeChecker,PyArgumentList QCoreApplication.installTranslator(self.translator) self.plugin_menu = None self.geohealth_menu = None self.main_action = None self.xy_action = None self.blur_action = None self.incidence_action = None self.density_action = None self.histogram_action = None # Add to processing self.provider = Provider() Processing.addProvider(self.provider, True) def initGui(self): self.plugin_menu = self.iface.pluginMenu() # Main window icon = QIcon(resource('icon-32.png')) self.main_action = QAction(icon, 'GeoHealth', self.iface.mainWindow()) self.plugin_menu.addAction(self.main_action) # noinspection PyUnresolvedReferences self.main_action.triggered.connect(self.open_main_window) def unload(self): self.plugin_menu.removeAction(self.main_action) Processing.removeProvider(self.provider) @staticmethod def open_main_window(): dialog = MainDialog() dialog.show() dialog.exec_()
class SeptimaGeoSearch(object): def __init__(self, iface): # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = QFileInfo(QgsApplication.qgisUserDatabaseFilePath() ).path() + "/python/plugins/" + __package__ # initialize locale. Default to Danish self.config = QSettings() localePath = "" try: locale = self.config.value("locale/userLocale")[0:2] except: locale = 'da' if QFileInfo(self.plugin_dir).exists(): localePath = self.plugin_dir + "/i18n/" + locale + ".qt.qm" if QFileInfo(localePath).exists(): self.translator = QTranslator() self.translator.load(localePath) if qVersion() > '4.3.3': QgsApplication.installTranslator(self.translator) # new config method self.settings = Settings() self.options_factory = OptionsFactory(self.settings) self.options_factory.setTitle('Geosearch DK') iface.registerOptionsWidgetFactory(self.options_factory) def initGui(self): # create the widget to display information self.searchwidget = SearchBox(self.iface) # create the dockwidget with the correct parent and add the valuewidget self.searchdockwidget = QDockWidget("Geosearch DK", self.iface.mainWindow()) self.searchdockwidget.setObjectName("Geosearch DK") self.searchdockwidget.setWidget(self.searchwidget) # add the dockwidget to iface self.iface.addDockWidget(Qt.TopDockWidgetArea, self.searchdockwidget) # Make changed settings apply immediately self.settings.settings_updated.connect(self.searchwidget.readconfig) def unload(self): self.searchwidget.unload( ) # try to avoid processing events, when QGIS is closing self.iface.removeDockWidget(self.searchdockwidget) self.iface.unregisterOptionsWidgetFactory(self.options_factory)
class QgisCloudPlugin(object): def __init__(self, iface, version): # Save reference to the QGIS interface self.iface = iface self.version = version def initGui(self): # Create action that will start plugin configuration self.action = QAction(QIcon(":/plugins/qgiscloud/icon.png"), \ "Cloud Settings", self.iface.mainWindow()) self.action.triggered.connect(self.showHideDockWidget) # Add toolbar button and menu item self.iface.addToolBarIcon(self.action) self.iface.addPluginToMenu("&Cloud", self.action) self.plugin_dir = os.path.dirname(__file__) # initialize locale locale_short = QSettings().value("locale/userLocale", type=str)[0:2] locale_long = QSettings().value("locale/userLocale", type=str) if QFileInfo(self.plugin_dir).exists(): if QFileInfo(self.plugin_dir + "/i18n/qgiscloudplugin_" + locale_short + ".qm").exists(): self.translator = QTranslator() self.translator.load( self.plugin_dir + "/i18n/qgiscloudplugin_" + locale_short + ".qm") if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) elif QFileInfo(self.plugin_dir + "/i18n/qgiscloudplugin_" + locale_long + ".qm").exists(): self.translator = QTranslator() self.translator.load( self.plugin_dir + "/i18n/qgiscloudplugin_" + locale_long + ".qm") if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # # dock widget self.dockWidget = QgisCloudPluginDialog(self.iface, self.version) self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dockWidget) def unload(self): # Remove the plugin menu item and icon self.iface.removePluginMenu("&Cloud",self.action) self.iface.removeToolBarIcon(self.action) self.dockWidget.unload() self.iface.removeDockWidget(self.dockWidget) def showHideDockWidget(self): if self.dockWidget.isVisible(): self.dockWidget.hide() else: self.dockWidget.show()
class RProviderPlugin: """QGIS Plugin Implementation.""" def __init__(self, iface: QgisInterface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ super().__init__() # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', '{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) QCoreApplication.installTranslator(self.translator) # processing framework self.provider = RAlgorithmProvider() @staticmethod def tr(message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('RProvider', message) def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" QgsApplication.processingRegistry().addProvider(self.provider) def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" QgsApplication.processingRegistry().removeProvider(self.provider)
class Interlis: def __init__(self, iface): # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value("locale/userLocale")[0:2] localePath = os.path.join(self.plugin_dir, 'i18n', 'interlis_{}.qm'.format(locale)) if os.path.exists(localePath): self.translator = QTranslator() self.translator.load(localePath) QCoreApplication.installTranslator(self.translator) if ogr_version_num() < 2000200: raise ImportError("GDAL/OGR 2.0.2 or newer required") # Create the dialog (after translation) and keep reference self.dlg = InterlisDialog(self) # Processing provider self.provider = InterlisProvider() def initGui(self): # Create action that will start plugin configuration self.action = QAction(QIcon(":/plugins/interlis/icon.png"), u"Interlis", self.iface.mainWindow()) # connect the action to the run method self.action.triggered.connect(self.run) # Add toolbar button and menu item self.iface.addToolBarIcon(self.action) self.iface.addPluginToMenu(u"&Interlis", self.action) QgsApplication.processingRegistry().addProvider(self.provider) def unload(self): QgsApplication.processingRegistry().removeProvider(self.provider) # Remove the plugin menu item and icon self.iface.removePluginMenu(u"&Interlis", self.action) self.iface.removeToolBarIcon(self.action) def messageLogWidget(self): return self.iface.mainWindow().findChild(QDockWidget, 'MessageLog') def run(self): self.dlg.setup() self.dlg.exec_()
class Translate(): def __init__(self, pluginName): def getFile(): overrideLocale = QSettings().value('locale/overrideFlag', False, type=bool) localeFullName = QLocale.system().name() if not overrideLocale else QSettings().value('locale/userLocale', '') qmPathFile = "i18n/{0}_{1}.qm".format( pluginName, localeFullName ) pluginPath = os.path.dirname(__file__) translationFile = "{}/{}".format( pluginPath, qmPathFile ) return translationFile self.translator = None translationFile = getFile() if QFileInfo( translationFile ).exists(): self.translator = QTranslator() self.translator.load( translationFile ) QCoreApplication.installTranslator( self.translator )
def test_qgis_translations(self): """Test that translations work.""" parent_path = os.path.join(__file__, os.path.pardir, os.path.pardir) dir_path = os.path.abspath(parent_path) file_path = os.path.join(dir_path, 'i18n', 'af.qm') self.assertTrue( os.path.isfile(file_path), "%s is not a valid translation file or it does not exist" % file_path) translator = QTranslator() translator.load(file_path) QCoreApplication.installTranslator(translator) expected_message = 'Goeie more' real_message = QCoreApplication.translate("@default", 'Good morning') self.assertEqual(real_message, expected_message)
class GeocatBridge: def __init__(self, iface): self.iface = iface readServers() self.provider = BridgeProvider() self.pluginFolder = os.path.dirname(__file__) localePath = "" self.locale = QSettings().value("locale/userLocale")[0:2] if os.path.exists(self.pluginFolder): localePath = os.path.join(self.pluginFolder, "i18n", "bridge_" + self.locale + ".qm") self.translator = QTranslator() if os.path.exists(localePath): self.translator.load(localePath) QCoreApplication.installTranslator(self.translator) def initGui(self): iconPublish = QIcon( os.path.join(os.path.dirname(__file__), "icons", "publish_button.png")) self.actionPublish = QAction( iconPublish, QCoreApplication.translate("GeocatBridge", "Publish"), self.iface.mainWindow()) self.actionPublish.setObjectName("startPublish") self.actionPublish.triggered.connect(self.publishClicked) self.iface.addPluginToWebMenu("GeoCatBridge", self.actionPublish) self.iface.addWebToolBarIcon(self.actionPublish) QgsApplication.processingRegistry().addProvider(self.provider) def unload(self): removeTempFolder() self.iface.removePluginWebMenu("GeoCatBridge", self.actionPublish) self.iface.removeWebToolBarIcon(self.actionPublish) QgsApplication.processingRegistry().removeProvider(self.provider) def publishClicked(self): dialog = BridgeDialog(self.iface.mainWindow()) dialog.exec_()
def getTranslate(namePlugin, nameDir=None): if nameDir is None: nameDir = namePlugin pluginPath = os.path.join('python', 'plugins', nameDir) userPath = QFileInfo(QgsApplication.qgisUserDatabaseFilePath()).path() userPluginPath = os.path.join(userPath, pluginPath) systemPath = QgsApplication.prefixPath() systemPluginPath = os.path.join(systemPath, pluginPath) pp = userPluginPath if QFileInfo(userPluginPath).exists() else systemPluginPath overrideLocale = QSettings().value('locale/overrideFlag', False, type=bool) if overrideLocale: qmPathFilepattern = os.path.join('i18n', '{0}_{1}_*.qm'.format(namePlugin, QSettings().value('locale/userLocale', ''))) qmfiles = glob.glob(os.path.join(pp, qmPathFilepattern)) if qmfiles: translationFile = sorted(qmfiles)[0] QgsApplication.messageLog().logMessage( ("QGIS location overried is activated. Using the first found translationfile for pattern {}.".format(qmPathFilepattern)), 'Midvatten', level=Qgis.Info) else: QgsApplication.messageLog().logMessage( ("QGIS location overried is activated. No translation file found using pattern {}, no translation file installed!".format(qmPathFilepattern)), 'Midvatten', level=Qgis.Info) return else: localeFullName = QLocale.system().name() qmPathFile = os.path.join('i18n', '{0}_{1}.qm'.format(namePlugin, localeFullName)) translationFile = os.path.join(pp, qmPathFile) if QFileInfo(translationFile).exists(): translator = QTranslator() translator.load(translationFile) QCoreApplication.installTranslator(translator) QgsApplication.messageLog().logMessage(('Installed translation file {}'.format(translationFile)), 'Midvatten', level=Qgis.Info) return translator else: QgsApplication.messageLog().logMessage( ("translationFile {} didn't exist, no translation file installed!".format(translationFile)), 'Midvatten', level=Qgis.Info)
class StatistPlugin: def __init__(self, iface): self.iface = iface locale = QgsApplication.locale() qmPath = "{}/i18n/statist_{}.qm".format(pluginPath, locale) if os.path.exists(qmPath): self.translator = QTranslator() self.translator.load(qmPath) QCoreApplication.installTranslator(self.translator) def initGui(self): self.actionRun = QAction(self.tr("Statist"), self.iface.mainWindow()) self.actionRun.setIcon(QIcon(os.path.join(pluginPath, "icons", "statist.png"))) self.actionRun.setObjectName("runStatist") self.iface.registerMainWindowAction(self.actionRun, "Shift+S") self.actionAbout = QAction(self.tr("About Statist…"), self.iface.mainWindow()) self.actionAbout.setIcon(QgsApplication.getThemeIcon("/mActionHelpContents.svg")) self.actionRun.setObjectName("aboutStatist") self.iface.addPluginToVectorMenu(self.tr("Statist"), self.actionRun) self.iface.addPluginToVectorMenu(self.tr("Statist"), self.actionAbout) self.iface.addVectorToolBarIcon(self.actionRun) self.actionRun.triggered.connect(self.run) self.actionAbout.triggered.connect(self.about) def unload(self): self.iface.unregisterMainWindowAction(self.actionRun) self.iface.removePluginVectorMenu(self.tr("Statist"), self.actionRun) self.iface.removePluginVectorMenu(self.tr("Statist"), self.actionAbout) self.iface.removeVectorToolBarIcon(self.actionRun) def run(self): dlg = StatistDialog() dlg.show() dlg.exec_() def about(self): d = AboutDialog() d.exec_() def tr(self, text): return QCoreApplication.translate("Statist", text)
def init(self, logo, title, **kwargs): from qgis.core import QgsApplication from qgis.PyQt.QtWidgets import QApplication from qgis.PyQt.QtGui import QFont, QIcon from qgis.PyQt.QtCore import QLocale, QTranslator try: import qgis.PyQt.QtSql except ImportError: pass # In python3 we need to convert to a bytes object (or should # QgsApplication accept a QString instead of const char* ?) try: argvb = list(map(os.fsencode, sys.argv)) except AttributeError: argvb = sys.argv self.app = QgsApplication(argvb, True) QgsApplication.setPrefixPath(self.prefixpath, True) QgsApplication.initQgis() locale = QLocale.system().name() self.translationFile = os.path.join(self.i18npath, '{0}.qm'.format(locale)) translator = QTranslator() translator.load(self.translationFile, "i18n") self.app.installTranslator(translator) QApplication.setStyle("Plastique") QApplication.setFont(QFont('Segoe UI')) QApplication.setWindowIcon(QIcon(logo)) QApplication.setApplicationName(title) import roam.editorwidgets.core if "register_widgets" not in kwargs: register_widgets = True else: register_widgets = False if register_widgets: roam.editorwidgets.core.registerallwidgets() import roam.qgisfunctions return self
def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface self.canvas = iface.mapCanvas() self.provider = NoaaTidalPredictionsProvider() self.toolbar = self.iface.addToolBar('NOAA Tidal Predictions Toolbar') self.toolbar.setObjectName('NoaaTidalPredictionsToolbar') # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join( self.plugin_dir, 'i18n', 'NoaaTidalPredictions_{}.qm'.format(locale)) if os.path.exists(locale_path): translator = QTranslator() translator.load(locale_path) QCoreApplication.installTranslator(translator) # Declare instance attributes self.actions = [] self.menu = tr(u'&NOAA Tidal Predictions') self.dock = TidalPredictionWidget(None, self.canvas) self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dock) self.dock.hide() self.predictionTool = None QgsApplication.processingRegistry().addProvider(self.provider) PredictionExpressions.registerFunctions()
def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface self.canvas = iface.mapCanvas() self.provider = CompassRoutesProvider() self.toolbar = self.iface.addToolBar('Compass Routes Toolbar') self.toolbar.setObjectName('CompassRoutesToolbar') # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'CompassRoutes_{}.qm'.format(locale)) if os.path.exists(locale_path): translator = QTranslator() translator.load(locale_path) QCoreApplication.installTranslator(translator) # Declare instance attributes self.actions = [] self.menu = tr(u'&Compass Routes') # Check if plugin was started the first time in current QGIS session # Must be set in initGui() to survive plugin reloads self.route_needs_init = None QgsApplication.processingRegistry().addProvider(self.provider) # Add custom functions to compute the magnetic variation at a point, or for a line QgsExpression.registerFunction(self.magnetic_variation) QgsExpression.registerFunction(self.to_magnetic)
class Translate(): def __init__(self, pluginName): def getFile(): overrideLocale = QSettings().value('locale/overrideFlag', False, type=bool) localeFullName = QLocale.system().name( ) if not overrideLocale else QSettings().value( 'locale/userLocale', '') qmPathFile = f"i18n/{pluginName}_{localeFullName}.qm" pluginPath = os.path.dirname(__file__) translationFile = f"{pluginPath}/{qmPathFile}" return translationFile self.translator = None translationFile = getFile() if QFileInfo(translationFile).exists(): self.translator = QTranslator() self.translator.load(translationFile) QCoreApplication.installTranslator(self.translator)
class ImageLegendWidgetPlugin: """QGIS Plugin Implementation.""" def __init__(self, iface: QgisInterface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ super().__init__() # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QgsApplication.locale() locale_path = os.path.join(self.plugin_dir, 'i18n', '{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) QCoreApplication.installTranslator(self.translator) self.provider = None def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" self.provider = ImageLegendProvider() QgsGui.layerTreeEmbeddedWidgetRegistry().addProvider(self.provider) def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" QgsGui.layerTreeEmbeddedWidgetRegistry().removeProvider( self.provider.id()) self.provider = None #=========================================================================================
class VisualistPlugin(object): def __init__(self): # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] log('Locale: {}'.format(locale)) log('Plugin directory: {}'.format(self.plugin_dir)) locale_path = os.path.join(self.plugin_dir, 'i18n', 'visualist_{}.qm'.format(locale)) log('Translation file: {}'.format(locale_path)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) log('Translator added') #Store settings used by the plugin s = QgsSettings() s.setValue("visualist/homepage", "https://ipsac2.unil.ch/main/") yaml_path = os.path.join(self.plugin_dir, 'visualist.yaml') yaml_stream = open(yaml_path, 'r') yaml_document = yaml.safe_load(yaml_stream) for helper in yaml_document: s.setValue("visualist/help/" + helper, yaml_document[helper]) #initialize provider self.provider = VisualistProvider() def initGui(self): QgsApplication.processingRegistry().addProvider(self.provider) def unload(self): QgsApplication.processingRegistry().removeProvider(self.provider)
class RasterTransparencyPlugin: def __init__(self, iface): self.iface = iface locale = QgsApplication.locale() qmPath = "{}/i18n/rastertransparency_{}.qm".format(pluginPath, locale) if os.path.exists(qmPath): self.translator = QTranslator() self.translator.load(qmPath) QCoreApplication.installTranslator(self.translator) self.factory = TransparencyPanelFactory() def initGui(self): self.actionAbout = QAction(self.tr("About RasterTransparency…"), self.iface.mainWindow()) self.actionAbout.setIcon(QgsApplication.getThemeIcon("/mActionHelpContents.svg")) self.actionAbout.setObjectName("aboutRasterTransparency") self.actionAbout.triggered.connect(self.about) self.iface.addPluginToRasterMenu(self.tr("Raster transparency"), self.actionAbout) self.iface.registerMapLayerConfigWidgetFactory(self.factory) def unload(self): self.iface.removePluginRasterMenu(self.tr("Raster transparency"), self.actionAbout) self.iface.unregisterMapLayerConfigWidgetFactory(self.factory) def about(self): d = AboutDialog() d.exec_() def tr(self, text): return QCoreApplication.translate("RasterTransparency", text)
def setup_i18n(the_preferred_locale=None): """ Setup internationalisation for the plugin. See if QGIS wants to override the system locale and then see if we can get a valid translation file for whatever locale is effectively being used. @param the_preferred_locale will override any other locale setting """ logger = logging.getLogger(__name__) my_override_flag = QSettings().value('locale/overrideFlag', False, type=bool) my_locale_name = None if the_preferred_locale is not None: my_locale_name = the_preferred_locale logger.info('Using preferred locale: ' + my_locale_name) elif my_override_flag: my_locale_name = QSettings().value('locale/userLocale', '') logger.info('Using QGIS override locale: ' + my_locale_name) else: my_locale_name = QLocale.system().name() # NOTES: we split the locale name because we need the first two # character i.e. 'id', 'af, etc my_locale_name = str(my_locale_name) logger.info('Using system default locale: ' + my_locale_name) # Insert into QT's translation system # As soon as translator gets deleted, the translation will stop # Therefore, QCoreApplication is set as parent to not delete it # while the application is running (but we might end up loading # the same translation twice) translator = QTranslator(QCoreApplication.instance()) my_translator_file = 'qgepplugin_' + my_locale_name my_result = translator.load(my_translator_file, 'i18n') if my_result: QCoreApplication.instance().installTranslator(translator)
class AzimuthDistanceCalculator(object): def __init__(self, iface): # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value("locale/userLocale")[0:2] localePath = os.path.join(self.plugin_dir, 'i18n', 'azimuthdistancecalculator_{}.qm'.format(locale)) if os.path.exists(localePath): self.translator = QTranslator() self.translator.load(localePath) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Create the dialog (after translation) and keep reference self.dlg = AzimuthDistanceCalculatorDialog(self.iface) # Obtaining the map canvas self.canvas = iface.mapCanvas() # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('azimuthdistancecalculator', message) def initGui(self): # Create action that will start plugin configuration self.action = QAction( QIcon(":/plugins/azimuthdistancecalculator/north.png"), self.tr("Calculator"), self.iface.mainWindow()) # connect the action to the run method self.action.triggered.connect(self.run) # Add toolbar button and menu item self.iface.addToolBarIcon(self.action) self.iface.addPluginToMenu(self.tr("Azimuth and Distance Calculator"), self.action) def unload(self): # Remove the plugin menu item and icon self.iface.removePluginMenu(self.tr("Azimuth and Distance Calculator"), self.action) self.iface.removeToolBarIcon(self.action) # run method that performs all the real work def run(self): # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result == 1: # do something useful (delete the line containing pass and # substitute with your code) pass
class geopunt4QgisPoidialog(QDialog): def __init__(self, iface): QDialog.__init__(self, None) self.setWindowFlags( self.windowFlags() & ~Qt.WindowContextHelpButtonHint ) #self.setWindowFlags( self.windowFlags() |Qt.WindowStaysOnTopHint) self.iface = iface # initialize locale locale = QSettings().value("locale/userLocale", "nl") if not locale: locale == 'nl' else: locale = locale[0:2] localePath = os.path.join(os.path.dirname(__file__), 'i18n', 'geopunt4qgis_{}.qm'.format(locale)) if os.path.exists(localePath): self.translator = QTranslator() self.translator.load(localePath) QCoreApplication.installTranslator(self.translator) self._initGui() def _initGui(self): 'Set up the user interface from Designer.' self.ui = Ui_geopunt4QgisPoiDlg() self.ui.setupUi(self) #get settings self.s = QSettings() self.loadSettings() #setup geopunt and geometryHelper objects self.gh = geometryHelper(self.iface) self.ph = poiHelper( self.iface) #create the graphicsLayer self.graphicsLayer = [] #setup a message bar self.bar = QgsMessageBar() self.bar.setSizePolicy( QSizePolicy.Minimum, QSizePolicy.Fixed ) self.ui.verticalLayout.addWidget(self.bar) self.ui.buttonBox.addButton( QPushButton("Sluiten"), QDialogButtonBox.RejectRole ) for btn in self.ui.buttonBox.buttons(): btn.setAutoDefault(0) #table ui self.ui.resultLijst.hideColumn(0) # filters self.firstShow = True self.poiTypes = {} self.poiCategories = {} self.poiThemes = {} #actions self.ui.resultLijst.addAction( self.ui.actionZoomtoSelection ) self.ui.actionZoomtoSelection.triggered.connect( self.onZoomSelClicked) self.ui.resultLijst.addAction( self.ui.actionAddTSeltoMap ) self.ui.actionAddTSeltoMap.triggered.connect( self.onAddSelClicked) #event handlers self.ui.zoekKnop.clicked.connect(self.onZoekActivated) self.ui.zoomSelKnop.clicked.connect(self.onZoomSelClicked) self.ui.resultLijst.itemDoubleClicked.connect(self.onZoomSelClicked ) self.ui.resultLijst.itemSelectionChanged.connect(self.onSelectionChanged) self.ui.addToMapKnop.clicked.connect(self.onAddSelClicked) self.ui.addMinModelBtn.clicked.connect( self.addMinModel ) self.ui.poiText.textChanged.connect( self.searchTxtChanged ) self.ui.buttonBox.helpRequested.connect(self.openHelp) self.finished.connect(self.clean ) def loadSettings(self): self.saveToFile = int( self.s.value("geopunt4qgis/poiSavetoFile" , 1)) layerName = self.s.value("geopunt4qgis/poilayerText", "") if layerName: self.layerName= layerName self.timeout = int( self.s.value("geopunt4qgis/timeout" ,15)) if settings().proxyUrl: self.proxy = settings().proxyUrl else: self.proxy = "" self.startDir = self.s.value("geopunt4qgis/startDir", os.path.expanduser("~") ) self.poi = Poi(self.timeout, self.proxy) def show(self): QDialog.show(self) self.setWindowModality(0) if self.firstShow: inet = internet_on(proxyUrl=self.proxy, timeout=self.timeout) #filters if inet: self.poiThemes = dict( self.poi.listPoiThemes() ) poiThemes = [""] + list(self.poiThemes.keys()) poiThemes.sort() self.ui.filterPoiThemeCombo.addItems( poiThemes ) self.poiCategories = dict( self.poi.listPoiCategories() ) poiCategories = [""] + list(self.poiCategories.keys()) poiCategories.sort() self.ui.filterPoiCategoryCombo.addItems( poiCategories ) self.poiTypes = dict( self.poi.listPoitypes() ) poiTypes = [""] + list(self.poiTypes.keys()) poiTypes.sort() self.ui.filterPoiTypeCombo.addItems( poiTypes ) gemeentes = json.load( open(os.path.join(os.path.dirname(__file__), "data/gemeentenVL.json")) ) self.NIScodes= { n["Naam"] : n["Niscode"] for n in gemeentes } gemeenteNamen = [n["Naam"] for n in gemeentes] gemeenteNamen.sort() self.ui.filterPoiNIS.addItems( gemeenteNamen ) #connect when inet on self.ui.filterPoiThemeCombo.activated.connect(self.onThemeFilterChange) self.ui.filterPoiCategoryCombo.activated.connect(self.onCategorieFilterChange) self.firstShow = False else: self.bar.pushMessage( QCoreApplication.translate("geopunt4QgisPoidialog", "Waarschuwing "), QCoreApplication.translate("geopunt4QgisPoidialog", "Kan geen verbing maken met het internet."), level=Qgis.Warning, duration=3) def openHelp(self): webbrowser.open_new_tab("http://www.geopunt.be/voor-experts/geopunt-plug-ins/functionaliteiten/poi") def onZoekActivated(self): txt = self.ui.poiText.text() self.ui.resultLijst.clearContents() self.ui.resultLijst.setRowCount(0) self.ui.msgLbl.setText("") ##filters: poithemeText = self.ui.filterPoiThemeCombo.currentText() if poithemeText != "": poitheme = self.poiThemes[ poithemeText ] else: poitheme = "" poiCategorieText = self.ui.filterPoiCategoryCombo.currentText() if poiCategorieText != "": poiCategorie = self.poiCategories[ poiCategorieText ] else: poiCategorie = "" poiTypeText = self.ui.filterPoiTypeCombo.currentText() if poiTypeText!= "": poiType = self.poiTypes[ poiTypeText ] else: poiType = "" NISText= self.ui.filterPoiNIS.currentText() if NISText != "" and not self.ui.currentBoundsVink.isChecked(): Niscode = self.NIScodes[NISText] else: Niscode = "" if self.ui.currentBoundsVink.isChecked(): bbox = self.iface.mapCanvas().extent() minX, minY = self.gh.prjPtFromMapCrs([bbox.xMinimum(),bbox.yMinimum()], 4326) maxX, maxY = self.gh.prjPtFromMapCrs([bbox.xMaximum(),bbox.yMaximum()], 4326) xyBox = [minX, minY, maxX, maxY] self.poi.fetchPoi( txt, c=32, srs=4326 , maxModel=True, updateResults=True, bbox=xyBox, theme=poitheme , category=poiCategorie, POItype=poiType ) else: self.poi.fetchPoi( txt, c=32, srs=4326 , maxModel=True, updateResults=True, bbox=None, theme=poitheme , category=poiCategorie, POItype=poiType, region=Niscode ) suggesties = self.poi.poiSuggestion() if type(suggesties) is list: #prevent sorting every time an item is added self.ui.resultLijst.setSortingEnabled(False) row =0 for sug in suggesties: id = QTableWidgetItem( sug[0], 0 ) theme = QTableWidgetItem( sug[1], 0 ) categorie = QTableWidgetItem( sug[2], 0 ) PoiType = QTableWidgetItem( sug[3], 0 ) naam = QTableWidgetItem( sug[4], 0 ) straat = QTableWidgetItem( sug[5], 0) huisnr = QTableWidgetItem( sug[6], 0) busnr = QTableWidgetItem( sug[7], 0) postcode = QTableWidgetItem( sug[8], 0) gemeente = QTableWidgetItem( sug[9], 0) self.ui.resultLijst.insertRow(row) self.ui.resultLijst.setItem(row, 0, id) self.ui.resultLijst.setItem(row, 1, theme) self.ui.resultLijst.setItem(row, 2, categorie) self.ui.resultLijst.setItem(row, 3, PoiType) self.ui.resultLijst.setItem(row, 4, naam) self.ui.resultLijst.setItem(row, 5, straat) self.ui.resultLijst.setItem(row, 6, huisnr) self.ui.resultLijst.setItem(row, 7, busnr) self.ui.resultLijst.setItem(row, 8, postcode) self.ui.resultLijst.setItem(row, 9, gemeente) row += 1 self.ui.resultLijst.setSortingEnabled(True) if self.poi.resultCount > 0: self.ui.msgLbl.setText(QCoreApplication.translate("geopunt4QgisPoidialog", "Aantal getoond: %s gevonden: %s" % ( self.ui.resultLijst.rowCount() , self.poi.resultCount ) )) elif self.poi.resultCount == 0: self.bar.pushMessage( QCoreApplication.translate("geopunt4QgisPoidialog", "Geen resultaten gevonden voor deze zoekopdracht"), "", level=Qgis.Info, duration=10) elif self.poi.resultCount < 0: self.bar.pushMessage(QCoreApplication.translate("geopunt4QgisPoidialog", "Het aantal gevonden kon niet worden bepaald, te complexe zoekopdracht"), "", level=Qgis.Info, duration=10) self.ui.msgLbl.setText(QCoreApplication.translate("geopunt4QgisPoidialog", "Aantal getoond: %s, aantal gevonden niet bepaald" % self.ui.resultLijst.rowCount() ) ) elif type( suggesties ) is str: self.bar.pushMessage( QCoreApplication.translate("geopunt4QgisPoidialog","Waarschuwing"), suggesties, level=Qgis.Warning) else: self.bar.pushMessage("Error", QCoreApplication.translate("geopunt4QgisPoidialog","onbekende fout"), level=Qgis.Critical) def onZoomSelClicked(self): if not len( self.ui.resultLijst.selectedIndexes() ): self.bar.pushMessage("", QCoreApplication.translate("geopunt4QgisPoidialog", "Er zijn geen records geselecteerd"), level=Qgis.Warning ) return selPois = self._getSelectedPois() if len(selPois) <= 0 : self.bar.pushMessage( QCoreApplication.translate("geopunt4QgisPoidialog", "Merk op"), QCoreApplication.translate("geopunt4QgisPoidialog", "Er niets om naar te zoomen"), level=Qgis.Info, duration=3) elif len(selPois) >= 2: pts = [n['location']['points'][0]['Point']['coordinates'] for n in selPois ] bounds = self.gh.getBoundsOfPointArray(pts) self.gh.zoomtoRec(bounds[:2], bounds[2:4], 4326) elif len(selPois) == 1: x, y = selPois[0]['location']['points'][0]['Point']['coordinates'] bounds = self.gh.getBoundsOfPoint(x,y) self.gh.zoomtoRec(bounds[:2], bounds[2:4], 4326) def onSelectionChanged(self): selPois = self._getSelectedPois() canvas = self.iface.mapCanvas() self.clearGraphicsLayer() pts = [ self.gh.prjPtToMapCrs( n['location']['points'][0]['Point']['coordinates'], 4326) for n in selPois ] for pt in pts: x,y = pt m = QgsVertexMarker(canvas) self.graphicsLayer.append(m) m.setCenter(QgsPointXY(x,y)) m.setColor(QColor(255,255,0)) m.setIconSize(1) m.setIconType(QgsVertexMarker.ICON_BOX) m.setPenWidth(10) def onAddSelClicked(self): if not len( self.ui.resultLijst.selectedIndexes() ): self.bar.pushMessage("", QCoreApplication.translate("geopunt4QgisPoidialog", "Er zijn geen records geselecteerd"), level=Qgis.Warning ) return if not self.layernameValid(): return self.clearGraphicsLayer() pts = self._getSelectedPois() self.ph.save_pois_points( pts , layername=self.layerName, startFolder= os.path.join(self.startDir, self.layerName), saveToFile=self.saveToFile, sender=self ) def onThemeFilterChange(self): poithemeText = self.ui.filterPoiThemeCombo.currentText() if poithemeText != "": poithemeID = self.poiThemes[ poithemeText ] poiCategories = [""] + [n[0] for n in self.poi.listPoiCategories(poithemeID)] poiCategories.sort() self.ui.filterPoiCategoryCombo.clear() self.ui.filterPoiTypeCombo.clear() self.ui.filterPoiCategoryCombo.addItems( poiCategories ) else: self.ui.filterPoiCategoryCombo.addItems([""] + list(self.poiCategories.keys())) self.ui.filterPoiTypeCombo.addItems([""] + list(self.poiTypes.keys())) def onCategorieFilterChange(self): poithemeText = self.ui.filterPoiThemeCombo.currentText() poiCategorieText = self.ui.filterPoiCategoryCombo.currentText() if poiCategorieText != "" and poithemeText != "": poiCategorieID = self.poiCategories[ poiCategorieText ] poithemeID = self.poiThemes[ poithemeText ] poiTypes = [""] + [n[0] for n in self.poi.listPoitypes(poithemeID, poiCategorieID)] poiTypes.sort() self.ui.filterPoiTypeCombo.clear() self.ui.filterPoiTypeCombo.addItems( poiTypes ) def addMinModel(self): if not self.layernameValid(): return self.clearGraphicsLayer() txt = self.ui.poiText.text() poithemeText = self.ui.filterPoiThemeCombo.currentText() if poithemeText != "": poitheme = self.poiThemes[ poithemeText ] else: poitheme = "" poiCategorieText = self.ui.filterPoiCategoryCombo.currentText() if poiCategorieText != "": poiCategorie = self.poiCategories[ poiCategorieText ] else: poiCategorie = "" poiTypeText = self.ui.filterPoiTypeCombo.currentText() if poiTypeText!= "": poiType = self.poiTypes[ poiTypeText ] else: poiType = "" NISText= self.ui.filterPoiNIS.currentText() if NISText != "" and not self.ui.currentBoundsVink.isChecked(): Niscode = self.NIScodes[NISText] else: Niscode = "" cluster = self.ui.clusterCheck.isChecked() if self.ui.currentBoundsVink.isChecked(): bbox = self.iface.mapCanvas().extent() minX, minY = self.gh.prjPtFromMapCrs([bbox.xMinimum(),bbox.yMinimum()], 4326) maxX, maxY = self.gh.prjPtFromMapCrs([bbox.xMaximum(),bbox.yMaximum()], 4326) xyBox = [minX, minY, maxX, maxY] pts= self.poi.fetchPoi( txt, c=1024, srs=4326 , maxModel=0, updateResults=0, bbox= xyBox, theme= poitheme , category= poiCategorie, POItype= poiType, clustering= cluster ) else: pts= self.poi.fetchPoi( txt, c=1024, srs=4326 , maxModel=0, updateResults=0, bbox=None, theme= poitheme , category= poiCategorie, POItype= poiType, region= Niscode, clustering= cluster ) if type( pts ) == str: self.bar.pushMessage( QCoreApplication.translate("geopunt4QgisPoidialog","Waarschuwing"), pts, level=Qgis.Warning, duration=5) elif type( pts ) == list or type( pts ) == dict: self.ph.save_minPois_points(pts, layername=self.layerName, startFolder= os.path.join(self.startDir, self.layerName), saveToFile=self.saveToFile, sender=self ) self.close() def searchTxtChanged(self): txt= self.ui.poiText.text() if txt != "": msg = QCoreApplication.translate("geopunt4QgisPoidialog", "Voeg meer punten toe") else: msg = QCoreApplication.translate("geopunt4QgisPoidialog", "Voeg alle punten toe" ) self.ui.addMinModelBtn.setText(msg) def _getSelectedPois(self): pois = self.poi.PoiResult selPois = [] selRows = set( [sel.row() for sel in self.ui.resultLijst.selectedIndexes()] ) for row in selRows: itemID = self.ui.resultLijst.item(row,0).text() selPois += [i for i in pois if i["id"] == itemID] return selPois def clearGraphicsLayer(self): for graphic in self.graphicsLayer: self.iface.mapCanvas().scene().removeItem(graphic) self.graphicsLayer = [] def layernameValid(self): if not hasattr(self, 'layerName'): layerName, accept = QInputDialog.getText(None, QCoreApplication.translate("geopunt4Qgis", 'Laag toevoegen'), QCoreApplication.translate("geopunt4Qgis", 'Geef een naam voor de laag op:') ) if accept == False: return False else: self.layerName = layerName return True def clean(self): self.bar.clearWidgets() self.ui.poiText.setText("") self.ui.msgLbl.setText("") self.ui.resultLijst.clearContents() self.ui.resultLijst.setRowCount(0) self.clearGraphicsLayer()
class geopunt4QgisElevationDialog(QDialog): def __init__(self, iface): QDialog.__init__(self, None) self.setWindowFlags( self.windowFlags() & ~Qt.WindowContextHelpButtonHint ) self.iface = iface # initialize locale locale = QSettings().value("locale/userLocale", "en") if not locale: locale == 'en' else: locale = locale[0:2] localePath = os.path.join(os.path.dirname(__file__), 'i18n', 'geopunt4qgis_{}.qm'.format(locale)) if os.path.exists(localePath): self.translator = QTranslator() self.translator.load(localePath) QCoreApplication.installTranslator(self.translator) self._initGui() def _initGui(self): """setup the user interface""" self.ui = Ui_elevationDlg() self.ui.setupUi(self) #get settings self.s = QSettings() self.loadSettings() self.gh = geometryHelper( self.iface ) self.eh = elevationHelper( self.iface, self.startDir) #setup a message bar self.bar = QgsMessageBar() self.bar.setSizePolicy( QSizePolicy.Minimum, QSizePolicy.Fixed ) self.ui.verticalLayout.addWidget(self.bar) self.ui.buttonBox.addButton(QPushButton("Sluiten"), QDialogButtonBox.RejectRole ) for btn in self.ui.buttonBox.buttons(): btn.setAutoDefault(0) ##graph global vars self.Rubberline = None self.profile = None self.pt = None self.ax = None self.ano = None self.anoLbl = None self.counter = 0 self.xscaleUnit = (1, "m") # a figure instance to plot on self.figure = Figure() #create the Canvas widget and toolbar and set graphWgt as parent self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas, self) ### #self.ui.toolbar.layout().insertWidget(0, self.toolbar) self.ui.graphWgt.layout().addWidget(self.canvas) self.createCanvasToolbar() #events self.ui.drawBtn.clicked.connect(self.drawBtnClicked) self.figure.canvas.mpl_connect('motion_notify_event', self.showGraphMotion) self.ui.saveLineBtn.clicked.connect(self.saveLineClicked) self.ui.savePntBtn.clicked.connect(self.savePntClicked) self.ui.addDHMbtn.clicked.connect(self.addDHMasWMS) self.ui.refreshBtn.clicked.connect( self.onRefresh ) self.ui.buttonBox.helpRequested.connect(self.openHelp) self.rejected.connect(self.clean ) def createCanvasToolbar (self): ''' 1 Reset original view 2 Back to previous view 3 Forward to next view 4 Pan axes with left mouse, zoom with right 5 Zoom to rectangle 6 Save the figure 7 Edit curves line and axes parameters ''' self.toolbar.setVisible(False) toolbarBtns = self.ui.toolbar.findChildren(QToolButton) self.ui.toolbar.setStyleSheet("""QToolButton {border-width: 2px; border-style: outset; border-color: #fbd837; border-radius: 5px ; background-color: white } QToolButton:pressed { border-style: inset; background-color: grey } """) toolbarBtns[0].setToolTip(QCoreApplication.translate("geopunt4QgisElevationDialog", "Keer terug naar overzicht")) toolbarBtns[0].setIcon( QIcon(":/plugins/geopunt4Qgis/images/full_extent.png")) toolbarBtns[0].clicked.connect( self.toolbar.home ) toolbarBtns[1].setToolTip(QCoreApplication.translate("geopunt4QgisElevationDialog", "Vorige")) toolbarBtns[1].setIcon( QIcon(":/plugins/geopunt4Qgis/images/previous.png")) toolbarBtns[1].clicked.connect( self.toolbar.back ) toolbarBtns[2].setToolTip(QCoreApplication.translate("geopunt4QgisElevationDialog", "Volgende")) toolbarBtns[2].setIcon( QIcon(":/plugins/geopunt4Qgis/images/next.png")) toolbarBtns[2].clicked.connect( self.toolbar.forward ) toolbarBtns[3].setToolTip(QCoreApplication.translate("geopunt4QgisElevationDialog", "Pannen")) toolbarBtns[3].setIcon( QIcon(":/plugins/geopunt4Qgis/images/pan.png")) toolbarBtns[3].clicked.connect( self.toolbar.pan ) toolbarBtns[4].setToolTip(QCoreApplication.translate("geopunt4QgisElevationDialog", "Zoom naar rechthoek")) toolbarBtns[4].setIcon( QIcon(":/plugins/geopunt4Qgis/images/rectangleZoom.png")) toolbarBtns[4].clicked.connect( self.toolbar.zoom ) toolbarBtns[5].setToolTip(QCoreApplication.translate("geopunt4QgisElevationDialog", "Opslaan als afbeelding")) toolbarBtns[5].setIcon( QIcon(":/plugins/geopunt4Qgis/images/save.png")) toolbarBtns[5].clicked.connect( self.save_fig ) #semf.toolbar.save_figure toolbarBtns[6].setToolTip(QCoreApplication.translate("geopunt4QgisElevationDialog", "Vorm grafiek aanpassen")) toolbarBtns[6].setIcon( QIcon(":/plugins/geopunt4Qgis/images/wrench.png")) toolbarBtns[6].clicked.connect( self.toolbar.edit_parameters) toolbarBtns[7].setIcon( QIcon(":/plugins/geopunt4Qgis/images/fill.png")) toolbarBtns[7].setToolTip( QCoreApplication.translate("geopunt4QgisElevationDialog", "Kies de vulkleur")) toolbarBtns[7].clicked.connect( self.setFill) def loadSettings(self): self.timeout = int( self.s.value("geopunt4qgis/timeout" ,15)) if settings().proxyUrl: self.proxy = settings().proxyUrl else: self.proxy = "" self.samplesSavetoFile = int( self.s.value("geopunt4qgis/samplesSavetoFile" , 1)) sampleLayer = self.s.value("geopunt4qgis/sampleLayerTxt", "") if sampleLayer: self.sampleLayerTxt = sampleLayer self.profileLineSavetoFile = int( self.s.value("geopunt4qgis/profileLineSavetoFile" , 1)) profileLineLayer= self.s.value("geopunt4qgis/profileLineLayerTxt", "") if profileLineLayer: self.profileLineLayerTxt = profileLineLayer self.startDir = self.s.value("geopunt4qgis/startDir", os.path.expanduser("~")) self.elevation = elevation(self.timeout, self.proxy ) def resizeEvent(self, event): QDialog.resizeEvent(self, event) if self.ax: self.figure.tight_layout() #eventhandlers def save_fig(self): formats = ( "Joint Photographic Experts Group (*.jpg) (*.jpg);;Scalable Vector Grapics (*.svg) (*.svg);;"+ "Portable Document Format (*.pdf) (*.pdf);;Tagged Image File Format (*.tif) (*.tif)"+ ";;Encapsulated Postscript (*.eps) (*.eps)") if not(sys.platform == 'win32'): formats += ";;Portable Network Graphics (*.png) (*.png)" fileName, __ = QFileDialog.getSaveFileName( self , "Save File", self.startDir, formats); self.figure.savefig(fileName) def onRefresh(self): if self.ano: self.ano.remove() self.ano = None if self.anoLbl: self.anoLbl.remove() self.anoLbl = None self.plot() def onResize(self, event): self.figure.tight_layout() def openHelp(self): webbrowser.open_new_tab("http://www.geopunt.be/voor-experts/geopunt-plug-ins/functionaliteiten/hoogteprofiel") def drawBtnClicked(self): self.clean() #self.reSetFigure() self.tool = lineTool(self.iface, self.callBack ) self.iface.mapCanvas().setMapTool(self.tool) self.showMinimized() self.counter += 1 def showGraphMotion(self, event): if self.ax == None: return if event.xdata != None and event.ydata != None: if self.ano != None: self.ano.remove() self.ano = None if self.anoLbl != None: self.anoLbl.remove() self.anoLbl = None xdata = np.array( [n[0] for n in self.profile ] ) * self.xscaleUnit[0] ydata = np.array( [n[3] for n in self.profile ] )# if n[3] > -9999 ] zx = np.interp( event.xdata, xdata, ydata ) xmax = np.max( xdata ) xmin = np.min( xdata ) zmax = np.max( ydata ) zmin = np.max( [n[3] for n in self.profile if n[3] > -9999 ] ) if event.xdata <= xmax and event.xdata >= xmin : self.ano = self.ax.arrow( event.xdata , -9999, 0, zx + 9999, fc="k", ec="k" ) box_props = dict(boxstyle="Round,pad=0.3", fc="cyan", ec="b", lw=2) self.anoLbl = self.ax.annotate( str( round(zx, 2)) + " m", xy= (event.xdata, zx ) , xytext= (event.xdata , zx + (0.2 * ( zmax - zmin )) ), bbox=box_props ) self.setMapPt( event.xdata / self.xscaleUnit[0] ) else: self.setMapPt() event.canvas.draw() def saveLineClicked(self): if not hasattr(self, 'profileLineLayerTxt'): layerName, accept = QInputDialog.getText(None, QCoreApplication.translate("geopunt4Qgis", 'Laag toevoegen'), QCoreApplication.translate("geopunt4Qgis", 'Geef een naam voor de laag op:') ) if accept == False: return else: self.profileLineLayerTxt = layerName if self.profile != None and self.Rubberline != None: title = self.ax.get_title() self.eh.save_profile( self.Rubberline.asGeometry(), self.profile, title, self.profileLineLayerTxt, self.profileLineSavetoFile, sender=self ) def savePntClicked(self): if not hasattr(self, 'sampleLayerTxt'): layerName, accept = QInputDialog.getText(None, QCoreApplication.translate("geopunt4Qgis", 'Laag toevoegen'), QCoreApplication.translate("geopunt4Qgis", 'Geef een naam voor de laag op:') ) if accept == False: return else: self.sampleLayerTxt = layerName if self.profile != None: title = self.ax.get_title() self.eh.save_sample_points( self.profile, title, self.sampleLayerTxt, self.samplesSavetoFile, sender=self ) def setFill( self ): if self.profile == None: return if self.ax == None: return clr = QColorDialog.getColor( Qt.white, self, QCoreApplication.translate( "geopunt4QgisElevationDialog", "Kies de vulkleur") ) if clr.isValid(): xdata = np.array( [n[0] for n in self.profile ] ) * self.xscaleUnit[0] ydata = np.array( [n[3] for n in self.profile ] ) self.ax.fill_between( xdata, ydata, -9999, color=clr.name() ) def addDHMasWMS(self): crs = self.gh.getGetMapCrs(self.iface).authid() if crs != 'EPSG:31370' or crs != 'EPSG:3857' or crs != 'EPSG:3043': crs = 'EPSG:31370' dhmUrl = "url=https://geoservices.informatievlaanderen.be/raadpleegdiensten/DHMV/wms&layers=DHMVII_DTM_1m&&format=image/png&styles=default&crs="+ crs try: rlayer = QgsRasterLayer(dhmUrl, 'Hoogtemodel', 'wms') if rlayer.isValid(): rlayer.renderer().setOpacity(0.8) QgsProject.instance().addMapLayer(rlayer) else: self.bar.pushMessage("Error", QCoreApplication.translate("geopunt4QgisElevationDialog", "Kan WMS niet laden"), level=Qgis.Critical, duration=10) except: self.bar.pushMessage("Error", str( sys.exc_info()[1] ), level=Qgis.Critical, duration=10) return def plot(self): if self.Rubberline == None: return wgsLine = self.gh.prjLineFromMapCrs( self.Rubberline.asGeometry() ) lineString = [ list(n) for n in wgsLine.asPolyline()] nrSamples = self.ui.nrOfSampleSpin.value() #try: self.profile = self.elevation.fetchElevaton( lineString, 4326, nrSamples) #except geopuntError as ge: # self.bar.pushMessage("Error", ge.message, level=Qgis.Critical, duration=10) # return if np.max( [n[0] for n in self.profile ] ) > 1000: self.xscaleUnit = (0.001 , "km" ) else: self.xscaleUnit = (1 , "m" ) xdata = np.array( [n[0] for n in self.profile ] ) * self.xscaleUnit[0] ydata = np.array( [n[3] for n in self.profile ] ) #need at least 3 values if len(xdata) <= 2 or len([n for n in self.profile if n[3] > -9999 ]) <= 2: self.bar.pushMessage("Error", QCoreApplication.translate( "geopunt4QgisElevationDialog", "Er werd geen of onvoldoende data gevonden"), level=Qgis.Warning, duration=5) self.profile = None return ymin = np.min( [n[3] for n in self.profile if n[3] > -9999 ] ) ymax = np.max( ydata ) # create an axis self.ax = self.figure.add_subplot(111) # discards the old graph self.ax.hold(False) # plot data self.ax.plot( xdata, ydata,'r*') self.ax.fill_between(xdata, ydata, -9999, color='#F8E6E0' ) self.ax.set_ylim([ymin , ymax]) self.ax.set_xlim([0 , None ]) self.ax.set_ylabel("hoogte (m)") self.ax.set_xlabel("afstand (%s)" % self.xscaleUnit[1] ) self.ax.set_title("Hoogteprofiel " + str( self.counter) ) # refresh canvas self.figure.tight_layout() self.canvas.draw() def callBack(self, geom): self.iface.mapCanvas().unsetMapTool(self.tool) self.Rubberline = geom self.showNormal() self.activateWindow() self.plot() self.ui.saveWgt.setEnabled(True) def setMapPt(self, dist=None ): if self.pt: self.iface.mapCanvas().scene().removeItem(self.pt) if dist==None: return if self.Rubberline == None: return # dist is measured in lambert 72 in meters lb72Line = self.gh.prjLineFromMapCrs( self.Rubberline.asGeometry() , 31370 ) lb72pt = lb72Line.interpolate(dist).asPoint() pt = self.gh.prjPtToMapCrs(lb72pt, 31370) self.pt = QgsVertexMarker(self.iface.mapCanvas()) self.pt.setCenter( pt ) self.pt.setColor(QColor(0,255,250)) self.pt.setIconSize(5) self.pt.setIconType(QgsVertexMarker.ICON_BOX ) # or ICON_CROSS, ICON_X self.pt.setPenWidth(7) if self.xscaleUnit[0] != 1: msg= "lengte= %s %s" % (round( dist * self.xscaleUnit[0], 2) , self.xscaleUnit[1]) else: msg= "lengte= %s %s" % (int( dist * self.xscaleUnit[0]) , self.xscaleUnit[1]) self.ui.mgsLbl.setText( msg ) def clean(self): if self.pt: self.iface.mapCanvas().scene().removeItem(self.pt) if self.Rubberline: self.iface.mapCanvas().scene().removeItem(self.Rubberline) if self.ano: self.ano.remove() self.ano = None if self.anoLbl: self.anoLbl.remove() self.anoLbl = None if self.ax: self.ax.hold(False) self.ax.clear() self.ax = None self.figure.clf() self.canvas.draw() self.ui.saveWgt.setEnabled(False) self.profile = None self.Rubberline = None self.ui.mgsLbl.setText("")
class IWAMS: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join( self.plugin_dir, 'i18n', 'IWAMS_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.actions = [] self.menu = self.tr(u'&Indian WAtershed Management support System') # Check if plugin was started the first time in current QGIS session # Must be set in initGui() to survive plugin reloads self.first_start = None # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('IWAMS', message) def add_action( self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: # Adds plugin icon to Plugins toolbar self.iface.addToolBarIcon(action) if add_to_menu: self.iface.addPluginToMenu( self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path1 = os.path.dirname(__file__) +'/icon1.png' icon_path2 = os.path.dirname(__file__) + '/icon2.png' icon_path3 = os.path.dirname(__file__) +'/icon3.png' self.add_action( icon_path1, text=self.tr(u'Hydrological Analysis Module'), callback=self.run_hydrological, parent=self.iface.mainWindow()) self.add_action( icon_path2, text=self.tr(u'Priortisation Module'), callback=self.run_priortisation, parent=self.iface.mainWindow()) self.add_action( icon_path3, text=self.tr(u'Conservation Measures Module'), callback=self.run_conservation, parent=self.iface.mainWindow()) # will be set False in run() self.first_start = True def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginMenu( self.tr(u'&Indian WAtershed Management support System'), action) self.iface.removeToolBarIcon(action) def run_hydrological(self): """Run method that performs all the real work""" # Create the dialog with elements (after translation) and keep reference # Only create GUI ONCE in callback, so that it will only load when the plugin is started if self.first_start == True: # self.first_start = False self.dlg = HydrologicalDialog() # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: # Do something useful here - delete the line containing pass and # substitute with your code. pass def run_priortisation(self): """Run method that performs all the real work""" # Create the dialog with elements (after translation) and keep reference # Only create GUI ONCE in callback, so that it will only load when the plugin is started if self.first_start == True: # self.first_start = False self.dlg = PriortisationDialog() # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: # Do something useful here - delete the line containing pass and # substitute with your code. pass def run_conservation(self): """Run method that performs all the real work""" # Create the dialog with elements (after translation) and keep reference # Only create GUI ONCE in callback, so that it will only load when the plugin is started if self.first_start == True: # self.first_start = False self.dlg = ConservationDialog() # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: # Do something useful here - delete the line containing pass and # substitute with your code. pass
***************************************************************************/ """ from __future__ import absolute_import # Import the PyQt and QGIS libraries from builtins import object from qgis.PyQt.QtCore import QSettings, QTranslator, QObject from qgis.PyQt.QtWidgets import QApplication, QAction from qgis.PyQt.QtGui import QIcon from qgis.core import QgsApplication # Initialize Qt resources from file resources.py from . import qrc_resources # Add translations to translator application = QgsApplication.instance() localeName = QSettings().value("locale/userLocale", type=str) translator = QTranslator() translator.load("B4UdigNL_"+localeName, ":/") # Add translator to application application.installTranslator(translator) # Import the code for the dialog from .B4UdigNLDialog import B4UdigNLDialog class B4UdigNL(object): def __init__(self, iface): # Save reference to the QGIS interface self.iface = iface self.dialog = None def initGui(self): # Create action that will start plugin configuration
class NewRaptor: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'NewRaptor_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.actions = [] self.menu = self.tr(u'&Add New Raptor') # Check if plugin was started the first time in current QGIS session # Must be set in initGui() to survive plugin reloads self.first_start = None # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('NewRaptor', message) def add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: # Adds plugin icon to Plugins toolbar self.iface.addToolBarIcon(action) if add_to_menu: self.iface.addPluginToVectorMenu(self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/new_raptor/icon.png' self.add_action(icon_path, text=self.tr(u'Add New Raptor Nest'), callback=self.run, parent=self.iface.mainWindow()) # will be set False in run() self.first_start = True def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginVectorMenu(self.tr(u'&Add New Raptor'), action) self.iface.removeToolBarIcon(action) def run(self): """Run method that performs all the real work""" # Create the dialog with elements (after translation) and keep reference # Only create GUI ONCE in callback, so that it will only load when the plugin is started if self.first_start == True: self.first_start = False self.dlg = NewRaptorDialog() self.dlg.cmbSpecies.currentTextChanged.connect( self.evt_cmbSpecies_changed) mc = self.iface.mapCanvas() self.dlg.spbLatitude.setValue(mc.center().y()) self.dlg.spbLongitude.setValue(mc.center().x()) self.dlg.dteLast.setDate(QDate.currentDate()) map_layers = [] for lyr in mc.layers(): map_layers.append(lyr.name()) missing_layers = [] if not "Raptor Nests" in map_layers: missing_layers.append("Raptor Nests") if not "Raptor Buffer" in map_layers: missing_layers.append("Raptor Buffer") if not "Linear Buffer" in map_layers: missing_layers.append("Linear Buffer") if missing_layers: msg = "The following layers are missing from this project\n" for lyr in missing_layers: msg += "\n{}".format(lyr) QMessageBox.critical(self.dlg, "Missing Layers!", msg) return # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: lyrNest = QgsProject.instance().mapLayersByName("Raptor Nests")[0] lyrBuffer = QgsProject.instance().mapLayersByName( "Raptor Buffer")[0] lyrLinear = QgsProject.instance().mapLayersByName( "Linear Buffer")[0] idxNestId = lyrNest.fields().indexOf("Nest_ID") valNestId = lyrNest.maximumValue(idxNestId) + 1 valLat = self.dlg.spbLatitude.value() valLng = self.dlg.spbLongitude.value() valSpecies = self.dlg.cmbSpecies.currentText() valBuffer = self.dlg.spbBuffer.value() valStatus = self.dlg.cmbStatus.currentText() valLast = self.dlg.dteLast.date() QMessageBox.information( self.dlg, "Message", "New Nest ID: {}\nLatitude: {}\nLongitude: {}\nSpecies: {}\nBuffer: {}\nStatus: {}\nLast survey: {}" .format(valNestId, valLat, valLng, valSpecies, valBuffer, valStatus, valLast)) ftrNest = QgsFeature(lyrNest.fields()) ftrNest.setAttribute("lat_y_dd", valLat) ftrNest.setAttribute("long_x_dd", valLng) ftrNest.setAttribute("recentspec", valSpecies) ftrNest.setAttribute("buf_dist", valBuffer) ftrNest.setAttribute("recentstat", valStatus) ftrNest.setAttribute("lastsurvey", valLast) ftrNest.setAttribute("Nest_ID", valNestId) geom = QgsGeometry(QgsPoint(valLng, valLat)) ftrNest.setGeometry(geom) pr = lyrNest.dataProvider() pr.addFeatures([ftrNest]) lyrNest.reload() pr = lyrBuffer.dataProvider() buffer = geom.buffer(valBuffer, 10) ftrNest.setGeometry(buffer) pr.addFeatures([ftrNest]) lyrBuffer.reload() dlgTable = DlgTable() dlgTable.setWindowTitle( "Impacts Table for Nest {}".format(valNestId)) #Find linear projects that will be impacted by the Nest bb = buffer.boundingBox() linears = lyrLinear.getFeatures(bb) for linear in linears: valId = linear.attribute("Project") valType = linear.attribute("type") valDistance = linear.geometry().distance( geom) #geom is de geometry of the nestpoint if valDistance < valBuffer: # populate the table with linear data row = dlgTable.tblImpacts.rowCount() dlgTable.tblImpacts.insertRow(row) dlgTable.tblImpacts.setItem(row, 0, QTableWidgetItem(str(valId))) dlgTable.tblImpacts.setItem(row, 1, QTableWidgetItem(valType)) twi = QTableWidgetItem("{:4.5f}".format(valDistance)) twi.setTextAlignment(QtCore.Qt.AlignRight) dlgTable.tblImpacts.setItem(row, 2, twi) dlgTable.tblImpacts.sortItems(2) dlgTable.show() dlgTable.exec_() else: QMessageBox.information(self.dlg, "Message", "Should only run if cancelled") def evt_cmbSpecies_changed(self, species): if species == "Swainsons Hawk": self.dlg.spbBuffer.setValue(0.004) else: self.dlg.spbBuffer.setValue(0.008)
class geopunt4Qgis(object): def __init__(self, iface): 'initialize' # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value("locale/userLocale", "nl") if not locale: locale == 'nl' else: locale = locale[0:2] localePath = os.path.join(self.plugin_dir, 'i18n', 'geopunt4qgis_{}.qm'.format(locale)) if os.path.exists(localePath): self.translator = QTranslator() self.translator.load(localePath) QCoreApplication.installTranslator(self.translator) #version check if locale == 'nl': vc = versionChecker() if not vc.isUptoDate(): QMessageBox.warning(self.iface.mainWindow(), QCoreApplication.translate("geopunt4Qgis", "Waarschuwing"), QCoreApplication.translate("geopunt4Qgis", "Je versie van <a href='http://plugins.qgis.org/plugins/geopunt4Qgis' >geopunt4qgis</a> is niet meer up to date. <br/>Je kunt deze upgraden via het menu:<br/> "+ "<strong>Plugins > Beheer en installeer Plugins > Op te waarderen.</strong><br/>Klik daarna op <strong>Plugin opwaarderen</strong>")) # Create the dialogs (after translation) and keep reference self.adresdlg = geopunt4QgisAdresDialog(self.iface) self.batchgeoDlg = geopunt4QgisBatcGeoCodeDialog(self.iface) self.poiDlg = geopunt4QgisPoidialog(self.iface) self.gipodDlg = geopunt4QgisGipodDialog(self.iface) self.settingsDlg = geopunt4QgisSettingsDialog() if mathplotlibWorks : self.elevationDlg = geopunt4QgisElevationDialog(self.iface) self.datacatalogusDlg = geopunt4QgisDataCatalog(self.iface) self.parcelDlg = geopunt4QgisParcelDlg(self.iface) self.aboutDlg = geopunt4QgisAboutDialog() def initGui(self): 'intialize UI' #get settings self.s = QSettings() self.loadSettings() self.gh = geometryHelper(self.iface) self.graphicsLayer = [] # Create actions that will start plugin configuration self.adresAction = QAction(QIcon(":/plugins/geopunt4Qgis/images/geopuntAddress.png"), QCoreApplication.translate("geopunt4Qgis" , u"Zoek een adres"), self.iface.mainWindow()) self.reverseAction = QAction(QIcon(":/plugins/geopunt4Qgis/images/geopuntReverse.png"), QCoreApplication.translate("geopunt4Qgis", u"Prik een adres op de kaart"), self.iface.mainWindow()) self.batchAction = QAction(QIcon(":/plugins/geopunt4Qgis/images/geopuntBatchgeocode.png"), QCoreApplication.translate("geopunt4Qgis", u"CSV-adresbestanden geocoderen"), self.iface.mainWindow()) self.poiAction = QAction(QIcon(":/plugins/geopunt4Qgis/images/geopuntPoi.png"), QCoreApplication.translate("geopunt4Qgis" , u"Zoek een interessante plaats"), self.iface.mainWindow()) self.gipodAction = QAction(QIcon(":/plugins/geopunt4Qgis/images/geopuntGIPOD.png"), QCoreApplication.translate("geopunt4Qgis" , u"Bevraag GIPOD"), self.iface.mainWindow()) self.settingsAction = QAction(QIcon(":/plugins/geopunt4Qgis/images/geopuntSettings.png"), QCoreApplication.translate("geopunt4Qgis" , u"Instellingen"), self.iface.mainWindow()) self.elevationAction = QAction(QIcon(":/plugins/geopunt4Qgis/images/geopuntElevation.png"), QCoreApplication.translate("geopunt4Qgis" , u"Hoogteprofiel"), self.iface.mainWindow()) self.datacatalogusAction = QAction(QIcon(":/plugins/geopunt4Qgis/images/geopuntDataCatalogus.png"), QCoreApplication.translate("geopunt4Qgis" , u"Geopunt-catalogus"), self.iface.mainWindow()) self.parcelAction = QAction(QIcon(":/plugins/geopunt4Qgis/images/geopuntParcel.png"), QCoreApplication.translate("geopunt4Qgis" , u"Zoeken naar perceel"), self.iface.mainWindow()) self.aboutAction = QAction(QIcon(":/plugins/geopunt4Qgis/images/geopunt.png"), QCoreApplication.translate("geopunt4Qgis" , u"Over geopunt4Qgis"), self.iface.mainWindow()) # connect the action to the run method self.adresAction.triggered.connect(self.runAdresDlg) self.reverseAction.triggered.connect(self.reverse) self.batchAction.triggered.connect(self.runBatch) self.poiAction.triggered.connect(self.runPoiDlg) self.gipodAction.triggered.connect(self.runGipod) self.elevationAction.triggered.connect(self.runElevation) self.datacatalogusAction.triggered.connect(self.rundatacatalog) self.parcelAction.triggered.connect(self.runParcel) self.settingsAction.triggered.connect(self.runSettingsDlg) self.aboutAction.triggered.connect(self.runAbout) #Create toolbar self.toolbar = self.iface.addToolBar("Geopunt toolbar") self.toolbar.setObjectName("Geopunt toolbar") # Add to toolbar button self.toolbar.addAction(self.adresAction) self.toolbar.addAction(self.reverseAction) self.toolbar.addAction(self.batchAction) self.toolbar.addAction(self.poiAction) self.toolbar.addAction(self.gipodAction) self.toolbar.addAction(self.elevationAction) self.toolbar.addAction(self.parcelAction) self.toolbar.addAction(self.datacatalogusAction) # Add to Menu self.iface.addPluginToWebMenu(u"&geopunt4Qgis", self.adresAction) self.iface.addPluginToWebMenu(u"&geopunt4Qgis", self.reverseAction) self.iface.addPluginToWebMenu(u"&geopunt4Qgis", self.batchAction) self.iface.addPluginToWebMenu(u"&geopunt4Qgis", self.poiAction) self.iface.addPluginToWebMenu(u"&geopunt4Qgis", self.gipodAction) self.iface.addPluginToWebMenu(u"&geopunt4Qgis", self.elevationAction) self.iface.addPluginToWebMenu(u'&geopunt4Qgis' ,self.parcelAction) self.iface.addPluginToWebMenu(u"&geopunt4Qgis", self.datacatalogusAction) self.iface.addPluginToWebMenu(u"&geopunt4Qgis", self.settingsAction) self.iface.addPluginToWebMenu(u"&geopunt4Qgis", self.aboutAction) def unload(self): ' Remove the plugin menu items and icons' self.iface.removePluginMenu(u"&geopunt4Qgis", self.adresAction) self.iface.removePluginMenu(u"&geopunt4Qgis", self.poiAction) self.iface.removePluginMenu(u"&geopunt4Qgis", self.reverseAction) self.iface.removePluginMenu(u"&geopunt4Qgis", self.batchAction) self.iface.removePluginMenu(u"&geopunt4Qgis", self.aboutAction) self.iface.removePluginMenu(u"&geopunt4Qgis", self.settingsAction) self.iface.removePluginMenu(u"&geopunt4Qgis", self.gipodAction) self.iface.removePluginMenu(u"&geopunt4Qgis", self.elevationAction) self.iface.removePluginMenu(u"&geopunt4Qgis", self.datacatalogusAction) self.iface.removePluginMenu(u"&geopunt4Qgis", self.parcelAction) self.iface.removeToolBarIcon( self.adresAction) self.iface.removeToolBarIcon( self.poiAction) self.iface.removeToolBarIcon( self.reverseAction) self.iface.removeToolBarIcon( self.batchAction) self.iface.removeToolBarIcon( self.aboutAction) self.iface.removeToolBarIcon( self.gipodAction) self.iface.removeToolBarIcon( self.elevationAction) self.iface.removeToolBarIcon( self.datacatalogusAction) self.iface.removeToolBarIcon( self.parcelAction) del self.toolbar def loadSettings(self): self.saveToFile_reverse = int(self.s.value("geopunt4qgis/reverseSavetoFile", 0)) layerName_reverse = self.s.value("geopunt4qgis/reverseLayerText", "") if layerName_reverse: self.layerName_reverse = layerName_reverse self.timeout = int( self.s.value("geopunt4qgis/timeout" ,15)) if settings().proxyUrl: self.proxy = settings().proxyUrl else: self.proxy = "" self.startDir = self.s.value("geopunt4qgis/startDir", os.path.expanduser("~")) self.gp = Adres(self.timeout, self.proxy) def runSettingsDlg(self): ' show the dialog' if self.settingsDlg.isVisible(): self.settingsDlg.showNormal() self.settingsDlg.activateWindow() return self.settingsDlg.show() # Run the dialog event loop result = self.settingsDlg.exec_() if result: self.loadSettings() def runAdresDlg(self): ' show the dialog' if self.adresdlg.isVisible(): self.adresdlg.showNormal() self.adresdlg.activateWindow() return self.adresdlg.loadSettings() self.adresdlg.show() # Run the dialog event loop self.adresdlg.exec_() def runPoiDlg(self): 'show the dialog' if self.poiDlg.isVisible(): self.poiDlg.showNormal() self.poiDlg.activateWindow() return self.poiDlg.loadSettings() self.poiDlg.show() # Run the dialog event loop self.poiDlg.exec_() def runGipod(self): 'show the dialog' if self.gipodDlg.isVisible(): self.gipodDlg.showNormal() self.gipodDlg.activateWindow() return self.gipodDlg.loadSettings() self.gipodDlg.show() # Run the dialog event loop self.gipodDlg.exec_() def runBatch(self): 'show the dialog' if self.batchgeoDlg.isVisible(): self.batchgeoDlg.showNormal() self.batchgeoDlg.activateWindow() return self.batchgeoDlg.loadSettings() self.batchgeoDlg.show() # Run the dialog event loop self.batchgeoDlg.exec_() def runElevation(self): if mathplotlibWorks == False: QMessageBox.critical(None, "Error", QCoreApplication.translate("geopunt4Qgis" , "Deze functie kan niet geladen worden door het ontbreken van of een fout in mathplotlib") ) return 'show the dialog' if self.elevationDlg.isVisible(): self.elevationDlg.showNormal() self.elevationDlg.activateWindow() return self.elevationDlg.loadSettings() self.elevationDlg.show() # Run the dialog event loop self.elevationDlg.exec_() def rundatacatalog(self): 'show the dialog' if self.datacatalogusDlg.isVisible(): self.datacatalogusDlg.showNormal() self.datacatalogusDlg.activateWindow() return self.datacatalogusDlg.loadSettings() self.datacatalogusDlg.show() # Run the dialog event loop self.datacatalogusDlg.exec_() def runParcel(self): 'show the dialog' if self.parcelDlg.isVisible(): self.parcelDlg.showNormal() self.parcelDlg.activateWindow() return self.parcelDlg.loadSettings() self.parcelDlg.show() # Run the dialog event loop self.parcelDlg.exec_() def runAbout(self): 'show the dialog' if self.aboutDlg.isVisible(): self.aboutDlg.showNormal() self.aboutDlg.activateWindow() return self.aboutDlg.show() # Run the dialog event loop self.aboutDlg.exec_() def reverse(self): widget = self.iface.messageBar().createMessage( QCoreApplication.translate("geopunt4Qgis" ,"Zoek een Adres: "), QCoreApplication.translate("geopunt4Qgis" ,'Klik op de kaart om het adres op te vragen')) helpBtn = QPushButton("Help", widget) helpBtn.clicked.connect(self.openReverseHelp) widget.layout().addWidget(helpBtn) self.iface.messageBar().clearWidgets() self.iface.messageBar().pushWidget(widget, level=Qgis.Info) reverseAdresTool = reverseAdresMapTool(self.iface, self._reverseAdresCallback) self.iface.mapCanvas().setMapTool(reverseAdresTool) def _reverseAdresCallback(self, point): self._addMarker( point ) lam72 = QgsCoordinateReferenceSystem(31370) mapCrs = self.gh.getGetMapCrs(self.iface) xform = QgsCoordinateTransform(mapCrs, lam72, QgsProject.instance()) lam72clickt = xform.transform(point) #to clear or not clear that is the question self.iface.messageBar().clearWidgets() #fetch Location from geopunt adres = self.gp.fetchLocation( str( lam72clickt.x() ) + "," + str( lam72clickt.y() ), 1) Timer( 3, self._clearGraphicLayer, ()).start() if len(adres) and type( adres ) is list: #only one result in list, was set in request FormattedAddress = adres[0]["FormattedAddress"] #add a button to the messageBar widget xlam72, ylam72 = adres[0]["Location"]["X_Lambert72"], adres[0]["Location"]["Y_Lambert72"] diff = int(((xlam72 - lam72clickt.x())**2 +(ylam72 - lam72clickt.y())**2 )**(0.5)) widget = self.iface.messageBar().createMessage(QCoreApplication.translate( "geopunt4Qgis", "Resultaat: "), "{0} (verschil: {1}m)".format(FormattedAddress, diff)) xy = self.gh.prjPtToMapCrs([xlam72, ylam72], 31370) self._addMarker( xy, QColor(0,255,200)) button = QPushButton(widget) button.clicked.connect(lambda: self._addReverse(adres[0])) button.setText(QCoreApplication.translate("geopunt4Qgis" ,"Voeg toe")) widget.layout().addWidget(button) self.iface.messageBar().clearWidgets() self.iface.messageBar().pushWidget(widget, level=Qgis.Info) elif len(adres) == 0: self.iface.messageBar().pushMessage(QCoreApplication.translate("geopunt4Qgis","Waarschuwing"), QCoreApplication.translate("geopunt4Qgis", "Geen resultaten gevonden"), level=QgsMessageBar.INFO, duration=3) elif type( adres ) is str: self.iface.messageBar().pushMessage(QCoreApplication.translate("geopunt4Qgis", "Waarschuwing"), adres, level=QgsMessageBar.WARNING) else: self.iface.messageBar().pushMessage("Error", QCoreApplication.translate("geopunt4Qgis","onbekende fout"), level=Qgis.Critical) def _addReverse(self, adres): formattedAddress, locationType = adres["FormattedAddress"] , adres["LocationType"] xlam72, ylam72 = adres["Location"]["X_Lambert72"] , adres["Location"]["Y_Lambert72"] if not hasattr(self, 'layerName_reverse'): layerName, accept = QInputDialog.getText(None, QCoreApplication.translate("geopunt4Qgis", 'Laag toevoegen'), QCoreApplication.translate("geopunt4Qgis", 'Geef een naam voor de laag op:')) if accept == False: return else: self.layerName_reverse = layerName xy = self.gh.prjPtToMapCrs([xlam72, ylam72], 31370) self.gh.save_adres_point(xy, formattedAddress, locationType, layername=self.layerName_reverse, startFolder=os.path.join( self.startDir, self.layerName_reverse), saveToFile=self.saveToFile_reverse , sender=self.iface.mainWindow()) self.iface.messageBar().popWidget() self._clearGraphicLayer() def openReverseHelp(self): webbrowser.open_new_tab("http://www.geopunt.be/voor-experts/geopunt-plug-ins/functionaliteiten/prik-een-adres-op-kaart") def _addMarker(self, pnt, clr=QColor(255,255,0)): m = QgsVertexMarker(self.iface.mapCanvas()) m.setCenter( pnt ) m.setColor(clr) m.setIconSize(1) m.setIconType(QgsVertexMarker.ICON_BOX) m.setPenWidth(9) self.graphicsLayer.append(m) return m def _clearGraphicLayer(self): for graphic in self.graphicsLayer: self.iface.mapCanvas().scene().removeItem(graphic) self.graphicsLayer = []
class excel_sync: """QGIS Plugin Implementation.""" def setUpSyncerTest(self, excelName, excelKeyName, shpName, shpKeyName): """Test the setup""" exps = { "Flaeche_ha": "area( $geometry )/10000", "FEE_Nr": "y( $geometry )" } s = Settings(excelName, "Tabelle1", excelKeyName, 1, shpName, shpKeyName, exps) self.syncer = Syncer(s) def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface self.syncer = None # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', '{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) self.dlg = None # Declare instance attributes self.actions = [] self.menu = self.tr(u'&ExcelSync') # TODO: We are going to let the user set this up in a future iteration self.toolbar = self.iface.addToolBar(u'excel_sync') self.toolbar.setObjectName(u'excel_sync') self.initProject() def initProject(self): """ initialize project related connections """ self.iface.projectRead.connect(self.readSettings) self.iface.newProjectCreated.connect(self.reset) QgsProject.instance().writeProject.connect(self.writeSettings) def reset(self): del self.syncer self.syncer = None def readSettings(self): # "Settings","excelName excelSheetName excelKeyName skipLines shpName # shpKeyName expressions") self.reset() metasettings = OrderedDict() metasettings["excelName"] = (str, None) metasettings["excelSheetName"] = (str, None) metasettings["excelKeyName"] = (str, None) metasettings["skipLines"] = (int, None) metasettings["shpKeyName"] = (str, None) metasettings["shpName"] = (str, None) metasettings["expressions"] = (list, []) metasettings["hideDialog"] = (bool, False) settings_dict = ProjectHandler.readSettings("SHPSYNC", metasettings) if "excelName" not in settings_dict or \ settings_dict["excelName"] == '': return else: exps = settings_dict["expressions"] exps_dict = {} for exp in exps: kv = exp.split(":::") exps_dict[kv[0]] = kv[1] settings = Settings( settings_dict["excelName"], settings_dict["excelSheetName"], settings_dict["excelKeyName"], settings_dict["skipLines"], settings_dict["shpName"], settings_dict["shpKeyName"], exps_dict, settings_dict['hideDialog']) self.initSyncer(settings) def writeSettings(self, doc): if self.syncer is None: return settings = self.syncer.s._asdict() settings["expressions"] = [ "{}:::{}".format(k, v) for k, v in settings["expressions"].items() ] ProjectHandler.writeSettings("SHPSYNC", settings) # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('excel_sync', message) def add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: self.toolbar.addAction(action) if add_to_menu: self.iface.addPluginToMenu(self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/excel_sync/icon.png' self.add_action(icon_path, text=self.tr(u'Set up ExcelSync'), callback=self.run, parent=self.iface.mainWindow()) def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginMenu(self.tr(u'&ExcelSync'), action) self.iface.removeToolBarIcon(action) # remove the toolbar del self.toolbar def run(self): """Run method that performs all the real work""" # show the dialog if self.dlg is not None: del self.dlg self.dlg = excel_syncDialog() self.dlg.buttonBox.accepted.connect(self.parseSettings) self.dlg.buttonBox.rejected.connect(self.hideDialog) if self.syncer is None: for i in range(3): self.dlg.addExpressionWidget() self.dlg.exps[0].setField("x($geometry)") self.dlg.exps[1].setField("y($geometry)") self.dlg.exps[2].setField("area($geometry)/10000") else: self.dlg.restoreSettings(self.syncer.s) self.dlg.show() def parseSettings(self): exps = self.dlg.getExpressionsDict() excelName = self.dlg.comboBox_slave.currentText() excelKeyName = self.dlg.comboBox_slave_key.currentText() shpName = self.dlg.comboBox_master.currentText() shpKeyName = self.dlg.comboBox_master_key.currentText() excelSheetName = self.dlg.lineEdit_sheetName.text() skipLines = self.dlg.spinBox.value() hideDialog = self.dlg.checkBox.isChecked() s = Settings(excelName, excelSheetName, excelKeyName, skipLines, shpName, shpKeyName, exps, hideDialog) self.initSyncer(s) self.hideDialog() def initSyncer(self, settings): if self.syncer is not None: del self.syncer self.syncer = Syncer(settings) def hideDialog(self): self.dlg.hide()
class GBIFOccurrences(object): """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join( self.plugin_dir, 'i18n', 'GBIFOccurrences_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Create the dialog (after translation) and keep reference self.dlg = GBIFOccurrencesDialog() # Declare instance attributes self.actions = [] self.menu = self.tr(u'&GBIF Occurrences') # TODO: We are going to let the user set this up in a future iteration self.toolbar = self.iface.addToolBar(u'GBIFOccurrences') self.toolbar.setObjectName(u'GBIFOccurrences') # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('GBIFOccurrences', message) def add_action( self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the InaSAFE toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: self.toolbar.addAction(action) if add_to_menu: self.iface.addPluginToVectorMenu( self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/GBIFOccurrences/icon.png' self.add_action( icon_path, text=self.tr(u'Load GBIF occurrences'), callback=self.run, parent=self.iface.mainWindow()) def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginVectorMenu( self.tr(u'&GBIF Occurrences'), action) self.iface.removeToolBarIcon(action) def run(self): """Run method that performs all the real work""" # show the dialog self.dlg.show() # Run the dialog event loop self.dlg.exec_()
class SortNumber(QObject): """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ super(SortNumber, self).__init__() # necessary for pyqtSignal # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join( self.plugin_dir, 'i18n', 'SortNumber_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Create the dialog (after translation) and keep reference self.dlg = SortNumberDialog() # Declare instance attributes self.actions = [] self.menu = self.tr(u'&Sort and Number') # TODO: We are going to let the user set this up in a future iteration self.toolbar = self.iface.addToolBar(u'SortNumber') self.toolbar.setObjectName(u'SortNumber') # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('SortNumber', message) def add_action( self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: self.toolbar.addAction(action) if add_to_menu: self.iface.addPluginToVectorMenu( self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/SortNumber/icon.png' self.add_action( icon_path, text=self.tr(u'Sort & Number'), callback=self.run, parent=self.iface.mainWindow()) self.dlg.layerComboBox.activated.connect( self.onLayerChange ) self.dlg.attributeComboBox1.activated.connect( self.onAttr1Change ) self.dlg.attributeComboBox2.activated.connect( self.onAttr2Change ) self.dlg.fieldNameLineEdit.textChanged.connect( self.checkRunButton ) self.dlg.runButton.clicked.connect( self.main ) def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginVectorMenu( self.tr(u'&Sort and Number'), action) self.iface.removeToolBarIcon(action) # remove the toolbar del self.toolbar def onLayerChange(self, index): self.excludeList = ["", ""] # selected fields (used to filter comboboxes) # if a layer is selectd, fill 1st attribute combobox if index > 0: self.dlg.attributeComboBox1.setEnabled(True) self.disableCheckBoxesFrom( 2 ) self.dlg.invCheckBox1.setEnabled(True) self.layer = self.dlg.layerComboBox.itemData( index ) self.fillAttrComboBox( self.dlg.attributeComboBox1 ) # else, disable 1st combobox else: self.dlg.attributeComboBox1.setEnabled(False) self.dlg.attributeComboBox1.clear() self.disableCheckBoxesFrom( 1 ) # disable other comboboxes self.dlg.attributeComboBox2.setEnabled(False) self.dlg.attributeComboBox2.clear() self.dlg.attributeComboBox3.setEnabled(False) self.dlg.attributeComboBox3.clear() self.checkRunButton() def onAttr1Change(self, index): # if a field is selected, fill 2nd attribute combobox if index > 0: self.dlg.attributeComboBox2.setEnabled(True) self.disableCheckBoxesFrom( 3 ) self.dlg.invCheckBox2.setEnabled(True) field = self.dlg.attributeComboBox1.itemData( index ) self.excludeList = [field.name(), ""] self.fillAttrComboBox( self.dlg.attributeComboBox2 ) # else, disable 2nd combobox else: self.dlg.attributeComboBox2.setEnabled(False) self.dlg.attributeComboBox2.clear() self.disableCheckBoxesFrom( 2 ) self.excludeList = ["", ""] # disable 3rd comboboxes self.dlg.attributeComboBox3.setEnabled(False) self.dlg.attributeComboBox3.clear() self.checkRunButton() def onAttr2Change(self, index): # if a field is selected, fill 3rd attribute combobox if index > 0: self.dlg.attributeComboBox3.setEnabled(True) self.dlg.invCheckBox3.setEnabled(True) field = self.dlg.attributeComboBox2.itemData( index ) self.excludeList[1] = field.name() self.fillAttrComboBox( self.dlg.attributeComboBox3 ) # else, disable 3rd combobox else: self.dlg.attributeComboBox3.setEnabled(False) self.dlg.attributeComboBox3.clear() self.disableCheckBoxesFrom( 3 ) self.excludeList[1] = "" def fillAttrComboBox(self, comboBox): comboBox.clear() # clear the combobox comboBox.addItem( '', None ) for field in self.layer.fields(): if not field.name() in self.excludeList: comboBox.addItem( field.name(), field ) def disableCheckBoxesFrom(self, idx): if idx < 2: self.dlg.invCheckBox1.setChecked(False) self.dlg.invCheckBox1.setEnabled(False) if idx < 3: self.dlg.invCheckBox2.setChecked(False) self.dlg.invCheckBox2.setEnabled(False) self.dlg.invCheckBox3.setChecked(False) self.dlg.invCheckBox3.setEnabled(False) def checkRunButton(self): if self.dlg.layerComboBox.currentIndex() > 0 and self.dlg.attributeComboBox1.currentIndex() > 0 and self.dlg.fieldNameLineEdit.text() != "": self.dlg.runButton.setEnabled(True) else: self.dlg.runButton.setEnabled(False) def main(self): # If attribute already exists if not self.layer.dataProvider().fields().indexFromName( self.dlg.fieldNameLineEdit.text() ) == -1: messageBox = QMessageBox() messageBox.setWindowTitle( "Sort and Number" ) messageBox.setText( self.tr("Field name already exists!") ) messageBox.setInformativeText( self.tr("Continue anyway? Existing values will be lost.") ) messageBox.setIcon( QMessageBox.Warning ) messageBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel); res = messageBox.exec_() # Cancel overwrite if res == QMessageBox.Cancel: # self.dlg.runButton.setEnabled(True) # self.dlg.closeButton.setEnabled(True) return # Continue and overwrite else: attrIdx = self.layer.dataProvider().fields().indexFromName( self.dlg.fieldNameLineEdit.text() ) # Reset order values to NULL self.layer.startEditing() for f in list( self.layer.getFeatures() ): self.layer.changeAttributeValue(f.id(), attrIdx, None) self.layer.commitChanges() else: # Add new attribute self.layer.dataProvider().addAttributes( [QgsField(self.dlg.fieldNameLineEdit.text(), QVariant.Int)] ) attrIdx = self.layer.dataProvider().fields().indexFromName( self.dlg.fieldNameLineEdit.text() ) self.layer.updateFields() # tell the vector layer to fetch changes from the provider self.dlg.runButton.setEnabled(False) # Get params field1 = self.dlg.attributeComboBox1.itemData( self.dlg.attributeComboBox1.currentIndex() ) field1Id = self.layer.dataProvider().fields().indexFromName( field1.name() ) isInv1 = self.dlg.invCheckBox1.isChecked() if self.dlg.attributeComboBox2.currentIndex() > 0: field2 = self.dlg.attributeComboBox2.itemData( self.dlg.attributeComboBox2.currentIndex() ) field2Id = self.layer.dataProvider().fields().indexFromName( field2.name() ) isInv2 = self.dlg.invCheckBox2.isChecked() else: field2 = None field2Id = None if self.dlg.attributeComboBox3.currentIndex() > 0: field3 = self.dlg.attributeComboBox3.itemData( self.dlg.attributeComboBox3.currentIndex() ) field3Id = self.layer.dataProvider().fields().indexFromName( field3.name() ) isInv3 = self.dlg.invCheckBox3.isChecked() else: field3 = None field3Id = None #locale.setlocale(locale.LC_ALL, "") # alphabetical sort if self.dlg.selFeatureCheckBox.isChecked(): featureList = list( self.layer.selectedFeatures() ) # Message to Log Messages Panel for debugging #QgsMessageLog.logMessage( "Use selected features only.", "QGISSortAndNumber", 0 ) else: featureList = list( self.layer.getFeatures() ) #QgsMessageLog.logMessage( "Use all features.", "QGISSortAndNumber", 0 ) if field3Id != None: featureList = sorted(featureList, key=lambda f: f[field3Id], reverse=isInv3) if field2Id != None: featureList = sorted(featureList, key=lambda f: f[field2Id], reverse=isInv2) featureList = sorted(featureList, key=lambda f: f[field1Id], reverse=isInv1) # add numbering field to layer self.layer.startEditing() for i, f in enumerate(featureList): #print f.id() self.layer.changeAttributeValue(f.id(), attrIdx, i+1) self.layer.commitChanges() # "Done" message messageBox = QMessageBox() messageBox.setWindowTitle( "Sort and Number" ) messageBox.setText( self.tr("Done") ) messageBox.setIcon( QMessageBox.Information ) messageBox.setStandardButtons(QMessageBox.Ok); res = messageBox.exec_() self.dlg.runButton.setEnabled(True) def run(self): """Run method that performs all the real work""" mapCanvas = self.iface.mapCanvas() # some elements are disabled by default self.disableCheckBoxesFrom( 1 ) self.dlg.attributeComboBox1.setEnabled(False) self.dlg.attributeComboBox1.clear() self.dlg.attributeComboBox2.setEnabled(False) self.dlg.attributeComboBox2.clear() self.dlg.attributeComboBox3.setEnabled(False) self.dlg.attributeComboBox3.clear() self.dlg.runButton.setEnabled(False) # list layers for input combobox self.dlg.layerComboBox.clear() # clear the combobox self.dlg.layerComboBox.addItem( '', None ) layers = list(QgsProject.instance().mapLayers().values()) # Create list with all layers for layer in layers: if layer.type() == QgsMapLayer.VectorLayer: # check if layer is vector self.dlg.layerComboBox.addItem( layer.name(), layer ) # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_()
class linedirectionhistogram: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save a reference to the QGIS interface self.iface = iface # initialize the plugin directory pluginPath = os.path.dirname(__file__) # initialize the locale using the QGIS locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join( pluginPath, 'i18n', '{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Create the dialog (after translation) and keep the reference self.dlg = linedirectionhistogramDialog(self.iface) # Declare instance attributes self.menuname = self.tr(u'&Line Direction Histogram') # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('LineDirectionHistogram', message) def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = os.path.join(os.path.dirname(__file__), "icon.png") # Create an action that will start the plugin configuration self.action = QAction( QIcon(icon_path), self.menuname, self.iface.mainWindow()) # connect the action to the run method self.action.triggered.connect(self.run) # Add toolbar icon if hasattr(self.iface, 'addVectorToolBarIcon'): self.iface.addVectorToolBarIcon(self.action) else: self.iface.addToolBarIcon(self.action) # Add menu item if hasattr(self.iface, 'addPluginToVectorMenu'): self.iface.addPluginToVectorMenu(self.menuname, self.action) else: self.iface.addPluginToMenu(self.menuname, self.action) def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" # Remove the plugin menu item if hasattr(self.iface, 'removePluginVectorMenu'): self.iface.removePluginVectorMenu(self.menuname, self.action) else: self.iface.removePluginMenu(self.menuname, self.action) # Remove the plugin toolbar icon if hasattr(self.iface, 'removeVectorToolBarIcon'): self.iface.removeVectorToolBarIcon(self.action) else: self.iface.removeToolBarIcon(self.action) def run(self): """Run method that performs all the real work""" # Do some initialisations # The progressbar self.dlg.progressBar.setValue(0.0) # Prepare for sorting layers = QgsProject.instance().mapLayers() layerslist = [] for id in layers.keys(): if layers[id].type() == QgsMapLayer.VectorLayer: if not layers[id].isValid(): QMessageBox.information(None, self.tr('Information'), 'Layer ' + layers[id].name() + ' is not valid') else: layerslist.append((layers[id].name(), id)) # Sort the layers by name layerslist.sort(key=lambda x: x[0], reverse=False) # Add the layers to the input layer combobox self.dlg.InputLayer.clear() for layerdescription in layerslist: if (layers[layerdescription[1]].geometryType() == QgsWkbTypes.LineGeometry or layers[layerdescription[1]].geometryType() == QgsWkbTypes.PolygonGeometry): self.dlg.InputLayer.addItem(layerdescription[0], layerdescription[1]) # Add the layers to the tiling layer combobox self.dlg.TilingLayer.clear() for layerdescription in layerslist: if (layers[layerdescription[1]].geometryType() == QgsWkbTypes.PolygonGeometry): self.dlg.TilingLayer.addItem(layerdescription[0], layerdescription[1]) # show the dialog self.dlg.show()
class Qdraw(object): def __init__(self, iface): locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join( os.path.dirname(__file__), 'i18n', 'qdraw_{}.qm'.format(locale)) self.translator = None if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) self.iface = iface self.sb = self.iface.statusBarIface() self.tool = None self.toolname = None self.bGeom = None self.actions = [] self.menu = '&Qdraw' self.toolbar = self.iface.addToolBar('Qdraw') self.toolbar.setObjectName('Qdraw') self.settings = QdrawSettings() def unload(self): for action in self.actions: self.iface.removePluginVectorMenu('&Qdraw', action) self.iface.removeToolBarIcon(action) del self.toolbar def tr(self, message): return QCoreApplication.translate('Qdraw', message) def add_action( self, icon_path, text, callback, enabled_flag=True, checkable=False, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, menu=None, parent=None): icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) action.setCheckable(checkable) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if menu is not None: action.setMenu(menu) if add_to_toolbar: self.toolbar.addAction(action) if add_to_menu: self.iface.addPluginToVectorMenu( self.menu, action) self.actions.append(action) return action def initGui(self): pointMenu = QMenu() pointMenu.addAction( QIcon(':/plugins/Qgeric/resources/icon_DrawPtXY.png'), self.tr('XY Point drawing tool'), self.drawXYPoint) pointMenu.addAction( QIcon(':/plugins/Qgeric/resources/icon_DrawPtDMS.png'), self.tr('DMS Point drawing tool'), self.drawDMSPoint) icon_path = ':/plugins/Qgeric/resources/icon_DrawPt.png' self.add_action( icon_path, text=self.tr('Point drawing tool'), checkable=True, menu=pointMenu, callback=self.drawPoint, parent=self.iface.mainWindow() ) icon_path = ':/plugins/Qgeric/resources/icon_DrawL.png' self.add_action( icon_path, text=self.tr('Line drawing tool'), checkable=True, callback=self.drawLine, parent=self.iface.mainWindow() ) icon_path = ':/plugins/Qgeric/resources/icon_DrawR.png' self.add_action( icon_path, text=self.tr('Rectangle drawing tool'), checkable=True, callback=self.drawRect, parent=self.iface.mainWindow() ) icon_path = ':/plugins/Qgeric/resources/icon_DrawC.png' self.add_action( icon_path, text=self.tr('Circle drawing tool'), checkable=True, callback=self.drawCircle, parent=self.iface.mainWindow() ) icon_path = ':/plugins/Qgeric/resources/icon_DrawP.png' self.add_action( icon_path, text=self.tr('Polygon drawing tool'), checkable=True, callback=self.drawPolygon, parent=self.iface.mainWindow() ) bufferMenu = QMenu() polygonBufferAction = QAction( QIcon(':/plugins/Qgeric/resources/icon_DrawTP.png'), self.tr('Polygon buffer drawing tool on the selected layer'), bufferMenu) polygonBufferAction.triggered.connect(self.drawPolygonBuffer) bufferMenu.addAction(polygonBufferAction) icon_path = ':/plugins/Qgeric/resources/icon_DrawT.png' self.add_action( icon_path, text=self.tr('Buffer drawing tool on the selected layer'), checkable=True, menu=bufferMenu, callback=self.drawBuffer, parent=self.iface.mainWindow() ) icon_path = ':/plugins/Qgeric/resources/icon_Settings.png' self.add_action( icon_path, text=self.tr('Settings'), callback=self.showSettingsWindow, parent=self.iface.mainWindow() ) def drawPoint(self): if self.tool: self.tool.reset() self.tool = DrawPoint(self.iface, self.settings.getColor()) self.tool.setAction(self.actions[0]) self.tool.selectionDone.connect(self.draw) self.iface.mapCanvas().setMapTool(self.tool) self.drawShape = 'point' self.toolname = 'drawPoint' self.resetSB() def drawXYPoint(self): tuple, ok = XYDialog().getPoint( self.iface.mapCanvas().mapSettings().destinationCrs()) point = tuple[0] self.XYcrs = tuple[1] if ok: if point.x() == 0 and point.y() == 0: QMessageBox.critical( self.iface.mainWindow(), self.tr('Error'), self.tr('Invalid input !')) else: self.drawPoint() self.tool.rb = QgsRubberBand( self.iface.mapCanvas(), QgsWkbTypes.PointGeometry) self.tool.rb.setColor(self.settings.getColor()) self.tool.rb.setWidth(3) self.tool.rb.addPoint(point) self.drawShape = 'XYpoint' self.draw() def drawDMSPoint(self): point, ok = DMSDialog().getPoint() self.XYcrs = QgsCoordinateReferenceSystem(4326) if ok: if point.x() == 0 and point.y() == 0: QMessageBox.critical( self.iface.mainWindow(), self.tr('Error'), self.tr('Invalid input !')) else: self.drawPoint() self.tool.rb = QgsRubberBand( self.iface.mapCanvas(), QgsWkbTypes.PointGeometry) self.tool.rb.setColor(self.settings.getColor()) self.tool.rb.setWidth(3) self.tool.rb.addPoint(point) self.drawShape = 'XYpoint' self.draw() def drawLine(self): if self.tool: self.tool.reset() self.tool = DrawLine(self.iface, self.settings.getColor()) self.tool.setAction(self.actions[1]) self.tool.selectionDone.connect(self.draw) self.tool.move.connect(self.updateSB) self.iface.mapCanvas().setMapTool(self.tool) self.drawShape = 'line' self.toolname = 'drawLine' self.resetSB() def drawRect(self): if self.tool: self.tool.reset() self.tool = DrawRect(self.iface, self.settings.getColor()) self.tool.setAction(self.actions[2]) self.tool.selectionDone.connect(self.draw) self.tool.move.connect(self.updateSB) self.iface.mapCanvas().setMapTool(self.tool) self.drawShape = 'polygon' self.toolname = 'drawRect' self.resetSB() def drawCircle(self): if self.tool: self.tool.reset() self.tool = DrawCircle(self.iface, self.settings.getColor(), 40) self.tool.setAction(self.actions[3]) self.tool.selectionDone.connect(self.draw) self.tool.move.connect(self.updateSB) self.iface.mapCanvas().setMapTool(self.tool) self.drawShape = 'polygon' self.toolname = 'drawCircle' self.resetSB() def drawPolygon(self): if self.tool: self.tool.reset() self.tool = DrawPolygon(self.iface, self.settings.getColor()) self.tool.setAction(self.actions[4]) self.tool.selectionDone.connect(self.draw) self.tool.move.connect(self.updateSB) self.iface.mapCanvas().setMapTool(self.tool) self.drawShape = 'polygon' self.toolname = 'drawPolygon' self.resetSB() def drawBuffer(self): self.bGeom = None if self.tool: self.tool.reset() self.tool = SelectPoint(self.iface, self.settings.getColor()) self.actions[5].setIcon( QIcon(':/plugins/Qgeric/resources/icon_DrawT.png')) self.actions[5].setText( self.tr('Buffer drawing tool on the selected layer')) self.actions[5].triggered.disconnect() self.actions[5].triggered.connect(self.drawBuffer) self.actions[5].menu().actions()[0].setIcon( QIcon(':/plugins/Qgeric/resources/icon_DrawTP.png')) self.actions[5].menu().actions()[0].setText( self.tr('Polygon buffer drawing tool on the selected layer')) self.actions[5].menu().actions()[0].triggered.disconnect() self.actions[5].menu().actions()[0].triggered.connect( self.drawPolygonBuffer) self.tool.setAction(self.actions[5]) self.tool.select.connect(self.selectBuffer) self.tool.selectionDone.connect(self.draw) self.iface.mapCanvas().setMapTool(self.tool) self.drawShape = 'polygon' self.toolname = 'drawBuffer' self.resetSB() def drawPolygonBuffer(self): self.bGeom = None if self.tool: self.tool.reset() self.tool = DrawPolygon(self.iface, self.settings.getColor()) self.actions[5].setIcon( QIcon(':/plugins/Qgeric/resources/icon_DrawTP.png')) self.actions[5].setText( self.tr('Polygon buffer drawing tool on the selected layer')) self.actions[5].triggered.disconnect() self.actions[5].triggered.connect(self.drawPolygonBuffer) self.actions[5].menu().actions()[0].setIcon( QIcon(':/plugins/Qgeric/resources/icon_DrawT.png')) self.actions[5].menu().actions()[0].setText( self.tr('Buffer drawing tool on the selected layer')) self.actions[5].menu().actions()[0].triggered.disconnect() self.actions[5].menu().actions()[0].triggered.connect(self.drawBuffer) self.tool.setAction(self.actions[5]) self.tool.selectionDone.connect(self.selectBuffer) self.iface.mapCanvas().setMapTool(self.tool) self.drawShape = 'polygon' self.toolname = 'drawBuffer' self.resetSB() def showSettingsWindow(self): self.settings.settingsChanged.connect(self.settingsChangedSlot) self.settings.show() # triggered when a setting is changed def settingsChangedSlot(self): if self.tool: self.tool.rb.setColor(self.settings.getColor()) def resetSB(self): message = { 'drawPoint': 'Left click to place a point.', 'drawLine': 'Left click to place points. Right click to confirm.', 'drawRect': 'Maintain the left click to draw a rectangle.', 'drawCircle': 'Maintain the left click to draw a circle. \ Simple Left click to give a perimeter.', 'drawPolygon': 'Left click to place points. Right click to \ confirm.', 'drawBuffer': 'Select a vector layer in the Layer Tree, \ then select an entity on the map.' } self.sb.showMessage(self.tr(message[self.toolname])) def updateSB(self): g = self.geomTransform( self.tool.rb.asGeometry(), self.iface.mapCanvas().mapSettings().destinationCrs(), QgsCoordinateReferenceSystem(2154)) if self.toolname == 'drawLine': if g.length() >= 0: self.sb.showMessage( self.tr('Length') + ': ' + str("%.2f" % g.length()) + " m") else: self.sb.showMessage(self.tr('Length')+': '+"0 m") else: if g.area() >= 0: self.sb.showMessage( self.tr('Area')+': '+str("%.2f" % g.area())+" m"+u'²') else: self.sb.showMessage(self.tr('Area')+': '+"0 m"+u'²') self.iface.mapCanvas().mapSettings().destinationCrs().authid() def geomTransform(self, geom, crs_orig, crs_dest): g = QgsGeometry(geom) crsTransform = QgsCoordinateTransform( crs_orig, crs_dest, QgsCoordinateTransformContext()) # which context ? g.transform(crsTransform) return g def selectBuffer(self): rb = self.tool.rb if isinstance(self.tool, DrawPolygon): rbSelect = self.tool.rb else: rbSelect = self.tool.rbSelect layer = self.iface.layerTreeView().currentLayer() if layer is not None and layer.type() == QgsMapLayer.VectorLayer \ and self.iface.layerTreeView().currentNode().isVisible(): # rubberband reprojection g = self.geomTransform( rbSelect.asGeometry(), self.iface.mapCanvas().mapSettings().destinationCrs(), layer.crs()) features = layer.getFeatures(QgsFeatureRequest(g.boundingBox())) rbGeom = [] for feature in features: geom = feature.geometry() try: if g.intersects(geom): rbGeom.append(feature.geometry()) except: # there's an error but it intersects # fix_print_with_import print('error with '+layer.name()+' on '+str(feature.id())) rbGeom.append(feature.geometry()) if len(rbGeom) > 0: for geometry in rbGeom: if rbGeom[0].combine(geometry) is not None: if self.bGeom is None: self.bGeom = geometry else: self.bGeom = self.bGeom.combine(geometry) rb.setToGeometry(self.bGeom, layer) if isinstance(self.tool, DrawPolygon): self.draw() def draw(self): rb = self.tool.rb g = rb.asGeometry() ok = True warning = False errBuffer_noAtt = False errBuffer_Vertices = False layer = self.iface.layerTreeView().currentLayer() if self.toolname == 'drawBuffer': if self.bGeom is None: warning = True errBuffer_noAtt = True else: perim, ok = QInputDialog.getDouble( self.iface.mainWindow(), self.tr('Perimeter'), self.tr('Give a perimeter in m:') + '\n'+self.tr('(works only with metric crs)'), min=0) g = self.bGeom.buffer(perim, 40) rb.setToGeometry(g, QgsVectorLayer( "Polygon?crs="+layer.crs().authid(), "", "memory")) if g.length() == 0 and ok: warning = True errBuffer_Vertices = True if self.toolname == 'drawCopies': if g.length() < 0: warning = True errBuffer_noAtt = True if ok and not warning: name = '' ok = True add = False index = 0 layers = [] while not name.strip() and not add and ok: dlg = QDrawLayerDialog(self.iface, self.drawShape) name, add, index, layers, ok = dlg.getName( self.iface, self.drawShape) if ok and not warning: layer = None if add: layer = layers[index] if self.drawShape in ['point', 'XYpoint']: g = g.centroid() else: if self.drawShape == 'point': layer = QgsVectorLayer("Point?crs="+self.iface.mapCanvas().mapSettings().destinationCrs().authid()+"&field="+self.tr('Drawings')+":string(255)", name, "memory") g = g.centroid() # force geometry as point elif self.drawShape == 'XYpoint': layer = QgsVectorLayer("Point?crs="+self.XYcrs.authid()+"&field="+self.tr('Drawings')+":string(255)", name, "memory") g = g.centroid() elif self.drawShape == 'line': layer = QgsVectorLayer("LineString?crs="+self.iface.mapCanvas().mapSettings().destinationCrs().authid()+"&field="+self.tr('Drawings')+":string(255)", name, "memory") # fix_print_with_import print("LineString?crs="+self.iface.mapCanvas().mapSettings().destinationCrs().authid()+"&field="+self.tr('Drawings')+":string(255)") else: layer = QgsVectorLayer("Polygon?crs="+self.iface.mapCanvas().mapSettings().destinationCrs().authid()+"&field="+self.tr('Drawings')+":string(255)", name, "memory") layer.startEditing() symbols = layer.renderer().symbols(QgsRenderContext()) # todo which context ? symbols[0].setColor(self.settings.getColor()) feature = QgsFeature() feature.setGeometry(g) feature.setAttributes([name]) layer.dataProvider().addFeatures([feature]) layer.commitChanges() if not add: pjt = QgsProject.instance() pjt.addMapLayer(layer, False) if pjt.layerTreeRoot().findGroup(self.tr('Drawings')) is None: pjt.layerTreeRoot().insertChildNode( 0, QgsLayerTreeGroup(self.tr('Drawings'))) group = pjt.layerTreeRoot().findGroup( self.tr('Drawings')) group.insertLayer(0, layer) self.iface.layerTreeView().refreshLayerSymbology(layer.id()) self.iface.mapCanvas().refresh() else: if warning: if errBuffer_noAtt: self.iface.messageBar().pushWarning( self.tr('Warning'), self.tr('You didn\'t click on a layer\'s attribute !')) elif errBuffer_Vertices: self.iface.messageBar().pushWarning( self.tr('Warning'), self.tr('You must give a non-null value for a \ point\'s or line\'s perimeter !')) else: self.iface.messageBar().pushWarning( self.tr('Warning'), self.tr('There is no selected layer, or it is not \ vector nor visible !')) self.tool.reset() self.resetSB() self.bGeom = None
class QuickMapServices(object): """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = get_file_dir(__file__) # initialize locale self.translator = QTranslator() self.locale = Locale.get_locale() locale_path = os.path.join( self.plugin_dir, 'i18n', 'QuickMapServices_{}.qm'.format(self.locale)) if os.path.exists(locale_path): r = self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) self.custom_translator = CustomTranslator() QCoreApplication.installTranslator(self.custom_translator) # Create the dialog (after translation) and keep reference self.info_dlg = AboutDialog() # Check Contrib and User dirs try: ExtraSources.check_extra_dirs() except: error_message = self.tr('Extra dirs for %s can\'t be created: %s %s') % (PluginSettings.product_name(), sys.exc_type, sys.exc_value) self.iface.messageBar().pushMessage(self.tr('Error'), error_message, level=QgsMessageBar.CRITICAL) # Declare instance attributes self.service_actions = [] self.service_layers = [] # TODO: id and smart remove self._scales_list = None # noinspection PyMethodMayBeStatic def tr(self, message): # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('QuickMapServices', message) def initGui(self): #import pydevd #pydevd.settrace('localhost', port=9921, stdoutToServer=True, stderrToServer=True, suspend=False) # Register plugin layer type self.tileLayerType = TileLayerType(self) qgisRegistryInstance.addPluginLayerType(self.tileLayerType) # Create menu icon_path = self.plugin_dir + '/icons/mActionAddLayer.svg' self.menu = QMenu(self.tr(u'QuickMapServices')) self.menu.setIcon(QIcon(icon_path)) self.init_server_panel() self.build_menu_tree() # add to QGIS menu/toolbars self.append_menu_buttons() def _load_scales_list(self): scales_filename = os.path.join(self.plugin_dir, 'scales.xml') scales_list = [] # TODO: remake when fix: http://hub.qgis.org/issues/11915 # QgsScaleUtils.loadScaleList(scales_filename, scales_list, importer_message) xml_root = ET.parse(scales_filename).getroot() for scale_el in xml_root.findall('scale'): scales_list.append(scale_el.get('value')) return scales_list @property def scales_list(self): if not self._scales_list: self._scales_list = self._load_scales_list() return self._scales_list def set_nearest_scale(self): #get current scale curr_scale = self.iface.mapCanvas().scale() #find nearest nearest_scale = sys.maxsize for scale_str in self.scales_list: scale = scale_str.split(':')[1] scale_int = int(scale) if abs(scale_int-curr_scale) < abs(nearest_scale - curr_scale): nearest_scale = scale_int #set new scale if nearest_scale != sys.maxsize: self.iface.mapCanvas().zoomScale(nearest_scale) def set_tms_scales(self): res = QMessageBox.question( self.iface.mainWindow(), self.tr('QuickMapServices'), self.tr('Set SlippyMap scales for current project? \nThe previous settings will be overwritten!'), QMessageBox.Yes | QMessageBox.No) if res == QMessageBox.Yes: # set scales QgsProject.instance().writeEntry('Scales', '/ScalesList', self.scales_list) # activate QgsProject.instance().writeEntry('Scales', '/useProjectScales', True) # update in main window # ???? no way to update: http://hub.qgis.org/issues/11917 def insert_layer(self): action = self.menu.sender() ds = action.data() add_layer_to_map(ds) def unload(self): # remove menu/panels self.remove_menu_buttons() self.remove_server_panel() # clean vars self.menu = None self.toolbutton = None self.service_actions = None self.ds_list = None self.groups_list = None self.service_layers = None # # Unregister plugin layer type qgisRegistryInstance.removePluginLayerType(TileLayer.LAYER_TYPE) def build_menu_tree(self): # Main Menu self.menu.clear() self.groups_list = GroupsList() self.ds_list = DataSourcesList() data_sources = self.ds_list.data_sources.values() data_sources = sorted(data_sources, key=lambda x: x.alias or x.id) ds_hide_list = PluginSettings.get_hide_ds_id_list() for ds in data_sources: if ds.id in ds_hide_list: continue ds.action.triggered.connect(self.insert_layer) gr_menu = self.groups_list.get_group_menu(ds.group) gr_menu.addAction(ds.action) if gr_menu not in self.menu.children(): self.menu.addMenu(gr_menu) # QMS web service self.menu.addSeparator() self.service_actions.append(self.qms_search_action) self.menu.addAction(self.qms_search_action) icon_create_service_path = self.plugin_dir + '/icons/mActionCreate.svg' qms_create_service_action = QAction(self.tr('Add to Search'), self.iface.mainWindow()) qms_create_service_action.setIcon(QIcon(icon_create_service_path)) qms_create_service_action.triggered.connect(self.openURL) self.menu.addAction(qms_create_service_action) # Scales, Settings and About actions self.menu.addSeparator() icon_set_nearest_scale_path = self.plugin_dir + '/icons/mActionSettings.svg' # TODO change icon set_nearest_scale_act = QAction(QIcon(icon_set_nearest_scale_path), self.tr('Set proper scale'), self.iface.mainWindow()) set_nearest_scale_act.triggered.connect(self.set_nearest_scale) self.menu.addAction(set_nearest_scale_act) # TODO: uncomment after fix self.service_actions.append(set_nearest_scale_act) icon_scales_path = self.plugin_dir + '/icons/mActionSettings.svg' # TODO change icon scales_act = QAction(QIcon(icon_scales_path), self.tr('Set SlippyMap scales'), self.iface.mainWindow()) scales_act.triggered.connect(self.set_tms_scales) #self.menu.addAction(scales_act) # TODO: uncomment after fix self.service_actions.append(scales_act) icon_settings_path = self.plugin_dir + '/icons/mActionSettings.svg' settings_act = QAction(QIcon(icon_settings_path), self.tr('Settings'), self.iface.mainWindow()) self.service_actions.append(settings_act) settings_act.triggered.connect(self.show_settings_dialog) self.menu.addAction(settings_act) icon_about_path = self.plugin_dir + '/icons/mActionAbout.svg' info_act = QAction(QIcon(icon_about_path), self.tr('About'), self.iface.mainWindow()) self.service_actions.append(info_act) info_act.triggered.connect(self.info_dlg.show) self.menu.addAction(info_act) def remove_menu_buttons(self): """ Remove menus/buttons from all toolbars and main submenu :return: None """ # remove menu if self.menu: self.iface.webMenu().removeAction(self.menu.menuAction()) self.iface.addLayerMenu().removeAction(self.menu.menuAction()) # remove toolbar button if self.tb_action: self.iface.webToolBar().removeAction(self.tb_action) self.iface.layerToolBar().removeAction(self.tb_action) if self.qms_search_action: self.iface.webToolBar().removeAction(self.qms_search_action) self.iface.layerToolBar().removeAction(self.qms_search_action) def append_menu_buttons(self): """ Append menus and buttons to appropriate toolbar :return: """ # add to QGIS menu if PluginSettings.move_to_layers_menu(): self.iface.addLayerMenu().addMenu(self.menu) else: # need workaround for WebMenu _temp_act = QAction('temp', self.iface.mainWindow()) self.iface.addPluginToWebMenu("_tmp", _temp_act) self.iface.webMenu().addMenu(self.menu) self.iface.removePluginWebMenu("_tmp", _temp_act) # add to QGIS toolbar toolbutton = QToolButton() toolbutton.setPopupMode(QToolButton.InstantPopup) toolbutton.setMenu(self.menu) toolbutton.setIcon(self.menu.icon()) toolbutton.setText(self.menu.title()) toolbutton.setToolTip(self.menu.title()) # self.tb_action = toolbutton.defaultAction() # print "self.tb_action: ", self.tb_action if PluginSettings.move_to_layers_menu(): self.tb_action = self.iface.layerToolBar().addWidget(toolbutton) self.iface.layerToolBar().addAction(self.qms_search_action) else: self.tb_action = self.iface.webToolBar().addWidget(toolbutton) self.iface.webToolBar().addAction(self.qms_search_action) def show_settings_dialog(self): settings_dlg = SettingsDialog() settings_dlg.exec_() # apply settings # self.remove_menu_buttons() self.build_menu_tree() # self.append_menu_buttons() def init_server_panel(self): self.server_toolbox = QmsServiceToolbox(self.iface) self.iface.addDockWidget(PluginSettings.server_dock_area(), self.server_toolbox) self.server_toolbox.setWindowIcon(QIcon(self.plugin_dir + '/icons/mActionSearch.svg')) self.server_toolbox.setVisible(PluginSettings.server_dock_visibility()) # self.server_toolbox.setFloating(PluginSettings.dock_floating()) # self.server_toolbox.resize(PluginSettings.dock_size()) # self.server_toolbox.move(PluginSettings.dock_pos()) # self.server_toolbox.setWindowIcon(QIcon(path.join(_current_path, 'edit-find-project.png'))) # QMS search action icon_settings_path = self.plugin_dir + '/icons/mActionSearch.svg' self.qms_search_action = self.server_toolbox.toggleViewAction() self.qms_search_action.setIcon(QIcon(icon_settings_path)) self.qms_search_action.setText(self.tr('Search QMS')) def remove_server_panel(self): mw = self.iface.mainWindow() PluginSettings.set_server_dock_area(mw.dockWidgetArea(self.server_toolbox)) PluginSettings.set_server_dock_visibility(self.server_toolbox.isVisible()) # PluginSettings.set_dock_floating(self.__quick_tlb.isFloating()) # PluginSettings.set_dock_pos(self.__quick_tlb.pos()) # PluginSettings.set_dock_size(self.__quick_tlb.size()) # PluginSettings.set_dock_geocoder_name(self.__quick_tlb.get_active_geocoder_name()) self.iface.removeDockWidget(self.server_toolbox) del self.server_toolbox def openURL(self): QDesktopServices.openUrl(QUrl("https://qms.nextgis.com/create"))
class ThreeDiCustomStats: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join( self.plugin_dir, 'i18n', 'ThreeDiCustomStats_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.actions = [] self.menu = self.tr(u'&3Di Custom Statistics') # Check if plugin was started the first time in current QGIS session # Must be set in initGui() to survive plugin reloads self.first_start = None self.tm = QgsApplication.taskManager() # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('ThreeDiCustomStats', message) def add_action( self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: # Adds plugin icon to Plugins toolbar self.iface.addToolBarIcon(action) if add_to_menu: self.iface.addPluginToMenu( self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/threedi_custom_stats/icon.png' self.add_action( icon_path, text=self.tr(u'3Di Custom Statistics'), callback=self.run, parent=self.iface.mainWindow()) # will be set False in run() self.first_start = True def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginMenu( self.tr(u'&3Di Custom Statistics'), action) self.iface.removeToolBarIcon(action) def run(self): """Run method that performs all the real work""" # Create the dialog with elements (after translation) and keep reference # Only create GUI ONCE in callback, so that it will only load when the plugin is started if self.first_start: self.first_start = False self.dlg = ThreeDiCustomStatsDialog(self.iface) # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: # 3Di results results_3di = self.dlg.QgsFileWidget3DiResults.filePath() grid_admin = self.dlg.QgsFileWidgetGridAdmin.filePath() # Filtering parameters start_time = self.dlg.doubleSpinBoxStartTime.value() end_time = self.dlg.doubleSpinBoxEndTime.value() bbox_qgs_rectangle = self.dlg.mExtentGroupBox.outputExtent() # bbox is now a https://qgis.org/pyqgis/master/core/QgsRectangle.html#qgis.core.QgsRectangle bbox = None if bbox_qgs_rectangle is not None: if not bbox_qgs_rectangle.isEmpty(): bbox = [bbox_qgs_rectangle.xMinimum(), bbox_qgs_rectangle.yMinimum(), bbox_qgs_rectangle.xMaximum(), bbox_qgs_rectangle.yMaximum()] subsets = [] if self.dlg.checkBox1D2DConnections.isChecked(): subsets.append('1D2D') if self.dlg.checkBoxAll1D.isChecked(): subsets.append('All1D') if self.dlg.checkBoxAll2D.isChecked(): subsets.append('All2D') if self.dlg.checkBoxAllSewerage.isChecked(): subsets.append('AllSewerage') if self.dlg.checkBoxCulverts.isChecked(): subsets.append('Culverts') if self.dlg.checkBoxOrifices.isChecked(): subsets.append('Orifices') if self.dlg.checkBoxPipes.isChecked(): subsets.append('Pipes') if self.dlg.checkBoxWeirs.isChecked(): subsets.append('Weirs') # Resolution resolution = self.dlg.doubleSpinBoxResolution.value() # Outputs output_flowlines = self.dlg.groupBoxFlowlines.isChecked() output_nodes = self.dlg.groupBoxNodes.isChecked() output_cells = self.dlg.groupBoxCells.isChecked() output_rasters = self.dlg.groupBoxRasters.isChecked() # Resample point layer resample_point_layer = self.dlg.checkBoxResample.isChecked() if resample_point_layer: interpolation_method = 'linear' else: interpolation_method = None aggregate_threedi_results_task = Aggregate3DiResults( description='Aggregate 3Di Results', parent=self.dlg, gridadmin=grid_admin, results_3di=results_3di, demanded_aggregations=self.dlg.demanded_aggregations, bbox=bbox, start_time=start_time, end_time=end_time, subsets=subsets, interpolation_method=interpolation_method, resample_point_layer=resample_point_layer, resolution=resolution, output_flowlines=output_flowlines, output_cells=output_cells, output_nodes=output_nodes, output_rasters=output_rasters ) self.tm.addTask(aggregate_threedi_results_task)
class ConstraintChecker: def __init__(self, iface): # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value("locale/userLocale")[0:2] localePath = os.path.join(self.plugin_dir, 'i18n', 'constraintchecker_{}.qm'.format(locale)) if os.path.exists(localePath): self.translator = QTranslator() self.translator.load(localePath) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Create the dialog (after translation) and keep reference # self.dlg = ConstraintCheckerDialog() self.freeHandTool = FreehandPolygonMaptool(self.iface.mapCanvas()) def initGui(self): # Create action that will start plugin configuration self.existingCheckAction = QAction( QIcon(os.path.join(self.plugin_dir, "images/checker_select_32.png")), "Check Constraints for Existing Polygon", self.iface.mainWindow()) self.freehandCheckAction = QAction( QIcon(os.path.join(self.plugin_dir, "images/checker_freehand_32.png")), "Check Constraints for Free-hand Polygon", self.iface.mainWindow()) self.openConfigurationAction = QAction( QIcon(os.path.join(self.plugin_dir, "images/checker_config_32.png")), "Edit Configuration", self.iface.mainWindow()) # connect the action to the run method self.existingCheckAction.triggered.connect(self.checkExistingGeometry) self.freehandCheckAction.triggered.connect(self.checkFreehandGeometry) self.openConfigurationAction.triggered.connect(self.openConfiguration) # Add toolbar button and menu item self.iface.addToolBarIcon(self.existingCheckAction) self.iface.addToolBarIcon(self.freehandCheckAction) self.iface.addPluginToMenu("&Constraint Checker", self.existingCheckAction) self.iface.addPluginToMenu("&Constraint Checker", self.freehandCheckAction) self.iface.addPluginToMenu("&Constraint Checker", self.openConfigurationAction) self.freeHandTool.trigger.connect(self.receiveFeature) def unload(self): # Remove the plugin menu item and icon self.iface.removePluginMenu("&Constraint Checker", self.existingCheckAction) self.iface.removePluginMenu("&Constraint Checker", self.freehandCheckAction) self.iface.removePluginMenu("&Constraint Checker", self.openConfigurationAction) self.iface.removeToolBarIcon(self.existingCheckAction) self.iface.removeToolBarIcon(self.freehandCheckAction) self.freeHandTool.trigger.disconnect() def receiveFeature(self, geom): crs = self.iface.mapCanvas().mapSettings().destinationCrs() epsg = int(crs.authid().split('EPSG:')[1]) self.iface.mapCanvas().unsetMapTool(self.freeHandTool) self.constraintCheck(geom, epsg) def checkExistingGeometry(self): """ The user should already have a feature selected. Ensure this is the case and then send the geometry to the main function. """ erTitle = 'Select a feature' erMsg = 'Please select a single feature in a loaded vector layer.' if self.iface.mapCanvas().layerCount() < 1: QMessageBox.critical(self.iface.mainWindow(), erTitle, erMsg) return currentLayer = self.iface.mapCanvas().currentLayer() if currentLayer is None or currentLayer.type() != QgsMapLayer.VectorLayer: QMessageBox.critical(self.iface.mainWindow(), erTitle, erMsg) return if currentLayer.selectedFeatureCount() != 1: QMessageBox.critical(self.iface.mainWindow(), erTitle, erMsg) return # By this point the user has a single, existing feature selected # Now pass the geometry to the query # Due to an existing bug ? 777 # We need to fetch the list first before taking off the feature we want selFeats = currentLayer.selectedFeatures() geom = QgsGeometry(selFeats[0].geometry()) authid = currentLayer.crs().authid() try: epsg = int(authid.split('EPSG:')[1]) except: msg = 'Please ensure the layer to which the query feature belongs has a CRS set.' QMessageBox.critical(self.iface.mainWindow(), 'Failed to determine CRS', msg) return self.constraintCheck(geom, epsg) def checkFreehandGeometry(self): self.iface.messageBar().pushMessage("Constraint Checker", "Please digitise your area of interest - Right-click to add last vertex.", level=Qgis.Info, duration=10) self.iface.mapCanvas().setMapTool(self.freeHandTool) def constraintCheck(self, queryGeom, epsg): # Prompt the user for a reference number refDlg = ReferenceNumberDialog() result = refDlg.exec_() if result == QDialog.Rejected: # User pressed cancel return refNumber = refDlg.getRefNumber() try: c = Checker(self.iface, refNumber) c.check(queryGeom, epsg) c.display() except: msg = 'The query failed and the detailed error was:\n\n%s' % traceback.format_exc() QMessageBox.critical(self.iface.mainWindow(), 'Query Failed', msg) def openConfiguration(self): # Display the configuration editor dialog d = ConfigurationDialog(self.iface) d.exec_()
class CertCveCatastral: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale self.dlg = CertCveCatastralDialog(parent = iface.mainWindow()) locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join( self.plugin_dir, 'i18n', 'CertCveCatastral_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.actions = [] self.menu = self.tr(u'&Cert Cve Catastral') self.canvas = iface.mapCanvas() self.abrePredio = False self.directorioAGuardar = None self.cve_catastral = None #eventos self.dlg.btnBrowse.clicked.connect(self.selectDirectory) self.dlg.btnGenerar.clicked.connect(self.generarDoc) self.dlg.btnSeleccionar.clicked.connect(self.activarSeleccion) self.dlg.exit_signal.connect(self.closeEvent) self.dlg.fldCveCat.textChanged.connect(self.lineEditToUpper) rx = QRegExp("[a-zA-Z0-9]{31}") val = QRegExpValidator(rx) self.dlg.fldCveCat.setValidator(val) # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('CertCveCatastral', message) def add_action( self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: # Adds plugin icon to Plugins toolbar self.iface.addToolBarIcon(action) if add_to_menu: self.iface.addPluginToMenu( self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/cert_cve_catastral/icon.png' self.add_action( icon_path, text=self.tr(u''), callback=self.run, parent=self.iface.mainWindow()) # will be set False in run() self.first_start = True def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginMenu( self.tr(u'&Cert Cve Catastral'), action) self.iface.removeToolBarIcon(action) def run(self): """Run method that performs all the real work""" self.obtenerXCapas1() self.xManzana.selectionChanged.connect(self.seleccionaClave) self.xPredGeom.selectionChanged.connect(self.seleccionaClave) self.xPredNum.selectionChanged.connect(self.seleccionaClave) self.xConst.selectionChanged.connect(self.seleccionaClave) self.xHoriGeom.selectionChanged.connect(self.seleccionaClave) self.xHoriNum.selectionChanged.connect(self.seleccionaClave) self.xVert.selectionChanged.connect(self.seleccionaClave) self.xCvesVert.selectionChanged.connect(self.seleccionaClave) # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: # Do something useful here - delete the line containing pass and # substitute with your code. pass def selectDirectory(self): # self.archivo = QtGui.QFileDialog.getOpenFileName(self, 'Abir Archivo') options = QFileDialog.Options() options |= QFileDialog.Directory options |= QFileDialog.ShowDirsOnly directory = QFileDialog.getExistingDirectory(self.dlg, "Elige un directorio", options=options) if directory: self.directorioAGuardar = directory self.dlg.fldDirectorio.setText(directory) def generarDoc(self): self.cve_catastral = self.dlg.fldCveCat.text() if not (self.directorioAGuardar and self.cve_catastral): self.UTI.mostrarAlerta("Por favor llene los campos.", QMessageBox.Critical, "Certificacion clave catastral") return m = {} m['claveCatastral'] = self.cve_catastral print(m) jsonParaGuardarAtributos = json.dumps(m) print(jsonParaGuardarAtributos) url = self.CFG.urlCertCveCat payload = jsonParaGuardarAtributos headers = {'Content-Type': 'application/json', 'Authorization': self.UTI.obtenerToken()} try: response = requests.post(url, headers = headers, data = payload) print(requests.post(url + self.cve_catastral, headers=headers)) d = response.headers['content-disposition'] print(f"DIRECTORIO: {self.directorioAGuardar}") fname = re.findall("filename=(.+)", d)[0].strip('"') ruta = f"{self.directorioAGuardar }/{fname}" f = open( ruta, 'wb') f.write(response.content) f.close() self.cambiarStatus("Archivo guardado", "ok") except requests.exceptions.RequestException: self.UTI.mostrarAlerta("No se ha podido conectar al servidor v1", QMessageBox.Critical, "Certificacion clave catastral") # Error en la peticion de consulta self.cancelaSeleccion() def seleccionaClave(self): capaActiva = self.iface.activeLayer() features = [] if capaActiva: # saber cual capa esta activa, a cual se le dio click if capaActiva.id() == self.ACA.obtenerIdCapa('predios.geom'): features = self.xPredGeom.selectedFeatures() # validar si el predio contiene algun condominio condVCve = self.xCvesVert.getFeatures() condHori = self.xHoriGeom.getFeatures() # -- buscar si el predio seleccionado contiene condominios # -* ya sean verticales u horizontales for p in features: geomP = p.geometry() # verifica si tiene claves de verticales for cv in condVCve: geom = cv.geometry() if geom.within(geomP): cond = True break # verifica si tiene horizontales for cv in condHori: geom = cv.geometry().buffer(-0.000001, 1) if geom.within(geomP): cond = True break elif capaActiva.id() == self.ACA.obtenerIdCapa('horizontales.geom'): features = self.xHoriGeom.selectedFeatures() cond = True elif capaActiva.id() == self.ACA.obtenerIdCapa('cves_verticales'): features = self.xCvesVert.selectedFeatures() cond = True if len(features) == 0: self.cambiarStatus("Seleccione una geometria valida", "error") self.cancelaSeleccionYRepinta() return if len(features) != 1: self.cambiarStatus("Seleccione una sola geometria", "error") self.cancelaSeleccionYRepinta() return else: self.cambiarStatus("Predio seleccionado", "ok") feat = features[0] self.cve_catastral = feat['cve_cat'] self.dlg.fldCveCat.setText(self.cve_catastral) self.dlg.btnSeleccionar.setEnabled(True) else: self.UTI.mostrarAlerta("Elija una capa.", QMessageBox.Critical, "Certificacion clave catastral") def activarSeleccion(self): if not self.abrePredio: self.iface.actionSelect().trigger() self.canvas.setCursor(self.UTI.cursorRedondo) self.dlg.btnSeleccionar.setEnabled(False) self.abrePredio = True def cancelaSeleccion(self): if self.abrePredio: self.dlg.btnSeleccionar.setEnabled(True) # regresa herramienta de seleccion normal self.iface.actionPan().trigger() self.cambiarStatus("Listo...", "ok") self.abrePredio = False def cancelaSeleccionYRepinta(self): self.dlg.btnSeleccionar.setEnabled(True) self.xPredGeom.removeSelection() self.xHoriGeom.removeSelection() self.xCvesVert.removeSelection() self.xManzana.removeSelection() self.xPredNum.removeSelection() self.xConst.removeSelection() self.xHoriNum.removeSelection() self.xVert.removeSelection() self.canvas.refresh() # regresa herramienta de seleccion normal self.iface.actionPan().trigger() self.abrePredio = False #recibimos el closeEvent del dialog def closeEvent(self, msg): if msg: self.cancelaSeleccionYRepinta() def cambiarStatus(self, texto, estado): self.dlg.lbEstatusCedula.setText(texto) if estado == "ok": # abriendo self.dlg.lbEstatusCedula.setStyleSheet('color: green') elif estado == "error": # Seleccione un solo predio self.dlg.lbEstatusCedula.setStyleSheet('color: red') else: self.dlg.lbEstatusCedula.setStyleSheet('color: black') def lineEditToUpper(self): self.dlg.fldCveCat.setText(self.dlg.fldCveCat.text().upper()) def obtenerXCapas1(self): # carga las capas en caso de no existir # self.UTI.cargarCapaVacio() xMan = QSettings().value('xManzana') xPredG = QSettings().value('xPredGeom') xPredN = QSettings().value('xPredNum') xCon = QSettings().value('xConst') xHoriG = QSettings().value('xHoriGeom') xHoriN = QSettings().value('xHoriNum') xVe = QSettings().value('xVert') xCv = QSettings().value('xCvesVert') self.xManzana = QgsProject.instance().mapLayer(xMan) self.xPredGeom = QgsProject.instance().mapLayer(xPredG) self.xPredNum = QgsProject.instance().mapLayer(xPredN) self.xConst = QgsProject.instance().mapLayer(xCon) self.xHoriGeom = QgsProject.instance().mapLayer(xHoriG) self.xHoriNum = QgsProject.instance().mapLayer(xHoriN) self.xVert = QgsProject.instance().mapLayer(xVe) self.xCvesVert = QgsProject.instance().mapLayer(xCv)
class Qchainage(object): """Main class for Chainage """ def __init__(self, iface): # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale_path = "" locale = QSettings().value("locale/userLocale")[0:2] if QFileInfo(self.plugin_dir).exists(): locale_path = self.plugin_dir + "/i18n/qchainage_" + locale + ".qm" if QFileInfo(locale_path).exists(): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) def initGui(self): """Initiate GUI """ # Create action that will start plugin configuration self.action = QAction( QIcon(":/plugins/qchainage/img/qchainage.svg"), u"QChainage", self.iface.mainWindow()) # connect the action to the run method self.action.triggered.connect(self.run) # Add toolbar button and menu item self.iface.addToolBarIcon(self.action) self.iface.addPluginToVectorMenu(u"&QChainage", self.action) def unload(self): """ Unloading the plugin """ # Remove the plugin menu item and icon self.iface.removePluginVectorMenu(u"&QChainage", self.action) self.iface.removeToolBarIcon(self.action) def run(self): """ Running the plugin """ # otf = self.iface.mapCanvas().mapRenderer().hasCrsTransformEnabled() # if otf: # message = "There might be wrong results with OTF switched on." \ # "Please switch it off and chainage the layer you want to" # show_warning(self, message) leave = -1 for layer in self.iface.mapCanvas().layers(): if layer.type() == QgsMapLayer.VectorLayer and \ layer.geometryType() == QgsWkbTypes.LineGeometry: leave += 1 if leave < 0: message = "No layers with line features - chainage not useful!" show_warning(self, message) return # show the dialog dialog = QChainageDialog(self.iface) # Run the dialog event loop result = dialog.exec_() # See if OK was pressed if result == 1: # do something useful (delete the line containing pass and # substitute with your code) pass
class PdokServicesPlugin(object): def __init__(self, iface): # Save reference to the QGIS interface self.iface = iface # docked or dialog, defaults to dialog # 2018 may: RD: deprecating Docked window, as the content is getting to big anyway # if isinstance(QSettings().value("/pdokservicesplugin/docked"), QVariant): # self.docked = QSettings().value("/pdokservicesplugin/docked", QVariant(False)) # else: # self.docked = QSettings().value("/pdokservicesplugin/docked", False) # # # Create the dialog and keep reference # if "True" == self.docked or "true" == self.docked or True is self.docked: # self.dlg = PdokServicesPluginDockWidget() # self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dlg) # else: # self.dlg = PdokServicesPluginDialog(parent=self.iface.mainWindow()) self.dlg = PdokServicesPluginDialog(parent=self.iface.mainWindow()) # initialize plugin directory self.plugin_dir = QFileInfo(QgsApplication.qgisUserDatabaseFilePath()).path() + "/python/plugins/pdokservicesplugin" # initialize locale localePath = "" if isinstance(QSettings().value("locale/userLocale"), QVariant): locale = QSettings().value("locale/userLocale").value()[0:2] else: locale = QSettings().value("locale/userLocale")[0:2] if QFileInfo(self.plugin_dir).exists(): localePath = self.plugin_dir + "/i18n/pdokservicesplugin_" + locale + ".qm" if QFileInfo(localePath).exists(): self.translator = QTranslator() self.translator.load(localePath) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) self.currentLayer = None self.SETTINGS_SECTION = '/pdokservicesplugin/' self.pointer = None self.pdokgeocoder = PDOKGeoLocator(self.iface) self.geocoderSourceModel = None def getSettingsValue(self, key, default=''): if QSettings().contains(self.SETTINGS_SECTION + key): key = self.SETTINGS_SECTION + key if Qgis.QGIS_VERSION_INT < 10900: # qgis <= 1.8 return str(QSettings().value(key).toString()) else: return str(QSettings().value(key)) else: return default def setSettingsValue(self, key, value): key = self.SETTINGS_SECTION + key if Qgis.QGIS_VERSION_INT < 10900: # qgis <= 1.8 QSettings().setValue(key, QVariant(value)) else: QSettings().setValue(key, value) def initGui(self): # Create action that will start plugin configuration self.run_action = QAction(QIcon(":/plugins/pdokservicesplugin/icon.png"), \ u"Pdok Services Plugin", self.iface.mainWindow()) self.servicesLoaded = False # connect the action to the run method # 2018 may: RD: deprecating Docked window, as the content is getting to big anyway # if "True" == self.docked or "true" == self.docked or True == self.docked: # self.run_action.triggered.connect(self.showAndRaise) # self.dlg.radioDocked.setChecked(True) # # docked the dialog is immidiately visible, so should run NOW # else: # self.run_action.triggered.connect(self.run) # self.dlg.radioDocked.setChecked(False) # self.setupfq() self.run_action.triggered.connect(self.run) #self.dlg.radioDocked.setChecked(False) self.setupfq() # Add toolbar button and menu item #self.iface.addToolBarIcon(self.action) self.toolbar = self.iface.addToolBar("PDOK services plugin") self.toolbar.setObjectName("PDOK services plugin") self.toolbar.addAction(self.run_action) self.toolbarSearch = QLineEdit() self.toolbarSearch.setMaximumWidth(200) self.toolbarSearch.setAlignment(Qt.AlignLeft) self.toolbarSearch.setPlaceholderText("PDOK Locatieserver zoek") self.toolbar.addWidget(self.toolbarSearch) self.toolbarSearch.returnPressed.connect(self.searchAddressFromToolbar) # address/point cleanup self.clean_action = QAction(QIcon(":/plugins/pdokservicesplugin/eraser.png"), \ u"Cleanup", self.eraseAddress()) self.toolbar.addAction(self.clean_action) self.clean_action.triggered.connect(self.eraseAddress) self.iface.addPluginToMenu(u"&Pdok Services Plugin", self.run_action) # about self.aboutAction = QAction(QIcon(":/plugins/pdokservicesplugin/help.png"), \ "About", self.iface.mainWindow()) self.aboutAction.setWhatsThis("Pdok Services Plugin About") self.iface.addPluginToMenu(u"&Pdok Services Plugin", self.aboutAction) self.aboutAction.triggered.connect(self.about) self.dlg.ui.btnLoadLayer.clicked.connect(self.loadService) self.dlg.geocoderSearch.returnPressed.connect(self.searchAddress) self.dlg.geocoderSearch.textEdited.connect(self.searchAddress) self.dlg.geocoderSearch.setPlaceholderText("PDOK Locatieserver zoek, bv postcode of postcode huisnummer") self.dlg.geocoderResultSearch.textChanged.connect(self.filterGeocoderResult) self.dlg.geocoderResultSearch.setPlaceholderText("een of meer zoekwoorden uit resultaat") #self.dlg.radioDocked.toggled.connect(self.set_docked) self.dlg.btnCheckPdokJson.clicked.connect(self.checkPdokJson) #self.iface.mapCanvas().renderStarting.connect(self.extentsChanged) ui = self.dlg.ui cbxs = [ui.cbx_gem, ui.cbx_wpl, ui.cbx_weg, ui.cbx_pcd, ui.cbx_adr, ui.cbx_pcl, ui.cbx_hmp] # connect all fq checkboxes with suggest, so upon a change in fq filter we re-search for cbx in cbxs: cbx.stateChanged.connect(self.searchAddress) self.run(True) # for now hiding the pointer as soon as the extent changes #def extentsChanged(self): # self.removePointer() def checkPdokJson(self): myversion = self.getSettingsValue('pdokversion', '1') msgtxt = '' msglvl = 0 # QgsMessageBar.INFO try: response = urllib.request.urlopen('http://www.qgis.nl/pdok.version') str_response = response.read().decode('utf-8') pdokversion = json.loads(str_response) if pdokversion > int(myversion): response = urllib.request.urlopen('http://www.qgis.nl/pdok.json') str_response = response.read().decode('utf-8') pdokjson = json.loads(str_response) with open(self.plugin_dir +'/pdok.json', 'w') as outfile: json.dump(pdokjson, outfile) msgtxt = "De laatste versie is opgehaald en zal worden gebruikt " + \ str(pdokversion) + ' (was ' + myversion +')' self.servicesLoaded = False # reset reading of json self.run() self.setSettingsValue('pdokversion', pdokversion) else: msgtxt = "Geen nieuwere versie beschikbaar dan " + str(pdokversion) except Exception as e: #print e msgtxt = "Fout bij ophalen van service info. Netwerk probleem?" msglvl = 2 # QgsMessageBar.CRITICAL # msg if hasattr(self.iface, 'messageBar'): self.iface.messageBar().pushMessage("PDOK services update", msgtxt, level=msglvl, duration=10) else: # 1.8 QMessageBox.information(self.iface.mainWindow(), "Pdok Services Plugin", msgtxt) # def set_docked(self, foo): # self.setSettingsValue('docked', self.dlg.radioDocked.isChecked()) # #if Qgis.QGIS_VERSION_INT < 10900: # # # qgis <= 1.8 # # QSettings().setValue("/pdokservicesplugin/docked", QVariant(self.dlg.radioDocked.isChecked())) # #else: # # QSettings().setValue("/pdokservicesplugin/docked", self.dlg.radioDocked.isChecked()) def showAndRaise(self): self.dlg.show() self.dlg.raise_() # also remove the pointer self.removePointer() def about(self): infoString = "Written by Richard Duivenvoorde\nEmail - [email protected]\n" infoString += "Company - Zuidt - http://www.zuidt.nl\n" infoString += "Source: https://github.com/rduivenvoorde/pdokservicesplugin" QMessageBox.information(self.iface.mainWindow(), "Pdok Services Plugin About", infoString) def unload(self): self.removePointer() # Remove the plugin menu item and icon self.iface.removePluginMenu(u"&Pdok Services Plugin",self.run_action) del self.toolbarSearch def showService(self, selectedIndexes): if len(selectedIndexes)==0: self.currentLayer = None self.dlg.ui.layerInfo.setHtml('') self.dlg.ui.comboSelectProj.clear() return # needed to scroll To the selected row incase of using the keyboard / arrows self.dlg.servicesView.scrollTo(self.dlg.servicesView.selectedIndexes()[0]) # itemType holds the data (== column 1) self.currentLayer = self.dlg.servicesView.selectedIndexes()[1].data(Qt.UserRole) if isinstance(self.currentLayer, QVariant): self.currentLayer = self.currentLayer.toMap() # QGIS 1.8: QVariants currentLayer = {} for key in list(self.currentLayer.keys()): val = self.currentLayer[key] currentLayer[str(key)]=str(val.toString()) self.currentLayer = currentLayer url = self.currentLayer['url'] title = self.currentLayer['title'] style = '' if 'style' in self.currentLayer: style = self.currentLayer['style'] title = title + ' [' + style + ']' servicetitle = self.currentLayer['servicetitle'] layername = self.currentLayer['layers'] abstract = self.currentLayer['abstract'] stype = self.currentLayer['type'].upper() minscale ='' if 'minscale' in self.currentLayer and self.currentLayer['minscale'] != None and self.currentLayer['minscale'] != '': minscale = "min. schaal 1:"+self.currentLayer['minscale'] maxscale = '' if 'maxscale' in self.currentLayer and self.currentLayer['maxscale'] != None and self.currentLayer['maxscale'] != '': maxscale = "max. schaal 1:"+self.currentLayer['maxscale'] self.dlg.ui.layerInfo.setText('') self.dlg.ui.btnLoadLayer.setEnabled(True) self.dlg.ui.layerInfo.setHtml('<h4>%s</h4><h3>%s</h3><lu><li>%s</li><li> </li><li>%s</li><li>%s</li><li>%s</li><li>%s</li><li>%s</li><li>%s</li></lu>' % (servicetitle, title, abstract, stype, url, layername, style, minscale, maxscale)) self.dlg.ui.comboSelectProj.clear() if stype=="WMS": try: crs = self.currentLayer['crs'] except KeyError: crs = 'EPSG:28992' crs = crs.split(',') self.dlg.ui.comboSelectProj.addItems(crs) for i in range(len(crs)): if crs[i] == 'EPSG:28992': self.dlg.ui.comboSelectProj.setCurrentIndex(i) if stype=="WMTS": tilematrixsets = self.currentLayer['tilematrixsets'].split(',') self.dlg.ui.comboSelectProj.addItems(tilematrixsets) for i in range(len(tilematrixsets)): if tilematrixsets[i].startswith('EPSG:28992'): self.dlg.ui.comboSelectProj.setCurrentIndex(i) def loadService(self): if self.currentLayer == None: return servicetype = self.currentLayer['type'] url = self.currentLayer['url'] # some services have an url with query parameters in it, we have to urlencode those: location,query = urllib.parse.splitquery(url) url = location if query != None and query != '': url +=('?'+urllib.parse.quote_plus(query)) title = self.currentLayer['title'] if 'style' in self.currentLayer: style = self.currentLayer['style'] title = title + ' [' + style + ']' else: style = '' # == default for this service layers = self.currentLayer['layers'] # mmm, tricky: we take the first one while we can actually want png/gif or jpeg if servicetype == "wms": imgformat = self.currentLayer['imgformats'].split(',')[0] if self.dlg.ui.comboSelectProj.currentIndex() == -1: crs = 'EPSG:28992' else: crs = self.dlg.ui.comboSelectProj.currentText() if Qgis.QGIS_VERSION_INT < 10900: # qgis <= 1.8 uri = url self.iface.addRasterLayer( uri, # service uri title, # name for layer (as seen in QGIS) "wms", # dataprovider key [layers], # array of layername(s) for provider (id's) [""], # array of stylename(s) NOTE: ignoring styles here!!! imgformat, # image format searchstring crs) # crs code searchstring else: # qgis > 1.8 uri = "crs="+crs+"&layers="+layers+"&styles="+style+"&format="+imgformat+"&url="+url; self.iface.addRasterLayer(uri, title, "wms") elif servicetype == "wmts": if Qgis.QGIS_VERSION_INT < 10900: QMessageBox.warning(self.iface.mainWindow(), "PDOK plugin", ("Sorry, dit type layer: '"+servicetype.upper()+"' \nkan niet worden geladen in deze versie van QGIS.\nMisschien kunt u QGIS 2.0 installeren (die kan het WEL)?\nOf is de laag niet ook beschikbaar als wms of wfs?"), QMessageBox.Ok, QMessageBox.Ok) return if self.dlg.ui.comboSelectProj.currentIndex() == -1: tilematrixset = 'EPSG:28992' else: tilematrixset = self.dlg.ui.comboSelectProj.currentText() imgformat = self.currentLayer['imgformats'].split(',')[0] # special case for luchtfoto #if layers=="luchtfoto": # # tileMatrixSet=nltilingschema&crs=EPSG:28992&layers=luchtfoto&styles=&format=image/jpeg&url=http://geodata1.nationaalgeoregister.nl/luchtfoto/wmts/1.0.0/WMTSCapabilities.xml # # {u'layers': u'luchtfoto', u'imgformats': u'image/jpeg', u'title': u'PDOK-achtergrond luchtfoto', u'url': u'http://geodata1.nationaalgeoregister.nl/luchtfoto/wms', u'abstract': u'', u'tilematrixsets': u'nltilingschema', u'type': u'wmts'} # uri = "tileMatrixSet="+tilematrixsets+"&crs=EPSG:28992&layers="+layers+"&styles=&format="+imgformat+"&url="+url #else: # uri = "tileMatrixSet="+tilematrixsets+"&crs=EPSG:28992&layers="+layers+"&styles=&format="+imgformat+"&url="+url; #uri = "tileMatrixSet="+tilematrixsets+"&crs=EPSG:28992&layers="+layers+"&styles=default&format="+imgformat+"&url="+url; if tilematrixset.startswith('EPSG:'): crs=tilematrixset i = crs.find(':', 5) if i > -1: crs=crs[:i] elif tilematrixset.startswith('OGC:1.0'): crs='EPSG:3857' uri = "tileMatrixSet="+tilematrixset+"&crs="+crs+"&layers="+layers+"&styles=default&format="+imgformat+"&url="+url; #print "############ PDOK URI #################" #print uri self.iface.addRasterLayer(uri, title, "wms") elif servicetype == "wfs": location, query = urllib.parse.splitquery(url) #uri = location+"?SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME="+layers+"&SRSNAME=EPSG:28992" #uri = location + "?SERVICE=WFS&REQUEST=GetFeature&TYPENAME=" + layers + "&SRSNAME=EPSG:28992" # adding a bbox paramater forces QGIS to NOT cache features but retrieve new features all the time # QGIS will update the BBOX to the right value #uri += "&BBOX=-10000,310000,290000,650000" uri = " pagingEnabled='true' restrictToRequestBBOX='1' srsname='EPSG:28992' typename='"+layers+"' url='"+url+"' version='2.0.0' " self.iface.addVectorLayer(uri, title, "WFS") elif servicetype == "wcs": # cache=AlwaysCache&crs=EPSG:28992&format=GeoTIFF&identifier=ahn25m:ahn25m&url=http://geodata.nationaalgeoregister.nl/ahn25m/wcs uri = '' # cache=AlwaysCache # cache=PreferNetwork # cache=AlwaysNetwork # cache=AlwaysNetwork&crs=EPSG:28992&format=GeoTIFF&identifier=ahn25m:ahn25m&url=http://geodata.nationaalgeoregister.nl/ahn25m/wcs #uri = "cache=AlwaysNetwork&crs=EPSG:28992&format=image/tiff&version=1.1.1&identifier="+layers+"&url="+url # working for ahn1 ahn2 and ahn3: GEOTIFF_FLOAT32 format = 'GEOTIFF_FLOAT32' # working for ahn25m is only image/tiff if layers=='ahn25m': format = 'image/tiff' # we handcrated some wcs layers with 2 different image formats: tiff (RGB) and tiff (float32): if 'imgformats' in self.currentLayer: format = self.currentLayer['imgformats'].split(',')[0] uri = "cache=AlwaysNetwork&crs=EPSG:28992&format="+format+"&version=1.1.2&identifier=" + layers + "&url=" + url #uri = "cache=AlwaysNetwork&crs=EPSG:28992&format=image/tiff&version=1.1.2&identifier=" + layers + "&url=" + url self.iface.addRasterLayer(uri, title, "wcs") else: QMessageBox.warning(self.iface.mainWindow(), "PDOK plugin", ("Sorry, dit type layer: '"+servicetype.upper()+"' \nkan niet worden geladen door de plugin of door QGIS.\nIs het niet beschikbaar als wms, wmts of wfs?"), QMessageBox.Ok, QMessageBox.Ok) return def filterGeocoderResult(self, string): #print "filtering geocoder results: %s" % string self.dlg.geocoderResultView.selectRow(0) self.geocoderProxyModel.setFilterCaseSensitivity(Qt.CaseInsensitive) self.geocoderProxyModel.setFilterFixedString(string) def searchAddressFromToolbar(self): self.removePointer() self.geocoderSourceModel.clear() self.geocode() def searchAddress(self): self.removePointer() #print "search geocoder for: %s" % self.dlg.geocoderSearch.text() self.geocoderSourceModel.clear() #self.geocode(self.dlg.geocoderSearch.text()) self.suggest() def eraseAddress(self): """ clean the input and remove the pointer """ self.removePointer() if self.geocoderSourceModel is not None: self.geocoderSourceModel.clear() if self.dlg.geocoderSearch is not None: self.dlg.geocoderSearch.clear() if self.toolbarSearch is not None: self.toolbarSearch.clear() def filterLayers(self, string): # remove selection if one row is selected self.dlg.servicesView.selectRow(0) #self.currentLayer = None self.proxyModel.setFilterCaseSensitivity(Qt.CaseInsensitive) self.proxyModel.setFilterFixedString(string) #def addSourceRow(self, service, layer): def addSourceRow(self, serviceLayer): # you can attache different "data's" to to an QStandarditem # default one is the visible one: itemType = QStandardItem("%s" % (serviceLayer["type"].upper()) ) # userrole is a free form one: # only attach the data to the first item # service layer = a dict/object with all props of the layer itemType.setData( serviceLayer, Qt.UserRole ) itemType.setToolTip("%s - %s" % (serviceLayer["type"].upper() ,serviceLayer["title"] )) # only wms services have styles (sometimes) layername = serviceLayer["title"] if 'style' in serviceLayer: itemLayername = QStandardItem("%s [%s]" % (serviceLayer["title"], serviceLayer["style"]) ) layername = "%s [%s]" % (serviceLayer["title"], serviceLayer["style"]) else: itemLayername = QStandardItem("%s" % (serviceLayer["title"])) itemLayername.setToolTip("%s - %s" % (serviceLayer["type"].upper() ,serviceLayer["servicetitle"] )) # itemFilter is the item used to search filter in. That is why layername is a combi of layername + filter here itemFilter = QStandardItem("%s %s %s %s" % (serviceLayer["type"], layername, serviceLayer["servicetitle"], serviceLayer["abstract"]) ) itemServicetitle = QStandardItem("%s" % (serviceLayer["servicetitle"])) itemServicetitle.setToolTip("%s - %s" % (serviceLayer["type"].upper() ,serviceLayer["title"] )) self.sourceModel.appendRow( [ itemLayername, itemType, itemServicetitle, itemFilter ] ) # run method that performs all the real work def run(self, hiddenDialog=False): # enable possible remote pycharm debugging #import pydevd #pydevd.settrace('localhost', port=5678, stdoutToServer=True, stderrToServer=True) # last viewed/selected tab if QSettings().contains("/pdokservicesplugin/currenttab"): if Qgis.QGIS_VERSION_INT < 10900: # qgis <= 1.8 self.dlg.tabs.widget(QSettings().value("/pdokservicesplugin/currenttab").toInt()[0]) else: self.dlg.tabs.widget(int(QSettings().value("/pdokservicesplugin/currenttab"))) if self.servicesLoaded == False: pdokjson = os.path.join(os.path.dirname(__file__), ".", "pdok.json") f = open(pdokjson, 'r', encoding='utf-8') self.pdok = json.load(f) f.close() self.proxyModel = QSortFilterProxyModel() self.sourceModel = QStandardItemModel() self.proxyModel.setSourceModel(self.sourceModel) # filter == search on itemFilter column: self.proxyModel.setFilterKeyColumn(3) self.dlg.servicesView.setModel(self.proxyModel) self.dlg.servicesView.setEditTriggers(QAbstractItemView.NoEditTriggers) self.geocoderProxyModel = QSortFilterProxyModel() self.geocoderSourceModel = QStandardItemModel() self.geocoderProxyModel.setSourceModel(self.geocoderSourceModel) self.geocoderProxyModel.setFilterKeyColumn(0) self.dlg.geocoderResultView.setModel(self.geocoderProxyModel) self.dlg.geocoderResultView.setEditTriggers(QAbstractItemView.NoEditTriggers) #{"services":[ # {"naam":"WMS NHI","url":"http://geodata.nationaalgeoregister.nl/nhi/ows","layers":["dmlinks","dmnodes"],"type":"wms"}, # {"naam":"WMS NHI","url":"http://geodata.nationaalgeoregister.nl/nhi/ows","layers":["dmlinks","dmnodes"],"type":"wms"} # ]} # for service in self.pdok["services"]: # service[layer] was an array if isinstance(service["layers"], str) or isinstance(service["layers"], str): self.addSourceRow(service) self.dlg.layerSearch.textChanged.connect(self.filterLayers) self.dlg.layerSearch.setPlaceholderText("woord uit laagnaam, type of service ") self.dlg.servicesView.selectionModel().selectionChanged.connect(self.showService) self.dlg.servicesView.doubleClicked.connect(self.loadService) # actually I want to load a service when doubleclicked on header # but as I cannot get this to work, let's disable clicking it then self.dlg.servicesView.verticalHeader().setSectionsClickable(False) self.dlg.servicesView.horizontalHeader().setSectionsClickable(False) #self.dlg.geocoderResultView.doubleClicked.connect(self.zoomToAddress) self.dlg.geocoderResultView.selectionModel().selectionChanged.connect(self.zoomToAddress) # hide itemFilter column: self.dlg.servicesView.hideColumn(3) self.servicesLoaded = True; self.sourceModel.setHeaderData(2, Qt.Horizontal, "Service") self.sourceModel.setHeaderData(1, Qt.Horizontal, "Type") self.sourceModel.setHeaderData(0, Qt.Horizontal, "Laagnaam [style]") self.sourceModel.horizontalHeaderItem(2).setTextAlignment(Qt.AlignLeft) self.sourceModel.horizontalHeaderItem(1).setTextAlignment(Qt.AlignLeft) self.sourceModel.horizontalHeaderItem(0).setTextAlignment(Qt.AlignLeft) #self.dlg.servicesView.verticalHeader().hide() #self.dlg.servicesView.resizeColumnsToContents() self.dlg.servicesView.setColumnWidth(0, 300) # set name to 300px (there are some huge layernames) self.dlg.servicesView.horizontalHeader().setStretchLastSection(True) # show the dialog ? if not hiddenDialog: self.dlg.show() # Run the dialog event loop #result = self.dlg.exec_() if Qgis.QGIS_VERSION_INT < 10900: # qgis <= 1.8 QSettings().setValue("/pdokservicesplugin/currenttab", QVariant(self.dlg.tabs.currentIndex())) else: QSettings().setValue("/pdokservicesplugin/currenttab", self.dlg.tabs.currentIndex()) self.removePointer() def setupfq(self): """ Setup the fq checkboxes in the gui, by looking into the settings for the 'pdokservicesplugin/checkedfqs' key, which contains a list of type strings like ['weg','adres'] """ checked_fqs = self.getSettingsValue('checkedfqs', []) #self.info('setup fq: {}'.format(checked_fqs)) if len(checked_fqs) > 0: # else there is not saved state... take gui defaults self.dlg.ui.cbx_gem.setChecked('gemeente' in checked_fqs) self.dlg.ui.cbx_wpl.setChecked('woonplaats' in checked_fqs) self.dlg.ui.cbx_weg.setChecked('weg' in checked_fqs) self.dlg.ui.cbx_pcd.setChecked('postcode' in checked_fqs) self.dlg.ui.cbx_adr.setChecked('adres' in checked_fqs) self.dlg.ui.cbx_pcl.setChecked('perceel' in checked_fqs) self.dlg.ui.cbx_hmp.setChecked('hectometerpaal' in checked_fqs) def createfq(self): """ This creates a fq-string (Filter Query, see https://github.com/PDOK/locatieserver/wiki/Zoekvoorbeelden-Locatieserver) Based on the checkboxes in the dialog. Defaults to '' Example: 'fq=+type:adres+type:gemeente' (only gemeente AND addresses) :return: """ fqlist = [] if self.dlg.ui.cbx_gem.isChecked(): fqlist.append('gemeente') if self.dlg.ui.cbx_wpl.isChecked(): fqlist.append('woonplaats') if self.dlg.ui.cbx_weg.isChecked(): fqlist.append('weg') if self.dlg.ui.cbx_pcd.isChecked(): fqlist.append('postcode') if self.dlg.ui.cbx_adr.isChecked(): fqlist.append('adres') if self.dlg.ui.cbx_pcl.isChecked(): fqlist.append('perceel') if self.dlg.ui.cbx_hmp.isChecked(): fqlist.append('hectometerpaal') self.setSettingsValue('checkedfqs', fqlist) #self.info(self.getSettingsValue('checkedfqs', ['leeg?'])) fq = '' if len(fqlist) > 0: fq = '&fq=+type:' + '+type:'.join(fqlist) return fq def suggest(self): self.dlg.ui.lookupinfo.setHtml('') search_text = self.dlg.geocoderSearch.text() if len(search_text) <= 1: # QMessageBox.warning(self.iface.mainWindow(), "PDOK plugin", ( \ # "meer input aub: {}".format(search_text) # ), QMessageBox.Ok, QMessageBox.Ok) return # QMessageBox.warning(self.iface.mainWindow(), "PDOK plugin", ( \ # "zoeken: {}".format(search_text) # ), QMessageBox.Ok, QMessageBox.Ok) results = self.pdokgeocoder.suggest(search_text, self.createfq()) if len(results) == 0: # ignore, as we are suggesting, maybe more characters will reveal something... return for result in results: #print address adrestekst = QStandardItem("%s" % (result["adrestekst"])) adrestekst.setData(result, Qt.UserRole) type = QStandardItem("%s" % (result["type"])) id = QStandardItem("%s" % (result["id"])) score = QStandardItem("%s" % (result["score"])) adrestekst.setData(result, Qt.UserRole) self.geocoderSourceModel.appendRow([adrestekst, type]) self.geocoderSourceModel.setHeaderData(0, Qt.Horizontal, "Resultaat") self.geocoderSourceModel.setHeaderData(1, Qt.Horizontal, "Type") self.geocoderSourceModel.horizontalHeaderItem(0).setTextAlignment(Qt.AlignLeft) self.dlg.geocoderResultView.resizeColumnsToContents() self.dlg.geocoderResultView.horizontalHeader().setStretchLastSection(True) def geocode(self): self.dlg.geocoderSearch.setText(self.toolbarSearch.text()) self.suggest() if self.dlg.geocoderResultView.model().rowCount()>0: self.dlg.geocoderResultView.selectRow(0) self.zoomToAddress() else: QMessageBox.warning(self.iface.mainWindow(), "PDOK plugin", ( \ "Niets gevonden.\nProbeer een andere spelling, of alleen postcode/huisnummer?\n\nSelecteer meer (Locatieserver) 'typen' in de PdokServicesPlugin dialoog.\n\nOf gebruik de 'PDOK geocoder'-tab in de PdokServicesPlugin dialoog." ), QMessageBox.Ok, QMessageBox.Ok) # def geocode(self): # self.dlg.ui.lookupinfo.setHtml('') # search_text = self.toolbarSearch.text() # addresses = self.pdokgeocoder.search(search_text) # if len(addresses) == 0: # QMessageBox.warning(self.iface.mainWindow(), "PDOK plugin", ( \ # "Niets gevonden. Probeer een andere spelling of alleen postcode/huisnummer." # ), QMessageBox.Ok, QMessageBox.Ok) # return # for address in addresses: # #print address # adrestekst = QStandardItem("%s" % (address["adrestekst"])) # adrestekst.setData(address, Qt.UserRole) # straat = QStandardItem("%s" % (address["straat"])) # nummer = QStandardItem("%s" % (address["nummer"])) # postcode = QStandardItem("%s" % (address["postcode"])) # plaats = QStandardItem("%s" % (address["plaats"])) # gemeente = QStandardItem("%s" % (address["gemeente"])) # provincie = QStandardItem("%s" % (address["provincie"])) # self.geocoderSourceModel.appendRow([adrestekst, straat, nummer, postcode, plaats, gemeente, provincie]) # # self.dlg.geocoderResultView.selectRow(0) # self.zoomToAddress() # # self.geocoderSourceModel.setHeaderData(0, Qt.Horizontal, "Resultaat") # self.geocoderSourceModel.setHeaderData(1, Qt.Horizontal, "Straat") # self.geocoderSourceModel.setHeaderData(2, Qt.Horizontal, "Nr") # self.geocoderSourceModel.setHeaderData(3, Qt.Horizontal, "Postcode") # self.geocoderSourceModel.setHeaderData(4, Qt.Horizontal, "Plaats") # self.geocoderSourceModel.setHeaderData(5, Qt.Horizontal, "Gemeente") # self.geocoderSourceModel.setHeaderData(6, Qt.Horizontal, "Provincie") # # self.geocoderSourceModel.horizontalHeaderItem(0).setTextAlignment(Qt.AlignLeft) # self.geocoderSourceModel.horizontalHeaderItem(1).setTextAlignment(Qt.AlignLeft) # self.geocoderSourceModel.horizontalHeaderItem(2).setTextAlignment(Qt.AlignLeft) # self.geocoderSourceModel.horizontalHeaderItem(3).setTextAlignment(Qt.AlignLeft) # self.geocoderSourceModel.horizontalHeaderItem(4).setTextAlignment(Qt.AlignLeft) # self.geocoderSourceModel.horizontalHeaderItem(5).setTextAlignment(Qt.AlignLeft) # self.geocoderSourceModel.horizontalHeaderItem(6).setTextAlignment(Qt.AlignLeft) # # self.dlg.geocoderResultView.resizeColumnsToContents() # self.dlg.geocoderResultView.horizontalHeader().setStretchLastSection(True) def zoomToAddress(self): # get x,y from data of record self.removePointer() data = self.dlg.geocoderResultView.selectedIndexes()[0].data(Qt.UserRole) if 'centroide_rd' in data: # free OR lookup service geom = QgsGeometry.fromWkt(data['centroide_rd']) adrestekst = data['adrestekst'] else: # no centroid yet, probably only object id, retrieve it via lookup service id = data['id'] data = self.pdokgeocoder.lookup(id) geom = QgsGeometry.fromWkt(data['centroide_rd']) adrestekst = data['adrestekst'] lookup_data= data['data'] lis = '' for key in lookup_data.keys(): lis = lis + '<li>{}: {}</li>'.format(key, lookup_data[key]) self.dlg.ui.lookupinfo.setHtml( '<h4>{}</h4><lu>{}</lu>'.format(adrestekst, lis)) # just always transform from 28992 to mapcanvas crs crs = self.iface.mapCanvas().mapSettings().destinationCrs() crs28992 = QgsCoordinateReferenceSystem() crs28992.createFromId(28992) crsTransform = QgsCoordinateTransform(crs28992, crs, QgsProject.instance()) z = 1587 if adrestekst.lower().startswith('adres'): z = 794 elif adrestekst.lower().startswith('perceel'): z = 794 elif adrestekst.lower().startswith('hectometer'): z = 1587 elif adrestekst.lower().startswith('straat'): z = 3175 elif adrestekst.lower().startswith('postcode'): z = 6350 elif adrestekst.lower().startswith('woonplaats'): z = 25398 elif adrestekst.lower().startswith('gemeente'): z = 50797 elif adrestekst.lower().startswith('provincie'): z = 812750 geom.transform(crsTransform) center = geom.asPoint() self.setPointer(center) # zoom to with center is actually setting a point rectangle and then zoom rect = QgsRectangle(center, center) self.iface.mapCanvas().setExtent(rect) self.iface.mapCanvas().zoomScale(z) self.iface.mapCanvas().refresh() def setPointer(self, point): self.removePointer() self.pointer = QgsVertexMarker(self.iface.mapCanvas()) self.pointer.setColor(QColor(255, 255, 0)) self.pointer.setIconSize(10) self.pointer.setPenWidth(5) self.pointer.setCenter(point) def removePointer(self): if self.pointer is not None: self.iface.mapCanvas().scene().removeItem(self.pointer) def info(self, msg=""): QgsMessageLog.logMessage('{}'.format(msg), 'PDOK-services Plugin', Qgis.Info)
class ViewMapem: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'ViewMapem_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.actions = [] self.menu = self.tr(u'&View Mapem') # Check if plugin was started the first time in current QGIS session # Must be set in initGui() to survive plugin reloads self.first_start = None # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('ViewMapem', message) def add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: # Adds plugin icon to Plugins toolbar self.iface.addToolBarIcon(action) if add_to_menu: self.iface.addPluginToMenu(self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/view_mapem/icon.png' self.add_action(icon_path, text=self.tr(u'View MAPEM'), callback=self.run, parent=self.iface.mainWindow()) # will be set False in run() self.first_start = True def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginMenu(self.tr(u'&View Mapem'), action) self.iface.removeToolBarIcon(action) def run(self): def filePath(title): qfd = QFileDialog() path = "" filter = "uper(*.uper)" f = QFileDialog.getOpenFileName(qfd, title, path, filter) return f fpath = filePath("Select *.uper") if fpath[0] != "": with tempfile.TemporaryDirectory() as tmpdirname: #print('created temporary directory', tmpdirname) get_geojson_from_complete_uper( tmpdirname, fpath[0], os.path.join(os.path.dirname(__file__), 'mapem_spatem.asn')) layer = QgsProject.instance().layerTreeRoot() def addGroupIfNotExist(name, group): mapem_group = None for i in group.children(): if i.name() == name: mapem_group = i break if mapem_group == None: # create layer group.addGroup(name) for i in group.children(): if i.name() == name: mapem_group = i break return mapem_group #mapem_group = addGroupIfNotExist("MAPEM",layer) mapem_group = addGroupIfNotExist( os.path.basename(fpath[0]).split('.')[0] + ".uper", layer) intersections = addGroupIfNotExist("intersections", mapem_group) roadSegments = addGroupIfNotExist("roadSegments", mapem_group) def addFileJsonInLayer(filename, group, name): #listLayers=QgsProject.instance().mapLayersByName(name) listLayers = group.children() to_delete = [] for i in listLayers: #print(i.name(), i.layer().id()) if i.name() == name: to_delete.append(i.layer().id()) QgsProject.instance().removeMapLayers(to_delete) vl = QgsVectorLayer(filename, name) crs = QgsCoordinateReferenceSystem( 3857, QgsCoordinateReferenceSystem.PostgisCrsId) nameShape_folder = os.path.dirname( QgsProject.instance().fileName()) nameShape_filename = os.path.basename(filename).split( ".")[0] + ".shp" nameShape = os.path.join(nameShape_folder, nameShape_filename) QgsVectorFileWriter.writeAsVectorFormat(vl, nameShape, "utf-8", crs, "ESRI Shapefile", onlySelected=False) vl = QgsVectorLayer(nameShape, name) QgsProject.instance().addMapLayer(vl, False) group.addLayer(vl) return vl for path, subdirs, files in os.walk(tmpdirname + "intersections"): for name in files: f = os.path.join(path, name) g = addGroupIfNotExist( name.split("-")[0], intersections) layer = addFileJsonInLayer(f, g, name.split(".")[0]) if "connectsTo" in layer.name(): layer.loadNamedStyle( ':/plugins/view_mapem/styles/intersections/connectsTo.qml' ) layer.triggerRepaint() if "GenericLane" in layer.name(): layer.loadNamedStyle( ':/plugins/view_mapem/styles/intersections/GenericLane.qml' ) layer.triggerRepaint() if "nodeList" in layer.name(): layer.loadNamedStyle( ':/plugins/view_mapem/styles/intersections/nodeList.qml' ) layer.triggerRepaint() if "refPoint" in layer.name(): layer.loadNamedStyle( ':/plugins/view_mapem/styles/intersections/refPoint.qml' ) layer.triggerRepaint() for path, subdirs, files in os.walk(tmpdirname + "roadSegments"): for name in files: f = os.path.join(path, name) g = addGroupIfNotExist( name.split("-")[0], roadSegments) layer = addFileJsonInLayer(f, g, name.split(".")[0]) if "connectsTo" in layer.name(): layer.loadNamedStyle( ':/plugins/view_mapem/styles/roadSegments/connectsTo.qml' ) layer.triggerRepaint() if "GenericLane" in layer.name(): layer.loadNamedStyle( ':/plugins/view_mapem/styles/roadSegments/GenericLane.qml' ) layer.triggerRepaint() if "nodeList" in layer.name(): layer.loadNamedStyle( ':/plugins/view_mapem/styles/roadSegments/nodeList.qml' ) layer.triggerRepaint() if "refPoint" in layer.name(): layer.loadNamedStyle( ':/plugins/view_mapem/styles/roadSegments/refPoint.qml' ) layer.triggerRepaint() # Settign the CRS of the data set option 1 canvas = self.iface.mapCanvas() selectedcrs = "EPSG:3857" target_crs = QgsCoordinateReferenceSystem() target_crs.createFromUserInput(selectedcrs) canvas.setDestinationCrs(target_crs) outputinfo = "Импортирование завершено." Q = QMessageBox(self.iface.mainWindow()) Q = QMessageBox.information(Q, 'Import from MAPEM', outputinfo, QMessageBox.Ok)
class timemanager_obj(object): """Plugin information""" name = "timemanager" longName = "TimeManager Plugin for QGIS >= 2.3" description = "Working with temporal vector data" author = "Anita Graser, Karolina Alexiou" pluginUrl = "https://github.com/anitagraser/TimeManager" def __init__(self, iface): """Initialize the plugin""" global control try: control except NameError: try: overrideLocale = bool(QSettings().value("locale/overrideFlag", False)) if not overrideLocale: lang = QLocale.system().name().split("_")[0] else: lang = QSettings().value("locale/userLocale", "").split("_")[0] except Exception: lang = "en" # could not get locale, OSX may have this bug info("Plugin language loaded: {}".format(lang)) self.changeI18n(lang) control = TimeManagerControl(iface) def getController(self): return control def initGui(self): """Initialize the gui""" control.load() def changeI18n(self, new_lang): """ Change internationalisation for the plugin. Override the system locale and then see if we can get a valid translation file for whatever locale is effectively being used. """ # os.environ["LANG"] = str(new_lang) root = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) translation_path = "TimeManager:i18n/{}_{}.qm".format(self.name, new_lang) self.translator = QTranslator() result = self.translator.load(translation_path) if not result: error( "Translation file {} for lang {} was not loaded properly," + "falling back to English".format(translation_path, new_lang) ) return if qVersion() > "4.3.3": QCoreApplication.installTranslator(self.translator) else: self.translator = None warn("Translation not supported for Qt <= {}".format(qVersion())) def unload(self): """Unload the plugin""" control.unload() QgsExpression.unregisterFunction("$animation_datetime") QgsExpression.unregisterFunction("animation_datetime") QgsExpression.unregisterFunction("$animation_time_frame_size") QgsExpression.unregisterFunction("animation_time_frame_size") QgsExpression.unregisterFunction("$animation_time_frame_type") QgsExpression.unregisterFunction("animation_time_frame_type") QgsExpression.unregisterFunction("$animation_start_datetime") QgsExpression.unregisterFunction("animation_start_datetime") QgsExpression.unregisterFunction("$animation_end_datetime") QgsExpression.unregisterFunction("animation_end_datetime") @qgsfunction(0, "TimeManager") def animation_datetime(values, feature, parent): """Current animation time""" return time_util.datetime_to_str(control.getTimeLayerManager().getCurrentTimePosition(), time_util.DEFAULT_FORMAT) @qgsfunction(0, "TimeManager") def animation_time_frame_size(values, feature, parent): """Animation time frame size""" return control.getTimeLayerManager().getTimeFrameSize() @qgsfunction(0, "TimeManager") def animation_time_frame_type(values, feature, parent): """Unit of time frame, i.e. days, hours, minutes, seconds, ...""" return control.getTimeLayerManager().getTimeFrameType() @qgsfunction(0, "TimeManager") def animation_start_datetime(values, feature, parent): """Earliest time stamp""" return time_util.datetime_to_str(control.getTimeLayerManager().getProjectTimeExtents()[0], time_util.DEFAULT_FORMAT) @qgsfunction(0, "TimeManager") def animation_end_datetime(values, feature, parent): """Last time stamp""" return time_util.datetime_to_str(control.getTimeLayerManager().getProjectTimeExtents()[1], time_util.DEFAULT_FORMAT)
class CanadianWebServices(object): """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgisInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'CanadianWebServices_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Create the dialogs and keep reference self.dlg = CanadianWebServicesDialog() self.dlginfo = InfoDialog() # Declare instance attributes self.actions = [] self.menu = self.tr(u'&Canadian Web Services') # TODO: We are going to let the user set this up in a future iteration self.toolbar = self.iface.addToolBar(u'CanadianWebServices') self.toolbar.setObjectName(u'CanadianWebServices') # define the datasets used: self.works = True # will be used to determine whether the list url can be reached self.services = self.loadServiceList() if self.works == True: # only sorts when the url worked self.services = self.sortServices( self.services) # initialize and sort the services self.shownServices = self.services # will change when serch criteria change to allow for the selected dataset to be found by row number # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('CanadianWebServices', message) ## add_action(self,icon_path,text,etc.) adds to the toolbar in QGIS's GUI def add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ # Create the dialog (after translation) and keep reference self.dlg = CanadianWebServicesDialog() icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: self.toolbar.addAction(action) if add_to_menu: self.iface.addPluginToWebMenu(self.menu, action) self.actions.append(action) return action ## initGui(self) is used here (after add_action call) to connect events to functions def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/CanadianWebServices/icon.png' self.add_action(icon_path, text=self.tr(u'Load Canadian web services'), callback=self.run, parent=self.iface.mainWindow()) # initialize event connections self.dlg.tableWidget.itemSelectionChanged.connect(self.updateDesc) self.dlg.close_btn.released.connect(self.dlg.close) self.dlg.load_btn.released.connect(self.loadWebService) self.dlg.searchBox.textEdited.connect(self.search) self.dlg.sortCombo.activated.connect(self.sortCurrentServices) self.dlg.info_btn.released.connect(self.openInfo) ## unload(self) removes the plugin from QGIS GUI def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginWebMenu(self.tr(u'&Canadian Web Services'), action) self.iface.removeToolBarIcon(action) # remove the toolbar del self.toolbar # getSelectedServices(self) returns the web service object of the currently selected service in the table # getSelectedServices: CWS -> List of Services def getSelectedServices(self): """Gets the selected dataset from the table""" # get the number of the selected row: #rowNum = self.dlg.tableWidget.currentRow() rowNums = [] selected = self.dlg.tableWidget.selectedItems() if (len(selected) > 0): for i in range(0, len(selected), 4): rowNums.append(self.dlg.tableWidget.row(selected[i])) selectedServices = [] for row in rowNums: selectedServices.append(self.shownServices[row]) # return the webServiceObj from the datasets list for that row return selectedServices # updateDesc(self) updates the description box with the name and description of the selected service # updateDesc: CWS -> None def updateDesc(self): # get the selected dataset: serv = self.getSelectedServices() #Gets the name of the last clicked service desc = serv[-1].desc if len(serv) > 0 else "" name = serv[-1].name if len(serv) > 0 else "" # update the description: self.dlg.textEdit.clear() cursor = QTextCursor(self.dlg.textEdit.document()) cursor.insertText(name + "\n\n" + desc) self.dlg.textEdit.setReadOnly(True) # percentUp(self, up, down): returns the percent up time using up and down times # percentUp: CWS Float Float -> Int def percentUp(self, up, down): if up == 'null' or down == 'null' or up == 0: return 0 elif down == 0: return 100 total = up + down return int((up / total) * 100) # loadServiceList(self) returns a list of web services that meet the criteria of: # Has a name, 20 or fewer layers, 90%+ weekly uptime, not WMTS # loadServiceList: CWS -> (listof Service) OR (listof None) # Modifies: When url can't be reached, self.works is set to false def loadServiceList(self): url = 'http://directory.spatineo.com/nrcan-harvest/json/v1/latest.json' response = requests.get(url) try: json_test = response.json() except: self.works = False # this will be used in the run method to check if the url works # if it doesn't, an error message will appear on startup and the program will close return list() if self.works == True: response = response.text services = json.loads(response) webServicesList = [] # will hold web service objects for service in services: # get information needed to determine whether to include this service name = service['title'] layers = service['layers'] numLayers = len(layers) # get availability times and calculate a weekly up time percentage availability = service['availability'] upWeek = float((availability['week'])['hoursUp']) downWeek = float((availability['week'])['hoursDown']) perAvailable = self.percentUp( upWeek, downWeek ) # to only include services with a high percent up time serviceType = service[ 'serviceInterfaceType'] # to exclude WMTS services from being included if service[ 'title'] != "" and numLayers <= 20 and perAvailable >= 90 and serviceType != "WMTS": #IMPORTANT***************************************************************** # if its a good enough service, get the other fields and add it to the list desc = service['abstract'] if serviceType == "ESRI_MapServer": serviceType = "ESRI MapServer" url = service['url'] # make a host url like the ones on the website using the url host = url[:url.index(".ca") + 3] # remove whats after '.ca' host = host[host.index("/") + 2:] # removes 'https://' or 'http://' directory = service['directoryUrl'] # create an object containing all the fields of a web service webServiceObj = ServiceObject(name, host, desc, serviceType, url, directory, numLayers) # add that object to our list of web service objects webServicesList.append(webServiceObj) return webServicesList # setTableWidgetBehaviour(self) defines how tableWidget will behave # setTableWidgetBehaviour: CWS -> None def setTableWidgetBehaviour(self): # set row and column sizes and lock them self.dlg.tableWidget.setColumnWidth(0, 110) self.dlg.tableWidget.setColumnWidth(1, 110) self.dlg.tableWidget.setColumnWidth(2, 207) self.dlg.tableWidget.setColumnWidth(3, 86) self.dlg.tableWidget.horizontalHeader().setSectionResizeMode( QHeaderView.Fixed) self.dlg.tableWidget.verticalHeader().setSectionResizeMode( QHeaderView.Fixed) #self.dlg.tableWidget.resizeRowsToContents() # set event behaviors for the table self.dlg.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows) self.dlg.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers) self.dlg.tableWidget.setSelectionMode(QAbstractItemView.MultiSelection) # fill_table(self, serviceList): fills tableWidget with the services in serviceList # fill_table: CWS (listof Service) -> None def fill_table(self, serviceList): # initialize an empty table with 3 columns self.dlg.tableWidget.setRowCount(0) self.dlg.tableWidget.setColumnCount(4) for service in serviceList: index = serviceList.index(service) self.dlg.tableWidget.insertRow(index) # inserts a blank row # lets fill that row: self.dlg.tableWidget.setItem( index, 0, QTableWidgetItem(service.name)) # fills in with the name self.dlg.tableWidget.setItem( index, 1, QTableWidgetItem( service.serviceType)) # fills in with the service type self.dlg.tableWidget.setItem( index, 2, QTableWidgetItem(service.host)) # fills in with the host self.dlg.tableWidget.setItem( index, 3, QTableWidgetItem(str( service.layers))) # fills in with the number of layers # initialize the header labels self.dlg.tableWidget.setHorizontalHeaderLabels( ["Name", "Type", "Host", "# of Layers"]) self.setTableWidgetBehaviour() # search(self) updates the displayed services (and self.shownServices) with only services # that contain the text in searchBox in their name, type, host, or number of layers # search: CWS -> None # Modifies: self.shownServices changes according to the text in searchBox # services in the table change to what is in self.shownServices def search(self): # clear description box self.dlg.textEdit.clear() # get entered text criteria = self.dlg.searchBox.text() criteria = criteria.lower() applicableServices = [ ] # will hold all services that meet the specified criteria # loops through all services for service in self.services: name = service.name.lower() host = service.host.lower() serviceType = service.serviceType.lower() # checks if the service meets the criteria in some way if (criteria in name) or (criteria in host) or (criteria in serviceType): applicableServices.append(service) # populates the table with only applicable services self.shownServices = applicableServices # for description display and loading purposes self.sortCurrentServices() self.fill_table(applicableServices) # sortServices(self, servicesList) rearranges the services in ascending order based on # the selected sort field in sortCombo # sortServices: CWS (listof Service) -> (listof Service) # Modifies: table is filled with the sorted list of services def sortServices(self, servicesList): sortParam = self.dlg.sortCombo.currentText() # requires that these specific names are used in the sortCombo combo box if sortParam == "Name": servicesList.sort(key=lambda service: service.name.lower()) elif sortParam == "Type": servicesList.sort(key=lambda service: service.serviceType) elif sortParam == "Host": servicesList.sort(key=lambda service: service.host) elif sortParam == "Layers": servicesList.sort(key=lambda service: service.layers) self.fill_table(servicesList) return servicesList # sortCurrentServices(self) acts as a wrapper for sortServices so it can be connected # to the change of sort type in sortCombo # sortCurrentServices: CWS -> (listof Service) # Modifies: table is filled with sorted version of self.shownServices def sortCurrentServices(self): # used for the sortCombo box because it can only take one parameter and will always use shownDatasets return self.sortServices(self.shownServices) # loadWebService(self): loads the selected service into the map layer by layer. If any layer # is not valid, a warning message will be displayed to the user # loadWebService: CWS -> None def loadWebService(self): # default projection, possibly changed later: EPSG_code = '4326' for serv in self.getSelectedServices(): name = serv.name servType = serv.serviceType service_url = serv.url serviceErrors = False # will become true if any of the layers cannot load in if servType == "WMS": service_url = service_url[: -36] # simple way of removing the GetCapabilities request saveLayers(name, service_url, servType) wms = WebMapService(service_url) layerList = list( wms.contents ) # creates a list of the names of each layer in the service numLayers = len(layerList) for layer in range(numLayers): # construct a WMS url for the current layer urlWithParams1 = 'url=' + str( service_url) + '&format=image/png&layers=' urlWithParams2 = '&styles=&crs=EPSG:' + str(EPSG_code) urlWithParams = urlWithParams1 + layerList[ layer] + urlWithParams2 # create the layer and add it to the map rlayer = QgsRasterLayer(urlWithParams, wms[layerList[layer]].title, "wms") if not rlayer.isValid( ): # set service Errors to True if any layers can't be loaded serviceErrors = True QgsProject.instance().addMapLayer(rlayer) elif servType == "WFS": saveLayers(name, service_url[:-35], servType) service_url = service_url[: -36] # simple way of removing the GetCapabilities request wfs = WebFeatureService(service_url) layerList = list( wfs.contents ) # creates a list of the names of each layer in the service numLayers = len(layerList) for layer in range(numLayers): # construct a WFS uri for the current layer urlWithParams1 = str(service_url) + "?srsname=EPSG:" + str( EPSG_code) + "&typename=" + layerList[layer] urlWithParams2 = "&version=" + wfs.identification.version + "&request=GetFeature&service=WFS" urlWithParams = urlWithParams1 + urlWithParams2 # create the layer and add it to the map vlayer = QgsVectorLayer(urlWithParams, wfs[layerList[layer]].title, "WFS") if not vlayer.isValid( ): # set service Errors to True if any layers can't be loaded serviceErrors = True QgsProject.instance().addMapLayer(vlayer) elif servType == "WMTS": """ CURRENTLY WMTS SERVICES ARE NOT INCLUDED IN THE LOADED SERVICES """ # to enable WMTS, remove the WMTS part of the if statement in loadServiceList service_url = service_url[: -37] # simple way of removing the GetCapabilities request wmts = WebMapTileService(service_url) layerList = list(wmts.contents) numLayers = len(layerList) # requires that the url ends with "?f=pjson" elif servType == "ESRI MapServer": # grab lists of the layer IDs and Names ids = mapServerHelp.getIDs(service_url) names = mapServerHelp.getNames(service_url) service_url = service_url[:-8] # gets rid of "?f=pjson" saveLayers(name, service_url, servType) counter = 0 # used as an index for the ids and names lists for id in ids: # create the layer and add it to the map layer = QgsRasterLayer( "url='" + service_url + "' layer='" + str(ids[counter]) + "'", names[counter], "arcgismapserver") if not layer.isValid( ): # set service Errors to True if any layers can't be loaded serviceErrors = True QgsProject.instance().addMapLayer(layer) counter = counter + 1 if serviceErrors == True: # display an error message when one or more layers could not be loaded QMessageBox.warning( None, "Error Loading Layer(s)", "One or more of the layers from this service could not be loaded." ) # openInfo(self) opens the info dialog # openInfo: CWS -> None def openInfo(self): self.dlginfo.show() def run(self): """Run method that performs all the real work""" if self.works == False: # if the URL to load in the services wasn't working QMessageBox.warning( None, "WARNING", "We couldn't reach our list of web services at this time. Please try again later." ) # just show the user an error message and don't launch the plugin else: # if all is well, continue on with opening the plugin self.shownServices = self.services # reinitialize shownDatasets with all the datasets sorted by name self.dlg.sortCombo.setCurrentIndex( 0) # reset sortCombo to the Names option self.sortServices( self.services ) # reinitialize the table with all datasets sorted by name self.dlg.searchBox.clear() # clear search box self.dlg.textEdit.clear() # clear description box self.dlg.show() # show the dialog # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: # Do something useful here - delete the line containing pass and # substitute with your code. pass
class AssimilaDatacCube: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'AssimilaDatacCube_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) QCoreApplication.installTranslator(self.translator) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.actions = [] self.menu = self.tr(u'&Assimila Data Cube') # Check if plugin was started the first time in current QGIS session # Must be set in initGui() to survive plugin reloads self.first_start = None self.dlg = AssimilaDatacCubeDialog(iface) # Calls the keyfile at location specified in the lineEdit widget self.http_client = AssimilaData(self.dlg.lineEdit.displayText()) # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('AssimilaDatacCube', message) def add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: # Adds plugin icon to Plugins toolbar self.iface.addToolBarIcon(action) if add_to_menu: self.iface.addPluginToMenu(self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/assimila_datacube/icon.png' self.add_action(icon_path, text=self.tr(u'Visualise the datacube.'), callback=self.run, parent=self.iface.mainWindow()) # will be set False in run() self.first_start = True def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginMenu(self.tr(u'&Assimila Data Cube'), action) self.iface.removeToolBarIcon(action) def check(self, north, east, south, west, start, end): # check start is after end date if str(end) < str(start): raise ValueError('End date should not be before start date') # check that end date does not exceed 30 days from start date # limit is 30 days 23 hours # 01/01/2000 - 31/01/2000 -> SUCCESS # 01/01/2000 - 01/02/2000 -> FAIL if start.daysTo(end) > 30: raise ValueError( 'Maximum number of delays selected is limited to 30 days') # check east value is greater than west value if east != 0 and west != 0 and east < west: raise ValueError('East value should be greater than west') # check north value is greater than south value if north != 0 and south != 0 and north < south: raise ValueError('North value should be greater than south') # check area of box is less than 25*25=625 print('N-S=' + str(north - south)) print('E-W=' + str(east - west)) print('Total area = ' + str((north - south) * (east - west))) if (north - south) * (east - west) > 625: raise ValueError('Exceeded maximum area of canvas') def subproduct_selectionchange(self): # Clears previous options in the subproducts dropdown menu self.dlg.subproducts_comboBox.clear() # Matching subporducts to their products if str(self.dlg.products_comboBox.currentText()) == 'TAMSAT' or str( self.dlg.products_comboBox.currentText()) == 'CHIRPS': subproducts = ['rfe'] else: subproducts = [ 'skt', 't2m', 'skt_ensemble_mean', 'land_sea_mask', 't2m_ensemble_spread', 't2m_ensemble_mean', 'skt_ensemble_spread' ] # Displays the subproducts in the dropdown menu self.dlg.subproducts_comboBox.addItems(subproducts) def radio_btn_state(self, b, dt1, dt2): # If single radio button (b) is checked, then enable 1 datetime widget box if b.isChecked() == True: dt1.setDisabled(False) dt2.setDisabled(True) #print (b.text()+" is selected") else: # Multi radio button is checked, so enable both datetime widget boxes dt1.setDisabled(False) dt2.setDisabled(False) #print (b.text()+" is deselected") def get_data_from_datacube_nesw(self, product, subproduct, north, east, south, west, start, end): # Clear the products and subproducts drop down menu self.dlg.products_comboBox.clear() self.dlg.subproducts_comboBox.clear() # Requests data from the datacube res = self.http_client.get({ 'command': 'GET_DATA', 'product_metadata': { 'product': product.lower(), # case sensitive 'subproduct': [subproduct], 'north': north, 'east': east, 'south': south, 'west': west, 'start_date': np.datetime64(start), 'end_date': np.datetime64(end), } }) # Return an Xarray (later reffered to as y) return res[0] def run(self): # Clears the values from previous run self.dlg.products_comboBox.clear() self.dlg.lineEdit.clear() # Displays default key file path location self.key_file = os.path.join(expanduser("~"), "Documents", ".assimila_dq") self.dlg.lineEdit.insert(self.key_file) # Display dropdowns products = ['TAMSAT', 'CHIRPS', 'era5'] self.dlg.products_comboBox.addItems(products) self.dlg.subproducts_comboBox.addItem( 'rfe' ) # Defaulting 1st item in Product is 'TAMSAT' so 1st item in Subprodusct is 'rfe' self.dlg.products_comboBox.currentTextChanged.connect( self.subproduct_selectionchange) # For updating the subproduct self.dlg.subproducts_comboBox.removeItem( 1) # Removing default subproduct value of 'rfe' # Links the Radio buttons and datetime widgets self.dlg.multi_radioButton.toggled.connect( lambda: self.radio_btn_state(self.dlg.single_radioButton, self.dlg. dateTimeEdit_1, self.dlg. dateTimeEdit_2)) # Show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # Create the dialog with elements (after translation) and keep reference # Only create GUI ONCE in callback, so that it will only load when the plugin is started if self.first_start == True: self.first_start = False self.dlg = AssimilaDatacCubeDialog(self.iface) # Runs when OK button is pressed if result: # runs process using values in widgets product = (self.dlg.products_comboBox.currentText()).lower() print(product) subproduct = self.dlg.subproducts_comboBox.currentText() print(subproduct) north = self.dlg.N_spinBox.value() print('N: ' + str(north)) east = self.dlg.E_spinBox.value() print('E: ' + str(east)) south = self.dlg.S_spinBox.value() print('S: ' + str(south)) west = self.dlg.W_spinBox.value() print('W: ' + str(west)) # Format start and end dates and hour for datecube start = self.dlg.dateTimeEdit_1.dateTime().toString( "yyyy-MM-ddTHH:00:00") if self.dlg.single_radioButton.isChecked(): end = start else: end = self.dlg.dateTimeEdit_2.dateTime().toString( "yyyy-MM-ddTHH:00:00") # Perform checks method self.check(north, east, south, west, self.dlg.dateTimeEdit_1.dateTime(), self.dlg.dateTimeEdit_2.dateTime()) # Get Xarray from datacube y = self.get_data_from_datacube_nesw(product, subproduct, north, east, south, west, start, end) # Re-formats the start and end dates and hour for filename start_datetime = self.dlg.dateTimeEdit_1.dateTime().toString( "yyyyMMdd_HH") end_datetime = self.dlg.dateTimeEdit_2.dateTime().toString( "yyyyMMdd_HH") # Create filename and find its path filename = "%s_%s_N%d_E%d_S%d_W%d_%s_%s" % ( product, subproduct, north, east, south, west, start_datetime, end_datetime) default_temp_path = f"{tempfile.gettempdir()}/{filename}.nc" # Write Xarray to netcdf y.to_netcdf(default_temp_path) print(default_temp_path) # Creates new layer and adds to current project self.iface.addRasterLayer(default_temp_path, "raster_file") pass
class QFieldSync(object): """QGIS Plugin Implementation.""" QFIELD_SCOPE = "QFieldSync" push_dlg = None def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QLocale(QSettings().value('locale/userLocale')) locale_path = os.path.join(self.plugin_dir, 'i18n') self.translator = QTranslator() self.translator.load(locale, 'QFieldSync', '_', locale_path) QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.actions = [] self.menu = self.tr(u'&QFieldSync') # TODO: We are going to let the user set this up in a future iteration self.toolbar = self.iface.addToolBar(u'QFieldSync') self.toolbar.setObjectName(u'QFieldSync') # instance of the QgsOfflineEditing self.offline_editing = QgsOfflineEditing() self.preferences = Preferences() QgsProject.instance().readProject.connect(self.update_button_enabled_status) # store warnings from last run self.last_action_warnings = [] # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('QFieldSync', message) def add_action( self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: self.toolbar.addAction(action) if add_to_menu: self.iface.addPluginToMenu( self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" self.push_action = self.add_action( ':/plugins/qfieldsync/refresh.png', text=self.tr(u'Package for QField'), callback=self.show_package_dialog, parent=self.iface.mainWindow()) self.add_action( ':/plugins/qfieldsync/refresh-reverse.png', text=self.tr(u'Synchronize from QField'), callback=self.show_synchronize_dialog, parent=self.iface.mainWindow()) self.add_action( ':/plugins/qfieldsync/icon.png', text=self.tr(u'Project Configuration'), callback=self.show_project_configuration_dialog, parent=self.iface.mainWindow(), add_to_toolbar=False ) self.add_action( ':/plugins/qfieldsync/icon.png', text=self.tr(u'Preferences'), callback=self.show_preferences_dialog, parent=self.iface.mainWindow(), add_to_toolbar=False) self.update_button_enabled_status() def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginMenu( self.tr(u'&QFieldSync'), action) self.iface.removeToolBarIcon(action) # remove the toolbar del self.toolbar def show_preferences_dialog(self): dlg = PreferencesDialog(self.preferences, self.iface.mainWindow()) dlg.exec_() def show_synchronize_dialog(self): """ Synchronize from QField """ dlg = SynchronizeDialog(self.iface, self.preferences, self.offline_editing, self.iface.mainWindow()) dlg.exec_() def show_package_dialog(self): """ Push to QField """ self.push_dlg = PackageDialog(self.iface, self.preferences, QgsProject.instance(), self.offline_editing, self.iface.mainWindow()) self.push_dlg.setAttribute(Qt.WA_DeleteOnClose) self.push_dlg.setWindowFlags(self.push_dlg.windowFlags() | Qt.Tool) self.push_dlg.show() self.push_dlg.finished.connect(self.push_dialog_finished) self.update_button_enabled_status() def show_project_configuration_dialog(self): """ Show the project configuration dialog. """ dlg = ProjectConfigurationDialog(self.iface, self.iface.mainWindow()) dlg.exec_() def action_start(self): self.clear_last_action_warnings() def clear_last_action_warnings(self): self.last_action_warnings = [] def push_dialog_finished(self): """ When the push dialog is closed, make sure it's no longer enabled before entering update_button_enabled_status() """ try: self.push_dlg.setEnabled(False) except RuntimeError: pass self.update_button_enabled_status() def update_button_enabled_status(self): """ Will update the plugin buttons according to open dialog and project properties. """ try: dialog_is_enabled = self.push_dlg and self.push_dlg.isEnabled() except RuntimeError: dialog_is_enabled = False if self.offline_editing.isOfflineProject() or dialog_is_enabled: self.push_action.setEnabled(False) else: self.push_action.setEnabled(True)
class S411_ICE_DATA: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'S411_ICE_DATA_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.actions = [] self.menu = self.tr(u'&S-411 ICE DATA Loader (BSH)') # Check if plugin was started the first time in current QGIS session # Must be set in initGui() to survive plugin reloads self.first_start = None # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('S411_ICE_DATA', message) def add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: # Adds plugin icon to Plugins toolbar self.iface.addToolBarIcon(action) if add_to_menu: self.iface.addPluginToMenu(self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/s411_ice_data_loader/icon.png' self.add_action(icon_path, text=self.tr(u'IHO S-411 Ice Data Loader'), callback=self.run, parent=self.iface.mainWindow()) # will be set False in run() self.first_start = True def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginMenu( self.tr(u'&S-411 ICE DATA Loader (BSH)'), action) self.iface.removeToolBarIcon(action) def run(self): """Run method that performs all the real work""" # Create the dialog with elements (after translation) and keep reference # Only create GUI ONCE in callback, so that it will only load when the plugin is started if self.first_start == True: self.first_start = False self.dlg = S411_ICE_DATADialog() # Own Code fullIceDataSets = [] with ftplib.FTP('ftp.bsh.de') as ftp: print(ftp.getwelcome()) try: ftp.login() ftp.cwd('outgoing/eisbericht/S411') files = [] ftp.retrlines('LIST', files.append) #fullIceDataSets.append("most recent") for fl in files: if "S411_full" in fl: tokens = fl.split(maxsplit=9) fullIceDataSets.append( str(tokens[8]).replace(".zip", "")) fullIceDataSets.sort(reverse=True) self.dlg.comboBox.addItems(fullIceDataSets) self.dlg.show() result = self.dlg.exec_() if result: savedir = 'C:/temp/ice' if not os.path.exists(savedir): os.makedirs(savedir) os.chdir(savedir) else: os.chdir(savedir) comboBoxValue = str(self.dlg.comboBox.currentText()) iceDataSetName = comboBoxValue + '.zip' localFile = savedir + '/' + iceDataSetName print(iceDataSetName) ftp.retrbinary('RETR ' + iceDataSetName, open(localFile, 'wb').write) ftp.close() localZipFile = zipfile.ZipFile(localFile) localZipFile.extractall() localZipFile.close() os.remove(localFile) iceDataSetGmlPath = localFile.replace( '.zip', '/data/') + comboBoxValue + '.gml' print(iceDataSetGmlPath) vlayer = iface.addVectorLayer(iceDataSetGmlPath, comboBoxValue, "ogr") # get Style styleDirName = os.path.dirname(__file__) styleComboBoxValue = str(self.dlg.comboBox_2.currentText()) sldFileName = os.path.join(styleDirName, 'SLD\\seaice_iceact.sld') if styleComboBoxValue == "Total Concentration (ICEACT)": sldFileName = os.path.join(styleDirName, 'SLD\\seaice_iceact.sld') vlayer.setName(comboBoxValue + '_seaice_iceact') if styleComboBoxValue == "Stage of Development (ICESOD)": vlayer.setName(comboBoxValue + '_seaice_icesod') sldFileName = os.path.join(styleDirName, 'SLD\\seaice_icesod.sld') print(sldFileName) vlayer.loadSldStyle(sldFileName) if not vlayer: print("Layer failed to load!") except ftplib.all_errors as e: print('FTP error: ', e)
class PolygonsFromCSV: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ self.csv_fields = None self.output_layer = None self.import_log_path = None self.csv_data_error = '' # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'PolygonsFromCSV_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.actions = [] self.menu = self.tr(u'&PolygonsFromCSV') # Check if plugin was started the first time in current QGIS session # Must be set in initGui() to survive plugin reloads self.first_start = None # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('PolygonsFromCSV', message) def add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: # Adds plugin icon to Plugins toolbar self.iface.addToolBarIcon(action) if add_to_menu: self.iface.addPluginToMenu(self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/polygons_from_csv/icon.png' self.add_action(icon_path, text=self.tr(u'PolygonsFromCSV'), callback=self.run, parent=self.iface.mainWindow()) # will be set False in run() self.first_start = True def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginMenu(self.tr(u'&PolygonsFromCSV'), action) self.iface.removeToolBarIcon(action) def set_import_log_path(self, csv_path): """ Set full path to import log file. :param csv_path: str, full path to CSV data file """ directory, file_name = os.path.split(csv_path) base_name = os.path.splitext(file_name)[0] timestamp = datetime.now().strftime("%Y-%m-%d-%H%M%S") self.import_log_path = os.path.join( directory, "{}_Import_{}.log".format(timestamp, base_name)) def log_message(self, message): """ Append message to import log file. :param message: str, message to log """ with open(self.import_log_path, 'a') as f: timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f") f.write("{} | {}\n".format(timestamp, message)) def open_import_log(self): os.startfile(self.import_log_path) def disable_show_import_log_file(self): self.dlg.pushButtonShowImportLogFile.setEnabled(False) self.dlg.pushButtonShowImportLogFile.setText("") def enable_show_import_log_file(self): self.dlg.pushButtonShowImportLogFile.setEnabled(True) self.dlg.pushButtonShowImportLogFile.setText(self.import_log_path) def initialize_csv_fields_assignment(self): """ Fill in drop-down lists with CSV fields. """ self.dlg.comboBoxFieldPolygonName.addItems(self.csv_fields) self.dlg.comboBoxFieldLongitude.addItems(self.csv_fields) self.dlg.comboBoxFieldLatitude.addItems(self.csv_fields) def remove_csv_fields_assignment(self): """ Remove CSV fields assigned to drop-down lists. """ self.dlg.comboBoxFieldPolygonName.clear() self.dlg.comboBoxFieldLongitude.clear() self.dlg.comboBoxFieldLatitude.clear() def get_csv_fields(self): input_path = self.dlg.mQgsFileWidgetInputFile.filePath() if os.path.isfile(input_path): with open(input_path, 'r') as file: delimiter = self.dlg.comboBoxCSVDelimiter.currentText() reader = csv.DictReader(file, delimiter=delimiter) return reader.fieldnames def reset_csv_fields_assignment(self): """ Read fields from CSV input file and fill drop-down lists with them if there are 3 or more fields in CSV file. """ self.disable_show_import_log_file() fields = self.get_csv_fields() if fields: fields_count = len(fields) if fields_count >= 3: self.csv_fields = fields self.remove_csv_fields_assignment() self.initialize_csv_fields_assignment() else: self.csv_fields = None self.remove_csv_fields_assignment() QMessageBox.critical(QWidget(), "Message", "At least 3 fields required!") @staticmethod def is_field_value_none(value): if value is None: return True @staticmethod def is_field_value_empty(value): if value.strip() == '': return True def get_raw_data(self, row): result = True err_msg = 'ERROR | ' for key, value in row.items(): if self.is_field_value_none(value): err_msg += 'Missing field {}. '.format(key) result = False elif self.is_field_value_empty(value): err_msg += 'Empty field {}. '.format(key) result = False if not result: self.log_message('{} {}'.format(err_msg, row)) else: return row def get_vertex_data(self, row): raw_data = self.get_raw_data(row) if raw_data: polygon_name = raw_data[ self.dlg.comboBoxFieldPolygonName.currentText()] lon = Coordinate( raw_data[self.dlg.comboBoxFieldLongitude.currentText()], AT_LONGITUDE) lat = Coordinate( raw_data[self.dlg.comboBoxFieldLatitude.currentText()], AT_LATITUDE) lon_dd = lon.convert_to_dd() lat_dd = lat.convert_to_dd() if lon_dd is not None and lat_dd is not None: vertex = QgsPointXY(lon_dd, lat_dd) return polygon_name, vertex else: self.log_message( "ERROR | Invalid coordinate(s) or coordinate(s) " "format not supported " "{}.".format(raw_data)) @staticmethod def generate_layer_name(): """ Generate layer name based on timestamp. """ timestamp = datetime.now() return timestamp.strftime("%Y_%m_%d_%H%M%f") def create_output_layer(self, layer_name): """ Create output layer with polygons - memory layer. """ self.output_layer = QgsVectorLayer('Polygon?crs=epsg:4326', layer_name, 'memory') provider = self.output_layer.dataProvider() self.output_layer.startEditing() provider.addAttributes( [QgsField("POL_NAME", QVariant.String, len=100)]) self.output_layer.commitChanges() QgsProject.instance().addMapLayer(self.output_layer) def create_polygon(self, polygon, polygon_name, vertices): """ Create and add polygon to output layer. :param polygon: QgsFeature(), feature to be created and added to output layer :param polygon_name: str :param vertices: list, list of QgsPoint - vertices to create shape of polygon """ if polygon_name: vertices_number = len(vertices) if vertices_number >= 3: # At least 3 vertices required to create polygon # Check if first and last vertices have the same coordinates first_vertex = vertices[0] last_vertex = vertices[-1] if not first_vertex.compare(last_vertex): vertices.append(vertices[0]) polygon.setAttributes([polygon_name]) polygon.setGeometry(QgsGeometry.fromPolygonXY([vertices])) provider = self.output_layer.dataProvider() provider.addFeature(polygon) self.output_layer.commitChanges() self.log_message("INFO | Polygon added to output layer. " "Polygon {}, vertices count {}.".format( polygon_name, len(vertices))) else: self.log_message("ERROR | Not enough vertices. " "Polygon {}, vertices count {}.".format( polygon_name, vertices_number)) def import_polygons_from_csv_file(self): """ Read CSV file, create polygons and and them to output layer. """ input_path = self.dlg.mQgsFileWidgetInputFile.filePath() if self.is_plugin_form_data_correct(): delimiter = self.dlg.comboBoxCSVDelimiter.currentText() self.set_import_log_path(input_path) self.log_message( "INFO | Importing polygons from file {} started.".format( input_path)) layer_name = self.generate_layer_name() self.create_output_layer(layer_name) with open(input_path, 'r') as input_file: reader = csv.DictReader(input_file, delimiter=delimiter) current_polygon_name = None polygon_name = None vertices = [] polygon = QgsFeature() while True: try: row = next(reader) vertex_data = self.get_vertex_data(row) if vertex_data: polygon_name, vertex = vertex_data if polygon_name == current_polygon_name: vertices.append(vertex) else: self.create_polygon(polygon, current_polygon_name, vertices) current_polygon_name = polygon_name vertices.clear() vertices.append(vertex) except StopIteration: self.create_polygon(polygon, polygon_name, vertices) self.enable_show_import_log_file() break # Stop iteration def is_plugin_form_data_correct(self): """ Check if input data in plugin form is correct, example: input file is selected """ self.disable_show_import_log_file() input_path = self.dlg.mQgsFileWidgetInputFile.filePath() if input_path.strip() == "": QMessageBox.critical(QWidget(), "Message", "Select input CSV file!") elif os.path.isfile(input_path): if self.csv_fields: if self.dlg.comboBoxFieldLongitude.currentText( ) == self.dlg.comboBoxFieldLatitude.currentText(): QMessageBox.critical( QWidget(), "Message", "Longitude and latitude fields can not be the same!") else: return True else: QMessageBox.critical(QWidget(), "Message", "At least 3 fields required!") else: QMessageBox.critical(QWidget(), "Message", "{} is not a file!".format(input_path)) def run(self): """Run method that performs all the real work""" # Create the dialog with elements (after translation) and keep reference # Only create GUI ONCE in callback, so that it will only load when the plugin is started if self.first_start == True: self.first_start = False self.dlg = PolygonsFromCSVDialog() self.disable_show_import_log_file() self.dlg.pushButtonCreatePolygons.clicked.connect( self.import_polygons_from_csv_file) self.dlg.pushButtonCancel.clicked.connect(self.dlg.close) self.dlg.pushButtonShowImportLogFile.clicked.connect( self.open_import_log) self.dlg.comboBoxCSVDelimiter.currentIndexChanged.connect( self.reset_csv_fields_assignment) self.dlg.mQgsFileWidgetInputFile.fileChanged.connect( self.reset_csv_fields_assignment) self.dlg.mQgsFileWidgetInputFile.setFilter('*.csv') # show the dialog self.dlg.show() self.dlg.mQgsFileWidgetInputFile.lineEdit().clear() self.dlg.comboBoxCSVDelimiter.setCurrentIndex(0) self.remove_csv_fields_assignment() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: # Do something useful here - delete the line containing pass and # substitute with your code. pass
class FFTConvolution: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'FFTConvolution_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Create the dialog (after translation) and keep reference self.dlg = FFTConvolutionDialog() # Declare instance attributes self.actions = [] self.menu = self.tr(u'&FFT COnvolution Filters') # TODO: We are going to let the user set this up in a future iteration self.toolbar = self.iface.addToolBar(u'FFTConvolution') self.toolbar.setObjectName(u'FFTConvolution') self.dlg.output_file.clear() self.dlg.output_file_button.clicked.connect(self.select_output_file) # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('FFTConvolution', message) def add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: self.toolbar.addAction(action) if add_to_menu: self.iface.addPluginToRasterMenu(self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/FFTConvolution/icon.png' self.add_action(icon_path, text=self.tr(u'FFT Convolution filters'), callback=self.run, parent=self.iface.mainWindow()) def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginRasterMenu( self.tr(u'&FFT COnvolution Filters'), action) self.iface.removeToolBarIcon(action) # remove the toolbar del self.toolbar def select_output_file(self): filename = QFileDialog.getSaveFileName(self.dlg, "Select output file ", "", '*.tif')[0] self.dlg.output_file.setText(filename) def run(self): """Run method that performs all the real work""" # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: if self.dlg.smoothing.isChecked(): edge = False else: edge = True #call the function linking to real work #the input is translated from the GUI input to correct format here self.fft_convolution(in_layer=self.dlg.input_layer.currentLayer(), out_path=self.dlg.output_file.text(), size=self.dlg.size.text(), edge=edge, new_crs=self.dlg.crs.crs(), tiled=self.dlg.window.isChecked(), tilerows=self.dlg.window_rows.text(), tilecols=self.dlg.window_cols.text(), add_layer=self.dlg.check_add.isChecked()) #this function parses the arguments, calls the appropriate functions and displays the new layer if needed def fft_convolution(self, in_layer, out_path, size=10, edge=False, new_crs=None, tiled=False, tilerows=0, tilecols=0, add_layer=True): #if the file has no extension, add '.tif' ext = os.path.splitext(out_path)[-1].lower() if ext == '': out_path = out_path + '.tif' #if the file already exists, ask the user if os.path.isfile(out_path): reply = QMessageBox.question(None, 'File exists!', 'File exists - overwite it?', QMessageBox.Yes, QMessageBox.No) if reply == QMessageBox.No: return False #we need the CRS as EPSG code, or None if invalid if new_crs.isValid(): new_crs = new_crs.authid() else: new_crs = None #preprocessing the input layer's path in_path = in_layer.dataProvider().dataSourceUri() #QMessageBox.information(None, "DEBUG:", str(in_path)) if in_path.find('=') > -1: QMessageBox.information(None, "Sorry!", "WMS support wasn't implemented yet!") return False #the main computation layer = self.gaussian_filter(in_path=in_path, out_path=out_path, size=int(re.sub(r"\D", "", size)), edge=edge, tiled=tiled, tilerows=tilerows, tilecols=tilecols, new_crs=new_crs) if add_layer: QgsProject.instance().addMapLayer(layer) qgis.utils.iface.mapCanvas().refresh() #returns number of array dimensions def __array_rank(self, arr): return len(arr.shape) #loads the newly created layer def __load_layer(self, path): fileName = path fileInfo = QFileInfo(fileName) baseName = fileInfo.baseName() rlayer = QgsRasterLayer(fileName, baseName) if not rlayer.isValid(): raise Exception( "Computation finished, but layer failed to load. Inspect the path you specified for the output layer." ) return rlayer #pads the window to process its original extend accurately def __extend_window(self, window, size, height, width): minrow = max(window[0][0] - size, 0) maxrow = min(window[0][1] + size, height) mincol = max(window[1][0] - size, 0) maxcol = min(window[1][1] + size, width) return ((minrow, maxrow), (mincol, maxcol)) #creates a window generator, in the same format as it is returned by block_windows method def __generate_windows(self, height, width, tilerows, tilecols): rownum = int(math.ceil(float(height) / tilerows)) colnum = int(math.ceil(float(width) / tilecols)) for i in range(rownum): #last row's and column's dimensions are computed by modulo - they are smaller than regular tiles if i == rownum - 1: rowsize = height % tilerows else: rowsize = tilerows for j in range(colnum): if j == colnum - 1: colsize = width % tilecols else: colsize = tilecols cell = ((i, j), ((i * tilerows, i * tilerows + rowsize), (j * tilecols, j * tilecols + colsize))) yield cell #like __generate_windows(), but returns an array def __generate_window_array(self, height, width, tilerows, tilecols): rownum = int(math.ceil(float(height) / tilerows)) colnum = int(math.ceil(float(width) / tilecols)) windows = np.asarray(np.zeros((height, width), dtype=object)) for i in range(rownum): #last row's and column's dimensions are computed by modulo - they are smaller than regular tiles if i == rownum - 1: rowsize = height % tilerows else: rowsize = tilerows for j in range(colnum): if j == colnum - 1: colsize = width % tilecols else: colsize = tilecols windows[i][j] = ((i * tilerows, i * tilerows + rowsize), (j * tilecols, j * tilecols + colsize)) return windows #processes the window parameters #returns the windows as a generator or an array (specified in the generator parameter) def __compute_windows(self, in_raster, height, width, size, tilerows=0, tilecols=0, generator=True): #input validation size = int(size) try: tilerows = int(tilerows) except ValueError: tilerows = 0 try: tilecols = int(tilecols) except ValueError: tilecols = 0 #when raster's dimensions are modified due to reprojection, we must adjust the windows as well #this algorithm is quick'n'dirty - we just sompute one ratio and make all tiles larger/smaller #reprojecting each tile node would be better - perhaps in some future version if height != in_raster.height or width != in_raster.width: hratio = float(height) / in_raster.height wratio = float(width) / in_raster.width else: hratio = 1 wratio = 1 windows = [] #if only one of tile's dimension was set, we assume a square if tilecols == 0 and tilerows > 0: tilecols = tilerows elif tilerows == 0 and tilecols > 0: tilerows = tilecols #if tiles are too small (including default 0 length), we make them automatically #"2*size" is the total padding length and also an arbitrarily chosen minimum #"size" would be a minimum to get accurate tiles, but this way only 1/9 of the tile would be useful => inefficient #"2*size" means at least 50% efficiency if min(tilerows, tilecols) <= 2 * size: #if the raster has blocks and they are big enough, we use them blocks = in_raster.block_shapes block = blocks[0] if min(block[0], block[1]) > 2 * size: #if we compute the original raster, use the block as-is #otherwise use the dimensions and continue if hratio == 1 and wratio == 1: return in_raster.block_windows(1) else: tilerows = block[0] tilecols = block[1] else: #"2*size + 100" is an arbitrary constant #it's quite efficient on smaller rasters and shouldn't make any memory issues #really small rasters shouldn't be computed by tiles anyway tilerows = 2 * size + 100 tilecols = 2 * size + 100 #we transform the dimensions if needed tilerows = int(hratio * tilerows) tilecols = int(wratio * tilecols) #if the tiles are too big (more than half of any dimension of the raster), #we switch to the untiled algorithm if 2 * tilerows >= height or 2 * tilecols >= width: return False #if windows are not read from the raster, we must make them if generator: windows = self.__generate_windows(height, width, tilerows, tilecols) else: windows = self.__generate_window_array(height, width, tilerows, tilecols) return windows #computes the affine transformation, raster dimensions and metadata for the new raster def __compute_transform(self, in_raster, new_crs): affine, width, height = calculate_default_transform( in_raster.crs, new_crs, in_raster.width, in_raster.height, *in_raster.bounds) kwargs = in_raster.meta.copy() kwargs.update({ 'driver': 'GTiff', 'crs': new_crs, 'transform': affine, 'affine': affine, 'width': width, 'height': height }) return affine, height, width, kwargs #calls reproject() function for every band def __reproject(self, in_raster, out_raster, affine, new_crs): for k in range(1, in_raster.count + 1): reproject(source=rasterio.band(in_raster, k), destination=rasterio.band(out_raster, k), src_transform=affine, src_crs=in_raster.crs, dst_transform=affine, dst_crs=new_crs, resampling=Resampling.nearest) return out_raster #the original MikeT's function from http://gis.stackexchange.com/a/10467 #my addition is the conversion of the padded array to float to avoid errors with integer rasters #the intended input is a single band raster array def __gaussian_blur1d(self, in_array, size): #check validity try: if 0 in in_array.shape: raise Exception("Null array can't be processed!") except TypeError: raise Exception("Null array can't be processed!") # expand in_array to fit edge of kernel padded_array = np.pad(in_array, size, 'symmetric').astype(float) # build kernel x, y = np.mgrid[-size:size + 1, -size:size + 1] g = np.exp(-(x**2 / float(size) + y**2 / float(size))) g = (g / g.sum()).astype(float) # do the Gaussian blur out_array = fftconvolve(padded_array, g, mode='valid') return out_array.astype(in_array.dtype) #the intended input is an array with various number of bands #returns a numpy array def __gaussian_blur(self, in_array, size): #make sure the input is a numpy array in_array = np.asarray(in_array) #find number of dimensions - 2 for single-band or 3 for multiband rasters rank = self.__array_rank(in_array) if rank == 2: return self.__gaussian_blur1d(in_array, size).astype(in_array.dtype) elif rank > 3 or rank == 1: raise TypeError("Invalid number of dimensions!") #continue to multiband count = in_array.shape[0] out = [] for i in range(count): band = in_array[i] out_band = self.__gaussian_blur1d(band, size) #.astype(in_array.dtype) #if out_band != False: out.append(out_band) return np.asarray(out) #the real work is done here #filters a raster specified by the file's path (in_path) and writes it to another file (out_path) def gaussian_filter(self, in_path, out_path, size, edge=False, tiled=False, tilerows=0, tilecols=0, new_crs=None): with rasterio.Env(): with rasterio.open(in_path, 'r') as in_raster: if new_crs == None: new_crs = in_raster.crs affine, height, width, kwargs = self.__compute_transform( in_raster, new_crs) if tiled: #we make two sets of tiles, for the old and the new raster #this is important in case of reprojection old_windows = self.__compute_windows( in_raster=in_raster, height=in_raster.height, width=in_raster.width, size=size, tilerows=tilerows, tilecols=tilecols) #windows for the new raster are made in two steps: generator and array new_windows = self.__compute_windows(in_raster=in_raster, height=height, width=width, size=size, tilerows=tilerows, tilecols=tilecols, generator=False) #if windows are too big or invalid, we process the raster without them try: iter(old_windows) iter(new_windows) except TypeError: tiled = False with rasterio.open(out_path, 'w', **kwargs) as out_raster: out_raster = self.__reproject(in_raster, out_raster, affine, new_crs) if tiled: for index, window in old_windows: oldbigwindow = self.__extend_window( window, size, in_raster.height, in_raster.width) in_array = in_raster.read(window=oldbigwindow) out_array = self.__gaussian_blur(in_array, size) #for edge detection we subtract the output array from the original #this may produce some artifacts when the raster is reprojected #or extensive and with degree coordinates if edge: out_array = np.subtract(in_array, out_array) #now compute the window for writing into the new raster nwindow = new_windows[index[0]][index[1]] newbigwindow = self.__extend_window( nwindow, size, height, width) out_raster.write(out_array, window=newbigwindow) else: in_array = in_raster.read() out_array = self.__gaussian_blur(in_array, size) if edge: out_array = out_array = np.subtract( in_array, out_array) out_raster.write(out_array) return self.__load_layer(out_path)
class CartoGIS54: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'CartoGIS54_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.actions = [] self.menu = self.tr(u'&CartoGIS54') # Check if plugin was started the first time in current QGIS session # Must be set in initGui() to survive plugin reloads self.first_start = None # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('CartoGIS54', message) def add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: # Adds plugin icon to Plugins toolbar self.iface.addToolBarIcon(action) if add_to_menu: self.iface.addPluginToMenu(self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/carto54/icon.png' self.add_action(icon_path, text=self.tr(u'CartoGIS54 - Configuration'), callback=self.run, parent=self.iface.mainWindow()) # will be set False in run() self.first_start = True def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginMenu(self.tr(u'&CartoGIS54'), action) self.iface.removeToolBarIcon(action) def destination(self): return self.dlg.ipt_dest.text() def host(self): return self.dlg.ipt_host.text() def open_destination_explorer(self, output): destination = QFileDialog.getExistingDirectory(self.dlg, "Choose destination", output.directory) if destination: self.dlg.ipt_dest.setText(destination) def open_brand_explorer(self, output): brand = QFileDialog.getOpenFileName( self.dlg, "Choose an image", output.directory, "Images (*.png *.jpg *.svg *.gif)")[0] if brand: self.dlg.ipt_brand.setText(brand) def fill_display_table(self, output): form.fill_table(self.dlg.tw_display, output.fields()) def generate_output(self, output): """ Save the output """ output.set_directory(self.dlg.ipt_dest.text()) output.set_host(self.dlg.ipt_host.text()) output.set_brand(self.dlg.ipt_brand.text()) output.set_modals(modals.get_all(self.dlg.tw_modals)) output.set_query_params(server.query_params(self.dlg.tw_qp)) output.set_fields_display(form.fields_display(self.dlg.tw_display)) print(output.__dict__) output.save() self.dlg.close() def run(self): """Run method that performs all the real work""" # Create the dialog with elements (after translation) and keep reference # Only create GUI ONCE in callback, so that it will only load when the plugin is started # Default values default_directory = QgsProject.instance().absolutePath() layers = [ l for l in QgsProject.instance().mapLayers().values() if l.type() == QgsMapLayerType.VectorLayer ] # Creating Output instance output = Output(default_directory) output.set_form(layers) if self.first_start: self.first_start = False self.dlg = CartoGIS54Dialog() # Config display table self.dlg.tw_display.setRowCount(len(output.fields())) self.fill_display_table(output) # Listening clicks on buttons self.dlg.btn_dest.clicked.connect( lambda: self.open_destination_explorer(output)) self.dlg.btn_add_qp.clicked.connect( lambda: server.add_row(self.dlg.tw_qp)) self.dlg.btn_delete_qp.clicked.connect( lambda: server.remove_rows(self.dlg.tw_qp)) self.dlg.btn_brand.clicked.connect( lambda: self.open_brand_explorer(output)) self.dlg.btn_add_modal.clicked.connect( lambda: modals.add_row(self.dlg.tw_modals)) self.dlg.btn_delete_modal.clicked.connect( lambda: modals.remove_rows(self.dlg.tw_modals)) self.dlg.btn_cancel.clicked.connect(self.dlg.close) self.dlg.btn_generate.clicked.connect( lambda: self.generate_output(output)) # show the dialog self.dlg.show()
class QuickOSMPlugin(object): def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface setup_logger('QuickOSM') # initialize plugin directory self.plugin_dir = dirname(__file__) # initialize locale # noinspection PyBroadException try: locale = QgsSettings().value('locale/userLocale', 'en')[0:2] except AttributeError: # Fallback to english #132 LOGGER.warning('Fallback to English as default language for the plugin') locale = 'en' locale_path = join( self.plugin_dir, 'i18n', 'QuickOSM_{0}.qm'.format(locale)) if exists(locale_path): LOGGER.info('Translation to {}'.format(locale)) self.translator = QTranslator() self.translator.load(locale_path) QCoreApplication.installTranslator(self.translator) self.provider = None # Add the toolbar self.toolbar = self.iface.addToolBar('QuickOSM') self.toolbar.setObjectName('QuickOSM') self.quickosm_menu = None self.vector_menu = None self.mainWindowAction = None self.osmFileAction = None self.osmFileDockWidget = None self.queryAction = None self.queryDockWidget = None self.quickQueryAction = None self.quickQueryDockWidget = None self.josmAction = None def initProcessing(self): """Init Processing provider for QGIS >= 3.8.""" self.provider = Provider() QgsApplication.processingRegistry().addProvider(self.provider) 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 unload(self): self.iface.removePluginVectorMenu('&QuickOSM', self.mainWindowAction) self.iface.removeToolBarIcon(self.mainWindowAction) QgsApplication.processingRegistry().removeProvider(self.provider) 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 openMainWindow(self): self.iface.QuickOSM_mainWindowDialog.listWidget.setCurrentRow(0) self.iface.QuickOSM_mainWindowDialog.exec_()
class NNJoin(object): """QGIS NNJoin Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save a reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join( self.plugin_dir, 'i18n', 'NNJoin_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.NNJOIN = self.tr('NNJoin') self.NNJOINAMP = self.tr('&NNJoin') self.toolbar = None # Separate toolbar for NNJoin: # self.toolbar = self.iface.addToolBar(self.NNJOIN) # self.toolbar.setObjectName(self.NNJOIN) # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('NNJoin', message) def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI""" icon_path = os.path.join(os.path.dirname(__file__), "nnjoin.png") # Create action that will start plugin configuration self.nnj_action = QAction( QIcon(icon_path), self.NNJOIN, self.iface.mainWindow()) # connect the action to the run method self.nnj_action.triggered.connect(self.run) # Add toolbar button if hasattr(self.iface, 'addVectorToolBarIcon'): self.iface.addVectorToolBarIcon(self.nnj_action) else: self.iface.addToolBarIcon(self.nnj_action) # Add menu item if hasattr(self.iface, 'addPluginToVectorMenu'): self.iface.addPluginToVectorMenu(self.NNJOINAMP, self.nnj_action) else: self.iface.addPluginToMenu(self.NNJOINAMP, self.nnj_action) def unload(self): """Removes the plugin menu item and icon from QGIS GUI""" # Remove the plugin menu item if hasattr(self.iface, 'removePluginVectorMenu'): self.iface.removePluginVectorMenu(self.NNJOINAMP, self.nnj_action) else: self.iface.removePluginMenu(self.NNJOINAMP, self.nnj_action) # Remove the plugin toolbar icon if hasattr(self.iface, 'removeVectorToolBarIcon'): self.iface.removeVectorToolBarIcon(self.nnj_action) else: self.iface.removeToolBarIcon(self.nnj_action) def run(self): """Run method that initialises and starts the user interface""" # Create the dialog (after translation) and keep reference self.dlg = NNJoinDialog(self.iface) # Intitalise the components self.dlg.progressBar.setValue(0.0) self.dlg.outputDataset.setText('Result') # Populate the input and join layer combo boxes # layers = QgsMapLayerRegistry.instance().mapLayers() layers = QgsProject.instance().mapLayers() layerslist = [] for id in layers.keys(): if layers[id].type() == QgsMapLayer.VectorLayer: if not layers[id].isValid(): QMessageBox.information(None, self.tr('Information'), 'Layer ' + layers[id].name() + ' is not valid') if layers[id].wkbType() != QgsWkbTypes.NoGeometry: layerslist.append((layers[id].name(), id)) if len(layerslist) == 0 or len(layers) == 0: QMessageBox.information(None, self.tr('Information'), self.tr('Vector layers not found')) return # Add the layers to the layers combobox self.dlg.inputVectorLayer.clear() for layerdescription in layerslist: self.dlg.inputVectorLayer.addItem(layerdescription[0], layerdescription[1]) # for alayer in self.iface.legendInterface().layers(): # for alayer in layers: # if alayer.type() == QgsMapLayer.VectorLayer: # self.dlg.inputVectorLayer.addItem(alayer.name(), alayer.id()) self.dlg.joinVectorLayer.clear() # for alayer in self.iface.legendInterface().layers(): # for alayer in layers: # if alayer.type() == QgsMapLayer.VectorLayer: # self.dlg.joinVectorLayer.addItem(alayer.name(), alayer.id()) # Add the layers to the layers combobox for layerdescription in layerslist: self.dlg.joinVectorLayer.addItem(layerdescription[0], layerdescription[1]) # show the dialog (needed for the messagebar cancel button) self.dlg.show() # Run the dialog event loop self.dlg.exec_()