Beispiel #1
0
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)
Beispiel #2
0
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)
Beispiel #6
0
    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)
Beispiel #8
0
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)
Beispiel #11
0
    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)
Beispiel #12
0
    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_()
Beispiel #14
0
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()
Beispiel #17
0
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 )
Beispiel #20
0
    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)
Beispiel #23
0
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)
Beispiel #24
0
    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()
Beispiel #26
0
    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)
Beispiel #27
0
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


#=========================================================================================
Beispiel #29
0
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)
Beispiel #31
0
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("")
Beispiel #35
0
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
Beispiel #36
0
 ***************************************************************************/
"""
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
Beispiel #37
0
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)
Beispiel #38
0
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 = []
Beispiel #39
0
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()
Beispiel #43
0
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)
Beispiel #48
0
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>&nbsp;</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)
Beispiel #50
0
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)
Beispiel #52
0
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
Beispiel #53
0
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
Beispiel #54
0
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)
Beispiel #55
0
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)
Beispiel #58
0
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()
Beispiel #59
0
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_()