Skip to main content
fixed part numbers
Source Link
Kadir Şahbaz
  • 78k
  • 57
  • 257
  • 404
import sys
from qgis.core import *
from qgis.gui import *
from qgis.PyQt.QtWidgets import *

######## PART 1: Add QGIS plugin path to the system path ########
import sys
sys.path.append(r"C:\Users\user\AppData\Roaming\QGIS\QGIS3\profiles\ks3.12\python\plugins")
########

######## PART 2: Import plugin dialog ########
from NNJoin.NNJoin_gui import NNJoinDialog
########

class MapViewer(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self, None)

        self._canvas = QgsMapCanvas()
        self._root = QgsProject.instance().layerTreeRoot()

        self.bridge = QgsLayerTreeMapCanvasBridge(self._root, self._canvas)
        self.model = QgsLayerTreeModel(self._root)
        self.model.setFlag(0x25043)
        self.model.setFlag(QgsLayerTreeModel.ShowLegend)
        self.layer_treeview = QgsLayerTreeView()
        self.layer_treeview.setModel(self.model)

        self.layer_tree_dock = QDockWidget("Layers")
        self.layer_tree_dock.setObjectName("layers")
        self.layer_tree_dock.setFeatures(QDockWidget.NoDockWidgetFeatures)
        self.layer_tree_dock.setWidget(self.layer_treeview)

        self.splitter = QSplitter()
        self.splitter.addWidget(self.layer_tree_dock)
        self.splitter.addWidget(self._canvas)
        self.splitter.setCollapsible(0, False)
        self.splitter.setStretchFactor(1, 1)

        self.layout = QHBoxLayout()
        self.layout.addWidget(self.splitter)
        self.contents = QWidget()
        self.contents.setLayout(self.layout)
        self.setCentralWidget(self.contents)

        ######## PART 3: Add messagebar to main window ########
        # We need this, because parent widget of NNJoin dialog
        # calls this messagebar.
        self.bar = QgsMessageBar()
        self.statusBar().addWidget(self.bar)
        self.messageBar = lambda: self.bar
        ########

        self.button = QPushButton("NNJoin")
        self.button.setMaximumHeight(30)
        self.button.setMaximumWidth(80)
        self.statusBar().addPermanentWidget(self.button)
        ######## PART 4: Connect click event of button to method ########
        self.button.clicked.connect(self.open_nnjoin_window)
        self.load_layers()

        ######## PART 45: Create an instance of plugin dioalg ########
        # 'self' is used here instead of 'self.iface' in plugin
        self.dlg = NNJoinDialog(self)
        ########

    def load_layers(self):
        # Adding two sample layers
        self.layer1 = QgsVectorLayer("file1.shp", 'Layer1', 'ogr')
        self.layer2 = QgsVectorLayer("file2.shp", 'Layer2', 'ogr')

        layers = [self.layer1, self.layer2]
        QgsProject.instance().addMapLayers(layers)
        self._canvas.setExtent(self.layer1.extent())
        self._canvas.setLayers(layers)

    ######## PART 56: Initialising NNJoin dialog ########
    # this method runs by clicking the button
    # this part was copied from NNJoin source code and modified
    def open_nnjoin_window(self):
        self.dlg.progressBar.setValue(0.0)
        self.dlg.outputDataset.setText('Result')

        layers = QgsProject.instance().mapLayers()
        layerslist = []
        for id in layers.keys():
            if layers[id].type() == QgsMapLayer.VectorLayer:
                if not layers[id].isValid():
                    QMessageBox.information(None, 'Information',
                        'Layer ' + layers[id].name() + ' is not valid')
                if layers[id].wkbType() != QgsWkbTypes.NoGeometry:
                    layerslist.append((layers[id].name(), id))

        self.dlg.inputVectorLayer.clear()
        for layerdescription in layerslist:
            self.dlg.inputVectorLayer.addItem(layerdescription[0],
                                        layerdescription[1])
        self.dlg.joinVectorLayer.clear()

        for layerdescription in layerslist:
            self.dlg.joinVectorLayer.addItem(layerdescription[0],
                                        layerdescription[1])

        self.dlg.show()
        self.dlg.exec_()
    ########
import sys
from qgis.core import *
from qgis.gui import *
from qgis.PyQt.QtWidgets import *

######## PART 1: Add QGIS plugin path to the system path ########
import sys
sys.path.append(r"C:\Users\user\AppData\Roaming\QGIS\QGIS3\profiles\ks3.12\python\plugins")
########

######## PART 2: Import plugin dialog ########
from NNJoin.NNJoin_gui import NNJoinDialog
########

class MapViewer(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self, None)

        self._canvas = QgsMapCanvas()
        self._root = QgsProject.instance().layerTreeRoot()

        self.bridge = QgsLayerTreeMapCanvasBridge(self._root, self._canvas)
        self.model = QgsLayerTreeModel(self._root)
        self.model.setFlag(0x25043)
        self.model.setFlag(QgsLayerTreeModel.ShowLegend)
        self.layer_treeview = QgsLayerTreeView()
        self.layer_treeview.setModel(self.model)

        self.layer_tree_dock = QDockWidget("Layers")
        self.layer_tree_dock.setObjectName("layers")
        self.layer_tree_dock.setFeatures(QDockWidget.NoDockWidgetFeatures)
        self.layer_tree_dock.setWidget(self.layer_treeview)

        self.splitter = QSplitter()
        self.splitter.addWidget(self.layer_tree_dock)
        self.splitter.addWidget(self._canvas)
        self.splitter.setCollapsible(0, False)
        self.splitter.setStretchFactor(1, 1)

        self.layout = QHBoxLayout()
        self.layout.addWidget(self.splitter)
        self.contents = QWidget()
        self.contents.setLayout(self.layout)
        self.setCentralWidget(self.contents)

        ######## PART 3: Add messagebar to main window ########
        # We need this, because parent widget of NNJoin dialog
        # calls this messagebar.
        self.bar = QgsMessageBar()
        self.statusBar().addWidget(self.bar)
        self.messageBar = lambda: self.bar
        ########

        self.button = QPushButton("NNJoin")
        self.button.setMaximumHeight(30)
        self.button.setMaximumWidth(80)
        self.statusBar().addPermanentWidget(self.button)
        ######## PART 4: Connect click event of button to method ########
        self.button.clicked.connect(self.open_nnjoin_window)
        self.load_layers()

        ######## PART 4: Create an instance of plugin dioalg ########
        # 'self' is used here instead of 'self.iface' in plugin
        self.dlg = NNJoinDialog(self)
        ########

    def load_layers(self):
        # Adding two sample layers
        self.layer1 = QgsVectorLayer("file1.shp", 'Layer1', 'ogr')
        self.layer2 = QgsVectorLayer("file2.shp", 'Layer2', 'ogr')

        layers = [self.layer1, self.layer2]
        QgsProject.instance().addMapLayers(layers)
        self._canvas.setExtent(self.layer1.extent())
        self._canvas.setLayers(layers)

    ######## PART 5: Initialising NNJoin dialog ########
    # this method runs by clicking the button
    # this part was copied from NNJoin source code and modified
    def open_nnjoin_window(self):
        self.dlg.progressBar.setValue(0.0)
        self.dlg.outputDataset.setText('Result')

        layers = QgsProject.instance().mapLayers()
        layerslist = []
        for id in layers.keys():
            if layers[id].type() == QgsMapLayer.VectorLayer:
                if not layers[id].isValid():
                    QMessageBox.information(None, 'Information',
                        'Layer ' + layers[id].name() + ' is not valid')
                if layers[id].wkbType() != QgsWkbTypes.NoGeometry:
                    layerslist.append((layers[id].name(), id))

        self.dlg.inputVectorLayer.clear()
        for layerdescription in layerslist:
            self.dlg.inputVectorLayer.addItem(layerdescription[0],
                                        layerdescription[1])
        self.dlg.joinVectorLayer.clear()

        for layerdescription in layerslist:
            self.dlg.joinVectorLayer.addItem(layerdescription[0],
                                        layerdescription[1])

        self.dlg.show()
        self.dlg.exec_()
    ########
import sys
from qgis.core import *
from qgis.gui import *
from qgis.PyQt.QtWidgets import *

######## PART 1: Add QGIS plugin path to the system path ########
import sys
sys.path.append(r"C:\Users\user\AppData\Roaming\QGIS\QGIS3\profiles\ks3.12\python\plugins")
########

######## PART 2: Import plugin dialog ########
from NNJoin.NNJoin_gui import NNJoinDialog
########

class MapViewer(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self, None)

        self._canvas = QgsMapCanvas()
        self._root = QgsProject.instance().layerTreeRoot()

        self.bridge = QgsLayerTreeMapCanvasBridge(self._root, self._canvas)
        self.model = QgsLayerTreeModel(self._root)
        self.model.setFlag(0x25043)
        self.model.setFlag(QgsLayerTreeModel.ShowLegend)
        self.layer_treeview = QgsLayerTreeView()
        self.layer_treeview.setModel(self.model)

        self.layer_tree_dock = QDockWidget("Layers")
        self.layer_tree_dock.setObjectName("layers")
        self.layer_tree_dock.setFeatures(QDockWidget.NoDockWidgetFeatures)
        self.layer_tree_dock.setWidget(self.layer_treeview)

        self.splitter = QSplitter()
        self.splitter.addWidget(self.layer_tree_dock)
        self.splitter.addWidget(self._canvas)
        self.splitter.setCollapsible(0, False)
        self.splitter.setStretchFactor(1, 1)

        self.layout = QHBoxLayout()
        self.layout.addWidget(self.splitter)
        self.contents = QWidget()
        self.contents.setLayout(self.layout)
        self.setCentralWidget(self.contents)

        ######## PART 3: Add messagebar to main window ########
        # We need this, because parent widget of NNJoin dialog
        # calls this messagebar.
        self.bar = QgsMessageBar()
        self.statusBar().addWidget(self.bar)
        self.messageBar = lambda: self.bar
        ########

        self.button = QPushButton("NNJoin")
        self.button.setMaximumHeight(30)
        self.button.setMaximumWidth(80)
        self.statusBar().addPermanentWidget(self.button)
        ######## PART 4: Connect click event of button to method ########
        self.button.clicked.connect(self.open_nnjoin_window)
        self.load_layers()

        ######## PART 5: Create an instance of plugin dioalg ########
        # 'self' is used here instead of 'self.iface' in plugin
        self.dlg = NNJoinDialog(self)
        ########

    def load_layers(self):
        # Adding two sample layers
        self.layer1 = QgsVectorLayer("file1.shp", 'Layer1', 'ogr')
        self.layer2 = QgsVectorLayer("file2.shp", 'Layer2', 'ogr')

        layers = [self.layer1, self.layer2]
        QgsProject.instance().addMapLayers(layers)
        self._canvas.setExtent(self.layer1.extent())
        self._canvas.setLayers(layers)

    ######## PART 6: Initialising NNJoin dialog ########
    # this method runs by clicking the button
    # this part was copied from NNJoin source code and modified
    def open_nnjoin_window(self):
        self.dlg.progressBar.setValue(0.0)
        self.dlg.outputDataset.setText('Result')

        layers = QgsProject.instance().mapLayers()
        layerslist = []
        for id in layers.keys():
            if layers[id].type() == QgsMapLayer.VectorLayer:
                if not layers[id].isValid():
                    QMessageBox.information(None, 'Information',
                        'Layer ' + layers[id].name() + ' is not valid')
                if layers[id].wkbType() != QgsWkbTypes.NoGeometry:
                    layerslist.append((layers[id].name(), id))

        self.dlg.inputVectorLayer.clear()
        for layerdescription in layerslist:
            self.dlg.inputVectorLayer.addItem(layerdescription[0],
                                        layerdescription[1])
        self.dlg.joinVectorLayer.clear()

        for layerdescription in layerslist:
            self.dlg.joinVectorLayer.addItem(layerdescription[0],
                                        layerdescription[1])

        self.dlg.show()
        self.dlg.exec_()
    ########
fixed grammar
Source Link
Kadir Şahbaz
  • 78k
  • 57
  • 257
  • 404

Fist of all, for using a plugin (NNJoin here) in standalone script, you need to examine that plugin's code, decide which part you can call (I don't think this is always possible but I'm not sure 100%) and what changes/addings do you need in your standalone script.

1. You can open NNJoin dialog window by script, you select options manually and click OK to run.

2. Or you can set options by script without opening nnjoinNNJoin window and trigger the OK button.

Fist of all, for using a plugin (NNJoin here) in standalone script, you need to examine that plugin's code, decide which part you can call (I don't think this is always possible but I'm not sure 100%) and what changes/addings do you need in your standalone script.

1. You can open NNJoin dialog window by script, you select options manually and click OK to run

2. Or you can set options by script without opening nnjoin window and trigger the OK button.

Fist of all, for using a plugin (NNJoin here) in standalone script, you need to examine that plugin's code, decide which part you can call (I don't think this is always possible but I'm not sure 100%) and what changes/addings you need in your standalone script.

1. You can open NNJoin dialog window by script, you select options manually and click OK to run.

2. Or you can set options by script without opening NNJoin window and trigger the OK button.

Source Link
Kadir Şahbaz
  • 78k
  • 57
  • 257
  • 404

Fist of all, for using a plugin (NNJoin here) in standalone script, you need to examine that plugin's code, decide which part you can call (I don't think this is always possible but I'm not sure 100%) and what changes/addings do you need in your standalone script.

How works NNJoin plugin?: It opens a QDialog window, you select options, you click OK button and it processes.

So, you have two solutions here:

1. You can open NNJoin dialog window by script, you select options manually and click OK to run

2. Or you can set options by script without opening nnjoin window and trigger the OK button.


SOLUTION 1:

I have two files: main.py (minimal pyqgis standalone script) and MapViewer.py (includes all GUI)

main.py:

import os
import sys
from qgis.core import QgsApplication

QgsApplication.setPrefixPath(os.environ['QGIS_PREFIX_PATH'], True)
qgs = QgsApplication([], True)
qgs.initQgis()

from MapViewer import MapViewer
main_window = MapViewer()
main_window.show()
qgs.exec_()
qgs.exitQgis()

MapViewer.py: It includes a layers panel, a map canvas, a status bar with a button. Please review the script. I added all explanation to the script as comment (PART 1, PART 2, ...).

import sys
from qgis.core import *
from qgis.gui import *
from qgis.PyQt.QtWidgets import *

######## PART 1: Add QGIS plugin path to the system path ########
import sys
sys.path.append(r"C:\Users\user\AppData\Roaming\QGIS\QGIS3\profiles\ks3.12\python\plugins")
########

######## PART 2: Import plugin dialog ########
from NNJoin.NNJoin_gui import NNJoinDialog
########

class MapViewer(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self, None)

        self._canvas = QgsMapCanvas()
        self._root = QgsProject.instance().layerTreeRoot()

        self.bridge = QgsLayerTreeMapCanvasBridge(self._root, self._canvas)
        self.model = QgsLayerTreeModel(self._root)
        self.model.setFlag(0x25043)
        self.model.setFlag(QgsLayerTreeModel.ShowLegend)
        self.layer_treeview = QgsLayerTreeView()
        self.layer_treeview.setModel(self.model)

        self.layer_tree_dock = QDockWidget("Layers")
        self.layer_tree_dock.setObjectName("layers")
        self.layer_tree_dock.setFeatures(QDockWidget.NoDockWidgetFeatures)
        self.layer_tree_dock.setWidget(self.layer_treeview)

        self.splitter = QSplitter()
        self.splitter.addWidget(self.layer_tree_dock)
        self.splitter.addWidget(self._canvas)
        self.splitter.setCollapsible(0, False)
        self.splitter.setStretchFactor(1, 1)

        self.layout = QHBoxLayout()
        self.layout.addWidget(self.splitter)
        self.contents = QWidget()
        self.contents.setLayout(self.layout)
        self.setCentralWidget(self.contents)

        ######## PART 3: Add messagebar to main window ########
        # We need this, because parent widget of NNJoin dialog
        # calls this messagebar.
        self.bar = QgsMessageBar()
        self.statusBar().addWidget(self.bar)
        self.messageBar = lambda: self.bar
        ########

        self.button = QPushButton("NNJoin")
        self.button.setMaximumHeight(30)
        self.button.setMaximumWidth(80)
        self.statusBar().addPermanentWidget(self.button)
        ######## PART 4: Connect click event of button to method ########
        self.button.clicked.connect(self.open_nnjoin_window)
        self.load_layers()

        ######## PART 4: Create an instance of plugin dioalg ########
        # 'self' is used here instead of 'self.iface' in plugin
        self.dlg = NNJoinDialog(self)
        ########

    def load_layers(self):
        # Adding two sample layers
        self.layer1 = QgsVectorLayer("file1.shp", 'Layer1', 'ogr')
        self.layer2 = QgsVectorLayer("file2.shp", 'Layer2', 'ogr')

        layers = [self.layer1, self.layer2]
        QgsProject.instance().addMapLayers(layers)
        self._canvas.setExtent(self.layer1.extent())
        self._canvas.setLayers(layers)

    ######## PART 5: Initialising NNJoin dialog ########
    # this method runs by clicking the button
    # this part was copied from NNJoin source code and modified
    def open_nnjoin_window(self):
        self.dlg.progressBar.setValue(0.0)
        self.dlg.outputDataset.setText('Result')

        layers = QgsProject.instance().mapLayers()
        layerslist = []
        for id in layers.keys():
            if layers[id].type() == QgsMapLayer.VectorLayer:
                if not layers[id].isValid():
                    QMessageBox.information(None, 'Information',
                        'Layer ' + layers[id].name() + ' is not valid')
                if layers[id].wkbType() != QgsWkbTypes.NoGeometry:
                    layerslist.append((layers[id].name(), id))

        self.dlg.inputVectorLayer.clear()
        for layerdescription in layerslist:
            self.dlg.inputVectorLayer.addItem(layerdescription[0],
                                        layerdescription[1])
        self.dlg.joinVectorLayer.clear()

        for layerdescription in layerslist:
            self.dlg.joinVectorLayer.addItem(layerdescription[0],
                                        layerdescription[1])

        self.dlg.show()
        self.dlg.exec_()
    ########

Note that NNJoin plugin doesn't return any layer reference, but just add a layer to QgsProject instance. So you should get the returned layer using QgsProject.instance().mapLayersByName("LAYER_NAME").