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
def snapToMap(self, pt): self.filter.matches = list() match = QgsMapCanvasSnappingUtils.snapToMap(self, pt, self.filter) def sorter(match): layer = match.layer() try: return self.layer_priority.index(layer) except ValueError: return 0 layer_tolerances = dict() for layer_config in self.layers(): layer_tolerances[layer_config.layer] = QgsTolerance.toleranceInProjectUnits( layer_config.tolerance, layer_config.layer, self.mapSettings(), layer_config.unit) matches = sorted(self.filter.matches, key=sorter) matches = [m for m in matches if m.distance() < layer_tolerances[m.layer()]] if matches: match = matches[0] elif self.config().mode() == QgsSnappingConfig.AdvancedConfiguration: for layer in self.layers(): if layer.type & QgsPointLocator.Area: loc = self.locatorForLayer(layer.layer) results = loc.pointInPolygon(pt) if results: return results[0] return match
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
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
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
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 canvasPressEvent(self, event): """ If pressEvent point is near the layer point, enable dragging. Else show msg box """ if event.button() == Qt.LeftButton: click_point = self.toLayerCoordinates(self.lm_layer, event.pos()) if self.lm_layer.featureCount() == 1: feature_list = self.lm_layer.dataProvider().getFeatures( ) #Returns iterator to a list of one feature self.lm_feature = next( feature_list) #get first and only element in the list self.lm_point = self.lm_feature.geometry().asPoint() dist = QgsPointXY.distance(click_point, self.lm_point) tolerance = (QgsTolerance.toleranceInMapUnits( 15, self.lm_layer, self.canvas().mapSettings(), QgsTolerance.Pixels)) if dist < tolerance: #Clicked on a landmark self.clicked_on_landmark = True self.create_ghost_point() else: #Not clicked on a landmark confirmation_msg = "Do you want to move {} here? \n\n".format( self.lm_layer.name()) reply = QMessageBox.question(self.parent(), 'Movement Confirmation', confirmation_msg, QMessageBox.Yes, QMessageBox.No) if reply == QMessageBox.Yes: self.move_position(click_point)
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
def syntheticFeatureSelection(self, startPoint: QgsPointXY, endPoint: QgsPointXY, modifiers: Qt.KeyboardModifiers) -> None: if startPoint is None or endPoint is None: raise Exception( 'Something went very bad, unable to create selection without start or end point' ) assert self.simplifiedSegmentsLayer if self.selectionMode != SelectionModes.LINES: self.simplifiedSegmentsLayer.removeSelection() # check the Shift and Control modifiers to reproduce the navive selection if modifiers & Qt.ShiftModifier: selectBehaviour = QgsVectorLayer.AddToSelection elif modifiers & Qt.ControlModifier: selectBehaviour = QgsVectorLayer.RemoveFromSelection else: selectBehaviour = QgsVectorLayer.SetSelection if startPoint.x() == endPoint.x() and startPoint.y() == endPoint.y(): tolerance = QgsTolerance.defaultTolerance(iface.activeLayer(), QgsMapSettings()) tolerance = tolerance * self.canvas.mapUnitsPerPixel() startPoint = QgsPointXY(startPoint.x() - tolerance, startPoint.y() - tolerance) endPoint = QgsPointXY(endPoint.x() + tolerance, endPoint.y() + tolerance) lines = None rect = QgsRectangle(startPoint, endPoint) if self.selectionMode == SelectionModes.ENCLOSING: lines = self.getLinesSelectionModeEnclosing(selectBehaviour, rect) elif self.selectionMode == SelectionModes.LINES: lines = self.getLinesSelectionModeLines(selectBehaviour, rect) elif self.selectionMode == SelectionModes.NODES: lines = self.getLinesSelectionModeVertices(selectBehaviour, rect) if lines is None: return else: raise Exception( 'Wrong selection mode selected, should never be the case') if not len(lines): show_info(__('No results found!')) self.deleteAllCandidates() return if not self.addCandidates(lines): show_info(__('Unable to add candidates')) return
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()
def canvasReleaseEvent(self, event): searchRadius = (QgsTolerance.toleranceInMapUnits( 5, self.layerfrom, self.canvas().mapRenderer(), QgsTolerance.Pixels)) point = self.toMapCoordinates(event.pos()) rect = QgsRectangle() rect.setXMinimum(point.x() - searchRadius) rect.setXMaximum(point.x() + searchRadius) rect.setYMinimum(point.y() - searchRadius) rect.setYMaximum(point.y() + searchRadius) rq = QgsFeatureRequest().setFilterRect(rect) try: # Only supports the first feature # TODO build picker to select which feature to inspect feature = self.layerfrom.getFeatures(rq).next() self.band.setToGeometry(feature.geometry(), self.layerfrom) fields = self.layerto.pendingFields() newfeature = QgsFeature(fields) if self.layerto.geometryType() == QGis.Point: newfeature.setGeometry(QgsGeometry.fromPoint(point)) else: newfeature.setGeometry(QgsGeometry(feature.geometry())) #Set the default values for indx in xrange(fields.count()): newfeature[indx] = self.layerto.dataProvider().defaultValue( indx) # Assign the old values to the new feature for fieldfrom, fieldto in self.fields.iteritems(): newfeature[fieldto] = feature[fieldfrom] passed, message = self.validation_method(feature=newfeature, layerto=self.layerto) if passed: self.finished.emit(self.layerto, newfeature) else: self.band.reset() self.error.emit(message) except StopIteration: pass
def canvasReleaseEvent(self, event): searchRadius = (QgsTolerance.toleranceInMapUnits( 5, self.layerfrom, self.canvas().mapRenderer(), QgsTolerance.Pixels)) point = self.toMapCoordinates(event.pos()) rect = QgsRectangle() rect.setXMinimum(point.x() - searchRadius) rect.setXMaximum(point.x() + searchRadius) rect.setYMinimum(point.y() - searchRadius) rect.setYMaximum(point.y() + searchRadius) rq = QgsFeatureRequest().setFilterRect(rect) # Look for an existing feature first. If there is one # then we emit that back to qmap. try: feature = self.layerto.getFeatures(rq).next() self.band.setToGeometry(feature.geometry(), self.layerto) self.finished.emit(self.layerto, feature) return except StopIteration: pass try: # Only supports the first feature # TODO build picker to select which feature to inspect feature = self.layerfrom.getFeatures(rq).next() self.band.setToGeometry(feature.geometry(), self.layerfrom) fields = self.layerto.pendingFields() newfeature = QgsFeature(fields) newfeature.setGeometry(QgsGeometry(feature.geometry())) #Set the default values for indx in xrange(fields.count()): newfeature[indx] = self.layerto.dataProvider().defaultValue( indx) # Assign the old values to the new feature for fieldfrom, fieldto in self.fields.iteritems(): newfeature[fieldto] = feature[fieldfrom] self.finished.emit(self.layerto, newfeature) except StopIteration: pass
def canvasReleaseEvent(self, event): searchRadius = (QgsTolerance.toleranceInMapUnits( 5, self.layerfrom, self.canvas().mapRenderer(), QgsTolerance.Pixels)) point = self.toMapCoordinates(event.pos()) rect = QgsRectangle() rect.setXMinimum(point.x() - searchRadius) rect.setXMaximum(point.x() + searchRadius) rect.setYMinimum(point.y() - searchRadius) rect.setYMaximum(point.y() + searchRadius) rq = QgsFeatureRequest().setFilterRect(rect) # Look for an existing feature first. If there is one # then we emit that back to qmap. try: feature = self.layerto.getFeatures(rq).next() self.band.setToGeometry(feature.geometry(), self.layerto) self.finished.emit(self.layerto, feature) return except StopIteration: pass try: # Only supports the first feature # TODO build picker to select which feature to inspect feature = self.layerfrom.getFeatures(rq).next() self.band.setToGeometry(feature.geometry(), self.layerfrom) fields = self.layerto.pendingFields() newfeature = QgsFeature(fields) newfeature.setGeometry(QgsGeometry(feature.geometry())) #Set the default values for indx in xrange(fields.count()): newfeature[indx] = self.layerto.dataProvider().defaultValue( indx ) # Assign the old values to the new feature for fieldfrom, fieldto in self.fields.iteritems(): newfeature[fieldto] = feature[fieldfrom] self.finished.emit(self.layerto, newfeature) except StopIteration: pass
def canvasReleaseEvent(self, event): searchRadius = (QgsTolerance.toleranceInMapUnits( 5, self.layerfrom, self.canvas().mapRenderer(), QgsTolerance.Pixels)) point = self.toMapCoordinates(event.pos()) rect = QgsRectangle() rect.setXMinimum(point.x() - searchRadius) rect.setXMaximum(point.x() + searchRadius) rect.setYMinimum(point.y() - searchRadius) rect.setYMaximum(point.y() + searchRadius) rq = QgsFeatureRequest().setFilterRect(rect) try: # Only supports the first feature # TODO build picker to select which feature to inspect feature = self.layerfrom.getFeatures(rq).next() self.band.setToGeometry(feature.geometry(), self.layerfrom) fields = self.layerto.pendingFields() newfeature = QgsFeature(fields) if self.layerto.geometryType() == QGis.Point: newfeature.setGeometry(QgsGeometry.fromPoint(point)) else: newfeature.setGeometry(QgsGeometry(feature.geometry())) #Set the default values for indx in xrange(fields.count()): newfeature[indx] = self.layerto.dataProvider().defaultValue( indx ) # Assign the old values to the new feature for fieldfrom, fieldto in self.fields.iteritems(): newfeature[fieldto] = feature[fieldfrom] passed, message = self.validation_method(feature=newfeature, layerto=self.layerto) if passed: self.finished.emit(self.layerto, newfeature) else: self.band.reset() self.error.emit(message) except StopIteration: pass
def layer_tolerance(map_canvas, layer): """Functions finds out default tolerance from qgis settings. Required value (of qgis settings) is returned by QgsTolerance.defaultTolerance(...) calling. If returned value equals 0.0, we ignore it and calculate our own tolerance from current extent width. @return default tolerance """ qgis_tolerance = QgsTolerance.defaultTolerance( layer, map_canvas.mapRenderer()) if qgis_tolerance == 0.0: extent = map_canvas.extent() w = extent.xMaximum() - extent.xMinimum() return w / 220 return qgis_tolerance
def getFeatures(self, point): searchRadius = (QgsTolerance.toleranceInMapUnits( self.radius, self.layers[0], self.canvas.mapRenderer(), QgsTolerance.Pixels)) point = self.toMapCoordinates(point) rect = QgsRectangle() rect.setXMinimum(point.x() - searchRadius) rect.setXMaximum(point.x() + searchRadius) rect.setYMinimum(point.y() - searchRadius) rect.setYMaximum(point.y() + searchRadius) rq = QgsFeatureRequest().setFilterRect(rect) self.band.reset() for layer in self.layers: rq = QgsFeatureRequest().setFilterRect(rect) for feature in layer.getFeatures(rq): if feature.isValid(): yield feature, layer
def getFeatures(self, point): searchRadius = (QgsTolerance.toleranceInMapUnits( self.radius, self.layers[0], self.canvas.mapRenderer(), QgsTolerance.Pixels)) point = self.toMapCoordinates(point) rect = QgsRectangle() rect.setXMinimum(point.x() - searchRadius) rect.setXMaximum(point.x() + searchRadius) rect.setYMinimum(point.y() - searchRadius) rect.setYMaximum(point.y() + searchRadius) rq = QgsFeatureRequest().setFilterRect(rect) self.band.reset() for layer in self.layers: rq = QgsFeatureRequest().setFilterRect(rect) for feature in layer.getFeatures(rq): if feature.isValid(): yield feature, layer
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()
def canvasPressEvent(self, event): """ Override of QgsMapTool mouse press event """ if event.button() == Qt.LeftButton and not self.mCtrl: if self.band: self.band.hide() self.band = None self.feature = None logger.info("layer feature count {}".format(self.layer.featureCount())) if not self.layer: return logger.info("Trying to find feature in layer") point = self.toLayerCoordinates(self.layer, event.pos()) search_radius = (QgsTolerance.toleranceInMapUnits(10, self.layer, self.canvas().mapSettings(), QgsTolerance.Pixels)) rect = QgsRectangle() rect.setXMinimum(point.x() - search_radius) rect.setXMaximum(point.x() + search_radius) rect.setYMinimum(point.y() - search_radius) rect.setYMaximum(point.y() + search_radius) rq = QgsFeatureRequest().setFilterRect(rect) f = QgsFeature() self.layer.getFeatures(rq).nextFeature(f) if f.geometry(): self.band = self.create_rubber_band() self.band.setToGeometry(f.geometry(), self.layer) self.band.show() self.startcoord = self.toMapCoordinates(event.pos()) self.feature = f self.clicked_outside_layer = False return else: self.clicked_outside_layer = True
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
def createFormButtons(self, projectlayers): """ Create buttons for each form that is definded """ # Remove all the old buttons for action in self.actions: self.actionGroup.removeAction(action) self.toolbar.removeAction(action) self.edittool.layers = [] self.movetool.layers = [] for layer in projectlayers: try: qgslayer = QgsMapLayerRegistry.instance().mapLayersByName(layer.name)[0] if qgslayer.type() == QgsMapLayer.RasterLayer: utils.log("We can't support raster layers for data entry") continue layer.QGISLayer = qgslayer except KeyError: utils.log("Layer not found in project") continue if 'capture' in layer.capabilities: text = layer.icontext try: tool = layer.getMaptool(self.iface.mapCanvas()) except NoMapToolConfigured: utils.log("No map tool configured") continue except ErrorInMapTool as error: self.messageBar.pushMessage("Error configuring map tool", error.message, level=QgsMessageBar.WARNING) continue # Hack until I fix it later if isinstance(tool, PointTool): add = functools.partial(self.addNewFeature, qgslayer) tool.geometryComplete.connect(add) else: tool.finished.connect(self.openForm) action = QAction(QIcon(layer.icon), text, self.mainwindow) action.setData(layer) action.setCheckable(True) action.toggled.connect(functools.partial(self.setMapTool, tool)) self.toolbar.insertAction(self.editingmodeaction, action) if not tool.isEditTool(): # Connect the GPS tools strip to the action pressed event. showgpstools = (functools.partial(self.extraaddtoolbar.showToolbar, action, None)) action.toggled.connect(showgpstools) self.actionGroup.addAction(action) self.actions.append(action) if 'edit' in layer.capabilities: # TODO Use snapping options from project radius = (QgsTolerance.toleranceInMapUnits( 10, qgslayer, self.iface.mapCanvas().mapRenderer(), QgsTolerance.Pixels)) self.edittool.addLayer(qgslayer) self.edittool.searchRadius = radius if 'move' in layer.capabilities: self.movetool.addLayer(qgslayer)