class D3DataVis:
    heatmapDialog = None
    def __init__(self, iface):
        self.iface = iface

    def initGui(self):
        """ Initialize the menu and dialog boxes for the D3 heatmap chart """
        icon = QIcon(os.path.dirname(__file__) + "/icon.png")
        self.heatmapAction = QAction(icon, "Circular Date/Time Heatmap", self.iface.mainWindow())
        self.heatmapAction.triggered.connect(self.showHeatmapDialog)
        self.heatmapAction.setCheckable(False)
        self.iface.addWebToolBarIcon(self.heatmapAction)
        # Add a D3 Data Visualization menu item to the Web menu
        self.iface.addPluginToWebMenu("D3 Data Visualization", self.heatmapAction)

    def unload(self):
        self.iface.removePluginWebMenu("D3 Data Visualization", self.heatmapAction)
        self.iface.removeWebToolBarIcon(self.heatmapAction)
    
    def showHeatmapDialog(self):
        """Display the circular date/time heatmap dialog box"""
        if not self.heatmapDialog:
            from .heatmapDialog import HeatmapDialog
            self.heatmapDialog = HeatmapDialog(self.iface, self.iface.mainWindow())
        self.heatmapDialog.show()
Beispiel #2
0
class QMatplotlibWidget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.canvas = QMatplotlibCanvas()
        self.ax = self.canvas.ax
        self.figure = self.canvas.figure
        self.toolBar = NavigationToolbar2QT(self.canvas, self)

        bgColor = self.palette().color(QPalette.Background).name()
        self.figure.set_facecolor(bgColor)

        self.layout = QVBoxLayout()
        self.layout.setSpacing(2)
        self.layout.setMargin(0)

        self.layout.addWidget(self.toolBar)
        self.layout.addWidget(self.canvas)
        self.setLayout(self.layout)

        self._setupToolbar()

    def _setupToolbar(self):
        self.actionToggleGrid = QAction(self.tr('Toggle grid'), self.toolBar)
        self.actionToggleGrid.setIcon(
            QIcon(os.path.join(pluginPath, 'icons', 'toggleGrid.svg')))
        self.actionToggleGrid.setCheckable(True)

        self.actionToggleGrid.triggered.connect(self.toggleGrid)

        self.toolBar.insertAction(self.toolBar.actions()[7], self.actionToggleGrid)
        self.toolBar.insertSeparator(self.toolBar.actions()[8])

    def toggleGrid(self):
        self.ax.grid()
        self.canvas.draw()

    def alignLabels(self):
        self.figure.autofmt_xdate()

    def clear(self):
        self.ax.clear()
        self.canvas.draw()

    def setTitle(self, text):
        self.ax.set_title(text)

    def setXAxisCaption(self, text):
        self.ax.set_xlabel(text)

    def setYAxisCaption(self, text):
        self.ax.set_ylabel(text)
Beispiel #3
0
    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
class PlainGeometryEditor(object):

    def __init__(self, iface):
        self.iface = iface
        self.mapCanvas = iface.mapCanvas()
        self.dlgs = []
   
    def initGui(self):
        # help
        self.helpAction = QAction(QIcon(":/help.svg"), "Help", self.iface.mainWindow())
        self.helpAction.triggered.connect(lambda: QDesktopServices().openUrl(QUrl("http://3nids.github.io/plaingeometryeditor")))
        self.iface.addPluginToMenu("&Plain Geometry Editor", self.helpAction)
        # map tool action
        self.mapToolAction = QAction(QIcon(":/icon.svg"),
                                     "Plain Geometry Editor", self.iface.mainWindow())
        self.mapToolAction.setCheckable(True)
        self.mapTool = IdentifyGeometry(self.mapCanvas)
        self.mapTool.geomIdentified.connect(self.editGeometry)
        self.mapTool.setAction(self.mapToolAction)
        self.mapToolAction.triggered.connect(self.setMapTool)
        self.iface.addToolBarIcon(self.mapToolAction)
        self.iface.addPluginToMenu("&Plain Geometry Editor", self.mapToolAction)

    def unload(self):
        self.iface.removePluginMenu("&Plain Geometry Editor", self.helpAction)
        self.iface.removePluginMenu("&Plain Geometry Editor", self.mapToolAction)
        self.iface.removeToolBarIcon(self.mapToolAction)

    def setMapTool(self):
        self.mapCanvas.setMapTool(self.mapTool)
        
    def editGeometry(self, layer, feature):
        dlg = GeomEditorDialog(layer, feature, self.mapCanvas, self.iface.mainWindow())
        dlg.show()
        # save dlg so it does not get out of scope and layer is properly disconnect
        self.dlgs.append(dlg)
Beispiel #5
0
class PythonConsoleWidget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setWindowTitle(
            QCoreApplication.translate("PythonConsole", "Python Console"))

        self.settings = QgsSettings()

        self.shell = ShellScintilla(self)
        self.setFocusProxy(self.shell)
        self.shellOut = ShellOutputScintilla(self)
        self.tabEditorWidget = EditorTabWidget(self)

        # ------------ UI -------------------------------

        self.splitterEditor = QSplitter(self)
        self.splitterEditor.setOrientation(Qt.Horizontal)
        self.splitterEditor.setHandleWidth(6)
        self.splitterEditor.setChildrenCollapsible(True)

        self.shellOutWidget = QWidget(self)
        self.shellOutWidget.setLayout(QVBoxLayout())
        self.shellOutWidget.layout().setContentsMargins(0, 0, 0, 0)
        self.shellOutWidget.layout().addWidget(self.shellOut)

        self.splitter = QSplitter(self.splitterEditor)
        self.splitter.setOrientation(Qt.Vertical)
        self.splitter.setHandleWidth(3)
        self.splitter.setChildrenCollapsible(False)
        self.splitter.addWidget(self.shellOutWidget)
        self.splitter.addWidget(self.shell)

        # self.splitterEditor.addWidget(self.tabEditorWidget)

        self.splitterObj = QSplitter(self.splitterEditor)
        self.splitterObj.setHandleWidth(3)
        self.splitterObj.setOrientation(Qt.Horizontal)
        # self.splitterObj.setSizes([0, 0])
        # self.splitterObj.setStretchFactor(0, 1)

        self.widgetEditor = QWidget(self.splitterObj)
        self.widgetFind = QWidget(self)

        self.listClassMethod = QTreeWidget(self.splitterObj)
        self.listClassMethod.setColumnCount(2)
        objInspLabel = QCoreApplication.translate("PythonConsole",
                                                  "Object Inspector")
        self.listClassMethod.setHeaderLabels([objInspLabel, ''])
        self.listClassMethod.setColumnHidden(1, True)
        self.listClassMethod.setAlternatingRowColors(True)

        # self.splitterEditor.addWidget(self.widgetEditor)
        # self.splitterObj.addWidget(self.listClassMethod)
        # self.splitterObj.addWidget(self.widgetEditor)

        # Hide side editor on start up
        self.splitterObj.hide()
        self.listClassMethod.hide()
        # Hide search widget on start up
        self.widgetFind.hide()

        icon_size = iface.iconSize(
            dockedToolbar=True) if iface else QSize(16, 16)

        sizes = self.splitter.sizes()
        self.splitter.setSizes(sizes)

        # ----------------Restore Settings------------------------------------

        self.restoreSettingsConsole()

        # ------------------Toolbar Editor-------------------------------------

        # Action for Open File
        openFileBt = QCoreApplication.translate("PythonConsole",
                                                "Open Script…")
        self.openFileButton = QAction(self)
        self.openFileButton.setCheckable(False)
        self.openFileButton.setEnabled(True)
        self.openFileButton.setIcon(
            QgsApplication.getThemeIcon("mActionScriptOpen.svg"))
        self.openFileButton.setMenuRole(QAction.PreferencesRole)
        self.openFileButton.setIconVisibleInMenu(True)
        self.openFileButton.setToolTip(openFileBt)
        self.openFileButton.setText(openFileBt)

        openExtEditorBt = QCoreApplication.translate(
            "PythonConsole", "Open in External Editor")
        self.openInEditorButton = QAction(self)
        self.openInEditorButton.setCheckable(False)
        self.openInEditorButton.setEnabled(True)
        self.openInEditorButton.setIcon(
            QgsApplication.getThemeIcon("console/iconShowEditorConsole.svg"))
        self.openInEditorButton.setMenuRole(QAction.PreferencesRole)
        self.openInEditorButton.setIconVisibleInMenu(True)
        self.openInEditorButton.setToolTip(openExtEditorBt)
        self.openInEditorButton.setText(openExtEditorBt)
        # Action for Save File
        saveFileBt = QCoreApplication.translate("PythonConsole", "Save")
        self.saveFileButton = QAction(self)
        self.saveFileButton.setCheckable(False)
        self.saveFileButton.setEnabled(False)
        self.saveFileButton.setIcon(
            QgsApplication.getThemeIcon("mActionFileSave.svg"))
        self.saveFileButton.setMenuRole(QAction.PreferencesRole)
        self.saveFileButton.setIconVisibleInMenu(True)
        self.saveFileButton.setToolTip(saveFileBt)
        self.saveFileButton.setText(saveFileBt)
        # Action for Save File As
        saveAsFileBt = QCoreApplication.translate("PythonConsole", "Save As…")
        self.saveAsFileButton = QAction(self)
        self.saveAsFileButton.setCheckable(False)
        self.saveAsFileButton.setEnabled(True)
        self.saveAsFileButton.setIcon(
            QgsApplication.getThemeIcon("mActionFileSaveAs.svg"))
        self.saveAsFileButton.setMenuRole(QAction.PreferencesRole)
        self.saveAsFileButton.setIconVisibleInMenu(True)
        self.saveAsFileButton.setToolTip(saveAsFileBt)
        self.saveAsFileButton.setText(saveAsFileBt)
        # Action Cut
        cutEditorBt = QCoreApplication.translate("PythonConsole", "Cut")
        self.cutEditorButton = QAction(self)
        self.cutEditorButton.setCheckable(False)
        self.cutEditorButton.setEnabled(True)
        self.cutEditorButton.setIcon(
            QgsApplication.getThemeIcon("mActionEditCut.svg"))
        self.cutEditorButton.setMenuRole(QAction.PreferencesRole)
        self.cutEditorButton.setIconVisibleInMenu(True)
        self.cutEditorButton.setToolTip(cutEditorBt)
        self.cutEditorButton.setText(cutEditorBt)
        # Action Copy
        copyEditorBt = QCoreApplication.translate("PythonConsole", "Copy")
        self.copyEditorButton = QAction(self)
        self.copyEditorButton.setCheckable(False)
        self.copyEditorButton.setEnabled(True)
        self.copyEditorButton.setIcon(
            QgsApplication.getThemeIcon("mActionEditCopy.svg"))
        self.copyEditorButton.setMenuRole(QAction.PreferencesRole)
        self.copyEditorButton.setIconVisibleInMenu(True)
        self.copyEditorButton.setToolTip(copyEditorBt)
        self.copyEditorButton.setText(copyEditorBt)
        # Action Paste
        pasteEditorBt = QCoreApplication.translate("PythonConsole", "Paste")
        self.pasteEditorButton = QAction(self)
        self.pasteEditorButton.setCheckable(False)
        self.pasteEditorButton.setEnabled(True)
        self.pasteEditorButton.setIcon(
            QgsApplication.getThemeIcon("mActionEditPaste.svg"))
        self.pasteEditorButton.setMenuRole(QAction.PreferencesRole)
        self.pasteEditorButton.setIconVisibleInMenu(True)
        self.pasteEditorButton.setToolTip(pasteEditorBt)
        self.pasteEditorButton.setText(pasteEditorBt)
        # Action Run Script (subprocess)
        runScriptEditorBt = QCoreApplication.translate("PythonConsole",
                                                       "Run Script")
        self.runScriptEditorButton = QAction(self)
        self.runScriptEditorButton.setCheckable(False)
        self.runScriptEditorButton.setEnabled(True)
        self.runScriptEditorButton.setIcon(
            QgsApplication.getThemeIcon("mActionStart.svg"))
        self.runScriptEditorButton.setMenuRole(QAction.PreferencesRole)
        self.runScriptEditorButton.setIconVisibleInMenu(True)
        self.runScriptEditorButton.setToolTip(runScriptEditorBt)
        self.runScriptEditorButton.setText(runScriptEditorBt)
        # Action Run Script (subprocess)
        commentEditorBt = QCoreApplication.translate("PythonConsole",
                                                     "Comment")
        self.commentEditorButton = QAction(self)
        self.commentEditorButton.setCheckable(False)
        self.commentEditorButton.setEnabled(True)
        self.commentEditorButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconCommentEditorConsole.svg"))
        self.commentEditorButton.setMenuRole(QAction.PreferencesRole)
        self.commentEditorButton.setIconVisibleInMenu(True)
        self.commentEditorButton.setToolTip(commentEditorBt)
        self.commentEditorButton.setText(commentEditorBt)
        # Action Run Script (subprocess)
        uncommentEditorBt = QCoreApplication.translate("PythonConsole",
                                                       "Uncomment")
        self.uncommentEditorButton = QAction(self)
        self.uncommentEditorButton.setCheckable(False)
        self.uncommentEditorButton.setEnabled(True)
        self.uncommentEditorButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconUncommentEditorConsole.svg"))
        self.uncommentEditorButton.setMenuRole(QAction.PreferencesRole)
        self.uncommentEditorButton.setIconVisibleInMenu(True)
        self.uncommentEditorButton.setToolTip(uncommentEditorBt)
        self.uncommentEditorButton.setText(uncommentEditorBt)
        # Action for Object browser
        objList = QCoreApplication.translate("PythonConsole",
                                             "Object Inspector…")
        self.objectListButton = QAction(self)
        self.objectListButton.setCheckable(True)
        self.objectListButton.setEnabled(
            self.settings.value("pythonConsole/enableObjectInsp",
                                False,
                                type=bool))
        self.objectListButton.setIcon(
            QgsApplication.getThemeIcon("console/iconClassBrowserConsole.svg"))
        self.objectListButton.setMenuRole(QAction.PreferencesRole)
        self.objectListButton.setIconVisibleInMenu(True)
        self.objectListButton.setToolTip(objList)
        self.objectListButton.setText(objList)
        # Action for Find text
        findText = QCoreApplication.translate("PythonConsole", "Find Text")
        self.findTextButton = QAction(self)
        self.findTextButton.setCheckable(True)
        self.findTextButton.setEnabled(True)
        self.findTextButton.setIcon(
            QgsApplication.getThemeIcon("console/iconSearchEditorConsole.svg"))
        self.findTextButton.setMenuRole(QAction.PreferencesRole)
        self.findTextButton.setIconVisibleInMenu(True)
        self.findTextButton.setToolTip(findText)
        self.findTextButton.setText(findText)

        # ----------------Toolbar Console-------------------------------------

        # Action Show Editor
        showEditor = QCoreApplication.translate("PythonConsole", "Show Editor")
        self.showEditorButton = QAction(self)
        self.showEditorButton.setEnabled(True)
        self.showEditorButton.setCheckable(True)
        self.showEditorButton.setIcon(
            QgsApplication.getThemeIcon("console/iconShowEditorConsole.svg"))
        self.showEditorButton.setMenuRole(QAction.PreferencesRole)
        self.showEditorButton.setIconVisibleInMenu(True)
        self.showEditorButton.setToolTip(showEditor)
        self.showEditorButton.setText(showEditor)
        # Action for Clear button
        clearBt = QCoreApplication.translate("PythonConsole", "Clear Console")
        self.clearButton = QAction(self)
        self.clearButton.setCheckable(False)
        self.clearButton.setEnabled(True)
        self.clearButton.setIcon(
            QgsApplication.getThemeIcon("console/iconClearConsole.svg"))
        self.clearButton.setMenuRole(QAction.PreferencesRole)
        self.clearButton.setIconVisibleInMenu(True)
        self.clearButton.setToolTip(clearBt)
        self.clearButton.setText(clearBt)
        # Action for settings
        optionsBt = QCoreApplication.translate("PythonConsole", "Options…")
        self.optionsButton = QAction(self)
        self.optionsButton.setCheckable(False)
        self.optionsButton.setEnabled(True)
        self.optionsButton.setIcon(
            QgsApplication.getThemeIcon("console/iconSettingsConsole.svg"))
        self.optionsButton.setMenuRole(QAction.PreferencesRole)
        self.optionsButton.setIconVisibleInMenu(True)
        self.optionsButton.setToolTip(optionsBt)
        self.optionsButton.setText(optionsBt)
        # Action for Run script
        runBt = QCoreApplication.translate("PythonConsole", "Run Command")
        self.runButton = QAction(self)
        self.runButton.setCheckable(False)
        self.runButton.setEnabled(True)
        self.runButton.setIcon(
            QgsApplication.getThemeIcon("console/mIconRunConsole.svg"))
        self.runButton.setMenuRole(QAction.PreferencesRole)
        self.runButton.setIconVisibleInMenu(True)
        self.runButton.setToolTip(runBt)
        self.runButton.setText(runBt)

        # Help button
        self.helpConsoleAction = QAction(self)
        self.helpConsoleAction.setEnabled(True)
        self.helpConsoleAction.setText(
            QCoreApplication.translate("PythonConsole", "Python Console Help"))
        self.helpAPIAction = QAction(self)
        self.helpAPIAction.setEnabled(True)
        self.helpAPIAction.setText(
            QCoreApplication.translate("PythonConsole",
                                       "PyQGIS API Documentation"))
        self.helpCookbookAction = QAction(self)
        self.helpCookbookAction.setEnabled(True)
        self.helpCookbookAction.setText(
            QCoreApplication.translate("PythonConsole", "PyQGIS Cookbook"))

        self.helpMenu = QMenu(self)
        self.helpMenu.addAction(self.helpConsoleAction)
        self.helpMenu.addAction(self.helpAPIAction)
        self.helpMenu.addAction(self.helpCookbookAction)

        helpBt = QCoreApplication.translate("PythonConsole", "Help…")
        self.helpButton = QToolButton(self)
        self.helpButton.setPopupMode(QToolButton.InstantPopup)
        self.helpButton.setEnabled(True)
        self.helpButton.setIcon(
            QgsApplication.getThemeIcon("console/iconHelpConsole.svg"))
        self.helpButton.setToolTip(helpBt)
        self.helpButton.setMenu(self.helpMenu)

        self.toolBar = QToolBar()
        self.toolBar.setEnabled(True)
        self.toolBar.setFocusPolicy(Qt.NoFocus)
        self.toolBar.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.toolBar.setLayoutDirection(Qt.LeftToRight)
        self.toolBar.setIconSize(icon_size)
        self.toolBar.setMovable(False)
        self.toolBar.setFloatable(False)
        self.toolBar.addAction(self.clearButton)
        self.toolBar.addAction(self.runButton)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.showEditorButton)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.optionsButton)
        self.toolBar.addWidget(self.helpButton)

        self.toolBarEditor = QToolBar()
        self.toolBarEditor.setEnabled(False)
        self.toolBarEditor.setFocusPolicy(Qt.NoFocus)
        self.toolBarEditor.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.toolBarEditor.setLayoutDirection(Qt.LeftToRight)
        self.toolBarEditor.setIconSize(icon_size)
        self.toolBarEditor.setMovable(False)
        self.toolBarEditor.setFloatable(False)
        self.toolBarEditor.addAction(self.openFileButton)
        self.toolBarEditor.addAction(self.openInEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.saveFileButton)
        self.toolBarEditor.addAction(self.saveAsFileButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.runScriptEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.cutEditorButton)
        self.toolBarEditor.addAction(self.copyEditorButton)
        self.toolBarEditor.addAction(self.pasteEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.findTextButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.commentEditorButton)
        self.toolBarEditor.addAction(self.uncommentEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.objectListButton)

        self.widgetButton = QWidget()
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.widgetButton.sizePolicy().hasHeightForWidth())
        self.widgetButton.setSizePolicy(sizePolicy)

        self.widgetButtonEditor = QWidget(self.widgetEditor)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.widgetButtonEditor.sizePolicy().hasHeightForWidth())
        self.widgetButtonEditor.setSizePolicy(sizePolicy)

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.shellOut.sizePolicy().hasHeightForWidth())
        self.shellOut.setSizePolicy(sizePolicy)

        self.shellOut.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.shell.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)

        # ------------ Layout -------------------------------

        self.mainLayout = QGridLayout(self)
        self.mainLayout.setMargin(0)
        self.mainLayout.setSpacing(0)
        self.mainLayout.addWidget(self.widgetButton, 0, 0, 1, 1)
        self.mainLayout.addWidget(self.splitterEditor, 0, 1, 1, 1)

        self.shellOutWidget.layout().insertWidget(0, self.toolBar)

        self.layoutEditor = QGridLayout(self.widgetEditor)
        self.layoutEditor.setMargin(0)
        self.layoutEditor.setSpacing(0)
        self.layoutEditor.addWidget(self.toolBarEditor, 0, 1, 1, 1)
        self.layoutEditor.addWidget(self.widgetButtonEditor, 1, 0, 2, 1)
        self.layoutEditor.addWidget(self.tabEditorWidget, 1, 1, 1, 1)
        self.layoutEditor.addWidget(self.widgetFind, 2, 1, 1, 1)

        #  Layout for the find widget
        self.layoutFind = QGridLayout(self.widgetFind)
        self.layoutFind.setContentsMargins(0, 0, 0, 0)
        self.lineEditFind = QgsFilterLineEdit()
        placeHolderTxt = QCoreApplication.translate("PythonConsole",
                                                    "Enter text to find…")

        self.lineEditFind.setPlaceholderText(placeHolderTxt)
        self.toolBarFindText = QToolBar()
        self.toolBarFindText.setIconSize(icon_size)
        self.findNextButton = QAction(self)
        self.findNextButton.setEnabled(False)
        toolTipfindNext = QCoreApplication.translate("PythonConsole",
                                                     "Find Next")
        self.findNextButton.setToolTip(toolTipfindNext)
        self.findNextButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconSearchNextEditorConsole.svg"))
        self.findPrevButton = QAction(self)
        self.findPrevButton.setEnabled(False)
        toolTipfindPrev = QCoreApplication.translate("PythonConsole",
                                                     "Find Previous")
        self.findPrevButton.setToolTip(toolTipfindPrev)
        self.findPrevButton.setIcon(
            QgsApplication.getThemeIcon(
                "console/iconSearchPrevEditorConsole.svg"))
        self.caseSensitive = QCheckBox()
        caseSensTr = QCoreApplication.translate("PythonConsole",
                                                "Case Sensitive")
        self.caseSensitive.setText(caseSensTr)
        self.wholeWord = QCheckBox()
        wholeWordTr = QCoreApplication.translate("PythonConsole", "Whole Word")
        self.wholeWord.setText(wholeWordTr)
        self.wrapAround = QCheckBox()
        self.wrapAround.setChecked(True)
        wrapAroundTr = QCoreApplication.translate("PythonConsole",
                                                  "Wrap Around")
        self.wrapAround.setText(wrapAroundTr)

        self.toolBarFindText.addWidget(self.lineEditFind)
        self.toolBarFindText.addAction(self.findPrevButton)
        self.toolBarFindText.addAction(self.findNextButton)
        self.toolBarFindText.addWidget(self.caseSensitive)
        self.toolBarFindText.addWidget(self.wholeWord)
        self.toolBarFindText.addWidget(self.wrapAround)

        self.layoutFind.addWidget(self.toolBarFindText, 0, 1, 1, 1)

        # ------------ Add first Tab in Editor -------------------------------

        # self.tabEditorWidget.newTabEditor(tabName='first', filename=None)

        # ------------ Signal -------------------------------

        self.findTextButton.triggered.connect(self._toggleFind)
        self.objectListButton.toggled.connect(self.toggleObjectListWidget)
        self.commentEditorButton.triggered.connect(self.commentCode)
        self.uncommentEditorButton.triggered.connect(self.uncommentCode)
        self.runScriptEditorButton.triggered.connect(self.runScriptEditor)
        self.cutEditorButton.triggered.connect(self.cutEditor)
        self.copyEditorButton.triggered.connect(self.copyEditor)
        self.pasteEditorButton.triggered.connect(self.pasteEditor)
        self.showEditorButton.toggled.connect(self.toggleEditor)
        self.clearButton.triggered.connect(self.shellOut.clearConsole)
        self.optionsButton.triggered.connect(self.openSettings)
        self.runButton.triggered.connect(self.shell.entered)
        self.openFileButton.triggered.connect(self.openScriptFile)
        self.openInEditorButton.triggered.connect(self.openScriptFileExtEditor)
        self.saveFileButton.triggered.connect(self.saveScriptFile)
        self.saveAsFileButton.triggered.connect(self.saveAsScriptFile)
        self.helpConsoleAction.triggered.connect(self.openHelpConsole)
        self.helpAPIAction.triggered.connect(self.openHelpAPI)
        self.helpCookbookAction.triggered.connect(self.openHelpCookbook)
        self.listClassMethod.itemClicked.connect(self.onClickGoToLine)
        self.lineEditFind.returnPressed.connect(self._findNext)
        self.findNextButton.triggered.connect(self._findNext)
        self.findPrevButton.triggered.connect(self._findPrev)
        self.lineEditFind.textChanged.connect(self._textFindChanged)

        self.findScut = QShortcut(QKeySequence.Find, self.widgetEditor)
        self.findScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findScut.activated.connect(self._openFind)

        self.findNextScut = QShortcut(QKeySequence.FindNext, self.widgetEditor)
        self.findNextScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findNextScut.activated.connect(self._findNext)

        self.findPreviousScut = QShortcut(QKeySequence.FindPrevious,
                                          self.widgetEditor)
        self.findPreviousScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findPreviousScut.activated.connect(self._findPrev)

        # Escape on editor hides the find bar
        self.findScut = QShortcut(Qt.Key_Escape, self.widgetEditor)
        self.findScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findScut.activated.connect(self._closeFind)

    def _toggleFind(self):
        self.tabEditorWidget.currentWidget().newEditor.toggleFindWidget()

    def _openFind(self):
        self.tabEditorWidget.currentWidget().newEditor.openFindWidget()

    def _closeFind(self):
        self.tabEditorWidget.currentWidget().newEditor.closeFindWidget()

    def _findNext(self):
        self.tabEditorWidget.currentWidget().newEditor.findText(True)

    def _findPrev(self):
        self.tabEditorWidget.currentWidget().newEditor.findText(False)

    def _textFindChanged(self):
        if self.lineEditFind.text():
            self.findNextButton.setEnabled(True)
            self.findPrevButton.setEnabled(True)
            self.tabEditorWidget.currentWidget().newEditor.findText(
                True, showMessage=False, findFirst=True)
        else:
            self.lineEditFind.setStyleSheet('')
            self.findNextButton.setEnabled(False)
            self.findPrevButton.setEnabled(False)

    def onClickGoToLine(self, item, column):
        tabEditor = self.tabEditorWidget.currentWidget().newEditor
        if item.text(1) == 'syntaxError':
            check = tabEditor.syntaxCheck(fromContextMenu=False)
            if check and not tabEditor.isReadOnly():
                self.tabEditorWidget.currentWidget().save()
            return
        linenr = int(item.text(1))
        itemName = str(item.text(0))
        charPos = itemName.find(' ')
        if charPos != -1:
            objName = itemName[0:charPos]
        else:
            objName = itemName
        tabEditor.goToLine(objName, linenr)

    def toggleEditor(self, checked):
        self.splitterObj.show() if checked else self.splitterObj.hide()
        if not self.tabEditorWidget:
            self.tabEditorWidget.enableToolBarEditor(checked)
            self.tabEditorWidget.restoreTabsOrAddNew()

    def toggleObjectListWidget(self, checked):
        self.listClassMethod.show() if checked else self.listClassMethod.hide()

    def pasteEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.paste()

    def cutEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.cut()

    def copyEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.copy()

    def runScriptEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.runScriptCode()

    def commentCode(self):
        self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(True)

    def uncommentCode(self):
        self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(False)

    def openScriptFileExtEditor(self):
        tabWidget = self.tabEditorWidget.currentWidget()
        path = tabWidget.path
        import subprocess
        try:
            subprocess.Popen([os.environ['EDITOR'], path])
        except KeyError:
            QDesktopServices.openUrl(QUrl.fromLocalFile(path))

    def openScriptFile(self):
        lastDirPath = self.settings.value("pythonConsole/lastDirPath",
                                          QDir.homePath())
        openFileTr = QCoreApplication.translate("PythonConsole", "Open File")
        fileList, selected_filter = QFileDialog.getOpenFileNames(
            self, openFileTr, lastDirPath, "Script file (*.py)")
        if fileList:
            for pyFile in fileList:
                for i in range(self.tabEditorWidget.count()):
                    tabWidget = self.tabEditorWidget.widget(i)
                    if tabWidget.path == pyFile:
                        self.tabEditorWidget.setCurrentWidget(tabWidget)
                        break
                else:
                    tabName = QFileInfo(pyFile).fileName()
                    self.tabEditorWidget.newTabEditor(tabName, pyFile)

                    lastDirPath = QFileInfo(pyFile).path()
                    self.settings.setValue("pythonConsole/lastDirPath", pyFile)
                    self.updateTabListScript(pyFile, action='append')

    def saveScriptFile(self):
        tabWidget = self.tabEditorWidget.currentWidget()
        try:
            tabWidget.save()
        except (IOError, OSError) as error:
            msgText = QCoreApplication.translate(
                'PythonConsole',
                'The file <b>{0}</b> could not be saved. Error: {1}').format(
                    tabWidget.path, error.strerror)
            self.callWidgetMessageBarEditor(msgText, 2, False)

    def saveAsScriptFile(self, index=None):
        tabWidget = self.tabEditorWidget.currentWidget()
        if not index:
            index = self.tabEditorWidget.currentIndex()
        if not tabWidget.path:
            fileName = self.tabEditorWidget.tabText(index) + '.py'
            folder = self.settings.value("pythonConsole/lastDirPath",
                                         QDir.homePath())
            pathFileName = os.path.join(folder, fileName)
            fileNone = True
        else:
            pathFileName = tabWidget.path
            fileNone = False
        saveAsFileTr = QCoreApplication.translate("PythonConsole",
                                                  "Save File As")
        filename, filter = QFileDialog.getSaveFileName(self, saveAsFileTr,
                                                       pathFileName,
                                                       "Script file (*.py)")
        if filename:
            try:
                tabWidget.save(filename)
            except (IOError, OSError) as error:
                msgText = QCoreApplication.translate(
                    'PythonConsole',
                    'The file <b>{0}</b> could not be saved. Error: {1}'
                ).format(tabWidget.path, error.strerror)
                self.callWidgetMessageBarEditor(msgText, 2, False)
                if fileNone:
                    tabWidget.path = None
                else:
                    tabWidget.path = pathFileName
                return

            if not fileNone:
                self.updateTabListScript(pathFileName, action='remove')

    def openHelpConsole(self):
        QgsHelp.openHelp("plugins/python_console.html")

    def openHelpAPI(self):
        m = re.search(r'^([0-9]+)\.([0-9]+)\.', Qgis.QGIS_VERSION)
        if m:
            QDesktopServices.openUrl(
                QUrl('https://qgis.org/pyqgis/{}.{}/'.format(
                    m.group(1), m.group(2))))

    def openHelpCookbook(self):
        m = re.search(r'^([0-9]+)\.([0-9]+)\.', Qgis.QGIS_VERSION)
        if m:
            QDesktopServices.openUrl(
                QUrl(
                    'https://docs.qgis.org/{}.{}/en/docs/pyqgis_developer_cookbook/index.html'
                    .format(m.group(1), m.group(2))))

    def openSettings(self):
        if optionsDialog(self).exec_():
            self.shell.refreshSettingsShell()
            self.shellOut.refreshSettingsOutput()
            self.tabEditorWidget.refreshSettingsEditor()

    def callWidgetMessageBar(self, text):
        self.shellOut.widgetMessageBar(iface, text)

    def callWidgetMessageBarEditor(self, text, level, timed):
        self.tabEditorWidget.widgetMessageBar(iface, text, level, timed)

    def updateTabListScript(self, script, action=None):
        if action == 'remove':
            self.tabListScript.remove(script)
        elif action == 'append':
            if not self.tabListScript:
                self.tabListScript = []
            if script not in self.tabListScript:
                self.tabListScript.append(script)
        else:
            self.tabListScript = []
        self.settings.setValue("pythonConsole/tabScripts", self.tabListScript)

    def saveSettingsConsole(self):
        self.settings.setValue("pythonConsole/splitterConsole",
                               self.splitter.saveState())
        self.settings.setValue("pythonConsole/splitterObj",
                               self.splitterObj.saveState())
        self.settings.setValue("pythonConsole/splitterEditor",
                               self.splitterEditor.saveState())

        self.shell.writeHistoryFile(True)

    def restoreSettingsConsole(self):
        storedTabScripts = self.settings.value("pythonConsole/tabScripts", [])
        self.tabListScript = storedTabScripts
        self.splitter.restoreState(
            self.settings.value("pythonConsole/splitterConsole", QByteArray()))
        self.splitterEditor.restoreState(
            self.settings.value("pythonConsole/splitterEditor", QByteArray()))
        self.splitterObj.restoreState(
            self.settings.value("pythonConsole/splitterObj", QByteArray()))
Beispiel #6
0
class ProductionFrame(QFrame, FORM_CLASS):
    def __init__(self, dockwidget, parent=None):
        """Constructor."""
        super(ProductionFrame, self).__init__(parent)
        self.setupUi(self)
        self.dockwidget = dockwidget
        self.layer_registry = LayerRegistry()
        self.db = db
        self.db.connect()
        self.building_layer = QgsVectorLayer()
        self.add_outlines()
        # Set up edit dialog
        self.edit_dialog = EditDialog(self)
        self.change_instance = None

        self.cb_production.setChecked(True)

        # set up signals and slots
        self.btn_exit.clicked.connect(self.exit_clicked)
        self.cb_production.clicked.connect(self.cb_production_clicked)
        QgsProject.instance().layerWillBeRemoved.connect(self.layers_removed)

        self.setup_toolbar()

    def setup_toolbar(self):

        if "Add Outline" not in (
                action.text() for action in iface.building_toolbar.actions()):
            image_dir = os.path.join(__location__, "..", "icons")
            icon_path = os.path.join(image_dir, "plus.png")
            icon = QIcon()
            icon.addFile(icon_path, QSize(8, 8))
            self.add_action = QAction(icon, "Add Outline",
                                      iface.building_toolbar)
            iface.registerMainWindowAction(self.add_action, "Ctrl+1")
            self.add_action.triggered.connect(self.canvas_add_outline)
            iface.building_toolbar.addAction(self.add_action)

        if "Edit Geometry" not in (
                action.text() for action in iface.building_toolbar.actions()):
            image_dir = os.path.join(__location__, "..", "icons")
            icon_path = os.path.join(image_dir, "edit_geometry.png")
            icon = QIcon()
            icon.addFile(icon_path, QSize(8, 8))
            self.edit_geom_action = QAction(icon, "Edit Geometry",
                                            iface.building_toolbar)
            iface.registerMainWindowAction(self.edit_geom_action, "Ctrl+2")
            self.edit_geom_action.triggered.connect(self.canvas_edit_geometry)
            iface.building_toolbar.addAction(self.edit_geom_action)

        if "Edit Attributes" not in (
                action.text() for action in iface.building_toolbar.actions()):
            image_dir = os.path.join(__location__, "..", "icons")
            icon_path = os.path.join(image_dir, "edit_attributes.png")
            icon = QIcon()
            icon.addFile(icon_path, QSize(8, 8))
            self.edit_attrs_action = QAction(icon, "Edit Attributes",
                                             iface.building_toolbar)
            iface.registerMainWindowAction(self.edit_attrs_action, "Ctrl+3")
            self.edit_attrs_action.triggered.connect(
                self.canvas_edit_attribute)
            iface.building_toolbar.addAction(self.edit_attrs_action)

        iface.building_toolbar.show()

    def add_outlines(self):
        """
            Add building outlines to canvas
        """
        path = os.path.join(os.path.dirname(os.path.dirname(__file__)),
                            "styles/")
        self.layer_registry.remove_layer(self.building_layer)
        self.building_historic = self.layer_registry.add_postgres_layer(
            "historic_outlines", "building_outlines", "shape", "buildings", "",
            "end_lifespan is not NULL")
        self.building_historic.loadNamedStyle(path + "building_historic.qml")
        self.building_layer = None
        self.building_layer = self.layer_registry.add_postgres_layer(
            "building_outlines", "building_outlines", "shape", "buildings", "",
            "end_lifespan is NULL")
        self.building_layer.loadNamedStyle(path + "building_blue.qml")
        iface.setActiveLayer(self.building_layer)

    @pyqtSlot(bool)
    def cb_production_clicked(self, checked):
        group = QgsProject.instance().layerTreeRoot().findGroup(
            "Building Tool Layers")
        if checked:
            group.setItemVisibilityCheckedRecursive(True)
        else:
            group.setItemVisibilityCheckedRecursive(False)

    def canvas_add_outline(self):
        """
            When add outline radio button toggled
        """
        self.edit_dialog.show()
        self.edit_dialog.add_outline()
        self.change_instance = self.edit_dialog.get_change_instance()

        self.circle_tool = None
        self.polyline = None
        # setup circle button
        image_dir = os.path.join(__location__, "..", "icons")
        icon_path = os.path.join(image_dir, "circle.png")
        icon = QIcon()
        icon.addFile(icon_path, QSize(8, 8))
        self.circle_action = QAction(icon, "Draw Circle",
                                     iface.building_toolbar)
        iface.registerMainWindowAction(self.circle_action, "Ctrl+0")
        self.circle_action.triggered.connect(self.circle_tool_clicked)
        self.circle_action.setCheckable(True)
        iface.building_toolbar.addAction(self.circle_action)

    def circle_tool_clicked(self):
        if self.circle_action.isChecked():
            circle_tool.setup_circle(self)
        else:
            iface.actionAddFeature().trigger()

    def canvas_edit_attribute(self):
        """
            When edit outline radio button toggled
        """
        self.edit_dialog.show()
        self.edit_dialog.edit_attribute()
        self.change_instance = self.edit_dialog.get_change_instance()

    def canvas_edit_geometry(self):
        """
            When edit geometry radio button toggled
        """
        self.edit_dialog.edit_geometry()
        self.edit_dialog.show()
        self.change_instance = self.edit_dialog.get_change_instance()

    @pyqtSlot()
    def exit_clicked(self):
        """
        Called when edit production exit button clicked.
        """
        self.close_frame()
        self.dockwidget.lst_sub_menu.clearSelection()

    def close_frame(self):
        """
        Clean up and remove the edit production frame.
        """
        if self.change_instance is not None:
            self.edit_dialog.close()
        iface.actionCancelEdits().trigger()
        QgsProject.instance().layerWillBeRemoved.disconnect(
            self.layers_removed)
        self.layer_registry.remove_layer(self.building_layer)
        self.layer_registry.remove_layer(self.building_historic)
        # reset toolbar
        for action in iface.building_toolbar.actions():
            if action.objectName() not in ["mActionPan"]:
                iface.building_toolbar.removeAction(action)
        iface.building_toolbar.hide()

        from buildings.gui.menu_frame import MenuFrame

        dw = self.dockwidget
        dw.stk_options.removeWidget(dw.stk_options.currentWidget())
        dw.new_widget(MenuFrame(dw))

    @pyqtSlot()
    def edit_cancel_clicked(self):
        if len(QgsProject.instance().mapLayersByName("building_outlines")) > 0:
            if isinstance(self.change_instance,
                          production_changes.EditAttribute):
                try:
                    self.building_layer.selectionChanged.disconnect(
                        self.change_instance.selection_changed)
                except TypeError:
                    pass
            elif isinstance(self.change_instance,
                            production_changes.EditGeometry):
                try:
                    self.building_layer.geometryChanged.disconnect()
                except TypeError:
                    pass
            elif isinstance(self.change_instance,
                            production_changes.AddProduction):
                try:
                    self.building_layer.featureAdded.disconnect()
                except TypeError:
                    pass
                try:
                    self.building_layer.featureDeleted.disconnect()
                except TypeError:
                    pass
                try:
                    self.building_layer.geometryChanged.disconnect()
                except TypeError:
                    pass
                if self.polyline:
                    self.polyline.reset()
                if isinstance(self.circle_tool, PointTool):
                    self.circle_tool.canvas_clicked.disconnect()
                    self.circle_tool.mouse_moved.disconnect()
                    self.circle_tool.deactivate()
                iface.actionPan().trigger()

        iface.actionCancelEdits().trigger()

        self.setup_toolbar()
        self.change_instance = None

    @pyqtSlot(str)
    def layers_removed(self, layerids):
        self.layer_registry.update_layers()
        for layer in ["building_outlines", "historic_outlines"]:
            if layer in layerids:
                self.cb_production.setDisabled(1)
                iface.messageBar().pushMessage(
                    "ERROR",
                    "Required layer Removed! Please reload the buildings plugin or the current frame before continuing",
                    level=Qgis.Critical,
                    duration=5,
                )
                return
Beispiel #7
0
class HffPlugin_s(object):
    HOME = os.environ['HFF_HOME']

    PARAMS_DICT = {'SERVER': '',
                   'HOST': '',
                   'DATABASE': '',
                   'PASSWORD': '',
                   'PORT': '',
                   'USER': '',
                   'THUMB_PATH': '',
                   'THUMB_RESIZE': '',
                   'EXPERIMENTAL': ''}

    path_rel = os.path.join(os.sep, HOME, 'HFF_DB_folder', 'config.cfg')
    conf = open(path_rel, "rb+")
    data = conf.read()
    text = (b'THUMB_RESIZE')
   
    if text in data:
        pass   
    else:       
        conf.seek(-3,2)
        conf.read(1)    
        conf.write(b"','THUMB_RESIZE' : 'insert path for the image resized'}")
        
   
     
    conf.close()
    PARAMS_DICT = eval(data)

 

    def __init__(self, iface):
        self.iface = iface
        userPluginPath = os.path.dirname(__file__)
        systemPluginPath = QgsApplication.prefixPath() + "/python/plugins/HFF"

        # overrideLocale = QgsSettings().value("locale/overrideFlag", QVariant)  # .toBool()
        # if not overrideLocale:
            # localeFullName = QLocale.system().name()
        # else:
            # localeFullName = QgsSettings().value("locale/userLocale", QVariant)  # .toString()

        # if QFileInfo(userPluginPath).exists():
            # translationPath = userPluginPath + "/i18n/hff_system__plugin_" + localeFullName + ".qm"
        # else:
            # translationPath = systemPluginPath + "/i18n/hff_system__plugin_" + localeFullName + ".qm"

        # self.localePath = translationPath
        # if QFileInfo(self.localePath).exists():
            # self.translator = QTranslator()
            # self.translator.load(self.localePath)
            # QCoreApplication.installTranslator(self.translator)

    def initGui(self):
      
        settings = QgsSettings()
        icon_paius = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'hfflogo.png'))
        self.action = QAction(QIcon(icon_paius), "HFF Main Panel",
                              self.iface.mainWindow())
        self.action.triggered.connect(self.showHideDockWidget)

        # dock widget
        self.dockWidget = HffPluginDialog(self.iface)
        self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dockWidget)

        # TOOLBAR
        self.toolBar = self.iface.addToolBar("HFF")
        self.toolBar.setObjectName("HFF")
        self.toolBar.addAction(self.action)

        self.dataToolButton = QToolButton(self.toolBar)
        self.dataToolButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.toolBar.addSeparator()
        
        
        ######  Section dedicated to the basic data entry
        # add Actions data
        self.siteToolButton = QToolButton(self.toolBar)
        #self.siteToolButton.setPopupMode(QToolButton.MenuButtonPopup)
        icon_site = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'iconSite.png'))
        self.actionSite = QAction(QIcon(icon_site), "Site", self.iface.mainWindow())
        self.actionSite.setWhatsThis("Site")
        self.actionSite.triggered.connect(self.runSite)
        self.siteToolButton.addActions([self.actionSite])
        self.siteToolButton.setDefaultAction(self.actionSite)
        self.toolBar.addWidget(self.siteToolButton)
        self.toolBar.addSeparator()
        
        
        self.emeanaToolButton = QToolButton(self.toolBar)
        #self.emeanaToolButton.setPopupMode(QToolButton.MenuButtonPopup)
        icon_eamena = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'eamena.jpg'))
        self.actionEamena = QAction(QIcon(icon_eamena), "Eamena", self.iface.mainWindow())
        self.actionEamena.setWhatsThis("Eamena")
        self.actionEamena.triggered.connect(self.runEamena)
        self.emeanaToolButton.addActions([self.actionEamena])
        self.emeanaToolButton.setDefaultAction(self.actionEamena)
        self.toolBar.addWidget(self.emeanaToolButton)
        self.toolBar.addSeparator()
        
        ######  Section dedicated to the shipwreck
        # add Actions documentation
        self.ShipwreckToolButton = QToolButton(self.toolBar)
        icon_shipwreck = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'Shipwreck.png'))
        self.actionShipwreck = QAction(QIcon(icon_shipwreck), "Shipwreck", self.iface.mainWindow())
        self.actionShipwreck.setWhatsThis("Shipwreck")
        self.actionShipwreck.triggered.connect(self.runShipwreck)
        self.ShipwreckToolButton.addActions([self.actionShipwreck])
        self.ShipwreckToolButton.setDefaultAction(self.actionShipwreck)
        self.toolBar.addWidget(self.ShipwreckToolButton)
        self.toolBar.addSeparator()
        ######  Section dedicated to the UnderWater data entry
        # add Actions data
        icon_UW = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'snorkel.png'))
        self.actionUW = QAction(QIcon(icon_UW), "Divelog Form", self.iface.mainWindow())
        self.actionUW.setWhatsThis("Divelog")
        self.actionUW.triggered.connect(self.runUW)
        
        icon_ANC = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'iconANC.png'))
        self.actionANC = QAction(QIcon(icon_ANC), "Anchor", self.iface.mainWindow())
        self.actionANC.setWhatsThis("Anchor")
        self.actionANC.triggered.connect(self.runANC)
        
        icon_ART = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'radar.png'))
        self.actionART = QAction(QIcon(icon_ART), "Artefact", self.iface.mainWindow())
        self.actionART.setWhatsThis("Artefact")
        self.actionART.triggered.connect(self.runART)
        
        icon_Pottery = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'pottery.png'))
        self.actionPottery = QAction(QIcon(icon_Pottery), "Pottery", self.iface.mainWindow())
        self.actionPottery.setWhatsThis("Pottery")
        self.actionPottery.triggered.connect(self.runPottery)
        
        self.dataToolButton.addActions(
            [self.actionUW, self.actionART, self.actionANC, self.actionPottery])
        self.dataToolButton.setDefaultAction(self.actionUW)

        self.toolBar.addWidget(self.dataToolButton)

        self.toolBar.addSeparator()
        
        
 
        ######  Section dedicated to the documentation
        # add Actions documentation
        self.docToolButton = QToolButton(self.toolBar)
        self.docToolButton.setPopupMode(QToolButton.MenuButtonPopup)

       
        icon_imageViewer = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'photo.png'))
        self.actionimageViewer = QAction(QIcon(icon_imageViewer), "Media manager", self.iface.mainWindow())
        self.actionimageViewer.setWhatsThis("Media manager")
        self.actionimageViewer.triggered.connect(self.runImageViewer)

        icon_Directory_export = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'directoryExp.png'))
        self.actionImages_Directory_export = QAction(QIcon(icon_Directory_export), "Download image",
                                                     self.iface.mainWindow())
        self.actionImages_Directory_export.setWhatsThis("Download image")
        self.actionImages_Directory_export.triggered.connect(self.runImages_directory_export)

        icon_excel_exp = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'excel-export.png'))
        self.actionexcelExp = QAction(QIcon(icon_excel_exp), "Download EXCEL", self.iface.mainWindow())
        self.actionexcelExp.setWhatsThis("Download EXCEL")
        self.actionexcelExp.triggered.connect(self.runPdfexp)

      
        self.docToolButton.addActions(
            [self.actionexcelExp, self.actionimageViewer, self.actionexcelExp, self.actionImages_Directory_export])

        self.docToolButton.setDefaultAction(self.actionimageViewer)

        #if self.PARAMS_DICT['EXPERIMENTAL'] == 'Si':
        self.actionImages_Directory_export.setCheckable(True)
        self.actionexcelExp.setCheckable(True)
        self.actionimageViewer.setCheckable(True)

        self.toolBar.addWidget(self.docToolButton)

        self.toolBar.addSeparator()

       

        ######  Section dedicated to the plugin management

        self.manageToolButton = QToolButton(self.toolBar)
        self.manageToolButton.setPopupMode(QToolButton.MenuButtonPopup)


        icon_Con = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'iconConn.png'))
        self.actionConf = QAction(QIcon(icon_Con), "Config plugin", self.iface.mainWindow())
        self.actionConf.setWhatsThis("Config plugin")
        self.actionConf.triggered.connect(self.runConf)

        icon_Dbmanagment = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'backup.png'))
        self.actionDbmanagment = QAction(QIcon(icon_Dbmanagment), "Database manager", self.iface.mainWindow())
        self.actionDbmanagment.setWhatsThis("Database manager")
        self.actionDbmanagment.triggered.connect(self.runDbmanagment)

        icon_Info = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'iconInfo.png'))
        self.actionInfo = QAction(QIcon(icon_Info), "Plugin info", self.iface.mainWindow())
        self.actionInfo.setWhatsThis("Plugin info")
        self.actionInfo.triggered.connect(self.runInfo)

        self.manageToolButton.addActions(
            [self.actionConf,  self.actionDbmanagment, self.actionInfo])
        self.manageToolButton.setDefaultAction(self.actionConf)

        self.toolBar.addWidget(self.manageToolButton)

        self.toolBar.addSeparator()

        # menu
        self.iface.addPluginToMenu("HFF - Survey UW Archaeological GIS Tools", self.actionUW)
        self.iface.addPluginToMenu("HFF - Survey UW Archaeological GIS Tools", self.actionANC)
        self.iface.addPluginToMenu("HFF - Survey UW Archaeological GIS Tools", self.actionART)
        self.iface.addPluginToMenu("HFF - Survey UW Archaeological GIS Tools", self.actionPottery)
        
        self.iface.addPluginToMenu("HFF - Survey UW Archaeological GIS Tools", self.actionShipwreck)
        
        
        
        self.iface.addPluginToMenu("HFF - Survey Terrestrial Archaeological GIS Tools", self.actionSite)
        self.iface.addPluginToMenu("HFF - Survey Terrestrial Archaeological GIS Tools", self.actionEamena)
        
        self.iface.addPluginToMenu("HFF - Media manager GIS Tools", self.actionimageViewer)
        self.iface.addPluginToMenu("HFF - Media manager GIS Tools", self.actionexcelExp)
        self.iface.addPluginToMenu("HFF - Media manager GIS Tools", self.actionImages_Directory_export)

        
        self.iface.addPluginToMenu("HFF - Config GIS Tools", self.actionConf)
        
        self.iface.addPluginToMenu("HFF - Config GIS Tools", self.actionDbmanagment)
        self.iface.addPluginToMenu("HFF - Info GIS Tools", self.actionInfo)

        # MENU
        self.menu = QMenu("HFF")
        self.menu.addActions([self.actionSite])
        
        self.menu.addSeparator()
        self.menu.addActions([self.actionEamena])
        
        self.menu.addSeparator()
        
        self.menu.addActions([self.actionShipwreck])
        self.menu.addSeparator()
        self.menu.addActions([self.actionUW, self.actionART, self.actionANC, self.actionPottery])
        
        
        self.menu.addActions([self.actionimageViewer, self.actionexcelExp, self.actionImages_Directory_export])
        self.menu.addSeparator()
      
        self.menu.addActions([self.actionConf,  self.actionDbmanagment, self.actionInfo])
        menuBar = self.iface.mainWindow().menuBar()
        menuBar.addMenu(self.menu)
    
    ##
    def runSite(self):
        pluginGui = hff_system__Site(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save
        
    
    def runEamena(self):
        pluginGui = Eamena(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save    
    
    
    
    def runUW(self):
        pluginGui = hff_system__UW(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save

    def runANC(self):
        pluginGui = hff_system__ANC(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save

    def runART(self):
        pluginGui = hff_system__ART(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save

    def runPottery(self):
        pluginGui = hff_system__Pottery(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save
        
        
    def runShipwreck(self):
        pluginGui = hff_system__Shipwreck(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save    
    
    
    

    def runConf(self):
        pluginConfGui = HFF_systemDialog_Config()
        pluginConfGui.show()
        self.pluginGui = pluginConfGui  # save

    def runInfo(self):
        pluginInfoGui = HFF_systemDialog_Info()
        pluginInfoGui.show()
        self.pluginGui = pluginInfoGui  # save

    def runImageViewer(self):
        pluginImageView = Main()
        pluginImageView.show()
        self.pluginGui = pluginImageView  # save

   

    def runImages_directory_export(self):
        pluginImage_directory_export = hff_system__Images_directory_export()
        pluginImage_directory_export.show()
        self.pluginGui = pluginImage_directory_export  # save

    

    def runDbmanagment(self):
        pluginDbmanagment = hff_system__dbmanagment(self.iface)
        pluginDbmanagment.show()
        self.pluginGui = pluginDbmanagment  # save

    def runPdfexp(self):
        pluginPdfexp = hff_system__excel_export(self.iface)
        pluginPdfexp.show()
        self.pluginGui = pluginPdfexp  # save

   

    def unload(self):
        # Remove the plugin
        
        self.iface.removePluginMenu("HFF - Survey UW Archaeological GIS Tools", self.actionUW)
        self.iface.removePluginMenu("HFF - Survey UW Archaeological GIS Tools", self.actionANC)
        self.iface.removePluginMenu("HFF - Survey UW Archaeological GIS Tools", self.actionART)
        self.iface.removePluginMenu("HFF - Survey UW Archaeological GIS Tools", self.actionPottery)
        
        self.iface.removePluginMenu("HFF - Survey UW Archaeological GIS Tools", self.actionShipwreck)
        
        self.iface.removePluginMenu("HFF - Survey Terrestrial Archaeological GIS Tools", self.actionSite)
        self.iface.removePluginMenu("HFF - Survey Terrestrial Archaeological GIS Tools", self.actionEamena)
        
        self.iface.removePluginMenu("HFF - Media manager GIS Tools", self.actionimageViewer)
        self.iface.removePluginMenu("HFF - Media manager GIS Tools", self.actionImages_Directory_export)
        self.iface.removePluginMenu("HFF - Media manager GIS Tools", self.actionexcelExp)
        
        self.iface.removePluginMenu("HFF - Config GIS Tools", self.actionConf)
       
        self.iface.removePluginMenu("HFF - Info GIS Tools", self.actionInfo)
        self.iface.removePluginMenu("HFF - Config GIS Tools", self.actionDbmanagment)

        self.iface.removeToolBarIcon(self.actionUW)
        self.iface.removeToolBarIcon(self.actionART)
        self.iface.removeToolBarIcon(self.actionANC)
        self.iface.removeToolBarIcon(self.actionPottery)
        
        self.iface.removeToolBarIcon(self.actionShipwreck)
        
        self.iface.removeToolBarIcon(self.actionSite)
        self.iface.removeToolBarIcon(self.actionEamena)
        self.iface.removeToolBarIcon(self.actionimageViewer)
        self.iface.removeToolBarIcon(self.actionImages_Directory_export)
        self.iface.removeToolBarIcon(self.actionexcelExp)
        
        self.iface.removeToolBarIcon(self.actionConf)
       
        self.iface.removeToolBarIcon(self.actionInfo)
        self.iface.removeToolBarIcon(self.actionDbmanagment)

        self.dockWidget.setVisible(False)
        self.iface.removeDockWidget(self.dockWidget)

        # remove tool bar
        del self.toolBar
    
                
         
    def showHideDockWidget(self):
        if self.dockWidget.isVisible():
            self.dockWidget.hide()
        else:
            self.dockWidget.show()
    def create_tools(self):
        """
        Creates all map tools ands add them to the QGIS interface
        """
        action_single_point_templated_marker = QAction(
            GuiUtils.get_icon('single_point_templated_marker.svg'),
            self.tr('Single Point Templated Marker'))
        action_single_point_templated_marker.setCheckable(True)
        self.tools[SinglePointTemplatedMarkerTool.
                   ID] = SinglePointTemplatedMarkerTool(
                       self.iface.mapCanvas(), self.iface.cadDockWidget(),
                       self.iface, action_single_point_templated_marker)
        self.tools[SinglePointTemplatedMarkerTool.ID].setAction(
            action_single_point_templated_marker)
        action_single_point_templated_marker.triggered.connect(
            partial(self.switch_tool, SinglePointTemplatedMarkerTool.ID))
        action_single_point_templated_marker.setData(
            SinglePointTemplatedMarkerTool.ID)
        self.toolbar.addAction(action_single_point_templated_marker)
        self.actions.append(action_single_point_templated_marker)

        self.get_map_tool_action_group().addAction(
            action_single_point_templated_marker)

        # single point at center of line tool

        action_single_point_at_center_of_line = QAction(
            GuiUtils.get_icon('marker_at_center_of_line.svg'),
            self.tr('Single Point Templated Marker Via Two Points'))
        action_single_point_at_center_of_line.setCheckable(True)
        self.tools[
            TwoPointTemplatedMarkerTool.ID] = TwoPointTemplatedMarkerTool(
                self.iface.mapCanvas(), self.iface.cadDockWidget(), self.iface,
                action_single_point_at_center_of_line)
        self.tools[TwoPointTemplatedMarkerTool.ID].setAction(
            action_single_point_at_center_of_line)
        action_single_point_at_center_of_line.triggered.connect(
            partial(self.switch_tool, TwoPointTemplatedMarkerTool.ID))
        action_single_point_at_center_of_line.setData(
            TwoPointTemplatedMarkerTool.ID)
        self.toolbar.addAction(action_single_point_at_center_of_line)
        self.actions.append(action_single_point_at_center_of_line)

        self.get_map_tool_action_group().addAction(
            action_single_point_at_center_of_line)

        # multi point tool

        action_multi_point_templated_marker = QAction(
            GuiUtils.get_icon('multi_point_templated_marker.svg'),
            self.tr('Multiple Point Templated Marker Along LineString'))
        action_multi_point_templated_marker.setCheckable(True)
        self.tools[
            MultiPointTemplatedMarkerTool.ID] = MultiPointTemplatedMarkerTool(
                self.iface.mapCanvas(), self.iface.cadDockWidget(), self.iface,
                action_multi_point_templated_marker)
        self.tools[MultiPointTemplatedMarkerTool.ID].setAction(
            action_multi_point_templated_marker)
        action_multi_point_templated_marker.triggered.connect(
            partial(self.switch_tool, MultiPointTemplatedMarkerTool.ID))
        action_multi_point_templated_marker.setData(
            MultiPointTemplatedMarkerTool.ID)
        self.toolbar.addAction(action_multi_point_templated_marker)
        self.actions.append(action_multi_point_templated_marker)

        self.get_map_tool_action_group().addAction(
            action_single_point_templated_marker)

        # multi at center of segment point tool

        action_multi_point_center_segment_templated_marker = QAction(
            GuiUtils.get_icon('multi_point_templated_marker_at_center.svg'),
            self.tr('Multiple Point Templated Marker At Center Of Segments'))
        action_multi_point_center_segment_templated_marker.setCheckable(True)
        self.tools[MultiPointSegmentCenterTemplatedMarkerTool.
                   ID] = MultiPointSegmentCenterTemplatedMarkerTool(
                       self.iface.mapCanvas(), self.iface.cadDockWidget(),
                       self.iface,
                       action_multi_point_center_segment_templated_marker)
        self.tools[MultiPointSegmentCenterTemplatedMarkerTool.ID].setAction(
            action_multi_point_center_segment_templated_marker)
        action_multi_point_center_segment_templated_marker.triggered.connect(
            partial(self.switch_tool,
                    MultiPointSegmentCenterTemplatedMarkerTool.ID))
        action_multi_point_center_segment_templated_marker.setData(
            MultiPointSegmentCenterTemplatedMarkerTool.ID)
        self.toolbar.addAction(
            action_multi_point_center_segment_templated_marker)
        self.actions.append(action_multi_point_center_segment_templated_marker)

        self.get_map_tool_action_group().addAction(
            action_single_point_templated_marker)

        self.enable_actions_for_layer(self.iface.activeLayer())
class OpenlayersPlugin:
    def __init__(self, iface):
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # Keep a reference to all OL layers to avoid GC
        self._ol_layers = []
        # initialize locale
        locale = QSettings().value("locale/userLocale")[0:2]
        localePath = os.path.join(self.plugin_dir, "i18n",
                                  "openlayers_{}.qm".format(locale))

        if os.path.exists(localePath):
            self.translator = QTranslator()
            self.translator.load(localePath)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        self._olLayerTypeRegistry = WebLayerTypeRegistry(self)
        self.olOverview = OLOverview(iface, self._olLayerTypeRegistry)
        self.dlgAbout = AboutDialog()
        self.pluginLayerRegistry = QgsPluginLayerRegistry()

    def initGui(self):
        self._olMenu = QMenu("TMS for Korea")
        self._olMenu.setIcon(QIcon(":/plugins/openlayers/openlayers.png"))

        # Overview
        self.overviewAddAction = QAction(
            QApplication.translate("OpenlayersPlugin", "OpenLayers Overview"),
            self.iface.mainWindow())
        self.overviewAddAction.setCheckable(True)
        self.overviewAddAction.setChecked(False)
        self.overviewAddAction.toggled.connect(self.olOverview.setVisible)
        self._olMenu.addAction(self.overviewAddAction)

        self._actionAbout = QAction(
            QApplication.translate("dlgAbout", "About OpenLayers Plugin"),
            self.iface.mainWindow())
        self._actionAbout.triggered.connect(self.dlgAbout.show)
        self._olMenu.addAction(self._actionAbout)
        self.dlgAbout.finished.connect(self._publicationInfoClosed)

        # Daum
        self._olLayerTypeRegistry.register(OlDaumStreetLayer())
        self._olLayerTypeRegistry.register(OlDaumHybridLayer())
        self._olLayerTypeRegistry.register(OlDaumSatelliteLayer())
        self._olLayerTypeRegistry.register(OlDaumPhysicalLayer())
        self._olLayerTypeRegistry.register(OlDaumCadstralLayer())

        # Naver
        self._olLayerTypeRegistry.register(OlNaverStreetLayer())
        self._olLayerTypeRegistry.register(OlNaverHybridLayer())
        self._olLayerTypeRegistry.register(OlNaverSatelliteLayer())
        self._olLayerTypeRegistry.register(OlNaverPhysicalLayer())
        self._olLayerTypeRegistry.register(OlNaverCadastralLayer())

        # VWorld
        self._olLayerTypeRegistry.register(OlVWorldStreetLayer())
        self._olLayerTypeRegistry.register(OlVWorldSatelliteLayer())
        self._olLayerTypeRegistry.register(OlVWorldGrayLayer())
        self._olLayerTypeRegistry.register(OlVWorldHybridLayer())

        # NGII
        self._olLayerTypeRegistry.register(OlNgiiStreetLayer())
        self._olLayerTypeRegistry.register(OlNgiiBlankLayer())
        self._olLayerTypeRegistry.register(OlNgiiEnglishLayer())
        self._olLayerTypeRegistry.register(OlNgiiHighDensityLayer())
        self._olLayerTypeRegistry.register(OlNgiiColorBlindLayer())

        # Mango
        #self._olLayerTypeRegistry.register(OlMangoBaseMapLayer())
        #self._olLayerTypeRegistry.register(OlMangoBaseMapGrayLayer())
        #self._olLayerTypeRegistry.register(OlMangoHiDPIMapLayer())
        #self._olLayerTypeRegistry.register(OlMangoHiDPIMapGrayLayer())

        for group in self._olLayerTypeRegistry.groups():
            groupMenu = group.menu()
            for layer in self._olLayerTypeRegistry.groupLayerTypes(group):
                layer.addMenuEntry(groupMenu, self.iface.mainWindow())
            self._olMenu.addMenu(groupMenu)

        # Create Web menu, if it doesn't exist yet
        self.iface.addPluginToWebMenu("_tmp", self._actionAbout)
        self._menu = self.iface.webMenu()
        self._menu.addMenu(self._olMenu)
        self.iface.removePluginWebMenu("_tmp", self._actionAbout)

        # Register plugin layer type
        self.pluginLayerType = OpenlayersPluginLayerType(
            self.iface, self.setReferenceLayer, self._olLayerTypeRegistry)

        self.pluginLayerRegistry.addPluginLayerType(self.pluginLayerType)

        QgsProject.instance().readProject.connect(self.projectLoaded)
        QgsProject.instance().projectSaved.connect(self.projectSaved)

    def unload(self):
        self.iface.webMenu().removeAction(self._olMenu.menuAction())

        self.olOverview.setVisible(False)
        del self.olOverview

        # Unregister plugin layer type
        self.pluginLayerRegistry.removePluginLayerType(
            OpenlayersLayer.LAYER_TYPE)

        QgsProject.instance().readProject.disconnect(self.projectLoaded)
        QgsProject.instance().projectSaved.disconnect(self.projectSaved)

    def addLayer(self, layerType):
        if layerType.hasXYZUrl():
            # create XYZ layer
            layer, url = self.createXYZLayer(layerType, layerType.displayName)
        else:
            # create OpenlayersLayer
            layer = OpenlayersLayer(self.iface, self._olLayerTypeRegistry)
            layer.setName(layerType.displayName)
            layer.setLayerType(layerType)

        if layer.isValid():
            coordRefSys = layerType.coordRefSys(self.canvasCrs())
            self.setMapCrs(coordRefSys)
            QgsProject.instance().addMapLayer(layer)

            # store xyz config into qgis settings
            if layerType.hasXYZUrl():
                settings = QSettings()
                settings.beginGroup('qgis/connections-xyz')
                settings.setValue("%s/authcfg" % (layer.name()), '')
                settings.setValue("%s/password" % (layer.name()), '')
                settings.setValue("%s/referer" % (layer.name()), '')
                settings.setValue("%s/url" % (layer.name()), url)
                settings.setValue("%s/username" % (layer.name()), '')
                # specify max/min or else only a picture of the map is saved
                # in settings
                settings.setValue("%s/zmax" % (layer.name()), '18')
                settings.setValue("%s/zmin" % (layer.name()), '0')
                settings.endGroup()
                # reload connections to update Browser Panel content
                self.iface.reloadConnections()

            self._ol_layers += [layer]

            # last added layer is new reference
            self.setReferenceLayer(layer)

            if not layerType.hasXYZUrl():
                msg = "Printing and rotating of Javascript API " \
                      "based layers is currently not supported!"
                self.iface.messageBar().pushMessage("OpenLayers Plugin",
                                                    msg,
                                                    level=Qgis.MessageLevel(1),
                                                    duration=5)

    def setReferenceLayer(self, layer):
        self.layer = layer

    def removeLayer(self, layerId):
        if self.layer is not None:
            if self.layer.id() == layerId:
                self.layer = None
            # TODO: switch to next available OpenLayers layer?

    def canvasCrs(self):
        mapCanvas = self.iface.mapCanvas()
        crs = mapCanvas.mapSettings().destinationCrs()
        return crs

    def setMapCrs(self, targetCRS):
        mapCanvas = self.iface.mapCanvas()
        mapExtent = mapCanvas.extent()

        sourceCRS = self.canvasCrs()
        QgsProject.instance().setCrs(targetCRS)
        mapCanvas.freeze(False)
        try:
            coordTrans = QgsCoordinateTransform(sourceCRS, targetCRS,
                                                QgsProject.instance())
            mapExtent = coordTrans.transform(
                mapExtent, QgsCoordinateTransform.ForwardTransform)
            mapCanvas.setExtent(mapExtent)
        except:
            pass

    def projectLoaded(self):
        # replace old OpenlayersLayer with XYZ layer(OL plugin <= 1.3.6)
        rootGroup = self.iface.layerTreeView().layerTreeModel().rootGroup()
        for layer in QgsProject.instance().mapLayers().values():
            if layer.type(
            ) == QgsMapLayer.PluginLayer and layer.pluginLayerType(
            ) == OpenlayersLayer.LAYER_TYPE:
                if layer.layerType.hasXYZUrl():
                    # replace layer
                    xyzLayer, url = self.createXYZLayer(
                        layer.layerType, layer.name())
                    if xyzLayer.isValid():
                        self.replaceLayer(rootGroup, layer, xyzLayer)

    def _hasOlLayer(self):
        for layer in QgsProject.instance().mapLayers().values():
            if layer.customProperty('ol_layer_type'):
                return True
        return False

    def _publicationInfo(self):
        cloud_info_off = QSettings().value("Plugin-OpenLayers/cloud_info_off",
                                           defaultValue=False,
                                           type=bool)
        day = 3600 * 24
        now = time.time()
        lastInfo = QSettings().value("Plugin-OpenLayers/cloud_info_ts",
                                     defaultValue=0.0,
                                     type=float)
        if lastInfo == 0.0:
            lastInfo = now - 20 * day  # Show first time after 10 days
            QSettings().setValue("Plugin-OpenLayers/cloud_info_ts", lastInfo)
        days = (now - lastInfo) / day
        if days >= 30 and not cloud_info_off:
            self.dlgAbout.tabWidget.setCurrentWidget(
                self.dlgAbout.tab_publishing)
            self.dlgAbout.show()
            QSettings().setValue("Plugin-OpenLayers/cloud_info_ts", now)

    def _publicationInfoClosed(self):
        QSettings().setValue("Plugin-OpenLayers/cloud_info_off",
                             self.dlgAbout.cb_publishing.isChecked())

    def projectSaved(self):
        if self._hasOlLayer():
            self._publicationInfo()

    def createXYZLayer(self, layerType, name):
        # create XYZ layer with tms url as uri
        provider = 'wms'
        url = "type=xyz&url=" + layerType.xyzUrlConfig()
        layer = QgsRasterLayer(url, name, provider,
                               QgsRasterLayer.LayerOptions())
        layer.setCustomProperty('ol_layer_type', layerType.layerTypeName)
        return layer, layerType.xyzUrlConfig()

    def replaceLayer(self, group, oldLayer, newLayer):
        index = 0
        for child in group.children():
            if QgsLayerTree.isLayer(child):
                if child.layerId() == oldLayer.id():
                    # insert new layer
                    QgsProject.instance().addMapLayer(newLayer, False)
                    newLayerNode = group.insertLayer(index, newLayer)
                    newLayerNode.setVisible(child.isVisible())

                    # remove old layer
                    QgsProject.instance().removeMapLayer(oldLayer.id())

                    msg = "Updated layer '%s' from old \
                     OpenLayers Plugin version" % newLayer.name()
                    self.iface.messageBar().pushMessage(
                        "OpenLayers Plugin", msg, level=Qgis.MessageLevel(0))
                    QgsMessageLog.logMessage(msg, "OpenLayers Plugin",
                                             QgsMessageLog.INFO)

                    # layer replaced
                    return True
            else:
                if self.replaceLayer(child, oldLayer, newLayer):
                    # layer replaced in child group
                    return True

            index += 1

        # layer not in this group
        return False
Beispiel #10
0
class ProcessingPlugin(QObject):

    def __init__(self, iface):
        super().__init__()
        self.iface = iface
        self.options_factory = None
        self.drop_handler = None
        self.item_provider = None
        self.locator_filter = None
        self.edit_features_locator_filter = None
        self.initialized = False
        self.initProcessing()

    def initProcessing(self):
        if not self.initialized:
            self.initialized = True
            Processing.initialize()

    def initGui(self):
        # port old log, ONCE ONLY!
        settings = QgsSettings()
        if not settings.value("/Processing/hasPortedOldLog", False, bool):
            processing_history_provider = QgsGui.historyProviderRegistry().providerById('processing')
            if processing_history_provider:
                processing_history_provider.portOldLog()
                settings.setValue("/Processing/hasPortedOldLog", True)

        self.options_factory = ProcessingOptionsFactory()
        self.options_factory.setTitle(self.tr('Processing'))
        iface.registerOptionsWidgetFactory(self.options_factory)
        self.drop_handler = ProcessingDropHandler()
        iface.registerCustomDropHandler(self.drop_handler)
        self.item_provider = ProcessingDataItemProvider()
        QgsApplication.dataItemProviderRegistry().addProvider(self.item_provider)
        self.locator_filter = AlgorithmLocatorFilter()
        iface.registerLocatorFilter(self.locator_filter)
        # Invalidate the locator filter for in-place when active layer changes
        iface.currentLayerChanged.connect(lambda _: self.iface.invalidateLocatorResults())
        self.edit_features_locator_filter = InPlaceAlgorithmLocatorFilter()
        iface.registerLocatorFilter(self.edit_features_locator_filter)

        self.toolbox = ProcessingToolbox()
        self.iface.addDockWidget(Qt.RightDockWidgetArea, self.toolbox)
        self.toolbox.hide()
        self.toolbox.visibilityChanged.connect(self.toolboxVisibilityChanged)

        self.toolbox.executeWithGui.connect(self.executeAlgorithm)

        self.resultsDock = ResultsDock()
        self.iface.addDockWidget(Qt.RightDockWidgetArea, self.resultsDock)
        self.resultsDock.hide()

        self.menu = QMenu(self.iface.mainWindow().menuBar())
        self.menu.setObjectName('processing')
        self.menu.setTitle(self.tr('Pro&cessing'))

        self.toolboxAction = QAction(self.tr('&Toolbox'), self.iface.mainWindow())
        self.toolboxAction.setCheckable(True)
        self.toolboxAction.setObjectName('toolboxAction')
        self.toolboxAction.setIcon(
            QgsApplication.getThemeIcon("/processingAlgorithm.svg"))
        self.iface.registerMainWindowAction(self.toolboxAction,
                                            QKeySequence('Ctrl+Alt+T').toString(QKeySequence.NativeText))
        self.toolboxAction.toggled.connect(self.openToolbox)
        self.iface.attributesToolBar().insertAction(self.iface.actionOpenStatisticalSummary(), self.toolboxAction)
        self.menu.addAction(self.toolboxAction)

        self.modelerAction = QAction(
            QgsApplication.getThemeIcon("/processingModel.svg"),
            QCoreApplication.translate('ProcessingPlugin', '&Graphical Modeler…'), self.iface.mainWindow())
        self.modelerAction.setObjectName('modelerAction')
        self.modelerAction.triggered.connect(self.openModeler)
        self.iface.registerMainWindowAction(self.modelerAction,
                                            QKeySequence('Ctrl+Alt+G').toString(QKeySequence.NativeText))
        self.menu.addAction(self.modelerAction)

        self.historyAction = QAction(
            QgsApplication.getThemeIcon("/mIconHistory.svg"),
            QCoreApplication.translate('ProcessingPlugin', '&History…'), self.iface.mainWindow())
        self.historyAction.setObjectName('historyAction')
        self.historyAction.triggered.connect(self.openHistory)
        self.iface.registerMainWindowAction(self.historyAction,
                                            QKeySequence('Ctrl+Alt+H').toString(QKeySequence.NativeText))
        self.menu.addAction(self.historyAction)
        self.toolbox.processingToolbar.addAction(self.historyAction)

        self.resultsAction = QAction(
            QgsApplication.getThemeIcon("/processingResult.svg"),
            self.tr('&Results Viewer'), self.iface.mainWindow())
        self.resultsAction.setObjectName('resultsViewer')
        self.resultsAction.setCheckable(True)
        self.iface.registerMainWindowAction(self.resultsAction,
                                            QKeySequence('Ctrl+Alt+R').toString(QKeySequence.NativeText))

        self.menu.addAction(self.resultsAction)
        self.toolbox.processingToolbar.addAction(self.resultsAction)
        self.resultsDock.visibilityChanged.connect(self.resultsAction.setChecked)
        self.resultsAction.toggled.connect(self.resultsDock.setUserVisible)

        self.toolbox.processingToolbar.addSeparator()

        self.editInPlaceAction = QAction(
            QgsApplication.getThemeIcon("/mActionProcessSelected.svg"),
            self.tr('Edit Features In-Place'), self.iface.mainWindow())
        self.editInPlaceAction.setObjectName('editInPlaceFeatures')
        self.editInPlaceAction.setCheckable(True)
        self.editInPlaceAction.toggled.connect(self.editSelected)
        self.menu.addAction(self.editInPlaceAction)
        self.toolbox.processingToolbar.addAction(self.editInPlaceAction)

        self.toolbox.processingToolbar.addSeparator()

        self.optionsAction = QAction(
            QgsApplication.getThemeIcon("/mActionOptions.svg"),
            self.tr('Options'), self.iface.mainWindow())
        self.optionsAction.setObjectName('optionsAction')
        self.optionsAction.triggered.connect(self.openProcessingOptions)
        self.toolbox.processingToolbar.addAction(self.optionsAction)

        menuBar = self.iface.mainWindow().menuBar()
        menuBar.insertMenu(
            self.iface.firstRightStandardMenu().menuAction(), self.menu)

        self.menu.addSeparator()

        initializeMenus()
        createMenus()
        createButtons()

        # In-place editing button state sync
        self.iface.currentLayerChanged.connect(self.sync_in_place_button_state)
        self.iface.mapCanvas().selectionChanged.connect(self.sync_in_place_button_state)
        self.iface.actionToggleEditing().triggered.connect(partial(self.sync_in_place_button_state, None))
        self.sync_in_place_button_state()

        # Sync project models
        self.projectModelsMenu = None
        self.projectMenuAction = None
        self.projectMenuSeparator = None

        self.projectProvider = QgsApplication.instance().processingRegistry().providerById("project")
        self.projectProvider.algorithmsLoaded.connect(self.updateProjectModelMenu)

    def updateProjectModelMenu(self):
        """Add projects models to menu"""

        if self.projectMenuAction is None:
            self.projectModelsMenu = QMenu(self.tr("Models"))
            self.projectMenuAction = self.iface.projectMenu().insertMenu(self.iface.projectMenu().children()[-1], self.projectModelsMenu)
            self.projectMenuAction.setParent(self.projectModelsMenu)
            self.iface.projectMenu().insertSeparator(self.projectMenuAction)

        self.projectModelsMenu.clear()

        for model in self.projectProvider.algorithms():
            modelSubMenu = self.projectModelsMenu.addMenu(model.name())
            modelSubMenu.setParent(self.projectModelsMenu)
            action = QAction(self.tr("Execute…"), modelSubMenu)
            action.triggered.connect(partial(self.executeAlgorithm, model.id(), self.projectModelsMenu, self.toolbox.in_place_mode))
            modelSubMenu.addAction(action)
            if model.flags() & QgsProcessingAlgorithm.FlagSupportsBatch:
                action = QAction(self.tr("Execute as Batch Process…"), modelSubMenu)
                modelSubMenu.addAction(action)
                action.triggered.connect(partial(self.executeAlgorithm, model.id(), self.projectModelsMenu, self.toolbox.in_place_mode, True))

    @pyqtSlot(str, QWidget, bool, bool)
    def executeAlgorithm(self, alg_id, parent, in_place=False, as_batch=False):
        """Executes a project model with GUI interaction if needed.

        :param alg_id: algorithm id
        :type alg_id: string
        :param parent: parent widget
        :type parent: QWidget
        :param in_place: in place flag, defaults to False
        :type in_place: bool, optional
        :param as_batch: execute as batch flag, defaults to False
        :type as_batch: bool, optional
        """

        config = {}
        if in_place:
            config['IN_PLACE'] = True

        alg = QgsApplication.instance().processingRegistry().createAlgorithmById(alg_id, config)

        if alg is not None:

            ok, message = alg.canExecute()
            if not ok:
                dlg = MessageDialog()
                dlg.setTitle(self.tr('Error executing algorithm'))
                dlg.setMessage(
                    self.tr('<h3>This algorithm cannot '
                            'be run :-( </h3>\n{0}').format(message))
                dlg.exec_()
                return

            if as_batch:
                dlg = BatchAlgorithmDialog(alg, iface.mainWindow())
                dlg.show()
                dlg.exec_()
            else:
                in_place_input_parameter_name = 'INPUT'
                if hasattr(alg, 'inputParameterName'):
                    in_place_input_parameter_name = alg.inputParameterName()

                if in_place and not [d for d in alg.parameterDefinitions() if d.name() not in (in_place_input_parameter_name, 'OUTPUT')]:
                    parameters = {}
                    feedback = MessageBarProgress(algname=alg.displayName())
                    ok, results = execute_in_place(alg, parameters, feedback=feedback)
                    if ok:
                        iface.messageBar().pushSuccess('', self.tr('{algname} completed. %n feature(s) processed.', n=results['__count']).format(algname=alg.displayName()))
                    feedback.close()
                    # MessageBarProgress handles errors
                    return

                if alg.countVisibleParameters() > 0:
                    dlg = alg.createCustomParametersWidget(parent)

                    if not dlg:
                        dlg = AlgorithmDialog(alg, in_place, iface.mainWindow())
                    canvas = iface.mapCanvas()
                    prevMapTool = canvas.mapTool()
                    dlg.show()
                    dlg.exec_()
                    if canvas.mapTool() != prevMapTool:
                        try:
                            canvas.mapTool().reset()
                        except Exception:
                            pass
                        canvas.setMapTool(prevMapTool)
                else:
                    feedback = MessageBarProgress(algname=alg.displayName())
                    context = dataobjects.createContext(feedback)
                    parameters = {}
                    ret, results = execute(alg, parameters, context, feedback)
                    handleAlgorithmResults(alg, context, feedback)
                    feedback.close()

    def sync_in_place_button_state(self, layer=None):
        """Synchronise the button state with layer state"""

        if layer is None:
            layer = self.iface.activeLayer()

        old_enabled_state = self.editInPlaceAction.isEnabled()

        new_enabled_state = layer is not None and layer.type() == QgsMapLayerType.VectorLayer
        self.editInPlaceAction.setEnabled(new_enabled_state)

        if new_enabled_state != old_enabled_state:
            self.toolbox.set_in_place_edit_mode(new_enabled_state and self.editInPlaceAction.isChecked())

    def openProcessingOptions(self):
        self.iface.showOptionsDialog(self.iface.mainWindow(), currentPage='processingOptions')

    def unload(self):
        self.toolbox.setVisible(False)
        self.iface.removeDockWidget(self.toolbox)
        self.iface.attributesToolBar().removeAction(self.toolboxAction)

        self.resultsDock.setVisible(False)
        self.iface.removeDockWidget(self.resultsDock)

        self.toolbox.deleteLater()
        self.menu.deleteLater()

        # also delete temporary help files
        folder = tempHelpFolder()
        if QDir(folder).exists():
            shutil.rmtree(folder, True)

        self.iface.unregisterMainWindowAction(self.toolboxAction)
        self.iface.unregisterMainWindowAction(self.modelerAction)
        self.iface.unregisterMainWindowAction(self.historyAction)
        self.iface.unregisterMainWindowAction(self.resultsAction)

        self.iface.unregisterOptionsWidgetFactory(self.options_factory)
        self.iface.deregisterLocatorFilter(self.locator_filter)
        self.iface.deregisterLocatorFilter(self.edit_features_locator_filter)
        self.iface.unregisterCustomDropHandler(self.drop_handler)
        QgsApplication.dataItemProviderRegistry().removeProvider(self.item_provider)

        removeButtons()
        removeMenus()

        if self.projectMenuAction is not None:
            self.iface.projectMenu().removeAction(self.projectMenuAction)
            self.projectMenuAction = None
        if self.projectMenuSeparator is not None:
            self.iface.projectMenu().removeAction(self.projectMenuSeparator)
            self.projectMenuSeparator = None

        Processing.deinitialize()

    def openToolbox(self, show):
        self.toolbox.setUserVisible(show)

    def toolboxVisibilityChanged(self, visible):
        self.toolboxAction.setChecked(visible)

    def openModeler(self):
        dlg = ModelerDialog.create()
        dlg.update_model.connect(self.updateModel)
        dlg.show()

    def updateModel(self):
        model_provider = QgsApplication.processingRegistry().providerById('model')
        model_provider.refreshAlgorithms()

    def openResults(self):
        if self.resultsDock.isVisible():
            self.resultsDock.hide()
        else:
            self.resultsDock.show()

    def openHistory(self):
        dlg = HistoryDialog()
        dlg.exec_()

    def tr(self, message, disambiguation=None, n=-1):
        return QCoreApplication.translate('ProcessingPlugin', message, disambiguation=disambiguation, n=n)

    def editSelected(self, enabled):
        self.toolbox.set_in_place_edit_mode(enabled)
Beispiel #11
0
class GeToolsPlugin:
    def __init__(self, iface):
        self.iface = iface

        locale = QgsApplication.locale()
        qmPath = '{}/i18n/getools_{}.qm'.format(pluginPath, locale)

        if os.path.exists(qmPath):
            self.translator = QTranslator()
            self.translator.load(qmPath)
            QCoreApplication.installTranslator(self.translator)

    def initGui(self):
        self.actionPostionToGe = QAction(self.tr('Coords to the Google Earth'), self.iface.mainWindow())
        self.actionPostionToGe.setIcon(QIcon(os.path.join(pluginPath, 'icons', 'ge-click.svg')))
        self.actionPostionToGe.setObjectName('gePosition')
        self.actionPostionToGe.setCheckable(True)

        self.actionFeaturesToGe = QAction(self.tr('Feature(s) to the Google Earth'), self.iface.mainWindow())
        self.actionFeaturesToGe.setIcon(QIcon(os.path.join(pluginPath, 'icons', 'ge-selected.svg')))
        self.actionFeaturesToGe.setObjectName('geFeatures')
        self.actionFeaturesToGe.setCheckable(True)

        self.actionVectorToGe = QAction(self.tr('Vector layer to the Google Earth'), self.iface.mainWindow())
        self.actionVectorToGe.setIcon(QIcon(os.path.join(pluginPath, 'icons', 'ge-export-vector.svg')))
        self.actionVectorToGe.setObjectName('geVector')

        self.actionRasterToGe = QAction(self.tr('Raster layer to the Google Earth'), self.iface.mainWindow())
        self.actionRasterToGe.setIcon(QIcon(os.path.join(pluginPath, 'icons', 'ge-export-raster.svg')))
        self.actionRasterToGe.setObjectName('geRaster')

        self.actionSettings = QAction(self.tr('Settings…'), self.iface.mainWindow())
        self.actionSettings.setIcon(QgsApplication.getThemeIcon('/mActionOptions.svg'))
        self.actionSettings.setObjectName('geSettings')

        self.actionAbout = QAction(self.tr('About GETools…'), self.iface.mainWindow())
        self.actionAbout.setIcon(QgsApplication.getThemeIcon('/mActionHelpContents.svg'))
        self.actionAbout.setObjectName('geAbout')

        self.iface.addPluginToMenu(self.tr('GETools'), self.actionPostionToGe)
        self.iface.addPluginToMenu(self.tr('GETools'), self.actionFeaturesToGe)
        self.iface.addPluginToMenu(self.tr('GETools'), self.actionVectorToGe)
        self.iface.addPluginToMenu(self.tr('GETools'), self.actionRasterToGe)
        self.iface.addPluginToMenu(self.tr('GETools'), self.actionSettings)
        self.iface.addPluginToMenu(self.tr('GETools'), self.actionAbout)

        self.iface.addVectorToolBarIcon(self.actionPostionToGe)
        self.iface.addVectorToolBarIcon(self.actionFeaturesToGe)
        self.iface.addVectorToolBarIcon(self.actionVectorToGe)
        self.iface.addRasterToolBarIcon(self.actionRasterToGe)

        self.actionPostionToGe.triggered.connect(self.selectPosition)
        self.actionFeaturesToGe.triggered.connect(self.selectFeatures)
        self.actionVectorToGe.triggered.connect(self.exportLayer)
        self.actionRasterToGe.triggered.connect(self.exportLayer)
        self.actionSettings.triggered.connect(self.settings)
        self.actionAbout.triggered.connect(self.about)

        self.toolClick = MapToolClick(self.iface.mapCanvas())
        self.toolClick.setAction(self.actionPostionToGe)
        self.toolClick.canvasClicked.connect(self.exportPosition)

        self.toolSelect = MapToolSelect(self.iface.mapCanvas())
        self.toolSelect.setAction(self.actionFeaturesToGe)
        self.toolSelect.featuresSelected.connect(self.exportFeatures)

        self.iface.currentLayerChanged.connect(self.toggleButtons)

        self.taskManager = QgsApplication.taskManager()

    def unload(self):
        self.iface.removeVectorToolBarIcon(self.actionPostionToGe)
        self.iface.removeVectorToolBarIcon(self.actionFeaturesToGe)
        self.iface.removeVectorToolBarIcon(self.actionVectorToGe)
        self.iface.removeRasterToolBarIcon(self.actionRasterToGe)

        self.iface.removePluginMenu(self.tr('GETools'), self.actionPostionToGe)
        self.iface.removePluginMenu(self.tr('GETools'), self.actionFeaturesToGe)
        self.iface.removePluginMenu(self.tr('GETools'), self.actionVectorToGe)
        self.iface.removePluginMenu(self.tr('GETools'), self.actionRasterToGe)
        self.iface.removePluginMenu(self.tr('GETools'), self.actionSettings)
        self.iface.removePluginMenu(self.tr('GETools'), self.actionAbout)

        if self.iface.mapCanvas().mapTool() == self.toolClick:
            self.iface.mapCanvas().unsetMapTool(self.toolClick)
        if self.iface.mapCanvas().mapTool() == self.toolSelect:
            self.iface.mapCanvas().unsetMapTool(self.toolSelect)

        del self.toolClick
        del self.toolSelect

        utils.removeTempFiles()

    def settings(self):
        dlg = OptionsDialog(self.iface.mainWindow())
        dlg.exec_()

    def about(self):
        dlg = AboutDialog()
        dlg.exec_()

    def tr(self, text):
        return QCoreApplication.translate('GeTools', text)

    def selectPosition(self):
        self.iface.mapCanvas().setMapTool(self.toolClick)

    def selectFeatures(self):
        self.iface.mapCanvas().setMapTool(self.toolSelect)

    def toggleButtons(self, layer):
        if layer and layer.type() == QgsMapLayer.VectorLayer:
            self.actionFeaturesToGe.setEnabled(True)
            self.actionVectorToGe.setEnabled(True)
            self.actionRasterToGe.setEnabled(False)
        elif layer and layer.type() == QgsMapLayer.RasterLayer:
            self.actionFeaturesToGe.setEnabled(False)
            self.actionVectorToGe.setEnabled(False)
            self.actionRasterToGe.setEnabled(True)
        else:
            self.actionFeaturesToGe.setEnabled(False)
            self.actionVectorToGe.setEnabled(False)
            self.actionRasterToGe.setEnabled(False)

    def exportPosition(self, point, button):
        task = KmlWriterTask(point)
        task.exportComplete.connect(self.completed)
        task.errorOccurred.connect(self.errored)

        self.taskManager.addTask(task)

    def exportFeatures(self):
        task = KmlWriterTask(self.iface.activeLayer(), True)
        task.exportComplete.connect(self.completed)
        task.errorOccurred.connect(self.errored)

        self.taskManager.addTask(task)

    def exportLayer(self):
        task = KmlWriterTask(self.iface.activeLayer())
        task.exportComplete.connect(self.completed)
        task.errorOccurred.connect(self.errored)

        self.taskManager.addTask(task)

    def completed(self, fileName):
        uri = QUrl.fromLocalFile(fileName)
        self.iface.messageBar().pushSuccess(self.tr('GETools'), self.tr('Successfully exported to <a href="{}">{}</a>').format(uri.toString(), fileName))
        QDesktopServices.openUrl(uri)

    def errored(self, error):
        self.iface.messageBar().pushWarning(self.tr('GETools'), error)
class LatLonTools:
    digitizerDialog = None
    
    def __init__(self, iface):
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.crossRb = QgsRubberBand(self.canvas, QgsWkbTypes.LineGeometry)
        self.crossRb.setColor(Qt.red)
        self.provider = LatLonToolsProvider()
        self.toolbar = self.iface.addToolBar('Lat Lon Tools Toolbar')
        self.toolbar.setObjectName('LatLonToolsToolbar')

    def initGui(self):
        '''Initialize Lot Lon Tools GUI.'''
        # Initialize the Settings Dialog box
        self.settingsDialog = SettingsWidget(self, self.iface, self.iface.mainWindow())
        self.mapTool = CopyLatLonTool(self.settingsDialog, self.iface)
        self.showMapTool = ShowOnMapTool(self.iface)
        
        # Add Interface for Coordinate Capturing
        icon = QIcon(os.path.dirname(__file__) + "/images/copyicon.png")
        self.copyAction = QAction(icon, "Copy Latitude, Longitude", self.iface.mainWindow())
        self.copyAction.setObjectName('latLonToolsCopy')
        self.copyAction.triggered.connect(self.startCapture)
        self.copyAction.setCheckable(True)
        self.toolbar.addAction(self.copyAction)
        self.iface.addPluginToMenu("Lat Lon Tools", self.copyAction)
        
        # Add Interface for External Map
        icon = QIcon(os.path.dirname(__file__) + "/images/mapicon.png")
        self.externMapAction = QAction(icon, "Show in External Map", self.iface.mainWindow())
        self.externMapAction.setObjectName('latLonToolsExternalMap')
        self.externMapAction.triggered.connect(self.setShowMapTool)
        self.externMapAction.setCheckable(True)
        self.toolbar.addAction(self.externMapAction)
        self.iface.addPluginToMenu("Lat Lon Tools", self.externMapAction)

        # Add Interface for Zoom to Coordinate
        icon = QIcon(os.path.dirname(__file__) + "/images/zoomicon.png")
        self.zoomToAction = QAction(icon, "Zoom To Latitude, Longitude", self.iface.mainWindow())
        self.zoomToAction.setObjectName('latLonToolsZoom')
        self.zoomToAction.triggered.connect(self.showZoomToDialog)
        self.toolbar.addAction(self.zoomToAction)
        self.iface.addPluginToMenu('Lat Lon Tools', self.zoomToAction)

        self.zoomToDialog = ZoomToLatLon(self, self.iface, self.iface.mainWindow())
        self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.zoomToDialog)
        self.zoomToDialog.hide()
        
        # Add Interface for Multi point zoom
        icon = QIcon(os.path.dirname(__file__) + '/images/multizoom.png')
        self.multiZoomToAction = QAction(icon, "Multi-location Zoom", self.iface.mainWindow())
        self.multiZoomToAction.setObjectName('latLonToolsMultiZoom')
        self.multiZoomToAction.triggered.connect(self.multiZoomTo)
        self.toolbar.addAction(self.multiZoomToAction)
        self.iface.addPluginToMenu('Lat Lon Tools', self.multiZoomToAction)

        self.multiZoomDialog = MultiZoomWidget(self, self.settingsDialog, self.iface.mainWindow())
        self.multiZoomDialog.hide()
        self.multiZoomDialog.setFloating(True)
        
        # Create the conversions menu
        menu = QMenu()
        icon = QIcon(os.path.dirname(__file__) + '/images/field2geom.png')
        action = menu.addAction(icon, "Fields to point layer", self.field2geom)
        action.setObjectName('latLonToolsField2Geom')
        icon = QIcon(os.path.dirname(__file__) + '/images/geom2field.png')
        action = menu.addAction(icon, "Point layer to fields", self.geom2Field)
        action.setObjectName('latLonToolsGeom2Field')
        icon = QIcon(os.path.dirname(__file__) + '/images/pluscodes.png')
        action = menu.addAction(icon, "Plus Codes to point layer", self.PlusCodestoLayer)
        action.setObjectName('latLonToolsPlusCodes2Geom')
        action = menu.addAction(icon, "Point layer to Plus Codes", self.toPlusCodes)
        action.setObjectName('latLonToolsGeom2PlusCodes')
        icon = QIcon(os.path.dirname(__file__) + '/images/mgrs2point.png')
        action = menu.addAction(icon, "MGRS to point layer", self.MGRStoLayer)
        action.setObjectName('latLonToolsMGRS2Geom')
        icon = QIcon(os.path.dirname(__file__) + '/images/point2mgrs.png')
        action = menu.addAction(icon, "Point layer to MGRS", self.toMGRS)
        action.setObjectName('latLonToolsGeom2MGRS')
        self.conversionsAction = QAction(icon, "Conversions", self.iface.mainWindow())
        self.conversionsAction.setMenu(menu)
        self.iface.addPluginToMenu('Lat Lon Tools', self.conversionsAction)
        
        # Add to Digitize Toolbar
        icon = QIcon(os.path.dirname(__file__) + '/images/latLonDigitize.png')
        self.digitizeAction = QAction(icon, "Lat Lon Digitize", self.iface.mainWindow())
        self.digitizeAction.setObjectName('latLonToolsDigitize')
        self.digitizeAction.triggered.connect(self.digitizeClicked)
        self.digitizeAction.setEnabled(False)
        self.toolbar.addAction(self.digitizeAction)
        self.iface.addPluginToMenu('Lat Lon Tools', self.digitizeAction)
        
        # Add Interface for copying the canvas extent
        icon = QIcon(os.path.dirname(__file__) + "/images/copycanvas.png")
        self.copyCanvasAction = QAction(icon, "Copy Canvas Bounding Box", self.iface.mainWindow())
        self.copyCanvasAction.setObjectName('latLonToolsCopyCanvas')
        self.copyCanvasAction.triggered.connect(self.copyCanvas)
        self.toolbar.addAction(self.copyCanvasAction)
        self.iface.addPluginToMenu("Lat Lon Tools", self.copyCanvasAction)
        
        # Initialize the Settings Dialog Box
        settingsicon = QIcon(os.path.dirname(__file__) + '/images/settings.png')
        self.settingsAction = QAction(settingsicon, "Settings", self.iface.mainWindow())
        self.settingsAction.setObjectName('latLonToolsSettings')
        self.settingsAction.triggered.connect(self.settings)
        self.iface.addPluginToMenu('Lat Lon Tools', self.settingsAction)
        
        # Help
        icon = QIcon(os.path.dirname(__file__) + '/images/help.png')
        self.helpAction = QAction(icon, "Help", self.iface.mainWindow())
        self.helpAction.setObjectName('latLonToolsHelp')
        self.helpAction.triggered.connect(self.help)
        self.iface.addPluginToMenu('Lat Lon Tools', self.helpAction)
        
        
        self.iface.currentLayerChanged.connect(self.currentLayerChanged)
        self.canvas.mapToolSet.connect(self.unsetTool)
        self.enableDigitizeTool()
        # Add the processing provider
        
        QgsApplication.processingRegistry().addProvider(self.provider)
                
    def unsetTool(self, tool):
        '''Uncheck the Copy Lat Lon tool'''
        try:
            if not isinstance(tool, CopyLatLonTool):
                self.copyAction.setChecked(False)
                self.multiZoomDialog.stopCapture()
                self.mapTool.capture4326 = False
            if not isinstance(tool, ShowOnMapTool):
                self.externMapAction.setChecked(False)
        except:
            pass

    def unload(self):
        '''Unload LatLonTools from the QGIS interface'''
        self.zoomToDialog.removeMarker()
        self.multiZoomDialog.removeMarkers()
        self.canvas.unsetMapTool(self.mapTool)
        self.canvas.unsetMapTool(self.showMapTool)
        self.iface.removePluginMenu('Lat Lon Tools', self.copyAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.copyCanvasAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.externMapAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.zoomToAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.multiZoomToAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.conversionsAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.settingsAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.helpAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.digitizeAction)
        self.iface.removeDockWidget(self.zoomToDialog)
        self.iface.removeDockWidget(self.multiZoomDialog)
        # Remove Toolbar Icons
        self.iface.removeToolBarIcon(self.copyAction)
        self.iface.removeToolBarIcon(self.copyCanvasAction)
        self.iface.removeToolBarIcon(self.zoomToAction)
        self.iface.removeToolBarIcon(self.externMapAction)
        self.iface.removeToolBarIcon(self.multiZoomToAction)
        self.iface.removeToolBarIcon(self.digitizeAction)
        del self.toolbar
        
        self.zoomToDialog = None
        self.multiZoomDialog = None
        self.settingsDialog = None
        self.showMapTool = None
        self.mapTool = None
        self.digitizerDialog = None
        QgsApplication.processingRegistry().removeProvider(self.provider)

    def startCapture(self):
        '''Set the focus of the copy coordinate tool and check it'''
        self.copyAction.setChecked(True)
        self.canvas.setMapTool(self.mapTool)

    def copyCanvas(self):
        extent = self.iface.mapCanvas().extent()
        canvasCrs = self.canvas.mapSettings().destinationCrs()
        if settings.bBoxCrs == 0 and canvasCrs != epsg4326:
            transform = QgsCoordinateTransform(canvasCrs, epsg4326, QgsProject.instance())
            p1x, p1y = transform.transform(float(extent.xMinimum()), float(extent.yMinimum()))
            p2x, p2y = transform.transform(float(extent.xMaximum()), float(extent.yMaximum()))
            extent.set(p1x, p1y, p2x, p2y)
        delim = settings.bBoxDelimiter
        prefix = settings.bBoxPrefix
        suffix = settings.bBoxSuffix
        precision = settings.bBoxDigits
        outStr = ''
        minX = extent.xMinimum()
        minY = extent.yMinimum()
        maxX = extent.xMaximum()
        maxY = extent.yMaximum()
        if settings.bBoxFormat == 0: # minX,minY,maxX,maxY - using the delimiter
            outStr = '{:.{prec}f}{}{:.{prec}f}{}{:.{prec}f}{}{:.{prec}f}'.format(
                minX, delim, minY, delim, maxX, delim, maxY, prec=precision)
        elif settings.bBoxFormat == 1: # minX,maxX,minY,maxY - Using the selected delimiter'
            outStr = '{:.{prec}f}{}{:.{prec}f}{}{:.{prec}f}{}{:.{prec}f}'.format(
                minX, delim, maxX, delim, minY, delim, maxY, prec=precision)
        elif settings.bBoxFormat == 2: # x1 y1,x2 y2,x3 y3,x4 y4,x1 y1 - Polygon format
            outStr = '{:.{prec}f} {:.{prec}f},{:.{prec}f} {:.{prec}f},{:.{prec}f} {:.{prec}f},{:.{prec}f} {:.{prec}f},{:.{prec}f} {:.{prec}f}'.format(
                minX, minY, minX, maxY, maxX, maxY, maxX, minY, minX, minY, prec=precision)
        elif settings.bBoxFormat == 3: # x1,y1 x2,y2 x3,y3 x4,y4 x1,y1 - Polygon format
            outStr = '{:.{prec}f},{:.{prec}f} {:.{prec}f},{:.{prec}f} {:.{prec}f},{:.{prec}f} {:.{prec}f},{:.{prec}f} {:.{prec}f},{:.{prec}f}'.format(
                minX, minY, minX, maxY, maxX, maxY, maxX, minY, minX, minY, prec=precision)
        elif settings.bBoxFormat == 4: # WKT Polygon
            outStr = extent.asWktPolygon()
        elif settings.bBoxFormat == 5: # bbox: [minX, minY, maxX, maxY] - MapProxy
            outStr = 'bbox: [{}, {}, {}, {}]'.format(
                minX, minY, maxX, maxY)
        elif settings.bBoxFormat == 6: # bbox: [minX, minY, maxX, maxY] - MapProxy
            outStr = 'bbox={},{},{},{}'.format(
                minX, minY, maxX, maxY)
        outStr = '{}{}{}'.format(prefix, outStr, suffix)
        clipboard = QApplication.clipboard()
        clipboard.setText(outStr)
        self.iface.messageBar().pushMessage("", "'{}' copied to the clipboard".format(outStr), level=Qgis.Info, duration=4)
        
    def setShowMapTool(self):
        '''Set the focus of the external map tool and check it'''
        self.externMapAction.setChecked(True)
        self.canvas.setMapTool(self.showMapTool)

    def showZoomToDialog(self):
        '''Show the zoom to docked widget.'''
        self.zoomToDialog.show()

    def multiZoomTo(self):
        '''Display the Multi-zoom to dialog box'''
        self.multiZoomDialog.show()

    def field2geom(self):
        '''Convert layer containing a point x & y coordinate to a new point layer'''
        results = processing.execAlgorithmDialog('latlontools:field2geom', {})

    def geom2Field(self):
        '''Convert layer geometry to a text string'''
        results = processing.execAlgorithmDialog('latlontools:geom2field', {})

    def toMGRS(self):
        '''Display the to MGRS  dialog box'''
        results = processing.execAlgorithmDialog('latlontools:point2mgrs', {})

    def MGRStoLayer(self):
        '''Display the to MGRS  dialog box'''
        results = processing.execAlgorithmDialog('latlontools:mgrs2point', {})

    def toPlusCodes(self):
        results = processing.execAlgorithmDialog('latlontools:point2pluscodes', {})

    def PlusCodestoLayer(self):
        results = processing.execAlgorithmDialog('latlontools:pluscodes2point', {})
    
    def settings(self):
        '''Show the settings dialog box'''
        self.settingsDialog.show()
        
    def help(self):
        '''Display a help page'''
        url = QUrl.fromLocalFile(os.path.dirname(__file__) + "/index.html").toString()
        webbrowser.open(url, new=2)
        
    def settingsChanged(self):
        # Settings may have changed so we need to make sure the zoomToDialog window is configured properly
        self.zoomToDialog.configure()
        self.multiZoomDialog.settingsChanged()
            
 
    def zoomTo(self, srcCrs, lat, lon):
        canvasCrs = self.canvas.mapSettings().destinationCrs()
        transform = QgsCoordinateTransform(srcCrs, canvasCrs, QgsProject.instance())
        x, y = transform.transform(float(lon), float(lat))
            
        rect = QgsRectangle(x, y, x, y)
        self.canvas.setExtent(rect)

        pt = QgsPointXY(x, y)
        self.highlight(pt)
        self.canvas.refresh()
        return pt
        
    def highlight(self, point):
        currExt = self.canvas.extent()
        
        leftPt = QgsPoint(currExt.xMinimum(), point.y())
        rightPt = QgsPoint(currExt.xMaximum(), point.y())
        
        topPt = QgsPoint(point.x(), currExt.yMaximum())
        bottomPt = QgsPoint(point.x(), currExt.yMinimum())
        
        horizLine = QgsGeometry.fromPolyline( [ leftPt , rightPt ] )
        vertLine = QgsGeometry.fromPolyline( [ topPt , bottomPt ] )
        
        self.crossRb.reset(QgsWkbTypes.LineGeometry)
        self.crossRb.addGeometry(horizLine, None)
        self.crossRb.addGeometry(vertLine, None)
        
        QTimer.singleShot(700, self.resetRubberbands)
        
    def resetRubberbands(self):
        self.crossRb.reset()
        
    def digitizeClicked(self):
        if self.digitizerDialog == None:
            from .digitizer import DigitizerWidget
            self.digitizerDialog = DigitizerWidget(self, self.iface, self.iface.mainWindow())
        self.digitizerDialog.show()
        
    def currentLayerChanged(self):
        layer = self.iface.activeLayer()
        if layer != None:
            try:
                layer.editingStarted.disconnect(self.layerEditingChanged)
            except:
                pass
            try:
                layer.editingStopped.disconnect(self.layerEditingChanged)
            except:
                pass
            
            if isinstance(layer, QgsVectorLayer):
                layer.editingStarted.connect(self.layerEditingChanged)
                layer.editingStopped.connect(self.layerEditingChanged)
                
        self.enableDigitizeTool()

    def layerEditingChanged(self):
        self.enableDigitizeTool()

    def enableDigitizeTool(self):
        self.digitizeAction.setEnabled(False)
        layer = self.iface.activeLayer()
        
        if layer != None and isinstance(layer, QgsVectorLayer) and (layer.geometryType() == QgsWkbTypes.PointGeometry) and layer.isEditable():
            self.digitizeAction.setEnabled(True)
        else:
            if self.digitizerDialog != None:
                self.digitizerDialog.close()
Beispiel #13
0
    def __init__(self, iface):
        QMainWindow.__init__(self)
        self.resize(600, 600)
        self.layer = None
        self.iface = iface
        self.dstpoints = []
        self.srcpoints = []
        self.filename = None
        self.cursrc = None
        self.curdst = None
        self.xform_m2r = None
        self.xform_r2m = None

        self.canvas = QgsMapCanvas(self)
        #self.canvas.setCachingEnabled(True)
        self.canvas.setCanvasColor(Qt.white)
        self.canvas.setWheelAction(QgsMapCanvas.WheelZoomToMouseCursor)

        self.setCentralWidget(self.canvas)

        def t(name):
            return QgsApplication.getThemeIcon('/' + name)
        actionZoomIn = QAction(t('mActionZoomIn.svg'), "Zoom in", self)
        actionZoomOut = QAction(t('mActionZoomOut.svg'), "Zoom out", self)
        actionZoomToLayer = QAction(t('mActionZoomToLayer.svg'), "Zoom To Layer", self)
        actionZoomToDest = QAction("Zoom To Map", self)
        actionPan = QAction(t('mActionPan.svg'), "Pan", self)
        actionOpen = QAction(t('mActionFileOpen.svg'), "Open", self)
        actionSave = QAction(t('mActionFileSaveAs.svg'), "Save", self)
        actionAdd = QAction("Add GCP", self)
        actionDeleteAll = QAction("Delete All GCPs", self)

        actionZoomIn.setCheckable(True)
        actionZoomOut.setCheckable(True)
        actionPan.setCheckable(True)
        actionAdd.setCheckable(True)

        actionZoomIn.triggered.connect(self.zoomIn)
        actionZoomOut.triggered.connect(self.zoomOut)
        actionZoomToLayer.triggered.connect(self.zoomToLayer)
        actionZoomToDest.triggered.connect(self.zoomToDest)
        actionPan.triggered.connect(self.pan)
        actionOpen.triggered.connect(self.showOpen)
        actionSave.triggered.connect(self.savePoints)
        actionAdd.triggered.connect(self.addGcp)
        actionDeleteAll.triggered.connect(self.deleteAll)

        self.toolbar = self.addToolBar("Canvas actions")
        self.toolbar.addAction(actionOpen)
        self.toolbar.addAction(actionSave)
        self.toolbar.addSeparator()
        self.toolbar.addAction(actionPan)
        self.toolbar.addAction(actionZoomIn)
        self.toolbar.addAction(actionZoomOut)
        self.toolbar.addAction(actionZoomToLayer)
        self.toolbar.addAction(actionZoomToDest)
        self.toolbar.addSeparator()
        self.toolbar.addAction(actionAdd)
        self.toolbar.addSeparator()
        self.toolbar.addAction(actionDeleteAll)

        self.toolPan = QgsMapToolPan(self.canvas)
        self.toolPan.setAction(actionPan)
        self.toolZoomIn = QgsMapToolZoom(self.canvas, False)
        self.toolZoomIn.setAction(actionZoomIn)
        self.toolZoomOut = QgsMapToolZoom(self.canvas, True)
        self.toolZoomOut.setAction(actionZoomOut)
        self.toolSrcAdd = CaptureTool(self.canvas, self.iface.cadDockWidget())
        self.toolSrcAdd.pointSelected.connect(self.addSrcPoint)
        self.toolSrcAdd.pointDeleted.connect(self.delSrcPoint)
        self.toolDestAdd = CaptureTool(self.iface.mapCanvas(), self.iface.cadDockWidget())
        self.toolDestAdd.pointSelected.connect(self.addDestPoint)
        self.toolDestAdd.pointDeleted.connect(self.delDestPoint)
        #self.toolDestAdd.setAction(actionAdd)

        self.pan()

        self.overview = QgsMapOverviewCanvas(None, self.canvas)
        self.overview_dock = QDockWidget("Overview")
        self.overview_dock.setWidget(self.overview)
        self.addDockWidget(Qt.BottomDockWidgetArea, self.overview_dock)
        self.canvas.enableOverviewMode(self.overview)

        statusbar = self.statusBar()
        self.coordslabel = QLabel(statusbar)
        self.canvas.xyCoordinates.connect(self.showMouseCoordinates)
        statusbar.addPermanentWidget(self.coordslabel)
class MGRSCapture:
    def __init__(self, iface):
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.toolbar = self.iface.addToolBar('MGRS Toolbar')
        self.toolbar.setObjectName('MGRSToolbar')

    def initGui(self):
        '''Initialize Lot Lon Tools GUI.'''
        # Initialize the Settings Dialog box
        self.settingsDialog = SettingsWidget(self.iface)
        self.mapTool = CopyMgrsTool(self.iface)

        # Add Interface for Coordinate Capturing
        icon = QIcon(os.path.dirname(__file__) + "/images/copyMgrs.svg")
        self.copyAction = QAction(icon, "Copy/Display MGRS Coordinate",
                                  self.iface.mainWindow())
        self.copyAction.setObjectName('mgrsCopy')
        self.copyAction.triggered.connect(self.startCapture)
        self.copyAction.setCheckable(True)
        self.toolbar.addAction(self.copyAction)
        self.iface.addPluginToMenu("MGRS", self.copyAction)

        # Add Interface for Zoom to Coordinate
        icon = QIcon(os.path.dirname(__file__) + "/images/zoomToMgrs.svg")
        self.zoomToAction = QAction(icon, "Zoom To MGRS Coordinate",
                                    self.iface.mainWindow())
        self.zoomToAction.setObjectName('mgrsZoom')
        self.zoomToAction.triggered.connect(self.showZoomToDialog)
        self.toolbar.addAction(self.zoomToAction)
        self.iface.addPluginToMenu('MGRS', self.zoomToAction)

        self.zoomToDialog = ZoomToMgrs(self.iface, self.iface.mainWindow())
        self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.zoomToDialog)
        self.zoomToDialog.hide()

        # Initialize the Settings Dialog Box
        settingsicon = QIcon(':/images/themes/default/mActionOptions.svg')
        self.settingsAction = QAction(settingsicon, "Settings",
                                      self.iface.mainWindow())
        self.settingsAction.setObjectName('mgrsSettings')
        self.settingsAction.triggered.connect(self.settings)
        self.iface.addPluginToMenu('MGRS', self.settingsAction)

        # Help
        icon = QIcon(os.path.dirname(__file__) + '/images/help.svg')
        self.helpAction = QAction(icon, "Help", self.iface.mainWindow())
        self.helpAction.setObjectName('mgrsHelp')
        self.helpAction.triggered.connect(self.help)
        self.iface.addPluginToMenu('MGRS', self.helpAction)

        self.canvas.mapToolSet.connect(self.resetTools)

    def resetTools(self, newtool, oldtool):
        '''Uncheck the Copy MGRS tool'''
        try:
            if oldtool is self.mapTool:
                self.copyAction.setChecked(False)
            if newtool is self.mapTool:
                self.copyAction.setChecked(True)
        except Exception:
            pass

    def unload(self):
        '''Unload LatLonTools from the QGIS interface'''
        self.zoomToDialog.removeMarker()
        self.canvas.unsetMapTool(self.mapTool)
        self.iface.removePluginMenu('MGRS', self.copyAction)
        self.iface.removePluginMenu('MGRS', self.zoomToAction)
        self.iface.removePluginMenu('MGRS', self.settingsAction)
        self.iface.removePluginMenu('MGRS', self.helpAction)
        self.iface.removeDockWidget(self.zoomToDialog)
        # Remove Toolbar Icons
        self.iface.removeToolBarIcon(self.copyAction)
        self.iface.removeToolBarIcon(self.zoomToAction)
        del self.toolbar

        self.zoomToDialog = None
        self.settingsDialog = None
        self.mapTool = None

    def startCapture(self):
        '''Set the focus of the copy coordinate tool'''
        self.canvas.setMapTool(self.mapTool)

    def showZoomToDialog(self):
        '''Show the zoom to docked widget.'''
        self.zoomToDialog.show()

    def settings(self):
        '''Show the settings dialog box'''
        self.settingsDialog.show()

    def help(self):
        '''Display a help page'''
        url = QUrl.fromLocalFile(os.path.dirname(__file__) +
                                 "/index.html").toString()
        webbrowser.open(url, new=2)
    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,
        checkable=True):
        """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)

        action.setCheckable(checkable)

        if add_to_toolbar:
            self.toolbar.addAction(action)

        if add_to_menu:
            self.iface.addPluginToMenu(
                self.menu,
                action)

        self.actions.append(action)

        return action
class GeoGigPlugin(object):

    def __init__(self, iface):
        self.iface = iface
        config.iface = iface
        readSettings()
        config.initConfigParams()

        layers = list(QgsMapLayerRegistry.instance().mapLayers().values())
        for layer in layers:
            trackLayer(layer)
        try:
            from qgistester.tests import addTestModule
            from geogig.tests import testplugin
            addTestModule(testplugin, "GeoGig Light")
        except Exception as e:
            pass

        QSettings().setValue("/qgis/walForSqlite3", False)

    def unload(self):
        navigatorInstance.setVisible(False)
        try:
            QgsMapLayerRegistry.instance().layerWasAdded.disconnect(trackLayer)
            QgsMapLayerRegistry.instance().layerRemoved.disconnect(layerRemoved)
        except:
            pass

        self.menu.deleteLater()
        self.toolButton.deleteLater()

        self.iface.removePluginMenu("&GeoGig", self.explorerAction)
        self.iface.removePluginMenu("&GeoGig", self.toolAction)

        layers = list(QgsMapLayerRegistry.instance().mapLayers().values())
        for layer in layers:
            removeLayerActions(layer)
        removeNonexistentTrackedLayers()
        removeTempFolder()

        try:
            from qgistester.tests import removeTestModule
            from geogig.tests import testplugin
            removeTestModule(testplugin, "GeoGig Light")
        except Exception as e:
            pass

        try:
            from lessons import removeLessonsFolder
            removeLessonsFolder(folder, "geogig")
        except:
            pass

        removeHelpMenu("GeoGig")
        removeAboutMenu("GeoGig")
        removeSettingsMenu("GeoGig")

    def initGui(self):
        readTrackedLayers()

        QgsMapLayerRegistry.instance().layerWasAdded.connect(trackLayer)
        QgsMapLayerRegistry.instance().layerRemoved.connect(layerRemoved)

        icon = QIcon(os.path.dirname(__file__) + "/ui/resources/geogig.png")
        self.explorerAction = navigatorInstance.toggleViewAction()
        self.explorerAction.setIcon(icon)
        self.explorerAction.setText("GeoGig Navigator")
        icon = QIcon(os.path.dirname(__file__) + "/ui/resources/identify.png")
        self.toolAction = QAction(icon, "GeoGig Feature Info Tool", self.iface.mainWindow())
        self.toolAction.setCheckable(True)
        self.toolAction.triggered.connect(self.setTool)

        self.menu = QMenu(self.iface.mainWindow())
        self.menu.setTitle("GeoGig")
        self.menu.addAction(self.explorerAction)
        self.menu.addAction(self.toolAction)
        bar = self.iface.layerToolBar()
        self.toolButton = QToolButton()
        self.toolButton.setMenu(self.menu)
        self.toolButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.toolButton.setDefaultAction(self.explorerAction)
        bar.addWidget(self.toolButton)
        self.iface.addPluginToMenu("&GeoGig", self.explorerAction)
        self.iface.addPluginToMenu("&GeoGig", self.toolAction)

        addSettingsMenu("GeoGig")
        addHelpMenu("GeoGig")
        addAboutMenu("GeoGig")

        self.mapTool = MapToolGeoGigInfo(self.iface.mapCanvas())

        #This crashes QGIS, so we comment it out until finding a solution
        #self.mapTool.setAction(self.toolAction)

        self.iface.addDockWidget(Qt.RightDockWidgetArea, navigatorInstance)

        try:
            from lessons import addLessonsFolder, addGroup
            folder = os.path.join(os.path.dirname(__file__), "_lessons")
            addLessonsFolder(folder, "geogig")
            group_description = os.path.join(folder, "group.md")
            addGroup("GeoGig lessons", group_description)
        except Exception as e:
            pass

    def setWarning(self, msg):
        QMessageBox.warning(None, 'Could not complete GeoGig command',
                                  msg,
                                  QMessageBox.Ok)

    def setTool(self):
        self.toolAction.setChecked(True)
        self.iface.mapCanvas().setMapTool(self.mapTool)
class OpenlayersPlugin:

    def __init__(self, iface):
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # Keep a reference to all OL layers to avoid GC
        self._ol_layers = []
        # initialize locale
        locale = QSettings().value("locale/userLocale")[0:2]
        localePath = os.path.join(self.plugin_dir, "i18n",
                                  "openlayers_{}.qm".format(locale))

        if os.path.exists(localePath):
            self.translator = QTranslator()
            self.translator.load(localePath)

        self._olLayerTypeRegistry = WebLayerTypeRegistry(self)
        self.olOverview = OLOverview(iface, self._olLayerTypeRegistry)
        self.dlgAbout = AboutDialog()
        self.pluginLayerRegistry = QgsPluginLayerRegistry()

    def initGui(self):
        self._olMenu = QMenu("OpenLayers plugin")
        self._olMenu.setIcon(QIcon(":/plugins/openlayers/openlayers.png"))

        # Overview
        self.overviewAddAction = QAction(QApplication.translate(
            "OpenlayersPlugin", "OpenLayers Overview"),
                                         self.iface.mainWindow())
        self.overviewAddAction.setCheckable(True)
        self.overviewAddAction.setChecked(False)
        self.overviewAddAction.toggled.connect(self.olOverview.setVisible)
        self._olMenu.addAction(self.overviewAddAction)

        self._actionAbout = QAction("Terms of Service / About",
                                    self.iface.mainWindow())
        self._actionAbout.triggered.connect(self.dlgAbout.show)
        self._olMenu.addAction(self._actionAbout)
        self.dlgAbout.finished.connect(self._publicationInfoClosed)

        self._olLayerTypeRegistry.register(OlGooglePhysicalLayer())
        self._olLayerTypeRegistry.register(OlGoogleStreetsLayer())
        self._olLayerTypeRegistry.register(OlGoogleHybridLayer())
        self._olLayerTypeRegistry.register(OlGoogleSatelliteLayer())

        self._olLayerTypeRegistry.register(OlOpenStreetMapLayer())
        self._olLayerTypeRegistry.register(OlOpenCycleMapLayer())
        self._olLayerTypeRegistry.register(OlOCMLandscapeLayer())
        self._olLayerTypeRegistry.register(OlOCMPublicTransportLayer())

        # ID 8-10 was Yahoo
        self._olLayerTypeRegistry.register(OlOSMHumanitarianDataModelLayer())

        self._olLayerTypeRegistry.register(OlOCMOutdoorstLayer())
        self._olLayerTypeRegistry.register(OlOCMTransportDarkLayer())

        self._olLayerTypeRegistry.register(OlBingRoadLayer())
        self._olLayerTypeRegistry.register(OlBingAerialLayer())
        self._olLayerTypeRegistry.register(OlBingAerialLabelledLayer())

        # Order from here on is free. Layers 0-14 should keep order for
        # compatibility with OL Plugin < 2.3

        self._olLayerTypeRegistry.register(OlOCMSpinalMapLayer())
        self._olLayerTypeRegistry.register(OlOCMPioneerLayer())
        self._olLayerTypeRegistry.register(OlOCMMobileAtlasLayer())
        self._olLayerTypeRegistry.register(OlOCMNeighbourhoodLayer())

        self._olLayerTypeRegistry.register(OlOSMStamenTonerLayer())
        self._olLayerTypeRegistry.register(OlOSMStamenTonerLiteLayer())
        self._olLayerTypeRegistry.register(OlOSMStamenWatercolorLayer())
        self._olLayerTypeRegistry.register(OlOSMStamenTerrainLayer())

        self._olLayerTypeRegistry.register(OlAppleiPhotoMapLayer())

        self._olLayerTypeRegistry.register(WikimediaLabelledLayer())
        self._olLayerTypeRegistry.register(WikimediaUnLabelledLayer())

        for group in self._olLayerTypeRegistry.groups():
            groupMenu = group.menu()
            for layer in self._olLayerTypeRegistry.groupLayerTypes(group):
                layer.addMenuEntry(groupMenu, self.iface.mainWindow())
            self._olMenu.addMenu(groupMenu)

        # add action for API key dialogs
        for action in self._olMenu.actions():
            if action.text() == "Google Maps":
                self._actionGoogleMapsApiKey = QAction(
                    "Set API key", self.iface.mainWindow())
                self._actionGoogleMapsApiKey.triggered.connect(
                    self.showGoogleMapsApiKeyDialog)
                action.menu().addAction(self._actionGoogleMapsApiKey)
            if action.text() == "OSM/Thunderforest":
                self._actionThunderforestApiKey = QAction(
                    "Set API key", self.iface.mainWindow())
                self._actionThunderforestApiKey.triggered.connect(
                    self.showThunderforestApiKeyDialog)
                action.menu().addAction(self._actionThunderforestApiKey)

        # Create Web menu, if it doesn't exist yet
        self.iface.addPluginToWebMenu("_tmp", self._actionAbout)
        self._menu = self.iface.webMenu()
        self._menu.addMenu(self._olMenu)
        self.iface.removePluginWebMenu("_tmp", self._actionAbout)

        # Register plugin layer type
        self.pluginLayerType = OpenlayersPluginLayerType(
            self.iface, self.setReferenceLayer, self._olLayerTypeRegistry)

        self.pluginLayerRegistry.addPluginLayerType(
            self.pluginLayerType)

        QgsProject.instance().readProject.connect(self.projectLoaded)
        QgsProject.instance().projectSaved.connect(self.projectSaved)

    def unload(self):
        self.iface.webMenu().removeAction(self._olMenu.menuAction())

        self.olOverview.setVisible(False)
        del self.olOverview

        # Unregister plugin layer type
        self.pluginLayerRegistry.removePluginLayerType(
            OpenlayersLayer.LAYER_TYPE)

        QgsProject.instance().readProject.disconnect(self.projectLoaded)
        QgsProject.instance().projectSaved.disconnect(self.projectSaved)

    def addLayer(self, layerType):
        if layerType.hasXYZUrl():
            # create XYZ layer
            layer, url = self.createXYZLayer(layerType,
                                             layerType.displayName)
        else:
            # create OpenlayersLayer
            layer = OpenlayersLayer(self.iface, self._olLayerTypeRegistry)
            layer.setName(layerType.displayName)
            layer.setLayerType(layerType)

        if layer.isValid():
            coordRefSys = layerType.coordRefSys(self.canvasCrs())
            self.setMapCrs(coordRefSys)
            QgsProject.instance().addMapLayer(layer)

            # store xyz config into qgis settings
            if layerType.hasXYZUrl():
                settings = QSettings()
                settings.beginGroup('qgis/connections-xyz')
                settings.setValue("%s/authcfg" % (layer.name()), '')
                settings.setValue("%s/password" % (layer.name()), '')
                settings.setValue("%s/referer" % (layer.name()), '')
                settings.setValue("%s/url" % (layer.name()), url)
                settings.setValue("%s/username" % (layer.name()), '')
                # specify max/min or else only a picture of the map is saved
                # in settings
                settings.setValue("%s/zmax" % (layer.name()), '18')
                settings.setValue("%s/zmin" % (layer.name()), '0')
                settings.endGroup()
                # reload connections to update Browser Panel content
                self.iface.reloadConnections()

            self._ol_layers += [layer]

            # last added layer is new reference
            self.setReferenceLayer(layer)

            if not layerType.hasXYZUrl():
                msg = "Printing and rotating of Javascript API " \
                      "based layers is currently not supported!"
                self.iface.messageBar().pushMessage(
                    "OpenLayers Plugin", msg, level=Qgis.MessageLevel(1),
                    duration=5)

    def setReferenceLayer(self, layer):
        self.layer = layer

    def removeLayer(self, layerId):
        if self.layer is not None:
            if self.layer.id() == layerId:
                self.layer = None
            # TODO: switch to next available OpenLayers layer?

    def canvasCrs(self):
        mapCanvas = self.iface.mapCanvas()
        crs = mapCanvas.mapSettings().destinationCrs()
        return crs

    def setMapCrs(self, coordRefSys):
        mapCanvas = self.iface.mapCanvas()
        # On the fly
        canvasCrs = self.canvasCrs()
        if canvasCrs != coordRefSys:
            coordTrans = QgsCoordinateTransform(canvasCrs, coordRefSys,
                                                QgsProject.instance())
            extMap = mapCanvas.extent()
            extMap = coordTrans.transform(
                extMap, QgsCoordinateTransform.ForwardTransform)
            mapCanvas.setDestinationCrs(coordRefSys)
            mapCanvas.freeze(False)
            mapCanvas.setExtent(extMap)

    def projectLoaded(self):
        # replace old OpenlayersLayer with XYZ layer(OL plugin <= 1.3.6)
        rootGroup = self.iface.layerTreeView().layerTreeModel().rootGroup()
        for layer in QgsProject.instance().mapLayers().values():
            if layer.type() == QgsMapLayer.PluginLayer and layer.pluginLayerType() == OpenlayersLayer.LAYER_TYPE:
                if layer.layerType.hasXYZUrl():
                    # replace layer
                    xyzLayer, url = self.createXYZLayer(layer.layerType,
                                                        layer.name())
                    if xyzLayer.isValid():
                        self.replaceLayer(rootGroup, layer, xyzLayer)

    def _hasOlLayer(self):
        for layer in QgsProject.instance().mapLayers().values():
            if layer.customProperty('ol_layer_type'):
                return True
        return False

    def _publicationInfo(self):
        cloud_info_off = QSettings().value("Plugin-OpenLayers/cloud_info_off",
                                           defaultValue=False, type=bool)
        day = 3600*24
        now = time.time()
        lastInfo = QSettings().value("Plugin-OpenLayers/cloud_info_ts",
                                     defaultValue=0.0, type=float)
        if lastInfo == 0.0:
            lastInfo = now-20*day  # Show first time after 10 days
            QSettings().setValue("Plugin-OpenLayers/cloud_info_ts", lastInfo)
        days = (now-lastInfo)/day
        if days >= 30 and not cloud_info_off:
            self.dlgAbout.tabWidget.setCurrentWidget(
                self.dlgAbout.tab_publishing)
            self.dlgAbout.show()
            QSettings().setValue("Plugin-OpenLayers/cloud_info_ts", now)

    def _publicationInfoClosed(self):
        QSettings().setValue("Plugin-OpenLayers/cloud_info_off",
                             self.dlgAbout.cb_publishing.isChecked())

    def projectSaved(self):
        if self._hasOlLayer():
            self._publicationInfo()

    def createXYZLayer(self, layerType, name):
        # create XYZ layer with tms url as uri
        provider = 'wms'
        url = "type=xyz&url=" + layerType.xyzUrlConfig()
        layer = QgsRasterLayer(url, name, provider,
                               QgsRasterLayer.LayerOptions())
        layer.setCustomProperty('ol_layer_type', layerType.layerTypeName)
        return layer, layerType.xyzUrlConfig()

    def replaceLayer(self, group, oldLayer, newLayer):
        index = 0
        for child in group.children():
            if QgsLayerTree.isLayer(child):
                if child.layerId() == oldLayer.id():
                    # insert new layer
                    QgsProject.instance().addMapLayer(newLayer, False)
                    newLayerNode = group.insertLayer(index, newLayer)
                    newLayerNode.setVisible(child.isVisible())

                    # remove old layer
                    QgsProject.instance().removeMapLayer(
                        oldLayer.id())

                    msg = "Updated layer '%s' from old \
                     OpenLayers Plugin version" % newLayer.name()
                    self.iface.messageBar().pushMessage(
                        "OpenLayers Plugin", msg, level=Qgis.MessageLevel(0))
                    QgsMessageLog.logMessage(
                        msg, "OpenLayers Plugin", QgsMessageLog.INFO)

                    # layer replaced
                    return True
            else:
                if self.replaceLayer(child, oldLayer, newLayer):
                    # layer replaced in child group
                    return True

            index += 1

        # layer not in this group
        return False

    def showGoogleMapsApiKeyDialog(self):
        apiKey = QSettings().value("Plugin-OpenLayers/googleMapsApiKey")
        newApiKey, ok = QInputDialog.getText(
            self.iface.mainWindow(), "API key",
            "Enter your Google Maps API key", QLineEdit.Normal, apiKey)
        if ok:
            QSettings().setValue("Plugin-OpenLayers/googleMapsApiKey",
                                 newApiKey)

    def showThunderforestApiKeyDialog(self):
        apiKey = QSettings().value("Plugin-OpenLayers/thunderforestApiKey")
        newApiKey, ok = QInputDialog.getText(
            self.iface.mainWindow(), "API key",
            "Enter your API key (<a href=\"https://thunderforest.com/pricing/\">https://thunderforest.com</a>)", QLineEdit.Normal, apiKey)
        if ok:
            QSettings().setValue("Plugin-OpenLayers/thunderforestApiKey",
                                 newApiKey)
class cadastre_menu(object):
    def __init__(self, iface):
        self.iface = iface
        self.mapCanvas = iface.mapCanvas()
        self.cadastre_search_dialog = None
        self.provider = CadastreProvider()

    def cadastre_add_submenu(self, submenu):
        self.iface.addPluginToMenu("&Cadastre", submenu.menuAction())

    def initGui(self):

        # Add procesing provider
        QgsApplication.processingRegistry().addProvider(self.provider)

        # Import Submenu
        plugin_dir = str(Path(__file__).resolve().parent)
        icon = QIcon(plugin_dir + "/icons/database.png")
        self.import_action = QAction(icon, "Importer des données", self.iface.mainWindow())
        self.import_action.triggered.connect(self.open_import_dialog)

        # Search Submenu
        icon = QIcon(plugin_dir + "/icons/search.png")
        self.search_action = QAction(icon, "Outils de recherche", self.iface.mainWindow())
        self.search_action.triggered.connect(self.toggle_search_dialog)
        if not self.cadastre_search_dialog:
            dialog = cadastre_search_dialog(self.iface)
            self.cadastre_search_dialog = dialog

        # Load Submenu
        icon = QIcon(plugin_dir + "/icons/output.png")
        self.load_action = QAction(icon, "Charger des données", self.iface.mainWindow())
        self.load_action.triggered.connect(self.open_load_dialog)

        # Composer Submenu
        icon = QIcon(plugin_dir + "/icons/mActionSaveAsPDF.png")
        self.export_action = QAction(icon, "Exporter la vue", self.iface.mainWindow())
        self.export_action.triggered.connect(self.export_view)

        # Options Submenu
        icon = QIcon(plugin_dir + "/icons/config.png")
        self.option_action = QAction(icon, "Configurer le plugin", self.iface.mainWindow())
        self.option_action.triggered.connect(self.open_option_dialog)

        # About Submenu
        icon = QIcon(plugin_dir + "/icons/about.png")
        self.about_action = QAction(icon, "À propos", self.iface.mainWindow())
        self.about_action.triggered.connect(self.open_about_dialog)

        # Help Submenu
        icon = QIcon(plugin_dir + "/icons/about.png")
        self.help_action = QAction(icon, "Aide", self.iface.mainWindow())
        self.help_action.triggered.connect(self.open_help)

        # version Submenu
        icon = QIcon(plugin_dir + "/icons/about.png")
        self.version_action = QAction(icon, "Notes de version", self.iface.mainWindow())
        self.version_action.triggered.connect(self.open_message_dialog)

        # Add Cadastre to Extension menu
        self.iface.addPluginToMenu("&Cadastre", self.import_action)
        self.iface.addPluginToMenu("&Cadastre", self.load_action)
        self.iface.addPluginToMenu("&Cadastre", self.search_action)
        self.iface.addPluginToMenu("&Cadastre", self.export_action)
        self.iface.addPluginToMenu("&Cadastre", self.option_action)
        self.iface.addPluginToMenu("&Cadastre", self.about_action)
        self.iface.addPluginToMenu("&Cadastre", self.version_action)
        self.iface.addPluginToMenu("&Cadastre", self.help_action)


        # Add cadastre toolbar
        self.toolbar = self.iface.addToolBar('&Cadastre');

        # open import dialog
        self.openImportAction = QAction(
            QIcon(plugin_dir +"/icons/database.png"),
            "Importer des données",
            self.iface.mainWindow()
        )
        self.openImportAction.triggered.connect(self.open_import_dialog)
        self.toolbar.addAction(self.openImportAction)
        self.toolbar.setObjectName("cadastreToolbar");

        # open load dialog
        self.openLoadAction = QAction(
            QIcon(plugin_dir +"/icons/output.png"),
            "Charger des données",
            self.iface.mainWindow()
        )
        self.openLoadAction.triggered.connect(self.open_load_dialog)
        self.toolbar.addAction(self.openLoadAction)

        # open search dialog
        self.openSearchAction = QAction(
            QIcon(plugin_dir +"/icons/search.png"),
            "Outils de recherche",
            self.iface.mainWindow()
        )
        self.openSearchAction.triggered.connect(self.toggle_search_dialog)
        #~ self.openSearchAction.setCheckable(True)
        self.toolbar.addAction(self.openSearchAction)

        # export composer
        self.runExportAction = QAction(
            QIcon(plugin_dir +"/icons/mActionSaveAsPDF.png"),
            "Exporter la vue",
            self.iface.mainWindow()
        )
        self.runExportAction.triggered.connect(self.export_view)
        self.toolbar.addAction(self.runExportAction)

        # open Option dialog
        self.openOptionAction = QAction(
            QIcon(plugin_dir +"/icons/config.png"),
            "Configurer le plugin",
            self.iface.mainWindow()
        )
        self.openOptionAction.triggered.connect(self.open_option_dialog)
        self.toolbar.addAction(self.openOptionAction)

        # open About dialog
        self.openAboutAction = QAction(
            QIcon(plugin_dir +"/icons/about.png"),
            "À propos",
            self.iface.mainWindow()
        )
        self.openAboutAction.triggered.connect(self.open_about_dialog)
        self.toolbar.addAction(self.openAboutAction)

        # Create action for "Parcelle information"
        self.identifyParcelleAction = QAction(
            QIcon(plugin_dir +"/icons/toolbar/get-parcelle-info.png"),
            "Infos parcelle",
            self.iface.mainWindow()
        )
        self.identifyParcelleAction.setCheckable(True)
        self.identifyParcelleAction.triggered.connect( self.setIndentifyParcelleTool )
        self.toolbar.addAction( self.identifyParcelleAction )

        self.setActionsExclusive()

        # Display About window on first use
        s = QSettings()
        firstUse = s.value("cadastre/isFirstUse" , 1, type=int)
        if firstUse == 1:
            s.setValue("cadastre/isFirstUse", 0)
            self.open_about_dialog()

        # Display some messages depending on version number
        mConfig = configparser.ConfigParser()
        metadataFile = plugin_dir + "/metadata.txt"
        mConfig.read( metadataFile, encoding='utf-8' )
        self.mConfig = mConfig
        myVersion = mConfig.get('general', 'version').replace('.', '_')
        myVersionMsg = s.value("cadastre/version_%s" % myVersion , 1, type=int)
        if myVersionMsg == 1:
            s.setValue("cadastre/version_%s" % myVersion , 0)
            self.open_message_dialog()

        # Project load or create : refresh search and identify tool
        self.iface.projectRead.connect(self.onProjectRead)
        self.iface.newProjectCreated.connect(self.onNewProjectCreated)

        # Delete layers from table when deleted from registry
        lr = QgsProject.instance()
        lr.layersRemoved.connect( self.checkIdentifyParcelleTool )


    def open_import_dialog(self):
        '''
        Import dialog
        '''
        dialog = cadastre_import_dialog(self.iface)
        dialog.exec_()

    def open_load_dialog(self):
        '''
        Load dialog
        '''
        dialog = cadastre_load_dialog(
            self.iface,
            self.cadastre_search_dialog
        )
        dialog.exec_()

    def toggle_search_dialog(self):
        '''
        Search dock widget
        '''
        if self.cadastre_search_dialog.isVisible():
            self.cadastre_search_dialog.hide()
        else:
            self.cadastre_search_dialog.show()

    def export_view(self):
        '''
        Export current view to PDF
        '''
        # Load template from file
        s = QSettings()
        f = s.value("cadastre/composerTemplateFile", '', type=str)
        if not os.path.exists(f):
            f = os.path.join(str(Path(__file__).resolve().parent), 'composers', 'paysage_a4.qpt')
            s.setValue("cadastre/composerTemplateFile", f)

        QApplication.setOverrideCursor(Qt.WaitCursor)
        template_content = None
        with open(f, 'rt', encoding="utf-8") as ff:
            template_content = ff.read()
        if not template_content:
            return
        d = QDomDocument()
        d.setContent(template_content)

        c = QgsPrintLayout(QgsProject.instance())
        c.loadFromTemplate(d, QgsReadWriteContext() )

        # Set scale and extent
        cm=c.referenceMap()
        canvas = self.iface.mapCanvas()
        extent = canvas.extent()
        scale = canvas.scale()
        if extent:
            cm.zoomToExtent(extent)
        if scale:
            cm.setScale(scale)

        # Export
        tempDir = s.value("cadastre/tempDir", '%s' % tempfile.gettempdir(), type=str)
        self.targetDir = tempfile.mkdtemp('', 'cad_export_', tempDir)
        temp = int(time()*100)
        temppath = os.path.join(tempDir, 'export_cadastre_%s.pdf' % temp)

        exporter = QgsLayoutExporter(c)
        exportersettings = QgsLayoutExporter.PdfExportSettings()
        exportersettings.dpi = 300
        exportersettings.forceVectorOutput = True
        exportersettings.rasterizeWholeImage = False #rasterizeWholeImage = false
        exporter.exportToPdf(temppath, exportersettings )

        QApplication.restoreOverrideCursor()

        if os.path.exists(temppath):
            cadastre_common.openFile(temppath)

    def open_option_dialog(self):
        '''
        Config dialog
        '''
        dialog = cadastre_option_dialog(self.iface)
        dialog.exec_()


    def open_about_dialog(self):
        '''
        About dialog
        '''
        dialog = cadastre_about_dialog(self.iface)
        dialog.exec_()


    def setActionsExclusive(self):

        # Build an action list from QGIS navigation toolbar
        actionList = self.iface.mapNavToolToolBar().actions()

        # Add actions from QGIS attributes toolbar (handling QWidgetActions)
        tmpActionList = self.iface.attributesToolBar().actions()
        for action in tmpActionList:
            if isinstance(action, QWidgetAction):
                actionList.extend( action.defaultWidget().actions() )
            else:
                actionList.append( action )
        # ... add other toolbars' action lists...

        # Build a group with actions from actionList and add your own action
        group = QActionGroup( self.iface.mainWindow() )
        group.setExclusive(True)
        for action in actionList:
            group.addAction( action )
        group.addAction( self.identifyParcelleAction )

    def checkIdentifyParcelleTool(self, layerIds=None):
        '''
        When layers are removed from the project
        Check if the layer Parcelle remains
        If not deactivate Identify parcelle tool
        '''
        # Find parcelle layer
        parcelleLayer = None
        try:
            from .cadastre_dialogs import cadastre_common
            parcelleLayer = cadastre_common.getLayerFromLegendByTableProps('parcelle_info')
        except:
            parcelleLayer = None

        if not parcelleLayer:
            self.identifyParcelleAction.setChecked(False)
            self.iface.actionPan().trigger()
            return

    def setIndentifyParcelleTool(self):
        '''
        Activite the identify tool
        for the layer geo_parcelle
        '''

        # Find parcelle layer
        parcelleLayer = cadastre_common.getLayerFromLegendByTableProps('parcelle_info')
        if not parcelleLayer:
            QMessageBox.warning(
                self.cadastre_search_dialog,
                "Cadastre",
                "La couche de parcelles n'a pas été trouvée dans le projet"
            )
            self.identifyParcelleAction.setChecked(False)
            self.iface.actionPan().trigger()
            return

        self.identyParcelleTool = IdentifyParcelle( self.mapCanvas, parcelleLayer )
        self.identyParcelleTool.cadastreGeomIdentified.connect(self.getParcelleInfo)

        # The activate identify tool
        self.mapCanvas.setMapTool(self.identyParcelleTool)

    def getParcelleInfo(self, layer, feature):
        '''
        Return information of the identified
        parcelle
        '''
        parcelleDialog = cadastre_parcelle_dialog(
            self.iface,
            layer,
            feature,
            self.cadastre_search_dialog
        )
        parcelleDialog.show()

    def onProjectRead(self):
        '''
        Refresh search dialog when new data has been loaded
        '''
        if self.cadastre_search_dialog:
            self.cadastre_search_dialog.checkMajicContent()
            self.cadastre_search_dialog.clearComboboxes()
            self.cadastre_search_dialog.setupSearchCombobox('commune', None, 'sql')
            self.cadastre_search_dialog.setupSearchCombobox('section', None, 'sql')
            self.checkIdentifyParcelleTool()

    def onNewProjectCreated(self):
        '''
        Refresh search dialog when new data has been loaded
        '''
        self.checkIdentifyParcelleTool()
        if self.cadastre_search_dialog:
            self.cadastre_search_dialog.checkMajicContent()
            self.cadastre_search_dialog.clearComboboxes()


    def open_help(self):
        '''Opens the html help file content with default browser'''
        #~ localHelpUrl = "https://github.com/3liz/QgisCadastrePlugin/blob/master/doc/index.rst"
        localHelpUrl = os.path.join(str(Path(__file__).resolve().parent), 'doc', 'index.html')
        QDesktopServices.openUrl( QUrl(localHelpUrl) )

    def open_message_dialog(self):
        '''
        Display a message to the user
        '''
        versionMessages = {
            '1.1.0': [
                [
                    'Compatibilité avec QGIS 2.6',
                    'La compatibilité n\'est pas assurée à 100 % avec la dernière version 2.6 de QGIS, notamment pour la création d\'une base Spatialite vide. Vous pouvez utiliser les outils de QGIS pour le faire.'
                ] ,
                [
                    'Lien entre les parcelles EDIGEO et MAJIC',
                    'Pour cette nouvelle version du plugin, la structure de la base de données a été légèrement modifiée. Pour pouvoir utiliser les fonctions du plugin Cadastre, vous devez donc impérativement <b>réimporter les données dans une base vide</b>'
                ] ,
                [
                    'Validation des géométries',
                    'Certaines données EDIGEO contiennent des géométries invalides (polygones croisés dit "papillons", polygones non fermés, etc.). Cette version utilise une fonction de PostGIS qui tente de corriger ces invalidités. Il faut impérativement <b>utiliser une version récente de PostGIS</b> : 2.0.4 minimum pour la version 2, ou les version ultérieures (2.1 par exemple)'
                ]
            ]
            ,
            '1.4.0': [
                [
                    'Modification de la structure',
                    'Pour cette nouvelle version 1.4.0 du plugin, la structure de la base de données a été légèrement modifiée par rapport à la 1.4.0. Pour pouvoir utiliser les fonctions du plugin Cadastre, vous devez donc impérativement <b>réimporter les données dans une base vide</b>. Les changements concernent les identifiants des tables parcelle, geo_parcelle, commune, local00, local10, pev, pevexoneration, pevtaxation, pevprincipale, pevprofessionnelle, pevdependances, ainsi que la création d\'une table parcelle_info pour consolider EDIGEO et MAJIC.'
                ]
            ]
        }
        mConfig = self.mConfig
        version = mConfig.get('general', 'version')
        changelog = mConfig.get('general', 'changelog')

        message = '<h2>Version %s - notes concernant cette version</h2>' % version
        if version in versionMessages:
            message+='<ul>'
            for item in versionMessages[version]:
                message+='<li><b>%s</b> - %s</li>' % (item[0], item[1])
            message+='</ul>'

        message+= '<h3>Changelog</h3>'
        message+= '<p>'
        i = 0
        for item in changelog.split('*'):
            if i == 0:
                message+= '<b>%s</b><ul>' % item
            else:
                message+= '<li>%s</li>' % item
            i+=1
        message+='</ul>'
        message+= '</p>'

        dialog = cadastre_message_dialog(self.iface, message)
        dialog.exec_()



    def unload(self):

        self.iface.removePluginMenu("&Cadastre", self.import_action)
        self.iface.removePluginMenu("&Cadastre", self.load_action)
        self.iface.removePluginMenu("&Cadastre", self.search_action)
        self.iface.removePluginMenu("&Cadastre", self.export_action)
        self.iface.removePluginMenu("&Cadastre", self.option_action)
        self.iface.removePluginMenu("&Cadastre", self.about_action)
        self.iface.removePluginMenu("&Cadastre", self.version_action)
        self.iface.removePluginMenu("&Cadastre", self.help_action)

        self.iface.mainWindow().removeToolBar(self.toolbar)

        if self.cadastre_search_dialog:
            self.iface.removeDockWidget(self.cadastre_search_dialog)

        # Remove processing provider
        QgsApplication.processingRegistry().removeProvider(self.provider)
class OpenlayersPlugin:

    def __init__(self, iface):
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # Keep a reference to all OL layers to avoid GC
        self._ol_layers = []
        # initialize locale
        locale = QSettings().value("locale/userLocale")[0:2]
        localePath = os.path.join(self.plugin_dir, "i18n", "openlayers_{}.qm".format(locale))

        if os.path.exists(localePath):
            self.translator = QTranslator()
            self.translator.load(localePath)
            
            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        self._olLayerTypeRegistry = WebLayerTypeRegistry(self)
        self.olOverview = OLOverview(iface, self._olLayerTypeRegistry)
        self.dlgAbout = AboutDialog()
        self.pluginLayerRegistry = QgsPluginLayerRegistry()

    def initGui(self):
        self._olMenu = QMenu("TMS for Korea")
        self._olMenu.setIcon(QIcon(":/plugins/openlayers/openlayers.png"))

        # Overview
        self.overviewAddAction = QAction(QApplication.translate("OpenlayersPlugin", "OpenLayers Overview"), self.iface.mainWindow())
        self.overviewAddAction.setCheckable(True)
        self.overviewAddAction.setChecked(False)
        self.overviewAddAction.toggled.connect(self.olOverview.setVisible)
        self._olMenu.addAction(self.overviewAddAction)

        self._actionAbout = QAction(QApplication.translate("dlgAbout", "About OpenLayers Plugin"), self.iface.mainWindow())
        self._actionAbout.triggered.connect(self.dlgAbout.show)
        self._olMenu.addAction(self._actionAbout)
        self.dlgAbout.finished.connect(self._publicationInfoClosed)
        
        # Daum
        self._olLayerTypeRegistry.register(OlDaumStreetLayer())
        self._olLayerTypeRegistry.register(OlDaumHybridLayer())
        self._olLayerTypeRegistry.register(OlDaumSatelliteLayer())
        self._olLayerTypeRegistry.register(OlDaumPhysicalLayer())
        self._olLayerTypeRegistry.register(OlDaumCadstralLayer())
        
        # Naver
        self._olLayerTypeRegistry.register(OlNaverStreetLayer())
        self._olLayerTypeRegistry.register(OlNaverHybridLayer())
        self._olLayerTypeRegistry.register(OlNaverSatelliteLayer())
        self._olLayerTypeRegistry.register(OlNaverPhysicalLayer())
        self._olLayerTypeRegistry.register(OlNaverCadastralLayer())
        
        # VWorld
        self._olLayerTypeRegistry.register(OlVWorldStreetLayer())
        self._olLayerTypeRegistry.register(OlVWorldSatelliteLayer())
        self._olLayerTypeRegistry.register(OlVWorldGrayLayer())
        self._olLayerTypeRegistry.register(OlVWorldHybridLayer())
        
        # NGII
        self._olLayerTypeRegistry.register(OlNgiiStreetLayer())
        self._olLayerTypeRegistry.register(OlNgiiBlankLayer())
        self._olLayerTypeRegistry.register(OlNgiiEnglishLayer())
        self._olLayerTypeRegistry.register(OlNgiiHighDensityLayer())
        self._olLayerTypeRegistry.register(OlNgiiColorBlindLayer())
        
        # Mango
        #self._olLayerTypeRegistry.register(OlMangoBaseMapLayer())
        #self._olLayerTypeRegistry.register(OlMangoBaseMapGrayLayer())
        #self._olLayerTypeRegistry.register(OlMangoHiDPIMapLayer())
        #self._olLayerTypeRegistry.register(OlMangoHiDPIMapGrayLayer())
        
        for group in self._olLayerTypeRegistry.groups():
            groupMenu = group.menu()
            for layer in self._olLayerTypeRegistry.groupLayerTypes(group):
                layer.addMenuEntry(groupMenu, self.iface.mainWindow())
            self._olMenu.addMenu(groupMenu)
            
        # Create Web menu, if it doesn't exist yet
        self.iface.addPluginToWebMenu("_tmp", self._actionAbout)
        self._menu = self.iface.webMenu()
        self._menu.addMenu(self._olMenu)
        self.iface.removePluginWebMenu("_tmp", self._actionAbout)

        # Register plugin layer type
        self.pluginLayerType = OpenlayersPluginLayerType(
            self.iface, self.setReferenceLayer, self._olLayerTypeRegistry)

        self.pluginLayerRegistry.addPluginLayerType(
            self.pluginLayerType)

        QgsProject.instance().readProject.connect(self.projectLoaded)
        QgsProject.instance().projectSaved.connect(self.projectSaved)

    def unload(self):
        self.iface.webMenu().removeAction(self._olMenu.menuAction())

        self.olOverview.setVisible(False)
        del self.olOverview

        # Unregister plugin layer type
        self.pluginLayerRegistry.removePluginLayerType(
            OpenlayersLayer.LAYER_TYPE)

        QgsProject.instance().readProject.disconnect(self.projectLoaded)
        QgsProject.instance().projectSaved.disconnect(self.projectSaved)

    def addLayer(self, layerType):
        if layerType.hasXYZUrl():
            # create XYZ layer
            layer, url = self.createXYZLayer(layerType,
                                             layerType.displayName)
        else:
            # create OpenlayersLayer
            layer = OpenlayersLayer(self.iface, self._olLayerTypeRegistry)
            layer.setName(layerType.displayName)
            layer.setLayerType(layerType)

        if layer.isValid():
            coordRefSys = layerType.coordRefSys(self.canvasCrs())
            self.setMapCrs(coordRefSys)
            QgsProject.instance().addMapLayer(layer)

            # store xyz config into qgis settings
            if layerType.hasXYZUrl():
                settings = QSettings()
                settings.beginGroup('qgis/connections-xyz')
                settings.setValue("%s/authcfg" % (layer.name()), '')
                settings.setValue("%s/password" % (layer.name()), '')
                settings.setValue("%s/referer" % (layer.name()), '')
                settings.setValue("%s/url" % (layer.name()), url)
                settings.setValue("%s/username" % (layer.name()), '')
                # specify max/min or else only a picture of the map is saved
                # in settings
                settings.setValue("%s/zmax" % (layer.name()), '18')
                settings.setValue("%s/zmin" % (layer.name()), '0')
                settings.endGroup()
                # reload connections to update Browser Panel content
                self.iface.reloadConnections()

            self._ol_layers += [layer]

            # last added layer is new reference
            self.setReferenceLayer(layer)

            if not layerType.hasXYZUrl():
                msg = "Printing and rotating of Javascript API " \
                      "based layers is currently not supported!"
                self.iface.messageBar().pushMessage(
                    "OpenLayers Plugin", msg, level=Qgis.MessageLevel(1),
                    duration=5)

    def setReferenceLayer(self, layer):
        self.layer = layer

    def removeLayer(self, layerId):
        if self.layer is not None:
            if self.layer.id() == layerId:
                self.layer = None
            # TODO: switch to next available OpenLayers layer?

    def canvasCrs(self):
        mapCanvas = self.iface.mapCanvas()
        crs = mapCanvas.mapSettings().destinationCrs()
        return crs

    def setMapCrs(self, targetCRS):
        mapCanvas = self.iface.mapCanvas()
        mapExtent = mapCanvas.extent()
        
        sourceCRS = self.canvasCrs()
        QgsProject.instance().setCrs(targetCRS)
        mapCanvas.freeze(False)
        try:
            coordTrans = QgsCoordinateTransform(sourceCRS, targetCRS, QgsProject.instance())
            mapExtent = coordTrans.transform(mapExtent, QgsCoordinateTransform.ForwardTransform)
            mapCanvas.setExtent(mapExtent)
        except:
            pass

    def projectLoaded(self):
        # replace old OpenlayersLayer with XYZ layer(OL plugin <= 1.3.6)
        rootGroup = self.iface.layerTreeView().layerTreeModel().rootGroup()
        for layer in QgsProject.instance().mapLayers().values():
            if layer.type() == QgsMapLayer.PluginLayer and layer.pluginLayerType() == OpenlayersLayer.LAYER_TYPE:
                if layer.layerType.hasXYZUrl():
                    # replace layer
                    xyzLayer, url = self.createXYZLayer(layer.layerType,
                                                        layer.name())
                    if xyzLayer.isValid():
                        self.replaceLayer(rootGroup, layer, xyzLayer)

    def _hasOlLayer(self):
        for layer in QgsProject.instance().mapLayers().values():
            if layer.customProperty('ol_layer_type'):
                return True
        return False

    def _publicationInfo(self):
        cloud_info_off = QSettings().value("Plugin-OpenLayers/cloud_info_off",
                                           defaultValue=False, type=bool)
        day = 3600*24
        now = time.time()
        lastInfo = QSettings().value("Plugin-OpenLayers/cloud_info_ts",
                                     defaultValue=0.0, type=float)
        if lastInfo == 0.0:
            lastInfo = now-20*day  # Show first time after 10 days
            QSettings().setValue("Plugin-OpenLayers/cloud_info_ts", lastInfo)
        days = (now-lastInfo)/day
        if days >= 30 and not cloud_info_off:
            self.dlgAbout.tabWidget.setCurrentWidget(
                self.dlgAbout.tab_publishing)
            self.dlgAbout.show()
            QSettings().setValue("Plugin-OpenLayers/cloud_info_ts", now)

    def _publicationInfoClosed(self):
        QSettings().setValue("Plugin-OpenLayers/cloud_info_off",
                             self.dlgAbout.cb_publishing.isChecked())

    def projectSaved(self):
        if self._hasOlLayer():
            self._publicationInfo()

    def createXYZLayer(self, layerType, name):
        # create XYZ layer with tms url as uri
        provider = 'wms'
        url = "type=xyz&url=" + layerType.xyzUrlConfig()
        layer = QgsRasterLayer(url, name, provider,
                               QgsRasterLayer.LayerOptions())
        layer.setCustomProperty('ol_layer_type', layerType.layerTypeName)
        return layer, layerType.xyzUrlConfig()

    def replaceLayer(self, group, oldLayer, newLayer):
        index = 0
        for child in group.children():
            if QgsLayerTree.isLayer(child):
                if child.layerId() == oldLayer.id():
                    # insert new layer
                    QgsProject.instance().addMapLayer(newLayer, False)
                    newLayerNode = group.insertLayer(index, newLayer)
                    newLayerNode.setVisible(child.isVisible())

                    # remove old layer
                    QgsProject.instance().removeMapLayer(
                        oldLayer.id())

                    msg = "Updated layer '%s' from old \
                     OpenLayers Plugin version" % newLayer.name()
                    self.iface.messageBar().pushMessage(
                        "OpenLayers Plugin", msg, level=Qgis.MessageLevel(0))
                    QgsMessageLog.logMessage(
                        msg, "OpenLayers Plugin", QgsMessageLog.INFO)

                    # layer replaced
                    return True
            else:
                if self.replaceLayer(child, oldLayer, newLayer):
                    # layer replaced in child group
                    return True

            index += 1

        # layer not in this group
        return False
Beispiel #20
0
    def add_action(self,
                   icon_path,
                   text,
                   callback,
                   checkable=False,
                   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 = SelectByRelationshipDialog()

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        if checkable:
            action.toggled.connect(callback)
        else:
            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 add_to_toolbar:
            self.toolbar.addAction(action)

        if add_to_menu:
            self.iface.addPluginToDatabaseMenu(self.menu, action)

        self.actions.append(action)

        return action
Beispiel #21
0
class HuntRegister:
    """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__)

        # 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

        # This plugin depends on alkisplugin
        self.alkisplugin = None

        # Members
        self.alkisToolBar = None  # the toolbar instance where the alkisplugin and huntplugin QAction symbols are placed

        self.alkisSelectAreaLayer = None  # QgsVectorLayer selected parcels of alkisplugin
        self.huntSelectAreaLayer = None  # QgsVectorLayer selected parcels of huntplugin

        # help web view
        self.helpiew = None  # webview containing manuals

        # All actions are assigned to alter self.huntSelectAreaLayer
        self.hswapAction = None  # single QAction copy selected parcels from alkisplugin to huntplugin
        self.hAddMarkAction = None  # checkable QAction select and unselect parcels
        self.hlistAction = None  # single QAction select parcels by parcel attributes
        self.hclearAction = None  # single QAction unselect all selected parcels
        self.hownerAction = None  # single QAction get parcel certificates for all selected parcels
        self.hhuntAction = None  # single QAction create a hunt register
        self.hinfoAction = None  # single QAction get a basic summary of all selected parcels
        self.helpAction = None  # single QAction open help files webview browser window
        # self.testAction = None                                                                # single QAction used for testing program fragments

        self.hAddMarkTool = None  # click recognizing map tool for self.hAddMarkAction
        self.core = None  # function core for this plugin
        self.initTimer = QTimer(
            self.iface
        )  # timer used to init self.huntSelectAreaLayer dynamically when alkis layers are added
        self.initTimer.setInterval(1000)  # 1 sec interval
        self.initTimer.timeout.connect(self.initLayers)
        self.init()  # init main instances

    def init(self):
        """init main instances"""

        if (alkisAvailable):
            try:
                self.alkisplugin = Alkis.alkisplugin.alkisplugin(
                    self.iface)  # create alkisplugin object
                self.alkisplugin.queryOwnerAction = QAction(
                    None
                )  # this is used in akisplugin "opendb" and must therefore be set to prevent runtime errors
            except AttributeError:
                QMessageBox.critical(
                    None, "Fehler",
                    "norGIS ALKIS-Einbindung zuerst aktivieren und \"JagdKataster\" erneut aktivieren"
                )
                raise AttributeError("alkisplugin not active")
        else:
            QMessageBox.critical(
                None, "Fehler",
                "norGIS ALKIS-Einbindung installieren und zuerst aktivieren. Dann \"JagdKataster\" erneut aktivieren"
            )
            raise AttributeError("alkisplugin not installed")

        self.core = HuntCore(self)  # function core for this plugin

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        # will be set False in run()
        self.first_start = True

        self.helpview = QWebView()
        self.helpview.resize(1280, 850)
        self.helpview.setWindowTitle("JagdKataster Anleitungen")
        help_dir = os.path.join(self.plugin_dir, "help", "build", "html",
                                "index.html")
        self.helpview.load(QUrl.fromLocalFile(help_dir))

        # the toolbar entries of this plugin should be placed alongside the alkisplugin entries
        # therefore the alkisplugin toolbar is derived
        tBars = self.iface.mainWindow().findChildren(
            QToolBar)  # get all toolbars from main window
        self.alkisToolBar = next(
            (n
             for n in tBars if n.objectName() == "norGIS_ALKIS_Toolbar"), None
        )  # find the instance of alkisplugin toolbar by its static name

        if self.alkisToolBar is None:  # in case the toolbar is not yet loaded create the instance with its static name
            # create alkis toolbar in case it is not yet loaded
            self.alkisToolBar = self.iface.addToolBar(u"norGIS: ALKIS")
            self.alkisToolBar.setObjectName("norGIS_ALKIS_Toolbar")

        #create toolbar items
        self.hswapAction = QAction(QIcon("hunt:mark_transfer.svg"),
                                   "Flächenmarkierung übertragen",
                                   self.iface.mainWindow())
        self.hswapAction.setWhatsThis(
            "Flächenmarkierung (gelb) nach Jagd-Flächenmarkierung (blau) übertragen"
        )
        self.hswapAction.setStatusTip(
            "Flächenmarkierung (gelb) nach Jagd-Flächenmarkierung (blau) übertragen"
        )
        self.hswapAction.triggered.connect(lambda: self.core.swapAlkisToHunt())
        self.alkisToolBar.addAction(self.hswapAction)

        self.hAddMarkAction = QAction(QIcon("hunt:mark_add.svg"),
                                      u"Flurstück (de)selektieren",
                                      self.iface.mainWindow())
        self.hAddMarkAction.setWhatsThis(
            "Flurstück in Jagd-Flächenmarkierung selektieren oder deselektieren"
        )
        self.hAddMarkAction.setStatusTip(
            "Flurstück in Jagd-Flächenmarkierung selektieren oder deselektieren"
        )
        self.hAddMarkAction.setCheckable(True)
        self.hAddMarkAction.triggered.connect(
            lambda: self.iface.mapCanvas().setMapTool(self.hAddMarkTool))
        self.alkisToolBar.addAction(self.hAddMarkAction)
        self.hAddMarkTool = HAdd(self)
        self.hAddMarkTool.setAction(self.hAddMarkAction)

        self.hlistAction = QAction(QIcon("hunt:mark_list.svg"),
                                   "Selektieren nach Flurstückseigenschaft",
                                   self.iface.mainWindow())
        self.hlistAction.setWhatsThis(
            "Selektierung der Flurstücke in Jagd-Flächenmarkierung anhand Flurstückseigenschaften"
        )
        self.hlistAction.setStatusTip(
            "Selektierung der Flurstücke in Jagd-Flächenmarkierung anhand Flurstückseigenschaften"
        )
        self.hlistAction.triggered.connect(
            lambda: self.core.showListSelection())
        self.alkisToolBar.addAction(self.hlistAction)

        self.hclearAction = QAction(QIcon("hunt:mark_clear.svg"),
                                    "Alle deselektieren",
                                    self.iface.mainWindow())
        self.hclearAction.setWhatsThis(
            "Alle Flurstücke in Jagd-Flächenmarkierung deselektieren")
        self.hclearAction.setStatusTip(
            "Alle Flurstücke in Jagd-Flächenmarkierung deselektieren")
        self.hclearAction.triggered.connect(lambda: self.core.clearHighlight())
        self.alkisToolBar.addAction(self.hclearAction)

        self.hownerAction = QAction(QIcon("hunt:mark_own.svg"),
                                    "Flurstücksnachweise anzeigen",
                                    self.iface.mainWindow())
        self.hownerAction.setWhatsThis(
            "Flurstücksnachweise für selektierte Flurstücke in Jagd-Flächenmarkierung anzeigen"
        )
        self.hownerAction.setStatusTip(
            "Flurstücksnachweise für selektierte Flurstücke in Jagd-Flächenmarkierung anzeigen"
        )
        self.hownerAction.triggered.connect(
            lambda: self.core.showParcelCerts())
        self.alkisToolBar.addAction(self.hownerAction)

        self.hhuntAction = QAction(QIcon("hunt:mark_hunt.svg"),
                                   "Jagdkataster erstellen",
                                   self.iface.mainWindow())
        self.hhuntAction.setWhatsThis(
            "Jagdkataster für selektierte Flurstücke in Jagd-Flächenmarkierung erstellen"
        )
        self.hhuntAction.setStatusTip(
            "Jagdkataster für selektierte Flurstücke in Jagd-Flächenmarkierung erstellen"
        )
        self.hhuntAction.triggered.connect(lambda: self.core.showHuntReg())
        self.alkisToolBar.addAction(self.hhuntAction)

        self.hinfoAction = QAction(QIcon("hunt:mark_info.svg"),
                                   "Flurstückszusammenfassung anzeigen",
                                   self.iface.mainWindow())
        self.hinfoAction.setWhatsThis(
            "Flurstückszusammenfassung für selektierte Flurstücke in Jagd-Flächenmarkierung anzeigen"
        )
        self.hinfoAction.setStatusTip(
            "Flurstückszusammenfassung für selektierte Flurstücke in Jagd-Flächenmarkierung anzeigen"
        )
        self.hinfoAction.triggered.connect(
            lambda: self.core.showSummaryDialog())
        self.alkisToolBar.addAction(self.hinfoAction)

        self.helpAction = QAction(QIcon("hunt:logo.svg"), "Anleitungen",
                                  self.iface.mainWindow())
        self.helpAction.setWhatsThis("JagdKataster-Anleitungen")
        self.helpAction.setStatusTip("JagdKataster-Anleitungen")
        self.helpAction.triggered.connect(lambda: self.helpview.show())

        # self.testAction = QAction(QIcon("hunt:test.svg"), "Test", self.iface.mainWindow())
        # self.testAction.setWhatsThis("Test action")
        # self.testAction.setStatusTip("Test action")
        # self.testAction.triggered.connect(lambda: self.core.test(self.huntSelectAreaLayer))
        # self.alkisToolBar.addAction(self.testAction)

        self.iface.addPluginToDatabaseMenu("&ALKIS", self.helpAction)

        QgsProject.instance().layersAdded.connect(
            self.initTimer.start
        )  # react to changes in the layer tree. Maybe the alkis layers were added
        QgsProject.instance().layersWillBeRemoved.connect(
            self.layersRemoved
        )  # remove entries in case this plugin layers are to be removed

    def initLayers(self):
        """init self.huntSelectAreaLayer in case the alkis layers from alkisplugin are loaded"""
        self.initTimer.stop(
        )  # this methode may be called by a timer started when layers are added => stop the timer after first timeout event
        if self.alkisSelectAreaLayer is None:  # are alkisplugin layers loaded ad readable from entry?
            (layerId,
             res) = QgsProject.instance().readEntry("alkis",
                                                    "/areaMarkerLayer")
            if res and layerId:
                self.alkisSelectAreaLayer = QgsProject.instance().mapLayer(
                    layerId)
        if self.huntSelectAreaLayer is None:  # is the huntplugin layer already loaded?
            (layerId,
             res) = QgsProject.instance().readEntry("hunt", "/areaMarkerLayer")
            if res and layerId:
                self.huntSelectAreaLayer = QgsProject.instance().mapLayer(
                    layerId)
        if self.huntSelectAreaLayer is None and self.alkisSelectAreaLayer is not None:  # alkisplugin layers are loaded but huntplugin layer is not
            self.createLayer()  # create huntplugin layer

    def layersRemoved(self, layersIds):
        """remove entries and references in case this plugin layers are to be removed"""
        if self.alkisSelectAreaLayer is not None and self.alkisSelectAreaLayer.id(
        ) in layersIds:
            self.alkisSelectAreaLayer = None
        if self.huntSelectAreaLayer is not None and self.huntSelectAreaLayer.id(
        ) in layersIds:
            QgsProject.instance().removeEntry("hunt", "/areaMarkerLayer")
            self.core.hlayer = None
            self.huntSelectAreaLayer = None

    def createLayer(self):
        """create and add huntplugin layer to the layer tree"""
        if (self.alkisSelectAreaLayer is not None):
            parent = QgsProject.instance().layerTreeRoot().findLayer(
                self.alkisSelectAreaLayer).parent()
            layeropts = QgsVectorLayer.LayerOptions(False, False)

            self.init(
            )  # reinit main instances because alkis instance conninfo might have changed
            (db, conninfo) = self.core.openDB()
            if db is None:
                return

            self.huntSelectAreaLayer = QgsVectorLayer(
                u"%s estimatedmetadata=true checkPrimaryKeyUnicity=0 key='ogc_fid' type=MULTIPOLYGON srid=%d table=%s.po_polygons (polygon) sql=false"
                % (conninfo, self.alkisplugin.epsg,
                   self.alkisplugin.quotedschema()), u"Jagd-Flächenmarkierung",
                "postgres", layeropts)

            sym = QgsSymbol.defaultSymbol(QgsWkbTypes.PolygonGeometry)
            sym.setColor(Qt.blue)
            sym.setOpacity(0.3)

            self.huntSelectAreaLayer.setRenderer(QgsSingleSymbolRenderer(sym))
            QgsProject.instance().addMapLayer(self.huntSelectAreaLayer, False)
            parent.insertLayer(0, self.huntSelectAreaLayer)

            self.core.hlayer = None
            QgsProject.instance().writeEntry("hunt", "/areaMarkerLayer",
                                             self.huntSelectAreaLayer.id())

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        if self.hswapAction:
            self.hswapAction.deleteLater()
            self.hswapAction = None
        if self.hAddMarkAction:
            self.hAddMarkAction.deleteLater()
            self.hAddMarkAction = None
        if self.hlistAction:
            self.hlistAction.deleteLater()
            self.hlistAction = None
        if self.hclearAction:
            self.hclearAction.deleteLater()
            self.hclearAction = None
        if self.hownerAction:
            self.hownerAction.deleteLater()
            self.hownerAction = None
        if self.hhuntAction:
            self.hhuntAction.deleteLater()
            self.hhuntAction = None
        if self.hinfoAction:
            self.hinfoAction.deleteLater()
            self.hinfoAction = None
        if self.helpAction:
            self.helpAction.deleteLater()
            self.helpAction = None
        # if self.testAction:
        #     self.testAction.deleteLater()
        #     self.testAction = None

        QgsProject.instance().layersAdded.disconnect(self.initTimer.start)
        QgsProject.instance().layersWillBeRemoved.disconnect(
            self.layersRemoved)

    def run(self):
        """Run method"""
        if self.first_start:
            self.first_start = False
Beispiel #22
0
class ProcessingPlugin:

    def __init__(self, iface):
        self.iface = iface
        self.options_factory = None
        self.drop_handler = None
        self.item_provider = None
        self.locator_filter = None
        self.edit_features_locator_filter = None
        self.initialized = False
        self.initProcessing()

    def initProcessing(self):
        if not self.initialized:
            self.initialized = True
            Processing.initialize()

    def initGui(self):
        self.options_factory = ProcessingOptionsFactory()
        self.options_factory.setTitle(self.tr('Processing'))
        iface.registerOptionsWidgetFactory(self.options_factory)
        self.drop_handler = ProcessingDropHandler()
        iface.registerCustomDropHandler(self.drop_handler)
        self.item_provider = ProcessingDataItemProvider()
        QgsApplication.dataItemProviderRegistry().addProvider(self.item_provider)
        self.locator_filter = AlgorithmLocatorFilter()
        iface.registerLocatorFilter(self.locator_filter)
        # Invalidate the locator filter for in-place when active layer changes
        iface.currentLayerChanged.connect(lambda _: self.iface.invalidateLocatorResults())
        self.edit_features_locator_filter = InPlaceAlgorithmLocatorFilter()
        iface.registerLocatorFilter(self.edit_features_locator_filter)

        self.toolbox = ProcessingToolbox()
        self.iface.addDockWidget(Qt.RightDockWidgetArea, self.toolbox)
        self.toolbox.hide()
        self.toolbox.visibilityChanged.connect(self.toolboxVisibilityChanged)

        self.resultsDock = ResultsDock()
        self.iface.addDockWidget(Qt.RightDockWidgetArea, self.resultsDock)
        self.resultsDock.hide()

        self.menu = QMenu(self.iface.mainWindow().menuBar())
        self.menu.setObjectName('processing')
        self.menu.setTitle(self.tr('Pro&cessing'))

        self.toolboxAction = QAction(self.tr('&Toolbox'), self.iface.mainWindow())
        self.toolboxAction.setCheckable(True)
        self.toolboxAction.setObjectName('toolboxAction')
        self.toolboxAction.setIcon(
            QgsApplication.getThemeIcon("/processingAlgorithm.svg"))
        self.iface.registerMainWindowAction(self.toolboxAction,
                                            QKeySequence('Ctrl+Alt+T').toString(QKeySequence.NativeText))
        self.toolboxAction.toggled.connect(self.openToolbox)
        self.iface.attributesToolBar().insertAction(self.iface.actionOpenStatisticalSummary(), self.toolboxAction)
        self.menu.addAction(self.toolboxAction)

        self.modelerAction = QAction(
            QgsApplication.getThemeIcon("/processingModel.svg"),
            QCoreApplication.translate('ProcessingPlugin', 'Graphical &Modeler…'), self.iface.mainWindow())
        self.modelerAction.setObjectName('modelerAction')
        self.modelerAction.triggered.connect(self.openModeler)
        self.iface.registerMainWindowAction(self.modelerAction,
                                            QKeySequence('Ctrl+Alt+M').toString(QKeySequence.NativeText))
        self.menu.addAction(self.modelerAction)

        self.historyAction = QAction(
            QgsApplication.getThemeIcon("/mIconHistory.svg"),
            QCoreApplication.translate('ProcessingPlugin', '&History…'), self.iface.mainWindow())
        self.historyAction.setObjectName('historyAction')
        self.historyAction.triggered.connect(self.openHistory)
        self.iface.registerMainWindowAction(self.historyAction,
                                            QKeySequence('Ctrl+Alt+H').toString(QKeySequence.NativeText))
        self.menu.addAction(self.historyAction)
        self.toolbox.processingToolbar.addAction(self.historyAction)

        self.resultsAction = QAction(
            QgsApplication.getThemeIcon("/processingResult.svg"),
            self.tr('&Results Viewer'), self.iface.mainWindow())
        self.resultsAction.setCheckable(True)
        self.iface.registerMainWindowAction(self.resultsAction,
                                            QKeySequence('Ctrl+Alt+R').toString(QKeySequence.NativeText))

        self.menu.addAction(self.resultsAction)
        self.toolbox.processingToolbar.addAction(self.resultsAction)
        self.resultsDock.visibilityChanged.connect(self.resultsAction.setChecked)
        self.resultsAction.toggled.connect(self.resultsDock.setUserVisible)

        self.toolbox.processingToolbar.addSeparator()

        self.editInPlaceAction = QAction(
            QgsApplication.getThemeIcon("/mActionProcessSelected.svg"),
            self.tr('Edit Features In-Place'), self.iface.mainWindow())
        self.editInPlaceAction.setObjectName('editInPlaceFeatures')
        self.editInPlaceAction.setCheckable(True)
        self.editInPlaceAction.toggled.connect(self.editSelected)
        self.menu.addAction(self.editInPlaceAction)
        self.toolbox.processingToolbar.addAction(self.editInPlaceAction)

        self.toolbox.processingToolbar.addSeparator()

        self.optionsAction = QAction(
            QgsApplication.getThemeIcon("/mActionOptions.svg"),
            self.tr('Options'), self.iface.mainWindow())
        self.optionsAction.setObjectName('optionsAction')
        self.optionsAction.triggered.connect(self.openProcessingOptions)
        self.toolbox.processingToolbar.addAction(self.optionsAction)

        menuBar = self.iface.mainWindow().menuBar()
        menuBar.insertMenu(
            self.iface.firstRightStandardMenu().menuAction(), self.menu)

        self.menu.addSeparator()

        initializeMenus()
        createMenus()

        # In-place editing button state sync
        self.iface.currentLayerChanged.connect(self.sync_in_place_button_state)
        self.iface.mapCanvas().selectionChanged.connect(self.sync_in_place_button_state)
        self.iface.actionToggleEditing().triggered.connect(partial(self.sync_in_place_button_state, None))
        self.sync_in_place_button_state()

    def sync_in_place_button_state(self, layer=None):
        """Synchronise the button state with layer state"""

        if layer is None:
            layer = self.iface.activeLayer()

        old_enabled_state = self.editInPlaceAction.isEnabled()

        new_enabled_state = layer is not None and layer.type() == QgsMapLayerType.VectorLayer
        self.editInPlaceAction.setEnabled(new_enabled_state)

        if new_enabled_state != old_enabled_state:
            self.toolbox.set_in_place_edit_mode(new_enabled_state and self.editInPlaceAction.isChecked())

    def openProcessingOptions(self):
        self.iface.showOptionsDialog(self.iface.mainWindow(), currentPage='processingOptions')

    def unload(self):
        self.toolbox.setVisible(False)
        self.iface.removeDockWidget(self.toolbox)
        self.iface.attributesToolBar().removeAction(self.toolboxAction)

        self.resultsDock.setVisible(False)
        self.iface.removeDockWidget(self.resultsDock)

        self.toolbox.deleteLater()
        self.menu.deleteLater()

        # delete temporary output files
        folder = QgsProcessingUtils.tempFolder()
        if QDir(folder).exists():
            shutil.rmtree(folder, True)

        # also delete temporary help files
        folder = tempHelpFolder()
        if QDir(folder).exists():
            shutil.rmtree(folder, True)

        self.iface.unregisterMainWindowAction(self.toolboxAction)
        self.iface.unregisterMainWindowAction(self.modelerAction)
        self.iface.unregisterMainWindowAction(self.historyAction)
        self.iface.unregisterMainWindowAction(self.resultsAction)

        self.iface.unregisterOptionsWidgetFactory(self.options_factory)
        self.iface.deregisterLocatorFilter(self.locator_filter)
        self.iface.deregisterLocatorFilter(self.edit_features_locator_filter)
        self.iface.unregisterCustomDropHandler(self.drop_handler)
        QgsApplication.dataItemProviderRegistry().removeProvider(self.item_provider)

        removeMenus()
        Processing.deinitialize()

    def openToolbox(self, show):
        self.toolbox.setUserVisible(show)

    def toolboxVisibilityChanged(self, visible):
        self.toolboxAction.setChecked(visible)

    def openModeler(self):
        dlg = ModelerDialog()
        dlg.update_model.connect(self.updateModel)
        dlg.show()

    def updateModel(self):
        model_provider = QgsApplication.processingRegistry().providerById('model')
        model_provider.refreshAlgorithms()

    def openResults(self):
        if self.resultsDock.isVisible():
            self.resultsDock.hide()
        else:
            self.resultsDock.show()

    def openHistory(self):
        dlg = HistoryDialog()
        dlg.exec_()

    def tr(self, message):
        return QCoreApplication.translate('ProcessingPlugin', message)

    def editSelected(self, enabled):
        self.toolbox.set_in_place_edit_mode(enabled)
Beispiel #23
0
class OsCertificateStore:
    def __init__(self, iface):
        self.iface = iface
        self.action_setting = None
        self.action_about = None
        self.action_run = None
        if not self.is_supported():
            return

        # noinspection PyBroadException
        try:
            # noinspection PyPackageRequirements,PyUnresolvedReferences
            from .tests import testerplugin
            # noinspection PyUnresolvedReferences
            from qgistester.tests import addTestModule
            addTestModule(testerplugin, "OS Certificate Store")
        except:
            pass

    @staticmethod
    def log(msg, level=Qgis.Info):
        QgsMessageLog.logMessage(msg, "OS Certificate Store", level=level)

    @staticmethod
    def is_supported():
        """Check wether this plugin can run in this platform"""
        if platform == "linux" or platform == "linux2":
            # linux
            return False or TEST_ON_LINUX
        elif platform == "darwin":
            # OS X
            return False
        elif platform == "win32":
            # Windows...
            return True
        else:
            return False

    # noinspection PyPep8Naming
    def initGui(self):
        if not self.is_supported():
            return

        self.action_setting = QAction(
            self.tr("Import Windows intermediate certificate authorities "
                    "on startup"), self.iface.mainWindow())
        self.action_setting.setObjectName("enableoscertstore")
        self.action_setting.setCheckable(True)
        self.action_setting.setChecked(QgsSettings().value(SETTINGS_KEY +
                                                           '/import_enabled',
                                                           True,
                                                           type=bool))
        # noinspection PyUnresolvedReferences
        self.action_setting.changed.connect(self.setting_changed)
        self.iface.addPluginToMenu(self.tr("OS Certificate Store"),
                                   self.action_setting)

        icon_run = QIcon(os.path.dirname(__file__) + "/icons/certificate.svg")
        if QgsSettings().value(
                SETTINGS_KEY + '/import_successfully_run', True, type=bool) \
                or TEST_ON_LINUX:
            self.action_run = QAction(
                icon_run,
                self.tr(
                    "Reimport Windows intermediate certificate authorities"),
                self.iface.mainWindow())
            self.action_run.setObjectName("enableoscertstore")
            # noinspection PyUnresolvedReferences
            self.action_run.triggered.connect(partial(self.run_triggered,
                                                      True))
            self.iface.addPluginToMenu(self.tr("OS Certificate Store"),
                                       self.action_run)

        # noinspection PyArgumentList,PyCallByClass
        self.action_about = QAction(
            QgsApplication.getThemeIcon('/mActionHelpContents.svg'),
            "About...", self.iface.mainWindow())
        self.action_about.setObjectName("oscertstoreabout")
        # noinspection PyUnresolvedReferences
        self.action_about.triggered.connect(self.about_triggered)
        self.iface.addPluginToMenu(self.tr("OS Certificate Store"),
                                   self.action_about)

        # No toolbar and other menus
        # self.iface.addToolBarIcon(self.action)

        # Run on startup
        if QgsSettings().value(SETTINGS_KEY + '/import_enabled',
                               True,
                               type=bool):
            self.run_triggered(False)

    def unload(self):
        if not self.is_supported():
            return
        # noinspection PyBroadException
        try:
            # noinspection PyPackageRequirements,PyUnresolvedReferences
            from .tests import testerplugin
            # noinspection PyUnresolvedReferences
            from qgistester.tests import removeTestModule
            removeTestModule(testerplugin, self.tr("OS Certificate Store"))
        except:
            pass

        # noinspection PyBroadException
        try:
            # noinspection PyUnresolvedReferences
            from lessons import removeLessonsFolder
            folder = os.path.join(os.path.dirname(__file__), "_lessons")
            removeLessonsFolder(folder)
        except:
            pass

        self.iface.removePluginMenu(self.tr("OS Certificate Store"),
                                    self.action_about)
        self.iface.removePluginMenu(self.tr("OS Certificate Store"),
                                    self.action_setting)
        if self.action_run is not None:
            self.iface.removePluginMenu(self.tr("OS Certificate Store"),
                                        self.action_run)

    def setting_changed(self):
        if not self.is_supported():
            return
        self.log("Import at startup: %s" % self.action_setting.isChecked())
        QgsSettings().setValue(SETTINGS_KEY + '/import_enabled',
                               self.action_setting.isChecked())

    def run_triggered(self, notify):
        self.log("Importing intermediate certificates ...")
        try:
            from .certs_importer import run
            QgsSettings().setValue(SETTINGS_KEY + '/import_successfully_run',
                                   run(self))
            if notify:
                self.iface.messageBar().pushMessage(
                    self.tr("Success"),
                    self.tr("Intermediate certificates imported correctly "
                            "(see logs for details)."),
                    level=Qgis.Info)
        except Exception as ex:
            self.log("Error importing intermediate certificates: %s" % ex)
            QgsSettings().setValue(SETTINGS_KEY + '/import_successfully_run',
                                   False)
            if notify:
                self.iface.messageBar().pushMessage(
                    self.tr("Error"),
                    self.tr("There was an error importing intermediate "
                            "certificates (see the logs for details)."),
                    level=Qgis.Critical)

    def about_triggered(self):
        # noinspection PyArgumentList
        dlg = QgsMessageOutput.createMessageOutput()
        dlg.setTitle(self.tr("Plugin info"))
        dlg.setMessage(self._plugin_details("oscertstore"),
                       QgsMessageOutput.MessageHtml)
        dlg.showMessage()

    @staticmethod
    def tr(msg):
        return msg

    # noinspection PyUnusedLocal
    def _plugin_details(self, namespace):
        config = DictParser()
        config.read_file(
            open(
                os.path.join(os.path.realpath(os.path.dirname(__file__)),
                             'metadata.txt')))
        plugin = config.as_dict()['general']

        html = '<style>body, table {padding:0px; margin:0px; ' \
               'font-family:verdana; font-size: 1.1em;}</style>'
        html += '<body>'
        html += '<table cellspacing="4" width="100%"><tr><td>'
        html += '<h1>{}</h1>'.format(plugin.get('name'))
        html += '<h3>{}</h3>'.format(plugin.get('description'))

        if plugin.get('about'):
            html += plugin.get('about').replace('\n', '<br/>')

        html += '<br/><br/>'

        if plugin.get('category'):
            html += '{}: {} <br/>'.format(self.tr('Category'),
                                          plugin.get('category'))

        if plugin.get('tags'):
            html += '{}: {} <br/>'.format(self.tr('Tags'), plugin.get('tags'))

        if (plugin.get('homepage') or plugin.get('tracker')
                or plugin.get('code_repository')):
            html += self.tr('More info:')

            if plugin.get('homepage'):
                html += '<a href="{}">{}</a> &nbsp;'.format(
                    plugin.get('homepage'), self.tr('homepage'))

            if plugin.get('tracker'):
                html += '<a href="{}">{}</a> &nbsp;'.format(
                    plugin.get('tracker'), self.tr('bug_tracker'))

            if plugin.get('code_repository'):
                html += '<a href="{}">{}</a> &nbsp;'.format(
                    plugin.get('code_repository'), self.tr('code_repository'))

            html += '<br/>'

        html += '<br/>'

        if plugin.get('author_email'):
            html += '{}: <a href="mailto:{}">{}</a>'.format(
                self.tr('Author email'), plugin.get('author_email'),
                plugin.get('author_name'))
            html += '<br/><br/>'
        elif plugin.get('author'):
            html += '{}: {}'.format(self.tr('Author'), plugin.get('author'))
            html += '<br/><br/>'

        if plugin.get('version_installed'):
            ver = plugin.get('version_installed')
            if ver == '-1':
                ver = '?'

            html += self.tr('Installed version: {} (in {})<br/>'.format(
                ver, plugin.get('library')))

        if plugin.get('version_available'):
            html += self.tr('Available version: {} (in {})<br/>'.format(
                plugin.get('version_available'), plugin.get('zip_repository')))

        if plugin.get('changelog'):
            html += '<br/>'
            changelog = self.tr('Changelog:<br/>{} <br/>'.format(
                plugin.get('changelog')))
            html += changelog.replace('\n', '<br/>')

        html += '</td></tr></table>'
        html += '</body>'

        return html
Beispiel #24
0
    def add_action(self,
                   name,
                   icon_path,
                   text,
                   callback,
                   toggle_flag=False,
                   enabled_flag=True,
                   checkable_flag=False,
                   visible_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 name: Objectname of the action. Serves also as key for the stored actions.
        :type name: str

        :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 toggle_flag: A flag indicating if the action should connect
            the toggled or triggered signal by default.
            Defaults to triggered (False)
        :type toggle_flag: bool

        :param checkable_flag: A flag indicating if the action should be checkable
            by default. Defaults to False.
        :type checkable: bool

        :param visible_flag: A flag indicating if the action should be displayed
            by default. Defaults to True.
        :type visible: 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.setObjectName(name)
        if toggle_flag:
            action.toggled.connect(callback)
        else:
            action.triggered.connect(callback)
        action.setEnabled(enabled_flag)
        action.setCheckable(checkable_flag)
        action.setVisible(visible_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[name] = action

        return action
Beispiel #25
0
class AreaRatio:
    """QGIS Plugin to calculate area ratio among polygons"""
    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')
        if not locale:
            locale = QSettings().value('locale/globalLocale')
            if not locale:
                locale = "en"
        locale = locale[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)
        self.dlg = AreaRatioDialog(self)
        if os.path.exists(DEFAULT_CONFIG):
            parcel, buildings = self.config(DEFAULT_CONFIG)
        else:
            parcel, buildings = self.config(
                os.path.join(self.plugin_dir, 'default.cfg'))
        self.parcel = parcel
        self.buildings = buildings

    # 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('AreaRatio', message)

    def config(self, path):
        """ load default configuration (layers) """
        parcel = 'TELEK'
        buildings = [
            "Lakóépület", "Középület", "Gazdasági épület", "Melléképület",
            "Üdülőépület", "Toronyépület", "Üzemi épület",
            "Vegyes rendeltetésű épület"
        ]
        parser = configparser.ConfigParser()
        if not os.path.exists(path):
            QMessageBox.warning(
                None, self.tr("Missing file"),
                self.tr("Config file not found: {}").format(path))
            return parcel, buildings
        try:
            parser.read(path)
        except:
            QMessageBox.warning(
                None, self.tr("Error in file"),
                self.tr("Config file is not valid: {}").format(path))
            return parcel, buildings
        for section in parser.sections():
            if section == "layers":
                parcel = parser[section].get('parcel', parcel)
                w = parser[section].get('buildings')
                if len(w) > 0:
                    buildings = [name.strip() for name in w.split(',')]
        return parcel, buildings

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        icon_path = ':/plugins/arearatio/icon.png'
        self.action = QAction(QIcon(icon_path), self.tr(u'Area Ratio'),
                              self.iface.mainWindow())
        self.action.setCheckable(True)
        self.action.triggered.connect(self.run)
        self.iface.addToolBarIcon(self.action)
        self.iface.addPluginToMenu(u'Area Ratio', self.action)
        self.tool = PointTool(self.iface.mapCanvas(), self.action, self)
        # dialog
        icon_path = ':/plugins/arearatio/icon1.png'
        self.action1 = QAction(QIcon(icon_path), self.tr(u'Area Ratio Dialog'),
                               self.iface.mainWindow())
        self.action1.triggered.connect(self.dia)
        self.iface.addToolBarIcon(self.action1)
        self.iface.addPluginToMenu(u'Area Ratio', self.action1)

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        self.iface.removePluginMenu(u'Area Ratio', self.action)
        self.iface.removePluginMenu(u'Area Ratio', self.action1)
        self.iface.removeToolBarIcon(self.action)
        self.iface.removeToolBarIcon(self.action1)

    def run(self):
        """ Activate map tool """
        self.iface.mapCanvas().setMapTool(self.tool)

    def dia(self):
        """Show layer selection dialog"""
        self.dlg.show()
        result = self.dlg.exec_()
        if result:
            index = self.dlg.parcelLayerComboBox.currentIndex()
            self.parcel = self.dlg.parcelLayerComboBox.itemText(index)
            #self.tool.poly_layer_name = self.dlg.parcelLayerComboBox.currentText()
            #self.tool.in_poly_layers = [name.strip() for name
            #        in self.dlg.buildingsComboBox.currentText().split(',')]
            self.buildings = self.dlg.buildingsComboBox.checkedItems()
            # force index creation
            self.tool.index = None
Beispiel #26
0
class ShapeTools(object):
    def __init__(self, iface):
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.settingsDialog = None
        self.xyLineDialog = None
        self.geodesicDensifyDialog = None
        self.azDigitizerTool = None
        self.lineDigitizerTool = None
        self.previousLayer = None
        self.toolbar = self.iface.addToolBar('Shape Tools Toolbar')
        self.toolbar.setObjectName('ShapeToolsToolbar')
        self.provider = ShapeToolsProvider()
        # Initialize the plugin path directory
        self.plugin_dir = os.path.dirname(__file__)

        # initialize locale
        try:
            locale = QSettings().value("locale/userLocale", "en",
                                       type=str)[0:2]
        except Exception:
            locale = "en"
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'shapeTools_{}.qm'.format(locale))
        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)
            QCoreApplication.installTranslator(self.translator)

    def initGui(self):
        self.azDigitizerTool = AzDigitizerTool(self.iface)
        self.lineDigitizerTool = LineDigitizerTool(self.iface)

        # Initialize the create shape menu items
        menu = QMenu()
        # Initialize Create Arc Wedge tool
        icon = QIcon(self.plugin_dir + '/images/arc.png')
        self.createArcAction = menu.addAction(icon, tr('Create arc wedge'),
                                              self.createArc)
        self.createArcAction.setObjectName('stCreateArcWedge')
        icon = QIcon(self.plugin_dir + '/images/donut.png')
        self.createDonutAction = menu.addAction(icon, tr('Create donut'),
                                                self.createDonut)
        self.createDonutAction.setObjectName('stCreateDonut')
        icon = QIcon(self.plugin_dir + '/images/ellipse.png')
        self.createEllipseAction = menu.addAction(icon, tr('Create ellipse'),
                                                  self.createEllipse)
        self.createEllipseAction.setObjectName('stCreateEllipse')
        icon = QIcon(self.plugin_dir + '/images/rose.png')
        self.createEllipseRoseAction = menu.addAction(
            icon, tr('Create ellipse rose'), self.createEllipseRose)
        self.createEllipseRoseAction.setObjectName('stCreateEllipseRose')
        icon = QIcon(self.plugin_dir + '/images/epicycloid.png')
        self.createEpicycloidAction = menu.addAction(icon,
                                                     tr('Create epicycloid'),
                                                     self.createEpicycloid)
        self.createEpicycloidAction.setObjectName('stCreateEpicycloid')
        icon = QIcon(self.plugin_dir + '/images/heart.png')
        self.createHeartAction = menu.addAction(icon, tr('Create heart'),
                                                self.createHeart)
        self.createHeartAction.setObjectName('stCreateHeart')
        icon = QIcon(self.plugin_dir + '/images/hypocycloid.png')
        self.createHypocycloidAction = menu.addAction(icon,
                                                      tr('Create hypocycloid'),
                                                      self.createHypocycloid)
        self.createHypocycloidAction.setObjectName('stCreateHypocycloid')
        icon = QIcon(self.plugin_dir + '/images/line.png')
        self.createLOBAction = menu.addAction(icon,
                                              tr('Create line of bearing'),
                                              self.createLOB)
        self.createLOBAction.setObjectName('stCreateLineOfBearing')
        icon = QIcon(self.plugin_dir + '/images/pie.png')
        self.createPieAction = menu.addAction(icon, tr('Create pie wedge'),
                                              self.createPie)
        self.createPieAction.setObjectName('stCreatePie')
        icon = QIcon(self.plugin_dir + '/images/polyfoil.png')
        self.createPolyfoilAction = menu.addAction(icon, tr('Create polyfoil'),
                                                   self.createPolyfoil)
        self.createPolyfoilAction.setObjectName('stCreatePolyfoil')
        icon = QIcon(self.plugin_dir + '/images/polygon.png')
        self.createPolygonAction = menu.addAction(icon, tr('Create polygon'),
                                                  self.createPolygon)
        self.createPolygonAction.setObjectName('stCreatePolygon')
        icon = QIcon(self.plugin_dir + '/images/radialLines.png')
        self.createPolygonAction = menu.addAction(icon,
                                                  tr('Create radial lines'),
                                                  self.createRadialLines)
        self.createPolygonAction.setObjectName('stCreateRadialLines')
        icon = QIcon(self.plugin_dir + '/images/star.png')
        self.createStarAction = menu.addAction(icon, tr('Create star'),
                                               self.createStar)
        self.createStarAction.setObjectName('stCreateStar')
        # Add the shape creation tools to the menu
        icon = QIcon(self.plugin_dir + '/images/shapes.png')
        self.createShapesAction = QAction(icon, tr('Create shapes'),
                                          self.iface.mainWindow())
        self.createShapesAction.setMenu(menu)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.createShapesAction)
        # Add the shape creation tools to the toolbar
        self.createShapeButton = QToolButton()
        self.createShapeButton.setMenu(menu)
        self.createShapeButton.setDefaultAction(self.createDonutAction)
        self.createShapeButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.createShapeButton.triggered.connect(self.createShapeTriggered)
        self.createShapeToolbar = self.toolbar.addWidget(
            self.createShapeButton)

        # Initialize the XY to Line menu item
        icon = QIcon(self.plugin_dir + '/images/xyline.svg')
        self.xyLineAction = QAction(icon, tr('XY to line'),
                                    self.iface.mainWindow())
        self.xyLineAction.setObjectName('stXYtoLine')
        self.xyLineAction.triggered.connect(self.xyLineTool)
        self.iface.addPluginToVectorMenu('Shape Tools', self.xyLineAction)
        self.toolbar.addAction(self.xyLineAction)

        # Initialize the Geodesic Densifier menu item
        icon = QIcon(self.plugin_dir + '/images/geodesicDensifier.svg')
        self.geodesicDensifyAction = QAction(icon,
                                             tr('Geodesic shape densifier'),
                                             self.iface.mainWindow())
        self.geodesicDensifyAction.setObjectName('stGeodesicDensifier')
        self.geodesicDensifyAction.triggered.connect(self.geodesicDensifyTool)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.geodesicDensifyAction)
        self.toolbar.addAction(self.geodesicDensifyAction)

        # Initialize the Geodesic decimation menu items
        menu = QMenu()
        icon = QIcon(self.plugin_dir + '/images/geodesicLineDecimate.svg')
        self.lineDecimateAction = menu.addAction(icon,
                                                 tr('Geodesic line decimate'),
                                                 self.lineDecimateTool)
        self.lineDecimateAction.setObjectName('stGeodesicLineDecimate')
        icon = QIcon(self.plugin_dir + '/images/geodesicPointDecimate.svg')
        self.pointDecimateAction = menu.addAction(
            icon, tr('Geodesic point decimate'), self.pointDecimateTool)
        self.pointDecimateAction.setObjectName('stGeodesicPointDecimate')
        # Add the decimation tools to the menu
        icon = QIcon(self.plugin_dir + '/images/geodesicLineDecimate.svg')
        self.simplifyGeomAction = QAction(
            icon, tr('Geodesic geometry simplification'),
            self.iface.mainWindow())
        self.simplifyGeomAction.setMenu(menu)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.simplifyGeomAction)
        # Add the shape creation tools to the toolbar
        self.simplifyButton = QToolButton()
        self.simplifyButton.setMenu(menu)
        self.simplifyButton.setDefaultAction(self.lineDecimateAction)
        self.simplifyButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.simplifyButton.triggered.connect(self.simplifyTriggered)
        self.simplifyToolbar = self.toolbar.addWidget(self.simplifyButton)

        # Initialize the Geodesic line break menu item
        icon = QIcon(self.plugin_dir + '/images/idlbreak.svg')
        self.geodesicLineBreakAction = QAction(
            icon, tr('Geodesic line break at -180,180'),
            self.iface.mainWindow())
        self.geodesicLineBreakAction.setObjectName('stGeodesicLineBreak')
        self.geodesicLineBreakAction.triggered.connect(
            self.geodesicLineBreakTool)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.geodesicLineBreakAction)
        self.toolbar.addAction(self.geodesicLineBreakAction)

        # Initialize Geodesic Measure Tool
        self.geodesicMeasureTool = GeodesicMeasureTool(self.iface,
                                                       self.iface.mainWindow())
        icon = QIcon(self.plugin_dir + '/images/measure.svg')
        self.measureAction = QAction(icon, tr('Geodesic measure tool'),
                                     self.iface.mainWindow())
        self.measureAction.setObjectName('stGeodesicMeasureTool')
        self.measureAction.triggered.connect(self.measureTool)
        self.measureAction.setCheckable(True)
        self.iface.addPluginToVectorMenu('Shape Tools', self.measureAction)
        self.toolbar.addAction(self.measureAction)

        # Initialize Geodesic Measurement layer
        icon = QIcon(self.plugin_dir + '/images/measureLine.svg')
        self.measureLayerAction = QAction(icon,
                                          tr('Geodesic measurement layer'),
                                          self.iface.mainWindow())
        self.measureLayerAction.setObjectName('stGeodesicLineBreak')
        self.measureLayerAction.triggered.connect(self.measureLayerTool)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.measureLayerAction)
        self.toolbar.addAction(self.measureLayerAction)

        menu = QMenu()
        # Initialize Geodesic transformation tool
        icon = QIcon(self.plugin_dir + '/images/transformShape.svg')
        self.transformationsAction = menu.addAction(
            icon, tr('Geodesic transformations'), self.transformTool)
        self.transformationsAction.setObjectName('stGeodesicTransformations')

        icon = QIcon(self.plugin_dir + '/images/flip.svg')
        self.flipRotateAction = menu.addAction(icon,
                                               tr('Geodesic flip and rotate'),
                                               self.flipRotateTool)
        self.flipRotateAction.setObjectName('stGeodesicFlipRotate')

        icon = QIcon(self.plugin_dir + '/images/flipHorizontal.svg')
        self.flipHorizontalAction = menu.addAction(icon, tr('Flip horizontal'),
                                                   self.flipHorizontalTool)
        self.flipHorizontalAction.setObjectName('stGeodesicFlipHorizontal')
        self.flipHorizontalAction.setEnabled(False)
        icon = QIcon(self.plugin_dir + '/images/flipVertical.svg')
        self.flipVerticalAction = menu.addAction(icon, tr('Flip vertical'),
                                                 self.flipVerticalTool)
        self.flipVerticalAction.setObjectName('stGeodesicFlipVertical')
        self.flipVerticalAction.setEnabled(False)
        icon = QIcon(self.plugin_dir + '/images/rotate180.svg')
        self.rotate180Action = menu.addAction(icon, tr('Rotate 180\xb0'),
                                              self.rotate180Tool)
        self.rotate180Action.setObjectName('stGeodesicRotate180')
        self.rotate180Action.setEnabled(False)
        icon = QIcon(self.plugin_dir + '/images/rotatecw.svg')
        self.rotate90CWAction = menu.addAction(icon, tr('Rotate 90\xb0 CW'),
                                               self.rotate90CWTool)
        self.rotate90CWAction.setObjectName('stGeodesicRotate90CW')
        self.rotate90CWAction.setEnabled(False)
        icon = QIcon(self.plugin_dir + '/images/rotateccw.svg')
        self.rotate90CCWAction = menu.addAction(icon, tr('Rotate 90\xb0 CCW'),
                                                self.rotate90CCWTool)
        self.rotate90CCWAction.setObjectName('stGeodesicRotate90CCW')
        self.rotate90CCWAction.setEnabled(False)
        self.transformsAction = QAction(icon, tr('Geodesic transforms'),
                                        self.iface.mainWindow())
        self.transformsAction.setMenu(menu)
        self.iface.addPluginToVectorMenu('Shape Tools', self.transformsAction)

        self.transformationButton = QToolButton()
        self.transformationButton.setMenu(menu)
        self.transformationButton.setDefaultAction(self.transformationsAction)
        self.transformationButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.transformationButton.triggered.connect(self.toolButtonTriggered)
        self.tranformToolbar = self.toolbar.addWidget(
            self.transformationButton)

        # Initialize the Azimuth Distance Digitize function
        icon = QIcon(self.plugin_dir + '/images/dazdigitize.svg')
        self.digitizeAction = QAction(icon, tr('Azimuth distance digitizer'),
                                      self.iface.mainWindow())
        self.digitizeAction.setObjectName('stAzDistanceDigitizer')
        self.digitizeAction.triggered.connect(self.setShowAzDigitizerTool)
        self.digitizeAction.setCheckable(True)
        self.digitizeAction.setEnabled(False)
        self.iface.addPluginToVectorMenu(u'Shape Tools', self.digitizeAction)
        self.toolbar.addAction(self.digitizeAction)

        # Initialize the multi point azimuth Digitize function
        icon = QIcon(self.plugin_dir + '/images/linedigitize.svg')
        self.lineDigitizeAction = QAction(
            icon, tr('Azimuth distance sequence digitizer'),
            self.iface.mainWindow())
        self.lineDigitizeAction.setObjectName('stLineDigitizer')
        self.lineDigitizeAction.triggered.connect(self.setShowLineDigitizeTool)
        self.lineDigitizeAction.setCheckable(True)
        self.lineDigitizeAction.setEnabled(False)
        self.iface.addPluginToVectorMenu(u'Shape Tools',
                                         self.lineDigitizeAction)
        self.toolbar.addAction(self.lineDigitizeAction)

        # Settings
        icon = QIcon(':/images/themes/default/mActionOptions.svg')
        self.settingsAction = QAction(icon, tr('Settings'),
                                      self.iface.mainWindow())
        self.settingsAction.setObjectName('shapeToolsSettings')
        self.settingsAction.triggered.connect(self.settings)
        self.iface.addPluginToVectorMenu('Shape Tools', self.settingsAction)

        # Help
        icon = QIcon(self.plugin_dir + '/images/help.svg')
        self.helpAction = QAction(icon, tr('Shape Tools help'),
                                  self.iface.mainWindow())
        self.helpAction.setObjectName('shapeToolsHelp')
        self.helpAction.triggered.connect(self.help)
        self.iface.addPluginToVectorMenu('Shape Tools', self.helpAction)

        self.iface.currentLayerChanged.connect(self.currentLayerChanged)
        self.canvas.mapToolSet.connect(self.unsetTool)
        self.enableTools()

        # Add the processing provider
        QgsApplication.processingRegistry().addProvider(self.provider)

    def unsetTool(self, tool):
        try:
            if not isinstance(tool, GeodesicMeasureTool):
                self.measureAction.setChecked(False)
                self.geodesicMeasureTool.endInteractiveLine()
            if not isinstance(tool, AzDigitizerTool):
                self.digitizeAction.setChecked(False)
            if not isinstance(tool, LineDigitizerTool):
                self.lineDigitizeAction.setChecked(False)
        except Exception:
            pass

    def unload(self):
        self.canvas.unsetMapTool(self.azDigitizerTool)
        self.canvas.unsetMapTool(self.lineDigitizerTool)

        # remove from menu
        self.iface.removePluginVectorMenu('Shape Tools',
                                          self.createShapesAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.xyLineAction)
        self.iface.removePluginVectorMenu('Shape Tools',
                                          self.geodesicDensifyAction)
        self.iface.removePluginVectorMenu('Shape Tools',
                                          self.simplifyGeomAction)
        self.iface.removePluginVectorMenu('Shape Tools',
                                          self.geodesicLineBreakAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.measureAction)
        self.iface.removePluginVectorMenu('Shape Tools',
                                          self.measureLayerAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.transformsAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.digitizeAction)
        self.iface.removePluginVectorMenu('Shape Tools',
                                          self.lineDigitizeAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.settingsAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.helpAction)
        # Remove from toolbar
        self.iface.removeToolBarIcon(self.createShapeToolbar)
        self.iface.removeToolBarIcon(self.xyLineAction)
        self.iface.removeToolBarIcon(self.geodesicDensifyAction)
        self.iface.removeToolBarIcon(self.simplifyToolbar)
        self.iface.removeToolBarIcon(self.geodesicLineBreakAction)
        self.iface.removeToolBarIcon(self.measureAction)
        self.iface.removeToolBarIcon(self.measureLayerAction)
        self.iface.removeToolBarIcon(self.transformationsAction)
        self.iface.removeToolBarIcon(self.digitizeAction)
        self.iface.removeToolBarIcon(self.lineDigitizeAction)
        self.iface.removeToolBarIcon(self.tranformToolbar)
        self.azDigitizerTool = None
        self.lineDigitizerTool = None
        # remove the toolbar
        del self.toolbar

        QgsApplication.processingRegistry().removeProvider(self.provider)

    def toolButtonTriggered(self, action):
        self.transformationButton.setDefaultAction(action)

    def createShapeTriggered(self, action):
        self.createShapeButton.setDefaultAction(action)

    def simplifyTriggered(self, action):
        self.simplifyButton.setDefaultAction(action)

    def setShowAzDigitizerTool(self):
        self.digitizeAction.setChecked(True)
        self.canvas.setMapTool(self.azDigitizerTool)

    def setShowLineDigitizeTool(self):
        self.lineDigitizeAction.setChecked(True)
        self.canvas.setMapTool(self.lineDigitizerTool)

    def xyLineTool(self):
        processing.execAlgorithmDialog('shapetools:xy2line', {})

    def geodesicDensifyTool(self):
        processing.execAlgorithmDialog('shapetools:geodesicdensifier', {})

    def pointDecimateTool(self):
        processing.execAlgorithmDialog('shapetools:geodesicpointdecimate', {})

    def lineDecimateTool(self):
        processing.execAlgorithmDialog('shapetools:geodesiclinedecimate', {})

    def geodesicLineBreakTool(self):
        processing.execAlgorithmDialog('shapetools:linebreak', {})

    def measureTool(self):
        self.measureAction.setChecked(True)
        self.canvas.setMapTool(self.geodesicMeasureTool)

    def createArc(sefl):
        processing.execAlgorithmDialog('shapetools:createarc', {})

    def createDonut(sefl):
        processing.execAlgorithmDialog('shapetools:createdonut', {})

    def createEllipse(sefl):
        processing.execAlgorithmDialog('shapetools:createellipse', {})

    def createEllipseRose(sefl):
        processing.execAlgorithmDialog('shapetools:createrose', {})

    def createEpicycloid(sefl):
        processing.execAlgorithmDialog('shapetools:createepicycloid', {})

    def createHeart(sefl):
        processing.execAlgorithmDialog('shapetools:createheart', {})

    def createHypocycloid(sefl):
        processing.execAlgorithmDialog('shapetools:createhypocycloid', {})

    def createLOB(sefl):
        processing.execAlgorithmDialog('shapetools:createlob', {})

    def createPie(sefl):
        processing.execAlgorithmDialog('shapetools:createpie', {})

    def createPolyfoil(sefl):
        processing.execAlgorithmDialog('shapetools:createpolyfoil', {})

    def createPolygon(sefl):
        processing.execAlgorithmDialog('shapetools:createpolygon', {})

    def createRadialLines(sefl):
        processing.execAlgorithmDialog('shapetools:createradiallines', {})

    def createStar(sefl):
        processing.execAlgorithmDialog('shapetools:createstar', {})

    def measureLayerTool(self):
        processing.execAlgorithmDialog('shapetools:measurelayer', {})

    def transformTool(self):
        processing.execAlgorithmDialog('shapetools:geodesictransformations',
                                       {})

    def flipRotateTool(self):
        processing.execAlgorithmDialog('shapetools:geodesicflip', {})

    def flipHorizontalTool(self):
        layer = self.iface.activeLayer()
        flipLayer(self.iface, layer, 0)

    def flipVerticalTool(self):
        layer = self.iface.activeLayer()
        flipLayer(self.iface, layer, 1)

    def rotate180Tool(self):
        layer = self.iface.activeLayer()
        flipLayer(self.iface, layer, 2)

    def rotate90CWTool(self):
        layer = self.iface.activeLayer()
        flipLayer(self.iface, layer, 3)

    def rotate90CCWTool(self):
        layer = self.iface.activeLayer()
        flipLayer(self.iface, layer, 4)

    def settings(self):
        if self.settingsDialog is None:
            self.settingsDialog = SettingsWidget(self.iface,
                                                 self.iface.mainWindow())
        self.settingsDialog.show()

    def help(self):
        '''Display a help page'''
        url = QUrl.fromLocalFile(self.plugin_dir + '/index.html').toString()
        webbrowser.open(url, new=2)

    def currentLayerChanged(self):
        layer = self.iface.activeLayer()
        if self.previousLayer is not None:
            try:
                self.previousLayer.editingStarted.disconnect(
                    self.layerEditingChanged)
            except Exception:
                pass
            try:
                self.previousLayer.editingStopped.disconnect(
                    self.layerEditingChanged)
            except Exception:
                pass
        self.previousLayer = None
        if layer is not None:
            if isinstance(layer, QgsVectorLayer):
                layer.editingStarted.connect(self.layerEditingChanged)
                layer.editingStopped.connect(self.layerEditingChanged)
                self.previousLayer = layer
        self.enableTools()

    def layerEditingChanged(self):
        self.enableTools()

    def enableTools(self):
        self.digitizeAction.setEnabled(False)
        self.lineDigitizeAction.setEnabled(False)
        self.flipHorizontalAction.setEnabled(False)
        self.flipVerticalAction.setEnabled(False)
        self.rotate180Action.setEnabled(False)
        self.rotate90CWAction.setEnabled(False)
        self.rotate90CCWAction.setEnabled(False)
        layer = self.iface.activeLayer()

        if not layer or not layer.isValid() or (
                layer.type() !=
                QgsMapLayer.VectorLayer) or not layer.isEditable():
            return
        wkbtype = layer.wkbType()
        geomtype = QgsWkbTypes.geometryType(wkbtype)
        self.lineDigitizeAction.setEnabled(True)
        if geomtype == QgsWkbTypes.PointGeometry or geomtype == QgsWkbTypes.LineGeometry:
            self.digitizeAction.setEnabled(True)
        if geomtype == QgsWkbTypes.LineGeometry or geomtype == QgsWkbTypes.PolygonGeometry:
            self.flipHorizontalAction.setEnabled(True)
            self.flipVerticalAction.setEnabled(True)
            self.rotate180Action.setEnabled(True)
            self.rotate90CWAction.setEnabled(True)
            self.rotate90CCWAction.setEnabled(True)
Beispiel #27
0
class RelationEditorFeatureSideWidget(QgsAbstractRelationEditorWidget,
                                      WidgetUi):
    class LastView(str, Enum):
        ListView = "ListView"
        IconView = "IconView"

    settingsLastView = QgsSettingsEntryString(
        'relationEditorFeatureSideLastView', PluginHelper.PLUGIN_SLUG,
        LastView.ListView,
        PluginHelper.tr(
            'Last view used in the relation editor document side widget'))

    signalCurrentViewChanged = pyqtSignal()

    def __init__(self, config, parent):
        super().__init__(config, parent)
        self._updateUiTimer = QTimer()
        self._updateUiTimer.setSingleShot(True)
        self._updateUiTimer.timeout.connect(self.updateUiTimeout)
        self.setupUi(self)

        print('DocumentRelationEditorFeatureSideWidget.__init__')

        self.documents_path = str()
        self.document_filename = str()

        self.model = DocumentModel()

        self._nmRelation = QgsRelation()
        self._layerInSameTransactionGroup = False

        self._currentDocumentId = None

        # Actions
        self.actionToggleEditing = QAction(
            QIcon(":/images/themes/default/mActionToggleEditing.svg"),
            self.tr("Toggle editing mode for child layers"))
        self.actionToggleEditing.setCheckable(True)
        self.actionSaveEdits = QAction(
            QIcon(":/images/themes/default/mActionSaveEdits.svg"),
            self.tr("Save child layer edits"))
        self.actionShowForm = QAction(
            QIcon(":/images/themes/default/mActionMultiEdit.svg"),
            self.tr("Show form"))
        self.actionAddFeature = QAction(
            QIcon(":/images/themes/default/symbologyAdd.svg"),
            self.tr("Add document"))
        self.actionDeleteFeature = QAction(
            QIcon(":/images/themes/default/mActionDeleteSelected.svg"),
            self.tr("Drop document"))
        self.actionLinkFeature = QAction(
            QIcon(":/images/themes/default/mActionLink.svg"),
            self.tr("Link document"))
        self.actionUnlinkFeature = QAction(
            QIcon(":/images/themes/default/mActionUnlink.svg"),
            self.tr("Unlink document"))

        # Tool buttons
        self.mToggleEditingToolButton.setDefaultAction(
            self.actionToggleEditing)
        self.mSaveEditsToolButton.setDefaultAction(self.actionSaveEdits)
        self.mShowFormToolButton.setDefaultAction(self.actionShowForm)
        self.mAddFeatureToolButton.setDefaultAction(self.actionAddFeature)
        self.mDeleteFeatureToolButton.setDefaultAction(
            self.actionDeleteFeature)
        self.mLinkFeatureToolButton.setDefaultAction(self.actionLinkFeature)
        self.mUnlinkFeatureToolButton.setDefaultAction(
            self.actionUnlinkFeature)

        self.mListViewToolButton.setIcon(
            QIcon(":/images/themes/default/mIconListView.svg"))
        self.mIconViewToolButton.setIcon(
            QIcon(":/images/themes/default/mActionIconView.svg"))
        self.mListViewToolButton.setChecked(self.currentView == str(
            RelationEditorFeatureSideWidget.LastView.ListView))
        self.mIconViewToolButton.setChecked(self.currentView == str(
            RelationEditorFeatureSideWidget.LastView.IconView))

        # Quick image providers
        self._previewImageProvider = PreviewImageProvider()
        self._fileTypeSmallIconProvider = FileTypeIconImageProvider(32)
        self._fileTypeBigIconProvider = FileTypeIconImageProvider(100)

        # Setup QML part
        self.view = QQuickWidget()
        self.view.rootContext().setContextProperty("documentModel", self.model)
        self.view.rootContext().setContextProperty("parentWidget", self)
        self.view.rootContext().setContextProperty(
            "CONST_LIST_VIEW",
            str(RelationEditorFeatureSideWidget.LastView.ListView))
        self.view.rootContext().setContextProperty(
            "CONST_ICON_VIEW",
            str(RelationEditorFeatureSideWidget.LastView.IconView))
        self.view.engine().addImageProvider("previewImageProvider",
                                            self._previewImageProvider)
        self.view.engine().addImageProvider("fileTypeSmallIconProvider",
                                            self._fileTypeSmallIconProvider)
        self.view.engine().addImageProvider("fileTypeBigIconProvider",
                                            self._fileTypeBigIconProvider)
        self.view.setSource(
            QUrl.fromLocalFile(
                os.path.join(os.path.dirname(__file__),
                             '../qml/DocumentList.qml')))
        self.view.setResizeMode(QQuickWidget.SizeRootObjectToView)
        self.layout().addWidget(self.view)

        # Set initial state for add / remove etc.buttons
        self.updateButtons()

        # Signal slots
        self.actionToggleEditing.triggered.connect(self.toggleEditing)
        self.actionSaveEdits.triggered.connect(self.saveChildLayerEdits)
        self.actionShowForm.triggered.connect(self.showDocumentForm)
        self.actionAddFeature.triggered.connect(self.addDocument)
        self.actionDeleteFeature.triggered.connect(self.dropDocument)
        self.actionLinkFeature.triggered.connect(self.linkDocument)
        self.actionUnlinkFeature.triggered.connect(self.unlinkDocument)
        self.mListViewToolButton.toggled.connect(
            self.listViewToolButtonToggled)
        self.mIconViewToolButton.toggled.connect(
            self.iconViewToolButtonToggled)

    @pyqtProperty(str)
    def currentView(self):
        return self.settingsLastView.value()

    def updateCurrentView(self):
        if self.mListViewToolButton.isChecked():
            self.settingsLastView.setValue(
                str(RelationEditorFeatureSideWidget.LastView.ListView))
        else:
            self.settingsLastView.setValue(
                str(RelationEditorFeatureSideWidget.LastView.IconView))

        self.signalCurrentViewChanged.emit()

    @pyqtProperty(QVariant)
    def currentDocumentId(self):
        return self._currentDocumentId

    @pyqtSlot(QVariant)
    def setCurrentDocumentId(self, value):
        self._currentDocumentId = value
        self.updateButtons()

    def nmRelation(self):
        return self._nmRelation

    def config(self):
        return {}

    def setConfig(self, config):
        self.documents_path = config['documents_path']
        self.document_filename = config['document_filename']

    def updateUi(self):
        self._updateUiTimer.start(200)

    def updateUiTimeout(self):
        self.model.init(self.relation(), self.nmRelation(), self.feature(),
                        self.documents_path, self.document_filename)

    def updateButtons(self):
        toggleEditingButtonEnabled = False
        editable = False
        linkable = False
        spatial = False
        selectionNotEmpty = self._currentDocumentId is not None

        if self.relation().isValid():
            toggleEditingButtonEnabled = self.relation().referencingLayer(
            ).supportsEditing()
            editable = self.relation().referencingLayer().isEditable()
            linkable = self.relation().referencingLayer().isEditable()
            spatial = self.relation().referencingLayer().isSpatial()

        if self.nmRelation().isValid():
            toggleEditingButtonEnabled |= self.nmRelation().referencedLayer(
            ).supportsEditing()
            editable = self.nmRelation().referencedLayer().isEditable()
            spatial = self.nmRelation().referencedLayer().isSpatial()

        self.mToggleEditingToolButton.setEnabled(toggleEditingButtonEnabled)
        self.mAddFeatureToolButton.setEnabled(editable)
        self.mLinkFeatureToolButton.setEnabled(linkable)
        self.mDeleteFeatureToolButton.setEnabled(editable
                                                 and selectionNotEmpty)
        self.mUnlinkFeatureToolButton.setEnabled(linkable
                                                 and selectionNotEmpty)
        self.mToggleEditingToolButton.setChecked(editable)
        self.mSaveEditsToolButton.setEnabled(editable or linkable)

        self.mShowFormToolButton.setEnabled(selectionNotEmpty)

        self.mToggleEditingToolButton.setVisible(
            self._layerInSameTransactionGroup is False)
        self.mSaveEditsToolButton.setVisible(
            self._layerInSameTransactionGroup is False)

    def afterSetRelations(self):
        self._nmRelation = QgsProject.instance().relationManager().relation(
            str(self.nmRelationId()))

        self._checkTransactionGroup()

        if self.relation().isValid():
            self.relation().referencingLayer().editingStopped.connect(
                self.updateButtons)
            self.relation().referencingLayer().editingStarted.connect(
                self.updateButtons)

        if self.nmRelation().isValid():
            self.nmRelation().referencedLayer().editingStarted.connect(
                self.updateButtons)
            self.nmRelation().referencedLayer().editingStopped.connect(
                self.updateButtons)

        self.updateButtons()

    def _checkTransactionGroup(self):

        self._layerInSameTransactionGroup = False
        connectionString = PluginHelper.connectionString(
            self.relation().referencedLayer().source())
        transactionGroup = QgsProject.instance().transactionGroup(
            self.relation().referencedLayer().providerType(), connectionString)

        if transactionGroup is None:
            return

        if self.nmRelation().isValid():
            if (self.relation().referencedLayer() in transactionGroup.layers()
                    and self.relation().referencingLayer()
                    in transactionGroup.layers()
                    and self.nmRelation().referencedLayer()
                    in transactionGroup.layers()):
                self._layerInSameTransactionGroup = True
        else:
            if (self.relation().referencedLayer() in transactionGroup.layers()
                    and self.relation().referencingLayer()
                    in transactionGroup.layers()):
                self._layerInSameTransactionGroup = True

    def parentFormValueChanged(self, attribute, newValue):
        pass

    def checkLayerEditingMode(self):

        if self.relation().referencingLayer().isEditable() is False:
            QMessageBox.critical(
                self, self.tr("Layer not editable"),
                self.tr("Layer '{0}' is not in editing mode.").format(
                    self.relation().referencingLayer().name()))
            return False

        if self.nmRelation().isValid():
            if self.nmRelation().referencedLayer().isEditable() is False:
                QMessageBox.critical(
                    self, self.tr("Layer not editable"),
                    self.tr("Layer '{0}' is not in editing mode.").format(
                        self.nmRelation().referencedLayer().name()))
                return False

        return True

    @pyqtSlot(bool)
    def toggleEditing(self, state):

        super().toggleEditing(state)
        self.updateButtons()

    @pyqtSlot()
    def saveChildLayerEdits(self):

        super().saveEdits()

    @pyqtSlot()
    def addDocument(self):

        # Workaround because of QGIS not resetting this property after linking features
        self.editorContext().vectorLayerTools().setForceSuppressFormPopup(
            False)
        self.addFeature()

    @pyqtSlot()
    def dropDocument(self):

        if self._currentDocumentId is None:
            return

        self.deleteFeature(self._currentDocumentId)

    @pyqtSlot(str)
    def addDroppedDocument(self, fileUrl):

        if self.checkLayerEditingMode() is False:
            return

        # Workaround because of QGIS not resetting this property after linking features
        self.editorContext().vectorLayerTools().setForceSuppressFormPopup(
            False)

        layer = self.relation().referencingLayer()
        if self.nmRelation().isValid():
            layer = self.nmRelation().referencedLayer()

        default_documents_path = str()
        if self.documents_path:
            exp = QgsExpression(self.documents_path)
            context = QgsExpressionContext()
            context.appendScopes(
                QgsExpressionContextUtils.globalProjectLayerScopes(layer))
            default_documents_path = str(exp.evaluate(context))

        filename = QUrl(fileUrl).toLocalFile()
        if default_documents_path:
            filename = QDir(default_documents_path).relativeFilePath(filename)

        keyAttrs = dict()

        # Fields of the linking table
        fields = self.relation().referencingLayer().fields()

        # For generated relations insert the referenced layer field
        if self.relation().type() == QgsRelation.Generated:
            polyRel = self.relation().polymorphicRelation()
            keyAttrs[fields.indexFromName(
                polyRel.referencedLayerField())] = polyRel.layerRepresentation(
                    self.relation().referencedLayer())

        if self.nmRelation().isValid():
            # only normal relations support m:n relation
            if self.nmRelation().type() != QgsRelation.Normal:
                QMessageBox.critical(
                    self, self.tr("Add document"),
                    self.
                    tr("Invalid relation, Only normal relations support m:n relation."
                       ))
                return

            # Pre fill inserting document filepath
            attributes = {
                self.nmRelation().referencedLayer().fields().indexFromName(self.document_filename):
                filename
            }

            # n:m Relation: first let the user create a new feature on the other table
            # and autocreate a new linking feature.
            ok, feature = self.editorContext().vectorLayerTools().addFeature(
                self.nmRelation().referencedLayer(), attributes, QgsGeometry())
            if not ok:
                QMessageBox.critical(
                    self, self.tr("Add document"),
                    self.tr("Could not add a new linking feature."))
                return

            for key in self.relation().fieldPairs():
                keyAttrs[fields.indexOf(key)] = self.feature().attribute(
                    self.relation().fieldPairs()[key])

            for key in self.nmRelation().fieldPairs():
                keyAttrs[fields.indexOf(key)] = feature.attribute(
                    self.nmRelation().fieldPairs()[key])

            linkFeature = QgsVectorLayerUtils.createFeature(
                self.relation().referencingLayer(), QgsGeometry(), keyAttrs,
                self.relation().referencingLayer().createExpressionContext())

            if not self.relation().referencingLayer().addFeature(linkFeature):
                QMessageBox.critical(self, self.tr("Add document"),
                                     self.tr("Could not add a new feature."))
                return

        else:
            for key in self.relation().fieldPairs():
                keyAttrs[fields.indexFromName(key)] = self.feature().attribute(
                    self.relation().fieldPairs()[key])

            # Pre fill inserting document filepath
            keyAttrs[fields] = filename

            ok, feature = self.editorContext().vectorLayerTools().addFeature(
                self.relation().referencingLayer(), keyAttrs, QgsGeometry())
            if not ok:
                QMessageBox.critical(self, self.tr("Add document"),
                                     self.tr("Could not add a new feature."))
                return

        self.updateUi()

    @pyqtSlot()
    def linkDocument(self):

        self.linkFeature()

    @pyqtSlot()
    def unlinkDocument(self):

        if self._currentDocumentId is None:
            return

        self.unlinkFeature(self._currentDocumentId)

    @pyqtSlot()
    def showDocumentForm(self):

        if self._currentDocumentId is None:
            return

        layer = self.relation().referencingLayer()
        if self.nmRelation().isValid():
            layer = self.nmRelation().referencedLayer()

        showDocumentFormDialog = QgsAttributeDialog(
            layer, layer.getFeature(self._currentDocumentId), False, self,
            True)
        showDocumentFormDialog.exec()
        self.updateUi()

    @pyqtSlot(bool)
    def listViewToolButtonToggled(self, checked):
        self.mIconViewToolButton.blockSignals(True)
        self.mIconViewToolButton.setChecked(checked is False)
        self.mIconViewToolButton.blockSignals(False)
        self.updateCurrentView()

    @pyqtSlot(bool)
    def iconViewToolButtonToggled(self, checked):
        self.mListViewToolButton.blockSignals(True)
        self.mListViewToolButton.setChecked(checked is False)
        self.mListViewToolButton.blockSignals(False)
        self.updateCurrentView()
class ShapeTools(object):
    def __init__(self, iface):
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.settingsDialog = None
        self.shapeDialog = None
        self.xyLineDialog = None
        self.geodesicDensifyDialog = None
        self.azDigitizerTool = None
        self.previousLayer = None
        self.toolbar = self.iface.addToolBar('Shape Tools Toolbar')
        self.toolbar.setObjectName('ShapeToolsToolbar')
        self.provider = ShapeToolsProvider()

    def initGui(self):
        self.azDigitizerTool = AzDigitizerTool(self.iface)

        # Initialize the create shape menu item
        icon = QIcon(os.path.dirname(__file__) + '/images/shapes.png')
        self.shapeAction = QAction(icon, tr('Create Shapes'),
                                   self.iface.mainWindow())
        self.shapeAction.setObjectName('stCreateShapes')
        self.shapeAction.triggered.connect(self.shapeTool)
        self.iface.addPluginToVectorMenu('Shape Tools', self.shapeAction)
        self.toolbar.addAction(self.shapeAction)

        # Initialize the XY to Line menu item
        icon = QIcon(os.path.dirname(__file__) + '/images/xyline.png')
        self.xyLineAction = QAction(icon, tr('XY to Line'),
                                    self.iface.mainWindow())
        self.xyLineAction.setObjectName('stXYtoLine')
        self.xyLineAction.triggered.connect(self.xyLineTool)
        self.iface.addPluginToVectorMenu('Shape Tools', self.xyLineAction)
        self.toolbar.addAction(self.xyLineAction)

        # Initialize the Geodesic Densifier menu item
        icon = QIcon(
            os.path.dirname(__file__) + '/images/geodesicDensifier.png')
        self.geodesicDensifyAction = QAction(icon,
                                             tr('Geodesic Shape Densifier'),
                                             self.iface.mainWindow())
        self.geodesicDensifyAction.setObjectName('stGeodesicDensifier')
        self.geodesicDensifyAction.triggered.connect(self.geodesicDensifyTool)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.geodesicDensifyAction)
        self.toolbar.addAction(self.geodesicDensifyAction)

        # Initialize Geodesic Measure Tool
        self.geodesicMeasureTool = GeodesicMeasureTool(self.iface,
                                                       self.iface.mainWindow())
        icon = QIcon(os.path.dirname(__file__) + '/images/measure.png')
        self.measureAction = QAction(icon, tr('Geodesic Measure Tool'),
                                     self.iface.mainWindow())
        self.measureAction.setObjectName('stGeodesicMeasureTool')
        self.measureAction.triggered.connect(self.measureTool)
        self.measureAction.setCheckable(True)
        self.iface.addPluginToVectorMenu('Shape Tools', self.measureAction)
        self.toolbar.addAction(self.measureAction)

        # Initialize the Azimuth Distance Digitize function
        icon = QIcon(os.path.dirname(__file__) + '/images/dazdigitize.png')
        self.digitizeAction = QAction(icon, tr('Azimuth Distance Digitizer'),
                                      self.iface.mainWindow())
        self.digitizeAction.setObjectName('stAzDistanceDigitizer')
        self.digitizeAction.triggered.connect(self.setShowAzDigitizerTool)
        self.digitizeAction.setCheckable(True)
        self.digitizeAction.setEnabled(False)
        self.iface.addPluginToVectorMenu(u'Shape Tools', self.digitizeAction)
        self.toolbar.addAction(self.digitizeAction)

        # Settings
        icon = QIcon(os.path.dirname(__file__) + '/images/settings.png')
        self.settingsAction = QAction(icon, tr('Settings'),
                                      self.iface.mainWindow())
        self.settingsAction.setObjectName('shapeToolsSettings')
        self.settingsAction.triggered.connect(self.settings)
        self.iface.addPluginToVectorMenu('Shape Tools', self.settingsAction)

        # Help
        icon = QIcon(os.path.dirname(__file__) + '/images/help.png')
        self.helpAction = QAction(icon, tr('Shape Tools Help'),
                                  self.iface.mainWindow())
        self.helpAction.setObjectName('shapeToolsHelp')
        self.helpAction.triggered.connect(self.help)
        self.iface.addPluginToVectorMenu('Shape Tools', self.helpAction)

        self.iface.currentLayerChanged.connect(self.currentLayerChanged)
        self.canvas.mapToolSet.connect(self.unsetTool)
        self.enableDigitizeTool()

        # Add the processing provider
        QgsApplication.processingRegistry().addProvider(self.provider)

    def unsetTool(self, tool):
        try:
            if not isinstance(tool, GeodesicMeasureTool):
                self.measureAction.setChecked(False)
                self.geodesicMeasureTool.closeDialog()
            if not isinstance(tool, AzDigitizerTool):
                self.digitizeAction.setChecked(False)
        except:
            pass

    def unload(self):
        self.canvas.unsetMapTool(self.azDigitizerTool)

        # remove from menu
        self.iface.removePluginVectorMenu('Shape Tools', self.shapeAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.xyLineAction)
        self.iface.removePluginVectorMenu('Shape Tools',
                                          self.geodesicDensifyAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.measureAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.digitizeAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.settingsAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.helpAction)
        # Remove from toolbar
        self.iface.removeToolBarIcon(self.shapeAction)
        self.iface.removeToolBarIcon(self.xyLineAction)
        self.iface.removeToolBarIcon(self.geodesicDensifyAction)
        self.iface.removeToolBarIcon(self.measureAction)
        self.iface.removeToolBarIcon(self.digitizeAction)
        self.azDigitizerTool = None
        # remove the toolbar
        del self.toolbar

        QgsApplication.processingRegistry().removeProvider(self.provider)

    def shapeTool(self):
        if self.shapeDialog is None:
            self.shapeDialog = Vector2ShapeWidget(self.iface,
                                                  self.iface.mainWindow())
        self.shapeDialog.show()

    def setShowAzDigitizerTool(self):
        self.digitizeAction.setChecked(True)
        self.canvas.setMapTool(self.azDigitizerTool)

    def xyLineTool(self):
        results = processing.execAlgorithmDialog('shapetools:xy2line', {})

    def geodesicDensifyTool(self):
        results = processing.execAlgorithmDialog(
            'shapetools:geodesicdensifier', {})

    def measureTool(self):
        self.measureAction.setChecked(True)
        self.canvas.setMapTool(self.geodesicMeasureTool)

    def settings(self):
        if self.settingsDialog is None:
            self.settingsDialog = SettingsWidget(self.iface,
                                                 self.iface.mainWindow())
        self.settingsDialog.show()

    def help(self):
        '''Display a help page'''
        url = QUrl.fromLocalFile(os.path.dirname(__file__) +
                                 '/index.html').toString()
        webbrowser.open(url, new=2)

    def currentLayerChanged(self):
        layer = self.iface.activeLayer()
        if self.previousLayer != None:
            try:
                self.previousLayer.editingStarted.disconnect(
                    self.layerEditingChanged)
            except:
                pass
            try:
                self.previousLayer.editingStopped.disconnect(
                    self.layerEditingChanged)
            except:
                pass
        self.previousLayer = None
        if layer != None:
            if isinstance(layer, QgsVectorLayer) and (
                (layer.wkbType() == QgsWkbTypes.Point) or
                (layer.wkbType() == QgsWkbTypes.LineString) or
                (layer.wkbType() == QgsWkbTypes.MultiLineString)):
                layer.editingStarted.connect(self.layerEditingChanged)
                layer.editingStopped.connect(self.layerEditingChanged)
                self.previousLayer = layer
        self.enableDigitizeTool()

    def layerEditingChanged(self):
        self.enableDigitizeTool()

    def enableDigitizeTool(self):
        self.digitizeAction.setEnabled(False)
        layer = self.iface.activeLayer()

        if layer != None and isinstance(layer, QgsVectorLayer) and (
            (layer.wkbType() == QgsWkbTypes.Point) or
            (layer.wkbType() == QgsWkbTypes.LineString) or
            (layer.wkbType()
             == QgsWkbTypes.MultiLineString)) and layer.isEditable():
            self.digitizeAction.setEnabled(True)
        else:
            self.digitizeAction.setChecked(False)
Beispiel #29
0
class WebGisPlugin(object):

    dialog = None
    project = None
    ws = None

    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',
                                  'gisquick_{}.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/gisquick2/img/icon.svg"),
                              u"Publish in Gisquick", self.iface.mainWindow())
        self.action.setCheckable(True)
        # connect the action to the run method
        self.action.triggered.connect(self.toggle_tool)

        self.settings_action = QAction(
            QIcon(":/plugins/gisquick2/img/settings.svg"), u"Configure",
            self.iface.mainWindow())
        # connect the action to the run method
        self.settings_action.triggered.connect(self.show_settings)

        # Add toolbar button and menu item
        # self.iface.addToolBarIcon(self.action)
        self.iface.addWebToolBarIcon(self.action)
        self.iface.addPluginToWebMenu(u"&Gisquick2", self.action)
        self.iface.addPluginToWebMenu(u"&Gisquick2", self.settings_action)

    def unload(self):
        if self.ws:
            gisquick_ws.stop()
            self.ws = None

        # Remove the plugin menu item and icon
        self.iface.removePluginWebMenu(u"&Gisquick2", self.action)
        self.iface.removePluginWebMenu(u"&Gisquick2", self.settings_action)
        self.iface.removeWebToolBarIcon(self.action)

    def is_overlay_layer_for_publish(self, layer):
        """Checks whether layer can be published as an overlay layer.

        Args:
            layer (qgis.core.QgsMapLayer): project layer
 
        Returns:
            bool: True if a layer can be published as an overlay layer
        """
        return (layer.type() == QgsMapLayer.VectorLayer
                or (layer.type() == QgsMapLayer.RasterLayer
                    and layer.providerType() != "wms"))

    def is_base_layer_for_publish(self, layer):
        """Checks whether layer could be published as a base layer.

        Args:
            layer (qgis.core.QgsMapLayer): project layer
 
        Returns:
            bool: True if a layer can be published as a base layer
        """
        return layer.type() == QgsMapLayer.RasterLayer and layer.providerType(
        ) == "wms"

    def map_units(self):
        """Returns units name of the project (map).

        Returns:
            str: map units name ('meters', 'feet', 'degrees', 'miles' or 'unknown')
        """
        return {
            0: 'meters',
            1: 'feet',
            2: 'degrees',
            3: 'unknown',
            7: 'miles'
        }[self.iface.mapCanvas().mapUnits()]

    def scales_to_resolutions(self, scales):
        """Converts map scales to tile resolutions (with fixed DPI=96).

        Args:
            scales (List[int]): array of map scales

        Returns:
            List[Decimal]: array of computed tile resolutions
        """
        return scales_to_resolutions(scales, self.map_units())

    def resolutions_to_scales(self, resolutions):
        """Converts tile resolutions to map scales (with fixed DPI=96).

        Args:
            resolutions (List[Decimal]): array of tile resolutions

        Returns:
            List[int]: array of computed map scales
        """
        return resolutions_to_scales(resolutions, self.map_units())

    def filter_visible_resolutions(self, resolutions, layer):
        """Filters given tile resolutions by layer's visibility settings.

        Args:
            resolutions (List[Decimal]): array of tile resolutions
            layer (qgis.core.QgsMapLayer): map layer

        Returns:
            List[Decimal]: array of visible tile resolutions
        """
        if layer.hasScaleBasedVisibility():
            max_scale_exclusive = layer.maximumScale()
            min_scale_inclusive = layer.minimumScale()
            max_res_exclusive, min_res_inclusive = self.scales_to_resolutions(
                [max_scale_exclusive, min_scale_inclusive])
            return [
                res for res in resolutions
                if res >= min_res_inclusive and res < max_res_exclusive
            ]
        return resolutions

    def wmsc_layer_resolutions(self, layer):
        """Returns visible resolutions of given WMSC layer.

        Args:
            layer (qgis.core.QgsRasterLayer): raster layer (WMSC)

        Returns:
            List[Decimal]: array of layer's visible tile resolutions
        """
        layer_resolutions = layer.dataProvider().property('resolutions')
        if layer_resolutions:
            layer_resolutions = to_decimal_array(layer_resolutions)
            if layer.hasScaleBasedVisibility():
                layer_resolutions = self.filter_visible_resolutions(
                    layer_resolutions, layer)
            if layer_resolutions:
                return sorted(layer_resolutions, reverse=True)
            return []
        return None

    def project_layers_resolutions(self):
        """Returns list of possible tile resolutions for current project.

        Returns:
            List[Decimal]: project tile resolutions
        """
        # compute resolutions as an union of resolutions calculated from project's
        # map scales and resolutions of all WMSC layers.
        project_tile_resolutions = set()

        # collect set of all resolutions from WMSC base layers
        base_layers = {
            layer.id(): layer
            for layer in QgsProject.instance().mapLayers().values()
            if self.is_base_layer_for_publish(layer)
        }
        for layer in list(base_layers.values()):
            layer_resolutions = self.wmsc_layer_resolutions(layer)
            if layer_resolutions:
                project_tile_resolutions.update(layer_resolutions)

        wmsc_layers_scales = self.resolutions_to_scales(
            project_tile_resolutions)
        scales, ok = self.project.readListEntry("Scales", "/ScalesList")
        if ok and scales:
            scales = [int(scale.split(":")[-1]) for scale in scales]
            # filter duplicit scales
            scales = [
                scale for scale in scales if scale not in wmsc_layers_scales
            ]
            project_tile_resolutions.update(
                self.scales_to_resolutions(sorted(scales, reverse=True)))

        project_tile_resolutions = sorted(project_tile_resolutions,
                                          reverse=True)
        return project_tile_resolutions

    def layers_list(self):
        """Returns array of all project's layers.

        Returns:
            List[qgis.core.QgsMapLayer]: project's layers
        """
        # legend_iface = self.iface.legendInterface().layers()
        return [
            tree_layer.layer() for tree_layer in
            QgsProject.instance().layerTreeRoot().findLayers()
        ]

    def get_layer_attributes(self, layer):
        fields = layer.fields()
        attributes_data = []
        excluded_attributes = layer.excludeAttributesWfs()
        conversion_types = {
            'BIGINT': 'INTEGER',
            'INTEGER64': 'INTEGER',
            'REAL': 'DOUBLE',
            'STRING': 'TEXT',
            'INT2': 'INTEGER',
            'INT4': 'INTEGER',
            'INT8': 'INTEGER',
            'NUMERIC': 'DOUBLE',
            'FLOAT8': 'DOUBLE',
            'VARCHAR': 'TEXT',
            'CHARACTER': 'TEXT'
        }
        for field in fields:
            if field.name() in excluded_attributes:
                continue
            field_type = field.typeName().upper()
            if field_type in conversion_types:
                field_type = conversion_types[field_type]
            attribute_data = {
                'name': field.name(),
                'type': field_type,
                #'length': field.length(),
                #'precision': field.precision()
            }
            if field.comment():
                attribute_data['comment'] = field.comment()
            alias = layer.attributeAlias(fields.indexFromName(field.name()))
            if alias:
                attribute_data['alias'] = alias
            attributes_data.append(attribute_data)

        return attributes_data

    def get_project_layers(self, skip_layers_with_error=False):
        dbname_pattern = re.compile("dbname='([^']+)'")
        project = QgsProject.instance()
        project_dir = project.absolutePath() + os.path.sep

        non_identifiable_layers = project.readListEntry(
            "Identify", "/disabledLayers")[0] or []
        wfs_layers = project.readListEntry("WFSLayers", "/")[0] or []
        map_canvas = self.iface.mapCanvas()
        map_settings = map_canvas.mapSettings()

        if project.layerTreeRoot().hasCustomLayerOrder():
            layers_order = project.layerTreeRoot().customLayerOrder()
        else:
            layers_order = self.layers_list()

        def visit_node(tree_node):
            if isinstance(tree_node, QgsLayerTreeLayer):
                layer = tree_node.layer()
                layer_type = {
                    0: "vector",
                    1: "raster",
                    # 2: PluginLayer
                    # 3: MeshLayer
                }[layer.type()]
                source = layer.source()
                provider_type = layer.providerType()
                uri = ""

                if provider_type == "wms":
                    source_params = parse_qs(source)
                    uri = source_params["url"][0]
                elif provider_type == "postgres":
                    dp = layer.dataProvider()
                    uri = "postgresql://%s:%s" % (dp.uri().host(),
                                                  dp.uri().port())
                elif provider_type in ("ogr", "gdal"):
                    uri = "file://%s" % source.split("|")[0]
                elif provider_type == "spatialite":
                    match = dbname_pattern.search(source)
                    if match:
                        uri = "file://%s" % match.group(1)
                else:
                    uri = source

                extent = layer.extent()
                if not extent.isEmpty():
                    extent = map_settings.layerExtentToOutputExtent(
                        layer, layer.extent()).toRectF().getCoords()
                else:
                    extent = None
                info = {
                    "id":
                    layer.id(),
                    "name":
                    layer.name(),
                    "serverName":
                    layer.shortName()
                    if hasattr(layer, "shortName") else layer.name(),
                    "wfs":
                    layer.id() in wfs_layers,
                    "provider_type":
                    provider_type,
                    "projection":
                    layer.crs().authid(),
                    "type":
                    layer_type,
                    "source":
                    uri,
                    "extent":
                    extent,
                    "visible":
                    project.layerTreeRoot().findLayer(layer.id()).isVisible(),
                    "metadata": {
                        "title": layer.title(),
                        "abstract": layer.abstract(),
                        "keyword_list": layer.keywordList()
                    }
                }
                legend_url = layer.legendUrl()
                if legend_url:
                    info["legend_url"] = legend_url
                # if layer.isSpatial()
                if layer_type == "vector":
                    info["geom_type"] = ('POINT', 'LINE', 'POLYGON', None,
                                         None)[layer.geometryType()]
                    info["wkb_type"] = QgsWkbTypes.displayString(
                        layer.wkbType())
                    info["labels"] = layer.labelsEnabled()
                    info["attributes"] = self.get_layer_attributes(layer)
                    info["queryable"] = bool(info["attributes"]) and layer.id(
                    ) not in non_identifiable_layers and layer.id(
                    ) in wfs_layers
                    if info["attributes"]:
                        fields = layer.fields()
                        info["pk_attributes"] = [
                            fields.at(index).name() for index in
                            layer.dataProvider().pkAttributeIndexes()
                        ]

                if provider_type == "wms":
                    info["url"] = source_params["url"][0]
                    img_format = source_params.get("format", [None])[0]
                    if not img_format:
                        img_format = os.path.splitext(info["url"])[1].replace(
                            ".", "image/")

                    info["format"] = img_format

                    info["dpi"] = layer.dataProvider().dpi()
                    if "layers" in source_params:
                        info["wms_layers"] = source_params["layers"]

                if layer in layers_order:
                    info["drawing_order"] = layers_order.index(layer)
                if layer.attribution():
                    info["attribution"] = {
                        "title": layer.attribution(),
                        "url": layer.attributionUrl()
                    }
                return info
            else:
                children = []
                for child_tree_node in tree_node.children():
                    try:
                        info = visit_node(child_tree_node)
                        if info:
                            children.append(info)
                    except Exception as e:
                        if not skip_layers_with_error:
                            msg = "Failed to gather info from layer: '%s'" % child_tree_node.name(
                            )
                            raise WsError(msg, 405) from e
                return {"name": tree_node.name(), "layers": children}

        root_node = self.iface.layerTreeView().layerTreeModel().rootGroup()
        return visit_node(root_node)["layers"]

    def get_print_templates(self):
        composer_templates = []
        project_layout_manager = QgsProject.instance().layoutManager()
        for layout in project_layout_manager.layouts():
            map = layout.referenceMap()
            units_conversion = map.mapUnitsToLayoutUnits()
            composer_data = {
                'name':
                layout.name(),
                'width':
                layout.layoutBounds().width(),
                'height':
                layout.layoutBounds().height(),
                'map': {
                    'name': 'map0',
                    'x': map.pagePos().x(),
                    'y': map.pagePos().y(),
                    'width': map.extent().width() * units_conversion,
                    'height': map.extent().height() * units_conversion
                },
                'labels': [
                    item.id() for item in list(layout.items())
                    if isinstance(item, QgsLayoutItemLabel) and item.id()
                ]
            }
            grid = map.grid()
            if grid.enabled():
                composer_data['map']['grid'] = {
                    'intervalX': grid.intervalX(),
                    'intervalY': grid.intervalY(),
                }
            composer_templates.append(composer_data)
        return composer_templates

    def get_project_info(self, skip_layers_with_error=False):
        project = QgsProject.instance()
        project_crs = project.crs()
        map_canvas = self.iface.mapCanvas()

        # scales, _ = project.readListEntry("Scales", "/ScalesList")
        # scales = [int(s.split(":")[1]) for s in scales]

        view_settings = project.viewSettings()
        scales = view_settings.mapScales()

        projections = {}
        crs_list = [project_crs
                    ] + [l.crs() for l in project.mapLayers().values()]
        for crs in crs_list:
            if crs.authid() not in projections:
                projections[crs.authid()] = {
                    "is_geographic": crs.isGeographic(),
                    "proj4": crs.toProj4()
                }
        data = {
            "file":
            project.absoluteFilePath(),
            "directory":
            project.absolutePath(),
            "title":
            project.title() or project.readEntry("WMSServiceTitle", "/")[0],
            "layers":
            self.get_project_layers(skip_layers_with_error),
            "composer_templates":
            self.get_print_templates(),
            "projection": {
                "code": project_crs.authid(),
                "is_geographic": project_crs.isGeographic(),
                "proj4": project_crs.toProj4()
            },
            "units":
            self.map_units(),
            "scales":
            scales,
            "position_precision": {
                "automatic":
                project.readBoolEntry("PositionPrecision", "/Automatic")[0],
                "decimal_places":
                project.readNumEntry("PositionPrecision", "/DecimalPlaces")[0]
            },
            "extent":
            map_canvas.fullExtent().toRectF().getCoords(),
            # "default_view_extent": view_settings.defaultViewExtent(),
            "server": {
                "wms_add_geometry":
                project.readBoolEntry("WMSAddWktGeometry", "")[0]
            },
            "projections":
            projections
        }
        return data

    def get_settings(self):
        return QSettings(QSettings.IniFormat, QSettings.UserScope, "Gisquick",
                         "gisquick2")

    def show_settings(self):
        settings = self.get_settings()
        dialog_filename = os.path.join(self.plugin_dir, "ui", "settings.ui")
        dialog = PyQt5.uic.loadUi(dialog_filename)
        dialog.server_url.setText(settings.value("server_url", ""))
        dialog.username.setText(settings.value("username", ""))
        dialog.password.setText(settings.value("password", ""))

        dialog.show()
        res = dialog.exec_()
        if res == 1:
            settings.setValue("server_url",
                              dialog.server_url.text().rstrip("/"))
            settings.setValue("username", dialog.username.text())
            settings.setValue("password", dialog.password.text())

    def on_project_change(self, *args):
        gisquick_ws.send("ProjectChanged")

    def on_project_closed(self, *args):
        def debounced():
            # filter events caused by switching between projects
            if not QgsProject.instance().absoluteFilePath():
                gisquick_ws.send("ProjectChanged")

        QTimer.singleShot(300, debounced)

    def toggle_tool(self, active):
        """Display dialog window for publishing current project.

        During a configuration process (wizard setup), plugin will hold actual metadata
        object in 'WebGisPlugin.metadata' property. If metadata from previous publishing
        still exist, they will be loaded and stored in 'WebGisPlugin.last_metadata' property.
        """
        def callback(msg):
            msg_type = msg["type"]
            data = msg.get("data")
            if msg_type == "ProjectInfo":
                if QgsProject.instance().absolutePath():
                    if data:
                        skip_layers_with_error = data.get(
                            "skip_layers_with_error", False)
                    return self.get_project_info(
                        skip_layers_with_error=skip_layers_with_error)
                raise WsError("Project is not opened", 404)

            elif msg_type == "ProjectDirectory":
                dir_path = QgsProject.instance().absolutePath()
                if dir_path:
                    return dir_path
                raise WsError("Project is not opened", 404)
            else:
                raise ValueError("Unknown message type: %s" % msg_type)

        def on_connection_estabilished():
            # self.iface.messageBar().pushMessage("Gisquick", "plugin is connected to server: %s" % server_url, level=Qgis.Success)

            def open_browser():
                import webbrowser
                webbrowser.open(urljoin(server_url, '/user/'))

            widget = self.iface.messageBar().createMessage(
                "Gisquick",
                "successfully connected to server: %s" % server_url)
            button = QPushButton(widget)
            button.setText("Open Browser")
            button.pressed.connect(open_browser)
            widget.layout().addWidget(button)
            self.iface.messageBar().pushWidget(widget, Qgis.Success)
            self.active_notification_widget = widget

        project = QgsProject.instance()
        if active:
            self.active_notification_widget = None
            settings = self.get_settings()
            server_url = settings.value("server_url")
            username = settings.value("username")
            password = settings.value("password")
            if not server_url or not username or not password:
                self.show_settings()
                server_url = settings.value("server_url")
                username = settings.value("username")
                password = settings.value("password")

            plugin_ver = __metadata__["general"].get("version")
            client_info = "GisquickPlugin/%s (%s %s; QGIS %s)" % (
                plugin_ver, platform.system(), platform.machine(),
                Qgis.QGIS_VERSION)

            class WebsocketServer(QThread):
                finished = QtCore.pyqtSignal(int)
                success = QtCore.pyqtSignal()

                def run(self):
                    # print("Starting WS", "server:", server_url, "user:", username)
                    def on_success():
                        self.success.emit()

                    res = gisquick_ws.start(server_url, username, password,
                                            client_info, callback, on_success)
                    self.finished.emit(res)

            def on_finished(res):
                self.ws = None
                if self.action.isChecked():
                    self.action.setChecked(False)
                if res != 0:
                    QMessageBox.warning(None, 'Warning', 'Failed to connect!')
                else:
                    if self.iface.messageBar().currentItem(
                    ) == self.active_notification_widget:
                        self.iface.messageBar().popWidget(
                            self.active_notification_widget)
                    self.active_notification_widget = None

            self.ws = WebsocketServer()
            self.ws.finished.connect(on_finished)
            self.ws.success.connect(on_connection_estabilished)
            r = self.ws.start()

            # project.isDirtyChanged.connect(self.on_project_change)
            project.readProject.connect(self.on_project_change)
            project.projectSaved.connect(self.on_project_change)
            project.cleared.connect(self.on_project_closed)
        else:
            gisquick_ws.stop()
            project.readProject.disconnect(self.on_project_change)
            project.projectSaved.disconnect(self.on_project_change)
            project.cleared.disconnect(self.on_project_closed)
Beispiel #30
0
class QgepPlugin(object):
    """
    A plugin for wastewater management
    http://www.github.com/qgep/QGEP
    """
    # The networkAnalyzer will manage the networklayers and pathfinding
    network_analyzer = None

    # Remember not to reopen the dock if there's already one opened
    profile_dock = None

    # Wizard
    wizarddock = None

    # The layer ids the plugin will need
    edgeLayer = None
    nodeLayer = None
    specialStructureLayer = None
    networkElementLayer = None

    profile = None

    def __init__(self, iface):
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.nodes = None
        self.edges = None

        self.initLogger()
        setup_i18n()

    def tr(self, source_text):
        """
        This does not inherit from QObject but for the translation to work (in particular to have translatable strings
        picked up) we need a tr method.
        :rtype : unicode
        :param source_text: The text to translate
        :return: The translated text
        """
        return QApplication.translate('QgepPlugin', source_text)

    def initLogger(self):
        """
        Initializes the logger
        """
        self.logger = logging.getLogger(__package__)

        settings = QSettings()

        loglevel = settings.value("/QGEP/LogLevel", 'Warning')
        logfile = settings.value("/QGEP/LogFile", None)

        if hasattr(self.logger, 'qgepFileHandler'):
            self.logger.removeHandler(self.logger.qgepFileHandler)
            del self.logger.qgepFileHandler

        current_handlers = [h.__class__.__name__ for h in self.logger.handlers]
        if self.__class__.__name__ not in current_handlers:
            self.logger.addHandler(QgepQgsLogHandler())

        if logfile:
            log_handler = logging.FileHandler(logfile)
            fmt = logging.Formatter(LOGFORMAT)
            log_handler.setFormatter(fmt)
            self.logger.addHandler(log_handler)
            self.logger.fileHandler = log_handler

        if 'Debug' == loglevel:
            self.logger.setLevel(logging.DEBUG)
        elif 'Info' == loglevel:
            self.logger.setLevel(logging.INFO)
        elif 'Warning' == loglevel:
            self.logger.setLevel(logging.WARNING)
        elif 'Error' == loglevel:
            self.logger.setLevel(logging.ERROR)

        fp = os.path.join(os.path.abspath(os.path.dirname(__file__)),
                          "metadata.txt")

        ini_text = QSettings(fp, QSettings.IniFormat)
        verno = ini_text.value("version")

        self.logger.info('QGEP plugin version ' + verno + ' started')

    def initGui(self):
        """
        Called to setup the plugin GUI
        """
        self.network_layer_notifier = QgepLayerNotifier(
            self.iface.mainWindow(), ['vw_network_node', 'vw_network_segment'])
        self.wastewater_networkelement_layer_notifier = QgepLayerNotifier(
            self.iface.mainWindow(), ['vw_wastewater_node', 'vw_qgep_reach'])
        self.toolbarButtons = []

        # Create toolbar button
        self.profileAction = QAction(
            QIcon(
                os.path.join(plugin_root_path(),
                             "icons/wastewater-profile.svg")),
            self.tr("Profile"), self.iface.mainWindow())
        self.profileAction.setWhatsThis(self.tr("Reach trace"))
        self.profileAction.setEnabled(False)
        self.profileAction.setCheckable(True)
        self.profileAction.triggered.connect(self.profileToolClicked)

        self.downstreamAction = QAction(
            QIcon(
                os.path.join(plugin_root_path(),
                             "icons/wastewater-downstream.svg")),
            self.tr("Downstream"), self.iface.mainWindow())
        self.downstreamAction.setWhatsThis(self.tr("Downstream reaches"))
        self.downstreamAction.setEnabled(False)
        self.downstreamAction.setCheckable(True)
        self.downstreamAction.triggered.connect(self.downstreamToolClicked)

        self.upstreamAction = QAction(
            QIcon(
                os.path.join(plugin_root_path(),
                             "icons/wastewater-upstream.svg")),
            self.tr("Upstream"), self.iface.mainWindow())
        self.upstreamAction.setWhatsThis(self.tr("Upstream reaches"))
        self.upstreamAction.setEnabled(False)
        self.upstreamAction.setCheckable(True)
        self.upstreamAction.triggered.connect(self.upstreamToolClicked)

        self.wizardAction = QAction(
            QIcon(os.path.join(plugin_root_path(), "icons/wizard.svg")),
            "Wizard", self.iface.mainWindow())
        self.wizardAction.setWhatsThis(
            self.tr("Create new manholes and reaches"))
        self.wizardAction.setEnabled(False)
        self.wizardAction.setCheckable(True)
        self.wizardAction.triggered.connect(self.wizard)

        self.connectNetworkElementsAction = QAction(
            QIcon(
                os.path.join(plugin_root_path(),
                             "icons/link-wastewater-networkelement.svg")),
            QApplication.translate('qgepplugin',
                                   'Connect wastewater networkelements'),
            self.iface.mainWindow())
        self.connectNetworkElementsAction.setEnabled(False)
        self.connectNetworkElementsAction.setCheckable(True)
        self.connectNetworkElementsAction.triggered.connect(
            self.connectNetworkElements)

        self.refreshNetworkTopologyAction = QAction(
            QIcon(os.path.join(plugin_root_path(),
                               "icons/refresh-network.svg")),
            "Refresh network topology", self.iface.mainWindow())
        self.refreshNetworkTopologyAction.setWhatsThis(
            self.tr("Refresh network topology"))
        self.refreshNetworkTopologyAction.setEnabled(False)
        self.refreshNetworkTopologyAction.setCheckable(False)
        self.refreshNetworkTopologyAction.triggered.connect(
            self.refreshNetworkTopologyActionClicked)

        self.aboutAction = QAction(self.tr('About'), self.iface.mainWindow())
        self.aboutAction.triggered.connect(self.about)

        self.settingsAction = QAction(self.tr('Settings'),
                                      self.iface.mainWindow())
        self.settingsAction.triggered.connect(self.showSettings)

        # Add toolbar button and menu item
        self.toolbar = QToolBar(QApplication.translate('qgepplugin', 'QGEP'))
        self.toolbar.addAction(self.profileAction)
        self.toolbar.addAction(self.upstreamAction)
        self.toolbar.addAction(self.downstreamAction)
        self.toolbar.addAction(self.wizardAction)
        self.toolbar.addAction(self.refreshNetworkTopologyAction)
        self.toolbar.addAction(self.connectNetworkElementsAction)

        self.iface.addPluginToMenu("&QGEP", self.profileAction)
        self.iface.addPluginToMenu("&QGEP", self.settingsAction)
        self.iface.addPluginToMenu("&QGEP", self.aboutAction)

        self.iface.addToolBar(self.toolbar)

        # Local array of buttons to enable / disable based on context
        self.toolbarButtons.append(self.profileAction)
        self.toolbarButtons.append(self.upstreamAction)
        self.toolbarButtons.append(self.downstreamAction)
        self.toolbarButtons.append(self.wizardAction)
        self.toolbarButtons.append(self.refreshNetworkTopologyAction)

        self.network_layer_notifier.layersAvailable.connect(
            self.onLayersAvailable)
        self.network_layer_notifier.layersUnavailable.connect(
            self.onLayersUnavailable)

        # Init the object maintaining the network
        self.network_analyzer = QgepGraphManager()
        self.network_analyzer.message_emitted.connect(
            self.iface.messageBar().pushMessage)
        # Create the map tool for profile selection
        self.profile_tool = QgepProfileMapTool(self.iface, self.profileAction,
                                               self.network_analyzer)
        self.profile_tool.profileChanged.connect(self.onProfileChanged)

        self.upstream_tree_tool = QgepTreeMapTool(self.iface,
                                                  self.upstreamAction,
                                                  self.network_analyzer)
        self.upstream_tree_tool.setDirection("upstream")
        self.upstream_tree_tool.treeChanged.connect(self.onTreeChanged)
        self.downstream_tree_tool = QgepTreeMapTool(self.iface,
                                                    self.downstreamAction,
                                                    self.network_analyzer)
        self.downstream_tree_tool.setDirection("downstream")
        self.downstream_tree_tool.treeChanged.connect(self.onTreeChanged)

        self.maptool_connect_networkelements = QgepMapToolConnectNetworkElements(
            self.iface, self.connectNetworkElementsAction)

        self.wastewater_networkelement_layer_notifier.layersAvailableChanged.connect(
            self.connectNetworkElementsAction.setEnabled)

        self.processing_provider = QgepProcessingProvider()
        QgsApplication.processingRegistry().addProvider(
            self.processing_provider)

        self.network_layer_notifier.layersAdded([])

    def unload(self):
        """
        Called when unloading
        """
        self.toolbar.removeAction(self.profileAction)
        self.toolbar.removeAction(self.upstreamAction)
        self.toolbar.removeAction(self.downstreamAction)
        self.toolbar.removeAction(self.wizardAction)
        self.toolbar.removeAction(self.refreshNetworkTopologyAction)
        self.toolbar.removeAction(self.connectNetworkElementsAction)

        self.toolbar.deleteLater()

        self.iface.removePluginMenu("&QGEP", self.profileAction)
        self.iface.removePluginMenu("&QGEP", self.aboutAction)

        QgsApplication.processingRegistry().removeProvider(
            self.processing_provider)

    def onLayersAvailable(self, layers):
        for b in self.toolbarButtons:
            b.setEnabled(True)

        self.network_analyzer.setReachLayer(layers['vw_network_segment'])
        self.network_analyzer.setNodeLayer(layers['vw_network_node'])

    def onLayersUnavailable(self):
        for b in self.toolbarButtons:
            b.setEnabled(False)

    def profileToolClicked(self):
        """
        Is executed when the profile button is clicked
        """
        self.openDock()
        # Set the profile map tool
        self.profile_tool.setActive()

    def upstreamToolClicked(self):
        """
        Is executed when the user clicks the upstream search tool
        """
        self.openDock()
        self.upstream_tree_tool.setActive()

    def downstreamToolClicked(self):
        """
        Is executed when the user clicks the downstream search tool
        """
        self.openDock()
        self.downstream_tree_tool.setActive()

    def refreshNetworkTopologyActionClicked(self):
        """
        Is executed when the user clicks the refreshNetworkTopologyAction tool
        """
        self.network_analyzer.refresh()

    def wizard(self):
        """
        """
        if not self.wizarddock:
            self.wizarddock = QgepWizard(self.iface.mainWindow(), self.iface)
        self.logger.debug('Opening Wizard')
        self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.wizarddock)
        self.wizarddock.show()

    def connectNetworkElements(self, checked):
        self.iface.mapCanvas().setMapTool(self.maptool_connect_networkelements)

    def openDock(self):
        """
        Opens the dock
        """
        if self.profile_dock is None:
            self.logger.debug('Open dock')
            self.profile_dock = QgepProfileDockWidget(self.iface.mainWindow(),
                                                      self.iface.mapCanvas(),
                                                      self.iface.addDockWidget)
            self.profile_dock.closed.connect(self.onDockClosed)
            self.profile_dock.showIt()

            self.plotWidget = QgepPlotSVGWidget(self.profile_dock,
                                                self.network_analyzer)
            self.plotWidget.specialStructureMouseOver.connect(
                self.highlightProfileElement)
            self.plotWidget.specialStructureMouseOut.connect(
                self.unhighlightProfileElement)
            self.plotWidget.reachMouseOver.connect(
                self.highlightProfileElement)
            self.plotWidget.reachMouseOut.connect(
                self.unhighlightProfileElement)
            self.profile_dock.addPlotWidget(self.plotWidget)
            self.profile_dock.setTree(self.nodes, self.edges)

    def onDockClosed(self):  # used when Dock dialog is closed
        """
        Gets called when the dock is closed
        All the cleanup of the dock has to be done here
        """
        self.profile_dock = None

    def onProfileChanged(self, profile):
        """
        The profile changed: update the plot
        @param profile: The profile to plot
        """
        self.profile = profile.copy()

        if self.plotWidget:
            self.plotWidget.setProfile(profile)

    def onTreeChanged(self, nodes, edges):
        if self.profile_dock:
            self.profile_dock.setTree(nodes, edges)
        self.nodes = nodes
        self.edges = edges

    def highlightProfileElement(self, obj_id):
        if self.profile is not None:
            self.profile.highlight(str(obj_id))

    def unhighlightProfileElement(self):
        if self.profile is not None:
            self.profile.highlight(None)

    def about(self):
        from .gui.dlgabout import DlgAbout

        DlgAbout(self.iface.mainWindow()).exec_()

    def showSettings(self):
        settings_dlg = QgepSettingsDialog(self.iface.mainWindow())
        settings_dlg.exec_()
class GimpSelectionFeaturePlugin(QObject):

  def __init__(self, iface):
    super().__init__()
    self.iface = iface
    self.name = u"&Gimp Selection Feature"
    self.dock = self.exitsPluginGimp = None
    self.translate = Translate( 'gimpselectionfeature' )

  def initGui(self):
    def setExistsPluginGimp():
      def getDirPluginGimp():
        dirPlugin = None
        mask = r".*gimp.[0-9]+.[0-9]+/%s" % nameDirPlugin # Linux Format
        for root, dirs, files in os.walk( dirHome ):
          if re.match( mask, root.replace('\\', '/'), re.IGNORECASE ):
            dirPlugin = root
            break

        return dirPlugin

      def copyNewPlugin():
        shutil.copy2( gimpPlugin, gimpPluginInstall )
        if sys.platform != 'win32': # Add executable
          st =  os.stat( gimpPluginInstall )
          os.chmod( gimpPluginInstall, st.st_mode | stat.S_IEXEC )

      dirHome = os.path.expanduser('~')
      nameDirPlugin = "plug-ins"
      dirPluginGimp = getDirPluginGimp()
      if dirPluginGimp is None:
        msg = "Not found diretory 'GIMP' or 'GIMP {}' in '{}'".format( nameDirPlugin, dirHome )
        self.exitsPluginGimp = { 'isOk': False, 'msg': msg }
        return

      namePlugin = 'socket_server_selection.py'
      gimpPlugin = os.path.join( os.path.dirname(__file__), namePlugin )
      gimpPluginInstall = os.path.join( dirPluginGimp, namePlugin )
      if not os.path.exists( gimpPluginInstall ) or not filecmp.cmp( gimpPlugin, gimpPluginInstall ):
        copyNewPlugin()

      self.exitsPluginGimp = { 'isOk': True }

    name = "Gimp Selection Feature"
    about = QCoreApplication.translate('GimpSelectionFeature', 'Adding selected area in GIMP how a feature in shapefile')
    icon = QIcon( os.path.join( os.path.dirname(__file__), 'gimpselectionfeature.svg' ) )
    self.action = QAction( icon, name, self.iface.mainWindow() )
    self.action.setObjectName( name.replace(' ', '') )
    self.action.setWhatsThis( about )
    self.action.setStatusTip( about )
    self.action.setCheckable( True )
    self.action.triggered.connect( self.run )

    self.iface.addRasterToolBarIcon( self.action )
    self.iface.addPluginToRasterMenu( self.name, self.action )

    setExistsPluginGimp()
    if not self.exitsPluginGimp['isOk']:
      return

    self.dock = DockWidgetGimpSelectionFeature( self.iface )
    self.iface.addDockWidget( Qt.RightDockWidgetArea , self.dock )
    self.dock.visibilityChanged.connect( self.dockVisibilityChanged )

  def unload(self):
    self.iface.removeRasterToolBarIcon( self.action )
    self.iface.removePluginRasterMenu( self.name, self.action )

    if self.exitsPluginGimp['isOk']:
      self.dock.close()
      del self.dock
      self.dock = None

    del self.action

  @pyqtSlot()
  def run(self):
    if not self.exitsPluginGimp['isOk']:
      ( t, m ) = ( GimpSelectionFeature.nameModulus, self.exitsPluginGimp['msg'] )
      self.iface.messageBar().pushMessage( t, m, Qgis.Critical, 5 )
      self.action.setChecked( False )
      return

    if self.dock.isVisible():
      self.dock.hide()
    else:
      self.dock.show()

  @pyqtSlot(bool)
  def dockVisibilityChanged(self, visible):
    self.action.setChecked( visible )
Beispiel #32
0
class PSTimeSeries_Plugin:
    def __init__(self, iface):
        self.iface = iface
        self.featFinder = None
        self.running = False

        # used to know where to ask for a new time-series tablename
        self.last_ps_layerid = None
        self.ts_tablename = None

    def initGui(self):
        # create the actions
        self.action = QAction(QIcon(":/pstimeseries_plugin/icons/logo"),
                              "PS Time Series Viewer", self.iface.mainWindow())
        self.action.triggered.connect(self.run)
        self.action.setCheckable(True)

        self.aboutAction = QAction(QIcon(":/pstimeseries_plugin/icons/about"),
                                   "About", self.iface.mainWindow())
        self.aboutAction.triggered.connect(self.about)

        # add actions to toolbars and menus
        self.iface.addToolBarIcon(self.action)
        self.iface.addPluginToMenu("&Permanent Scatterers", self.action)
        #self.iface.addPluginToMenu( "&Permanent Scatterers", self.aboutAction )

    def unload(self):
        # remove actions from toolbars and menus
        self.iface.removeToolBarIcon(self.action)
        self.iface.removePluginMenu("&Permanent Scatterers", self.action)
        #self.iface.removePluginMenu( "&Permanent Scatterers", self.aboutAction )

    def about(self):
        """ display the about dialog """
        from .about_dlg import AboutDlg
        dlg = AboutDlg(self.iface.mainWindow())
        dlg.exec_()

    def run(self):
        # create a maptool to select a point feature from the canvas
        if not self.featFinder:
            from .MapTools import FeatureFinder
            self.featFinder = FeatureFinder(self.iface.mapCanvas())
            self.featFinder.setAction(self.action)
            self.featFinder.pointEmitted.connect(self.onPointClicked)

        # enable the maptool and set a message in the status bar
        self.featFinder.startCapture()
        self.iface.mainWindow().statusBar().showMessage(
            "Click on a point feature in canvas")

    def onPointClicked(self, point):
        layer = self.iface.activeLayer()
        if not layer or layer.type(
        ) != QgsMapLayer.VectorLayer or layer.geometryType(
        ) != QgsWkbTypes.PointGeometry:
            QMessageBox.information(self.iface.mainWindow(),
                                    "PS Time Series Viewer",
                                    "Select a vector layer and try again.")
            return

        # set the waiting cursor
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        try:
            dlg = self._onPointClicked(layer, point)
        finally:
            # restore the cursor
            QApplication.restoreOverrideCursor()

        if dlg:
            dlg.exec_()

        self.run()

    def _onPointClicked(self, ps_layer, point):
        # get the id of the point feature under the mouse click
        from .MapTools import FeatureFinder
        fid = FeatureFinder.findAtPoint(ps_layer,
                                        point,
                                        canvas=self.iface.mapCanvas(),
                                        onlyTheClosestOne=True,
                                        onlyIds=True)
        if fid is None:
            return

        # get the attribute map of the selected feature
        feat = QgsFeature()
        feats = ps_layer.getFeatures(QgsFeatureRequest(fid))
        feats.nextFeature(feat)
        attrs = feat.attributes()

        x, y = [], []  # lists containg x,y values
        infoFields = {
        }  # hold the index->name of the fields containing info to be displayed

        ps_source = ps_layer.source()
        ps_fields = ps_layer.dataProvider().fields()

        providerType = ps_layer.providerType()
        uri = ps_source
        subset = ""

        if providerType == 'ogr' and ps_source.lower().endswith(".shp"):
            # Shapefile
            for idx, fld in enumerate(ps_fields):
                if QRegExp("D\\d{8}", Qt.CaseInsensitive).indexIn(
                        fld.name()) < 0:
                    # info fields are all except those containing dates
                    infoFields[idx] = fld
                else:
                    x.append(
                        QDate.fromString(fld.name()[1:],
                                         "yyyyMMdd").toPyDate())
                    y.append(float(attrs[idx]))

        elif providerType == 'ogr' and (
                ps_source.upper().startswith("OCI:")
                or ps_source.lower().endswith(".vrt")):  # Oracle Spatial

            # fields containing values
            dateField = "data_misura"
            valueField = "spost_rel_mm"
            infoFields = dict(enumerate(ps_fields))

            # search for the id_dataset and code_target fields needed to join
            # PS and TS tables
            idDataset = codeTarget = None
            for idx, fld in enumerate(ps_fields):
                if fld.name().lower() == "id_dataset":
                    idDataset = attrs[idx]
                if fld.name().lower() == "code_target":
                    codeTarget = attrs[idx]

            if idDataset is None or codeTarget is None:
                QgsMessageLog.logMessage(
                    "idDataset is %s, codeTarget is %s. Exiting" %
                    (idDataset, codeTarget), "PSTimeSeriesViewer")
                return
            subset = "id_dataset='%s' AND code_target='%s'" % (idDataset,
                                                               codeTarget)

            # create the uri
            if ps_source.upper().startswith("OCI:"):
                default_tbl_name = "RISKNAT.RNAT_TARGET_SSTO"
            elif ps_source.lower().endswith(".vrt"):
                default_tbl_name = "rnat_target_sso.vrt"
            else:
                default_tbl_name = ""
            if not self._askTStablename(ps_layer, default_tbl_name):
                return

            if ps_source.upper().startswith("OCI:"):
                # uri is like OCI:userid/password@database:table
                pos = uri.indexOf(':', 4)
                if pos >= 0:
                    uri = uri[0:pos]
                uri = "%s:%s" % (uri, self.ts_tablename)
            else:
                # it's a VRT file
                uri = "%s/%s" % (QFileInfo(ps_source).path(),
                                 self.ts_tablename)
                uri = QDir.toNativeSeparators(uri)

            # load the layer containing time series
            ts_layer = self._createTSlayer(uri, providerType, subset)
            if ts_layer is None:
                return

            # get time series X and Y values
            try:
                x, y = self._getXYvalues(ts_layer, dateField, valueField)
            finally:
                ts_layer.deleteLater()
                del ts_layer

        elif providerType in ['postgres',
                              'spatialite']:  # either PostGIS or SpatiaLite

            # fields containing values
            dateField = "dataripresa"
            valueField = "valore"
            infoFields = dict(enumerate(ps_fields))

            # search for the id_dataset and code_target fields needed to join
            # PS and TS tables
            code = None
            for idx, fld in enumerate(ps_fields):
                if fld.name().lower() == "code":
                    code = attrs[idx]

            if code is None:
                QgsMessageLog.logMessage("code is None. Exiting" % code,
                                         "PSTimeSeriesViewer")
                return
            subset = "code='%s'" % code

            # create the uri
            dsuri = QgsDataSourceUri(ps_layer.source())
            default_tbl_name = "ts_%s" % dsuri.table()
            if not self._askTStablename(ps_layer, default_tbl_name):
                return
            dsuri.setDataSource(dsuri.schema(), self.ts_tablename,
                                None)  # None or "" ? check during tests
            dsuri.setWkbType(QgsWkbTypes.Unknown)
            dsuri.setSrid(None)
            uri = dsuri.uri()

            # load the layer containing time series
            ts_layer = self._createTSlayer(uri, providerType, subset)
            if ts_layer is None:
                return

            # get time series X and Y values
            try:
                x, y = self._getXYvalues(ts_layer, dateField, valueField)
            finally:
                ts_layer.deleteLater()
                del ts_layer

        if len(x) * len(y) <= 0:
            QMessageBox.warning(
                self.iface.mainWindow(), "PS Time Series Viewer",
                "No time series values found for the selected point.")
            QgsMessageLog.logMessage(
                "provider: %s - uri: %s\nsubset: %s" %
                (providerType, uri, subset), "PSTimeSeriesViewer")
            return

        # display the plot dialog
        from .pstimeseries_dlg import PSTimeSeries_Dlg
        dlg = PSTimeSeries_Dlg(ps_layer, infoFields)
        dlg.setFeatureId(fid)
        dlg.setData(x, y)
        return dlg

    def _getXYvalues(self, ts_layer, dateField, valueField):
        # utility function used to get the X and Y values
        x, y = [], []

        # get indexes of date (x) and value (y) fields
        dateIdx, valueIdx = None, None
        for idx, fld in enumerate(ts_layer.dataProvider().fields()):
            if fld.name().lower() == dateField:
                dateIdx = idx
            elif fld.name().lower() == valueField:
                valueIdx = idx

        if dateIdx is None or valueIdx is None:
            QgsMessageLog.logMessage(
                "field %s -> index %s, field %s -> index %s. Exiting" %
                (dateField, dateIdx, valueField, valueIdx),
                "PSTimeSeriesViewer")
            return

        # fetch and loop through all the features
        request = QgsFeatureRequest()
        request.setSubsetOfAttributes([dateIdx, valueIdx])
        for f in ts_layer.getFeatures(request):
            # get x and y values
            a = f.attributes()
            x.append(QDate.fromString(a[dateIdx], "yyyyMMdd").toPyDate())
            y.append(float(a[valueIdx]))

        return x, y

    def _askTStablename(self, ps_layer, default_tblname=None):
        # utility function used to ask to the user the name of the table
        # containing time series data
        if default_tblname is None:
            default_tblname = ""

        # ask a tablename to the user
        if ps_layer.id() != self.last_ps_layerid or not self.ts_tablename:
            tblname, ok = QInputDialog.getText(
                self.iface.mainWindow(),
                "PS Time Series Viewer",
                "Insert the name of the table containing time-series",
                text=default_tblname)
            if not ok:
                return False

            self.ts_tablename = tblname
            self.last_ps_layerid = ps_layer.id()

        return True

    def _createTSlayer(self, uri, providerType, subset=None):
        # utility function used to create the vector layer containing time
        # series data
        layer = QgsVectorLayer(uri, "time_series_layer", providerType)
        if not layer.isValid():
            QMessageBox.warning(
                self.iface.mainWindow(), "PS Time Series Viewer",
                "The layer '%s' wasn't found." % self.ts_tablename)
            self.ts_tablename = None
            return

        if subset is not None:
            layer.setSubsetString(subset)

        return layer
class PostNAS_Search:

    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]
        locale_path = os.path.join(self.plugin_dir,'i18n','PostNAS_Search_{}.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 = PostNAS_SearchDialog(iface=self.iface)
        self.conf = PostNAS_ConfDialog(iface=self.iface)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&PostNAS_Search')

        self.searchDockWidget = None
        self.searchDockWidgetArea = Qt.LeftDockWidgetArea

    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('PostNAS_Search', message)

    def initGui(self):
        # Create Conf-Action and Menuentry
        self.confAction = QAction("Einstellungen", self.iface.mainWindow())
        self.confAction.setWhatsThis("Konfiguration der PostNAS-Suche")
        self.confAction.setStatusTip("Konfiguration der PostNAS-Suche")
        self.confAction.triggered.connect(self.showConf)

        if hasattr(self.iface, "addPluginToDatabaseMenu"):
            self.iface.addPluginToDatabaseMenu("&PostNAS-Suche", self.confAction)
        else:
            self.iface.addPluginToMenu("&PostNAS-Suche", self.confAction)

        self.toggleSearchAction = QAction(u"Flurstücksuche", self.iface.mainWindow())
        self.toggleSearchAction.setWhatsThis(u"Starten/Schliessen der Flurstücksuche")
        self.toggleSearchAction.setStatusTip(u"Starten/Schliessen der Flurstücksuche")
        self.toggleSearchAction.triggered.connect(self.toggleWidget)

        if hasattr(self.iface, "addPluginToDatabaseMenu"):
            self.iface.addPluginToDatabaseMenu("&PostNAS-Suche", self.toggleSearchAction)
        else:
            self.iface.addPluginToMenu("&PostNAS-Suche", self.toggleSearchAction)

        self.fulltextindex = QAction(u"Volltextindex erstellen", self.iface.mainWindow())
        self.fulltextindex.setWhatsThis(u"Erzeugt einen Volltextindex in der Datenbank um die Suche zu beschleunigen")
        self.fulltextindex.setStatusTip(u"Erzeugt einen Volltextindex in der Datenbank um die Suche zu beschleunigen")
        self.fulltextindex.triggered.connect(self.createFulltextindex)

        if hasattr(self.iface, "addPluginToDatabaseMenu"):
            self.iface.addPluginToDatabaseMenu("&PostNAS-Suche", self.fulltextindex)
        else:
            self.iface.addPluginToMenu("&PostNAS-Suche", self.fulltextindex)

        # Create action that will start plugin configuration
        self.action = QAction(QIcon(":/plugins/PostNAS_Search/search_24x24.png"),u"Flurstücksuche", self.iface.mainWindow())
        self.action.setCheckable(True)
        # connect the action to the run method
        self.action.triggered.connect(self.toggleWidget)

        # Add toolbar button and menu item
        self.iface.addToolBarIcon(self.action)

    def toggleWidget(self, event):
        if self.searchDockWidget == None:
            self.searchDockWidget = QDockWidget(self.iface.mainWindow())
            self.searchDockWidget.setWindowTitle(self.tr(u'Suche'))
            self.searchDockWidget.setWidget(self.dlg)
            self.searchDockWidget.closeEvent = self.toggleWidget
            self.iface.addDockWidget(self.searchDockWidgetArea, self.searchDockWidget)
            self.action.setChecked(True)
        else:
            self.searchDockWidgetArea = self.iface.mainWindow().dockWidgetArea(self.searchDockWidget)
            self.iface.removeDockWidget(self.searchDockWidget)
            self.searchDockWidget = None
            self.action.setChecked(False)

    def showConf(self):
        dlg = PostNAS_ConfDialog(self)
        dlg.exec_()

    def createFulltextindex(self):
        dlg = PostNAS_CreateFulltextindex(self)
        dlg.exec_()

    def unload(self):
        # Remove the Toolbar Icon
        self.iface.removeToolBarIcon(self.action)
        # Remove DockWidget
        if self.searchDockWidget != None:
            self.iface.removeDockWidget(self.searchDockWidget)

        if hasattr(self.iface, "removePluginDatabaseMenu"):
            self.iface.removePluginDatabaseMenu("&PostNAS-Suche", self.confAction)
            self.iface.removePluginDatabaseMenu("&PostNAS-Suche", self.toggleSearchAction)
            self.iface.removePluginDatabaseMenu("&PostNAS-Suche", self.fulltextindex)
        else:
            self.iface.removePluginMenu("&PostNAS-Suche", self.confAction)
            self.iface.removePluginMenu("&PostNAS-Suche", self.toggleSearchAction)
            self.iface.removePluginMenu("&PostNAS-Suche", self.fulltextindex)

        if self.confAction:
            self.confAction.deleteLater()
            self.confAction = None

        if self.toggleSearchAction:
            self.toggleSearchAction.deleteLater()
            self.toggleSearchAction = None

        if self.fulltextindex:
            self.fulltextindex.deleteLater()
            self.fulltextindex = None
Beispiel #34
0
class ProcessingPlugin:

    def __init__(self, iface):
        self.iface = iface
        self.options_factory = ProcessingOptionsFactory()
        self.options_factory.setTitle(self.tr('Processing'))
        iface.registerOptionsWidgetFactory(self.options_factory)
        self.drop_handler = ProcessingDropHandler()
        iface.registerCustomDropHandler(self.drop_handler)
        self.item_provider = ProcessingDataItemProvider()
        QgsApplication.dataItemProviderRegistry().addProvider(self.item_provider)
        self.locator_filter = AlgorithmLocatorFilter()
        iface.registerLocatorFilter(self.locator_filter)
        self.edit_features_locator_filter = InPlaceAlgorithmLocatorFilter()
        iface.registerLocatorFilter(self.edit_features_locator_filter)
        Processing.initialize()

    def initGui(self):
        self.toolbox = ProcessingToolbox()
        self.iface.addDockWidget(Qt.RightDockWidgetArea, self.toolbox)
        self.toolbox.hide()
        self.toolbox.visibilityChanged.connect(self.toolboxVisibilityChanged)

        self.resultsDock = ResultsDock()
        self.iface.addDockWidget(Qt.RightDockWidgetArea, self.resultsDock)
        self.resultsDock.hide()

        self.menu = QMenu(self.iface.mainWindow().menuBar())
        self.menu.setObjectName('processing')
        self.menu.setTitle(self.tr('Pro&cessing'))

        self.toolboxAction = QAction(self.tr('&Toolbox'), self.iface.mainWindow())
        self.toolboxAction.setCheckable(True)
        self.toolboxAction.setObjectName('toolboxAction')
        self.toolboxAction.setIcon(
            QgsApplication.getThemeIcon("/processingAlgorithm.svg"))
        self.iface.registerMainWindowAction(self.toolboxAction,
                                            QKeySequence('Ctrl+Alt+T').toString(QKeySequence.NativeText))
        self.toolboxAction.toggled.connect(self.openToolbox)
        self.iface.attributesToolBar().insertAction(self.iface.actionOpenStatisticalSummary(), self.toolboxAction)
        self.menu.addAction(self.toolboxAction)

        self.modelerAction = QAction(
            QgsApplication.getThemeIcon("/processingModel.svg"),
            QCoreApplication.translate('ProcessingPlugin', 'Graphical &Modeler…'), self.iface.mainWindow())
        self.modelerAction.setObjectName('modelerAction')
        self.modelerAction.triggered.connect(self.openModeler)
        self.iface.registerMainWindowAction(self.modelerAction,
                                            QKeySequence('Ctrl+Alt+M').toString(QKeySequence.NativeText))
        self.menu.addAction(self.modelerAction)

        self.historyAction = QAction(
            QgsApplication.getThemeIcon("/mIconHistory.svg"),
            QCoreApplication.translate('ProcessingPlugin', '&History…'), self.iface.mainWindow())
        self.historyAction.setObjectName('historyAction')
        self.historyAction.triggered.connect(self.openHistory)
        self.iface.registerMainWindowAction(self.historyAction,
                                            QKeySequence('Ctrl+Alt+H').toString(QKeySequence.NativeText))
        self.menu.addAction(self.historyAction)
        self.toolbox.processingToolbar.addAction(self.historyAction)

        self.resultsAction = QAction(
            QgsApplication.getThemeIcon("/processingResult.svg"),
            self.tr('&Results Viewer'), self.iface.mainWindow())
        self.resultsAction.setCheckable(True)
        self.iface.registerMainWindowAction(self.resultsAction,
                                            QKeySequence('Ctrl+Alt+R').toString(QKeySequence.NativeText))

        self.menu.addAction(self.resultsAction)
        self.toolbox.processingToolbar.addAction(self.resultsAction)
        self.resultsDock.visibilityChanged.connect(self.resultsAction.setChecked)
        self.resultsAction.toggled.connect(self.resultsDock.setUserVisible)

        self.toolbox.processingToolbar.addSeparator()

        self.editSelectedAction = QAction(
            QgsApplication.getThemeIcon("/mActionProcessSelected.svg"),
            self.tr('Edit Selected Features'), self.iface.mainWindow())
        self.editSelectedAction.setObjectName('editSelectedFeatures')
        self.editSelectedAction.setCheckable(True)
        self.editSelectedAction.toggled.connect(self.editSelected)
        self.toolbox.processingToolbar.addAction(self.editSelectedAction)

        self.toolbox.processingToolbar.addSeparator()

        self.optionsAction = QAction(
            QgsApplication.getThemeIcon("/mActionOptions.svg"),
            self.tr('Options'), self.iface.mainWindow())
        self.optionsAction.setObjectName('optionsAction')
        self.optionsAction.triggered.connect(self.openProcessingOptions)
        self.toolbox.processingToolbar.addAction(self.optionsAction)

        menuBar = self.iface.mainWindow().menuBar()
        menuBar.insertMenu(
            self.iface.firstRightStandardMenu().menuAction(), self.menu)

        self.menu.addSeparator()

        initializeMenus()
        createMenus()

        # In-place editing button state sync
        self.iface.currentLayerChanged.connect(self.sync_in_place_button_state)
        self.iface.mapCanvas().selectionChanged.connect(self.sync_in_place_button_state)
        self.iface.actionToggleEditing().triggered.connect(partial(self.sync_in_place_button_state, None))
        self.sync_in_place_button_state()

    def sync_in_place_button_state(self, layer=None):
        """Synchronise the button state with layer state and selection"""

        if layer is None:
            layer = self.iface.activeLayer()

        old_enabled_state = self.editSelectedAction.isEnabled()

        new_enabled_state = layer is not None and layer.type() == QgsMapLayer.VectorLayer and layer.isEditable() and layer.selectedFeatureCount()
        self.editSelectedAction.setEnabled(new_enabled_state)

        if new_enabled_state != old_enabled_state:
            self.toolbox.set_in_place_edit_mode(new_enabled_state and self.editSelectedAction.isChecked())

    def openProcessingOptions(self):
        self.iface.showOptionsDialog(self.iface.mainWindow(), currentPage='processingOptions')

    def unload(self):
        self.toolbox.setVisible(False)
        self.iface.removeDockWidget(self.toolbox)
        self.iface.attributesToolBar().removeAction(self.toolboxAction)

        self.resultsDock.setVisible(False)
        self.iface.removeDockWidget(self.resultsDock)

        self.toolbox.deleteLater()
        self.menu.deleteLater()

        # delete temporary output files
        folder = QgsProcessingUtils.tempFolder()
        if QDir(folder).exists():
            shutil.rmtree(folder, True)

        # also delete temporary help files
        folder = tempHelpFolder()
        if QDir(folder).exists():
            shutil.rmtree(folder, True)

        self.iface.unregisterMainWindowAction(self.toolboxAction)
        self.iface.unregisterMainWindowAction(self.modelerAction)
        self.iface.unregisterMainWindowAction(self.historyAction)
        self.iface.unregisterMainWindowAction(self.resultsAction)

        self.iface.unregisterOptionsWidgetFactory(self.options_factory)
        self.iface.deregisterLocatorFilter(self.locator_filter)
        self.iface.deregisterLocatorFilter(self.edit_features_locator_filter)
        self.iface.unregisterCustomDropHandler(self.drop_handler)
        QgsApplication.dataItemProviderRegistry().removeProvider(self.item_provider)

        removeMenus()
        Processing.deinitialize()

    def openToolbox(self, show):
        self.toolbox.setUserVisible(show)

    def toolboxVisibilityChanged(self, visible):
        self.toolboxAction.setChecked(visible)

    def openModeler(self):
        dlg = ModelerDialog()
        dlg.update_model.connect(self.updateModel)
        dlg.show()

    def updateModel(self):
        model_provider = QgsApplication.processingRegistry().providerById('model')
        model_provider.refreshAlgorithms()

    def openResults(self):
        if self.resultsDock.isVisible():
            self.resultsDock.hide()
        else:
            self.resultsDock.show()

    def openHistory(self):
        dlg = HistoryDialog()
        dlg.exec_()

    def tr(self, message):
        return QCoreApplication.translate('ProcessingPlugin', message)

    def editSelected(self, enabled):
        self.toolbox.set_in_place_edit_mode(enabled)
class LatLonTools:
    digitizerDialog = None
    convertCoordinateDialog = None

    def __init__(self, iface):
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.crossRb = QgsRubberBand(self.canvas, QgsWkbTypes.LineGeometry)
        self.crossRb.setColor(Qt.red)
        self.provider = LatLonToolsProvider()
        self.toolbar = self.iface.addToolBar('Lat Lon Tools Toolbar')
        self.toolbar.setObjectName('LatLonToolsToolbar')

    def initGui(self):
        '''Initialize Lot Lon Tools GUI.'''
        # Initialize the Settings Dialog box
        self.settingsDialog = SettingsWidget(self, self.iface, self.iface.mainWindow())
        self.mapTool = CopyLatLonTool(self.settingsDialog, self.iface)
        self.showMapTool = ShowOnMapTool(self.iface)

        # Add Interface for Coordinate Capturing
        icon = QIcon(os.path.dirname(__file__) + "/images/copyicon.png")
        self.copyAction = QAction(icon, "Copy/Display Coordinate", self.iface.mainWindow())
        self.copyAction.setObjectName('latLonToolsCopy')
        self.copyAction.triggered.connect(self.startCapture)
        self.copyAction.setCheckable(True)
        self.toolbar.addAction(self.copyAction)
        self.iface.addPluginToMenu("Lat Lon Tools", self.copyAction)

        # Add Interface for External Map
        icon = QIcon(os.path.dirname(__file__) + "/images/mapicon.png")
        self.externMapAction = QAction(icon, "Show in External Map", self.iface.mainWindow())
        self.externMapAction.setObjectName('latLonToolsExternalMap')
        self.externMapAction.triggered.connect(self.setShowMapTool)
        self.externMapAction.setCheckable(True)
        self.toolbar.addAction(self.externMapAction)
        self.iface.addPluginToMenu("Lat Lon Tools", self.externMapAction)

        # Add Interface for Zoom to Coordinate
        icon = QIcon(os.path.dirname(__file__) + "/images/zoomicon.png")
        self.zoomToAction = QAction(icon, "Zoom To Coordinate", self.iface.mainWindow())
        self.zoomToAction.setObjectName('latLonToolsZoom')
        self.zoomToAction.triggered.connect(self.showZoomToDialog)
        self.toolbar.addAction(self.zoomToAction)
        self.iface.addPluginToMenu('Lat Lon Tools', self.zoomToAction)

        self.zoomToDialog = ZoomToLatLon(self, self.iface, self.iface.mainWindow())
        self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.zoomToDialog)
        self.zoomToDialog.hide()

        # Add Interface for Multi point zoom
        icon = QIcon(os.path.dirname(__file__) + '/images/multizoom.png')
        self.multiZoomToAction = QAction(icon, "Multi-location Zoom", self.iface.mainWindow())
        self.multiZoomToAction.setObjectName('latLonToolsMultiZoom')
        self.multiZoomToAction.triggered.connect(self.multiZoomTo)
        self.toolbar.addAction(self.multiZoomToAction)
        self.iface.addPluginToMenu('Lat Lon Tools', self.multiZoomToAction)

        self.multiZoomDialog = MultiZoomWidget(self, self.settingsDialog, self.iface.mainWindow())
        self.multiZoomDialog.hide()
        self.multiZoomDialog.setFloating(True)

        # Create the coordinate converter menu
        icon = QIcon(':/images/themes/default/mIconProjectionEnabled.svg')
        self.convertCoordinatesAction = QAction(icon, "Coordinate Conversion", self.iface.mainWindow())
        self.convertCoordinatesAction.setObjectName('latLonToolsCoordinateConversion')
        self.convertCoordinatesAction.triggered.connect(self.convertCoordinatesTool)
        self.toolbar.addAction(self.convertCoordinatesAction)
        self.iface.addPluginToMenu("Lat Lon Tools", self.convertCoordinatesAction)

        # Create the conversions menu
        menu = QMenu()
        icon = QIcon(os.path.dirname(__file__) + '/images/field2geom.png')
        action = menu.addAction(icon, "Fields to point layer", self.field2geom)
        action.setObjectName('latLonToolsField2Geom')
        icon = QIcon(os.path.dirname(__file__) + '/images/geom2field.png')
        action = menu.addAction(icon, "Point layer to fields", self.geom2Field)
        action.setObjectName('latLonToolsGeom2Field')
        icon = QIcon(os.path.dirname(__file__) + '/images/pluscodes.png')
        action = menu.addAction(icon, "Plus Codes to point layer", self.PlusCodestoLayer)
        action.setObjectName('latLonToolsPlusCodes2Geom')
        action = menu.addAction(icon, "Point layer to Plus Codes", self.toPlusCodes)
        action.setObjectName('latLonToolsGeom2PlusCodes')
        icon = QIcon(os.path.dirname(__file__) + '/images/mgrs2point.png')
        action = menu.addAction(icon, "MGRS to point layer", self.MGRStoLayer)
        action.setObjectName('latLonToolsMGRS2Geom')
        icon = QIcon(os.path.dirname(__file__) + '/images/point2mgrs.png')
        action = menu.addAction(icon, "Point layer to MGRS", self.toMGRS)
        action.setObjectName('latLonToolsGeom2MGRS')
        self.conversionsAction = QAction(icon, "Conversions", self.iface.mainWindow())
        self.conversionsAction.setMenu(menu)
        self.iface.addPluginToMenu('Lat Lon Tools', self.conversionsAction)

        # Add to Digitize Toolbar
        icon = QIcon(os.path.dirname(__file__) + '/images/latLonDigitize.png')
        self.digitizeAction = QAction(icon, "Lat Lon Digitize", self.iface.mainWindow())
        self.digitizeAction.setObjectName('latLonToolsDigitize')
        self.digitizeAction.triggered.connect(self.digitizeClicked)
        self.digitizeAction.setEnabled(False)
        self.toolbar.addAction(self.digitizeAction)
        self.iface.addPluginToMenu('Lat Lon Tools', self.digitizeAction)

        # Add Interface for copying the canvas extent
        icon = QIcon(os.path.dirname(__file__) + "/images/copycanvas.png")
        self.copyCanvasAction = QAction(icon, "Copy Canvas Bounding Box", self.iface.mainWindow())
        self.copyCanvasAction.setObjectName('latLonToolsCopyCanvas')
        self.copyCanvasAction.triggered.connect(self.copyCanvas)
        self.toolbar.addAction(self.copyCanvasAction)
        self.iface.addPluginToMenu("Lat Lon Tools", self.copyCanvasAction)

        # Initialize the Settings Dialog Box
        settingsicon = QIcon(os.path.dirname(__file__) + '/images/settings.png')
        self.settingsAction = QAction(settingsicon, "Settings", self.iface.mainWindow())
        self.settingsAction.setObjectName('latLonToolsSettings')
        self.settingsAction.triggered.connect(self.settings)
        self.iface.addPluginToMenu('Lat Lon Tools', self.settingsAction)

        # Help
        icon = QIcon(os.path.dirname(__file__) + '/images/help.png')
        self.helpAction = QAction(icon, "Help", self.iface.mainWindow())
        self.helpAction.setObjectName('latLonToolsHelp')
        self.helpAction.triggered.connect(self.help)
        self.iface.addPluginToMenu('Lat Lon Tools', self.helpAction)

        self.iface.currentLayerChanged.connect(self.currentLayerChanged)
        self.canvas.mapToolSet.connect(self.unsetTool)
        self.enableDigitizeTool()

        # Add the processing provider
        QgsApplication.processingRegistry().addProvider(self.provider)

    def unsetTool(self, tool):
        '''Uncheck the Copy Lat Lon tool'''
        try:
            if not isinstance(tool, CopyLatLonTool):
                self.copyAction.setChecked(False)
                self.multiZoomDialog.stopCapture()
                self.mapTool.capture4326 = False
            if not isinstance(tool, ShowOnMapTool):
                self.externMapAction.setChecked(False)
        except Exception:
            pass

    def unload(self):
        '''Unload LatLonTools from the QGIS interface'''
        self.zoomToDialog.removeMarker()
        self.multiZoomDialog.removeMarkers()
        self.canvas.unsetMapTool(self.mapTool)
        self.canvas.unsetMapTool(self.showMapTool)
        self.iface.removePluginMenu('Lat Lon Tools', self.copyAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.copyCanvasAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.externMapAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.zoomToAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.multiZoomToAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.convertCoordinatesAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.conversionsAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.settingsAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.helpAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.digitizeAction)
        self.iface.removeDockWidget(self.zoomToDialog)
        self.iface.removeDockWidget(self.multiZoomDialog)
        # Remove Toolbar Icons
        self.iface.removeToolBarIcon(self.copyAction)
        self.iface.removeToolBarIcon(self.copyCanvasAction)
        self.iface.removeToolBarIcon(self.zoomToAction)
        self.iface.removeToolBarIcon(self.externMapAction)
        self.iface.removeToolBarIcon(self.multiZoomToAction)
        self.iface.removeToolBarIcon(self.convertCoordinatesAction)
        self.iface.removeToolBarIcon(self.digitizeAction)
        del self.toolbar

        self.zoomToDialog = None
        self.multiZoomDialog = None
        self.settingsDialog = None
        self.showMapTool = None
        self.mapTool = None
        self.digitizerDialog = None
        self.convertCoordinateDialog = None
        QgsApplication.processingRegistry().removeProvider(self.provider)

    def startCapture(self):
        '''Set the focus of the copy coordinate tool and check it'''
        self.copyAction.setChecked(True)
        self.canvas.setMapTool(self.mapTool)

    def copyCanvas(self):
        extent = self.iface.mapCanvas().extent()
        canvasCrs = self.canvas.mapSettings().destinationCrs()
        if settings.bBoxCrs == 0 and canvasCrs != epsg4326:
            transform = QgsCoordinateTransform(canvasCrs, epsg4326, QgsProject.instance())
            p1x, p1y = transform.transform(float(extent.xMinimum()), float(extent.yMinimum()))
            p2x, p2y = transform.transform(float(extent.xMaximum()), float(extent.yMaximum()))
            extent.set(p1x, p1y, p2x, p2y)
        delim = settings.bBoxDelimiter
        prefix = settings.bBoxPrefix
        suffix = settings.bBoxSuffix
        precision = settings.bBoxDigits
        outStr = ''
        minX = extent.xMinimum()
        minY = extent.yMinimum()
        maxX = extent.xMaximum()
        maxY = extent.yMaximum()
        if settings.bBoxFormat == 0:  # minX,minY,maxX,maxY - using the delimiter
            outStr = '{:.{prec}f}{}{:.{prec}f}{}{:.{prec}f}{}{:.{prec}f}'.format(
                minX, delim, minY, delim, maxX, delim, maxY, prec=precision)
        elif settings.bBoxFormat == 1:  # minX,maxX,minY,maxY - Using the selected delimiter'
            outStr = '{:.{prec}f}{}{:.{prec}f}{}{:.{prec}f}{}{:.{prec}f}'.format(
                minX, delim, maxX, delim, minY, delim, maxY, prec=precision)
        elif settings.bBoxFormat == 2:  # x1 y1,x2 y2,x3 y3,x4 y4,x1 y1 - Polygon format
            outStr = '{:.{prec}f} {:.{prec}f},{:.{prec}f} {:.{prec}f},{:.{prec}f} {:.{prec}f},{:.{prec}f} {:.{prec}f},{:.{prec}f} {:.{prec}f}'.format(
                minX, minY, minX, maxY, maxX, maxY, maxX, minY, minX, minY, prec=precision)
        elif settings.bBoxFormat == 3:  # x1,y1 x2,y2 x3,y3 x4,y4 x1,y1 - Polygon format
            outStr = '{:.{prec}f},{:.{prec}f} {:.{prec}f},{:.{prec}f} {:.{prec}f},{:.{prec}f} {:.{prec}f},{:.{prec}f} {:.{prec}f},{:.{prec}f}'.format(
                minX, minY, minX, maxY, maxX, maxY, maxX, minY, minX, minY, prec=precision)
        elif settings.bBoxFormat == 4:  # WKT Polygon
            outStr = extent.asWktPolygon()
        elif settings.bBoxFormat == 5:  # bbox: [minX, minY, maxX, maxY] - MapProxy
            outStr = 'bbox: [{}, {}, {}, {}]'.format(
                minX, minY, maxX, maxY)
        elif settings.bBoxFormat == 6:  # bbox: [minX, minY, maxX, maxY] - MapProxy
            outStr = 'bbox={},{},{},{}'.format(
                minX, minY, maxX, maxY)
        outStr = '{}{}{}'.format(prefix, outStr, suffix)
        clipboard = QApplication.clipboard()
        clipboard.setText(outStr)
        self.iface.messageBar().pushMessage("", "'{}' copied to the clipboard".format(outStr), level=Qgis.Info, duration=4)

    def setShowMapTool(self):
        '''Set the focus of the external map tool and check it'''
        self.externMapAction.setChecked(True)
        self.canvas.setMapTool(self.showMapTool)

    def showZoomToDialog(self):
        '''Show the zoom to docked widget.'''
        self.zoomToDialog.show()

    def convertCoordinatesTool(self):
        '''Display the Convert Coordinate Tool Dialog box.'''
        if self.convertCoordinateDialog is None:
            from .coordinateConverter import CoordinateConverterWidget
            self.convertCoordinateDialog = CoordinateConverterWidget(self, self.settingsDialog, self.iface, self.iface.mainWindow())
        self.convertCoordinateDialog.show()

    def multiZoomTo(self):
        '''Display the Multi-zoom to dialog box'''
        self.multiZoomDialog.show()

    def field2geom(self):
        '''Convert layer containing a point x & y coordinate to a new point layer'''
        processing.execAlgorithmDialog('latlontools:field2geom', {})

    def geom2Field(self):
        '''Convert layer geometry to a text string'''
        processing.execAlgorithmDialog('latlontools:geom2field', {})

    def toMGRS(self):
        '''Display the to MGRS  dialog box'''
        processing.execAlgorithmDialog('latlontools:point2mgrs', {})

    def MGRStoLayer(self):
        '''Display the to MGRS  dialog box'''
        processing.execAlgorithmDialog('latlontools:mgrs2point', {})

    def toPlusCodes(self):
        processing.execAlgorithmDialog('latlontools:point2pluscodes', {})

    def PlusCodestoLayer(self):
        processing.execAlgorithmDialog('latlontools:pluscodes2point', {})

    def settings(self):
        '''Show the settings dialog box'''
        self.settingsDialog.show()

    def help(self):
        '''Display a help page'''
        url = QUrl.fromLocalFile(os.path.dirname(__file__) + "/index.html").toString()
        webbrowser.open(url, new=2)

    def settingsChanged(self):
        # Settings may have changed so we need to make sure the zoomToDialog window is configured properly
        self.zoomToDialog.configure()
        self.multiZoomDialog.settingsChanged()

    def zoomTo(self, srcCrs, lat, lon):
        canvasCrs = self.canvas.mapSettings().destinationCrs()
        transform = QgsCoordinateTransform(srcCrs, canvasCrs, QgsProject.instance())
        x, y = transform.transform(float(lon), float(lat))

        rect = QgsRectangle(x, y, x, y)
        self.canvas.setExtent(rect)

        pt = QgsPointXY(x, y)
        self.highlight(pt)
        self.canvas.refresh()
        return pt

    def highlight(self, point):
        currExt = self.canvas.extent()

        leftPt = QgsPoint(currExt.xMinimum(), point.y())
        rightPt = QgsPoint(currExt.xMaximum(), point.y())

        topPt = QgsPoint(point.x(), currExt.yMaximum())
        bottomPt = QgsPoint(point.x(), currExt.yMinimum())

        horizLine = QgsGeometry.fromPolyline([leftPt, rightPt])
        vertLine = QgsGeometry.fromPolyline([topPt, bottomPt])

        self.crossRb.reset(QgsWkbTypes.LineGeometry)
        self.crossRb.addGeometry(horizLine, None)
        self.crossRb.addGeometry(vertLine, None)

        QTimer.singleShot(700, self.resetRubberbands)

    def resetRubberbands(self):
        self.crossRb.reset()

    def digitizeClicked(self):
        if self.digitizerDialog is None:
            from .digitizer import DigitizerWidget
            self.digitizerDialog = DigitizerWidget(self, self.iface, self.iface.mainWindow())
        self.digitizerDialog.show()

    def currentLayerChanged(self):
        layer = self.iface.activeLayer()
        if layer is not None:
            try:
                layer.editingStarted.disconnect(self.layerEditingChanged)
            except Exception:
                pass
            try:
                layer.editingStopped.disconnect(self.layerEditingChanged)
            except Exception:
                pass

            if isinstance(layer, QgsVectorLayer):
                layer.editingStarted.connect(self.layerEditingChanged)
                layer.editingStopped.connect(self.layerEditingChanged)

        self.enableDigitizeTool()

    def layerEditingChanged(self):
        self.enableDigitizeTool()

    def enableDigitizeTool(self):
        self.digitizeAction.setEnabled(False)
        layer = self.iface.activeLayer()

        if layer is not None and isinstance(layer, QgsVectorLayer) and (layer.geometryType() == QgsWkbTypes.PointGeometry) and layer.isEditable():
            self.digitizeAction.setEnabled(True)
        else:
            if self.digitizerDialog is not None:
                self.digitizerDialog.close()
Beispiel #36
0
class PhotoViewer(QScrollArea):
    """
    Widget for viewing images by incorporating basic navigation options.
    """
    def __init__(self, parent=None, photo_path=""):
        QScrollArea.__init__(self, parent)
        self.setBackgroundRole(QPalette.Dark)

        self._printer = QPrinter()

        self._lbl_photo = QLabel()
        self._lbl_photo.setBackgroundRole(QPalette.Base)
        self._lbl_photo.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
        self._lbl_photo.setScaledContents(True)

        self.setWidget(self._lbl_photo)

        self._photo_path = photo_path
        self._ph_image = None
        self._scale_factor = 1.0
        self._aspect_ratio = -1

        self._create_actions()

        if self._photo_path:
            self.load_document(self._photo_path)

    def _create_actions(self):
        """
        Create actions for basic image navigation.
        """
        self._zoom_in_act = QAction(
            QApplication.translate("PhotoViewer", "Zoom &In (25%)"), self)
        self._zoom_in_act.setShortcut(
            QApplication.translate("PhotoViewer", "Ctrl++"))
        self._zoom_in_act.setEnabled(False)
        self._zoom_in_act.triggered.connect(self.zoom_in)

        self._zoom_out_act = QAction(
            QApplication.translate("PhotoViewer", "Zoom &Out (25%)"), self)
        self._zoom_out_act.setShortcut(
            QApplication.translate("PhotoViewer", "Ctrl+-"))
        self._zoom_out_act.setEnabled(False)
        self._zoom_out_act.triggered.connect(self.zoom_out)

        self._normal_size_act = QAction(
            QApplication.translate("PhotoViewer", "&Normal Size"), self)
        self._normal_size_act.setShortcut(
            QApplication.translate("PhotoViewer", "Ctrl+S"))
        self._normal_size_act.setEnabled(False)
        self._normal_size_act.triggered.connect(self.normal_size)

        self._fit_to_window_act = QAction(
            QApplication.translate("PhotoViewer", "&Fit to Window"), self)
        self._fit_to_window_act.setShortcut(
            QApplication.translate("PhotoViewer", "Ctrl+F"))
        self._fit_to_window_act.setEnabled(False)
        self._fit_to_window_act.setCheckable(True)
        self._fit_to_window_act.triggered.connect(self.fit_to_window)

        self._print_act = QAction(
            QApplication.translate("PhotoViewer", "&Print"), self)
        self._print_act.setShortcut(
            QApplication.translate("PhotoViewer", "Ctrl+P"))
        self._print_act.setEnabled(False)
        self._print_act.triggered.connect(self.print_photo)

    def zoom_in(self):
        self.scale_photo(1.25)

    def zoom_out(self):
        self.scale_photo(0.8)

    def normal_size(self):
        self._lbl_photo.adjustSize()
        self._scale_factor = 1.0

    def fit_to_window(self):
        fit_to_win = self._fit_to_window_act.isChecked()
        self.setWidgetResizable(fit_to_win)

        if not fit_to_win:
            self.normal_size()

        self.update_actions()

    def print_photo(self):
        print_dialog = QPrintDialog(self._printer, self)

        if print_dialog.exec_() == QDialog.Accepted:
            painter = QPainter(self._printer)
            rect = painter.viewport()
            size = self._lbl_photo.pixmap().size()
            size.scale(rect.size(), Qt.KeepAspectRatio)
            painter.setViewport(rect.x(), rect.y(), size.width(),
                                size.height())
            painter.setWindow(self._lbl_photo.pixmap().rect())
            painter.drawPixmap(0, 0, self._lbl_photo.pixmap())

    def wheelEvent(self, event):
        """
        Zoom the image based on the mouse wheel rotation action.
        :param event: Event containing the wheel rotation info.
        :type event: QWheelEvent
        """
        degrees = event.delta() / 8
        num_steps = degrees / 15

        if num_steps < 0:
            abs_num_steps = abs(num_steps)
            zoom_factor = 1 + (abs_num_steps * 0.25)

        else:
            zoom_factor = 1 - (num_steps * 0.2)

        self.scale_photo(zoom_factor)

    def heightForWidth(self, width):
        if self._aspect_ratio != -1:
            return width / self._aspect_ratio

        else:
            return -1

    def resizeEvent(self, event):
        """
        Event for resizing the widget based on the pixmap's aspect ratio.
        :param event: Contains event parameters for the resize event.
        :type event: QResizeEvent
        """
        super(PhotoViewer, self).resizeEvent(event)

    def update_actions(self):
        self._zoom_out_act.setEnabled(not self._fit_to_window_act.isChecked())
        self._zoom_in_act.setEnabled(not self._fit_to_window_act.isChecked())
        self._normal_size_act.setEnabled(
            not self._fit_to_window_act.isChecked())

    def scale_photo(self, factor):
        """
        :param factor: Value by which the image will be increased/decreased in the view.
        :type factor: float
        """
        if not self._lbl_photo.pixmap().isNull():
            self._scale_factor *= factor
            self._lbl_photo.resize(self._scale_factor *
                                   self._lbl_photo.pixmap().size())

            self._adjust_scroll_bar(self.horizontalScrollBar(), factor)
            self._adjust_scroll_bar(self.verticalScrollBar(), factor)

            self._zoom_in_act.setEnabled(self._scale_factor < 3.0)
            self._zoom_out_act.setEnabled(self._scale_factor > 0.333)

    def _adjust_scroll_bar(self, scroll_bar, factor):
        scroll_bar.setValue(
            int(factor * scroll_bar.value() +
                ((factor - 1) * scroll_bar.pageStep() / 2)))

    def load_document(self, photo_path):
        if photo_path:
            self._ph_image = QImage(photo_path)

            if self._ph_image.isNull():
                return False

            self._photo_path = photo_path

            ph_pixmap = QPixmap.fromImage(self._ph_image)

            self._lbl_photo.setPixmap(ph_pixmap)
            self._scale_factor = 1.0

            self._aspect_ratio = ph_pixmap.width() / ph_pixmap.height()

            self._fit_to_window_act.setEnabled(True)
            self._print_act.setEnabled(True)
            self._fit_to_window_act.trigger()

            self.update_actions()
            return ph_pixmap

        return True

    def photo_location(self):
        """
        :returns: Absolute path of the photo in the central document repository.
        """
        return self._photo_path

    def set_actions(self, menu):
        """
        Add custom actions to the sub-window menu
        """
        menu.addSeparator()
        menu.addAction(self._zoom_in_act)
        menu.addAction(self._zoom_out_act)
        menu.addAction(self._normal_size_act)
        menu.addAction(self._fit_to_window_act)
        menu.addSeparator()
        menu.addAction(self._print_act)
Beispiel #37
0
class FeatureSelectSample:
    def __init__(self, iface):

        # Save reference to the QGIS interface
        self.iface = iface
        self.canvas = self.iface.mapCanvas()
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)

        # プラグインの登録場所
        self.menu_pos = 'サンプル フューチャー選択'
        # キャンバスウィンドウ上でのマウスイベントの設定
        self.mouseEventSample = FeatureSelectionTool(self.canvas)

    def initGui(self):
        icon = QIcon(self.plugin_dir + '/icon.png')
        self.action = QAction(icon, '一つ選択→属性編集', self.iface.mainWindow())
        self.action.triggered.connect(
            self.execSample)  # アイコンを押下した時に実行されるメソッドを登録
        self.action.setCheckable(True)  # Trueだとアイコンを押下したら次に押下するまで凹んだままになる。
        #self.iface.addToolBarIcon(self.action)         # ツールバーにアイコンを表示させたいなら#外して
        self.iface.addPluginToMenu(self.menu_pos, self.action)

    # このサンプル以外のアイコンが押された場合、アイコンを元の状態に戻す
    def unsetTool(self, tool):
        if not isinstance(tool, FeatureSelectSample):
            try:
                self.mouseEventSample.featureIdentified.disconnect(
                    self.editAttribute)
            except Exception:
                pass

            self.iface.layerTreeView().currentLayerChanged.disconnect(
                self.changeLayer)

            self.canvas.mapToolSet.disconnect(self.unsetTool)
            self.canvas.unsetMapTool(self.mouseEventSample)

            self.action.setChecked(False)

    def execSample(self):
        if self.action.isChecked():
            self.layer = self.iface.activeLayer()

            if (self.layer == None) or (type(self.layer)
                                        is not qgis._core.QgsVectorLayer):
                QMessageBox.about(None, '警告', 'ベクタレイヤを選択してから実行してください')
                self.action.setChecked(False)
                return

            self.previousMapTool = self.canvas.mapTool()
            self.canvas.setMapTool(self.mouseEventSample)
            self.canvas.mapToolSet.connect(self.unsetTool)

            self.iface.layerTreeView().currentLayerChanged.connect(
                self.changeLayer)  # アクティブレイヤが変更された時に呼ぶメソッドを登録
            self.mouseEventSample.setLayer(self.iface.activeLayer())
            self.mouseEventSample.featureIdentified.connect(self.editAttribute)
        else:
            self.mouseEventSample.featureIdentified.disconnect(
                self.editAttribute)
            self.iface.layerTreeView().currentLayerChanged.disconnect(
                self.changeLayer)
            self.canvas.mapToolSet.disconnect(self.unsetTool)
            self.canvas.unsetMapTool(self.mouseEventSample)
            self.canvas.setMapTool(self.previousMapTool)

    # フューチャーを一つ選択した時に呼ばれる。
    def editAttribute(self, feature):
        self.layer.removeSelection()
        self.layer.select(feature.id())

        self.layer.startEditing()  # レイヤを編集状態にする

        # 選択しているフューチャーの属性フォーム表示
        self.attdlg = self.iface.getFeatureForm(self.layer, feature)
        self.attdlg.setMode(qgis.gui.QgsAttributeEditorContext.SingleEditMode)
        self.attdlg.finished.connect(self.commitEdit)
        self.attdlg.show()

    def commitEdit(self, result):
        if result == 1:
            self.layer.commitChanges()
        else:
            self.layer.rollBack()
        self.attdlg.finished.disconnect(self.commitEdit)

    # レイヤウィンドウでレイヤを選択したときに呼ばれる
    def changeLayer(self, layer):
        if (layer == None) or (type(layer) is not qgis.core.QgsVectorLayer):
            return

        self.layer.removeSelection()
        self.layer = layer
        self.mouseEventSample.setLayer(self.layer)
Beispiel #38
0
class OpenlayersPlugin:
    def __init__(self, iface):
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # Keep a reference to all OL layers to avoid GC
        self._ol_layers = []
        # initialize locale
        locale = QSettings().value("locale/userLocale")[0:2]
        localePath = os.path.join(self.plugin_dir, "i18n",
                                  "openlayers_{}.qm".format(locale))

        if os.path.exists(localePath):
            self.translator = QTranslator()
            self.translator.load(localePath)

            if qVersion() > "4.3.3":
                QCoreApplication.installTranslator(self.translator)

        self._olLayerTypeRegistry = WebLayerTypeRegistry(self)
        self.olOverview = OLOverview(iface, self._olLayerTypeRegistry)
        self.dlgAbout = AboutDialog()
        self.pluginLayerRegistry = QgsPluginLayerRegistry()

    def initGui(self):
        self._olMenu = QMenu("TMS for Korea")
        self._olMenu.setIcon(QIcon(":/plugins/openlayers/openlayers.png"))

        # Overview
        self.overviewAddAction = QAction(
            QApplication.translate("OpenlayersPlugin", "OpenLayers Overview"),
            self.iface.mainWindow())
        self.overviewAddAction.setCheckable(True)
        self.overviewAddAction.setChecked(False)
        self.overviewAddAction.toggled.connect(self.olOverview.setVisible)
        self._olMenu.addAction(self.overviewAddAction)

        self._actionAbout = QAction(
            QApplication.translate("dlgAbout", "About OpenLayers Plugin"),
            self.iface.mainWindow())
        self._actionAbout.triggered.connect(self.dlgAbout.show)
        self._olMenu.addAction(self._actionAbout)
        self.dlgAbout.finished.connect(self._publicationInfoClosed)

        # Kakao Maps - 5181
        self._olLayerTypeRegistry.register(OlDaumStreetLayer())
        self._olLayerTypeRegistry.register(OlDaumHybridLayer())
        self._olLayerTypeRegistry.register(OlDaumSatelliteLayer())
        self._olLayerTypeRegistry.register(OlDaumPhysicalLayer())
        self._olLayerTypeRegistry.register(OlDaumCadstralLayer())

        # Naver Maps - 3857(New)
        self._olLayerTypeRegistry.register(OlNaverStreetLayer())
        self._olLayerTypeRegistry.register(OlNaverHybridLayer())
        self._olLayerTypeRegistry.register(OlNaverSatelliteLayer())
        self._olLayerTypeRegistry.register(OlNaverPhysicalLayer())
        self._olLayerTypeRegistry.register(OlNaverCadastralLayer())

        # Naver Maps - 5179(Old)
        self._olLayerTypeRegistry.register(OlNaverStreet5179Layer())
        self._olLayerTypeRegistry.register(OlNaverHybrid5179Layer())
        self._olLayerTypeRegistry.register(OlNaverSatellite5179Layer())
        self._olLayerTypeRegistry.register(OlNaverPhysical5179Layer())
        self._olLayerTypeRegistry.register(OlNaverCadastral5179Layer())

        # VWorld - 3857
        self._olLayerTypeRegistry.register(OlVWorldStreetLayer())
        self._olLayerTypeRegistry.register(OlVWorldSatelliteLayer())
        self._olLayerTypeRegistry.register(OlVWorldGrayLayer())
        self._olLayerTypeRegistry.register(OlVWorldHybridLayer())

        # NGII - 5179
        self._olLayerTypeRegistry.register(OlNgiiStreetLayer())
        self._olLayerTypeRegistry.register(OlNgiiBlankLayer())
        self._olLayerTypeRegistry.register(OlNgiiEnglishLayer())
        self._olLayerTypeRegistry.register(OlNgiiHighDensityLayer())
        self._olLayerTypeRegistry.register(OlNgiiColorBlindLayer())

        # Mango - 3857
        #self._olLayerTypeRegistry.register(OlMangoBaseMapLayer())
        #self._olLayerTypeRegistry.register(OlMangoBaseMapGrayLayer())
        #self._olLayerTypeRegistry.register(OlMangoHiDPIMapLayer())
        #self._olLayerTypeRegistry.register(OlMangoHiDPIMapGrayLayer())

        for group in self._olLayerTypeRegistry.groups():
            groupMenu = group.menu()
            for layer in self._olLayerTypeRegistry.groupLayerTypes(group):
                layer.addMenuEntry(groupMenu, self.iface.mainWindow())
            self._olMenu.addMenu(groupMenu)

        # Create Web menu, if it doesn't exist yet
        self.iface.addPluginToWebMenu("_tmp", self._actionAbout)
        self._menu = self.iface.webMenu()
        self._menu.addMenu(self._olMenu)
        self.iface.removePluginWebMenu("_tmp", self._actionAbout)

        # Register plugin layer type
        self.pluginLayerType = OpenlayersPluginLayerType(
            self.iface, self.setReferenceLayer, self._olLayerTypeRegistry)

        self.pluginLayerRegistry.addPluginLayerType(self.pluginLayerType)

        QgsProject.instance().readProject.connect(self.projectLoaded)
        QgsProject.instance().projectSaved.connect(self.projectSaved)

    def unload(self):
        self.iface.webMenu().removeAction(self._olMenu.menuAction())

        self.olOverview.setVisible(False)
        del self.olOverview

        # Unregister plugin layer type
        self.pluginLayerRegistry.removePluginLayerType(
            OpenlayersLayer.LAYER_TYPE)

        QgsProject.instance().readProject.disconnect(self.projectLoaded)
        QgsProject.instance().projectSaved.disconnect(self.projectSaved)

    def addLayer(self, layerType):
        if layerType.hasXYZUrl():
            # create XYZ layer
            layer, url = self.createXYZLayer(layerType, layerType.displayName)
        else:
            # create OpenlayersLayer
            layer = OpenlayersLayer(self.iface, self._olLayerTypeRegistry)
            layer.setName(layerType.displayName)
            layer.setLayerType(layerType)

            if layer.isValid():
                coordRefSys = layerType.coordRefSys(self.canvasCrs())
                self.setMapCrs(coordRefSys)
                QgsProject.instance().addMapLayer(layer)

                self._ol_layers += [layer]

                # last added layer is new reference
                self.setReferenceLayer(layer)

    def setReferenceLayer(self, layer):
        self.layer = layer

    def removeLayer(self, layerId):
        if self.layer is not None:
            if self.layer.id() == layerId:
                self.layer = None
            # TODO: switch to next available OpenLayers layer?

    def canvasCrs(self):
        mapCanvas = self.iface.mapCanvas()
        crs = mapCanvas.mapSettings().destinationCrs()
        return crs

    def setMapCrs(self, targetCRS):
        mapCanvas = self.iface.mapCanvas()
        mapExtent = mapCanvas.extent()

        sourceCRS = self.canvasCrs()
        QgsProject.instance().setCrs(targetCRS)
        mapCanvas.freeze(False)
        try:
            coordTrans = QgsCoordinateTransform(sourceCRS, targetCRS,
                                                QgsProject.instance())
            mapExtent = coordTrans.transform(
                mapExtent, QgsCoordinateTransform.ForwardTransform)
            mapCanvas.setExtent(mapExtent)
        except:
            pass

    def projectLoaded(self):
        # replace old OpenlayersLayer with XYZ layer(OL plugin <= 1.3.6)
        rootGroup = self.iface.layerTreeView().layerTreeModel().rootGroup()
        for layer in QgsProject.instance().mapLayers().values():
            if layer.type(
            ) == QgsMapLayer.PluginLayer and layer.pluginLayerType(
            ) == OpenlayersLayer.LAYER_TYPE:
                if layer.layerType.hasXYZUrl():
                    # replace layer
                    xyzLayer, url = self.createXYZLayer(
                        layer.layerType, layer.name())
                    if xyzLayer.isValid():
                        self.replaceLayer(rootGroup, layer, xyzLayer)

    def _hasOlLayer(self):
        for layer in QgsProject.instance().mapLayers().values():
            if layer.customProperty("ol_layer_type"):
                return True
        return False

    def _publicationInfo(self):
        cloud_info_off = QSettings().value("Plugin-OpenLayers/cloud_info_off",
                                           defaultValue=False,
                                           type=bool)
        day = 3600 * 24
        now = time.time()
        lastInfo = QSettings().value("Plugin-OpenLayers/cloud_info_ts",
                                     defaultValue=0.0,
                                     type=float)
        if lastInfo == 0.0:
            lastInfo = now - 20 * day  # Show first time after 10 days
            QSettings().setValue("Plugin-OpenLayers/cloud_info_ts", lastInfo)
        days = (now - lastInfo) / day
        if days >= 30 and not cloud_info_off:
            self.dlgAbout.tabWidget.setCurrentWidget(
                self.dlgAbout.tab_publishing)
            self.dlgAbout.show()
            QSettings().setValue("Plugin-OpenLayers/cloud_info_ts", now)

    def _publicationInfoClosed(self):
        QSettings().setValue("Plugin-OpenLayers/cloud_info_off",
                             self.dlgAbout.cb_publishing.isChecked())

    def projectSaved(self):
        if self._hasOlLayer():
            self._publicationInfo()

    def createXYZLayer(self, layerType, name):
        # create XYZ layer with tms url as uri
        provider = "wms"

        # isinstance(P, (list, tuple, np.ndarray))
        xyzUrls = layerType.xyzUrlConfig()
        layerName = name
        tilePixelRatio = layerType.tilePixelRatio

        coordRefSys = layerType.coordRefSys(self.canvasCrs())
        self.setMapCrs(coordRefSys)

        if isinstance(xyzUrls, (list)):
            # create group layer
            root = QgsProject.instance().layerTreeRoot()
            layer = root.addGroup(layerType.groupName)

            i = 0
            for xyzUrl in xyzUrls:
                tmsLayerName = layerName

                # https://github.com/qgis/QGIS/blob/master/src/providers/wms/qgsxyzconnectiondialog.cpp

                uri = "url=" + xyzUrl + "&zmax=18&zmin=0&type=xyz"
                if (tilePixelRatio > 0):
                    uri = uri + "&tilePixelRatio=" + str(tilePixelRatio)

                if i > 0:
                    tmsLayerName = layerName + " Label"

                tmsLayer = QgsRasterLayer(uri, tmsLayerName, provider,
                                          QgsRasterLayer.LayerOptions())
                tmsLayer.setCustomProperty("ol_layer_type", tmsLayerName)

                layer.insertChildNode(0, QgsLayerTreeLayer(tmsLayer))
                i = i + 1

                if tmsLayer.isValid():
                    QgsProject.instance().addMapLayer(tmsLayer, False)
                    self._ol_layers += [tmsLayer]

                    # last added layer is new reference
                    self.setReferenceLayer(tmsLayer)
                    # add to XYT Tiles
                    self.addToXYZTiles(tmsLayerName, xyzUrl, tilePixelRatio)
        else:
            uri = "url=" + xyzUrls + "&zmax=18&zmin=0&type=xyz"
            if (tilePixelRatio > 0):
                uri = uri + "&tilePixelRatio=" + str(tilePixelRatio)

            layer = QgsRasterLayer(uri, layerName, provider,
                                   QgsRasterLayer.LayerOptions())
            layer.setCustomProperty("ol_layer_type", layerName)

            if layer.isValid():
                QgsProject.instance().addMapLayer(layer)
                self._ol_layers += [layer]

                # last added layer is new reference
                self.setReferenceLayer(layer)
                # add to XYT Tiles
                self.addToXYZTiles(layerName, xyzUrls, tilePixelRatio)

        # reload connections to update Browser Panel content
        self.iface.reloadConnections()

        return layer, xyzUrls

    def addToXYZTiles(self, name, url, tilePixelRatio):
        # store xyz config into qgis settings
        settings = QSettings()
        settings.beginGroup("qgis/connections-xyz")
        settings.setValue("%s/authcfg" % (name), "")
        settings.setValue("%s/password" % (name), "")
        settings.setValue("%s/referer" % (name), "")
        settings.setValue("%s/url" % (name), url)
        settings.setValue("%s/username" % (name), "")
        # specify max/min or else only a picture of the map is saved in settings
        settings.setValue("%s/zmax" % (name), "18")
        settings.setValue("%s/zmin" % (name), "0")
        if tilePixelRatio >= 0 and tilePixelRatio <= 2:
            settings.setValue("%s/tilePixelRatio" % (name),
                              str(tilePixelRatio))
        settings.endGroup()

    def replaceLayer(self, group, oldLayer, newLayer):
        index = 0
        for child in group.children():
            if QgsLayerTree.isLayer(child):
                if child.layerId() == oldLayer.id():
                    # insert new layer
                    QgsProject.instance().addMapLayer(newLayer, False)
                    newLayerNode = group.insertLayer(index, newLayer)
                    newLayerNode.setVisible(child.isVisible())

                    # remove old layer
                    QgsProject.instance().removeMapLayer(oldLayer.id())

                    msg = "Updated layer '%s' from old OpenLayers Plugin version" % newLayer.name(
                    )
                    self.iface.messageBar().pushMessage(
                        "OpenLayers Plugin", msg, level=Qgis.MessageLevel(0))
                    QgsMessageLog.logMessage(msg, "OpenLayers Plugin",
                                             QgsMessageLog.INFO)

                    # layer replaced
                    return True
            else:
                if self.replaceLayer(child, oldLayer, newLayer):
                    # layer replaced in child group
                    return True

            index += 1

        # layer not in this group
        return False
class W3WTools(object):
    def __init__(self, iface):
        self.iface = iface

        try:
            from what3words.tests import testerplugin
            from qgistester.tests import addTestModule
            addTestModule(testerplugin, "what3words")
        except:
            pass

        self.mapTool = None
        if processingOk:
            self.provider = W3WProvider()

        readSettings()

    def initGui(self):
        mapToolIcon = QIcon(
            os.path.join(os.path.dirname(__file__), "icons", "w3w.png"))
        self.toolAction = QAction(mapToolIcon, "what3words map tool",
                                  self.iface.mainWindow())
        self.toolAction.triggered.connect(self.setTool)
        self.toolAction.setCheckable(True)
        self.iface.addToolBarIcon(self.toolAction)
        self.iface.addPluginToMenu("what3words", self.toolAction)

        zoomToIcon = QIcon(':/images/themes/default/mActionZoomIn.svg')
        self.zoomToAction = QAction(zoomToIcon, "Zoom to 3 word address",
                                    self.iface.mainWindow())
        self.zoomToAction.triggered.connect(self.zoomTo)
        self.iface.addPluginToMenu("what3words", self.zoomToAction)

        addSettingsMenu("what3words", self.iface.addPluginToMenu)
        addHelpMenu("what3words", self.iface.addPluginToMenu)
        addAboutMenu("what3words", self.iface.addPluginToMenu)

        self.iface.mapCanvas().mapToolSet.connect(self.unsetTool)

        self.zoomToDialog = W3WCoordInputDialog(self.iface.mapCanvas(),
                                                self.iface.mainWindow())
        self.iface.addDockWidget(Qt.TopDockWidgetArea, self.zoomToDialog)
        self.zoomToDialog.hide()

        if processingOk:
            Processing.addProvider(self.provider)

        try:
            from lessons import addLessonsFolder, addGroup
            folder = os.path.join(os.path.dirname(__file__), "_lessons")
            addLessonsFolder(folder, "what3words")
        except:
            pass

    def zoomTo(self):
        apikey = pluginSetting("apiKey")
        if apikey is None or apikey == "":
            self._showMessage(
                'what3words API key is not set. Please set it and try again.',
                QgsMessageBar.WARNING)
            return
        self.zoomToDialog.setApiKey(apikey)
        self.zoomToDialog.show()

    def unsetTool(self, tool):
        try:
            if not isinstance(tool, W3WMapTool):
                self.toolAction.setChecked(False)
        except:
            # ignore exceptions thrown when unloading plugin, since
            # map tool class might not exist already
            pass

    def setTool(self):
        apikey = pluginSetting("apiKey")
        if apikey is None or apikey == "":
            self._showMessage(
                'what3words API key is not set. Please set it and try again.',
                QgsMessageBar.WARNING)
            return
        if self.mapTool is None:
            self.mapTool = W3WMapTool(self.iface.mapCanvas())
        self.toolAction.setChecked(True)
        self.iface.mapCanvas().setMapTool(self.mapTool)

    def unload(self):
        self.iface.mapCanvas().unsetMapTool(self.mapTool)
        self.iface.removeToolBarIcon(self.toolAction)
        self.iface.removePluginMenu("what3words", self.toolAction)
        self.iface.removePluginMenu("what3words", self.zoomToAction)

        removeSettingsMenu("what3words")
        removeHelpMenu("what3words")
        removeAboutMenu("what3words")

        self.iface.removeDockWidget(self.zoomToDialog)

        if processingOk:
            Processing.removeProvider(self.provider)

        try:
            from what3words.tests import testerplugin
            from qgistester.tests import removeTestModule
            removeTestModule(testerplugin, "what3words")
        except:
            pass

        try:
            from lessons import removeLessonsFolder
            folder = os.path.join(pluginPath, '_lessons')
            removeLessonsFolder(folder)
        except:
            pass

    def _showMessage(self, message, level=QgsMessageBar.INFO):
        iface.messageBar().pushMessage(message, level, iface.messageTimeout())
class DataPlotly:  # pylint: disable=too-many-instance-attributes
    """QGIS Plugin Implementation."""

    VERSION = '2.3'

    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 processing provider
        self.provider = DataPlotlyProvider(plugin_version=DataPlotly.VERSION)

        # initialize locale
        locale = QSettings().value('locale/userLocale', 'en_US')[0:2]
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'DataPlotly_{}.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.dock_widget = None
        self.show_dock_action = None
        self.menu = None
        self.toolbar = None

        self.plot_item_metadata = PlotLayoutItemMetadata()
        self.plot_item_gui_metadata = None
        QgsApplication.layoutItemRegistry().addLayoutItemType(
            self.plot_item_metadata)

    # noinspection PyMethodMayBeStatic
    def tr(self, message):  # pylint: disable=no-self-use
        """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('DataPlotly', message)

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        self.menu = QMenu(self.tr('&DataPlotly'))
        self.iface.pluginMenu().addMenu(self.menu)

        # TODO: We are going to let the user set this up in a future iteration
        self.toolbar = self.iface.addToolBar('DataPlotly')
        self.toolbar.setObjectName('DataPlotly')

        self.dock_widget = DataPlotlyDock()
        self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dock_widget)
        self.dock_widget.hide()

        self.show_dock_action = QAction(GuiUtils.get_icon('dataplotly.svg'),
                                        self.tr('DataPlotly'))
        self.show_dock_action.setToolTip(self.tr('Shows the DataPlotly dock'))
        self.show_dock_action.setCheckable(True)

        self.dock_widget.setToggleVisibilityAction(self.show_dock_action)

        self.menu.addAction(self.show_dock_action)
        self.toolbar.addAction(self.show_dock_action)

        # Add processing provider
        self.initProcessing()

        # Add layout gui utils
        self.plot_item_gui_metadata = PlotLayoutItemGuiMetadata()
        QgsGui.layoutItemGuiRegistry().addLayoutItemGuiMetadata(
            self.plot_item_gui_metadata)

    def initProcessing(self):
        """Create the Processing provider"""
        QgsApplication.processingRegistry().addProvider(self.provider)

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        self.show_dock_action.deleteLater()
        self.show_dock_action = None
        self.menu.deleteLater()
        self.menu = None
        self.toolbar.deleteLater()
        self.toolbar = None

        # Remove processing provider
        QgsApplication.processingRegistry().removeProvider(self.provider)

    def loadPlotFromDic(self, plot_dic):
        """
        Calls the method to load the DataPlotly dialog with a given dictionary
        """
        self.dock_widget.main_panel.showPlotFromDic(plot_dic)
        self.dock_widget.setUserVisible(True)
Beispiel #41
0
class PolygonMapWindow(QMainWindow):
    """Open a map window where the user can draw a polygon and use it to crop data.
       Shares a lot of similarities with MapWindow calss, but there're enough differences
        that I decided not to inherit from it."""
    # signal emitted when polygons succesfully selected
    finished = pyqtSignal()

    def __init__(self):
        QMainWindow.__init__(self)

        # creating map canvas, which draws the maplayers
        # setting up features like canvas color
        self.canvas = QgsMapCanvas()
        self.canvas.setMinimumSize(550, 700)
        self.canvas.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        self.canvas.setCanvasColor(Qt.white)
        self.canvas.enableAntiAliasing(True)

        # Qmainwindow requires a central widget. Canvas is placed
        self.setCentralWidget(self.canvas)

        # creating each desired action
        self.actionGet = QAction("Return polygon and close", self)
        self.actionPan = QAction("Pan tool", self)
        self.actionDraw = QAction("Polygon tool", self)
        self.actionConnect = QAction("Connect polygon", self)
        self.actionClear = QAction("Clear", self)
        self.actionCancel = QAction("Cancel and close", self)

        # these two function as on/off. the rest are clickable
        self.actionPan.setCheckable(True)
        self.actionDraw.setCheckable(True)

        # when actions are clicked, do corresponding function
        self.actionPan.triggered.connect(self.pan)
        self.actionDraw.triggered.connect(self.draw)
        self.actionClear.triggered.connect(self.clear)
        self.actionGet.triggered.connect(self.finishedSelection)
        self.actionConnect.triggered.connect(self.connect)
        self.actionCancel.triggered.connect(self.cancel)

        # toolbar at the top of the screen: houses actions as buttons
        # change order here to change their placement on toolbar
        self.toolbar = self.addToolBar("Canvas actions")
        self.toolbar.setContextMenuPolicy(Qt.PreventContextMenu)
        self.toolbar.setMovable(False)
        self.toolbar.addAction(self.actionGet)
        self.toolbar.addAction(self.actionPan)
        self.toolbar.addAction(self.actionDraw)
        self.toolbar.addAction(self.actionConnect)
        self.toolbar.addAction(self.actionClear)
        self.toolbar.addAction(self.actionCancel)

        # link actions to premade map tools
        self.toolPan = QgsMapToolPan(self.canvas)
        self.toolPan.setAction(self.actionPan)
        self.toolDraw = PolygonMapTool(self.canvas)
        self.toolDraw.setAction(self.actionDraw)

        # set draw tool by default
        self.draw()

    def pan(self):
        """Simply activates the tool"""
        self.canvas.setMapTool(self.toolPan)
        # make sure the other button isn't checked to avoid confusion
        self.actionDraw.setChecked(False)

    def draw(self):
        """Activates draw tool"""
        self.canvas.setMapTool(self.toolDraw)
        self.actionPan.setChecked(False)

    def clear(self):
        self.toolDraw.reset()

    def connect(self):
        """Calls the polygon tool to connect an unconnected polygon"""
        self.toolDraw.finishPolygon()

    def finishedSelection(self):
        """Activated when user clicks 'returns selection'. Closes window
            and emits signal to indicate the job is finished"""
        self.close()
        self.finished.emit()

    def cancel(self):
        """In case user changes their mind. Does the same as above, but doesn't
            emit signal."""
        self.close()

    def showCanvas(self):
        """Shows the map canvas with a vector background map for reference"""
        """
        url = ("http://86.50.168.160/geoserver/ows?service=wfs&version=2.0.0"+ 
        "&request=GetFeature&typename=ogiir:maakuntajako_2018_4500k&pagingEnabled=true")
        #self.bg_layer = QgsVectorLayer(url, "BACKGROUND-REMOVE", "WFS")
        """
        self.bg_layer = QgsRasterLayer(
            "url=http://86.50.168.160/ogiir_cache/wmts/1.0.0/" +
            "WMTSCapabilities.xml&crs=EPSG:3067&dpiMode=7&format=image/" +
            "png&layers=taustakartta&styles=default&tileMatrixSet=GRIDI-FIN",
            'GEOCUBES POLYGON BG-LAYER - TEMPORARY', 'wms')

        if self.bg_layer.isValid():
            QgsProject.instance().addMapLayer(self.bg_layer, False)
            self.canvas.setExtent(self.bg_layer.extent())
            self.canvas.setLayers([self.bg_layer])
        self.show()

    def closeEvent(self, event):
        """Activated anytime Mapwindow is closed either programmatically or
            if the user finds some other way to close the window. Automatically
            finishes the polygon if it's unconnected."""
        try:
            QgsProject.instance().removeMapLayer(self.bg_layer)
        except Exception:
            pass
        self.toolDraw.finishPolygon()
        QMainWindow.closeEvent(self, event)

    def getPolygon(self):
        return self.toolDraw.getPoints()

    def getPolygonBbox(self):
        return self.toolDraw.getPolyBbox()
Beispiel #42
0
class ProcessingPlugin:
    def __init__(self, iface):
        self.iface = iface
        self.options_factory = ProcessingOptionsFactory()
        self.options_factory.setTitle(self.tr('Processing'))
        iface.registerOptionsWidgetFactory(self.options_factory)
        self.drop_handler = ProcessingDropHandler()
        iface.registerCustomDropHandler(self.drop_handler)
        self.item_provider = ProcessingDataItemProvider()
        QgsApplication.dataItemProviderRegistry().addProvider(
            self.item_provider)
        self.locator_filter = AlgorithmLocatorFilter()
        iface.registerLocatorFilter(self.locator_filter)
        Processing.initialize()

    def initGui(self):
        self.toolbox = ProcessingToolbox()
        self.iface.addDockWidget(Qt.RightDockWidgetArea, self.toolbox)
        self.toolbox.hide()
        self.toolbox.visibilityChanged.connect(self.toolboxVisibilityChanged)

        self.resultsDock = ResultsDock()
        self.iface.addDockWidget(Qt.RightDockWidgetArea, self.resultsDock)
        self.resultsDock.hide()

        resultsList.resultAdded.connect(self.resultsDock.fillTree)

        self.menu = QMenu(self.iface.mainWindow().menuBar())
        self.menu.setObjectName('processing')
        self.menu.setTitle(self.tr('Pro&cessing'))

        self.toolboxAction = QAction(self.tr('&Toolbox'),
                                     self.iface.mainWindow())
        self.toolboxAction.setCheckable(True)
        self.toolboxAction.setObjectName('toolboxAction')
        self.toolboxAction.setIcon(
            QgsApplication.getThemeIcon("/processingAlgorithm.svg"))
        self.iface.registerMainWindowAction(self.toolboxAction, 'Ctrl+Alt+T')
        self.toolboxAction.toggled.connect(self.openToolbox)
        self.iface.attributesToolBar().insertAction(
            self.iface.actionOpenStatisticalSummary(), self.toolboxAction)
        self.menu.addAction(self.toolboxAction)

        self.modelerAction = QAction(
            QgsApplication.getThemeIcon("/processingModel.svg"),
            self.tr('Graphical &Modeler...'), self.iface.mainWindow())
        self.modelerAction.setObjectName('modelerAction')
        self.modelerAction.triggered.connect(self.openModeler)
        self.iface.registerMainWindowAction(self.modelerAction, 'Ctrl+Alt+M')
        self.menu.addAction(self.modelerAction)

        self.historyAction = QAction(
            QIcon(os.path.join(cmd_folder, 'images', 'history.svg')),
            self.tr('&History...'), self.iface.mainWindow())
        self.historyAction.setObjectName('historyAction')
        self.historyAction.triggered.connect(self.openHistory)
        self.iface.registerMainWindowAction(self.historyAction, 'Ctrl+Alt+H')
        self.menu.addAction(self.historyAction)
        self.toolbox.processingToolbar.addAction(self.historyAction)

        self.resultsAction = self.resultsDock.toggleViewAction()
        self.resultsAction.setObjectName('resultsAction')
        self.resultsAction.setIcon(
            QgsApplication.getThemeIcon("/processingResult.svg"))
        self.resultsAction.setText(self.tr('&Results Viewer'))
        self.iface.registerMainWindowAction(self.resultsAction, 'Ctrl+Alt+R')
        self.menu.addAction(self.resultsAction)
        self.toolbox.processingToolbar.addAction(self.resultsAction)

        self.optionsAction = QAction(
            QgsApplication.getThemeIcon("/mActionOptions.svg"),
            self.tr('Options'), self.iface.mainWindow())
        self.optionsAction.setObjectName('optionsAction')
        self.optionsAction.triggered.connect(self.openProcessingOptions)
        self.toolbox.processingToolbar.addAction(self.optionsAction)

        menuBar = self.iface.mainWindow().menuBar()
        menuBar.insertMenu(self.iface.firstRightStandardMenu().menuAction(),
                           self.menu)

        self.menu.addSeparator()

        initializeMenus()
        createMenus()

    def openProcessingOptions(self):
        self.iface.showOptionsDialog(self.iface.mainWindow(),
                                     currentPage='processingOptions')

    def unload(self):
        self.toolbox.setVisible(False)
        self.iface.removeDockWidget(self.toolbox)
        self.iface.attributesToolBar().removeAction(self.toolboxAction)

        self.resultsDock.setVisible(False)
        self.iface.removeDockWidget(self.resultsDock)

        self.menu.deleteLater()

        # delete temporary output files
        folder = QgsProcessingUtils.tempFolder()
        if QDir(folder).exists():
            shutil.rmtree(folder, True)

        # also delete temporary help files
        folder = tempHelpFolder()
        if QDir(folder).exists():
            shutil.rmtree(folder, True)

        self.iface.unregisterMainWindowAction(self.toolboxAction)
        self.iface.unregisterMainWindowAction(self.modelerAction)
        self.iface.unregisterMainWindowAction(self.historyAction)
        self.iface.unregisterMainWindowAction(self.resultsAction)

        self.iface.unregisterOptionsWidgetFactory(self.options_factory)
        self.iface.deregisterLocatorFilter(self.locator_filter)
        self.iface.unregisterCustomDropHandler(self.drop_handler)
        QgsApplication.dataItemProviderRegistry().removeProvider(
            self.item_provider)

        removeMenus()
        Processing.deinitialize()

    def openToolbox(self, show):
        self.toolbox.setUserVisible(show)

    def toolboxVisibilityChanged(self, visible):
        self.toolboxAction.setChecked(visible)

    def openModeler(self):
        dlg = ModelerDialog()
        dlg.update_model.connect(self.updateModel)
        dlg.show()

    def updateModel(self):
        model_provider = QgsApplication.processingRegistry().providerById(
            'model')
        model_provider.refreshAlgorithms()

    def openResults(self):
        if self.resultsDock.isVisible():
            self.resultsDock.hide()
        else:
            self.resultsDock.show()

    def openHistory(self):
        dlg = HistoryDialog()
        dlg.exec_()

    def tr(self, message):
        return QCoreApplication.translate('ProcessingPlugin', message)
Beispiel #43
0
class SplinePlugin(object):
    def __init__(self, iface):
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.plugin_dir = os.path.dirname(__file__)
        self.proc_provider = None
        locale = QSettings().value("locale/userLocale")[0:2]
        locale_path = os.path.join(self.plugin_dir, "i18n",
                                   "splineplugin_{}.qm".format(locale))
        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)
            QCoreApplication.installTranslator(self.translator)

        self.tool = SplineTool(self.iface)
        self.connected_layer = None
        self.settings_dialog = None
        self.action_settings = None
        self.action_spline = None

    def initProcessing(self):
        self.proc_provider = proc_provider()
        QgsApplication.processingRegistry().addProvider(self.proc_provider)

    def initGui(self):
        self.initProcessing()
        self.action_settings = QAction(
            QCoreApplication.translate("Spline", "Settings"),
            self.iface.mainWindow())
        self.action_settings.setObjectName("splineAction")
        self.action_settings.triggered.connect(self.open_settings)

        self.iface.addPluginToVectorMenu(u"Digitize Spline",
                                         self.action_settings)

        ico = QIcon(icon_path("icon.png"))
        self.action_spline = QAction(
            ico,
            QCoreApplication.translate("spline", "Digitize Splines"),
            self.iface.mainWindow(),
        )
        self.action_spline.setObjectName("actionSpline")
        self.action_spline.setEnabled(False)
        self.action_spline.setCheckable(True)

        # Connect to signals for button behaviour
        self.action_spline.triggered.connect(self.digitize)
        self.iface.currentLayerChanged.connect(self.layer_changed)
        self.layer_changed()  # to enable when plugin is loaded

        self.canvas.mapToolSet.connect(self.deactivate)

        # Add actions to the toolbar
        self.iface.addToolBarIcon(self.action_spline)

    def unload(self):
        QgsApplication.processingRegistry().removeProvider(self.proc_provider)
        self.iface.removeToolBarIcon(self.action_spline)
        self.iface.removePluginVectorMenu(u"Digitize Spline",
                                          self.action_settings)

    def open_settings(self):
        self.settings_dialog = SettingsDialog()
        self.settings_dialog.changed.connect(self.settings_changed)
        self.settings_dialog.show()

    def digitize(self):
        self.canvas.setMapTool(self.tool)
        self.action_spline.setChecked(True)

    def is_active_layer_for_spline(self):
        layer = self.iface.activeLayer()
        if layer is None:
            return False
        if layer.type() != QgsMapLayerType.VectorLayer:
            return False
        if not layer.geometryType() in (
                QgsWkbTypes.LineGeometry,
                QgsWkbTypes.PolygonGeometry,
        ):
            return False
        return True

    def enable_action(self):
        self.action_spline.setEnabled(False)
        self.action_spline.setChecked(False)
        if self.is_active_layer_for_spline():
            if self.iface.activeLayer().isEditable():
                self.action_spline.setEnabled(True)

    def layer_changed(self):
        self.deactivate()
        self.tool.deactivate()
        self.enable_action()
        self.connect_layer()

    def connect_layer(self):
        self.disconnect_layer()
        if not self.is_active_layer_for_spline():
            return
        layer = self.iface.activeLayer()
        if layer is None:
            return
        self.connected_layer = layer
        layer.editingStopped.connect(self.enable_action)
        layer.editingStarted.connect(self.enable_action)

    def disconnect_layer(self):
        try:
            self.connected_layer.editingStopped.disconnect(self.enable_action)
            self.connected_layer.editingStarted.disconnect(self.enable_action)
        except (RuntimeError, AttributeError, TypeError):
            pass
        self.connected_layer = None

    def deactivate(self):
        self.tool.deactivate()
        self.action_spline.setChecked(False)

    def settings_changed(self):
        self.tool.refresh()
Beispiel #44
0
class PythonConsoleWidget(QWidget):

    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setWindowTitle(QCoreApplication.translate("PythonConsole", "Python Console"))

        self.settings = QgsSettings()

        self.shell = ShellScintilla(self)
        self.setFocusProxy(self.shell)
        self.shellOut = ShellOutputScintilla(self)
        self.tabEditorWidget = EditorTabWidget(self)

        # ------------ UI -------------------------------

        self.splitterEditor = QSplitter(self)
        self.splitterEditor.setOrientation(Qt.Horizontal)
        self.splitterEditor.setHandleWidth(6)
        self.splitterEditor.setChildrenCollapsible(True)

        self.shellOutWidget = QWidget(self)
        self.shellOutWidget.setLayout(QVBoxLayout())
        self.shellOutWidget.layout().setContentsMargins(0, 0, 0, 0)
        self.shellOutWidget.layout().addWidget(self.shellOut)

        self.splitter = QSplitter(self.splitterEditor)
        self.splitter.setOrientation(Qt.Vertical)
        self.splitter.setHandleWidth(3)
        self.splitter.setChildrenCollapsible(False)
        self.splitter.addWidget(self.shellOutWidget)
        self.splitter.addWidget(self.shell)

        # self.splitterEditor.addWidget(self.tabEditorWidget)

        self.splitterObj = QSplitter(self.splitterEditor)
        self.splitterObj.setHandleWidth(3)
        self.splitterObj.setOrientation(Qt.Horizontal)
        # self.splitterObj.setSizes([0, 0])
        # self.splitterObj.setStretchFactor(0, 1)

        self.widgetEditor = QWidget(self.splitterObj)
        self.widgetFind = QWidget(self)

        self.listClassMethod = QTreeWidget(self.splitterObj)
        self.listClassMethod.setColumnCount(2)
        objInspLabel = QCoreApplication.translate("PythonConsole", "Object Inspector")
        self.listClassMethod.setHeaderLabels([objInspLabel, ''])
        self.listClassMethod.setColumnHidden(1, True)
        self.listClassMethod.setAlternatingRowColors(True)

        # self.splitterEditor.addWidget(self.widgetEditor)
        # self.splitterObj.addWidget(self.listClassMethod)
        # self.splitterObj.addWidget(self.widgetEditor)

        # Hide side editor on start up
        self.splitterObj.hide()
        self.listClassMethod.hide()
        # Hide search widget on start up
        self.widgetFind.hide()

        icon_size = iface.iconSize(dockedToolbar=True) if iface else QSize(16, 16)

        sizes = self.splitter.sizes()
        self.splitter.setSizes(sizes)

        # ----------------Restore Settings------------------------------------

        self.restoreSettingsConsole()

        # ------------------Toolbar Editor-------------------------------------

        # Action for Open File
        openFileBt = QCoreApplication.translate("PythonConsole", "Open Script…")
        self.openFileButton = QAction(self)
        self.openFileButton.setCheckable(False)
        self.openFileButton.setEnabled(True)
        self.openFileButton.setIcon(QgsApplication.getThemeIcon("console/iconOpenConsole.svg"))
        self.openFileButton.setMenuRole(QAction.PreferencesRole)
        self.openFileButton.setIconVisibleInMenu(True)
        self.openFileButton.setToolTip(openFileBt)
        self.openFileButton.setText(openFileBt)

        openExtEditorBt = QCoreApplication.translate("PythonConsole", "Open in External Editor")
        self.openInEditorButton = QAction(self)
        self.openInEditorButton.setCheckable(False)
        self.openInEditorButton.setEnabled(True)
        self.openInEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconShowEditorConsole.svg"))
        self.openInEditorButton.setMenuRole(QAction.PreferencesRole)
        self.openInEditorButton.setIconVisibleInMenu(True)
        self.openInEditorButton.setToolTip(openExtEditorBt)
        self.openInEditorButton.setText(openExtEditorBt)
        # Action for Save File
        saveFileBt = QCoreApplication.translate("PythonConsole", "Save")
        self.saveFileButton = QAction(self)
        self.saveFileButton.setCheckable(False)
        self.saveFileButton.setEnabled(False)
        self.saveFileButton.setIcon(QgsApplication.getThemeIcon("console/iconSaveConsole.svg"))
        self.saveFileButton.setMenuRole(QAction.PreferencesRole)
        self.saveFileButton.setIconVisibleInMenu(True)
        self.saveFileButton.setToolTip(saveFileBt)
        self.saveFileButton.setText(saveFileBt)
        # Action for Save File As
        saveAsFileBt = QCoreApplication.translate("PythonConsole", "Save As…")
        self.saveAsFileButton = QAction(self)
        self.saveAsFileButton.setCheckable(False)
        self.saveAsFileButton.setEnabled(True)
        self.saveAsFileButton.setIcon(QgsApplication.getThemeIcon("console/iconSaveAsConsole.svg"))
        self.saveAsFileButton.setMenuRole(QAction.PreferencesRole)
        self.saveAsFileButton.setIconVisibleInMenu(True)
        self.saveAsFileButton.setToolTip(saveAsFileBt)
        self.saveAsFileButton.setText(saveAsFileBt)
        # Action Cut
        cutEditorBt = QCoreApplication.translate("PythonConsole", "Cut")
        self.cutEditorButton = QAction(self)
        self.cutEditorButton.setCheckable(False)
        self.cutEditorButton.setEnabled(True)
        self.cutEditorButton.setIcon(QgsApplication.getThemeIcon("mActionEditCut.svg"))
        self.cutEditorButton.setMenuRole(QAction.PreferencesRole)
        self.cutEditorButton.setIconVisibleInMenu(True)
        self.cutEditorButton.setToolTip(cutEditorBt)
        self.cutEditorButton.setText(cutEditorBt)
        # Action Copy
        copyEditorBt = QCoreApplication.translate("PythonConsole", "Copy")
        self.copyEditorButton = QAction(self)
        self.copyEditorButton.setCheckable(False)
        self.copyEditorButton.setEnabled(True)
        self.copyEditorButton.setIcon(QgsApplication.getThemeIcon("mActionEditCopy.svg"))
        self.copyEditorButton.setMenuRole(QAction.PreferencesRole)
        self.copyEditorButton.setIconVisibleInMenu(True)
        self.copyEditorButton.setToolTip(copyEditorBt)
        self.copyEditorButton.setText(copyEditorBt)
        # Action Paste
        pasteEditorBt = QCoreApplication.translate("PythonConsole", "Paste")
        self.pasteEditorButton = QAction(self)
        self.pasteEditorButton.setCheckable(False)
        self.pasteEditorButton.setEnabled(True)
        self.pasteEditorButton.setIcon(QgsApplication.getThemeIcon("mActionEditPaste.svg"))
        self.pasteEditorButton.setMenuRole(QAction.PreferencesRole)
        self.pasteEditorButton.setIconVisibleInMenu(True)
        self.pasteEditorButton.setToolTip(pasteEditorBt)
        self.pasteEditorButton.setText(pasteEditorBt)
        # Action Run Script (subprocess)
        runScriptEditorBt = QCoreApplication.translate("PythonConsole", "Run Script")
        self.runScriptEditorButton = QAction(self)
        self.runScriptEditorButton.setCheckable(False)
        self.runScriptEditorButton.setEnabled(True)
        self.runScriptEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconRunScriptConsole.svg"))
        self.runScriptEditorButton.setMenuRole(QAction.PreferencesRole)
        self.runScriptEditorButton.setIconVisibleInMenu(True)
        self.runScriptEditorButton.setToolTip(runScriptEditorBt)
        self.runScriptEditorButton.setText(runScriptEditorBt)
        # Action Run Script (subprocess)
        commentEditorBt = QCoreApplication.translate("PythonConsole", "Comment")
        self.commentEditorButton = QAction(self)
        self.commentEditorButton.setCheckable(False)
        self.commentEditorButton.setEnabled(True)
        self.commentEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconCommentEditorConsole.svg"))
        self.commentEditorButton.setMenuRole(QAction.PreferencesRole)
        self.commentEditorButton.setIconVisibleInMenu(True)
        self.commentEditorButton.setToolTip(commentEditorBt)
        self.commentEditorButton.setText(commentEditorBt)
        # Action Run Script (subprocess)
        uncommentEditorBt = QCoreApplication.translate("PythonConsole", "Uncomment")
        self.uncommentEditorButton = QAction(self)
        self.uncommentEditorButton.setCheckable(False)
        self.uncommentEditorButton.setEnabled(True)
        self.uncommentEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconUncommentEditorConsole.svg"))
        self.uncommentEditorButton.setMenuRole(QAction.PreferencesRole)
        self.uncommentEditorButton.setIconVisibleInMenu(True)
        self.uncommentEditorButton.setToolTip(uncommentEditorBt)
        self.uncommentEditorButton.setText(uncommentEditorBt)
        # Action for Object browser
        objList = QCoreApplication.translate("PythonConsole", "Object Inspector…")
        self.objectListButton = QAction(self)
        self.objectListButton.setCheckable(True)
        self.objectListButton.setEnabled(self.settings.value("pythonConsole/enableObjectInsp",
                                                             False, type=bool))
        self.objectListButton.setIcon(QgsApplication.getThemeIcon("console/iconClassBrowserConsole.svg"))
        self.objectListButton.setMenuRole(QAction.PreferencesRole)
        self.objectListButton.setIconVisibleInMenu(True)
        self.objectListButton.setToolTip(objList)
        self.objectListButton.setText(objList)
        # Action for Find text
        findText = QCoreApplication.translate("PythonConsole", "Find Text")
        self.findTextButton = QAction(self)
        self.findTextButton.setCheckable(True)
        self.findTextButton.setEnabled(True)
        self.findTextButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchEditorConsole.svg"))
        self.findTextButton.setMenuRole(QAction.PreferencesRole)
        self.findTextButton.setIconVisibleInMenu(True)
        self.findTextButton.setToolTip(findText)
        self.findTextButton.setText(findText)

        # ----------------Toolbar Console-------------------------------------

        # Action Show Editor
        showEditor = QCoreApplication.translate("PythonConsole", "Show Editor")
        self.showEditorButton = QAction(self)
        self.showEditorButton.setEnabled(True)
        self.showEditorButton.setCheckable(True)
        self.showEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconShowEditorConsole.svg"))
        self.showEditorButton.setMenuRole(QAction.PreferencesRole)
        self.showEditorButton.setIconVisibleInMenu(True)
        self.showEditorButton.setToolTip(showEditor)
        self.showEditorButton.setText(showEditor)
        # Action for Clear button
        clearBt = QCoreApplication.translate("PythonConsole", "Clear Console")
        self.clearButton = QAction(self)
        self.clearButton.setCheckable(False)
        self.clearButton.setEnabled(True)
        self.clearButton.setIcon(QgsApplication.getThemeIcon("console/iconClearConsole.svg"))
        self.clearButton.setMenuRole(QAction.PreferencesRole)
        self.clearButton.setIconVisibleInMenu(True)
        self.clearButton.setToolTip(clearBt)
        self.clearButton.setText(clearBt)
        # Action for settings
        optionsBt = QCoreApplication.translate("PythonConsole", "Options…")
        self.optionsButton = QAction(self)
        self.optionsButton.setCheckable(False)
        self.optionsButton.setEnabled(True)
        self.optionsButton.setIcon(QgsApplication.getThemeIcon("console/iconSettingsConsole.svg"))
        self.optionsButton.setMenuRole(QAction.PreferencesRole)
        self.optionsButton.setIconVisibleInMenu(True)
        self.optionsButton.setToolTip(optionsBt)
        self.optionsButton.setText(optionsBt)
        # Action for Run script
        runBt = QCoreApplication.translate("PythonConsole", "Run Command")
        self.runButton = QAction(self)
        self.runButton.setCheckable(False)
        self.runButton.setEnabled(True)
        self.runButton.setIcon(QgsApplication.getThemeIcon("console/mIconRunConsole.svg"))
        self.runButton.setMenuRole(QAction.PreferencesRole)
        self.runButton.setIconVisibleInMenu(True)
        self.runButton.setToolTip(runBt)
        self.runButton.setText(runBt)
        # Help action
        helpBt = QCoreApplication.translate("PythonConsole", "Help…")
        self.helpButton = QAction(self)
        self.helpButton.setCheckable(False)
        self.helpButton.setEnabled(True)
        self.helpButton.setIcon(QgsApplication.getThemeIcon("console/iconHelpConsole.svg"))
        self.helpButton.setMenuRole(QAction.PreferencesRole)
        self.helpButton.setIconVisibleInMenu(True)
        self.helpButton.setToolTip(helpBt)
        self.helpButton.setText(helpBt)

        self.toolBar = QToolBar()
        self.toolBar.setEnabled(True)
        self.toolBar.setFocusPolicy(Qt.NoFocus)
        self.toolBar.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.toolBar.setLayoutDirection(Qt.LeftToRight)
        self.toolBar.setIconSize(icon_size)
        self.toolBar.setMovable(False)
        self.toolBar.setFloatable(False)
        self.toolBar.addAction(self.clearButton)
        self.toolBar.addAction(self.runButton)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.showEditorButton)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.optionsButton)
        self.toolBar.addAction(self.helpButton)

        self.toolBarEditor = QToolBar()
        self.toolBarEditor.setEnabled(False)
        self.toolBarEditor.setFocusPolicy(Qt.NoFocus)
        self.toolBarEditor.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.toolBarEditor.setLayoutDirection(Qt.LeftToRight)
        self.toolBarEditor.setIconSize(icon_size)
        self.toolBarEditor.setMovable(False)
        self.toolBarEditor.setFloatable(False)
        self.toolBarEditor.addAction(self.openFileButton)
        self.toolBarEditor.addAction(self.openInEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.saveFileButton)
        self.toolBarEditor.addAction(self.saveAsFileButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.runScriptEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.findTextButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.cutEditorButton)
        self.toolBarEditor.addAction(self.copyEditorButton)
        self.toolBarEditor.addAction(self.pasteEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.commentEditorButton)
        self.toolBarEditor.addAction(self.uncommentEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.objectListButton)

        self.widgetButton = QWidget()
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.widgetButton.sizePolicy().hasHeightForWidth())
        self.widgetButton.setSizePolicy(sizePolicy)

        self.widgetButtonEditor = QWidget(self.widgetEditor)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.widgetButtonEditor.sizePolicy().hasHeightForWidth())
        self.widgetButtonEditor.setSizePolicy(sizePolicy)

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.shellOut.sizePolicy().hasHeightForWidth())
        self.shellOut.setSizePolicy(sizePolicy)

        self.shellOut.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.shell.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)

        # ------------ Layout -------------------------------

        self.mainLayout = QGridLayout(self)
        self.mainLayout.setMargin(0)
        self.mainLayout.setSpacing(0)
        self.mainLayout.addWidget(self.widgetButton, 0, 0, 1, 1)
        self.mainLayout.addWidget(self.splitterEditor, 0, 1, 1, 1)

        self.shellOutWidget.layout().insertWidget(0, self.toolBar)

        self.layoutEditor = QGridLayout(self.widgetEditor)
        self.layoutEditor.setMargin(0)
        self.layoutEditor.setSpacing(0)
        self.layoutEditor.addWidget(self.toolBarEditor, 0, 1, 1, 1)
        self.layoutEditor.addWidget(self.widgetButtonEditor, 1, 0, 2, 1)
        self.layoutEditor.addWidget(self.tabEditorWidget, 1, 1, 1, 1)
        self.layoutEditor.addWidget(self.widgetFind, 2, 1, 1, 1)

        #  Layout for the find widget
        self.layoutFind = QGridLayout(self.widgetFind)
        self.layoutFind.setContentsMargins(0, 0, 0, 0)
        self.lineEditFind = QgsFilterLineEdit()
        placeHolderTxt = QCoreApplication.translate("PythonConsole", "Enter text to find…")

        self.lineEditFind.setPlaceholderText(placeHolderTxt)
        self.toolBarFindText = QToolBar()
        self.toolBarFindText.setIconSize(icon_size)
        self.findNextButton = QAction(self)
        self.findNextButton.setEnabled(False)
        toolTipfindNext = QCoreApplication.translate("PythonConsole", "Find Next")
        self.findNextButton.setToolTip(toolTipfindNext)
        self.findNextButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchNextEditorConsole.svg"))
        self.findPrevButton = QAction(self)
        self.findPrevButton.setEnabled(False)
        toolTipfindPrev = QCoreApplication.translate("PythonConsole", "Find Previous")
        self.findPrevButton.setToolTip(toolTipfindPrev)
        self.findPrevButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchPrevEditorConsole.svg"))
        self.caseSensitive = QCheckBox()
        caseSensTr = QCoreApplication.translate("PythonConsole", "Case Sensitive")
        self.caseSensitive.setText(caseSensTr)
        self.wholeWord = QCheckBox()
        wholeWordTr = QCoreApplication.translate("PythonConsole", "Whole Word")
        self.wholeWord.setText(wholeWordTr)
        self.wrapAround = QCheckBox()
        self.wrapAround.setChecked(True)
        wrapAroundTr = QCoreApplication.translate("PythonConsole", "Wrap Around")
        self.wrapAround.setText(wrapAroundTr)

        self.toolBarFindText.addWidget(self.lineEditFind)
        self.toolBarFindText.addAction(self.findPrevButton)
        self.toolBarFindText.addAction(self.findNextButton)
        self.toolBarFindText.addWidget(self.caseSensitive)
        self.toolBarFindText.addWidget(self.wholeWord)
        self.toolBarFindText.addWidget(self.wrapAround)

        self.layoutFind.addWidget(self.toolBarFindText, 0, 1, 1, 1)

        # ------------ Add first Tab in Editor -------------------------------

        # self.tabEditorWidget.newTabEditor(tabName='first', filename=None)

        # ------------ Signal -------------------------------

        self.findTextButton.triggered.connect(self._toggleFind)
        self.objectListButton.toggled.connect(self.toggleObjectListWidget)
        self.commentEditorButton.triggered.connect(self.commentCode)
        self.uncommentEditorButton.triggered.connect(self.uncommentCode)
        self.runScriptEditorButton.triggered.connect(self.runScriptEditor)
        self.cutEditorButton.triggered.connect(self.cutEditor)
        self.copyEditorButton.triggered.connect(self.copyEditor)
        self.pasteEditorButton.triggered.connect(self.pasteEditor)
        self.showEditorButton.toggled.connect(self.toggleEditor)
        self.clearButton.triggered.connect(self.shellOut.clearConsole)
        self.optionsButton.triggered.connect(self.openSettings)
        self.runButton.triggered.connect(self.shell.entered)
        self.openFileButton.triggered.connect(self.openScriptFile)
        self.openInEditorButton.triggered.connect(self.openScriptFileExtEditor)
        self.saveFileButton.triggered.connect(self.saveScriptFile)
        self.saveAsFileButton.triggered.connect(self.saveAsScriptFile)
        self.helpButton.triggered.connect(self.openHelp)
        self.listClassMethod.itemClicked.connect(self.onClickGoToLine)
        self.lineEditFind.returnPressed.connect(self._findNext)
        self.findNextButton.triggered.connect(self._findNext)
        self.findPrevButton.triggered.connect(self._findPrev)
        self.lineEditFind.textChanged.connect(self._textFindChanged)

        self.findScut = QShortcut(QKeySequence.Find, self.widgetEditor)
        self.findScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findScut.activated.connect(self._openFind)

        self.findNextScut = QShortcut(QKeySequence.FindNext, self.widgetEditor)
        self.findNextScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findNextScut.activated.connect(self._findNext)

        self.findPreviousScut = QShortcut(QKeySequence.FindPrevious, self.widgetEditor)
        self.findPreviousScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findPreviousScut.activated.connect(self._findPrev)

        # Escape on editor hides the find bar
        self.findScut = QShortcut(Qt.Key_Escape, self.widgetEditor)
        self.findScut.setContext(Qt.WidgetWithChildrenShortcut)
        self.findScut.activated.connect(self._closeFind)

    def _toggleFind(self):
        self.tabEditorWidget.currentWidget().newEditor.toggleFindWidget()

    def _openFind(self):
        self.tabEditorWidget.currentWidget().newEditor.openFindWidget()

    def _closeFind(self):
        self.tabEditorWidget.currentWidget().newEditor.closeFindWidget()

    def _findNext(self):
        self.tabEditorWidget.currentWidget().newEditor.findText(True)

    def _findPrev(self):
        self.tabEditorWidget.currentWidget().newEditor.findText(False)

    def _textFindChanged(self):
        if self.lineEditFind.text():
            self.findNextButton.setEnabled(True)
            self.findPrevButton.setEnabled(True)
            self.tabEditorWidget.currentWidget().newEditor.findText(True, showMessage=False, findFirst=True)
        else:
            self.lineEditFind.setStyleSheet('')
            self.findNextButton.setEnabled(False)
            self.findPrevButton.setEnabled(False)

    def onClickGoToLine(self, item, column):
        tabEditor = self.tabEditorWidget.currentWidget().newEditor
        if item.text(1) == 'syntaxError':
            check = tabEditor.syntaxCheck(fromContextMenu=False)
            if check and not tabEditor.isReadOnly():
                self.tabEditorWidget.currentWidget().save()
            return
        linenr = int(item.text(1))
        itemName = str(item.text(0))
        charPos = itemName.find(' ')
        if charPos != -1:
            objName = itemName[0:charPos]
        else:
            objName = itemName
        tabEditor.goToLine(objName, linenr)

    def toggleEditor(self, checked):
        self.splitterObj.show() if checked else self.splitterObj.hide()
        if not self.tabEditorWidget:
            self.tabEditorWidget.enableToolBarEditor(checked)
            self.tabEditorWidget.restoreTabsOrAddNew()

    def toggleObjectListWidget(self, checked):
        self.listClassMethod.show() if checked else self.listClassMethod.hide()

    def pasteEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.paste()

    def cutEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.cut()

    def copyEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.copy()

    def runScriptEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.runScriptCode()

    def commentCode(self):
        self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(True)

    def uncommentCode(self):
        self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(False)

    def openScriptFileExtEditor(self):
        tabWidget = self.tabEditorWidget.currentWidget()
        path = tabWidget.path
        import subprocess
        try:
            subprocess.Popen([os.environ['EDITOR'], path])
        except KeyError:
            QDesktopServices.openUrl(QUrl.fromLocalFile(path))

    def openScriptFile(self):
        lastDirPath = self.settings.value("pythonConsole/lastDirPath", QDir.homePath())
        openFileTr = QCoreApplication.translate("PythonConsole", "Open File")
        fileList, selected_filter = QFileDialog.getOpenFileNames(
            self, openFileTr, lastDirPath, "Script file (*.py)")
        if fileList:
            for pyFile in fileList:
                for i in range(self.tabEditorWidget.count()):
                    tabWidget = self.tabEditorWidget.widget(i)
                    if tabWidget.path == pyFile:
                        self.tabEditorWidget.setCurrentWidget(tabWidget)
                        break
                else:
                    tabName = QFileInfo(pyFile).fileName()
                    self.tabEditorWidget.newTabEditor(tabName, pyFile)

                    lastDirPath = QFileInfo(pyFile).path()
                    self.settings.setValue("pythonConsole/lastDirPath", pyFile)
                    self.updateTabListScript(pyFile, action='append')

    def saveScriptFile(self):
        tabWidget = self.tabEditorWidget.currentWidget()
        try:
            tabWidget.save()
        except (IOError, OSError) as error:
            msgText = QCoreApplication.translate('PythonConsole',
                                                 'The file <b>{0}</b> could not be saved. Error: {1}').format(tabWidget.path,
                                                                                                              error.strerror)
            self.callWidgetMessageBarEditor(msgText, 2, False)

    def saveAsScriptFile(self, index=None):
        tabWidget = self.tabEditorWidget.currentWidget()
        if not index:
            index = self.tabEditorWidget.currentIndex()
        if not tabWidget.path:
            fileName = self.tabEditorWidget.tabText(index) + '.py'
            folder = self.settings.value("pythonConsole/lastDirPath", QDir.homePath())
            pathFileName = os.path.join(folder, fileName)
            fileNone = True
        else:
            pathFileName = tabWidget.path
            fileNone = False
        saveAsFileTr = QCoreApplication.translate("PythonConsole", "Save File As")
        filename, filter = QFileDialog.getSaveFileName(self,
                                                       saveAsFileTr,
                                                       pathFileName, "Script file (*.py)")
        if filename:
            try:
                tabWidget.save(filename)
            except (IOError, OSError) as error:
                msgText = QCoreApplication.translate('PythonConsole',
                                                     'The file <b>{0}</b> could not be saved. Error: {1}').format(tabWidget.path,
                                                                                                                  error.strerror)
                self.callWidgetMessageBarEditor(msgText, 2, False)
                if fileNone:
                    tabWidget.path = None
                else:
                    tabWidget.path = pathFileName
                return

            if not fileNone:
                self.updateTabListScript(pathFileName, action='remove')

    def openHelp(self):
        QgsHelp.openHelp("plugins/python_console.html")

    def openSettings(self):
        if optionsDialog(self).exec_():
            self.shell.refreshSettingsShell()
            self.shellOut.refreshSettingsOutput()
            self.tabEditorWidget.refreshSettingsEditor()

    def callWidgetMessageBar(self, text):
        self.shellOut.widgetMessageBar(iface, text)

    def callWidgetMessageBarEditor(self, text, level, timed):
        self.tabEditorWidget.widgetMessageBar(iface, text, level, timed)

    def updateTabListScript(self, script, action=None):
        if action == 'remove':
            self.tabListScript.remove(script)
        elif action == 'append':
            if not self.tabListScript:
                self.tabListScript = []
            if script not in self.tabListScript:
                self.tabListScript.append(script)
        else:
            self.tabListScript = []
        self.settings.setValue("pythonConsole/tabScripts",
                               self.tabListScript)

    def saveSettingsConsole(self):
        self.settings.setValue("pythonConsole/splitterConsole", self.splitter.saveState())
        self.settings.setValue("pythonConsole/splitterObj", self.splitterObj.saveState())
        self.settings.setValue("pythonConsole/splitterEditor", self.splitterEditor.saveState())

        self.shell.writeHistoryFile(True)

    def restoreSettingsConsole(self):
        storedTabScripts = self.settings.value("pythonConsole/tabScripts", [])
        self.tabListScript = storedTabScripts
        self.splitter.restoreState(self.settings.value("pythonConsole/splitterConsole", QByteArray()))
        self.splitterEditor.restoreState(self.settings.value("pythonConsole/splitterEditor", QByteArray()))
        self.splitterObj.restoreState(self.settings.value("pythonConsole/splitterObj", QByteArray()))
Beispiel #45
0
class proposalsPanel(RestrictionTypeUtilsMixin):
    def __init__(self, iface, TOMsToolBar):
        #def __init__(self, iface, TOMsMenu, proposalsManager):

        # Save reference to the QGIS interface
        self.iface = iface
        self.canvas = self.iface.mapCanvas()
        self.TOMsToolBar = TOMsToolBar

        self.actionProposalsPanel = QAction(
            QIcon(":/plugins/TOMs/resources/TOMsStart.png"),
            QCoreApplication.translate("MyPlugin", "Start TOMs"),
            self.iface.mainWindow())
        self.actionProposalsPanel.setCheckable(True)

        self.TOMsToolBar.addAction(self.actionProposalsPanel)

        self.actionProposalsPanel.triggered.connect(self.onInitProposalsPanel)

        self.newProposalRequired = False

        self.proposalsManager = TOMsProposalsManager(self.iface)
        self.tableNames = self.proposalsManager.tableNames

        # Now set up the toolbar

        self.RestrictionTools = manageRestrictionDetails(
            self.iface, self.TOMsToolBar, self.proposalsManager)
        self.RestrictionTools.disableTOMsToolbarItems()
        self.searchBar = searchBar(self.iface, self.TOMsToolBar,
                                   self.proposalsManager)
        self.searchBar.disableSearchBar()

        TOMsMessageLog.logMessage("Finished proposalsPanel init ...",
                                  level=Qgis.Warning)

    def onInitProposalsPanel(self):
        """Filter main layer based on date and state options"""

        TOMsMessageLog.logMessage("In onInitProposalsPanel", level=Qgis.Info)

        #print "** STARTING ProposalPanel"

        # dockwidget may not exist if:
        #    first run of plugin
        #    removed on close (see self.onClosePlugin method)

        # self.TOMSLayers.TOMsStartupFailure.connect(self.setCloseTOMsFlag)
        #self.RestrictionTypeUtilsMixin.tableNames.TOMsStartupFailure.connect(self.closeTOMsTools)

        if self.actionProposalsPanel.isChecked():

            TOMsMessageLog.logMessage(
                "In onInitProposalsPanel. Activating ...", level=Qgis.Info)

            self.openTOMsTools()

        else:

            TOMsMessageLog.logMessage(
                "In onInitProposalsPanel. Deactivating ...", level=Qgis.Info)

            self.closeTOMsTools()

        pass

    def openTOMsTools(self):
        # actions when the Proposals Panel is closed or the toolbar "start" is toggled

        TOMsMessageLog.logMessage("In openTOMsTools. Activating ...",
                                  level=Qgis.Info)
        self.closeTOMs = False

        # Check that tables are present
        TOMsMessageLog.logMessage("In onInitProposalsPanel. Checking tables",
                                  level=Qgis.Info)
        self.tableNames.TOMsLayersNotFound.connect(self.setCloseTOMsFlag)

        self.tableNames.getLayers()

        if self.closeTOMs:
            QMessageBox.information(self.iface.mainWindow(), "ERROR",
                                    ("Unable to start TOMs ..."))
            self.actionProposalsPanel.setChecked(False)
            return

            # QMessageBox.information(self.iface.mainWindow(), "ERROR", ("TOMsActivated about to emit"))
        self.proposalsManager.TOMsActivated.emit()

        self.dock = ProposalPanelDockWidget()
        self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dock)

        # set up tabbing for Panels
        self.setupPanelTabs(self.iface, self.dock)

        self.proposalsManager.dateChanged.connect(self.onDateChanged)
        self.dock.filterDate.setDisplayFormat("dd-MM-yyyy")
        self.dock.filterDate.setDate(QDate.currentDate())

        self.Proposals = self.tableNames.setLayer("Proposals")

        # Set up field details for table  ** what about errors here **
        idxProposalID = self.Proposals.fields().indexFromName("ProposalID")
        self.idxProposalTitle = self.Proposals.fields().indexFromName(
            "ProposalTitle")
        self.idxCreateDate = self.Proposals.fields().indexFromName(
            "ProposalCreateDate")
        self.idxOpenDate = self.Proposals.fields().indexFromName(
            "ProposalOpenDate")
        self.idxProposalStatusID = self.Proposals.fields().indexFromName(
            "ProposalStatusID")

        self.createProposalcb()

        # set CurrentProposal to be 0

        #self.proposalsManager.setCurrentProposal(0)

        # set up action for when the date is changed from the user interface
        self.dock.filterDate.dateChanged.connect(
            lambda: self.proposalsManager.setDate(self.dock.filterDate.date()))

        # set up action for "New Proposal"
        self.dock.btn_NewProposal.clicked.connect(self.onNewProposal)

        # set up action for "View Proposal"
        self.dock.btn_ViewProposal.clicked.connect(self.onProposalDetails)

        self.proposalsManager.newProposalCreated.connect(
            self.onNewProposalCreated)

        # Create a transaction object for the Proposals

        self.proposalTransaction = TOMsTransaction(self.iface,
                                                   self.proposalsManager)

        self.RestrictionTools.enableTOMsToolbarItems(self.proposalTransaction)
        self.searchBar.enableSearchBar()

        # setup use of "Escape" key to deactive map tools - https://gis.stackexchange.com/questions/133228/how-to-deactivate-my-custom-tool-by-pressing-the-escape-key-using-pyqgis
        """shortcutEsc = QShortcut(QKeySequence(Qt.Key_Escape), self.iface.mainWindow())
        shortcutEsc.setContext(Qt.ApplicationShortcut)
        shortcutEsc.activated.connect(self.iface.mapCanvas().unsetMapTool(self.mapTool))"""
        self.proposalsManager.setCurrentProposal(0)

        # TODO: Deal with the change of project ... More work required on this
        # self.TOMsProject = QgsProject.instance()
        # self.TOMsProject.cleared.connect(self.closeTOMsTools)

    def setCloseTOMsFlag(self):
        self.closeTOMs = True

    def closeTOMsTools(self):
        # actions when the Proposals Panel is closed or the toolbar "start" is toggled

        TOMsMessageLog.logMessage("In closeTOMsTools. Deactivating ...",
                                  level=Qgis.Info)

        # TODO: Delete any objects that are no longer needed

        self.proposalTransaction.rollBackTransactionGroup()
        del self.proposalTransaction  # There is another call to this function from the dock.close()

        # Now disable the items from the Toolbar

        self.RestrictionTools.disableTOMsToolbarItems()
        self.searchBar.disableSearchBar()

        self.actionProposalsPanel.setChecked(False)

        # Now close the proposals panel

        self.dock.close()

        # Now clear the filters

        self.proposalsManager.clearRestrictionFilters()

        pass

    def createProposalcb(self):

        TOMsMessageLog.logMessage("In createProposalcb", level=Qgis.Info)
        # set up a "NULL" field for "No proposals to be shown"

        #self.dock.cb_ProposalsList.currentIndexChanged.connect(self.onProposalListIndexChanged)
        #self.dock.cb_ProposalsList.currentIndexChanged.disconnect(self.onProposalListIndexChanged)

        self.dock.cb_ProposalsList.clear()

        currProposalID = 0
        currProposalTitle = "0 - No proposal shown"

        TOMsMessageLog.logMessage("In createProposalcb: Adding 0",
                                  level=Qgis.Info)

        self.dock.cb_ProposalsList.addItem(currProposalTitle, currProposalID)

        for (currProposalID, currProposalTitle, currProposalStatusID,
             currProposalOpenDate, currProposal) in sorted(
                 self.proposalsManager.getProposalsListWithStatus(
                     ProposalStatus.IN_PREPARATION),
                 key=lambda f: f[1]):
            TOMsMessageLog.logMessage("In createProposalcb: proposalID: " +
                                      str(currProposalID) + ":" +
                                      currProposalTitle,
                                      level=Qgis.Info)
            self.dock.cb_ProposalsList.addItem(currProposalTitle,
                                               currProposalID)

        # set up action for when the proposal is changed
        self.dock.cb_ProposalsList.currentIndexChanged.connect(
            self.onProposalListIndexChanged)

    def onChangeProposal(self):
        TOMsMessageLog.logMessage("In onChangeProposal", level=Qgis.Info)

        # https://gis.stackexchange.com/questions/94135/how-to-populate-a-combobox-with-layers-in-toc
        newProposal_cbIndex = self.dock.cb_ProposalsList.currentIndex()
        newProposalID = self.dock.cb_ProposalsList.itemData(
            newProposal_cbIndex)
        newProposalTitle = self.dock.cb_ProposalsList.currentText()

        self.setCurrentProposal(newProposalID)
        TOMsMessageLog.logMessage("In onChangeProposal. newProposalID: " +
                                  str(newProposalID) + " newProposalTitle: " +
                                  str(newProposalTitle),
                                  level=Qgis.Info)

        # Set the project variable

        reply = QMessageBox.information(self.iface.mainWindow(), "Information",
                                        "All changes will be rolled back",
                                        QMessageBox.Ok)

    def onNewProposal(self):
        TOMsMessageLog.logMessage("In onNewProposal", level=Qgis.Info)

        # set up a transaction
        self.proposalTransaction.startTransactionGroup()

        # create a new Proposal
        """self.newProposal = QgsFeature(self.Proposals.fields())
        #newProposal.setGeometry(QgsGeometry())

        self.newProposal[self.idxProposalTitle] = ''   #str(uuid.uuid4())
        self.newProposal[self.idxCreateDate] = self.proposalsManager.date()
        self.newProposal[self.idxOpenDate] = self.proposalsManager.date()
        self.newProposal[self.idxProposalStatusID] = ProposalStatus.IN_PREPARATION
        self.newProposal.setGeometry(QgsGeometry())

        self.Proposals.addFeature(self.newProposal)  # TH (added for v3)"""
        self.newProposalObject = self.proposalsManager.currentProposalObject(
        ).initialiseProposal()
        self.newProposal = self.proposalsManager.currentProposalObject(
        ).getProposalRecord()

        self.proposalDialog = self.iface.getFeatureForm(
            self.Proposals, self.newProposal)

        #self.proposalDialog.attributeForm().disconnectButtonBox()
        self.button_box = self.proposalDialog.findChild(
            QDialogButtonBox, "button_box")

        if self.button_box is None:
            TOMsMessageLog.logMessage("In onNewProposal. button box not found",
                                      level=Qgis.Info)

            #self.button_box.accepted.disconnect()
        self.button_box.accepted.connect(
            functools.partial(self.onSaveProposalFormDetails, self.newProposal,
                              self.newProposalObject, self.Proposals,
                              self.proposalDialog, self.proposalTransaction))

        #self.button_box.rejected.disconnect()
        self.button_box.rejected.connect(self.onRejectProposalDetailsFromForm)

        self.proposalDialog.attributeForm().attributeChanged.connect(
            functools.partial(self.onAttributeChangedClass2, self.newProposal,
                              self.Proposals))

        self.proposalDialog.show()

        #self.iface.openFeatureForm(self.Proposals, newProposal, False, True)

        #self.createProposalcb()
        pass

    def onNewProposalCreated(self, proposal):
        TOMsMessageLog.logMessage("In onNewProposalCreated. New proposal = " +
                                  str(proposal),
                                  level=Qgis.Info)

        self.createProposalcb()

        # change the list to show the new proposal

        for currIndex in range(self.dock.cb_ProposalsList.count()):
            currProposalID = self.dock.cb_ProposalsList.itemData(currIndex)
            #TOMsMessageLog.logMessage("In onNewProposalSaved. checking index = " + str(currIndex), level=Qgis.Info)
            if currProposalID == proposal:
                TOMsMessageLog.logMessage(
                    "In onNewProposalCreated. index found as " +
                    str(currIndex),
                    level=Qgis.Info)
                self.dock.cb_ProposalsList.setCurrentIndex(currIndex)
                return

        return

        #def onSaveProposalDetailsFromForm(self):
        #self.onSaveProposalFormDetails(self.newProposal, self.Proposals, self.proposalDialog, self.currTransaction)

    def onRejectProposalDetailsFromForm(self):

        self.Proposals.destroyEditCommand()
        self.proposalDialog.reject()

        #self.rollbackCurrentEdits()

        self.proposalTransaction.rollBackTransactionGroup()

        pass

    def onProposalDetails(self):
        TOMsMessageLog.logMessage("In onProposalDetails", level=Qgis.Info)

        # set up transaction
        self.proposalTransaction.startTransactionGroup()

        # https://gis.stackexchange.com/questions/94135/how-to-populate-a-combobox-with-layers-in-toc
        currProposal_cbIndex = self.dock.cb_ProposalsList.currentIndex()

        if currProposal_cbIndex == 0:
            return  # there is nothing to see

        currProposalID = self.dock.cb_ProposalsList.itemData(
            currProposal_cbIndex)

        # self.currProposal = self.getProposal(currProposalID)
        self.currProposalObject = self.proposalsManager.currentProposalObject()
        self.currProposal = self.proposalsManager.currentProposalObject(
        ).getProposalRecord()
        self.proposalDialog = self.iface.getFeatureForm(
            self.Proposals, self.currProposal)

        #self.proposalDialog.attributeForm().disconnectButtonBox()
        self.button_box = self.proposalDialog.findChild(
            QDialogButtonBox, "button_box")

        if self.button_box is None:
            TOMsMessageLog.logMessage("In onNewProposal. button box not found",
                                      level=Qgis.Info)

        self.button_box.accepted.disconnect()
        self.button_box.accepted.connect(
            functools.partial(self.onSaveProposalFormDetails,
                              self.currProposal, self.currProposalObject,
                              self.Proposals, self.proposalDialog,
                              self.proposalTransaction))

        self.button_box.rejected.disconnect()
        self.button_box.rejected.connect(self.onRejectProposalDetailsFromForm)

        self.proposalDialog.attributeForm().attributeChanged.connect(
            functools.partial(self.onAttributeChangedClass2, self.currProposal,
                              self.Proposals))

        self.proposalDialog.show()

        pass

    def onProposalListIndexChanged(self):
        TOMsMessageLog.logMessage("In onProposalListIndexChanged.",
                                  level=Qgis.Info)
        #currProposal = self.proposalsManager.currentProposal()
        #currProposalIdx = self.dock.cb_ProposalsList.findData(currProposal)
        #self.dock.cb_ProposalsList.setCurrentIndex(currProposalIdx)

        currProposal_cbIndex = self.dock.cb_ProposalsList.currentIndex()
        TOMsMessageLog.logMessage(
            "In onProposalListIndexChanged. Current Index = " +
            str(currProposal_cbIndex),
            level=Qgis.Info)
        currProposalID = self.dock.cb_ProposalsList.itemData(
            currProposal_cbIndex)
        self.proposalsManager.setCurrentProposal(currProposalID)

        TOMsMessageLog.logMessage("In onProposalChanged. Zoom to extents",
                                  level=Qgis.Info)
        """if self.proposalsManager.getProposalBoundingBox():
            TOMsMessageLog.logMessage("In onProposalChanged. Bounding box found", level=Qgis.Info)
            self.iface.mapCanvas().setExtent(self.proposalsManager.getProposalBoundingBox())
            self.iface.mapCanvas().refresh()"""

    def updateCurrentProposal(self):
        TOMsMessageLog.logMessage("In updateCurrentProposal.", level=Qgis.Info)
        """Will be called whenever a new entry is selected in the combobox"""

        # Can we check to see if there are any outstanding edits?!!
        """reply = QMessageBox.information(self.iface.mainWindow(), "Information", "All changes will be rolled back",
                                        QMessageBox.Ok)

        if reply:

            self.iface.actionRollbackAllEdits().trigger()
            self.iface.actionCancelAllEdits().trigger()

        pass"""

        currProposal_cbIndex = self.dock.cb_ProposalsList.currentIndex()
        currProposalID = self.dock.cb_ProposalsList.itemData(
            currProposal_cbIndex)
        self.proposalsManager.setCurrentProposal(currProposalID)

    def onDateChanged(self):
        TOMsMessageLog.logMessage("In onDateChanged.", level=Qgis.Info)
        date = self.proposalsManager.date()
        self.dock.filterDate.setDate(date)
        """ onChangeProposalStatus(self):
        TOMsMessageLog.logMessage("In onChangeProposalStatus. Proposed status: " + str(self.Proposals.fields().indexFromName("ProposalStatusID")), level=Qgis.Info)

        # check to see if the proposal is "Accepted"
        acceptProposal = False

        newProposalStatus = int(self.Proposals.fields().indexFromName("ProposalStatusID"))

        if newProposalStatus == 1:    # should be 2 but with list ...

            # if so, check to see if this was intended

            reply = QMessageBox.question(self.iface.mainWindow(), 'Confirm changes to Proposal',
                                         'Are you you want to accept this proposal?. Accepting will make all the proposed changes permanent.', QMessageBox.Yes, QMessageBox.No)
            if reply == QMessageBox.Yes:
                # make the changes permanent
                acceptProposal = True

        # bring the Proposals dislog back to the front

        self.dlg.activateWindow()

        return acceptProposal"""
        """def getRestrictionLayerTableID(self, currRestLayer):
        TOMsMessageLog.logMessage("In getRestrictionLayerTableID.", level=Qgis.Info)
        # find the ID for the layer within the table "

        RestrictionsLayers = QgsMapLayerRegistry.instance().mapLayersByName("RestrictionLayers2")[0]

        layersTableID = 0

        # not sure if there is better way to search for something, .e.g., using SQL ??

        for layer in RestrictionsLayers.getFeatures():
            if layer.attribute("RestrictionLayerName") == str(currRestLayer.name()):
                layersTableID = layer.attribute("id")

        TOMsMessageLog.logMessage("In getRestrictionLayerTableID. layersTableID: " + str(layersTableID), level=Qgis.Info)

        return layersTableID"""

    def getProposal(self, proposalID):
        TOMsMessageLog.logMessage("In getProposal.", level=Qgis.Info)

        # proposalsLayer = QgsMapLayerRegistry.instance().mapLayersByName("Proposals")[0]  -- v2
        proposalsLayer = QgsProject.instance().mapLayersByName("Proposals")[0]

        # not sure if there is better way to search for something, .e.g., using SQL ??

        for currProposal in proposalsLayer.getFeatures():
            if currProposal.attribute("ProposalID") == proposalID:
                return currProposal

        return None

        pass
Beispiel #46
0
class ProcessingPlugin:

    def __init__(self, iface):
        self.iface = iface
        self.options_factory = ProcessingOptionsFactory()
        self.options_factory.setTitle(self.tr('Processing'))
        iface.registerOptionsWidgetFactory(self.options_factory)
        self.drop_handler = ProcessingDropHandler()
        iface.registerCustomDropHandler(self.drop_handler)
        self.item_provider = ProcessingDataItemProvider()
        QgsApplication.dataItemProviderRegistry().addProvider(self.item_provider)
        self.locator_filter = AlgorithmLocatorFilter()
        iface.registerLocatorFilter(self.locator_filter)
        Processing.initialize()

    def initGui(self):
        self.toolbox = ProcessingToolbox()
        self.iface.addDockWidget(Qt.RightDockWidgetArea, self.toolbox)
        self.toolbox.hide()
        self.toolbox.visibilityChanged.connect(self.toolboxVisibilityChanged)

        self.resultsDock = ResultsDock()
        self.iface.addDockWidget(Qt.RightDockWidgetArea, self.resultsDock)
        self.resultsDock.hide()

        self.menu = QMenu(self.iface.mainWindow().menuBar())
        self.menu.setObjectName('processing')
        self.menu.setTitle(self.tr('Pro&cessing'))

        self.toolboxAction = QAction(self.tr('&Toolbox'), self.iface.mainWindow())
        self.toolboxAction.setCheckable(True)
        self.toolboxAction.setObjectName('toolboxAction')
        self.toolboxAction.setIcon(
            QgsApplication.getThemeIcon("/processingAlgorithm.svg"))
        self.iface.registerMainWindowAction(self.toolboxAction,
                                            QKeySequence('Ctrl+Alt+T').toString(QKeySequence.NativeText))
        self.toolboxAction.toggled.connect(self.openToolbox)
        self.iface.attributesToolBar().insertAction(self.iface.actionOpenStatisticalSummary(), self.toolboxAction)
        self.menu.addAction(self.toolboxAction)

        self.modelerAction = QAction(
            QgsApplication.getThemeIcon("/processingModel.svg"),
            QCoreApplication.translate('ProcessingPlugin', 'Graphical &Modeler…'), self.iface.mainWindow())
        self.modelerAction.setObjectName('modelerAction')
        self.modelerAction.triggered.connect(self.openModeler)
        self.iface.registerMainWindowAction(self.modelerAction,
                                            QKeySequence('Ctrl+Alt+M').toString(QKeySequence.NativeText))
        self.menu.addAction(self.modelerAction)

        self.historyAction = QAction(
            QgsApplication.getThemeIcon("/mIconHistory.svg"),
            QCoreApplication.translate('ProcessingPlugin', '&History…'), self.iface.mainWindow())
        self.historyAction.setObjectName('historyAction')
        self.historyAction.triggered.connect(self.openHistory)
        self.iface.registerMainWindowAction(self.historyAction,
                                            QKeySequence('Ctrl+Alt+H').toString(QKeySequence.NativeText))
        self.menu.addAction(self.historyAction)
        self.toolbox.processingToolbar.addAction(self.historyAction)

        self.resultsAction = QAction(
            QgsApplication.getThemeIcon("/processingResult.svg"),
            self.tr('&Results Viewer'), self.iface.mainWindow())
        self.resultsAction.setCheckable(True)
        self.iface.registerMainWindowAction(self.resultsAction,
                                            QKeySequence('Ctrl+Alt+R').toString(QKeySequence.NativeText))

        self.menu.addAction(self.resultsAction)
        self.toolbox.processingToolbar.addAction(self.resultsAction)
        self.resultsDock.visibilityChanged.connect(self.resultsAction.setChecked)
        self.resultsAction.toggled.connect(self.resultsDock.setUserVisible)

        self.optionsAction = QAction(
            QgsApplication.getThemeIcon("/mActionOptions.svg"),
            self.tr('Options'), self.iface.mainWindow())
        self.optionsAction.setObjectName('optionsAction')
        self.optionsAction.triggered.connect(self.openProcessingOptions)
        self.toolbox.processingToolbar.addAction(self.optionsAction)

        menuBar = self.iface.mainWindow().menuBar()
        menuBar.insertMenu(
            self.iface.firstRightStandardMenu().menuAction(), self.menu)

        self.menu.addSeparator()

        initializeMenus()
        createMenus()

    def openProcessingOptions(self):
        self.iface.showOptionsDialog(self.iface.mainWindow(), currentPage='processingOptions')

    def unload(self):
        self.toolbox.setVisible(False)
        self.iface.removeDockWidget(self.toolbox)
        self.iface.attributesToolBar().removeAction(self.toolboxAction)

        self.resultsDock.setVisible(False)
        self.iface.removeDockWidget(self.resultsDock)

        self.toolbox.deleteLater()
        self.menu.deleteLater()

        # delete temporary output files
        folder = QgsProcessingUtils.tempFolder()
        if QDir(folder).exists():
            shutil.rmtree(folder, True)

        # also delete temporary help files
        folder = tempHelpFolder()
        if QDir(folder).exists():
            shutil.rmtree(folder, True)

        self.iface.unregisterMainWindowAction(self.toolboxAction)
        self.iface.unregisterMainWindowAction(self.modelerAction)
        self.iface.unregisterMainWindowAction(self.historyAction)
        self.iface.unregisterMainWindowAction(self.resultsAction)

        self.iface.unregisterOptionsWidgetFactory(self.options_factory)
        self.iface.deregisterLocatorFilter(self.locator_filter)
        self.iface.unregisterCustomDropHandler(self.drop_handler)
        QgsApplication.dataItemProviderRegistry().removeProvider(self.item_provider)

        removeMenus()
        Processing.deinitialize()

    def openToolbox(self, show):
        self.toolbox.setUserVisible(show)

    def toolboxVisibilityChanged(self, visible):
        self.toolboxAction.setChecked(visible)

    def openModeler(self):
        dlg = ModelerDialog()
        dlg.update_model.connect(self.updateModel)
        dlg.show()

    def updateModel(self):
        model_provider = QgsApplication.processingRegistry().providerById('model')
        model_provider.refreshAlgorithms()

    def openResults(self):
        if self.resultsDock.isVisible():
            self.resultsDock.hide()
        else:
            self.resultsDock.show()

    def openHistory(self):
        dlg = HistoryDialog()
        dlg.exec_()

    def tr(self, message):
        return QCoreApplication.translate('ProcessingPlugin', message)
class PSTimeSeries_Plugin:

	def __init__(self, iface):
		self.iface = iface
		self.featFinder = None
		self.running = False

		# used to know where to ask for a new time-series tablename
		self.last_ps_layerid = None
		self.ts_tablename = None

	def initGui(self):
		# create the actions
		self.action = QAction( QIcon( ":/pstimeseries_plugin/icons/logo" ), "PS Time Series Viewer", self.iface.mainWindow() )
		self.action.triggered.connect( self.run )
		self.action.setCheckable( True )

		self.aboutAction = QAction( QIcon( ":/pstimeseries_plugin/icons/about" ), "About", self.iface.mainWindow() )
		self.aboutAction.triggered.connect( self.about )

		# add actions to toolbars and menus
		self.iface.addToolBarIcon( self.action )
		self.iface.addPluginToMenu( "&Permanent Scatterers", self.action )
		#self.iface.addPluginToMenu( "&Permanent Scatterers", self.aboutAction )

	def unload(self):
		# remove actions from toolbars and menus
		self.iface.removeToolBarIcon( self.action )
		self.iface.removePluginMenu( "&Permanent Scatterers", self.action )
		#self.iface.removePluginMenu( "&Permanent Scatterers", self.aboutAction )

	def about(self):
		""" display the about dialog """
		from .about_dlg import AboutDlg
		dlg = AboutDlg( self.iface.mainWindow() )
		dlg.exec_()

	def run(self):
		# create a maptool to select a point feature from the canvas
		if not self.featFinder:
			from .MapTools import FeatureFinder
			self.featFinder = FeatureFinder(self.iface.mapCanvas())
			self.featFinder.setAction( self.action )
			self.featFinder.pointEmitted.connect(self.onPointClicked)

		# enable the maptool and set a message in the status bar
		self.featFinder.startCapture()
		self.iface.mainWindow().statusBar().showMessage( "Click on a point feature in canvas" )

	def onPointClicked(self, point):
		layer = self.iface.activeLayer()
		if not layer or layer.type() != QgsMapLayer.VectorLayer or layer.geometryType() != QgsWkbTypes.PointGeometry:
			QMessageBox.information(self.iface.mainWindow(), "PS Time Series Viewer", "Select a vector layer and try again.")
			return

		# set the waiting cursor
		QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
		try:
			dlg = self._onPointClicked( layer, point )
		finally:
			# restore the cursor
			QApplication.restoreOverrideCursor()

		if dlg:
			dlg.exec_()

		self.run()

	def _onPointClicked(self, ps_layer, point):
		# get the id of the point feature under the mouse click
		from .MapTools import FeatureFinder
		fid = FeatureFinder.findAtPoint(ps_layer, point, canvas=self.iface.mapCanvas(), onlyTheClosestOne=True, onlyIds=True)
		if fid is None:
			return

		# get the attribute map of the selected feature
		feat = QgsFeature()
		feats = ps_layer.getFeatures( QgsFeatureRequest(fid) )
		feats.nextFeature(feat)
		attrs = feat.attributes()

		x, y = [], []	# lists containg x,y values
		infoFields = {}	# hold the index->name of the fields containing info to be displayed

		ps_source = ps_layer.source()
		ps_fields = ps_layer.dataProvider().fields()

		providerType = ps_layer.providerType()
		uri = ps_source
		subset = ""

		if providerType == 'ogr' and ps_source.lower().endswith( ".shp" ):
			# Shapefile
			for idx, fld in enumerate(ps_fields):
				if QRegExp( "D\\d{8}", Qt.CaseInsensitive ).indexIn( fld.name() ) < 0:
					# info fields are all except those containing dates
					infoFields[ idx ] = fld
				else:
					x.append( QDate.fromString( fld.name()[1:], "yyyyMMdd" ).toPyDate() )
					y.append( float(attrs[ idx ]) )

		elif providerType == 'ogr' and (ps_source.upper().startswith("OCI:") or ps_source.lower().endswith(".vrt")):	# Oracle Spatial

			# fields containing values
			dateField = "data_misura"
			valueField = "spost_rel_mm"
			infoFields = dict(enumerate(ps_fields))

			# search for the id_dataset and code_target fields needed to join
			# PS and TS tables
			idDataset = codeTarget = None
			for idx, fld in enumerate(ps_fields):
				if fld.name().lower() == "id_dataset":
					idDataset = attrs[ idx ]
				if fld.name().lower() == "code_target":
					codeTarget = attrs[ idx ]

			if idDataset is None or codeTarget is None:
				QgsMessageLog.logMessage( "idDataset is %s, codeTarget is %s. Exiting" % (idDataset, codeTarget), "PSTimeSeriesViewer" )
				return
			subset = "id_dataset='%s' AND code_target='%s'" % (idDataset, codeTarget)

			# create the uri
			if ps_source.upper().startswith( "OCI:" ):
				default_tbl_name = "RISKNAT.RNAT_TARGET_SSTO"
			elif ps_source.lower().endswith(".vrt"):
				default_tbl_name = "rnat_target_sso.vrt"
			else:
				default_tbl_name = ""
			if not self._askTStablename( ps_layer,  default_tbl_name ):
				return

			if ps_source.upper().startswith( "OCI:" ):
				# uri is like OCI:userid/password@database:table
				pos = uri.indexOf(':', 4)
				if pos >= 0:
					uri = uri[0:pos]
				uri = "%s:%s" % (uri, self.ts_tablename)
			else:
				# it's a VRT file
				uri = "%s/%s" % (QFileInfo(ps_source).path(), self.ts_tablename)
				uri = QDir.toNativeSeparators( uri )

			# load the layer containing time series
			ts_layer = self._createTSlayer( uri, providerType, subset )
			if ts_layer is None:
				return

			# get time series X and Y values
			try:
				x, y = self._getXYvalues( ts_layer, dateField, valueField )
			finally:
				ts_layer.deleteLater()
				del ts_layer

		elif providerType in ['postgres', 'spatialite']:# either PostGIS or SpatiaLite

			# fields containing values
			dateField = "dataripresa"
			valueField = "valore"
			infoFields = dict(enumerate(ps_fields))

			# search for the id_dataset and code_target fields needed to join
			# PS and TS tables
			code = None
			for idx, fld in enumerate( ps_fields ):
				if fld.name().lower() == "code":
					code = attrs[ idx ]

			if code is None:
				QgsMessageLog.logMessage( "code is None. Exiting" % code, "PSTimeSeriesViewer" )
				return
			subset = "code='%s'" % code

			# create the uri
			dsuri = QgsDataSourceUri( ps_layer.source() )
			default_tbl_name = "ts_%s" % dsuri.table()
			if not self._askTStablename( ps_layer,  default_tbl_name ):
				return
			dsuri.setDataSource( dsuri.schema(), self.ts_tablename, None ) # None or "" ? check during tests
			dsuri.setWkbType(QgsWkbTypes.Unknown)
			dsuri.setSrid(None)
			uri = dsuri.uri()

			# load the layer containing time series
			ts_layer = self._createTSlayer( uri, providerType, subset )
			if ts_layer is None:
				return

			# get time series X and Y values
			try:
				x, y = self._getXYvalues( ts_layer, dateField, valueField )
			finally:
				ts_layer.deleteLater()
				del ts_layer

		if len(x) * len(y) <= 0:
			QMessageBox.warning( self.iface.mainWindow(),
					"PS Time Series Viewer",
					"No time series values found for the selected point." )
			QgsMessageLog.logMessage( "provider: %s - uri: %s\nsubset: %s" % (providerType, uri, subset), "PSTimeSeriesViewer" )
			return

		# display the plot dialog
		from .pstimeseries_dlg import PSTimeSeries_Dlg
		dlg = PSTimeSeries_Dlg( ps_layer, infoFields )
		dlg.setFeatureId( fid )
		dlg.setData( x, y )
		return dlg

	def _getXYvalues(self, ts_layer, dateField, valueField):
		# utility function used to get the X and Y values
		x, y = [], []

		# get indexes of date (x) and value (y) fields
		dateIdx, valueIdx = None, None
		for idx, fld in enumerate(ts_layer.dataProvider().fields()):
			if fld.name().lower() == dateField:
				dateIdx = idx
			elif fld.name().lower() == valueField:
				valueIdx = idx

		if dateIdx is None or valueIdx is None:
			QgsMessageLog.logMessage("field %s -> index %s, field %s -> index %s. Exiting" % (dateField, dateIdx, valueField, valueIdx), "PSTimeSeriesViewer")
			return

		# fetch and loop through all the features
		request = QgsFeatureRequest()
		request.setSubsetOfAttributes([dateIdx, valueIdx])
		for f in ts_layer.getFeatures( request ):
			# get x and y values
			a = f.attributes()
			x.append( QDate.fromString( a[ dateIdx ], "yyyyMMdd" ).toPyDate() )
			y.append( float(a[ valueIdx ]) )

		return x, y

	def _askTStablename(self, ps_layer, default_tblname=None):
		# utility function used to ask to the user the name of the table
		# containing time series data
		if default_tblname is None:
			default_tblname = ""

		# ask a tablename to the user
		if ps_layer.id() != self.last_ps_layerid or not self.ts_tablename:
			tblname, ok = QInputDialog.getText( self.iface.mainWindow(),
					"PS Time Series Viewer",
					"Insert the name of the table containing time-series",
					text=default_tblname )
			if not ok:
				return False

			self.ts_tablename = tblname
			self.last_ps_layerid = ps_layer.id()

		return True

	def _createTSlayer(self, uri, providerType, subset=None):
		# utility function used to create the vector layer containing time
		# series data
		layer = QgsVectorLayer( uri, "time_series_layer", providerType )
		if not layer.isValid():
			QMessageBox.warning( self.iface.mainWindow(),
					"PS Time Series Viewer",
					"The layer '%s' wasn't found." % self.ts_tablename )
			self.ts_tablename = None
			return

		if subset is not None:
			layer.setSubsetString( subset )

		return layer