Example #1
0
    def initGui(self):
        self._layers = LayerManager(self._iface)
        self._highlighter = AddressHighlighter(self._iface, self._layers, self._controller)
        self._highlighter.setEnabled(False)

        # Main address editing window
        self._loadaction = QAction(
            QIcon(":/plugins/ElectoralAddressLoader/loadaddress.png"),
            "Electoral address manager",
            self._iface.mainWindow(),
        )
        self._loadaction.setWhatsThis("Open the electoral address upload management window")
        self._loadaction.setStatusTip("Open the electoral address upload management window")
        self._loadaction.triggered.connect(self.loadEditor)

        self._infoaction = QAction(
            QIcon(":/plugins/ElectoralAddressLoader/addressinfo.png"),
            "Electoral address info tool",
            self._iface.mainWindow(),
        )
        self._infoaction.setWhatsThis("Start the electoral address loader info tool")
        self._infoaction.setStatusTip("Start the electoral address loader info tool")
        # Info window and info tool
        self._infoaction.setEnabled(False)
        self._infoaction.triggered.connect(self.startInfoTool)
        self._infotool = InfoTool(self._iface)
        self._infotool.setAction(self._infoaction)

        # Address highlighter
        self._highlightaction = QAction(
            QIcon(":/plugins/ElectoralAddressLoader/addresshighlight.png"),
            "Electoral address highlighter",
            self._iface.mainWindow(),
        )
        self._highlightaction.setWhatsThis("Turn the electoral address highlighter on or off")
        self._highlightaction.setStatusTip("Turn the electoral address highlighter on or off")
        self._highlightaction.setEnabled(False)
        self._highlightaction.setCheckable(True)
        self._highlightaction.toggled.connect(self._highlighter.setEnabled)

        # Delete address point
        self._deladdressaction = QAction(
            QIcon(":/plugins/ElectoralAddressLoader/deleteaddress.png"),
            "Delete landonline address point",
            self._iface.mainWindow(),
        )
        self._deladdressaction.setWhatsThis("Mark a landonline address point for deletion")
        self._deladdressaction.setStatusTip("Mark a landonline address point for deletion")
        self._deladdressaction.setEnabled(False)
        self._deladdressaction.triggered.connect(self.startDelAddressTool)
        self._deladdtool = DelAddressTool(self._iface, self._layers, self._controller)
        self._deladdtool.setAction(self._deladdressaction)

        # Create address geometry
        self._createpointaction = QAction(
            QIcon(":/plugins/ElectoralAddressLoader/createpoint.png"),
            "Create address geometry",
            self._iface.mainWindow(),
        )
        self._createpointaction.setWhatsThis("Mark a point to use as the geometry for the selected address")
        self._createpointaction.setStatusTip("Mark a point to use as the geometry for the selected address")
        self._createpointaction.setEnabled(False)
        self._createpointaction.triggered.connect(self.startCreatePointTool)
        self._createpnttool = CreatePointTool(self._iface, self._controller)
        self._createpnttool.setAction(self._createpointaction)

        # Create new address
        self._createnewaddressaction = QAction(
            QIcon(":/plugins/ElectoralAddressLoader/newaddresspoint.png"),
            "Create new address",
            self._iface.mainWindow(),
        )
        self._createnewaddressaction.setWhatsThis("place point for new address")
        self._createnewaddressaction.setStatusTip("place point for new address")
        self._createnewaddressaction.setEnabled(False)
        self._createnewaddressaction.triggered.connect(self.startNewAddressTool)
        self._createnewtool = CreateNewTool(self._iface, self._controller)
        self._createnewtool.setAction(self._createnewaddressaction)

        # Help button
        self._helpaction = QAction(
            QIcon(":/plugins/ElectoralAddressLoader/addresshelp.png"),
            "Electoral address help",
            self._iface.mainWindow(),
        )
        self._helpaction.setWhatsThis("Display help for the electoral address plugin")
        self._helpaction.setStatusTip("Display help for the electoral address plugin")
        self._helpaction.triggered.connect(self.showHelp)

        # Add to own toolbar
        self._toolbar = self._iface.addToolBar("Electoral address")
        self._toolbar.addAction(self._loadaction)
        self._toolbar.addAction(self._infoaction)
        self._toolbar.addAction(self._highlightaction)
        self._toolbar.addAction(self._deladdressaction)
        self._toolbar.addAction(self._createpointaction)
        self._toolbar.addAction(self._createnewaddressaction)
        self._toolbar.addAction(self._helpaction)

        # Add infowidget to attributes tool bar
        tb = self._iface.attributesToolBar()
        tb.insertAction(tb.actions()[0], self._infoaction)
        self._infowidget = tb.widgetForAction(self._infoaction)
        self._infowidget.hide()

        # Add actions to menu and toolbar icon
        self._iface.addToolBarIcon(self._loadaction)
        self._iface.addPluginToMenu("&Electoral address", self._loadaction)
        self._iface.addPluginToMenu("&Electoral address", self._infoaction)
        self._iface.addPluginToMenu("&Electoral address", self._highlightaction)
        self._iface.addPluginToMenu("&Electoral address", self._deladdressaction)
        self._iface.addPluginToMenu("&Electoral address", self._createpointaction)
        self._iface.addPluginToMenu("&Electoral address", self._createnewaddressaction)
        self._iface.addPluginToMenu("&Electoral address", self._helpaction)

        # Make useful connections!
        QgsProject.instance().readProject.connect(self.loadProject)
        self._layers.addressLayerAdded.connect(self.enableAddressLayer)
        self._layers.addressLayerRemoved.connect(self.disableAddressLayer)
        self._controller.jobLoading.connect(self.showMessage)
        self._controller.jobLoaded.connect(self.displayJob)
        self._controller.addressUpdated.connect(self.updateAddress)
        self._controller.addressSelected.connect(self._highlighter.setAddress)
        self._controller.addressSelected.connect(self._createpnttool.setAddress)
Example #2
0
class Plugin:

    Name = "ElectoralAddressLoader"
    LongName = "Electoral address loader"
    Version = "2.0"
    QgisMinimumVersion = "2.0"
    Author = "[email protected] <Chris Crook>; [email protected] <Bill M. Nelson>"
    PluginUrl = "http://inlinz2/CustomerServices/QgisPluginRepository/ElectoralAddressLoader.zip"
    Description = "Prepare address information supplied by regional authorities for loading into Landonline"

    SettingsBase = "ElectoralAddressLoader/"

    def __init__(self, iface):

        self._iface = iface
        self._statusbar = iface.mainWindow().statusBar()
        self._layers = None
        self._highlighter = None
        self._editor = None
        self._infowin = None
        self._infotool = None
        self._deladdtool = None
        self._createpnttool = None
        self._controller = Controller()
        # Setup address coord ref system (NZGD2000 = epsg 4167)
        self._addressCrs = QgsCoordinateReferenceSystem()
        self._addressCrs.createFromOgcWmsCrs("EPSG:4167")
        self._displayCrs = QgsCoordinateReferenceSystem()
        self._displayCrs.createFromOgcWmsCrs("EPSG:2193")
        self._addressZoomRadius = 150.0

    def initGui(self):
        self._layers = LayerManager(self._iface)
        self._highlighter = AddressHighlighter(self._iface, self._layers, self._controller)
        self._highlighter.setEnabled(False)

        # Main address editing window
        self._loadaction = QAction(
            QIcon(":/plugins/ElectoralAddressLoader/loadaddress.png"),
            "Electoral address manager",
            self._iface.mainWindow(),
        )
        self._loadaction.setWhatsThis("Open the electoral address upload management window")
        self._loadaction.setStatusTip("Open the electoral address upload management window")
        self._loadaction.triggered.connect(self.loadEditor)

        self._infoaction = QAction(
            QIcon(":/plugins/ElectoralAddressLoader/addressinfo.png"),
            "Electoral address info tool",
            self._iface.mainWindow(),
        )
        self._infoaction.setWhatsThis("Start the electoral address loader info tool")
        self._infoaction.setStatusTip("Start the electoral address loader info tool")
        # Info window and info tool
        self._infoaction.setEnabled(False)
        self._infoaction.triggered.connect(self.startInfoTool)
        self._infotool = InfoTool(self._iface)
        self._infotool.setAction(self._infoaction)

        # Address highlighter
        self._highlightaction = QAction(
            QIcon(":/plugins/ElectoralAddressLoader/addresshighlight.png"),
            "Electoral address highlighter",
            self._iface.mainWindow(),
        )
        self._highlightaction.setWhatsThis("Turn the electoral address highlighter on or off")
        self._highlightaction.setStatusTip("Turn the electoral address highlighter on or off")
        self._highlightaction.setEnabled(False)
        self._highlightaction.setCheckable(True)
        self._highlightaction.toggled.connect(self._highlighter.setEnabled)

        # Delete address point
        self._deladdressaction = QAction(
            QIcon(":/plugins/ElectoralAddressLoader/deleteaddress.png"),
            "Delete landonline address point",
            self._iface.mainWindow(),
        )
        self._deladdressaction.setWhatsThis("Mark a landonline address point for deletion")
        self._deladdressaction.setStatusTip("Mark a landonline address point for deletion")
        self._deladdressaction.setEnabled(False)
        self._deladdressaction.triggered.connect(self.startDelAddressTool)
        self._deladdtool = DelAddressTool(self._iface, self._layers, self._controller)
        self._deladdtool.setAction(self._deladdressaction)

        # Create address geometry
        self._createpointaction = QAction(
            QIcon(":/plugins/ElectoralAddressLoader/createpoint.png"),
            "Create address geometry",
            self._iface.mainWindow(),
        )
        self._createpointaction.setWhatsThis("Mark a point to use as the geometry for the selected address")
        self._createpointaction.setStatusTip("Mark a point to use as the geometry for the selected address")
        self._createpointaction.setEnabled(False)
        self._createpointaction.triggered.connect(self.startCreatePointTool)
        self._createpnttool = CreatePointTool(self._iface, self._controller)
        self._createpnttool.setAction(self._createpointaction)

        # Create new address
        self._createnewaddressaction = QAction(
            QIcon(":/plugins/ElectoralAddressLoader/newaddresspoint.png"),
            "Create new address",
            self._iface.mainWindow(),
        )
        self._createnewaddressaction.setWhatsThis("place point for new address")
        self._createnewaddressaction.setStatusTip("place point for new address")
        self._createnewaddressaction.setEnabled(False)
        self._createnewaddressaction.triggered.connect(self.startNewAddressTool)
        self._createnewtool = CreateNewTool(self._iface, self._controller)
        self._createnewtool.setAction(self._createnewaddressaction)

        # Help button
        self._helpaction = QAction(
            QIcon(":/plugins/ElectoralAddressLoader/addresshelp.png"),
            "Electoral address help",
            self._iface.mainWindow(),
        )
        self._helpaction.setWhatsThis("Display help for the electoral address plugin")
        self._helpaction.setStatusTip("Display help for the electoral address plugin")
        self._helpaction.triggered.connect(self.showHelp)

        # Add to own toolbar
        self._toolbar = self._iface.addToolBar("Electoral address")
        self._toolbar.addAction(self._loadaction)
        self._toolbar.addAction(self._infoaction)
        self._toolbar.addAction(self._highlightaction)
        self._toolbar.addAction(self._deladdressaction)
        self._toolbar.addAction(self._createpointaction)
        self._toolbar.addAction(self._createnewaddressaction)
        self._toolbar.addAction(self._helpaction)

        # Add infowidget to attributes tool bar
        tb = self._iface.attributesToolBar()
        tb.insertAction(tb.actions()[0], self._infoaction)
        self._infowidget = tb.widgetForAction(self._infoaction)
        self._infowidget.hide()

        # Add actions to menu and toolbar icon
        self._iface.addToolBarIcon(self._loadaction)
        self._iface.addPluginToMenu("&Electoral address", self._loadaction)
        self._iface.addPluginToMenu("&Electoral address", self._infoaction)
        self._iface.addPluginToMenu("&Electoral address", self._highlightaction)
        self._iface.addPluginToMenu("&Electoral address", self._deladdressaction)
        self._iface.addPluginToMenu("&Electoral address", self._createpointaction)
        self._iface.addPluginToMenu("&Electoral address", self._createnewaddressaction)
        self._iface.addPluginToMenu("&Electoral address", self._helpaction)

        # Make useful connections!
        QgsProject.instance().readProject.connect(self.loadProject)
        self._layers.addressLayerAdded.connect(self.enableAddressLayer)
        self._layers.addressLayerRemoved.connect(self.disableAddressLayer)
        self._controller.jobLoading.connect(self.showMessage)
        self._controller.jobLoaded.connect(self.displayJob)
        self._controller.addressUpdated.connect(self.updateAddress)
        self._controller.addressSelected.connect(self._highlighter.setAddress)
        self._controller.addressSelected.connect(self._createpnttool.setAddress)

    def unload(self):
        if self._editor:
            self._editor.close()
            self._editor = None
        if self._infowin:
            self._infowin.close()
            self._infowin = None
        self._iface.mainWindow().removeToolBar(self._toolbar)
        self._iface.attributesToolBar().removeAction(self._infoaction)
        self._iface.removeToolBarIcon(self._loadaction)
        self._iface.removePluginMenu("&Electoral address", self._loadaction)
        self._iface.removePluginMenu("&Electoral address", self._infoaction)
        self._iface.removePluginMenu("&Electoral address", self._highlightaction)
        self._iface.removePluginMenu("&Electoral address", self._deladdressaction)
        self._iface.removePluginMenu("&Electoral address", self._createpointaction)
        self._iface.removePluginMenu("&Electoral address", self._createnewaddressaction)
        self._iface.removePluginMenu("&Electoral address", self._helpaction)

    def defaultHelpFile(self):
        from os.path import dirname, join, abspath, exists

        helpfile = join(dirname(abspath(__file__)), "help", "index.html")
        return helpfile if exists(helpfile) else None

    def showHelp(self):
        helpfile = self.defaultHelpFile()
        if helpfile:
            url = QUrl.fromLocalFile(helpfile)
            QDesktopServices.openUrl(url)

    def loadProject(self, dom):
        jobid = self._layers.getLoadedJobId()
        if jobid < 0:
            editor = self.jobEditor(False)
            if editor:
                editor.hide()
        else:
            editor = self.jobEditor()
            editor.loadJob(jobid)

    def enableAddressLayer(self, layer):
        self._infowidget.setVisible(True)
        self._infoaction.setEnabled(True)
        self._deladdressaction.setEnabled(True)
        self._createpointaction.setEnabled(True)
        self._createnewaddressaction.setEnabled(True)
        self._highlightaction.setEnabled(True)
        if layer:
            layer.selectionChanged.connect(self.setSelectedAddressId)
            layer.committedFeaturesAdded.connect(self.updateAddedAddresses)
            layer.committedFeaturesRemoved.connect(self.updateRemovedAddresses)
            layer.committedAttributeValuesChanges.connect(self.updateEditedAddresses)
            layer.committedGeometriesChanges.connect(self.updateEditedGeometries)

    def disableAddressLayer(self):
        self._infoaction.setEnabled(False)
        self._infowidget.setVisible(False)
        self._highlightaction.setEnabled(False)

    def setSelectedAddressId(self):
        layer = self._layers.addressLayer()
        editor = self.jobEditor(False)
        if layer and layer.selectedFeatureCount() == 1:
            for id in layer.selectedFeaturesIds():
                self._controller.selectAddress(id)

    def updateAddedAddresses(self, id, featlist):
        for id in featlist.keys():
            self._controller.updateAddress(int(id))

    def updateRemovedAddresses(self, id, featlist):
        for id in featlist:
            self._controller.updateAddress(int(id))

    def updateEditedAddresses(self, id, changelist):
        for id in changelist.keys():
            self._controller.updateAddress(int(id))

    def updateEditedGeometries(self, id, geomap):
        # Refresh job links - when address geometries are changed the
        # update trigger on the address table sets the linked status to
        # false, so that relinking the job will fix up changed geometries
        # This also returns a list of parcel ids...
        ids = self._controller.job().refreshLandonlineLinks()
        for id in ids:
            self._controller.updateAddress(id)

    def loadEditor(self):
        editor = self.jobEditor()
        if not editor.isVisible():
            editor.parent().show()

    def jobEditor(self, create=True):
        if not self._editor and create:
            editor = JobManagerWidget(self._iface.mainWindow(), self._controller)
            helpfile = self.defaultHelpFile()
            if helpfile:
                editor.setHelpFile(helpfile)
            editor.addAddressAction("Display", self.zoomToAddress)
            DockWindow(self._iface.mainWindow(), editor, "JobManager", "Address manager")
            self._editor = editor
        return self._editor

    def updateAddress(self, address):
        self._layers.refreshAddressLayer()

    def startInfoTool(self):
        infowin = self.infoWindow()
        if not infowin.isVisible():
            infowin.parent().show()
        self._iface.mapCanvas().setMapTool(self._infotool)

    def startDelAddressTool(self):
        self._iface.mapCanvas().setMapTool(self._deladdtool)

    def startCreatePointTool(self):
        self._iface.mapCanvas().setMapTool(self._createpnttool)
        self._createpnttool.setEnabled(True)

    def startNewAddressTool(self):
        self._iface.mapCanvas().setMapTool(self._createnewtool)
        self._createnewtool.setEnabled(True)

    def infoWindow(self, create=True):
        if not self._infowin and create:
            infowin = InfoWidget(self._iface.mainWindow(), self._iface, self._layers, self._controller)
            DockWindow(self._iface.mainWindow(), infowin, "InfoWindow", "Address information")
            self._infowin = infowin
            self._infotool.areaSelected.connect(infowin.setSelectRectangle)
        return self._infowin

    def displayJob(self, job):
        canvas = self._iface.mapCanvas()
        renderer = canvas.mapRenderer()
        if renderer.destinationCrs() != self._displayCrs:
            setCrs = True
            if QgsMapLayerRegistry.instance().count() > 0:
                answer = QMessageBox.question(
                    self._iface.mainWindow(),
                    "Set coordinate system",
                    "The electoral address plugin prefers to use the NZTM projection\n"
                    + "Do you want to change the project to use this?",
                    QMessageBox.Yes | QMessageBox.No,
                )
                setCrs = answer == QMessageBox.Yes
            if setCrs:
                renderer.setDestinationCrs(self._displayCrs)
                renderer.setMapUnits(QGis.Meters)
        if renderer.destinationCrs() == self._displayCrs:
            renderer.setProjectionsEnabled(True)

        self._iface.mapCanvas().setRenderFlag(False)
        try:
            if job:
                self._layers.installLandonlineLayers()
            layer = self._layers.installAddressLayer(job)
            extents = layer.extent()
            if extents.isEmpty():
                self._iface.mapCanvas().zoomToFullExtent()
            else:
                transform = QgsCoordinateTransform(
                    self._addressCrs, self._iface.mapCanvas().mapRenderer().destinationCrs()
                )
                extents = transform.transformBoundingBox(extents)
                self._iface.mapCanvas().setExtent(extents)
        finally:
            self._iface.mapCanvas().setRenderFlag(True)

    def zoomToAddress(self, address):
        if not address or not address.location():
            return
        layer = self._layers.installAddressLayer(self._controller.job())
        self._iface.mapCanvas().setCurrentLayer(layer)
        transform = QgsCoordinateTransform(self._addressCrs, self._iface.mapCanvas().mapRenderer().destinationCrs())
        midpoint = transform.transform(address.location()[0], address.location()[1])
        buffer = self._addressZoomRadius
        extents = QgsRectangle(
            midpoint.x() - buffer, midpoint.y() - buffer, midpoint.x() + buffer, midpoint.y() + buffer
        )
        self._iface.mapCanvas().setExtent(extents)
        layer.removeSelection()
        self._iface.mapCanvas().refresh()

    def showMessage(self, string):
        self._statusbar.showMessage(string)