Ejemplo n.º 1
0
    def test_signalConnection(self):
        # remove all layers
        QgsProject.instance().removeAllMapLayers()
        # set dependencies and add back layers
        self.pointsLayer = QgsVectorLayer(
            "dbname='%s' table=\"node\" (geom) sql=" % self.fn, "points",
            "spatialite")
        assert (self.pointsLayer.isValid())
        self.linesLayer = QgsVectorLayer(
            "dbname='%s' table=\"section\" (geom) sql=" % self.fn, "lines",
            "spatialite")
        assert (self.linesLayer.isValid())
        self.pointsLayer2 = QgsVectorLayer(
            "dbname='%s' table=\"node2\" (geom) sql=" % self.fn, "_points2",
            "spatialite")
        assert (self.pointsLayer2.isValid())
        self.pointsLayer.setDependencies(
            [QgsMapLayerDependency(self.linesLayer.id())])
        self.pointsLayer2.setDependencies(
            [QgsMapLayerDependency(self.pointsLayer.id())])
        # this should update connections between layers
        QgsProject.instance().addMapLayers([self.pointsLayer])
        QgsProject.instance().addMapLayers([self.linesLayer])
        QgsProject.instance().addMapLayers([self.pointsLayer2])

        ms = QgsMapSettings()
        ms.setOutputSize(QSize(100, 100))
        ms.setExtent(QgsRectangle(0, 0, 1, 1))
        self.assertTrue(ms.hasValidSettings())

        u = QgsSnappingUtils()
        u.setMapSettings(ms)
        cfg = u.config()
        cfg.setEnabled(True)
        cfg.setMode(QgsSnappingConfig.AdvancedConfiguration)
        cfg.setIndividualLayerSettings(
            self.pointsLayer,
            QgsSnappingConfig.IndividualLayerSettings(True,
                                                      QgsSnappingConfig.Vertex,
                                                      20, QgsTolerance.Pixels))
        cfg.setIndividualLayerSettings(
            self.pointsLayer2,
            QgsSnappingConfig.IndividualLayerSettings(True,
                                                      QgsSnappingConfig.Vertex,
                                                      20, QgsTolerance.Pixels))
        u.setConfig(cfg)
        # add another line
        f = QgsFeature(self.linesLayer.fields())
        f.setId(4)
        geom = QgsGeometry.fromWkt("LINESTRING(0.5 0.2,0.6 0)")
        f.setGeometry(geom)
        self.linesLayer.startEditing()
        self.linesLayer.addFeatures([f])
        self.linesLayer.commitChanges()
        # check the second snapped point is OK
        m = u.snapToMap(QPoint(75, 100 - 0))
        self.assertTrue(m.isValid())
        self.assertTrue(m.hasVertex())
        self.assertEqual(m.point(), QgsPointXY(0.8, 0.0))

        self.pointsLayer.setDependencies([])
        self.pointsLayer2.setDependencies([])
Ejemplo n.º 2
0
 def zoomActual(self):
     point = self.view.mapToScene(QPoint(self.view.viewport().width() / 2, self.view.viewport().height() / 2))
     self.view.resetTransform()
     self.view.centerOn(point)
    def search_data(self, **kwargs):
        """
        Get plot geometries associated with parcels, both collected and official, zoom to them, activate map swipe tool
            and fill comparison table.

        :param kwargs: key-value (field name-field value) to search in parcel tables, both collected and official
                       Normally, keys are parcel_number, old_parcel_number or FMI, but if duplicates are found, an
                       additional t_id disambiguates only for the collected source. In the Official source we assume
                       we will not find duplicates, if there are, we will choose the first record found an will not deal
                       with letting the user choose one of the duplicates by hand (as we do for the collected source).
        """
        self.chk_show_all_plots.setEnabled(False)
        self.chk_show_all_plots.setChecked(True)
        self.initialize_tools_and_layers()  # Reset any filter on layers
        already_zoomed_in = False

        self.clear_result_table()

        search_field = self.cbo_parcel_fields.currentData()
        search_value = list(kwargs.values())[0]

        # Get OFFICIAL parcel's t_id and get related plot(s)
        expression = QgsExpression("{}='{}'".format(search_field,
                                                    search_value))
        request = QgsFeatureRequest(expression)
        field_idx = self.utils._official_layers[PARCEL_TABLE][LAYER].fields(
        ).indexFromName(ID_FIELD)
        request.setFlags(QgsFeatureRequest.NoGeometry)
        request.setSubsetOfAttributes([field_idx
                                       ])  # Note: this adds a new flag
        official_parcels = [
            feature for feature in self.utils._official_layers[PARCEL_TABLE]
            [LAYER].getFeatures(request)
        ]

        if len(official_parcels) > 1:
            # We do not expect duplicates in the official source!
            pass  # We'll choose the first one anyways
        elif len(official_parcels) == 0:
            print("No parcel found!", search_field, search_value)

        official_plot_t_ids = []
        if official_parcels:
            official_plot_t_ids = self.utils.ladm_data.get_plots_related_to_parcels(
                self.utils._official_db, [official_parcels[0][ID_FIELD]],
                field_name=ID_FIELD,
                plot_layer=self.utils._official_layers[PLOT_TABLE][LAYER],
                uebaunit_table=self.utils._official_layers[UEBAUNIT_TABLE]
                [LAYER])

            if official_plot_t_ids:
                self._current_official_substring = "\"{}\" IN ('{}')".format(
                    ID_FIELD,
                    "','".join([str(t_id) for t_id in official_plot_t_ids]))
                self.parent.request_zoom_to_features(
                    self.utils._official_layers[PLOT_TABLE][LAYER], list(),
                    official_plot_t_ids)
                already_zoomed_in = True

        # Now get COLLECTED parcel's t_id and get related plot(s)
        collected_parcel_t_id = None
        if 'collected_parcel_t_id' in kwargs:
            # This is the case when this panel is called and we already know the parcel number is duplicated
            collected_parcel_t_id = kwargs['collected_parcel_t_id']
            search_criterion_collected = {
                ID_FIELD: collected_parcel_t_id
            }  # As there are duplicates, we need to use t_ids
        else:
            # This is the case when:
            #   + Either this panel was called and we know the parcel number is not duplicated, or
            #   + This panel was shown without knowing about duplicates (e.g., individual parcel search) and we still
            #     need to discover whether we have duplicates for this search criterion
            search_criterion_collected = {search_field: search_value}

            request = QgsFeatureRequest(expression)
            request.setFlags(QgsFeatureRequest.NoGeometry)
            request.setSubsetOfAttributes(
                [ID_FIELD], self.utils._layers[PARCEL_TABLE]
                [LAYER].fields())  # Note this adds a new flag
            collected_parcels = self.utils._layers[PARCEL_TABLE][
                LAYER].getFeatures(request)
            collected_parcels_t_ids = [
                feature[ID_FIELD] for feature in collected_parcels
            ]

            if collected_parcels_t_ids:
                collected_parcel_t_id = collected_parcels_t_ids[0]
                if len(collected_parcels_t_ids
                       ) > 1:  # Duplicates in collected source after a search
                    QApplication.restoreOverrideCursor(
                    )  # Make sure cursor is not waiting (it is if on an identify)
                    QCoreApplication.processEvents()
                    dlg_select_parcel = SelectDuplicateParcelDialog(
                        self.utils, collected_parcels_t_ids, self.parent)
                    dlg_select_parcel.exec_()

                    if dlg_select_parcel.parcel_t_id:  # User selected one of the duplicated parcels
                        collected_parcel_t_id = dlg_select_parcel.parcel_t_id
                        search_criterion_collected = {
                            ID_FIELD: collected_parcel_t_id
                        }
                    else:
                        return  # User just cancelled the dialog, there is nothing more to do

        search_criterion_official = {search_field: search_value}

        self.fill_table(search_criterion_official, search_criterion_collected)

        if collected_parcel_t_id is not None:
            plot_t_ids = self.utils.ladm_data.get_plots_related_to_parcels(
                self.utils._db, [collected_parcel_t_id],
                field_name=ID_FIELD,
                plot_layer=self.utils._layers[PLOT_TABLE][LAYER],
                uebaunit_table=self.utils._layers[UEBAUNIT_TABLE][LAYER])
            if plot_t_ids:
                self._current_substring = "{} IN ('{}')".format(
                    ID_FIELD, "','".join([str(t_id) for t_id in plot_t_ids]))
                if not already_zoomed_in:
                    self.parent.request_zoom_to_features(
                        self.utils._layers[PLOT_TABLE][LAYER], list(),
                        plot_t_ids)

                # Send a custom mouse move on the map to make the map swipe tool's limit appear on the canvas

                # Activate Swipe Tool
                self.utils.qgis_utils.activate_layer_requested.emit(
                    self.utils._official_layers[PLOT_TABLE][LAYER])
                if official_plot_t_ids:  # Otherwise the map swipe tool doesn't add any value :)
                    self.parent.activate_map_swipe_tool()

                    plots = self.utils.ladm_data.get_features_from_t_ids(
                        self.utils._layers[PLOT_TABLE][LAYER], plot_t_ids,
                        True)
                    plots_extent = QgsRectangle()
                    for plot in plots:
                        plots_extent.combineExtentWith(
                            plot.geometry().boundingBox())

                    coord_x = plots_extent.xMaximum() - (plots_extent.xMaximum(
                    ) - plots_extent.xMinimum()) / 9  # 90%
                    coord_y = plots_extent.yMaximum() - (plots_extent.yMaximum(
                    ) - plots_extent.yMinimum()) / 2  # 50%

                    coord_transform = self.utils.iface.mapCanvas(
                    ).getCoordinateTransform()
                    map_point = coord_transform.transform(coord_x, coord_y)
                    widget_point = map_point.toQPointF().toPoint()
                    global_point = self.utils.canvas.mapToGlobal(widget_point)

                    self.utils.canvas.mousePressEvent(
                        QMouseEvent(QEvent.MouseButtonPress, global_point,
                                    Qt.LeftButton, Qt.LeftButton,
                                    Qt.NoModifier))
                    self.utils.canvas.mouseMoveEvent(
                        QMouseEvent(QEvent.MouseMove,
                                    widget_point + QPoint(1, 0), Qt.NoButton,
                                    Qt.LeftButton, Qt.NoModifier))
                    self.utils.canvas.mouseReleaseEvent(
                        QMouseEvent(QEvent.MouseButtonRelease,
                                    widget_point + QPoint(1, 0), Qt.LeftButton,
                                    Qt.LeftButton, Qt.NoModifier))

        # Once the query is done, activate the checkbox to alternate all plots/only selected plot
        self.chk_show_all_plots.setEnabled(True)
Ejemplo n.º 4
0
    def test_resetSnappingIndex(self):
        self.pointsLayer.setDependencies([])
        self.linesLayer.setDependencies([])
        self.pointsLayer2.setDependencies([])

        ms = QgsMapSettings()
        ms.setOutputSize(QSize(100, 100))
        ms.setExtent(QgsRectangle(0, 0, 1, 1))
        self.assertTrue(ms.hasValidSettings())

        u = QgsSnappingUtils()
        u.setMapSettings(ms)
        cfg = u.config()
        cfg.setEnabled(True)
        cfg.setMode(QgsSnappingConfig.AdvancedConfiguration)
        cfg.setIndividualLayerSettings(
            self.pointsLayer,
            QgsSnappingConfig.IndividualLayerSettings(True,
                                                      QgsSnappingConfig.Vertex,
                                                      20, QgsTolerance.Pixels))
        u.setConfig(cfg)

        m = u.snapToMap(QPoint(95, 100))
        self.assertTrue(m.isValid())
        self.assertTrue(m.hasVertex())
        self.assertEqual(m.point(), QgsPointXY(1, 0))

        f = QgsFeature(self.linesLayer.fields())
        f.setId(1)
        geom = QgsGeometry.fromWkt("LINESTRING(0 0,1 1)")
        f.setGeometry(geom)
        self.linesLayer.startEditing()
        self.linesLayer.addFeatures([f])
        self.linesLayer.commitChanges()

        l1 = len([f for f in self.pointsLayer.getFeatures()])
        self.assertEqual(l1, 4)
        m = u.snapToMap(QPoint(95, 0))
        # snapping not updated
        self.pointsLayer.setDependencies([])
        self.assertEqual(m.isValid(), False)

        # set layer dependencies
        self.pointsLayer.setDependencies(
            [QgsMapLayerDependency(self.linesLayer.id())])
        # add another line
        f = QgsFeature(self.linesLayer.fields())
        f.setId(2)
        geom = QgsGeometry.fromWkt("LINESTRING(0 0,0.5 0.5)")
        f.setGeometry(geom)
        self.linesLayer.startEditing()
        self.linesLayer.addFeatures([f])
        self.linesLayer.commitChanges()
        # check the snapped point is OK
        m = u.snapToMap(QPoint(45, 50))
        self.assertTrue(m.isValid())
        self.assertTrue(m.hasVertex())
        self.assertEqual(m.point(), QgsPointXY(0.5, 0.5))
        self.pointsLayer.setDependencies([])

        # test chained layer dependencies A -> B -> C
        cfg.setIndividualLayerSettings(
            self.pointsLayer2,
            QgsSnappingConfig.IndividualLayerSettings(True,
                                                      QgsSnappingConfig.Vertex,
                                                      20, QgsTolerance.Pixels))
        u.setConfig(cfg)
        self.pointsLayer.setDependencies(
            [QgsMapLayerDependency(self.linesLayer.id())])
        self.pointsLayer2.setDependencies(
            [QgsMapLayerDependency(self.pointsLayer.id())])
        # add another line
        f = QgsFeature(self.linesLayer.fields())
        f.setId(3)
        geom = QgsGeometry.fromWkt("LINESTRING(0 0.2,0.5 0.8)")
        f.setGeometry(geom)
        self.linesLayer.startEditing()
        self.linesLayer.addFeatures([f])
        self.linesLayer.commitChanges()
        # check the second snapped point is OK
        m = u.snapToMap(QPoint(75, 100 - 80))
        self.assertTrue(m.isValid())
        self.assertTrue(m.hasVertex())
        self.assertEqual(m.point(), QgsPointXY(0.7, 0.8))
        self.pointsLayer.setDependencies([])
        self.pointsLayer2.setDependencies([])
Ejemplo n.º 5
0
 def canvasPressEvent(self, event):
     self.pressed.emit(QPoint(event.pos().x(), event.pos().y()))
Ejemplo n.º 6
0
 def canvasMoveEvent(self, event):
     self.moved.emit(QPoint(event.pos().x(), event.pos().y()))
Ejemplo n.º 7
0
 def popup(self, pos, action=None):
     newPos = QPoint(pos.x() + self.offset, pos.y() + self.offset)
     QMenu.popup(self, newPos, action)
Ejemplo n.º 8
0
 def zoomActual(self):
     point = self.view.mapToScene(QPoint(self.view.viewport().width() / 2, self.view.viewport().height() / 2))
     self.view.resetTransform()
     self.view.scale(QgsApplication.desktop().logicalDpiX() / 96, QgsApplication.desktop().logicalDpiX() / 96)
     self.view.centerOn(point)
Ejemplo n.º 9
0
    def test_tool(self):
        """
        Test some plot tool logic
        """
        canvas = QgsElevationProfileCanvas()
        canvas.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        canvas.setFrameStyle(0)
        canvas.resize(600, 400)
        canvas.setProject(QgsProject.instance())
        canvas.show()
        self.assertEqual(canvas.width(), 600)
        self.assertEqual(canvas.height(), 400)
        ls = QgsLineString()
        ls.fromWkt('LineString(0 2, 10 2, 10 4)')
        canvas.setProfileCurve(ls)
        canvas.setVisiblePlotRange(0, ls.length(), 0, 100)

        self.assertFalse(canvas.tool())
        tool = TestTool(canvas)
        self.assertFalse(tool.isActive())
        canvas.setTool(tool)
        self.assertEqual(canvas.tool(), tool)

        key_press_event = QKeyEvent(QEvent.KeyPress, 54, Qt.ShiftModifier)
        canvas.keyPressEvent(key_press_event)
        self.assertEqual(tool.events[-1].type(), QEvent.KeyPress)

        key_release_event = QKeyEvent(QEvent.KeyRelease, 54, Qt.ShiftModifier)
        canvas.keyReleaseEvent(key_release_event)
        self.assertEqual(tool.events[-1].type(), QEvent.KeyRelease)

        mouse_dbl_click_event = QMouseEvent(QEvent.MouseButtonDblClick,
                                            QPointF(300, 200), Qt.LeftButton,
                                            Qt.MouseButtons(),
                                            Qt.ShiftModifier)
        canvas.mouseDoubleClickEvent(mouse_dbl_click_event)
        self.assertEqual(tool.events[-1].type(), QEvent.MouseButtonDblClick)
        self.assertIsInstance(tool.events[-1], QgsPlotMouseEvent)
        self.assertAlmostEqual(tool.events[-1].mapPoint().x(), 5.92, 1)
        self.assertAlmostEqual(tool.events[-1].mapPoint().y(), 2, 4)
        self.assertAlmostEqual(tool.events[-1].mapPoint().z(), 49.165, 0)

        mouse_move_event = QMouseEvent(QEvent.MouseMove,
                                       QPointF(300, 200), Qt.LeftButton,
                                       Qt.MouseButtons(), Qt.ShiftModifier)
        canvas.mouseMoveEvent(mouse_move_event)
        self.assertEqual(tool.events[-1].type(), QEvent.MouseMove)
        self.assertIsInstance(tool.events[-1], QgsPlotMouseEvent)
        self.assertAlmostEqual(tool.events[-1].mapPoint().x(), 5.92, 1)
        self.assertAlmostEqual(tool.events[-1].mapPoint().y(), 2, 4)
        self.assertAlmostEqual(tool.events[-1].mapPoint().z(), 49.165, 0)

        mouse_press_event = QMouseEvent(QEvent.MouseButtonPress,
                                        QPointF(300, 200), Qt.LeftButton,
                                        Qt.MouseButtons(), Qt.ShiftModifier)
        canvas.mousePressEvent(mouse_press_event)
        self.assertEqual(tool.events[-1].type(), QEvent.MouseButtonPress)
        self.assertIsInstance(tool.events[-1], QgsPlotMouseEvent)
        self.assertAlmostEqual(tool.events[-1].mapPoint().x(), 5.927, 1)
        self.assertAlmostEqual(tool.events[-1].mapPoint().y(), 2, 4)
        self.assertAlmostEqual(tool.events[-1].mapPoint().z(), 49.165, 0)

        mouse_release_event = QMouseEvent(QEvent.MouseButtonRelease,
                                          QPointF(300, 200), Qt.LeftButton,
                                          Qt.MouseButtons(), Qt.ShiftModifier)
        canvas.mouseReleaseEvent(mouse_release_event)
        self.assertEqual(tool.events[-1].type(), QEvent.MouseButtonRelease)
        self.assertIsInstance(tool.events[-1], QgsPlotMouseEvent)
        self.assertAlmostEqual(tool.events[-1].mapPoint().x(), 5.927, 1)
        self.assertAlmostEqual(tool.events[-1].mapPoint().y(), 2, 4)
        self.assertAlmostEqual(tool.events[-1].mapPoint().z(), 49.165, 0)

        wheel_event = QWheelEvent(QPointF(300, 200), QPointF(300, 200),
                                  QPoint(1, 2), QPoint(3, 4), Qt.NoButton,
                                  Qt.NoModifier, Qt.ScrollBegin, False)
        canvas.wheelEvent(wheel_event)
        self.assertEqual(tool.events[-1].type(), QEvent.Wheel)