Exemplo n.º 1
0
    def canvasMoveEvent(self, event):  # pylint: disable=missing-docstring
        if not self.is_active:
            # snapping tool - show indicator
            matches = self.get_district_boundary_matches(event.mapPoint())
            if self.matches_are_valid_for_boundary(matches):
                # we require exactly 2 matches from different districts -- cursor must be over a border
                # of two features
                self.snap_indicator.setMatch(matches[0])
            else:
                self.snap_indicator.setMatch(QgsPointLocator.Match())
        elif self.districts:
            dist = self.click_point.distance(event.mapPoint())
            if dist < QgsTolerance.vertexSearchRadius(self.canvas().mapSettings()):
                return
            match = self.get_district_area_match(event.mapPoint())
            p = QgsGeometry.fromPointXY(event.mapPoint())
            targets = [m for m in self.get_target_features_from_matches([match]) if
                       m.id() not in self.modified and m.geometry().intersects(p)]
            if len(targets) == 1:
                target = targets[0]
                old_district = target[self.handler.target_field]
                if not self.current_district:
                    candidates = [d for d in self.districts if d != old_district]
                    if candidates:
                        self.current_district = candidates[0]
                if self.current_district and old_district and self.current_district != old_district:
                    if not self.modified:
                        # first modified district - push edit command
                        self.handler.begin_edit_group(
                            QCoreApplication.translate('LinzRedistrict', 'Redistrict to {}').format(
                                self.district_registry.get_district_title(self.current_district)))

                    self.modified.add(target.id())
                    self.handler.assign_district([target.id()], self.current_district)
                    AudioUtils.play_redistrict_sound()
    def snap_to_intersection(self, pos):
        """ Temporarily override snapping config and snap to vertices and edges
         of any editable vector layer, to allow selection of node for editing
         (if snapped to edge, it would offer creation of a new vertex there).
        """
        map_point = self.toMapCoordinates(pos)
        tol = QgsTolerance.vertexSearchRadius(self.canvas().mapSettings())
        snap_type = QgsPointLocator.Type(QgsPointLocator.Edge)

        snap_layers = []
        for layer in self.canvas().layers():
            if not isinstance(layer, QgsVectorLayer):
                continue
            snap_layers.append(QgsSnappingUtils.LayerConfig(
                layer, snap_type, tol, QgsTolerance.ProjectUnits))

        snap_util = self.canvas().snappingUtils()
        old_layers = snap_util.layers()
        old_mode = snap_util.snapToMapMode()
        old_inter = snap_util.snapOnIntersections()
        snap_util.setLayers(snap_layers)
        snap_util.setSnapToMapMode(QgsSnappingUtils.SnapAdvanced)
        snap_util.setSnapOnIntersections(True)
        m = snap_util.snapToMap(map_point)
        snap_util.setLayers(old_layers)
        snap_util.setSnapToMapMode(old_mode)
        snap_util.setSnapOnIntersections(old_inter)
        return m
Exemplo n.º 3
0
    def snap_to_segment(self, pos):
        """ Temporarily override snapping config and snap to vertices and edges
         of any editable vector layer, to allow selection of node for editing
         (if snapped to edge, it would offer creation of a new vertex there).
        """
        map_point = self.toMapCoordinates(pos)
        tol = QgsTolerance.vertexSearchRadius(self.canvas.mapSettings())
        snap_type = QgsPointLocator.Type(QgsPointLocator.Edge)

        snap_layers = []
        for layer in self.canvas.layers():
            if not isinstance(layer, QgsVectorLayer):
                continue
            snap_layers.append(
                QgsSnappingUtils.LayerConfig(layer, snap_type, tol,
                                             QgsTolerance.ProjectUnits))

        snap_util = self.canvas.snappingUtils()
        old_layers = snap_util.layers()
        old_mode = snap_util.snapToMapMode()
        old_inter = snap_util.snapOnIntersections()
        snap_util.setLayers(snap_layers)
        snap_util.setSnapToMapMode(QgsSnappingUtils.SnapAdvanced)
        snap_util.setSnapOnIntersections(False)
        m = snap_util.snapToMap(map_point)
        snap_util.setLayers(old_layers)
        snap_util.setSnapToMapMode(old_mode)
        snap_util.setSnapOnIntersections(old_inter)
        return m
Exemplo n.º 4
0
    def snap_to_dimension_layer(self, pos):
        """ Temporarily override snapping config and snap to vertices and edges
            of any editable vector layer, to allow selection of node for editing
            (if snapped to edge, it would offer creation of a new vertex there).
           """
        map_point = self.toMapCoordinates(pos)
        tol = QgsTolerance.vertexSearchRadius(self.canvas().mapSettings())
        snap_type = QgsPointLocator.Type(QgsPointLocator.Edge)

        snap_layers = [
            QgsSnappingUtils.LayerConfig(self.layer, snap_type, tol,
                                         QgsTolerance.ProjectUnits)
        ]

        snap_util = self.canvas().snappingUtils()
        old_layers = snap_util.layers()
        old_mode = snap_util.snapToMapMode()
        old_inter = snap_util.snapOnIntersections()
        snap_util.setLayers(snap_layers)
        snap_util.setSnapToMapMode(QgsSnappingUtils.SnapAdvanced)
        snap_util.setSnapOnIntersections(False)
        m = snap_util.snapToMap(map_point)
        snap_util.setLayers(old_layers)
        snap_util.setSnapToMapMode(old_mode)
        snap_util.setSnapOnIntersections(old_inter)

        f = QgsFeature()
        if m.featureId() is not None:
            self.layer.getFeatures(QgsFeatureRequest().setFilterFid(
                m.featureId())).nextFeature(f)
        return f
Exemplo n.º 5
0
    def snap_to_dimension_layer(self, pos):
        """ Temporarily override snapping config and snap to vertices and edges
            of any editable vector layer, to allow selection of node for editing
            (if snapped to edge, it would offer creation of a new vertex there).
           """
        map_point = self.toMapCoordinates(pos)
        tol = QgsTolerance.vertexSearchRadius(self.canvas().mapSettings())
        snap_type = QgsPointLocator.Type(QgsPointLocator.Edge)

        snap_layers = [QgsSnappingUtils.LayerConfig(self.layer, snap_type, tol, QgsTolerance.ProjectUnits)]

        snap_util = self.canvas().snappingUtils()
        old_layers = snap_util.layers()
        old_mode = snap_util.snapToMapMode()
        old_inter = snap_util.snapOnIntersections()
        snap_util.setLayers(snap_layers)
        snap_util.setSnapToMapMode(QgsSnappingUtils.SnapAdvanced)
        snap_util.setSnapOnIntersections(False)
        m = snap_util.snapToMap(map_point)
        snap_util.setLayers(old_layers)
        snap_util.setSnapToMapMode(old_mode)
        snap_util.setSnapOnIntersections(old_inter)

        f = QgsFeature()
        if m.featureId() is not None:
            self.layer.getFeatures(QgsFeatureRequest().setFilterFid(m.featureId())).nextFeature(f)
        return f
Exemplo n.º 6
0
 def get_district_area_match(self, point):
     """
     Returns a possible snapping match corresponding to the area under
     the cursor
     :param point: map point to snap from
     """
     locator = self.canvas().snappingUtils().locatorForLayer(self.handler.target_layer)
     tolerance = QgsTolerance.vertexSearchRadius(self.canvas().mapSettings())
     match = locator.nearestArea(point, tolerance)
     return match
Exemplo n.º 7
0
    def get_district_boundary_matches(self, point):
        """
        Returns a list of snapping matches corresponding to boundaries
        between existing districts
        :param point: map point to snap from
        """

        # use QGIS cursor tolerance setting
        tolerance = QgsTolerance.vertexSearchRadius(self.canvas().mapSettings())

        # collect matching edges
        locator = self.canvas().snappingUtils().locatorForLayer(self.handler.target_layer)
        match_filter = UniqueFeatureEdgeMatchCollectingFilter(tolerance)
        locator.nearestEdge(point, tolerance, match_filter)
        return match_filter.get_matches()
Exemplo n.º 8
0
    def canvasPressEvent(self, event):
        if self.rubberBand is not None:
            self.rubberBand.reset()
        del self.rubberBand
        self.rubberBand = None
        self.canvas.refresh()

        layerCoords = self.toLayerCoordinates(self.layer, event.pos())
        searchRadius = QgsTolerance.vertexSearchRadius(self.canvas.currentLayer(), self.canvas.mapSettings())
        selectRect = QgsRectangle(layerCoords.x() - searchRadius,
                                  layerCoords.y() - searchRadius,
                                  layerCoords.x() + searchRadius,
                                  layerCoords.y() + searchRadius)

        pointGeometry = QgsGeometry.fromPoint(layerCoords)
        if not pointGeometry:
            return

        minDistance = sys.float_info.max

        cf = None
        for f in self.layer.getFeatures(QgsFeatureRequest().setFilterRect(selectRect).setSubsetOfAttributes([])):
            if f.geometry():
                currentDistance = pointGeometry.distance(f.geometry())
                if currentDistance < minDistance:
                    minDistance = currentDistance
                    cf = f

        if minDistance == sys.float_info.max:
            return

        self.movedFeatures[:] = []
        self.movedFeatures.append(QgsFeature(cf))

        self.rubberBand = self.createRubberBand(self.layer.geometryType())
        self.rubberBand.setToGeometry(cf.geometry(), self.layer)

        self.startPointMapCoords = self.toMapCoordinates(event.pos())
        self.rubberBand.setColor(QColor(255, 0, 0, 65))
        self.rubberBand.setWidth(2)
        self.rubberBand.show()
Exemplo n.º 9
0
    def snap_to_editable_layer(self, e):
        """ Temporarily override snapping config and snap to vertices and edges
         of any editable vector layer, to allow selection of node for editing
         (if snapped to edge, it would offer creation of a new vertex there).
        """
        QgsMessageLog.logMessage("In TOMsNodeTool:snap_to_editable_layer", tag="TOMs panel")

        map_point = self.toMapCoordinates(e.pos())
        tol = QgsTolerance.vertexSearchRadius(self.canvas().mapSettings())
        snap_type = QgsPointLocator.Type(QgsPointLocator.Vertex|QgsPointLocator.Edge)

        #snap_layers = []

        ### TH: Amend to choose only from selected feature (and layer)

        """snap_layers.append(QgsSnappingUtils.LayerConfig(
            self.origLayer, snap_type, tol, QgsTolerance.ProjectUnits))"""

        """for layer in self.canvas().layers():
            if not isinstance(layer, QgsVectorLayer) or not layer.isEditable():
                continue
            snap_layers.append(QgsSnappingUtils.LayerConfig(
                layer, snap_type, tol, QgsTolerance.ProjectUnits))"""

        snap_util = self.canvas().snappingUtils()
        old_snap_util = snap_util
        snap_config = snap_util.config()

        #snap_util = QgsSnappingUtils()
        #snap_config = snap_util.config()
        # old_layers = snap_util.layers()
        # old_mode = snap_util.mode()
        # old_intersections = old_snap_config.intersectionSnapping()

        """
        for layer in snap_config.individualLayerSettings().keys():
            snap_config.removeLayers([layer])
        """

        snap_util.setCurrentLayer(self.origLayer)

        snap_config.setMode(QgsSnappingConfig.ActiveLayer)
        snap_config.setIntersectionSnapping(False)  # only snap to layers
        #m = snap_util.snapToMap(map_point)
        snap_config.setTolerance(tol)
        snap_config.setUnits(QgsTolerance.ProjectUnits)
        snap_config.setType(QgsSnappingConfig.VertexAndSegment)
        snap_config.setEnabled(True)

        """snap_config.setMode(QgsSnappingConfig.AdvancedConfiguration)

        currLayerSnapSettings = snap_config.individualLayerSettings(self.origLayer)
        currLayerSnapSettings.setTolerance(tol)
        currLayerSnapSettings.setUnits(QgsTolerance.ProjectUnits)
        currLayerSnapSettings.setType(QgsSnappingConfig.VertexAndSegment)
        currLayerSnapSettings.setEnabled(True)

        snap_config.setIndividualLayerSettings(self.origLayer, currLayerSnapSettings)"""

        # try to stay snapped to previously used feature
        # so the highlight does not jump around at nodes where features are joined

        ### TH: Amend to choose only from selected feature (and layer)

        filter_last = OneFeatureFilter(self.origLayer, self.origFeature.getFeature().id())
        # m = snap_util.snapToMap(map_point, filter_last)
        """if m_last.isValid() and m_last.distance() <= m.distance():
            m = m_last"""
        self.origFeature.printFeature()
        QgsMessageLog.logMessage("In TOMsNodeTool:snap_to_editable_layer: origLayer " + self.origLayer.name(), tag="TOMs panel")

        """ v3 try to use some other elements of snap_config
            - snapToCurrentLayer
            - setCurrentLayer
            
        """
        QgsMessageLog.logMessage("In TOMsNodeTool:snap_to_editable_layer: pos " + str(e.pos().x()) + "|" + str(e.pos().y()),
                                 tag="TOMs panel")

        m = snap_util.snapToCurrentLayer(e.pos(), snap_type, filter_last)
        """self.canvas().setSnappingUtils(snap_util)
        m = snap_util.snapToMap(e.pos(), filter_last)"""

        #snap_util.setLayers(old_layers)
        #snap_config.setMode(old_mode)
        #snap_config.setIntersectionSnapping(old_intersections)
        self.canvas().setSnappingUtils(old_snap_util)

        #self.last_snap = m

        # TODO: Tidy up ...

        QgsMessageLog.logMessage("In TOMsNodeTool:snap_to_editable_layer: snap point " + str(m.type()) +";" + str(m.isValid()) + "; ", tag="TOMs panel")

        return m