Exemplo n.º 1
0
class SDRCDataCapture:
    def __init__(self, iface):
        self.iface = iface
        self.layerstoForms = {}
        self.actions = []
        self.navtoolbar = self.iface.mapNavToolToolBar()
        self.mainwindow = iface.mainWindow()
        self.iface.projectRead.connect(self.projectOpened)
        self.iface.initializationCompleted.connect(self.setupUI)
        self.settings = QSettings("settings.ini", QSettings.IniFormat)
        self.actionGroup = QActionGroup(self.iface.mainWindow())
        self.iface.mapCanvas().grabGesture(Qt.PinchGesture)
        self.iface.mapCanvas().viewport().setAttribute(Qt.WA_AcceptTouchEvents)

    def setupUI(self):
        """
        Set up the main QGIS interface items.  Called after QGIS has loaded
        the plugin.
        """
        self.iface.mainWindow().showFullScreen()
        self.navtoolbar.setMovable(False)
        self.navtoolbar.setAllowedAreas(Qt.TopToolBarArea)
        self.mainwindow.insertToolBar(self.toolbar, self.navtoolbar)
        self.showOpenProjectDialog()

    def setMapTool(self, tool):
        """
        Set the current map canvas tool

        tool -- The QgsMapTool to set
        """
        self.iface.mapCanvas().setMapTool(tool)

    def initGui(self):
        """
        Create all the icons and setup the tool bars.  Called by QGIS when
        loading. This is called before setupUI.
        """
        self.toolbar = QToolBar("SDRC Data Capture", self.mainwindow)
        self.mainwindow.addToolBar(Qt.TopToolBarArea, self.toolbar)
        self.toolbar.setMovable(False)

        spacewidget = QWidget()
        spacewidget.setMinimumWidth(30)

        gpsspacewidget = QWidget()
        gpsspacewidget.setMinimumWidth(30)
        gpsspacewidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.homeAction = QAction(self.iface.actionZoomFullExtent().icon(), "Default View", self.mainwindow)
        self.gpsAction = GPSAction(QIcon(":/icons/gps"), self.iface.mapCanvas(), self.mainwindow)
        self.openProjectAction = QAction(QIcon(":/icons/open"), "Open Project", self.mainwindow)
        self.toggleRasterAction = QAction(QIcon(":/icons/photo"), "Aerial Photos", self.mainwindow)
        self.editAction = EditAction("Edit", self.iface)
        self.syncAction = QAction(QIcon(":/syncing/sync"), "Sync", self.mainwindow)
        self.editAction.setCheckable(True)

        self.actionGroup.addAction(self.editAction)

        self.homeAction.triggered.connect(self.zoomToDefaultView)
        self.syncAction.triggered.connect(self.sync)
        self.openProjectAction.triggered.connect(self.showOpenProjectDialog)
        self.toggleRasterAction.triggered.connect(self.toggleRasterLayers)

        self.navtoolbar.insertAction(self.iface.actionZoomIn(), self.iface.actionTouch())
        self.navtoolbar.insertAction(self.iface.actionTouch(), self.homeAction)
        self.navtoolbar.insertAction(self.iface.actionTouch(), self.iface.actionZoomFullExtent())
        self.navtoolbar.insertAction(self.homeAction, self.iface.actionZoomFullExtent())
        self.navtoolbar.insertAction(self.iface.actionZoomFullExtent(), self.openProjectAction)

        self.navtoolbar.addAction(self.toggleRasterAction)
        self.navtoolbar.insertWidget(self.iface.actionZoomFullExtent(), spacewidget)
        self.toolbar.addAction(self.editAction)
        self.toolbar.addAction(self.syncAction)
        self.toolbar.insertSeparator(self.syncAction)
        self.toolbar.insertWidget(self.gpsAction, gpsspacewidget)
        self.toolbar.addAction(self.gpsAction)

        self.setupIcons()

    def zoomToDefaultView(self):
        """
        Zoom the map canvas to the extents the project was opened at i.e. the
        default extent.
        """
        self.iface.mapCanvas().setExtent(self.defaultextent)
        self.iface.mapCanvas().refresh()

    def toggleRasterLayers(self):
        """
        Toggle all raster layers on or off.
        """
        legend = self.iface.legendInterface()
        # Freeze the canvas to save on UI refresh
        self.iface.mapCanvas().freeze()
        for layer in QgsMapLayerRegistry.instance().mapLayers().values():
            if layer.type() == QgsMapLayer.RasterLayer:
                isvisible = legend.isLayerVisible(layer)
                legend.setLayerVisible(layer, not isvisible)
        self.iface.mapCanvas().freeze(False)
        self.iface.mapCanvas().refresh()

    def hasRasterLayers(self):
        """
        Check if the project has any raster layers.

        Returns: True if there is a raster layer, else False.
        """
        for layer in QgsMapLayerRegistry.instance().mapLayers().values():
            if layer.type() == QgsMapLayer.RasterLayer:
                return True
        return False

    def setupIcons(self):
        """
        Update toolbars to have text and icons, change normal QGIS
        icons to new style
        """
        toolbars = self.iface.mainWindow().findChildren(QToolBar)
        for toolbar in toolbars:
            toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
            toolbar.setIconSize(QSize(32, 32))

        self.iface.actionTouch().setIconText("Pan")
        self.iface.actionTouch().setIcon(QIcon(":/icons/pan"))
        self.iface.actionZoomIn().setIcon(QIcon(":/icons/in"))
        self.iface.actionZoomOut().setIcon(QIcon(":/icons/out"))
        self.iface.actionPan().setIcon(QIcon(":/icons/pan"))
        self.iface.actionZoomFullExtent().setIcon(QIcon(":/icons/home"))
        self.iface.actionZoomFullExtent().setIconText("Home View")

        self.actionGroup.addAction(self.iface.actionZoomIn())
        self.actionGroup.addAction(self.iface.actionZoomOut())
        self.actionGroup.addAction(self.iface.actionTouch())

    def projectOpened(self):
        """
            Called when a new project is opened in QGIS.
        """
        layers = dict((str(x.name()), x) for x in QgsMapLayerRegistry.instance().mapLayers().values())
        self.createFormButtons(layers)
        self.defaultextent = self.iface.mapCanvas().extent()
        # Enable the raster layers button only if the project contains a raster layer.
        self.toggleRasterAction.setEnabled(self.hasRasterLayers())

    def createFormButtons(self, layers):
        """
            Create buttons for each form that is definded
        """
        layerstoForms = {}

        # Remove all the old buttons
        for action in self.actions:
            self.toolbar.removeAction(action)

        userForms = forms.getForms()

        for form in userForms:
            try:
                layer = layers[form.layerName()]
                icon = form.icon()
                action = AddAction(form.formName(), self.iface, form, layer, icon)
                self.toolbar.insertAction(self.editAction, action)
                self.actionGroup.addAction(action)
                self.actions.append(action)
                layerstoForms[layer] = form
            except KeyError:
                log("Couldn't find layer for form %s" % form.layerName())

        self.editAction.setLayersForms(layerstoForms)

    def rejectProjectDialog(self):
        """
        Handler for rejected open project dialog.
        """
        if QgsProject.instance().fileName() is None:
            self.setUIState(False)
            self.openProjectAction.setEnabled(True)
        else:
            self.setUIState(True)

    def setUIState(self, enabled):
        """
        Enable or disable the toolbar.

        enabled -- True to enable all the toolbar icons.
        """
        toolbars = self.iface.mainWindow().findChildren(QToolBar)
        for toolbar in toolbars:
            toolbar.setEnabled(enabled)

    def showOpenProjectDialog(self):
        """
        Show the project selection dialog.
        """
        self.setUIState(False)
        self.dialog = ListProjectsDialog()
        self.dialog.requestOpenProject.connect(self.loadProject)
        self.dialog.requestOpenProject.connect(self.dialog.close)
        self.dialog.rejected.connect(self.rejectProjectDialog)
        self.dialog.setModal(True)
        self.dialog.show()
        QCoreApplication.processEvents()
        curdir = os.path.dirname(__file__)
        path = os.path.join(curdir, "projects/")
        self.dialog.loadProjectList([path])

    def loadProject(self, path):
        """
        Load a project into QGIS.

        path -- The path to the .qgs project file.
        """
        self.iface.addProject(path)
        self.setUIState(True)

    def unload(self):
        del self.toolbar

    def sync(self):
        """
        Open and run the sync.  Shows the sync dialog.

        notes: Blocking the user while we wait for syncing is not very nice.
               Maybe we can do it in the background and show the dialog as non
               model and report pass/fail.
        """
        self.syndlg = SyncDialog()
        self.syndlg.setModal(True)
        self.syndlg.show()
        # HACK
        QCoreApplication.processEvents()
        self.syndlg.runSync()
        self.iface.mapCanvas().refresh()
Exemplo n.º 2
0
class QMap():
    layerformmap = {}

    def __init__(self, iface):
        self.iface = iface
        self.layerstoForms = {}
        self.actions = []
        self.navtoolbar = self.iface.mapNavToolToolBar()
        self.mainwindow = iface.mainWindow()
        self.iface.projectRead.connect(self.projectOpened)
        self.iface.initializationCompleted.connect(self.setupUI)
        self.actionGroup = QActionGroup(self.iface.mainWindow())
        self.actionGroup.setExclusive(True)
        # self.editActionGroup = QActionGroup(self.iface.mainWindow())
        # self.editActionGroup.setExclusive(True)
        self.iface.mapCanvas().grabGesture(Qt.PinchGesture)
        self.iface.mapCanvas().viewport().setAttribute(Qt.WA_AcceptTouchEvents)
        self.movetool = MoveTool(iface.mapCanvas()) 

    def setupUI(self):
        """
        Set up the main QGIS interface items.  Called after QGIS has loaded
        the plugin.
        """
        self.iface.mainWindow().setWindowTitle("QMap: A data collection program for QGIS")
        fullscreen = utils.settings["fullscreen"]
        if fullscreen:
            self.iface.mainWindow().showFullScreen()
        else:
            self.iface.mainWindow().showMaximized()

        self.navtoolbar.setMovable(False)
        self.navtoolbar.setAllowedAreas(Qt.TopToolBarArea)
        self.mainwindow.insertToolBar(self.toolbar, self.navtoolbar)
        self.showOpenProjectDialog()

    def setMapTool(self, tool):
        """
        Set the current map canvas tool

        tool -- The QgsMapTool to set
        """
        self.iface.mapCanvas().setMapTool(tool)

    def createToolBars(self):
        """
        Create all the needed toolbars
        """
        self.toolbar = QToolBar("SDRC Data Capture", self.mainwindow)
        self.mainwindow.addToolBar(Qt.TopToolBarArea, self.toolbar)
        self.toolbar.setMovable(False)

        self.editingtoolbar = FloatingToolBar("Editing", self.toolbar)
        self.extraaddtoolbar = FloatingToolBar("Extra Add Tools", self.toolbar)

    def createActions(self):
        """
        Create all the actions
        """

        self.homeAction = (QAction(self.iface.actionZoomFullExtent().icon(),
                                  "Default View", self.mainwindow))
        self.gpsAction = (GPSAction(QIcon(":/icons/gps"), self.iface.mapCanvas(),
                                   self.mainwindow))
        self.openProjectAction = (QAction(QIcon(":/icons/open"), "Open Project",
                                         self.mainwindow))
        self.toggleRasterAction = (QAction(QIcon(":/icons/photo"), "Aerial Photos",
                                          self.mainwindow))
        self.syncAction = QAction(QIcon(":/syncing/sync"), "Sync", self.mainwindow)

        self.editattributesaction = EditAction("Edit Attributes", self.iface)
        self.editattributesaction.setCheckable(True)

        self.moveaction = QAction(QIcon(":/icons/move"), "Move Feature", self.mainwindow)
        self.moveaction.setCheckable(True)

        self.editingmodeaction = QAction(QIcon(":/icons/edittools"), "Editing Tools", self.mainwindow)
        self.editingmodeaction.setCheckable(True)

        self.addatgpsaction = QAction(QIcon(":/icons/gpsadd"), "Add at GPS", self.mainwindow)

    def initGui(self):
        """
        Create all the icons and setup the tool bars.  Called by QGIS when
        loading. This is called before setupUI.
        """

        def createSpacer():
            widget = QWidget()
            widget.setMinimumWidth(30)
            return widget

        self.createToolBars()
        self.createActions()

        spacewidget = createSpacer()
        gpsspacewidget = createSpacer()
        gpsspacewidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.moveaction.toggled.connect(functools.partial(self.setMapTool, self.movetool))
        
        showediting = (functools.partial(self.editingtoolbar.showToolbar, 
                                         self.editingmodeaction,
                                         self.editattributesaction))
        self.editingmodeaction.toggled.connect(showediting)

        self.addatgpsaction.triggered.connect(self.addAtGPS)
        self.addatgpsaction.setEnabled(self.gpsAction.isConnected)
        self.gpsAction.gpsfixed.connect(self.addatgpsaction.setEnabled)

        self.menu = QMenu()
        self.exitaction = self.menu.addAction("Exit")
        self.exitaction.setIcon(QIcon(":/icons/exit"))
        self.exitaction.triggered.connect(self.iface.actionExit().trigger)
        self.openProjectAction.setMenu(self.menu)

        self.editingtoolbar.addToActionGroup(self.editattributesaction)
        self.editingtoolbar.addToActionGroup(self.moveaction)

        self.actionGroup.addAction(self.editingmodeaction)

        self.homeAction.triggered.connect(self.zoomToDefaultView)
        self.syncAction.triggered.connect(self.sync)
        self.openProjectAction.triggered.connect(self.showOpenProjectDialog)
        self.toggleRasterAction.triggered.connect(self.toggleRasterLayers)

        self.navtoolbar.insertAction(self.iface.actionZoomIn(), self.iface.actionTouch())
        self.navtoolbar.insertAction(self.iface.actionTouch(), self.homeAction)
        self.navtoolbar.insertAction(self.iface.actionTouch(), self.iface.actionZoomFullExtent())
        self.navtoolbar.insertAction(self.homeAction, self.iface.actionZoomFullExtent())
        self.navtoolbar.insertAction(self.iface.actionZoomFullExtent(), self.openProjectAction)

        self.navtoolbar.addAction(self.toggleRasterAction)
        self.navtoolbar.insertWidget(self.iface.actionZoomFullExtent(), spacewidget)
        self.toolbar.addAction(self.editingmodeaction)
        self.toolbar.addAction(self.syncAction)
        self.toolbar.addAction(self.gpsAction)
        self.toolbar.insertWidget(self.syncAction, gpsspacewidget)
        self.toolbar.insertSeparator(self.gpsAction)

        self.extraaddtoolbar.addAction(self.addatgpsaction)

        self.editingtoolbar.addAction(self.editattributesaction)
        self.editingtoolbar.addAction(self.moveaction)

        self.setupIcons()

    def addAtGPS(self):
        """
        Add a record at the current GPS location.
        """
        action = self.actionGroup.checkedAction()
        log(action)
        if action:
            point = self.gpsAction.gpsLocation
            try:
                action.pointClick(point)
            except AttributeError:
                pass

    def zoomToDefaultView(self):
        """
        Zoom the map canvas to the extents the project was opened at i.e. the
        default extent.
        """
        self.iface.mapCanvas().setExtent(self.defaultextent)
        self.iface.mapCanvas().refresh()

    def toggleRasterLayers(self):
        """
        Toggle all raster layers on or off.
        """
        legend = self.iface.legendInterface()
        #Freeze the canvas to save on UI refresh
        self.iface.mapCanvas().freeze()
        for layer in QgsMapLayerRegistry.instance().mapLayers().values():
            if layer.type() == QgsMapLayer.RasterLayer:
                isvisible = legend.isLayerVisible(layer)
                legend.setLayerVisible(layer, not isvisible)
        self.iface.mapCanvas().freeze(False)
        self.iface.mapCanvas().refresh()

    def hasRasterLayers(self):
        """
        Check if the project has any raster layers.

        Returns: True if there is a raster layer, else False.
        """
        for layer in QgsMapLayerRegistry.instance().mapLayers().values():
            if layer.type() == QgsMapLayer.RasterLayer:
                return True
        return False

    def setupIcons(self):
        """
        Update toolbars to have text and icons, change normal QGIS
        icons to new style
        """
        toolbars = self.iface.mainWindow().findChildren(QToolBar)
        for toolbar in toolbars:
            toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
            toolbar.setIconSize(QSize(32, 32))

        self.iface.actionTouch().setIconText("Pan")
        self.iface.actionTouch().setIcon(QIcon(":/icons/pan"))
        self.iface.actionZoomIn().setIcon(QIcon(":/icons/in"))
        self.iface.actionZoomOut().setIcon(QIcon(":/icons/out"))
        self.iface.actionPan().setIcon(QIcon(":/icons/pan"))
        self.iface.actionZoomFullExtent().setIcon(QIcon(":/icons/home"))
        self.iface.actionZoomFullExtent().setIconText("Home View")

        self.actionGroup.addAction(self.iface.actionZoomIn())
        self.actionGroup.addAction(self.iface.actionZoomOut())
        self.actionGroup.addAction(self.iface.actionTouch())

    def projectOpened(self):
        """
            Called when a new project is opened in QGIS.
        """
        layers = dict((str(x.name()), x) for x in QgsMapLayerRegistry.instance().mapLayers().values())
        self.createFormButtons(layers)
        self.defaultextent = self.iface.mapCanvas().extent()
        # Enable the raster layers button only if the project contains a raster layer.
        self.toggleRasterAction.setEnabled(self.hasRasterLayers())

    def createFormButtons(self, layers):
        """
            Create buttons for each form that is definded
        """
        layerstoForms = {}

        # Remove all the old buttons
        for action in self.actions:
            self.toolbar.removeAction(action)

        for layername, form in forms.getForms().iteritems():
            try:
                layer = layers[layername]    
            except KeyError:
                log("Couldn't find layer for form %s" % layername)
                continue           
            text = "New %s" % form.nameforform(layername)
            action = (AddAction(text, self.iface,
                               form, layer, form.icon()))
            self.toolbar.insertAction(self.editingmodeaction, action)
            showgpstools = (functools.partial(self.extraaddtoolbar.showToolbar, 
                                             action,
                                             None))
            action.toggled.connect(showgpstools)
            self.actionGroup.addAction(action)
            self.actions.append(action)
            layerstoForms[layer] = form


        QMap.layerformmap = layerstoForms

    def rejectProjectDialog(self):
        """
        Handler for rejected open project dialog.
        """
        if QgsProject.instance().fileName() is None:
            self.setUIState(False)
            self.openProjectAction.setEnabled(True)
        else:
            self.setUIState(True)

    def setUIState(self, enabled):
        """
        Enable or disable the toolbar.

        enabled -- True to enable all the toolbar icons.
        """
        toolbars = self.iface.mainWindow().findChildren(QToolBar)
        for toolbar in toolbars:
            toolbar.setEnabled(enabled)

    def showOpenProjectDialog(self):
        """
        Show the project selection dialog.
        """
        self.setUIState(False)
        self.dialog = ListProjectsDialog()
        self.dialog.requestOpenProject.connect(self.loadProject)
        self.dialog.requestOpenProject.connect(self.dialog.close)
        self.dialog.rejected.connect(self.rejectProjectDialog)
        self.dialog.resize(self.iface.mapCanvas().size())
        point = self.iface.mapCanvas().geometry().topLeft()
        point = self.iface.mapCanvas().mapToGlobal(point)
        self.dialog.move(point)
        self.dialog.setModal(True)
        self.dialog.show()
        QCoreApplication.processEvents()
        curdir = os.path.dirname(__file__)
        path = os.path.join(curdir, 'projects/')
        self.dialog.loadProjectList([path])

    def loadProject(self, path):
        """
        Load a project into QGIS.

        path -- The path to the .qgs project file.
        """
        self.iface.addProject(path)
        self.setUIState(True)

    def unload(self):
        del self.toolbar

    def sync(self):
        """
        Open and run the sync.  Shows the sync dialog.

        notes: Blocking the user while we wait for syncing is not very nice.
               Maybe we can do it in the background and show the dialog as non
               model and report pass/fail.
        """
        self.syndlg = SyncDialog()
        self.syndlg.setModal(True)
        self.syndlg.show()
        # HACK
        QCoreApplication.processEvents()
        self.syndlg.runSync(syncproviders)
        self.iface.mapCanvas().refresh()