8

I'm trying to add points on a line with QgsMapTool. I need to show snap indicator (vertex or edge) while moving the mouse on a line.

How can I do that?

Here is my code:

class uubEditTool(QgsMapToolEdit):
    def __init__(self, canvas, iface, db):
        self.canvas = canvas
        self.iface = iface
        QgsMapToolEdit.__init__(self, self.canvas)

        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(
            self.plugin_dir,
            'i18n',
            'FiberManagementSystem_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)
            QCoreApplication.installTranslator(self.translator)
        self.msg = QMessageBox()
        self.rb = QgsRubberBand(self.canvas, QgsWkbTypes.PointGeometry)
        self.rb.setStrokeColor(QColor('Purple'))
        self.rb.setWidth(2.0)
        self.first_click = True
        # self.fixed_points = []
        self.deactivated.connect(lambda: self.clean_up)
       
    def canvasReleaseEvent(self, event):
        theUser = ''

        ugr_lyr = QgsProject().instance().mapLayersByName("Under Ground Route")[0]
        x_point = event.pos().x()
        y_point = event.pos().y()
        point = self.canvas.getCoordinateTransform().toMapCoordinates(x_point, y_point)
        print("point", point)
        click_point = event.snapPoint()

        if event.isSnapped():
            print("UUB is Snapped to UGR")
            if event.button() == Qt.LeftButton:
                
                self.layer = self.iface.activeLayer()
                new_point = QgsPointXY(point)
                geom = QgsGeometry().fromPointXY(new_point)
                if self.layer.isEditable():
                    source = self.layer.source()
                    kvp = source.split(" ")
                    for kv in kvp:
                        if kv.startswith("user"):
                            theUser = kv.split("=")[1][1:-1]
                    self.layer.beginEditCommand('Add Snapped Feature')
                    fields = self.layer.fields()
                    # gid_field = layer.fields().indexFromName('gid')
                    creat_by = self.layer.fields().indexFromName('created_by')
                    creat_date = self.layer.fields().indexFromName('created_date')
                    uub_name = self.layer.fields().indexFromName('uub_name')
                    uub_latitude = self.layer.fields().indexFromName('latitude')
                    uub_longitude = self.layer.fields().indexFromName('longitude')
                    # make = layer.fields().indexFromName('make')
                    self.feat = QgsFeature()
                    self.feat.setGeometry(geom)
                    self.feat.setFields(self.layer.fields())

                    x = geom.asPoint().x()
                    y = geom.asPoint().y()
                    self.feat[uub_longitude] = round(x, 6)
                    self.feat[uub_latitude] = round(y, 6)
                    d = QgsDistanceArea()
                    d.setEllipsoid('WGS84')

                    layer.addFeature(feat)
                    layer.updateFeature(feat)
                    layer.endEditCommand()

1
  • 1
    Your script has missing parts, for example, self.clean_up. Even if a solution is offered to you, the solution may not work for you without completing the missing parts. Nov 22, 2021 at 7:16

2 Answers 2

10

Add the following lines to __init__ method:

self.snapIndicator = QgsSnapIndicator(canvas)
self.snapper = self.canvas.snappingUtils()

And add a canvasMoveEvent method like this:

def canvasMoveEvent(self, e):
    snapMatch = self.snapper.snapToMap(e.pos())
    self.snapIndicator.setMatch(snapMatch)

After running the script, enable snapping from Snapping Toolbar.

enter image description here

Source: Activating snapping with PyQGIS?

PS: I've removed some lines to run it seamlessly in my QGIS. If your script in the question already works as it is, the solution will work for you.

0
5

Above answer will give the snapping for active Layer, for all Layers

self.snapper = canvas.snappingUtils()
config = QgsSnappingConfig()
config.setEnabled(True)
config.setType(QgsSnappingConfig.VertexAndSegment)
config.setUnits(QgsTolerance.Pixels)
config.setTolerance(12)
config.setMode(2)
self.snapper.setConfig(config)
self.snapindicator = QgsSnapIndicator(canvas)
1
  • I didn't add this detail to my answer, since you didn't particularly mention it. Nov 22, 2021 at 8:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.