def click_button_snapping(self, point, btn): # @UnusedVariable if not self.layer_dimensions: return layer = self.layer_dimensions self.iface.setActiveLayer(layer) layer.startEditing() snapper = QgsMapCanvasSnapper(self.canvas) map_point = self.canvas.getCoordinateTransform().transform(point) x = map_point.x() y = map_point.y() event_point = QPoint(x, y) # Snapping (retval, result) = snapper.snapToBackgroundLayers( event_point) # @UnusedVariable # That's the snapped point if result: # Check feature for snapped_point in result: if snapped_point.layer == self.layer_node: feat_type = 'node' elif snapped_point.layer == self.layer_connec: feat_type = 'connec' else: continue # Get the point point = QgsPoint(snapped_point.snappedVertex) snapp_feature = next( snapped_point.layer.getFeatures( QgsFeatureRequest().setFilterFid( snapped_point.snappedAtGeometry))) element_id = snapp_feature.attribute(feat_type + '_id') # Leave selection snapped_point.layer.select([snapped_point.snappedAtGeometry]) # Get depth of the feature if self.project_type == 'ws': fieldname = "depth" elif self.project_type == 'ud' and feat_type == 'node': fieldname = "ymax" elif self.project_type == 'ud' and feat_type == 'connec': fieldname = "connec_depth" sql = ("SELECT " + fieldname + "" " FROM " + self.schema_name + "." + feat_type + "" " WHERE " + feat_type + "_id = '" + element_id + "'") row = self.controller.get_row(sql) if not row: return utils_giswater.setText(self.dialog, "depth", row[0]) utils_giswater.setText(self.dialog, "feature_id", element_id) utils_giswater.setText(self.dialog, "feature_type", feat_type.upper())
class CaptureCoordinateToolUpdate(QgsMapTool): def __init__(self, canvas, dataBaseProcedureData0, point3d0, procEntityListType0): self.canvas = canvas QgsMapToolEmitPoint.__init__(self, self.canvas) self.mSnapper = QgsMapCanvasSnapper(canvas) self.rubberBand = QgsRubberBand(canvas, QGis.Point) self.rubberBand.setColor(Qt.red) self.rubberBand.setWidth(10) self.rubberBandClick = QgsRubberBand(canvas, QGis.Point) self.rubberBandClick.setColor(Qt.green) self.rubberBandClick.setWidth(3) self.obstaclesLayerList = QgisHelper.getSurfaceLayers( SurfaceTypes.Obstacles) self.demLayerList = QgisHelper.getSurfaceLayers(SurfaceTypes.DEM) self.reset() self.dataBaseProcedureData_0 = dataBaseProcedureData0 self.point3d_0 = point3d0 self.procEntityListType_0 = procEntityListType0 def reset(self): self.Point = None def canvasReleaseEvent(self, e): pointBackground = e.pos() self.Point, self.pointID, self.layer = self.snapPoint(e.pos()) self.selectedLayerFromSnapPoint = None resultValueList = [] self.rubberBandClick.reset(QGis.Point) self.rubberBandClick.addPoint(self.Point) self.rubberBandClick.show() if self.obstaclesLayerList != None: for obstacleLayer in self.obstaclesLayerList: if self.layer == None: break if obstacleLayer.name() == self.layer.name(): self.selectedLayerFromSnapPoint = self.layer break # itemList = [] if self.selectedLayerFromSnapPoint != None: dataProvider = self.selectedLayerFromSnapPoint.dataProvider() featureIter = dataProvider.getFeatures( QgsFeatureRequest(self.pointID)) feature = None for feature0 in featureIter: feature = feature0 idx = self.selectedLayerFromSnapPoint.fieldNameIndex('Name') idValue = feature.attributes()[idx] resultValueList.append(idValue.toString()) resultValueList.append(str(self.Point.x())) resultValueList.append(str(self.Point.y())) idx = self.selectedLayerFromSnapPoint.fieldNameIndex('Altitude') altitudeValue = feature.attributes()[idx] resultValueList.append(altitudeValue.toString()) else: if self.Point != None: identifyResult = None idValue = "Background" if self.demLayerList != None: for demLayer in self.demLayerList: identifyResults = demLayer.dataProvider().identify( self.Point, QgsRaster.IdentifyFormatValue) identifyResult = identifyResults.results() if identifyResult != None and identifyResult[1].toString( ) != "": idValue = "DEM" resultValueList.append(idValue) resultValueList.append(str(self.Point.x())) resultValueList.append(str(self.Point.y())) if identifyResult != None: resultValueList.append(identifyResult[1].toString()) else: resultValueList.append("0") self.point3d_0 = Point3D(self.Point.x(), self.Point.y()) self.emit(SIGNAL("resultPointValueList"), resultValueList, self.dataBaseProcedureData_0, self.point3d_0, self.procEntityListType_0, self) def canvasMoveEvent(self, e): if define._snapping == False: return self.rubberBand.reset(QGis.Point) # snapPoint = QgisHelper.snapPoint(e.pos(), self.mSnapper, define._canvas, True) snapPoint, snapPointID, layer = self.snapPoint(e.pos(), True) if snapPoint == None: return self.rubberBand.addPoint(snapPoint) self.rubberBand.show() # print snapPointID def snapPoint(self, p, bNone=False): if define._snapping == False: return ( define._canvas.getCoordinateTransform().toMapCoordinates(p), None, None) snappingResults = self.mSnapper.snapToBackgroundLayers(p) if (snappingResults[0] != 0 or len(snappingResults[1]) < 1): if bNone: return (None, None, None) else: return (define._canvas.getCoordinateTransform(). toMapCoordinates(p), None, None) else: return (snappingResults[1][0].snappedVertex, snappingResults[1][0].snappedAtGeometry, snappingResults[1][0].layer) def deactivate(self): self.rubberBand.reset(QGis.Point) QgsMapTool.deactivate(self) self.emit(SIGNAL("deactivated()"))
class MincutConnec(QgsMapTool): canvasClicked = pyqtSignal() def __init__(self, iface, controller): """ Class constructor """ self.iface = iface self.canvas = self.iface.mapCanvas() self.controller = controller # Call superclass constructor and set current action QgsMapTool.__init__(self, self.canvas) self.dragging = False # Vertex marker color = QColor(255, 100, 255) self.vertex_marker = QgsVertexMarker(self.canvas) self.vertex_marker.setIconType(QgsVertexMarker.ICON_CIRCLE) self.vertex_marker.setColor(color) self.vertex_marker.setIconSize(15) self.vertex_marker.setPenWidth(3) # Rubber band self.rubber_band = QgsRubberBand(self.canvas, QGis.Line) self.rubber_band.setColor(color) self.rubber_band.setWidth(1) # Select rectangle self.select_rect = QRect() # TODO: Parametrize self.connec_group = ["Wjoin", "Tap", "Fountain", "Greentap"] #self.snapperManager = SnappingConfigManager(self.iface) self.snapper = QgsMapCanvasSnapper(self.canvas) def activate(self): pass def canvasPressEvent(self, event): #@UnusedVariable self.select_rect.setRect(0, 0, 0, 0) self.rubber_band.reset() def canvasMoveEvent(self, event): """ With left click the digitizing is finished """ if event.buttons() == Qt.LeftButton: if not self.dragging: self.dragging = True self.select_rect.setTopLeft(event.pos()) self.select_rect.setBottomRight(event.pos()) self.set_rubber_band() else: # Hide highlight self.vertex_marker.hide() # Get the click x = event.pos().x() y = event.pos().y() event_point = QPoint(x, y) # Snapping (retval, result) = self.snapper.snapToBackgroundLayers( event_point) # @UnusedVariable # That's the snapped point if result: # Check feature for snap_point in result: element_type = snap_point.layer.name() if element_type in self.connec_group: # Get the point point = QgsPoint(snap_point.snappedVertex) # Add marker self.vertex_marker.setCenter(point) self.vertex_marker.show() break def canvasReleaseEvent(self, event): """ With left click the digitizing is finished """ if event.button() == Qt.LeftButton: # Get the click x = event.pos().x() y = event.pos().y() event_point = QPoint(x, y) # Not dragging, just simple selection if not self.dragging: # Snap to node (retval, result) = self.snapper.snapToBackgroundLayers( event_point) # @UnusedVariable # That's the snapped point if result: # Check feature for snapped_point in result: element_type = snapped_point.layer.name() if element_type in self.connec_group: feat_type = 'connec' else: continue point = QgsPoint( snapped_point.snappedVertex) # @UnusedVariable # layer.removeSelection() # layer.select([result[0].snappedAtGeometry]) #snapped_point.layer.removeSelection() snapped_point.layer.select( [snapped_point.snappedAtGeometry]) else: # Set valid values for rectangle's width and height if self.select_rect.width() == 1: self.select_rect.setLeft(self.select_rect.left() + 1) if self.select_rect.height() == 1: self.select_rect.setBottom(self.select_rect.bottom() + 1) self.set_rubber_band() self.select_multiple_features(self.selected_rectangle) self.dragging = False # Refresh map canvas self.rubber_band.reset() self.refresh_map_canvas() def set_rubber_band(self): # Coordinates transform transform = self.canvas.getCoordinateTransform() # Coordinates ll = transform.toMapCoordinates(self.select_rect.left(), self.select_rect.bottom()) lr = transform.toMapCoordinates(self.select_rect.right(), self.select_rect.bottom()) ul = transform.toMapCoordinates(self.select_rect.left(), self.select_rect.top()) ur = transform.toMapCoordinates(self.select_rect.right(), self.select_rect.top()) # Rubber band self.rubber_band.reset() self.rubber_band.addPoint(ll, False) self.rubber_band.addPoint(lr, False) self.rubber_band.addPoint(ur, False) self.rubber_band.addPoint(ul, False) self.rubber_band.addPoint(ll, True) self.selected_rectangle = QgsRectangle(ll, ur) def select_multiple_features(self, rectangle): if self.connec_group is None: return if QGis.QGIS_VERSION_INT >= 21600: # Selection for all connec group layers for layer_name in self.connec_group: # Get layer by his name layer = self.controller.get_layer_by_layername(layer_name, log_info=True) if layer: self.group_pointers_connec.append(layer) layer.selectByRect(rectangle) else: for layer_name in self.connec_group: self.iface.setActiveLayer(layer) layer.removeSelection() layer.select(rectangle, True)
class ArkMapToolInteractive(QgsMapTool): _active = False _dragging = False _panningEnabled = False _zoomingEnabled = False _zoomRubberBand = None #QgsRubberBand() _zoomRect = None # QRect() _snappingEnabled = False _snapper = None #QgsMapCanvasSnapper() _snappingMarker = None # QgsVertexMarker() _showSnappableVertices = False _snappableVertices = [] # [QgsPoint()] _snappableMarkers = [] # [QgsVertexMarker()] def __init__(self, canvas, snappingEnabled=False, showSnappableVertices=False): super(ArkMapToolInteractive, self).__init__(canvas) self._snappingEnabled = snappingEnabled self._showSnappableVertices = showSnappableVertices def __del__(self): if self._active: self.deactivate() def isActive(self): return self._active def activate(self): super(ArkMapToolInteractive, self).activate() self._active = True self._startSnapping() def deactivate(self): self._active = False if self._snappingEnabled: self._stopSnapping() if (self._zoomRubberBand is not None): self.canvas().scene().removeItem(self._zoomRubberBand) self._zoomRubberBand = None super(ArkMapToolInteractive, self).deactivate() def setAction(self, action): super(ArkMapToolInteractive, self).setAction(action) self.action().triggered.connect(self._activate) def _activate(self): self.canvas().setMapTool(self) def panningEnabled(self): return self._panningEnabled def setPanningEnabled(self, enabled): self._panningEnabled = enabled def zoomingEnabled(self): return self._zoomingEnabled def setZoomingEnabled(self, enabled): self._zoomingEnabled = enabled def snappingEnabled(self): return self._snappingEnabled def setSnappingEnabled(self, enabled): if (self._snappingEnabled == enabled): return self._snappingEnabled = enabled if not self._active: return if enabled: self._startSnapping() else: self._stopSnapping() def _startSnapping(self): self._snapper = QgsMapCanvasSnapper() self._snapper.setMapCanvas(self.canvas()) if self._showSnappableVertices: self._startSnappableVertices() def _stopSnapping(self): self._deleteSnappingMarker() self._snapper = None if self._showSnappableVertices: self._stopSnappableVertices() def showSnappableVertices(self): return self._showSnappableVertices def setShowSnappableVertices(self, show): if (self._showSnappableVertices == show): return self._showSnappableVertices = show if not self._active: return if show: self._startSnappableVertices() else: self._stopSnappableVertices() def _startSnappableVertices(self): self.canvas().layersChanged.connect(self._layersChanged) self.canvas().extentsChanged.connect(self._redrawSnappableMarkers) QgsProject.instance().snapSettingsChanged.connect(self._layersChanged) self._layersChanged() def _stopSnappableVertices(self): self._deleteSnappableMarkers() self._snappableLayers = [] self.canvas().layersChanged.disconnect(self._layersChanged) self.canvas().extentsChanged.disconnect(self._redrawSnappableMarkers) QgsProject.instance().snapSettingsChanged.disconnect(self._layersChanged) def canvasMoveEvent(self, e): super(ArkMapToolInteractive, self).canvasMoveEvent(e) if not self._active: return e.ignore() if (self._panningEnabled and e.buttons() & Qt.LeftButton): # Pan map mode if not self._dragging: self._dragging = True self.setCursor(QCursor(Qt.ClosedHandCursor)) self.canvas().panAction(e) e.accept() elif (self._zoomingEnabled and e.buttons() & Qt.RightButton): # Zoom map mode if not self._dragging: self._dragging = True self.setCursor(QCursor(Qt.ClosedHandCursor)) self._zoomRubberBand = QgsRubberBand(self.canvas(), QGis.Polygon) color = QColor(Qt.blue) color.setAlpha(63) self._zoomRubberBand.setColor(color) self._zoomRect = QRect(0, 0, 0, 0) self._zoomRect.setTopLeft(e.pos()) self._zoomRect.setBottomRight(e.pos()) if self._zoomRubberBand is not None: self._zoomRubberBand.setToCanvasRectangle(self._zoomRect) self._zoomRubberBand.show() e.accept() elif self._snappingEnabled: mapPoint, snapped = self._snapCursorPoint(e.pos()) if (snapped): self._createSnappingMarker(mapPoint) else: self._deleteSnappingMarker() def canvasReleaseEvent(self, e): super(ArkMapToolInteractive, self).canvasReleaseEvent(e) e.ignore() if (e.button() == Qt.LeftButton): if self._dragging: # Pan map mode self.canvas().panActionEnd(e.pos()) self.setCursor(capture_point_cursor) self._dragging = False e.accept() elif (e.button() == Qt.RightButton): if self._dragging: # Zoom mode self._zoomRect.setBottomRight(e.pos()) if (self._zoomRect.topLeft() != self._zoomRect.bottomRight()): coordinateTransform = self.canvas().getCoordinateTransform() ll = coordinateTransform.toMapCoordinates(self._zoomRect.left(), self._zoomRect.bottom()) ur = coordinateTransform.toMapCoordinates(self._zoomRect.right(), self._zoomRect.top()) r = QgsRectangle() r.setXMinimum(ll.x()) r.setYMinimum(ll.y()) r.setXMaximum(ur.x()) r.setYMaximum(ur.y()) r.normalize() if (r.width() != 0 and r.height() != 0): self.canvas().setExtent(r) self.canvas().refresh() self._dragging = False if (self._zoomRubberBand is not None): self.canvas().scene().removeItem(self._zoomRubberBand) self._zoomRubberBand = None e.accept() def keyPressEvent(self, e): super(ArkMapToolInteractive, self).keyPressEvent(e) if (e.key() == Qt.Key_Escape): self.canvas().unsetMapTool(self) e.accept() def _snapCursorPoint(self, cursorPoint): res, snapResults = self._snapper.snapToBackgroundLayers(cursorPoint) if (res != 0 or len(snapResults) < 1): return self.toMapCoordinates(cursorPoint), False else: # Take a copy as QGIS will delete the result! snappedVertex = QgsPoint(snapResults[0].snappedVertex) return snappedVertex, True def _createSnappingMarker(self, snapPoint): if (self._snappingMarker is None): self._snappingMarker = QgsVertexMarker(self.canvas()) self._snappingMarker.setIconType(QgsVertexMarker.ICON_CROSS) self._snappingMarker.setColor(Qt.magenta) self._snappingMarker.setPenWidth(3) self._snappingMarker.setCenter(snapPoint) def _deleteSnappingMarker(self): if (self._snappingMarker is not None): self.canvas().scene().removeItem(self._snappingMarker) self._snappingMarker = None def _createSnappableMarkers(self): if (not self._showSnappableVertices or not self._snappingEnabled): return extent = self.canvas().extent() for vertex in self._snappableVertices.asMultiPoint(): if (extent.contains(vertex)): marker = QgsVertexMarker(self.canvas()) marker.setIconType(QgsVertexMarker.ICON_X) marker.setColor(Qt.gray) marker.setPenWidth(1) marker.setCenter(vertex) self._snappableMarkers.append(marker) def _deleteSnappableMarkers(self): for marker in self._snappableMarkers: self.canvas().scene().removeItem(marker) del self._snappableMarkers[:] def _layersChanged(self): if (not self._showSnappableVertices or not self._snappingEnabled): return self._buildSnappableLayers() self._deleteSnappableMarkers() self._createSnappableMarkers() def _redrawSnappableMarkers(self): if (not self._showSnappableVertices or not self._snappingEnabled): return self._deleteSnappableMarkers() self._createSnappableMarkers() def _buildSnappableLayers(self): if (not self._showSnappableVertices or not self._snappingEnabled): return vertices = [] for layer in self.canvas().layers(): ok, enabled, type, units, tolerance, avoid = QgsProject.instance().snapSettingsForLayer(layer.id()) if (ok and enabled and not layer.isEditable()): for feature in layer.getFeatures(): geometry = feature.geometry() if geometry is None: pass elif geometry.type() == QGis.Point: vertices.extend([geometry.asPoint()]) elif geometry.type() == QGis.Line: vertices.extend(geometry.asPolyline()) elif geometry.type() == QGis.Polygon: lines = geometry.asPolygon() for line in lines: vertices.extend(line) self._snappableVertices = QgsGeometry.fromMultiPoint(vertices) self._snappableVertices.simplify(0)
class CaptureCoordinateTool(QgsMapTool): def __init__(self, canvas, txtXCoord, txtYCoord, annotation=None): self.canvas = canvas self.txtXCoord = txtXCoord self.txtYCoord = txtYCoord QgsMapToolEmitPoint.__init__(self, self.canvas) self.annotation = annotation self.mSnapper = QgsMapCanvasSnapper(canvas) self.rubberBand = QgsRubberBand(canvas, QGis.Point) self.rubberBand.setColor(Qt.red) self.rubberBand.setWidth(10) self.rubberBandClick = QgsRubberBand(canvas, QGis.Point) self.rubberBandClick.setColor(Qt.green) self.rubberBandClick.setWidth(3) # lblDoc = QTextDocument(label) # self.annotation.setDocument(lblDoc) # self.annotation.setFrameBackgroundColor(QColor(0,0,0,0)) # self.annotation.setFrameSize( QSizeF( 30, 20 ) ) self.reset() def reset(self): self.Point = None # def canvasPressEvent(self, e): def canvasReleaseEvent(self, e): # self.Point = QgisHelper.snapPoint(e.pos(), self.mSnapper, define._canvas) self.Point = self.snapPoint(e.pos()) if self.annotation is not None: self.annotation.setMapPosition(self.Point) self.annotation.show() else: self.rubberBandClick.reset(QGis.Point) # snapPoint = QgisHelper.snapPoint(e.pos(), self.mSnapper, define._canvas, True) self.rubberBandClick.addPoint(self.Point) self.rubberBandClick.show() # self.setOffsetFromReferencePoint (QPointF(self.Point.x(),self.Point.y())) self.txtXCoord.setText(str(self.Point.x())) # print str(self.Point.x()) self.txtYCoord.setText(str(self.Point.y())) def canvasMoveEvent(self, e): if define._snapping == False: return self.rubberBand.reset(QGis.Point) # snapPoint = QgisHelper.snapPoint(e.pos(), self.mSnapper, define._canvas, True) snapPoint = self.snapPoint(e.pos(), True) if snapPoint == None: return self.rubberBand.addPoint(snapPoint) self.rubberBand.show() def snapPoint(self, p, bNone=False): if define._snapping == False: return define._canvas.getCoordinateTransform().toMapCoordinates(p) snappingResults = self.mSnapper.snapToBackgroundLayers(p) if (snappingResults[0] != 0 or len(snappingResults[1]) < 1): if bNone: return None else: return define._canvas.getCoordinateTransform( ).toMapCoordinates(p) else: return snappingResults[1][0].snappedVertex def deactivate(self): self.rubberBand.reset(QGis.Point) QgsMapTool.deactivate(self) self.emit(SIGNAL("deactivated()"))
class DrawProfiles(ParentMapTool): """ Button 43: Draw_profiles """ def __init__(self, iface, settings, action, index_action): """ Class constructor """ # Call ParentMapTool constructor super(DrawProfiles, self).__init__(iface, settings, action, index_action) self.list_of_selected_nodes = [] self.nodes = [] def activate(self): # Get version of pgRouting sql = "SELECT version FROM pgr_version()" row = self.controller.get_row(sql) if not row: message = "Error getting pgRouting version" self.controller.show_warning(message) return self.version = str(row[0][:1]) self.dlg = DrawProfile() utils_giswater.setDialog(self.dlg) self.dlg.setWindowFlags(Qt.WindowStaysOnTopHint) self.set_icon(self.dlg.btn_add_start_point, "111") self.set_icon(self.dlg.btn_add_end_point, "111") self.set_icon(self.dlg.btn_add_arc, "111") self.set_icon(self.dlg.btn_delete_arc, "112") self.dlg.findChild(QPushButton, "btn_add_start_point").clicked.connect( self.activate_snapping_node1) self.dlg.findChild(QPushButton, "btn_add_end_point").clicked.connect( self.activate_snapping_node2) self.btn_save_profile = self.dlg.findChild(QPushButton, "btn_save_profile") self.btn_save_profile.clicked.connect(self.save_profile) self.btn_load_profile = self.dlg.findChild(QPushButton, "btn_load_profile") self.btn_load_profile.clicked.connect(self.load_profile) self.profile_id = self.dlg.findChild(QLineEdit, "profile_id") self.widget_start_point = self.dlg.findChild(QLineEdit, "start_point") self.widget_end_point = self.dlg.findChild(QLineEdit, "end_point") self.group_pointers_node = [] self.group_layers_node = [ "Junction", "Valve", "Reduction", "Tank", "Meter", "Manhole", "Source", "Hydrant", "Pump", "Filter", "Waterwell", "Register", "Netwjoin" ] for layername in self.group_layers_node: layer = QgsMapLayerRegistry.instance().mapLayersByName(layername) if layer: self.group_pointers_node.append(layer[0]) self.group_pointers_arc = [] self.group_layers_arc = ["Conduit", "Siphon", "Varc", "Waccel"] for layername in self.group_layers_arc: layer = QgsMapLayerRegistry.instance().mapLayersByName(layername) if layer: self.group_pointers_arc.append(layer[0]) self.nodes = [] self.list_of_selected_nodes = [] self.dlg.open() def save_profile(self): profile_id = self.profile_id.text() start_point = self.widget_start_point.text() end_point = self.widget_end_point.text() # Check if all data are entered if profile_id == '' or start_point == '' or end_point == '': self.controller.show_info_box("Some of data is missing", "Info") return # Check if id of profile already exists in DB sql = ("SELECT DISTINCT(profile_id)" " FROM " + self.schema_name + ".anl_arc_profile_value" " WHERE profile_id = '" + profile_id + "'") row = self.controller.get_row(sql) if row: self.controller.show_warning( "Selected 'profile_id' already exist in database", parameter=profile_id) return list_arc = [] n = self.tbl_list_arc.count() for i in range(n): list_arc.append(str(self.tbl_list_arc.item(i).text())) for i in range(n): sql = "INSERT INTO " + self.schema_name + ".anl_arc_profile_value (profile_id, arc_id, start_point, end_point) " sql += " VALUES ('" + profile_id + "', '" + list_arc[ i] + "', '" + start_point + "', '" + end_point + "')" status = self.controller.execute_sql(sql) if not status: message = "Error inserting profile table, you need to review data" self.controller.show_warning(message) return # Show message to user message = "Values has been updated" self.controller.show_info(message) self.deactivate() def load_profile(self): self.dlg_load = LoadProfiles() utils_giswater.setDialog(self.dlg_load) btn_open = self.dlg_load.findChild(QPushButton, "btn_open") btn_open.clicked.connect(self.open_profile) self.tbl_profiles = self.dlg_load.findChild(QListWidget, "tbl_profiles") sql = "SELECT DISTINCT(profile_id) FROM " + self.schema_name + ".anl_arc_profile_value" rows = self.controller.get_rows(sql) if rows: for row in rows: item_arc = QListWidgetItem(str(row[0])) self.tbl_profiles.addItem(item_arc) self.dlg_load.open() self.dlg.close() self.deactivate() def open_profile(self): # Selected item from list selected_profile = self.tbl_profiles.currentItem().text() # Get data from DB for selected item| profile_id, start_point, end_point sql = "SELECT start_point, end_point" sql += " FROM " + self.schema_name + ".anl_arc_profile_value" sql += " WHERE profile_id = '" + selected_profile + "'" row = self.controller.get_row(sql) if not row: return start_point = row['start_point'] end_point = row['end_point'] # Fill widgets of form draw_profile | profile_id, start_point, end_point self.widget_start_point.setText(str(start_point)) self.widget_end_point.setText(str(end_point)) profile_id = self.dlg.findChild(QLineEdit, "profile_id") profile_id.setText(str(selected_profile)) # Call dijkstra to set new list of arcs and list of nodes self.shortest_path(str(start_point), str(end_point)) self.dlg_load.close() self.dlg.open() def activate_snapping_node1(self): # Create the appropriate map tool and connect the gotPoint() signal. self.emit_point = QgsMapToolEmitPoint(self.canvas) self.canvas.setMapTool(self.emit_point) self.snapper = QgsMapCanvasSnapper(self.canvas) # Get layer 'v_edit_node' layer = self.controller.get_layer_by_tablename("v_edit_node", log_info=True) if layer: self.layer_valve_analytics = layer self.canvas.connect(self.canvas, SIGNAL("xyCoordinates(const QgsPoint&)"), self.mouse_move) self.emit_point.canvasClicked.connect(self.snapping_node1) def activate_snapping_node2(self): # Create the appropriate map tool and connect the gotPoint() signal. self.emit_point = QgsMapToolEmitPoint(self.canvas) self.canvas.setMapTool(self.emit_point) self.snapper = QgsMapCanvasSnapper(self.canvas) # Get layer 'v_edit_node' layer = self.controller.get_layer_by_tablename("v_edit_node", log_info=True) if layer: self.layer_valve_analytics = layer self.canvas.connect(self.canvas, SIGNAL("xyCoordinates(const QgsPoint&)"), self.mouse_move) self.emit_point.canvasClicked.connect(self.snapping_node2) def mouse_move(self, p): map_point = self.canvas.getCoordinateTransform().transform(p) x = map_point.x() y = map_point.y() eventPoint = QPoint(x, y) # Snapping (retval, result) = self.snapper.snapToCurrentLayer(eventPoint, 2) # @UnusedVariable # That's the snapped features if result: for snapped_point in result: viewname = self.controller.get_layer_source_table_name( snapped_point.layer) if viewname == 'v_edit_node': point = QgsPoint(snapped_point.snappedVertex) # Add marker self.vertex_marker.setCenter(point) self.vertex_marker.show() else: self.vertex_marker.hide() def snapping_node1(self, point, btn): # @UnusedVariable map_point = self.canvas.getCoordinateTransform().transform(point) x = map_point.x() y = map_point.y() event_point = QPoint(x, y) # Snapping (retval, result) = self.snapper.snapToBackgroundLayers( event_point) # @UnusedVariable # That's the snapped point if result: # Check feature for snapped_point in result: element_type = snapped_point.layer.name() if element_type in self.group_layers_node: # Get the point point = QgsPoint(snapped_point.snappedVertex) snapp_feature = next( snapped_point.layer.getFeatures( QgsFeatureRequest().setFilterFid( snapped_point.snappedAtGeometry))) element_id = snapp_feature.attribute('node_id') self.element_id = str(element_id) # Leave selection snapped_point.layer.select( [snapped_point.snappedAtGeometry]) self.widget_start_point.setText(str(element_id)) node_start = str(self.widget_start_point.text()) node_end = str(self.widget_end_point.text()) if node_start != '' and node_end != '': self.shortest_path(str(node_start), str(node_end)) def snapping_node2(self, point, btn): # @UnusedVariable map_point = self.canvas.getCoordinateTransform().transform(point) x = map_point.x() y = map_point.y() event_point = QPoint(x, y) # Snapping (retval, result) = self.snapper.snapToBackgroundLayers( event_point) # @UnusedVariable # That's the snapped point if result: # Check feature for snap_point in result: element_type = snap_point.layer.name() if element_type in self.group_layers_node: # Get the point point = QgsPoint(snap_point.snappedVertex) snapp_feature = next( snap_point.layer.getFeatures( QgsFeatureRequest().setFilterFid( snap_point.snappedAtGeometry))) element_id = snapp_feature.attribute('node_id') self.element_id = str(element_id) # Leave selection snap_point.layer.select([snap_point.snappedAtGeometry]) self.widget_end_point.setText(str(element_id)) node_start = str(self.widget_start_point.text()) node_end = str(self.widget_end_point.text()) if node_start != '' and node_end != '': self.shortest_path(str(node_start), str(node_end)) def paint_event(self, arc_id, node_id): """ Parent function - Draw profiles """ # Clear plot plt.gcf().clear() # arc_id ,node_id list of nodes and arc form dijkstra algoritam self.set_parameters(arc_id, node_id) self.fill_memory() self.set_table_parameters() # Start drawing # Draw first | start node # Function self.draw_first_node(start_point, top_elev, ymax, z1, z2, cat_geom1, geom1) self.draw_first_node(self.memory[0][0], self.memory[0][1], self.memory[0][2], self.memory[0][3], self.memory[0][4], self.memory[0][5], self.memory[0][6], 0) # Draw nodes between first and last node # Function self.draw_nodes(start_point, top_elev, ymax, z1, z2, cat_geom1, geom1, index) for i in range(1, self.n - 1): self.draw_nodes(self.memory[i][0], self.memory[i][1], self.memory[i][2], self.memory[i][3], self.memory[i][4], self.memory[i][5], self.memory[i][6], i, self.memory[i - 1][4], self.memory[i - 1][5]) self.draw_arc() self.draw_ground() # Draw last node self.draw_last_node( self.memory[self.n - 1][0], self.memory[self.n - 1][1], self.memory[self.n - 1][2], self.memory[self.n - 1][3], self.memory[self.n - 1][4], self.memory[self.n - 1][5], self.memory[self.n - 1][6], self.n - 1, self.memory[self.n - 2][4], self.memory[self.n - 2][5]) self.draw_arc() self.draw_ground() self.draw_table_horizontals() self.set_properties() self.draw_coordinates() self.draw_grid() # Maximeze window ( after drawing ) mng = plt.get_current_fig_manager() mng.window.showMaximized() plt.show() # Action on resizing window self.fig1.canvas.mpl_connect('resize_event', self.on_resize) def set_properties(self): """ Set properties of main window """ # Set window name self.win = plt.gcf() self.win.canvas.set_window_title('Draw Profile') # Hide axes self.axes = plt.gca() self.axes.set_axis_off() # Set background color of window self.fig1 = plt.figure(1) self.rect = self.fig1.patch self.rect.set_facecolor('white') # Set axes x_min = round(self.memory[0][0] - self.fix_x - self.fix_x * Decimal(0.15)) x_max = round(self.memory[self.n - 1][0] + self.fix_x + self.fix_x * Decimal(0.15)) self.axes.set_xlim([x_min, x_max]) # Set y-axes y_min = round(self.min_top_elev - self.z - self.height_row * Decimal(1.5)) y_max = round(self.max_top_elev + self.height_row * Decimal(1.5)) self.axes.set_ylim([y_min, y_max]) def set_parameters(self, arc_id, node_id): """ Get and calculate parameters and values for drawing """ self.list_of_selected_arcs = arc_id self.list_of_selected_nodes = node_id self.gis_length = [0] self.start_point = [0] self.arc_id = [] # Get arcs between nodes (on shortest path) self.n = len(self.list_of_selected_nodes) # Get length (gis_length) of arcs and save them in separate list ( self.gis_length ) for arc_id in self.list_of_selected_arcs: # Get gis_length from v_edit_arc sql = "SELECT gis_length" sql += " FROM " + self.schema_name + ".v_edit_arc" sql += " WHERE arc_id = '" + str(arc_id) + "'" row = self.controller.get_row(sql) if row: self.gis_length.append(row[0]) # Calculate start_point (coordinates) of drawing for each node n = len(self.gis_length) for i in range(1, n): x = self.start_point[i - 1] + self.gis_length[i] self.start_point.append(x) i = i + 1 def fill_memory(self): """ Get parameters from data base. Fill self.memory with parameters postgres """ self.memory = [] i = 0 # Get parameters and fill the memory for node_id in self.node_id: # self.parameters : list of parameters for one node # self.parameters [start_point, top_elev, y_max,z1, z2, cat_geom1, geom1, slope, elev1, elev2,y1 ,y2, node_id, elev] parameters = [ self.start_point[i], None, None, None, None, None, None, None, None, None, None, None, None, None ] # Get data top_elev ,y_max, elev, nodecat_id from v_edit_node # change elev to sys_elev sql = "SELECT top_elev, ymax, sys_elev, nodecat_id" sql += " FROM " + self.schema_name + ".v_edit_node" sql += " WHERE node_id = '" + str(node_id) + "'" row = self.controller.get_row(sql) if row: parameters[1] = row[0] parameters[2] = row[1] parameters[13] = row[2] nodecat_id = row[3] # Get data z1, z2 ,cat_geom1 ,elev1 ,elev2 , y1 ,y2 ,slope from v_edit_arc # Change to elevmax1 and elevmax2 sql = "SELECT z1, z2, cat_geom1, sys_elev1, sys_elev2, y1, y2, slope" sql += " FROM " + self.schema_name + ".v_edit_arc" sql += " WHERE node_1 = '" + str( node_id) + "' OR node_2 = '" + str(node_id) + "'" row = self.controller.get_row(sql) if row: parameters[3] = row[0] parameters[4] = row[1] parameters[5] = row[2] parameters[8] = row[3] parameters[9] = row[4] parameters[10] = row[5] parameters[11] = row[6] parameters[7] = row[7] # Geom1 from cat_node sql = "SELECT geom1" sql += " FROM " + self.schema_name + ".cat_node" sql += " WHERE id = '" + str(nodecat_id) + "'" row = self.controller.get_row(sql) if row: parameters[6] = row[0] # Set node_id in memory parameters[12] = node_id # Check if we have all data for drawing if None in parameters: message = "Some parameters are missing for node:" self.controller.show_info_box(message, "Info", node_id) parameters = [] return self.memory.append(parameters) i = i + 1 def draw_first_node(self, start_point, top_elev, ymax, z1, z2, cat_geom1, geom1, indx): #@UnusedVariable """ Draw first node """ # Draw first node x = [0, -(geom1), -(geom1), (geom1), (geom1)] y = [ top_elev, top_elev, top_elev - ymax, top_elev - ymax, top_elev - ymax + z1 ] x1 = [geom1, geom1, 0] y1 = [top_elev - ymax + z1 + cat_geom1, top_elev, top_elev] plt.plot(x, y, 'black', zorder=100) plt.plot(x1, y1, 'black', zorder=100) plt.show() self.first_top_x = 0 self.first_top_y = top_elev # Draw fixed part of table self.draw_fix_table(start_point) def draw_fix_table(self, start_point): """ Draw fixed part of table """ # DRAW TABLE - FIXED PART # Draw fixed part of table self.draw_marks(0) # Vertical line [-1,0] x = [ start_point - self.fix_x * Decimal(0.2), start_point - self.fix_x * Decimal(0.2) ] y = [ self.min_top_elev - 1 * self.height_row, self.min_top_elev - 6 * self.height_row ] plt.plot(x, y, 'black', zorder=100) # Vertical line [-2,0] x = [ start_point - self.fix_x * Decimal(0.75), start_point - self.fix_x * Decimal(0.75) ] y = [ self.min_top_elev - 2 * self.height_row, self.min_top_elev - 5 * self.height_row ] plt.plot(x, y, 'black', zorder=100) # Vertical line [-3,0] x = [start_point - self.fix_x, start_point - self.fix_x] y = [ self.min_top_elev - 1 * self.height_row, self.min_top_elev - 6 * self.height_row ] plt.plot(x, y, 'black', zorder=100) # Fill the fixed part of table with data - draw text # Called just with first node self.data_fix_table(start_point) def draw_marks(self, start_point): """ Draw marks for each node """ # Vertical line [0,0] x = [start_point, start_point] y = [ self.min_top_elev - 1 * self.height_row, self.min_top_elev - 2 * self.height_row - Decimal(0.1) * self.height_row ] plt.plot(x, y, 'black', zorder=100) # Vertical lines [0,0] - marks x = [start_point, start_point] y = [ self.min_top_elev - Decimal(2.9) * self.height_row, self.min_top_elev - Decimal(3.1) * self.height_row ] plt.plot(x, y, 'black', zorder=100) x = [start_point, start_point] y = [ self.min_top_elev - Decimal(3.9) * self.height_row, self.min_top_elev - Decimal(4.1) * self.height_row ] plt.plot(x, y, 'black', zorder=100) x = [start_point, start_point] y = [ self.min_top_elev - Decimal(4.9) * self.height_row, self.min_top_elev - Decimal(5.1) * self.height_row ] plt.plot(x, y, 'black', zorder=100) x = [start_point, start_point] y = [ self.min_top_elev - Decimal(5.9) * self.height_row, self.min_top_elev - Decimal(6.1) * self.height_row ] plt.plot(x, y, 'black', zorder=100) def data_fix_table(self, start_point): #@UnusedVariable """ FILL THE FIXED PART OF TABLE WITH DATA - DRAW TEXT """ c = (self.fix_x - self.fix_x * Decimal(0.2)) / 2 plt.text(-(c + self.fix_x * Decimal(0.2)), self.min_top_elev - 1 * self.height_row - Decimal(0.45) * self.height_row, 'DIAMETER', fontsize=7.5, horizontalalignment='center') plt.text(-(c + self.fix_x * Decimal(0.2)), self.min_top_elev - 1 * self.height_row - Decimal(0.80) * self.height_row, 'SLP. / LEN.', fontsize=7.5, horizontalalignment='center') c = (self.fix_x * Decimal(0.25)) / 2 plt.text(-(c + self.fix_x * Decimal(0.74)), self.min_top_elev - Decimal(2) * self.height_row - self.height_row * 3 / 2, 'ORDINATES', fontsize=7.5, rotation='vertical', horizontalalignment='center', verticalalignment='center') plt.text(-self.fix_x * Decimal(0.70), self.min_top_elev - Decimal(2.05) * self.height_row - self.height_row / 2, 'TOP ELEV', fontsize=7.5, verticalalignment='center') plt.text(-self.fix_x * Decimal(0.70), self.min_top_elev - Decimal(3.05) * self.height_row - self.height_row / 2, 'Y MAX', fontsize=7.5, verticalalignment='center') plt.text(-self.fix_x * Decimal(0.70), self.min_top_elev - Decimal(4.05) * self.height_row - self.height_row / 2, 'ELEV', fontsize=7.5, verticalalignment='center') c = (self.fix_x - self.fix_x * Decimal(0.2)) / 2 plt.text(-(c + self.fix_x * Decimal(0.2)), self.min_top_elev - Decimal(self.height_row * 5 + self.height_row / 2), 'NODE ID', fontsize=7.5, horizontalalignment='center', verticalalignment='center') # Fill table with values self.fill_data(0, 0) def draw_nodes(self, start_point, top_elev, ymax, z1, z2, cat_geom1, geom1, indx, z22, cat2): #@UnusedVariable """ Draw nodes between first and last node """ ytop1 = ymax - z1 - cat_geom1 # cat_geom_1 from node before ytop2 = ymax - z22 - cat2 x = [start_point, start_point - (geom1), start_point - (geom1)] y = [top_elev, top_elev, top_elev - ymax + z22 + cat2] x1 = [ start_point - (geom1), start_point - (geom1), start_point + (geom1), start_point + (geom1) ] y1 = [ top_elev - ymax + z22, top_elev - ymax, top_elev - ymax, top_elev - ymax + z1 ] x2 = [start_point + (geom1), start_point + (geom1), start_point] y2 = [top_elev - ytop1, top_elev, top_elev] plt.plot(x, y, 'black', zorder=100) plt.plot(x1, y1, 'black', zorder=100) plt.plot(x2, y2, 'black', zorder=100) plt.show() # index -1 for node before self.x = self.memory[indx - 1][6] + self.memory[indx - 1][0] self.y = self.memory[indx - 1][1] - self.memory[ indx - 1][2] + self.memory[indx - 1][3] + self.memory[indx - 1][5] self.x1 = self.memory[indx - 1][6] + self.memory[indx - 1][0] self.y1 = self.y1 = self.memory[indx - 1][1] - self.memory[ indx - 1][2] + self.memory[indx - 1][3] self.x2 = (start_point - (geom1)) self.y2 = top_elev - ytop2 self.x3 = (start_point - (geom1)) self.y3 = top_elev - ymax + z22 self.node_top_x = start_point self.node_top_y = top_elev self.first_top_x = self.memory[indx - 1][0] self.first_top_y = self.memory[indx - 1][1] # DRAW TABLE-MARKS self.draw_marks(start_point) # Fill table self.fill_data(start_point, indx) def fill_data(self, start_point, indx): # Fill top_elevation and node_id for all nodes # Fill top_elevation plt.annotate(' ' + '\n' + str(round(self.memory[indx][1], 2)) + '\n' + ' ', xy=(Decimal(start_point), self.min_top_elev - Decimal(self.height_row * 2 + self.height_row / 2)), fontsize=7.5, rotation='vertical', horizontalalignment='center', verticalalignment='center') # Draw node_id plt.text(0 + start_point, self.min_top_elev - Decimal(self.height_row * 5 + self.height_row / 2), self.memory[indx][12], fontsize=7.5, horizontalalignment='center', verticalalignment='center') # Fill y_max and alevation # 1st node : y_max,y2 and top_elev, elev2 if indx == 0: # Fill y_max plt.annotate( ' ' + '\n' + str(round(self.memory[0][2], 2)) + '\n' + str(round(self.memory[0][10], 2)), xy=(Decimal(0 + start_point), self.min_top_elev - Decimal(self.height_row * 3 + self.height_row / 2)), fontsize=7.5, rotation='vertical', horizontalalignment='center', verticalalignment='center') # Fill elevation plt.annotate( ' ' + '\n' + str(round(self.memory[0][13], 2)) + '\n' + str(round(self.memory[0][8], 2)), xy=(Decimal(0 + start_point), self.min_top_elev - Decimal(self.height_row * 4 + self.height_row / 2)), fontsize=7.5, rotation='vertical', horizontalalignment='center', verticalalignment='center') # Last node : y_max,y1 and top_elev, elev1 elif (indx == self.n - 1): # Fill y_max plt.annotate( str(round(self.memory[indx - 1][11], 2)) + '\n' + str(round(self.memory[indx][2], 2)) + '\n' + ' ', xy=(Decimal(0 + start_point), self.min_top_elev - Decimal(self.height_row * 3 + self.height_row / 2)), fontsize=7.5, rotation='vertical', horizontalalignment='center', verticalalignment='center') # Fill elevation plt.annotate( str(round(self.memory[indx - 1][9], 2)) + '\n' + str(round(self.memory[indx][13], 2)) + '\n' + ' ', xy=(Decimal(0 + start_point), self.min_top_elev - Decimal(self.height_row * 4 + self.height_row / 2)), fontsize=7.5, rotation='vertical', horizontalalignment='center', verticalalignment='center') # Nodes between 1st and last node : y_max,y1,y2 and top_elev, elev1, elev2 else: # Fill y_max plt.annotate( str(round(self.memory[indx - 1][11], 2)) + '\n' + str(round(self.memory[indx][2], 2)) + '\n' + str(round(self.memory[indx][10], 2)), xy=(Decimal(0 + start_point), self.min_top_elev - Decimal(self.height_row * 3 + self.height_row / 2)), fontsize=7.5, rotation='vertical', horizontalalignment='center', verticalalignment='center') # Fill elevation plt.annotate( str(round(self.memory[indx - 1][9], 2)) + '\n' + str(round(self.memory[indx][13], 2)) + '\n' + str(round(self.memory[indx][8], 2)), xy=(Decimal(0 + start_point), self.min_top_elev - Decimal(self.height_row * 4 + self.height_row / 2)), fontsize=7.5, rotation='vertical', horizontalalignment='center', verticalalignment='center') # Fill diameter and slope / length for all nodes except last node if (indx != self.n - 1): # Draw diameter center = self.gis_length[indx + 1] / 2 plt.text(center + start_point, self.min_top_elev - 1 * self.height_row - Decimal(0.45) * self.height_row, round(self.memory[indx][5], 2), fontsize=7.5, horizontalalignment='center' ) # PUT IN THE MIDDLE PARAMETRIZATION # Draw slope / length slope = str(round((self.memory[indx][7] * 100), 2)) length = str(round(self.gis_length[indx + 1], 2)) plt.text(center + start_point, self.min_top_elev - 1 * self.height_row - Decimal(0.8) * self.height_row, slope + '%/' + length, fontsize=7.5, horizontalalignment='center' ) # PUT IN THE MIDDLE PARAMETRIZATION def draw_last_node(self, start_point, top_elev, ymax, z1, z2, cat_geom1, geom1, indx, z22, cat2): #@UnusedVariable x = [start_point, start_point - (geom1), start_point - (geom1)] y = [top_elev, top_elev, top_elev - ymax + z22 + cat2] x1 = [ start_point - geom1, start_point - geom1, start_point + geom1, start_point + geom1, start_point ] y1 = [ top_elev - ymax + z2, top_elev - ymax, top_elev - ymax, top_elev, top_elev ] plt.plot(x, y, 'black', zorder=100) plt.plot(x1, y1, 'black', zorder=100) plt.show() self.x = self.memory[indx - 1][6] + self.memory[indx - 1][0] self.y = self.memory[indx - 1][1] - self.memory[ indx - 1][2] + self.memory[indx - 1][3] + self.memory[indx - 1][5] self.x1 = self.memory[indx - 1][6] + self.memory[indx - 1][0] self.y1 = self.y1 = self.memory[indx - 1][1] - self.memory[ indx - 1][2] + self.memory[indx - 1][3] ytop2 = ymax - z22 - cat2 self.x2 = (start_point - (geom1)) self.y2 = top_elev - ytop2 self.x3 = (start_point - (geom1)) self.y3 = top_elev - ymax + z22 self.first_top_x = self.memory[indx - 1][0] self.first_top_y = self.memory[indx - 1][1] self.node_top_x = start_point self.node_top_y = top_elev # DRAW TABLE # DRAW TABLE-MARKS self.draw_marks(start_point) # Fill table self.fill_data(start_point, indx) def set_table_parameters(self): # Search y coordinate min_top_elev ( top_elev- ymax) self.min_top_elev = self.memory[0][1] - self.memory[0][2] for i in range(1, self.n): if (self.memory[i][1] - self.memory[i][2]) < self.min_top_elev: self.min_top_elev = self.memory[i][1] - self.memory[i][2] # Search y coordinate max_top_elev self.max_top_elev = self.memory[0][1] for i in range(1, self.n): if (self.memory[i][1]) > self.max_top_elev: self.max_top_elev = self.memory[i][1] # Calculating dimensions of x-fixed part of table self.fix_x = Decimal(0.1 / (1 - 0.1)) * self.memory[self.n - 1][0] # Calculating dimensions of y-fixed part of table # Height y = height of table + height of graph self.z = self.max_top_elev - self.min_top_elev self.height_row = (self.z * Decimal(0.97)) / Decimal(5) # Height of graph + table self.height_y = self.z * 2 def draw_table_horizontals(self): self.set_table_parameters() # DRAWING TABLE # Nacrtat horizontale x = [self.memory[self.n - 1][0], self.memory[0][0] - self.fix_x] y = [ self.min_top_elev - self.height_row, self.min_top_elev - self.height_row ] plt.plot(x, y, 'black', zorder=100) x = [self.memory[self.n - 1][0], self.memory[0][0] - self.fix_x] y = [ self.min_top_elev - 2 * self.height_row, self.min_top_elev - 2 * self.height_row ] plt.plot(x, y, 'black', zorder=100) # horizontale krace x = [ self.memory[self.n - 1][0], self.memory[0][0] - self.fix_x * Decimal(0.75) ] y = [ self.min_top_elev - 3 * self.height_row, self.min_top_elev - 3 * self.height_row ] plt.plot(x, y, 'black', zorder=100) x = [ self.memory[self.n - 1][0], self.memory[0][0] - self.fix_x * Decimal(0.75) ] y = [ self.min_top_elev - 4 * self.height_row, self.min_top_elev - 4 * self.height_row ] plt.plot(x, y, 'black', zorder=100) # zadnje dvije linije x = [self.memory[self.n - 1][0], self.memory[0][0] - self.fix_x] y = [ self.min_top_elev - 5 * self.height_row, self.min_top_elev - 5 * self.height_row ] plt.plot(x, y, 'black', zorder=100) x = [self.memory[self.n - 1][0], self.memory[0][0] - self.fix_x] y = [ self.min_top_elev - 6 * self.height_row, self.min_top_elev - 6 * self.height_row ] plt.plot(x, y, 'black', zorder=100) def on_resize(self, event): """ TODO """ pass # Clear the entire current figure #plt.clf() #self.paint_event() #plt.rcParams['xtick.labelsize'] = 2 #plt.rcParams.update({'font-size':22}) #plt.draw() #res.remove() def check_colision(self, gis_length, pix): """ TODO: Checking colision just for text """ axes = plt.gca() [x, y] = axes.transData.transform([(0, 1), (1, 0)]) # available_length in pixels available_length = 2500 # gis_lenght in pixels, x[0]-pixels by unit gis_length_pix = Decimal(gis_length) * Decimal(x[0]) # if colision return 1 if gis_length_pix > available_length: return 1 #if no colision return 0 else: return 0 def draw_coordinates(self): start_point = self.memory[self.n - 1][0] geom1 = self.memory[self.n - 1][6] # Draw coocrinates x = [0, 0] y = [ self.min_top_elev - 1 * self.height_row, self.max_top_elev + 1 * self.height_row ] plt.plot(x, y, 'black', zorder=100) x = [start_point, start_point] y = [ self.min_top_elev - 1 * self.height_row, self.max_top_elev + 1 * self.height_row ] plt.plot(x, y, 'black', zorder=100) x = [0, start_point] y = [ self.max_top_elev + 1 * self.height_row, self.max_top_elev + 1 * self.height_row ] plt.plot(x, y, 'black', zorder=100) # Values left y_ordinate_max plt.text(0 - geom1 * Decimal(1.5), self.max_top_elev + self.height_row, str(round(self.max_top_elev + self.height_row, 2)), fontsize=7.5, horizontalalignment='right', verticalalignment='center') # Loop till self.max_top_elev + height_row y = int(math.ceil(self.min_top_elev - 1 * self.height_row)) x = int(math.floor(self.max_top_elev)) if x % 2 == 0: x = x + 2 else: x = x + 1 for i in range(y, x): if i % 2 == 0: x1 = [0, start_point] y1 = [i, i] else: i = i + 1 x1 = [0, start_point] y1 = [i, i] plt.plot(x1, y1, 'lightgray', zorder=1) # Values left y_ordinate_all plt.text(0 - geom1 * Decimal(1.5), i, str(i), fontsize=7.5, horizontalalignment='right', verticalalignment='center') def draw_grid(self): # Values right y_ordinate_max start_point = self.memory[self.n - 1][0] geom1 = self.memory[self.n - 1][6] plt.annotate('P.C. ' + str(round(self.min_top_elev - 1 * self.height_row, 2)) + '\n' + ' ', xy=(0 - geom1 * Decimal(1.5), self.min_top_elev - 1 * self.height_row), fontsize=7.5, horizontalalignment='right', verticalalignment='center') # Values right x_ordinate_min plt.annotate('0' + '\n' + ' ', xy=(0, self.max_top_elev + 1 * self.height_row), fontsize=7.5, horizontalalignment='center') # Values right x_ordinate_max plt.annotate(str(round(start_point, 2)) + '\n' + ' ', xy=(start_point, self.max_top_elev + 1 * self.height_row), fontsize=7.5, horizontalalignment='center') # Loop from 0 to start_point(of last node) x = int(math.floor(start_point)) # First after 0 (first is drawn ,start from i(0)+1) for i in range(50, x, 50): x1 = [i, i] y1 = [ self.min_top_elev - 1 * self.height_row, self.max_top_elev + 1 * self.height_row ] plt.plot(x1, y1, 'lightgray', zorder=1) # values left y_ordinate_all plt.text(0 - geom1 * Decimal(1.5), i, str(i), fontsize=7.5, horizontalalignment='right', verticalalignment='center') plt.text(start_point + geom1 * Decimal(1.5), i, str(i), fontsize=7.5, horizontalalignment='left', verticalalignment='center') # values right x_ordinate_all plt.annotate(str(i) + '\n' + ' ', xy=(i, self.max_top_elev + 1 * self.height_row), fontsize=7.5, horizontalalignment='center') def draw_arc(self): x = [self.x, self.x2] y = [self.y, self.y2] x1 = [self.x1, self.x3] y1 = [self.y1, self.y3] plt.plot(x, y, 'black', zorder=100) plt.plot(x1, y1, 'black', zorder=100) def draw_ground(self): # Green triangle plt.plot(self.first_top_x, self.first_top_y, 'g^', linewidth=3.5) plt.plot(self.node_top_x, self.node_top_y, 'g^', linewidth=3.5) x = [self.first_top_x, self.node_top_x] y = [self.first_top_y, self.node_top_y] plt.plot(x, y, 'green', linestyle='dashed') def shortest_path(self, start_point, end_point): """ Calculating shortest path using dijkstra algorithm """ args = [] start_point_id = start_point end_point_id = end_point args.append(start_point_id) args.append(end_point_id) self.rnode_id = [] self.rarc_id = [] rstart_point = None sql = "SELECT rid" sql += " FROM " + self.schema_name + ".v_anl_pgrouting_node" sql += " WHERE node_id = '" + start_point + "'" row = self.controller.get_row(sql) if row: rstart_point = int(row[0]) rend_point = None sql = "SELECT rid" sql += " FROM " + self.schema_name + ".v_anl_pgrouting_node" sql += " WHERE node_id = '" + end_point + "'" row = self.controller.get_row(sql) if row: rend_point = int(row[0]) # Check starting and end points if rstart_point is None or rend_point is None: message = "Start point or end point not found" self.controller.show_warning(message) return # Clear list of arcs and nodes - preparing for new profile sql = "SELECT * FROM public.pgr_dijkstra('SELECT id::integer, source, target, cost" sql += " FROM " + self.schema_name + ".v_anl_pgrouting_arc', " + str( rstart_point) + ", " + str(rend_point) + ", false" if self.version == '2': sql += ", false" elif self.version == '3': pass else: message = "You need to upgrade your version of pg_routing!" self.controller.show_info(message) return sql += ")" rows = self.controller.get_rows(sql) for i in range(0, len(rows)): if self.version == '2': self.rnode_id.append(str(rows[i][1])) self.rarc_id.append(str(rows[i][2])) elif self.version == '3': self.rnode_id.append(str(rows[i][2])) self.rarc_id.append(str(rows[i][3])) self.rarc_id.pop() self.arc_id = [] self.node_id = [] for n in range(0, len(self.rarc_id)): # convert arc_ids sql = "SELECT arc_id" sql += " FROM " + self.schema_name + ".v_anl_pgrouting_arc" sql += " WHERE id = '" + str(self.rarc_id[n]) + "'" row = self.controller.get_row(sql) if row: self.arc_id.append(str(row[0])) for m in range(0, len(self.rnode_id)): # convert node_ids sql = "SELECT node_id" sql += " FROM " + self.schema_name + ".v_anl_pgrouting_node" sql += " WHERE rid = '" + str(self.rnode_id[m]) + "'" row = self.controller.get_row(sql) if row: self.node_id.append(str(row[0])) # Select arcs of the shortest path if rows: # Build an expression to select them aux = "\"arc_id\" IN (" for i in range(len(self.arc_id)): aux += "'" + str(self.arc_id[i]) + "', " aux = aux[:-2] + ")" expr = QgsExpression(aux) if expr.hasParserError(): message = "Expression Error: " + str(expr.parserErrorString()) self.controller.show_warning(message) return # Loop which is pasing trough all layer of arc_group searching for feature for layer_arc in self.group_pointers_arc: it = layer_arc.getFeatures(QgsFeatureRequest(expr)) # Build a list of feature id's from the previous result id_list = [i.id() for i in it] # Select features with these id's layer_arc.selectByIds(id_list) # Select nodes of shortest path aux = "\"node_id\" IN (" for i in range(len(self.node_id)): aux += "'" + str(self.node_id[i]) + "', " aux = aux[:-2] + ")" expr = QgsExpression(aux) if expr.hasParserError(): message = "Expression Error: " + str(expr.parserErrorString()) self.controller.show_warning(message) return # Loop which is pasing trough all layers of node_group searching for feature for layer_node in self.group_pointers_node: it = layer_node.getFeatures(QgsFeatureRequest(expr)) # Build a list of feature id's from the previous result self.id_list = [i.id() for i in it] # Select features with these id's layer_node.selectByIds(self.id_list) if self.id_list != []: layer = layer_node center_widget = self.id_list[0] # Center profile (first node) canvas = self.iface.mapCanvas() layer.selectByIds([center_widget]) canvas.zoomToSelected(layer) self.tbl_list_arc = self.dlg.findChild(QListWidget, "tbl_list_arc") list_arc = [] # Clear list self.tbl_list_arc.clear() for i in range(len(self.arc_id)): item_arc = QListWidgetItem(self.arc_id[i]) self.tbl_list_arc.addItem(item_arc) list_arc.append(self.arc_id[i]) self.dlg.findChild(QPushButton, "btn_draw").clicked.connect( partial(self.paint_event, self.arc_id, self.node_id)) self.dlg.findChild(QPushButton, "btn_clear_profile").clicked.connect( self.clear_profile) def clear_profile(self): # Clear list of nodes and arcs self.list_of_selected_nodes = [] self.list_of_selected_arcs = [] self.nodes = [] self.arcs = [] start_point = self.dlg.findChild(QLineEdit, "start_point") start_point.clear() end_point = self.dlg.findChild(QLineEdit, "end_point") end_point.clear() profile_id = self.dlg.findChild(QLineEdit, "profile_id") profile_id.clear() # Get data from DB for selected item| tbl_list_arc tbl_list_arc = self.dlg.findChild(QListWidget, "tbl_list_arc") tbl_list_arc.clear() # Clear selection can = self.iface.mapCanvas() for layer in can.layers(): layer.removeSelection() can.refresh() self.deactivate()
class ManNodeDialog(ParentDialog): def __init__(self, dialog, layer, feature): """ Constructor class """ self.layer = layer self.feature = feature self.geom_type = "node" self.field_id = "node_id" self.id = utils_giswater.getWidgetText(dialog, self.field_id, False) super(ManNodeDialog, self).__init__(dialog, layer, feature) self.init_config_form() self.dlg_is_destroyed = False #self.controller.manage_translation('ud_man_node', dialog) if dialog.parent(): dialog.parent().setFixedSize(625, 660) def init_config_form(self): """ Custom form initial configuration """ # Get last point clicked on canvas last_click = self.canvas.mouseLastXY() self.last_point = QgsMapToPixel.toMapCoordinates( self.canvas.getCoordinateTransform(), last_click.x(), last_click.y()) # Define class variables self.filter = self.field_id + " = '" + str(self.id) + "'" emit_point = QgsMapToolEmitPoint(self.canvas) # Get user permisions role_basic = self.controller.check_role_user("role_basic") # Get widget controls self.tab_main = self.dialog.findChild(QTabWidget, "tab_main") self.tbl_element = self.dialog.findChild(QTableView, "tbl_element") self.tbl_document = self.dialog.findChild(QTableView, "tbl_document") self.tbl_event_element = self.dialog.findChild(QTableView, "tbl_event_element") self.tbl_event = self.dialog.findChild(QTableView, "tbl_event_node") self.tbl_scada = self.dialog.findChild(QTableView, "tbl_scada") self.tbl_scada_value = self.dialog.findChild(QTableView, "tbl_scada_value") self.tbl_costs = self.dialog.findChild(QTableView, "tbl_masterplan") self.nodecat_id = self.dialog.findChild(QLineEdit, 'nodecat_id') state_type = self.dialog.findChild(QComboBox, 'state_type') dma_id = self.dialog.findChild(QComboBox, 'dma_id') # Tables self.tbl_upstream = self.dialog.findChild(QTableView, "tbl_upstream") self.tbl_upstream.setSelectionBehavior(QAbstractItemView.SelectRows) self.tbl_downstream = self.dialog.findChild(QTableView, "tbl_downstream") self.tbl_downstream.setSelectionBehavior(QAbstractItemView.SelectRows) self.dialog.findChild(QPushButton, "btn_catalog").clicked.connect( partial(self.catalog, self.dialog, 'ud', 'node')) # New Workcat # self.dialog.findChild(QPushButton, "btn_new_workcat").clicked.connect(partial(self.cf_new_workcat, self.dialog)) self.tbl_upstream.doubleClicked.connect( partial(self.open_up_down_stream, self.tbl_upstream)) self.tbl_downstream.doubleClicked.connect( partial(self.open_up_down_stream, self.tbl_downstream)) feature = self.feature layer = self.iface.activeLayer() action_copypaste = self.dialog.findChild(QAction, "actionCopyPaste") layer.editingStarted.connect( partial(self.enabled_actions, action_copypaste, True)) layer.editingStopped.connect( partial(self.enabled_actions, action_copypaste, False)) action_rotation = self.dialog.findChild(QAction, "actionRotation") layer.editingStarted.connect( partial(self.enabled_actions, action_rotation, True)) layer.editingStopped.connect( partial(self.enabled_actions, action_rotation, False)) action_interpolate = self.dialog.findChild(QAction, "actionInterpolate") layer.editingStarted.connect( partial(self.enabled_actions, action_interpolate, True)) layer.editingStopped.connect( partial(self.enabled_actions, action_interpolate, False)) self.dialog.destroyed.connect(partial(self.dlg_destroyed, layer=layer)) # Toolbar actions action = self.dialog.findChild(QAction, "actionEnabled") self.dialog.findChild(QAction, "actionCopyPaste").setEnabled(layer.isEditable()) self.dialog.findChild(QAction, "actionRotation").setEnabled(layer.isEditable()) self.dialog.findChild(QAction, "actionInterpolate").setEnabled( layer.isEditable()) self.dialog.findChild(QAction, "actionZoom").triggered.connect( partial(self.action_zoom_in, self.feature, self.canvas, self.layer)) self.dialog.findChild(QAction, "actionCentered").triggered.connect( partial(self.action_centered, self.feature, self.canvas, self.layer)) if not role_basic: action.setChecked(layer.isEditable()) layer.editingStarted.connect( partial(self.check_actions, action, True)) layer.editingStopped.connect( partial(self.check_actions, action, False)) self.dialog.findChild(QAction, "actionEnabled").triggered.connect( partial(self.action_enabled, action, self.layer)) else: action.setEnabled(False) self.dialog.findChild(QAction, "actionZoomOut").triggered.connect( partial(self.action_zoom_out, self.feature, self.canvas, self.layer)) self.dialog.findChild(QAction, "actionRotation").triggered.connect( self.action_rotation) self.dialog.findChild(QAction, "actionCopyPaste").triggered.connect( partial(self.action_copy_paste, self.geom_type)) self.dialog.findChild(QAction, "actionLink").triggered.connect( partial(self.check_link, self.dialog, True)) self.dialog.findChild(QAction, "actionHelp").triggered.connect( partial(self.action_help, 'ud', 'node')) self.dialog.findChild(QAction, "actionInterpolate").triggered.connect( partial(self.activate_snapping, emit_point)) widget_ymax = self.dialog.findChild(QLineEdit, 'ymax') if widget_ymax is not None: widget_ymax.textChanged.connect( partial(self.compare_depth, widget_ymax, False)) widget_ymax.lostFocus.connect( partial(self.compare_depth, widget_ymax, True)) # Manage tab 'Scada' self.manage_tab_scada() # Check if exist URL from field 'link' in main tab self.check_link(self.dialog) # Check topology for new features continue_insert = True node_over_node = True check_topology_node = self.controller.plugin_settings_value( "check_topology_node", "0") check_topology_arc = self.controller.plugin_settings_value( "check_topology_arc", "0") # Check if feature has geometry object geometry = self.feature.geometry() if geometry: if self.id.upper() == 'NULL' and check_topology_node == "0": self.get_topology_parameters() (continue_insert, node_over_node) = self.check_topology_node() if continue_insert and not node_over_node: if self.id.upper() == 'NULL' and check_topology_arc == "0": self.check_topology_arc() # Create thread thread1 = Thread(self, self.controller, 3) thread1.start() self.filter = "node_id = '" + str(self.id) + "'" table_name = self.controller.schema_name + ".v_ui_node_x_connection_upstream" self.fill_table(self.tbl_upstream, table_name, self.filter) self.set_configuration(self.tbl_upstream, "v_ui_node_x_connection_upstream") table_name = self.controller.schema_name + ".v_ui_node_x_connection_downstream" self.fill_table(self.tbl_downstream, table_name, self.filter) self.set_configuration(self.tbl_downstream, "v_ui_node_x_connection_downstream") # Manage tab signal self.tab_connections_loaded = False self.tab_element_loaded = False self.tab_document_loaded = False self.tab_om_loaded = False self.tab_scada_loaded = False self.tab_cost_loaded = False self.tab_custom_fields_loaded = False self.tab_main.currentChanged.connect(self.tab_activation) # Load default settings widget_id = self.dialog.findChild(QLineEdit, 'node_id') if utils_giswater.getWidgetText(self.dialog, widget_id).lower() == 'null': self.load_default(self.dialog, "node") self.load_type_default(self.dialog, "nodecat_id", "nodecat_vdefault") self.load_state_type(self.dialog, state_type, self.geom_type) self.load_dma(self.dialog, dma_id, self.geom_type) def compare_depth(self, widget_ymax, show_message): widget_ymax.setStyleSheet("border: 1px solid gray") node_id = utils_giswater.getWidgetText(self.dialog, 'node_id') ymax = utils_giswater.getWidgetText(self.dialog, widget_ymax) if ymax is None: return bad_alert = False sql = ("SELECT * from " + self.schema_name + ".v_ui_node_x_connection_upstream " " WHERE node_id = '" + str(node_id) + "'") rows = self.controller.get_rows(sql, log_sql=False) arcs_list = "" if len(rows) > 0: arcs_list += "Upstream: " for row in rows: if row['upstream_depth'] is not None: if float(ymax) < float(row['upstream_depth']): widget_ymax.setStyleSheet("border: 1px solid red") arcs_list += str((row['feature_id'] + ", ")) bad_alert = True sql = ("SELECT * from " + self.schema_name + ".v_ui_node_x_connection_downstream " " WHERE node_id = '" + str(node_id) + "'") rows = self.controller.get_rows(sql, log_sql=False) if len(rows) > 0: arcs_list += "Downstream: " for row in rows: if row['downstream_depth'] is not None: if float(ymax) < float(row['downstream_depth']): widget_ymax.setStyleSheet("border: 1px solid red") arcs_list += str((row['feature_id'] + ", ")) bad_alert = True if len(arcs_list) > 2: arcs_list = arcs_list[:-2] if show_message and bad_alert: msg = "The depth of this node is less than the arc/'s {}".format( arcs_list) # self.controller.show_info_box(text=msg, title="Info") msg_box = QMessageBox() msg_box.setIcon(3) msg_box.setWindowTitle("Warning") msg_box.setText(msg) msg_box.exec_() def activate_snapping(self, emit_point): # Set circle vertex marker color = QColor(255, 100, 255) self.vertex_marker = QgsVertexMarker(self.canvas) self.vertex_marker.setIconType(QgsVertexMarker.ICON_CIRCLE) self.vertex_marker.setColor(color) self.vertex_marker.setIconSize(15) self.vertex_marker.setPenWidth(3) self.node1 = None self.node2 = None self.canvas.setMapTool(emit_point) self.snapper = QgsMapCanvasSnapper(self.canvas) self.layer_node = self.controller.get_layer_by_tablename("v_edit_node") self.iface.setActiveLayer(self.layer_node) self.canvas.connect(self.canvas, SIGNAL("xyCoordinates(const QgsPoint&)"), self.mouse_move) emit_point.canvasClicked.connect(partial(self.snapping_node)) def snapping_node(self, point, button): """ Get id of selected nodes (node1 and node2) """ if button == 2: self.dlg_destroyed() return map_point = self.canvas.getCoordinateTransform().transform(point) x = map_point.x() y = map_point.y() event_point = QPoint(x, y) # Snapping (retval, result) = self.snapper.snapToBackgroundLayers( event_point) # @UnusedVariable # That's the snapped point if result: # Check feature for snapped_point in result: if snapped_point.layer == self.layer_node: # Get the point snapp_feature = next( snapped_point.layer.getFeatures( QgsFeatureRequest().setFilterFid( snapped_point.snappedAtGeometry))) element_id = snapp_feature.attribute('node_id') message = "Selected node" if self.node1 is None: self.node1 = str(element_id) self.controller.show_message(message, message_level=0, duration=1, parameter=self.node1) elif self.node1 != str(element_id): self.node2 = str(element_id) self.controller.show_message(message, message_level=0, duration=1, parameter=self.node2) if self.node1 is not None and self.node2 is not None: self.iface.actionPan().trigger() self.iface.setActiveLayer(self.layer) self.iface.mapCanvas().scene().removeItem(self.vertex_marker) sql = ("SELECT " + self.schema_name + ".gw_fct_node_interpolate('" "" + str(self.last_point[0]) + "', '" + str(self.last_point[1]) + "', '" "" + str(self.node1) + "', '" + self.node2 + "')") row = self.controller.get_row(sql) if row: if 'elev' in row[0]: utils_giswater.setWidgetText(self.dialog, 'elev', row[0]['elev']) if 'top_elev' in row[0]: utils_giswater.setWidgetText(self.dialog, 'top_elev', row[0]['top_elev']) def mouse_move(self, p): map_point = self.canvas.getCoordinateTransform().transform(p) x = map_point.x() y = map_point.y() eventPoint = QPoint(x, y) # Snapping (retval, result) = self.snapper.snapToCurrentLayer(eventPoint, 2) # @UnusedVariable # That's the snapped features if result: for snapped_point in result: if snapped_point.layer == self.layer_node: point = QgsPoint(snapped_point.snappedVertex) # Add marker self.vertex_marker.setCenter(point) self.vertex_marker.show() else: self.vertex_marker.hide() def open_up_down_stream(self, qtable): """ Open selected node from @qtable """ selected_list = qtable.selectionModel().selectedRows() if len(selected_list) == 0: message = "Any record selected" self.controller.show_warning(message) return row = selected_list[0].row() feature_id = qtable.model().record(row).value("feature_id") featurecat_id = qtable.model().record(row).value("featurecat_id") # Get sys_feature_cat.id from cat_feature.id sql = ("SELECT sys_feature_cat.id FROM " + self.controller.schema_name + ".cat_feature" " INNER JOIN " + self.controller.schema_name + ".sys_feature_cat ON cat_feature.system_id = sys_feature_cat.id" " WHERE cat_feature.id = '" + featurecat_id + "'") row = self.controller.get_row(sql) if not row: return layer = self.get_layer(row[0]) if layer: field_id = self.controller.get_layer_primary_key(layer) aux = "\"" + field_id + "\" = " aux += "'" + str(feature_id) + "'" expr = QgsExpression(aux) if expr.hasParserError(): message = "Expression Error" self.controller.show_warning( message, parameter=expr.parserErrorString()) return it = layer.getFeatures(QgsFeatureRequest(expr)) features = [i for i in it] if features != []: self.iface.openFeatureForm(layer, features[0]) else: message = "Layer not found" self.controller.show_warning(message, parameter=row[0]) def get_topology_parameters(self): """ Get parameters 'node_proximity' and 'node2arc' from config table """ self.node_proximity = 0.1 self.node2arc = 0.01 sql = "SELECT node_proximity, node2arc FROM " + self.schema_name + ".config" row = self.controller.get_row(sql) if row: self.node_proximity = row['node_proximity'] def check_topology_arc(self): """ Check topology: Inserted node is over an existing arc? """ # Initialize plugin parameters self.controller.plugin_settings_set_value("check_topology_arc", "0") self.controller.plugin_settings_set_value("close_dlg", "0") # Get selected srid and coordinates. Set SQL to check topology srid = self.controller.plugin_settings_value('srid') point = self.feature.geometry().asPoint() node_geom = "ST_SetSRID(ST_Point(" + str(point.x()) + ", " + str( point.y()) + "), " + str(srid) + ")" sql = ("SELECT arc_id, state FROM " + self.schema_name + ".v_edit_arc" " WHERE ST_DWithin(" + node_geom + ", v_edit_arc.the_geom, " + str(self.node2arc) + ")" " ORDER BY ST_Distance(v_edit_arc.the_geom, " + node_geom + ")" " LIMIT 1") row = self.controller.get_row(sql) if row: sql = ( "SELECT value FROM " + self.schema_name + ".config_param_user" " WHERE parameter = 'edit_arc_division_dsbl' AND cur_user = current_user" ) row2 = self.controller.get_row(sql) if row2 and str(row2[0].lower()) == 'true': self.controller.plugin_settings_set_value( "check_topology_arc", "1") else: msg = ( "We have detected you are trying to divide an arc with state " + str(row['state']) + "" "\nIt will destroy it. Would you like to continue?") answer = self.controller.ask_question( msg, "Divide intersected arc?") if answer: self.controller.plugin_settings_set_value( "check_topology_arc", "1") else: self.controller.plugin_settings_set_value("close_dlg", "1") def check_topology_node(self): """ Check topology: Inserted node is over an existing node? """ node_over_node = False continue_insert = True # Initialize plugin parameters self.controller.plugin_settings_set_value("check_topology_node", "0") self.controller.plugin_settings_set_value("close_dlg", "0") # Get selected srid and coordinates. Set SQL to check topology srid = self.controller.plugin_settings_value('srid') point = self.feature.geometry().asPoint() node_geom = "ST_SetSRID(ST_Point(" + str(point.x()) + ", " + str( point.y()) + "), " + str(srid) + ")" sql = ("SELECT node_id, state FROM " + self.schema_name + ".v_edit_node" " WHERE ST_Intersects(ST_Buffer(" + node_geom + ", " + str(self.node_proximity) + "), the_geom)" " ORDER BY ST_Distance(" + node_geom + ", the_geom)" " LIMIT 1") row = self.controller.get_row(sql) if row: node_over_node = True msg = ( "We have detected you are trying to insert one node over another node with state " + str(row['state']) + "" "\nRemember that:" "\n\nIn case of old or new node has state 0, you are allowed to insert new one, because state 0 has not topology rules." "\nIn the rest of cases, remember that the state topology rules of Giswater only enables one node with the same state at the same position." "\n\nWould you like to continue?") answer = self.controller.ask_question(msg, "Insert node over node?") if answer: self.controller.plugin_settings_set_value( "check_topology_node", "1") else: self.controller.plugin_settings_set_value("close_dlg", "1") continue_insert = False return continue_insert, node_over_node def action_rotation(self): # Set map tool emit point and signals self.emit_point = QgsMapToolEmitPoint(self.canvas) self.canvas.setMapTool(self.emit_point) self.snapper = QgsMapCanvasSnapper(self.canvas) self.canvas.xyCoordinates.connect(self.action_rotation_mouse_move) self.emit_point.canvasClicked.connect( self.action_rotation_canvas_clicked) # Store user snapping configuration self.snapper_manager = SnappingConfigManager(self.iface) self.snapper_manager.store_snapping_options() # Clear snapping self.snapper_manager.clear_snapping() # Set snapping layer = self.controller.get_layer_by_tablename("v_edit_arc") self.snapper_manager.snap_to_layer(layer) layer = self.controller.get_layer_by_tablename("v_edit_connec") self.snapper_manager.snap_to_layer(layer) layer = self.controller.get_layer_by_tablename("v_edit_node") self.snapper_manager.snap_to_layer(layer) # Set marker color = QColor(255, 100, 255) self.vertex_marker = QgsVertexMarker(self.canvas) self.vertex_marker.setIconType(QgsVertexMarker.ICON_CROSS) self.vertex_marker.setColor(color) self.vertex_marker.setIconSize(15) self.vertex_marker.setPenWidth(3) def action_rotation_mouse_move(self, point): """ Slot function when mouse is moved in the canvas. Add marker if any feature is snapped """ # Hide marker and get coordinates self.vertex_marker.hide() map_point = self.canvas.getCoordinateTransform().transform(point) x = map_point.x() y = map_point.y() event_point = QPoint(x, y) # Snapping (retval, result) = self.snapper.snapToBackgroundLayers( event_point) # @UnusedVariable if not result: return # Check snapped features for snapped_point in result: point = QgsPoint(snapped_point.snappedVertex) self.vertex_marker.setCenter(point) self.vertex_marker.show() break def action_rotation_canvas_clicked(self, point, btn): if btn == Qt.RightButton: self.disable_rotation() return viewname = self.controller.get_layer_source_table_name(self.layer) sql = ("SELECT ST_X(the_geom), ST_Y(the_geom)" " FROM " + self.schema_name + "." + viewname + "" " WHERE node_id = '" + self.id + "'") row = self.controller.get_row(sql) if row: existing_point_x = row[0] existing_point_y = row[1] sql = ("UPDATE " + self.schema_name + ".node" " SET hemisphere = (SELECT degrees(ST_Azimuth(ST_Point(" + str(existing_point_x) + ", " + str(existing_point_y) + "), " " ST_Point(" + str(point.x()) + ", " + str(point.y()) + "))))" " WHERE node_id = '" + str(self.id) + "'") status = self.controller.execute_sql(sql) if not status: self.disable_rotation() return sql = ("SELECT degrees(ST_Azimuth(ST_Point(" + str(existing_point_x) + ", " + str(existing_point_y) + ")," " ST_Point( " + str(point.x()) + ", " + str(point.y()) + ")))") row = self.controller.get_row(sql) if row: utils_giswater.setWidgetText(self.dialog, "hemisphere", str(row[0])) message = "Hemisphere of the node has been updated. Value is" self.controller.show_info(message, parameter=str(row[0])) self.disable_rotation() def disable_rotation(self): """ Disable actionRotation and set action 'Identify' """ action_widget = self.dialog.findChild(QAction, "actionRotation") if action_widget: action_widget.setChecked(False) try: self.snapper_manager.recover_snapping_options() self.vertex_marker.hide() self.set_action_identify() self.canvas.xyCoordinates.disconnect() self.emit_point.canvasClicked.disconnect() except: pass def tab_activation(self): """ Call functions depend on tab selection """ # Get index of selected tab index_tab = self.tab_main.currentIndex() # Tab 'Custom fields' if index_tab == 1 and not self.tab_custom_fields_loaded: self.tab_custom_fields_loaded = self.fill_tab_custom_fields() # Tab 'Connections' if index_tab == ( 2 - self.tabs_removed) and not self.tab_connections_loaded: self.fill_tab_connections() self.tab_connections_loaded = True # Tab 'Element' elif index_tab == (3 - self.tabs_removed) and not self.tab_element_loaded: self.fill_tab_element() self.tab_element_loaded = True # Tab 'Document' elif index_tab == (4 - self.tabs_removed) and not self.tab_document_loaded: self.fill_tab_document() self.tab_document_loaded = True # Tab 'O&M' elif index_tab == (5 - self.tabs_removed) and not self.tab_om_loaded: self.fill_tab_om() self.tab_om_loaded = True # Tab 'Scada' elif index_tab == (6 - self.tabs_removed - self.tab_scada_removed ) and not self.tab_scada_loaded: self.fill_tab_scada() self.tab_scada_loaded = True # Tab 'Cost' elif index_tab == (7 - self.tabs_removed - self.tab_scada_removed ) and not self.tab_cost_loaded: self.fill_tab_cost() self.tab_cost_loaded = True def fill_tab_connections(self): """ Fill tab 'Connections' """ self.fill_tables(self.tbl_upstream, "v_ui_node_x_connection_upstream") self.fill_tables(self.tbl_downstream, "v_ui_node_x_connection_downstream") def fill_tab_element(self): """ Fill tab 'Element' """ table_element = "v_ui_element_x_node" self.fill_tbl_element_man(self.dialog, self.tbl_element, table_element, self.filter) self.set_configuration(self.tbl_element, table_element) def fill_tab_document(self): """ Fill tab 'Document' """ table_document = "v_ui_doc_x_node" self.fill_tbl_document_man(self.dialog, self.tbl_document, table_document, self.filter) self.set_configuration(self.tbl_document, table_document) def fill_tab_om(self): """ Fill tab 'O&M' (event) """ table_event_node = "v_ui_om_visit_x_node" self.fill_tbl_event(self.tbl_event, self.schema_name + "." + table_event_node, self.filter) self.tbl_event.doubleClicked.connect(self.open_visit_event) self.set_configuration(self.tbl_event, table_event_node) def fill_tab_scada(self): """ Fill tab 'Scada' """ pass def fill_tab_cost(self): """ Fill tab 'Cost' """ table_costs = "v_plan_node" self.fill_table(self.tbl_costs, self.schema_name + "." + table_costs, self.filter) self.set_configuration(self.tbl_costs, table_costs) def fill_tab_custom_fields(self): """ Fill tab 'Custom fields' """ node_type = self.dialog.findChild(QComboBox, "node_type") cat_feature_id = utils_giswater.getWidgetText(self.dialog, node_type) if cat_feature_id.lower() == "null": msg = "In order to manage custom fields, that field has to be set" self.controller.show_info(msg, parameter='node_type', duration=10) return False self.manage_custom_fields(cat_feature_id) return True
class ObstacleAreaJigSelectArea(QgsMapTool): def __init__(self, canvas, areaType): self.mCanvas = canvas self.areaType = areaType QgsMapTool.__init__(self, canvas) self.mCursor = Qt.ArrowCursor self.mRubberBand = None self.mDragging = False self.mSelectRect = QRect() self.mRubberBandResult = None self.mSnapper = QgsMapCanvasSnapper(canvas) self.lineCount = 0 self.resultGeomList = [] self.geomList = [] self.area = None self.isFinished = False # QgsRubberBand* mRubberBand; # def reset(self): # self.startPoint = None # self.endPoint = None # self.isDrawing = False # SelectByRect.RubberRect.reset(QGis.Polygon) # self.layer = self.canvas.currentLayer() def canvasPressEvent(self, e): QgisHelper.ClearRubberBandInCanvas(define._canvas) self.mSelectRect.setRect( 0, 0, 0, 0 ) self.mRubberBand = QgsRubberBand( self.mCanvas, QGis.Polygon ) self.startPoint, self.pointID, self.layer= self.snapPoint(e.pos()) def canvasMoveEvent(self, e): if self.areaType == ProtectionAreaType.Secondary: if self.lineCount == 0: define._messageLabel.setText("Select a line or arc representing the INNER edge of the secondary area.") elif self.lineCount == 1: define._messageLabel.setText("Select a line representing the OUTER edge of the secondary area.") elif self.areaType == ProtectionAreaType.Primary: define._messageLabel.setText("") elif self.areaType == ProtectionAreaType.PrimaryAndSecondary: if self.lineCount == 0: define._messageLabel.setText("Select a line or arc representing the INNER edge of the FIRST secondary area.") elif self.lineCount == 1: define._messageLabel.setText("Select a line representing the OUTER edge of the FIRST secondary area.") elif self.lineCount == 2: define._messageLabel.setText("Select a line or arc representing the INNER edge of the SECOND secondary area.") elif self.lineCount == 3: define._messageLabel.setText("Select a line representing the OUTER edge of the SECOND secondary area.") else: define._messageLabel.setText("") if ( e.buttons() != Qt.LeftButton ): return if ( not self.mDragging ): self.mDragging = True self.mSelectRect.setTopLeft( e.pos() ) self.mSelectRect.setBottomRight( e.pos() ) QgsMapToolSelectUtils.setRubberBand( self.mCanvas, self.mSelectRect,self.mRubberBand ) def canvasReleaseEvent(self, e): self.endPoint, self.pointID, self.layer= self.snapPoint(e.pos()) vlayer = QgsMapToolSelectUtils.getCurrentVectorLayer( self.mCanvas ) if ( vlayer == None ): if ( self.mRubberBand != None): self.mRubberBand.reset( QGis.Polygon ) del self.mRubberBand self.mRubberBand = None self.mDragging = False return if (not self.mDragging ): QgsMapToolSelectUtils.expandSelectRectangle(self. mSelectRect, vlayer, e.pos() ) else: if ( self.mSelectRect.width() == 1 ): self.mSelectRect.setLeft( self.mSelectRect.left() + 1 ) if ( self.mSelectRect.height() == 1 ): self.mSelectRect.setBottom( self.mSelectRect.bottom() + 1 ) if ( self.mRubberBand != None ): QgsMapToolSelectUtils.setRubberBand( self.mCanvas, self.mSelectRect, self.mRubberBand ) selectGeom = self.mRubberBand.asGeometry() selectedFeatures = QgsMapToolSelectUtils.setSelectFeaturesOrRubberband_Tas_1( self.mCanvas, selectGeom, e ) if len(selectedFeatures) > 0: self.lineCount += 1 geom = selectedFeatures[0].geometry() resultArray = QgisHelper.findArcOrLineInLineGeometry(geom, selectGeom) # if resultArray != None: # bulge = MathHelper.smethod_60(resultArray[0], resultArray[int(len(resultArray)/2)], resultArray[len(resultArray)-1]) # bulge1 = MathHelper.smethod_60(resultArray[len(resultArray)-1], resultArray[int(len(resultArray)/2)], resultArray[0]) # n = 0 pointArray0 = geom.asPolyline() self.resultGeomList.append(resultArray) self.geomList.append(pointArray0) if self.lineCount == 2 and self.areaType != ProtectionAreaType.PrimaryAndSecondary and self.areaType != ProtectionAreaType.Complex: self.area = self.makeArea(self.resultGeomList, self.areaType) pointArray = self.getPointArray(self.resultGeomList).method_14_closed() self.mRubberBandResult = None self.mRubberBandResult = QgsRubberBand( self.mCanvas, QGis.Polygon ) self.mRubberBandResult.setFillColor(QColor(255, 255, 255, 100)) self.mRubberBandResult.setBorderColor(QColor(0, 0, 0)) for point in pointArray: self.mRubberBandResult.addPoint(point) self.mRubberBandResult.show() self.emit(SIGNAL("outputResult"), self.area, self.mRubberBandResult) self.lineCount = 0 self.resultGeomList = [] self.isFinished = True # self.rubberBandLine.reset(QGis.Line) elif self.lineCount == 4 and self.areaType == ProtectionAreaType.PrimaryAndSecondary: self.area = self.makeArea(self.resultGeomList, self.areaType) pointArray = self.getPointArray([self.resultGeomList[1], self.resultGeomList[3]]).method_14_closed() self.mRubberBandResult = None self.mRubberBandResult = QgsRubberBand( self.mCanvas, QGis.Polygon ) self.mRubberBandResult.setFillColor(QColor(255, 255, 255, 100)) self.mRubberBandResult.setBorderColor(QColor(0, 0, 0)) for point in pointArray: self.mRubberBandResult.addPoint(point) self.mRubberBandResult.show() self.emit(SIGNAL("outputResult"), self.area, self.mRubberBandResult) self.lineCount = 0 self.resultGeomList = [] # else: # return del selectGeom self.mRubberBand.reset( QGis.Polygon ) del self.mRubberBand self.mRubberBand = None self.mDragging = False def getPointArray(self, geomList): pointArrayInner = geomList[0] pointArray1Outer = geomList[1] innerStartPoint = pointArrayInner[0] innerEndPoint = pointArrayInner[1] innerBulge = pointArrayInner[2] outerStartPoint = pointArray1Outer[0] outerEndPoint = pointArray1Outer[1] outerBulge = pointArray1Outer[2] line0 = QgsGeometry.fromPolyline([innerStartPoint, outerStartPoint]) line1 = QgsGeometry.fromPolyline([innerEndPoint, outerEndPoint]) # for i in range(1, len(pointArray0)): if line0.intersects(line1): tempPoint = outerStartPoint outerStartPoint = outerEndPoint outerEndPoint = tempPoint outerBulge = -outerBulge polylineArea = PolylineArea() polylineArea.Add(PolylineAreaPoint(innerStartPoint, innerBulge)) polylineArea.Add(PolylineAreaPoint(innerEndPoint)) polylineArea.Add(PolylineAreaPoint(outerEndPoint, -outerBulge)) polylineArea.Add(PolylineAreaPoint(outerStartPoint)) return polylineArea def makeArea(self, geomList, areaType): if areaType == ProtectionAreaType.Primary or areaType == ProtectionAreaType.Secondary: return self.makePrimaryAreaOrSecondaryArea(geomList, areaType) elif areaType == ProtectionAreaType.PrimaryAndSecondary: pointArray0 = geomList[0] pointArray1 = geomList[1] pointArray2 = geomList[2] pointArray3 = geomList[3] primaryArea = self.makePrimaryAreaOrSecondaryArea([pointArray0, pointArray2], ProtectionAreaType.Primary) secondaryArea1 = self.makePrimaryAreaOrSecondaryArea([pointArray0, pointArray1], ProtectionAreaType.Secondary) secondaryArea2 = self.makePrimaryAreaOrSecondaryArea([pointArray2, pointArray3], ProtectionAreaType.Secondary) return PrimarySecondaryObstacleArea(primaryArea, secondaryArea1, secondaryArea2) # if len(geomList[0]) == 2 and len(geomList[1]) == 2 and len(geomList[2]) == 2 and len(geomList[3]) == 2: # for i in range(1, len(geomList)): # pointArray0 = geomList[0] # pointArray1 = geomList[i] # line0 = QgsGeometry.fromPolyline([pointArray0[0], pointArray1[0]]) # line1 = QgsGeometry.fromPolyline([pointArray0[len(pointArray0) - 1], pointArray1[len(pointArray1) - 1]]) # if line0.intersects(line1): # pointArray1.reverse() # pointArray0 = geomList[0] # pointArray1 = geomList[1] # pointArray2 = geomList[2] # pointArray3 = geomList[3] # area = PrimarySecondaryObstacleArea() # area.set_areas(pointArray0, pointArray1, pointArray2, pointArray3) # return area # return None return None def makePrimaryAreaOrSecondaryArea(self, geomList, areaType): pointArrayInner = geomList[0] pointArray1Outer = geomList[1] innerStartPoint = pointArrayInner[0] innerEndPoint = pointArrayInner[1] innerBulge = pointArrayInner[2] outerStartPoint = pointArray1Outer[0] outerEndPoint = pointArray1Outer[1] outerBulge = pointArray1Outer[2] line0 = QgsGeometry.fromPolyline([innerStartPoint, outerStartPoint]) line1 = QgsGeometry.fromPolyline([innerEndPoint, outerEndPoint]) # for i in range(1, len(pointArray0)): if line0.intersects(line1): tempPoint = Point3D(outerStartPoint.get_X(), outerStartPoint.get_Y()) outerStartPoint = Point3D(outerEndPoint.get_X(), outerEndPoint.get_Y()) outerEndPoint = Point3D(tempPoint.get_X(), tempPoint.get_Y()) outerBulge = -outerBulge if areaType == ProtectionAreaType.Primary: polylineArea = PolylineArea() polylineArea.Add(PolylineAreaPoint(innerStartPoint, innerBulge)) polylineArea.Add(PolylineAreaPoint(innerEndPoint)) polylineArea.Add(PolylineAreaPoint(outerEndPoint, -outerBulge)) polylineArea.Add(PolylineAreaPoint(outerStartPoint)) return PrimaryObstacleArea(polylineArea) elif areaType == ProtectionAreaType.Secondary: if innerBulge == 0 and outerBulge == 0: return SecondaryObstacleArea(innerStartPoint, innerEndPoint, outerStartPoint, outerEndPoint, MathHelper.getBearing(innerStartPoint, innerEndPoint)) elif innerBulge != 0 and outerBulge != 0: if round(innerBulge, 1) != round(outerBulge, 1): return None innerCenterPoint = MathHelper.smethod_71(innerStartPoint, innerEndPoint, innerBulge) outerCenterPoint = MathHelper.smethod_71(outerStartPoint, outerEndPoint, outerBulge) innerRadius = MathHelper.calcDistance(innerCenterPoint, innerStartPoint); outerRadius = MathHelper.calcDistance(outerCenterPoint, outerStartPoint); bearing = (MathHelper.getBearing(innerCenterPoint, innerStartPoint) + MathHelper.getBearing(innerCenterPoint, innerEndPoint)) / 2 innerMiddlePoint = MathHelper.distanceBearingPoint(innerCenterPoint, bearing, innerRadius) if round(MathHelper.smethod_60(innerStartPoint, innerMiddlePoint, innerEndPoint), 4) != round(outerBulge, 4): bearing += 3.14159265358979 innerMiddlePoint = MathHelper.distanceBearingPoint(innerCenterPoint, bearing, innerRadius) bearing = (MathHelper.getBearing(outerCenterPoint, outerStartPoint) + MathHelper.getBearing(outerCenterPoint, outerEndPoint)) / 2 outerMiddlePoint = MathHelper.distanceBearingPoint(outerCenterPoint, bearing, outerRadius) if round(MathHelper.smethod_60(outerStartPoint, outerMiddlePoint, outerEndPoint), 4) != round(outerBulge, 4): bearing += 3.14159265358979 outerMiddlePoint = MathHelper.distanceBearingPoint(outerCenterPoint, bearing, outerRadius) return SecondaryObstacleArea(innerStartPoint, innerMiddlePoint, innerEndPoint, outerStartPoint, None, outerMiddlePoint, outerEndPoint, innerBulge, innerBulge) return None def snapPoint(self, p, bNone = False): if define._snapping == False: return (define._canvas.getCoordinateTransform().toMapCoordinates( p ), None, None) snappingResults = self.mSnapper.snapToBackgroundLayers( p ) if ( snappingResults[0] != 0 or len(snappingResults[1]) < 1 ): if bNone: return (None, None, None) else: return (define._canvas.getCoordinateTransform().toMapCoordinates( p ), None, None) else: return (snappingResults[1][0].snappedVertex, snappingResults[1][0].snappedAtGeometry, snappingResults[1][0].layer)
class ArkMapToolInteractive(QgsMapTool): _active = False _dragging = False _panningEnabled = False _zoomingEnabled = False _zoomRubberBand = None #QgsRubberBand() _zoomRect = None # QRect() _snappingEnabled = False _snapper = None #QgsMapCanvasSnapper() _snappingMarker = None # QgsVertexMarker() _showSnappableVertices = False _snappableVertices = [] # [QgsPoint()] _snappableMarkers = [] # [QgsVertexMarker()] def __init__(self, canvas, snappingEnabled=False, showSnappableVertices=False): super(ArkMapToolInteractive, self).__init__(canvas) self._snappingEnabled = snappingEnabled self._showSnappableVertices = showSnappableVertices def __del__(self): if self._active: self.deactivate() def isActive(self): return self._active def activate(self): super(ArkMapToolInteractive, self).activate() self._active = True self._startSnapping() def deactivate(self): self._active = False if self._snappingEnabled: self._stopSnapping() if (self._zoomRubberBand is not None): self.canvas().scene().removeItem(self._zoomRubberBand) self._zoomRubberBand = None super(ArkMapToolInteractive, self).deactivate() def setAction(self, action): super(ArkMapToolInteractive, self).setAction(action) self.action().triggered.connect(self._activate) def _activate(self): self.canvas().setMapTool(self) def panningEnabled(self): return self._panningEnabled def setPanningEnabled(self, enabled): self._panningEnabled = enabled def zoomingEnabled(self): return self._zoomingEnabled def setZoomingEnabled(self, enabled): self._zoomingEnabled = enabled def snappingEnabled(self): return self._snappingEnabled def setSnappingEnabled(self, enabled): if (self._snappingEnabled == enabled): return self._snappingEnabled = enabled if not self._active: return if enabled: self._startSnapping() else: self._stopSnapping() def _startSnapping(self): self._snapper = QgsMapCanvasSnapper() self._snapper.setMapCanvas(self.canvas()) if self._showSnappableVertices: self._startSnappableVertices() def _stopSnapping(self): self._deleteSnappingMarker() self._snapper = None if self._showSnappableVertices: self._stopSnappableVertices() def showSnappableVertices(self): return self._showSnappableVertices def setShowSnappableVertices(self, show): if (self._showSnappableVertices == show): return self._showSnappableVertices = show if not self._active: return if show: self._startSnappableVertices() else: self._stopSnappableVertices() def _startSnappableVertices(self): self.canvas().layersChanged.connect(self._layersChanged) self.canvas().extentsChanged.connect(self._redrawSnappableMarkers) QgsProject.instance().snapSettingsChanged.connect(self._layersChanged) self._layersChanged() def _stopSnappableVertices(self): self._deleteSnappableMarkers() self._snappableLayers = [] self.canvas().layersChanged.disconnect(self._layersChanged) self.canvas().extentsChanged.disconnect(self._redrawSnappableMarkers) QgsProject.instance().snapSettingsChanged.disconnect(self._layersChanged) def canvasMoveEvent(self, e): super(ArkMapToolInteractive, self).canvasMoveEvent(e) if not self._active: return e.ignore() if (self._panningEnabled and e.buttons() & Qt.LeftButton): # Pan map mode if not self._dragging: self._dragging = True self.setCursor(QCursor(Qt.ClosedHandCursor)) self.canvas().panAction(e) e.accept() elif (self._zoomingEnabled and e.buttons() & Qt.RightButton): # Zoom map mode if not self._dragging: self._dragging = True self.setCursor(QCursor(Qt.ClosedHandCursor)) self._zoomRubberBand = QgsRubberBand(self.canvas(), QGis.Polygon) color = QColor(Qt.blue) color.setAlpha(63) self._zoomRubberBand.setColor(color) self._zoomRect = QRect(0, 0, 0, 0) self._zoomRect.setTopLeft(e.pos()) self._zoomRect.setBottomRight(e.pos()) if self._zoomRubberBand is not None: self._zoomRubberBand.setToCanvasRectangle(self._zoomRect) self._zoomRubberBand.show() e.accept() elif self._snappingEnabled: mapPoint, snapped = self._snapCursorPoint(e.pos()) if (snapped): self._createSnappingMarker(mapPoint) else: self._deleteSnappingMarker() def canvasReleaseEvent(self, e): super(ArkMapToolInteractive, self).canvasReleaseEvent(e) e.ignore() if (e.button() == Qt.LeftButton): if self._dragging: # Pan map mode self.canvas().panActionEnd(e.pos()) self.setCursor(capture_point_cursor) self._dragging = False e.accept() elif (e.button() == Qt.RightButton): if self._dragging: # Zoom mode self._zoomRect.setBottomRight(e.pos()) if (self._zoomRect.topLeft() != self._zoomRect.bottomRight()): coordinateTransform = self.canvas().getCoordinateTransform() ll = coordinateTransform.toMapCoordinates(self._zoomRect.left(), self._zoomRect.bottom()) ur = coordinateTransform.toMapCoordinates(self._zoomRect.right(), self._zoomRect.top()) r = QgsRectangle() r.setXMinimum(ll.x()) r.setYMinimum(ll.y()) r.setXMaximum(ur.x()) r.setYMaximum(ur.y()) r.normalize() if (r.width() != 0 and r.height() != 0): self.canvas().setExtent(r) self.canvas().refresh() self._dragging = False if (self._zoomRubberBand is not None): self.canvas().scene().removeItem(self._zoomRubberBand) self._zoomRubberBand = None e.accept() def keyPressEvent(self, e): super(ArkMapToolInteractive, self).keyPressEvent(e) if (e.key() == Qt.Key_Escape): self.canvas().unsetMapTool(self) e.accept() def _snapCursorPoint(self, cursorPoint): res, snapResults = self._snapper.snapToBackgroundLayers(cursorPoint) if (res != 0 or len(snapResults) < 1): return self.toMapCoordinates(cursorPoint), False else: # Take a copy as QGIS will delete the result! snappedVertex = QgsPoint(snapResults[0].snappedVertex) return snappedVertex, True def _createSnappingMarker(self, snapPoint): if (self._snappingMarker is None): self._snappingMarker = QgsVertexMarker(self.canvas()) self._snappingMarker.setIconType(QgsVertexMarker.ICON_CROSS) self._snappingMarker.setColor(Qt.magenta) self._snappingMarker.setPenWidth(3) self._snappingMarker.setCenter(snapPoint) def _deleteSnappingMarker(self): if (self._snappingMarker is not None): self.canvas().scene().removeItem(self._snappingMarker) self._snappingMarker = None def _createSnappableMarkers(self): if (not self._showSnappableVertices or not self._snappingEnabled): return extent = self.canvas().extent() for vertex in self._snappableVertices.asMultiPoint(): if (extent.contains(vertex)): marker = QgsVertexMarker(self.canvas()) marker.setIconType(QgsVertexMarker.ICON_X) marker.setColor(Qt.gray) marker.setPenWidth(1) marker.setCenter(vertex) self._snappableMarkers.append(marker) def _deleteSnappableMarkers(self): for marker in self._snappableMarkers: self.canvas().scene().removeItem(marker) del self._snappableMarkers[:] def _layersChanged(self): if (not self._showSnappableVertices or not self._snappingEnabled): return self._buildSnappableLayers() self._deleteSnappableMarkers() self._createSnappableMarkers() def _redrawSnappableMarkers(self): if (not self._showSnappableVertices or not self._snappingEnabled): return self._deleteSnappableMarkers() self._createSnappableMarkers() def _buildSnappableLayers(self): if (not self._showSnappableVertices or not self._snappingEnabled): return vertices = [] for layer in self.canvas().layers(): ok, enabled, type, units, tolerance, avoid = QgsProject.instance().snapSettingsForLayer(layer.id()) if (ok and enabled and not layer.isEditable()): for feature in layer.getFeatures(): geometry = feature.geometry() if geometry is None: pass elif geometry.type() == QGis.Point: vertices.extend([geometry.asPoint()]) elif geometry.type() == QGis.Line: vertices.extend(geometry.asPolyline()) elif geometry.type() == QGis.Polygon: lines = geometry.asPolygon() for line in lines: vertices.extend(line) self._snappableVertices = QgsGeometry.fromMultiPoint(vertices) self._snappableVertices.simplify(0)
class SelectedFeatureByRectTasDraw(QgsMapTool): def __init__(self, canvas, distance): self.mCanvas = canvas QgsMapTool.__init__(self, canvas) self.mCursor = Qt.ArrowCursor self.mRubberBand = None self.mDragging = False self.mSelectRect = QRect() self.rubberBandLine = None self.distance = distance self.mSnapper = QgsMapCanvasSnapper(canvas) # QgsRubberBand* mRubberBand; # def reset(self): # self.startPoint = None # self.endPoint = None # self.isDrawing = False # SelectByRect.RubberRect.reset(QGis.Polygon) # self.layer = self.canvas.currentLayer() def canvasPressEvent(self, e): self.mSelectRect.setRect(0, 0, 0, 0) self.mRubberBand = QgsRubberBand(self.mCanvas, QGis.Polygon) self.startPoint, self.pointID, self.layer = self.snapPoint(e.pos()) # self.reset() # self.startPoint = self.toMapCoordinates(e.pos()) # self.isDrawing = True def canvasMoveEvent(self, e): if (e.buttons() != Qt.LeftButton): return if (not self.mDragging): self.mDragging = True self.mSelectRect.setTopLeft(e.pos()) self.mSelectRect.setBottomRight(e.pos()) QgsMapToolSelectUtils.setRubberBand(self.mCanvas, self.mSelectRect, self.mRubberBand) # if not self.isDrawing: # return # SelectByRect.RubberRect.reset(QGis.Polygon) # self.endPoint = self.toMapCoordinates(e.pos()) # self.rect = QgsRectangle(self.startPoint, self.endPoint) # SelectByRect.RubberRect.addGeometry(QgsGeometry.fromRect(self.rect), None) # SelectByRect.RubberRect.show() def canvasReleaseEvent(self, e): self.endPoint, self.pointID, self.layer = self.snapPoint(e.pos()) if len(define._newGeometryList) > 0: geom = define._newGeometryList[0] if geom.intersects(self.mRubberBand.asGeometry()): pointArray = geom.asPolyline() # pointArray1 = QgisHelper.offsetCurve(pointArray, 1200) if self.rubberBandLine != None: self.rubberBandLine.reset(QGis.Line) del self.rubberBandLine self.rubberBandLine = None self.rubberBandLine = QgsRubberBand(self.mCanvas, QGis.Line) self.rubberBandLine.setColor(Qt.blue) bearing = 0.0 if self.startPoint.y() >= self.endPoint.y() and ( math.fabs(self.startPoint.x() - self.endPoint.x()) < math.fabs(self.startPoint.y() - self.endPoint.y())): bearing = Unit.ConvertDegToRad(180) elif self.startPoint.x() >= self.endPoint.x() and ( math.fabs(self.startPoint.x() - self.endPoint.x()) > math.fabs(self.startPoint.y() - self.endPoint.y())): bearing = Unit.ConvertDegToRad(270) elif self.startPoint.x() < self.endPoint.x() and ( math.fabs(self.startPoint.x() - self.endPoint.x()) > math.fabs(self.startPoint.y() - self.endPoint.y())): bearing = Unit.ConvertDegToRad(90) else: bearing = 0.0 for point in pointArray: pt = MathHelper.distanceBearingPoint( Point3D(point.x(), point.y()), bearing, self.distance ) # MathHelper.getBearing(self.startPoint, self.endPoint), self.distance) self.rubberBandLine.addPoint(pt) gg = self.rubberBandLine.asGeometry() g = gg.asPolyline() # self.rubberBandLine.show() if (self.mRubberBand != None): self.mRubberBand.reset(QGis.Polygon) del self.mRubberBand self.mRubberBand = None self.mDragging = False self.emit( SIGNAL("resultSelectedFeatureByRectTasDraw"), gg, self.distance, bearing ) # MathHelper.getBearing(self.startPoint, self.endPoint)) return vlayer = QgsMapToolSelectUtils.getCurrentVectorLayer(self.mCanvas) if (vlayer == None): if (self.mRubberBand != None): self.mRubberBand.reset(QGis.Polygon) del self.mRubberBand self.mRubberBand = None self.mDragging = False return if (not self.mDragging): QgsMapToolSelectUtils.expandSelectRectangle( self.mSelectRect, vlayer, e.pos()) else: if (self.mSelectRect.width() == 1): self.mSelectRect.setLeft(self.mSelectRect.left() + 1) if (self.mSelectRect.height() == 1): self.mSelectRect.setBottom(self.mSelectRect.bottom() + 1) if (self.mRubberBand != None): QgsMapToolSelectUtils.setRubberBand(self.mCanvas, self.mSelectRect, self.mRubberBand) selectGeom = self.mRubberBand.asGeometry() # QgsMapToolSelectUtils.setSelectFeatures( self.mCanvas, selectGeom, e ) selectedFeatures = QgsMapToolSelectUtils.setSelectFeaturesOrRubberband_Tas_1( self.mCanvas, selectGeom, e) if len(selectedFeatures) > 0: geom = selectedFeatures[0].geometry() if geom.intersects(self.mRubberBand.asGeometry()): pointArray = geom.asPolyline() # pointArray1 = QgisHelper.offsetCurve(pointArray, 1200) if self.rubberBandLine != None: self.rubberBandLine.reset(QGis.Line) del self.rubberBandLine self.rubberBandLine = None self.rubberBandLine = QgsRubberBand( self.mCanvas, QGis.Line) self.rubberBandLine.setColor(Qt.blue) bearing = 0.0 gg = None if self.startPoint.y() >= self.endPoint.y() and ( math.fabs(self.startPoint.x() - self.endPoint.x()) < math.fabs(self.startPoint.y() - self.endPoint.y())): bearing = Unit.ConvertDegToRad(180) gg = self.newCreateLine(geom, self.distance, 180) elif self.startPoint.x() >= self.endPoint.x() and ( math.fabs(self.startPoint.x() - self.endPoint.x()) > math.fabs(self.startPoint.y() - self.endPoint.y())): bearing = Unit.ConvertDegToRad(270) gg = self.newCreateLine(geom, self.distance, 270) elif self.startPoint.x() < self.endPoint.x() and ( math.fabs(self.startPoint.x() - self.endPoint.x()) > math.fabs(self.startPoint.y() - self.endPoint.y())): bearing = Unit.ConvertDegToRad(90) gg = self.newCreateLine(geom, self.distance, 90) else: bearing = 0.0 gg = self.newCreateLine(geom, self.distance, 0) for point in pointArray: pt = MathHelper.distanceBearingPoint( Point3D(point.x(), point.y()), bearing, self.distance ) #MathHelper.getBearing(self.startPoint, self.endPoint), self.distance) self.rubberBandLine.addPoint(pt) # gg= self.newCreateLine(geom, -self.distance, 0) self.emit( SIGNAL("resultSelectedFeatureByRectTasDraw"), gg, self.distance, bearing ) #MathHelper.getBearing(self.startPoint, self.endPoint)) self.rubberBandLine.reset(QGis.Line) del selectGeom self.mRubberBand.reset(QGis.Polygon) del self.mRubberBand self.mRubberBand = None self.mDragging = False # self.canvasMoveEvent(e) # if self.layer != None: # self.layer.removeSelection() # if self.layer.crs().mapUnits() != self.canvas.mapUnits(): # if self.layer.crs().mapUnits == QGis.Meters: # lstPoint = QgisHelper.Degree2MeterList([self.startPoint, self.endPoint]) # else: # lstPoint = QgisHelper.Meter2DegreeList([self.startPoint, self.endPoint]) # rect = QgsRectangle(lstPoint[0], lstPoint[1]) # self.layer.select(rect, True) # else: # self.layer.select(self.rect, False) # else: # QMessageBox.warning(None, "Information", "Please select layer!") # self.reset() def snapPoint(self, p, bNone=False): if define._snapping == False: return ( define._canvas.getCoordinateTransform().toMapCoordinates(p), None, None) snappingResults = self.mSnapper.snapToBackgroundLayers(p) if (snappingResults[0] != 0 or len(snappingResults[1]) < 1): if bNone: return (None, None, None) else: return (define._canvas.getCoordinateTransform(). toMapCoordinates(p), None, None) else: return (snappingResults[1][0].snappedVertex, snappingResults[1][0].snappedAtGeometry, snappingResults[1][0].layer) def newCreateLine(self, geom, dist, angle): if define._units != QGis.Meters: dist = define._qgsDistanceArea.convertMeasurement( dist, QGis.Meters, QGis.Degrees, False)[0] g = geom.offsetCurve(dist, 0, 2, 2) pointArrayOld = geom.asPolyline() pointArrayNew = g.asPolyline() if MathHelper.calcDistance( pointArrayNew[0], pointArrayOld[0]) > MathHelper.calcDistance( pointArrayNew[0], pointArrayOld[len(pointArrayOld) - 1]): array = [] i = len(pointArrayNew) - 1 while i >= 0: array.append(pointArrayNew[i]) i -= 1 pointArrayNew = array if angle == 0: if pointArrayNew[0].y() < pointArrayOld[0].y(): g = geom.offsetCurve(-dist, 0, 2, 2) pointArrayNew = g.asPolyline() elif angle == 90: if pointArrayNew[0].x() < pointArrayOld[0].x(): g = geom.offsetCurve(-dist, 0, 2, 2) pointArrayNew = g.asPolyline() elif angle == 180: if pointArrayNew[0].y() > pointArrayOld[0].y(): g = geom.offsetCurve(-dist, 0, 2, 2) pointArrayNew = g.asPolyline() elif angle == 270: if pointArrayNew[0].x() > pointArrayOld[0].x(): g = geom.offsetCurve(-dist, 0, 2, 2) pointArrayNew = g.asPolyline() if MathHelper.calcDistance( pointArrayNew[0], pointArrayOld[0]) > MathHelper.calcDistance( pointArrayNew[0], pointArrayOld[len(pointArrayOld) - 1]): array = [] i = len(pointArrayNew) - 1 while i >= 0: array.append(pointArrayNew[i]) i -= 1 pointArrayNew = array i = 0 while i < len(pointArrayNew) - 1: if i == 0: i += 1 continue line = None if define._units == QGis.Meters: if angle == 0: line = QgsGeometry.fromPolyline([ pointArrayOld[0], QgsPoint(pointArrayOld[0].x(), 100000000) ]) elif angle == 90: line = QgsGeometry.fromPolyline([ pointArrayOld[0], QgsPoint(100000000, pointArrayOld[0].y()) ]) elif angle == 180: line = QgsGeometry.fromPolyline( [pointArrayOld[0], QgsPoint(pointArrayOld[0].x(), 0)]) elif angle == 270: line = QgsGeometry.fromPolyline( [pointArrayOld[0], QgsPoint(0, pointArrayOld[0].y())]) else: if angle == 0: line = QgsGeometry.fromPolyline([ pointArrayOld[0], QgsPoint(pointArrayOld[0].x(), pointArrayOld[0].y() + 0.1) ]) elif angle == 90: line = QgsGeometry.fromPolyline([ pointArrayOld[0], QgsPoint(pointArrayOld[0].x() + 0.1, pointArrayOld[0].y()) ]) elif angle == 180: line = QgsGeometry.fromPolyline([ pointArrayOld[0], QgsPoint(pointArrayOld[0].x(), pointArrayOld[0].y() - 0.1) ]) elif angle == 270: line = QgsGeometry.fromPolyline([ pointArrayOld[0], QgsPoint(pointArrayOld[0].x() - 0.1, pointArrayOld[0].y()) ]) lineNew = QgsGeometry.fromPolyline([ MathHelper.distanceBearingPoint( Point3D(pointArrayNew[i].x(), pointArrayNew[i].y()), MathHelper.getBearing(pointArrayNew[i], pointArrayNew[i - 1]), 100000), pointArrayNew[i] ]) if line.intersects(lineNew): pointGeom = line.intersection(lineNew) intersectPoint = pointGeom.asPoint() pointArrayNew.pop(i - 1) pointArrayNew.insert(i - 1, intersectPoint) break else: pointArrayNew.pop(i - 1) continue i += 1 i = len(pointArrayNew) - 1 while i > 1: line = None if define._units == QGis.Meters: if angle == 0: line = QgsGeometry.fromPolyline([ pointArrayOld[len(pointArrayOld) - 1], QgsPoint(pointArrayOld[len(pointArrayOld) - 1].x(), 100000000) ]) elif angle == 90: line = QgsGeometry.fromPolyline([ pointArrayOld[len(pointArrayOld) - 1], QgsPoint(100000000, pointArrayOld[len(pointArrayOld) - 1].y()) ]) elif angle == 180: line = QgsGeometry.fromPolyline([ pointArrayOld[len(pointArrayOld) - 1], QgsPoint(pointArrayOld[len(pointArrayOld) - 1].x(), 0) ]) elif angle == 270: line = QgsGeometry.fromPolyline([ pointArrayOld[len(pointArrayOld) - 1], QgsPoint(0, pointArrayOld[len(pointArrayOld) - 1].y()) ]) else: if angle == 0: line = QgsGeometry.fromPolyline([ pointArrayOld[len(pointArrayOld) - 1], QgsPoint( pointArrayOld[len(pointArrayOld) - 1].x(), pointArrayOld[len(pointArrayOld) - 1].y() + 0.1) ]) elif angle == 90: line = QgsGeometry.fromPolyline([ pointArrayOld[len(pointArrayOld) - 1], QgsPoint( pointArrayOld[len(pointArrayOld) - 1].x() + 0.1, pointArrayOld[len(pointArrayOld) - 1].y()) ]) elif angle == 180: line = QgsGeometry.fromPolyline([ pointArrayOld[len(pointArrayOld) - 1], QgsPoint( pointArrayOld[len(pointArrayOld) - 1].x(), pointArrayOld[len(pointArrayOld) - 1].y() - 0.1) ]) elif angle == 270: line = QgsGeometry.fromPolyline([ pointArrayOld[len(pointArrayOld) - 1], QgsPoint( pointArrayOld[len(pointArrayOld) - 1].x() - 0.1, pointArrayOld[len(pointArrayOld) - 1].y()) ]) # line = QgsGeometry.fromPolyline([pointArrayOld[len(pointArrayOld) - 1], QgsPoint(pointArrayOld[len(pointArrayOld) - 1].x(), 100000000)]) lineNew = QgsGeometry.fromPolyline([ MathHelper.distanceBearingPoint( Point3D(pointArrayNew[i].x(), pointArrayNew[i].y()), MathHelper.getBearing(pointArrayNew[i - 1], pointArrayNew[i]), 100000), pointArrayNew[i - 1] ]) if line.intersects(lineNew): pointGeom = line.intersection(lineNew) intersectPoint = pointGeom.asPoint() pointArrayNew.pop(i) pointArrayNew.insert(i, intersectPoint) break else: pointArrayNew.pop(i) i -= 1 continue i -= 1 return QgsGeometry.fromPolyline(pointArrayNew)
def click_button_snapping(self, point, btn): #@UnusedVariable # Disconnect mouse movement self.vertex_marker.hide() self.canvas.disconnect(self.canvas, SIGNAL("xyCoordinates(const QgsPoint&)"), self.mouse_move) if not self.layer_dimensions: return layer = self.layer_dimensions self.iface.setActiveLayer(layer) layer.startEditing() # TODO: node_group = [ "Junction", "Valve", "Reduction", "Tank", "Meter", "Manhole", "Source", "Hydrant", "Wtp", "Netsamplepoint", "Netelement", "Flexunion", "Expantank", "Netwjoin", "Register", "Pump", "Waterwell", "Filter" ] snapper = QgsMapCanvasSnapper(self.canvas) map_point = self.canvas.getCoordinateTransform().transform(point) x = map_point.x() y = map_point.y() event_point = QPoint(x, y) # Snapping (retval, result) = snapper.snapToBackgroundLayers( event_point) # @UnusedVariable # That's the snapped point if result <> []: # Check feature for snap_point in result: element_type = snap_point.layer.name() if element_type in node_group: feat_type = 'node' else: continue # Get the point point = QgsPoint(snap_point.snappedVertex) snapp_feature = next( snap_point.layer.getFeatures( QgsFeatureRequest().setFilterFid( snap_point.snappedAtGeometry))) element_id = snapp_feature.attribute(feat_type + '_id') # Leave selection snap_point.layer.select([snap_point.snappedAtGeometry]) # Get depth of the feature if self.project_type == 'ws': fieldname = "depth" elif self.project_type == 'ud' and feat_type == 'node': fieldname = "ymax" elif self.project_type == 'ud' and feat_type == 'connec': fieldname = "connec_depth" sql = "SELECT " + fieldname sql += " FROM " + self.schema_name + "." + feat_type sql += " WHERE " + feat_type + "_id = '" + element_id + "'" row = self.controller.get_row(sql) if not row: return utils_giswater.setText("depth", row[0]) utils_giswater.setText("feature_id", element_id) utils_giswater.setText("feature_type", element_type)
class Dimensions(ParentDialog): def __init__(self, dialog, layer, feature): """ Constructor class """ self.id = None super(Dimensions, self).__init__(dialog, layer, feature) self.init_config_form() if dialog.parent(): dialog.parent().setFixedSize(320, 410) def init_config_form(self): """ Custom form initial configuration """ # Set snapping self.canvas = self.iface.mapCanvas() self.emit_point = QgsMapToolEmitPoint(self.canvas) self.canvas.setMapTool(self.emit_point) self.snapper = QgsMapCanvasSnapper(self.canvas) # Vertex marker self.vertex_marker = QgsVertexMarker(self.canvas) self.vertex_marker.setColor(QColor(255, 100, 255)) self.vertex_marker.setIconSize(15) self.vertex_marker.setIconType(QgsVertexMarker.ICON_CROSS) self.vertex_marker.setPenWidth(3) btn_orientation = self.dialog.findChild(QPushButton, "btn_orientation") btn_orientation.clicked.connect(self.orientation) self.set_icon(btn_orientation, "133") btn_snapping = self.dialog.findChild(QPushButton, "btn_snapping") btn_snapping.clicked.connect(self.snapping) self.set_icon(btn_snapping, "129") # Set layers dimensions, node and connec self.layer_dimensions = self.controller.get_layer_by_tablename( "v_edit_dimensions") self.layer_node = self.controller.get_layer_by_tablename("v_edit_node") self.layer_connec = self.controller.get_layer_by_tablename( "v_edit_connec") self.create_map_tips() def orientation(self): # Disconnect previous snapping QObject.disconnect( self.emit_point, SIGNAL("canvasClicked(const QgsPoint &, Qt::MouseButton)"), self.click_button_snapping) self.emit_point.canvasClicked.connect(self.click_button_orientation) def snapping(self): # Set active layer and set signals self.iface.setActiveLayer(self.layer_node) QObject.disconnect( self.emit_point, SIGNAL("canvasClicked(const QgsPoint &, Qt::MouseButton)"), self.click_button_orientation) self.canvas.xyCoordinates.connect(self.mouse_move) QObject.connect( self.emit_point, SIGNAL("canvasClicked(const QgsPoint &, Qt::MouseButton)"), self.click_button_snapping) def mouse_move(self, p): self.vertex_marker.hide() map_point = self.canvas.getCoordinateTransform().transform(p) x = map_point.x() y = map_point.y() eventPoint = QPoint(x, y) # Snapping (retval, result) = self.snapper.snapToBackgroundLayers( eventPoint) # @UnusedVariable # That's the snapped point if result: # Check feature for snapped_point in result: if snapped_point.layer == self.layer_node or snapped_point.layer == self.layer_connec: point = QgsPoint(snapped_point.snappedVertex) # Add marker self.vertex_marker.setCenter(point) self.vertex_marker.show() def click_button_orientation(self, point): # @UnusedVariable if not self.layer_dimensions: return self.x_symbol = self.dialog.findChild(QLineEdit, "x_symbol") self.x_symbol.setText(str(point.x())) self.y_symbol = self.dialog.findChild(QLineEdit, "y_symbol") self.y_symbol.setText(str(point.y())) def click_button_snapping(self, point, btn): # @UnusedVariable if not self.layer_dimensions: return layer = self.layer_dimensions self.iface.setActiveLayer(layer) layer.startEditing() snapper = QgsMapCanvasSnapper(self.canvas) map_point = self.canvas.getCoordinateTransform().transform(point) x = map_point.x() y = map_point.y() event_point = QPoint(x, y) # Snapping (retval, result) = snapper.snapToBackgroundLayers( event_point) # @UnusedVariable # That's the snapped point if result: # Check feature for snapped_point in result: if snapped_point.layer == self.layer_node: feat_type = 'node' elif snapped_point.layer == self.layer_connec: feat_type = 'connec' else: continue # Get the point point = QgsPoint(snapped_point.snappedVertex) snapp_feature = next( snapped_point.layer.getFeatures( QgsFeatureRequest().setFilterFid( snapped_point.snappedAtGeometry))) element_id = snapp_feature.attribute(feat_type + '_id') # Leave selection snapped_point.layer.select([snapped_point.snappedAtGeometry]) # Get depth of the feature if self.project_type == 'ws': fieldname = "depth" elif self.project_type == 'ud' and feat_type == 'node': fieldname = "ymax" elif self.project_type == 'ud' and feat_type == 'connec': fieldname = "connec_depth" sql = ("SELECT " + fieldname + "" " FROM " + self.schema_name + "." + feat_type + "" " WHERE " + feat_type + "_id = '" + element_id + "'") row = self.controller.get_row(sql) if not row: return utils_giswater.setText("depth", row[0]) utils_giswater.setText("feature_id", element_id) utils_giswater.setText("feature_type", feat_type.upper()) def create_map_tips(self): """ Create MapTips on the map """ sql = ("SELECT value FROM " + self.schema_name + ".config_param_user" " WHERE cur_user = current_user AND parameter = 'dim_tooltip'") row = self.controller.get_row(sql) if not row: return if row[0].lower() != 'true': return self.timer_map_tips = QTimer(self.canvas) self.map_tip_node = QgsMapTip() self.map_tip_connec = QgsMapTip() self.canvas.connect(self.canvas, SIGNAL("xyCoordinates(const QgsPoint&)"), self.map_tip_changed) self.canvas.connect(self.timer_map_tips, SIGNAL("timeout()"), self.show_map_tip) self.timer_map_tips_clear = QTimer(self.canvas) self.canvas.connect(self.timer_map_tips_clear, SIGNAL("timeout()"), self.clear_map_tip) def map_tip_changed(self, p): """ SLOT. Initialize the Timer to show MapTips on the map """ if self.canvas.underMouse(): self.last_map_position = QgsPoint(p.x(), p.y()) self.map_tip_node.clear(self.canvas) self.map_tip_connec.clear(self.canvas) self.timer_map_tips.start(100) def show_map_tip(self): """ Show MapTips on the map """ self.timer_map_tips.stop() if self.canvas.underMouse(): point_qgs = self.last_map_position point_qt = self.canvas.mouseLastXY() if self.layer_node: self.map_tip_node.showMapTip(self.layer_node, point_qgs, point_qt, self.canvas) if self.layer_connec: self.map_tip_connec.showMapTip(self.layer_connec, point_qgs, point_qt, self.canvas) self.timer_map_tips_clear.start(1000) def clear_map_tip(self): """ Clear MapTips """ self.timer_map_tips_clear.stop() self.map_tip_node.clear(self.canvas) self.map_tip_connec.clear(self.canvas) def reject_dialog(self): """ Reject dialog without saving """ self.set_action_identify() try: self.canvas.xyCoordinates.disconnect() self.canvas.timeout.disconnect() except Exception: pass def save(self): """ Save feature """ # General save self.dialog.save() self.iface.actionSaveEdits().trigger() self.reject_dialog()
class LineMapTool(QgsMapTool): def __init__(self, iface, settings, action, index_action): ''' Class constructor ''' self.iface = iface self.canvas = self.iface.mapCanvas() self.settings = settings self.index_action = index_action self.elem_type_type = self.settings.value('insert_values/'+str(index_action)+'_elem_type_type') QgsMapTool.__init__(self, self.canvas) self.setAction(action) # Set rubber band features self.rubberBand = QgsRubberBand(self.canvas, QGis.Line) mFillColor = QColor(255, 0, 0); self.rubberBand.setColor(mFillColor) self.rubberBand.setWidth(2) self.reset() # Vertex marker self.vertexMarker = QgsVertexMarker(self.canvas) self.vertexMarker.setColor(QColor(0, 255, 0)) self.vertexMarker.setIconSize(9) self.vertexMarker.setIconType(QgsVertexMarker.ICON_BOX) # or ICON_CROSS, ICON_X self.vertexMarker.setPenWidth(5) # Snapper self.snapper = QgsMapCanvasSnapper(self.canvas) # Control button state self.mCtrl = False self.started = False # Tracing options self.firstTimeOnSegment = True self.lastPointMustStay = False self.lastPoint = None # Change map tool cursor self.cursor = QCursor() self.cursor.setShape(Qt.CrossCursor) self.parent().setCursor(self.cursor) def keyPressEvent(self, event): ''' We need to know, if ctrl-key is pressed ''' if event.key() == Qt.Key_Control: self.mCtrl = True def keyReleaseEvent(self, event): ''' Ctrl-key is released ''' if event.key() == Qt.Key_Control: self.mCtrl = False # Remove the last added point when the delete key is pressed if event.key() == Qt.Key_Backspace: self.rubberBand.removeLastPoint() def reset(self): self.start_point = self.end_point = None self.isEmittingPoint = False self.rubberBand.reset(QGis.Line) ''' QgsMapTools inherited event functions ''' def canvasPressEvent(self, event): ''' On left click, we add a point ''' if event.button() == 1: # layer = self.canvas.currentLayer() layer = self.iface.activeLayer() # Declare, that are we going to work self.started = True if layer <> None: x = event.pos().x() y = event.pos().y() selPoint = QPoint(x,y) # Check something snapped (retval,result) = self.snapper.snapToBackgroundLayers(selPoint) #@UnusedVariable # The point we want to have, is either from snapping result if result <> []: point = result[0].snappedVertex # If we snapped something, it's either a vertex if result[0].snappedVertexNr <> -1: self.firstTimeOnSegment = True # Or a point on a segment, so we have to declare, that a point on segment is found else: self.firstTimeOnSegment = False # Or its some point from out in the wild else: point = QgsMapToPixel.toMapCoordinates(self.canvas.getCoordinateTransform(), x, y) self.firstTimeOnSegment = True # Bring the rubberband to the cursor i.e. the clicked point self.rubberBand.movePoint(point) # Set a new point to go on with self.appendPoint(point) # Try to remember that this point was on purpose i.e. clicked by the user self.lastPointMustStay = True self.firstTimeOnSegment = True def canvasMoveEvent(self, event): # Hide highlight self.vertexMarker.hide() # Get the click x = event.pos().x() y = event.pos().y() eventPoint = QPoint(x,y) # Snapping (retval,result) = self.snapper.snapToBackgroundLayers(eventPoint) #@UnusedVariable # That's the snapped point if result <> []: point = QgsPoint(result[0].snappedVertex) # Add marker self.vertexMarker.setCenter(point) self.vertexMarker.show() # Check tracing if self.started: # Only if the ctrl key is pressed if self.mCtrl == True: # So if we have found a snapping if result <> []: # If it is a vertex, not a point on a segment if result[0].snappedVertexNr <> -1: self.rubberBand.movePoint(point) self.appendPoint(point) self.lastPointMustStay = True # The next point found, may be on a segment self.firstTimeOnSegment = True # We are on a segment else: self.rubberBand.movePoint(point) # If we are on a new segment, we add the point in any case if self.firstTimeOnSegment: self.appendPoint(point) self.lastPointMustStay = True self.firstTimeOnSegment = False # if we are not on a new segment, we have to test, if this point is really needed else: # but only if we have already enough points if self.rubberBand.numberOfVertices() >=3: num_vertexs = self.rubberBand.numberOfVertices() lastRbP = self.rubberBand.getPoint(0, num_vertexs-2) nextToLastRbP = self.rubberBand.getPoint(0, num_vertexs-3) if not self.pointOnLine(lastRbP, nextToLastRbP, QgsPoint(point)): self.appendPoint(point) self.lastPointMustStay = False else: if not self.lastPointMustStay: self.rubberBand.removeLastPoint() self.rubberBand.movePoint(point) else: self.appendPoint(point) self.lastPointMustStay = False self.firstTimeOnSegment = False else: #if nothing specials happens, just update the rubberband to the cursor position point = QgsMapToPixel.toMapCoordinates(self.canvas.getCoordinateTransform (), x, y) self.rubberBand.movePoint(point) else: ''' In "not-tracing" state, just update the rubberband to the cursor position but we have still to snap to act like the "normal" digitize tool ''' if result <> []: point = QgsPoint(result[0].snappedVertex) # Add marker self.vertexMarker.setCenter(point) self.vertexMarker.show() else: point = QgsMapToPixel.toMapCoordinates(self.canvas.getCoordinateTransform(), x, y) self.rubberBand.movePoint(point) def canvasReleaseEvent(self, event): ''' With right click the digitizing is finished ''' if event.button() == 2: # layer = self.canvas.currentLayer() layer = self.iface.activeLayer() x = event.pos().x() y = event.pos().y() if layer <> None and self.started == True: selPoint = QPoint(x,y) (retval,result) = self.snapper.snapToBackgroundLayers(selPoint) #@UnusedVariable if result <> []: point = result[0].snappedVertex #@UnusedVariable else: point = QgsMapToPixel.toMapCoordinates(self.canvas.getCoordinateTransform(), x, y) #@UnusedVariable self.sendGeometry() def appendPoint(self, point): ''' Don't add the point if it is identical to the last point we added ''' if not (self.lastPoint == point) : self.rubberBand.addPoint(point) self.lastPoint = QgsPoint(point) else: pass def sendGeometry(self): #layer = self.canvas.currentLayer() layer = self.iface.activeLayer() coords = [] self.rubberBand.removeLastPoint() if QGis.QGIS_VERSION_INT >= 10700: [coords.append(self.rubberBand.getPoint(0, i)) for i in range(self.rubberBand.numberOfVertices())] else: [coords.append(self.rubberBand.getPoint(0,i)) for i in range(1,self.rubberBand.numberOfVertices())] # On the Fly reprojection, not necessary any more, mapToLayerCoordinates is clever enough on its own #layerEPSG = layer.srs().epsg() #projectEPSG = self.canvas.mapRenderer().destinationSrs().epsg() #if layerEPSG != projectEPSG: coords_tmp = coords[:] coords = [] for point in coords_tmp: transformedPoint = self.canvas.mapRenderer().mapToLayerCoordinates( layer, point ); coords.append(transformedPoint) # Filter duplicated points coords_tmp = coords[:] coords = [] lastPt = None for pt in coords_tmp: if (lastPt <> pt) : coords.append(pt) lastPt = pt # Add geometry to feature. g = QgsGeometry().fromPolyline(coords) self.rubberBand.reset(QGis.Line) self.started = False # Write the feature self.createFeature(g) def createFeature(self, geom): # layer = self.canvas.currentLayer() layer = self.iface.activeLayer() provider = layer.dataProvider() f = QgsFeature() if (geom.isGeosValid()): f.setGeometry(geom) else: reply = QMessageBox.question(self.iface.mainWindow(), 'Feature not valid', "The geometry of the feature you just added isn't valid. Do you want to use it anyway?", QMessageBox.Yes, QMessageBox.No) if reply == QMessageBox.Yes: f.setGeometry(geom) else: return False # Add attribute fields to feature. fields = layer.pendingFields() try: #API-Break 1.8 vs. 2.0 handling attr = f.initAttributes(len(fields)) #@UnusedVariable for i in range(len(fields)): f.setAttribute(i, provider.defaultValue(i)) except AttributeError: #<=1.8 # Add attributefields to feature. for i in fields: f.addAttribute(i, provider.defaultValue(i)) idx = layer.fieldNameIndex('epa_type') f[idx] = self.elem_type_type # Upload changes layer.startEditing() layer.addFeature(f) # Control PostgreSQL exceptions boolOk = layer.commitChanges() # Update canvas self.canvas.refresh() # Capture edit exception if boolOk: # Spatial query to retrieve last added line, start searchingcandidates cands = layer.getFeatures(QgsFeatureRequest().setFilterRect(f.geometry().boundingBox())) # Iterate on candidates for line_feature in cands: if line_feature.geometry().equals(f.geometry()): # Highlight layer.setSelectedFeatures([line_feature.id()]) # Open form self.iface.openFeatureForm(layer, line_feature) break else: # Delete layer.rollBack() # User error msg = "Error adding PIPE: Typically this occurs if\n the first point is not located in a existing\n node or feature is out of the defined sectors." QMessageBox.information(None, "PostgreSQL error:", msg) def activate(self): self.canvas.setCursor(self.cursor) def deactivate(self): try: self.rubberBand.reset(QGis.Line) except AttributeError: pass
def click_button_add(self, layer_view, tablename, table_view, elem_type, point, button): """ :param layer_view: it is the view we are using :param tablename: Is the name of the table that we will use to make the SELECT and INSERT :param table_view: it's QTableView we are using, need ir for upgrade his own view :param elem_type: Used to buy the object that we "click" with the type of object we want to add or delete :param point: param inherited from signal canvasClicked :param button: param inherited from signal canvasClicked """ if button == Qt.LeftButton: node_group = ["Junction", "Valve", "Reduction", "Tank", "Meter", "Manhole", "Source", "Hydrant"] arc_group = ["Pipe"] canvas = self.iface.mapCanvas() snapper = QgsMapCanvasSnapper(canvas) map_point = canvas.getCoordinateTransform().transform(point) x = map_point.x() y = map_point.y() event_point = QPoint(x, y) # Snapping (retval, result) = snapper.snapToBackgroundLayers(event_point) # @UnusedVariable # That's the snapped point if result: # Check feature for snapped_feat in result: element_type = snapped_feat.layer.name() feat_type = None if element_type in node_group: feat_type = 'node' elif element_type in arc_group: feat_type = 'arc' if feat_type is not None: # Get the point feature = next(snapped_feat.layer.getFeatures(QgsFeatureRequest().setFilterFid(snapped_feat.snappedAtGeometry))) element_id = feature.attribute(feat_type + '_id') # LEAVE SELECTION snapped_feat.layer.select([snapped_feat.snappedAtGeometry]) # Get depth of feature if feat_type == elem_type: sql = "SELECT * FROM " + self.schema_name + "." + tablename sql += " WHERE " + feat_type+"_id = '" + element_id+"' AND psector_id = '" + self.psector_id.text() + "'" row = self.dao.get_row(sql) if not row: self.list_elemets[element_id] = feat_type else: message = "This id already exists" self.controller.show_info(message) else: message = self.tr("You are trying to introduce")+" "+feat_type+" "+self.tr("in a")+" "+elem_type self.controller.show_info(message) elif button == Qt.RightButton: for element_id, feat_type in self.list_elemets.items(): sql = "INSERT INTO " + self.schema_name + "." + tablename + "(" + feat_type + "_id, psector_id)" sql += "VALUES (" + element_id + ", " + self.psector_id.text() + ")" self.controller.execute_sql(sql) table_view.model().select() self.emit_point.canvasClicked.disconnect() self.list_elemets.clear() self.dlg.btn_add_arc_plan.setText('Add') self.dlg.btn_add_node_plan.setText('Add')
class MultipleSelection(QgsMapTool): canvasClicked = pyqtSignal() def __init__(self, iface, controller, layers, mincut=None, parent_manage=None, table_object=None): """ Class constructor """ self.layers = layers self.iface = iface self.canvas = self.iface.mapCanvas() self.mincut = mincut self.parent_manage = parent_manage self.table_object = table_object # Call superclass constructor and set current action QgsMapTool.__init__(self, self.canvas) self.controller = controller self.rubber_band = QgsRubberBand(self.canvas, QGis.Polygon) self.rubber_band.setColor(QColor(255, 100, 255)) self.rubber_band.setFillColor(QColor(254, 178, 76, 63)) self.rubber_band.setWidth(1) self.reset() self.snapper = QgsMapCanvasSnapper(self.canvas) self.selected_features = [] def reset(self): self.start_point = self.end_point = None self.is_emitting_point = False self.rubber_band.reset(QGis.Polygon) def canvasPressEvent(self, e): if e.button() == Qt.LeftButton: self.start_point = self.toMapCoordinates(e.pos()) self.end_point = self.start_point self.is_emitting_point = True self.show_rect(self.start_point, self.end_point) def canvasReleaseEvent(self, e): self.is_emitting_point = False rectangle = self.get_rectangle() selected_rectangle = None key = QApplication.keyboardModifiers() if e.button() != Qt.LeftButton: self.rubber_band.hide() return # Disconnect signal to enhance process # We will reconnect it when processing last layer of the group if self.mincut: self.mincut.disconnect_signal_selection_changed() if self.parent_manage: self.parent_manage.disconnect_signal_selection_changed() for i in range(len(self.layers)): layer = self.layers[i] if (i == len(self.layers) - 1): if self.mincut: self.mincut.connect_signal_selection_changed( "mincut_connec") if self.parent_manage: self.parent_manage.connect_signal_selection_changed( self.table_object) # Selection by rectangle if rectangle: if selected_rectangle is None: selected_rectangle = self.canvas.mapSettings( ).mapToLayerCoordinates(layer, rectangle) # If Ctrl+Shift pressed: remove features from selection if key == (Qt.ControlModifier | Qt.ShiftModifier): layer.selectByRect(selected_rectangle, layer.RemoveFromSelection) # If Ctrl pressed: add features to selection elif key == Qt.ControlModifier: layer.selectByRect(selected_rectangle, layer.AddToSelection) # If Ctrl not pressed: add features to selection else: layer.selectByRect(selected_rectangle, layer.AddToSelection) # Selection one by one else: x = e.pos().x() y = e.pos().y() eventPoint = QPoint(x, y) (retval, result) = self.snapper.snapToBackgroundLayers( eventPoint) #@UnusedVariable if result: # Check feature for snap_point in result: # Get the point. Leave selection #point = QgsPoint(snap_point.snappedVertex) snapp_feat = next( snap_point.layer.getFeatures( QgsFeatureRequest().setFilterFid( snap_point.snappedAtGeometry))) snap_point.layer.select([snap_point.snappedAtGeometry]) self.rubber_band.hide() def canvasMoveEvent(self, e): if not self.is_emitting_point: return self.end_point = self.toMapCoordinates(e.pos()) self.show_rect(self.start_point, self.end_point) def show_rect(self, start_point, end_point): self.rubber_band.reset(QGis.Polygon) if start_point.x() == end_point.x() or start_point.y() == end_point.y( ): return point1 = QgsPoint(start_point.x(), start_point.y()) point2 = QgsPoint(start_point.x(), end_point.y()) point3 = QgsPoint(end_point.x(), end_point.y()) point4 = QgsPoint(end_point.x(), start_point.y()) self.rubber_band.addPoint(point1, False) self.rubber_band.addPoint(point2, False) self.rubber_band.addPoint(point3, False) self.rubber_band.addPoint(point4, True) self.rubber_band.show() def get_rectangle(self): if self.start_point is None or self.end_point is None: return None elif self.start_point.x() == self.end_point.x() or self.start_point.y( ) == self.end_point.y(): return None return QgsRectangle(self.start_point, self.end_point) def deactivate(self): self.rubber_band.hide() QgsMapTool.deactivate(self) def activate(self): pass
class MultipleSnapping(QgsMapTool): canvasClicked = pyqtSignal() def __init__(self, iface, controller, group): """ Class constructor """ self.group_layers = group self.iface = iface self.canvas = self.iface.mapCanvas() # Call superclass constructor and set current action QgsMapTool.__init__(self, self.canvas) self.controller = controller self.rubber_band = QgsRubberBand(self.canvas, QGis.Polygon) mFillColor = QColor(254, 178, 76, 63) self.rubber_band.setColor(mFillColor) self.rubber_band.setWidth(1) self.reset() self.snapper = QgsMapCanvasSnapper(self.canvas) self.selected_features = [] # Vertex marker self.vertex_marker = QgsVertexMarker(self.canvas) self.vertex_marker.setColor(QColor(255, 0, 255)) self.vertex_marker.setIconSize(11) self.vertex_marker.setIconType( QgsVertexMarker.ICON_CROSS) # or ICON_CROSS, ICON_X, ICON_BOX self.vertex_marker.setPenWidth(3) def reset(self): self.start_point = self.end_point = None self.is_emitting_point = False self.rubber_band.reset(QGis.Polygon) def canvasPressEvent(self, e): if e.button() == Qt.LeftButton: self.start_point = self.toMapCoordinates(e.pos()) self.end_point = self.start_point self.is_emitting_point = True self.show_rect(self.start_point, self.end_point) def canvasReleaseEvent(self, e): self.is_emitting_point = False r = self.rectangle() # Use CTRL button to unselect features key = QApplication.keyboardModifiers() number_features = 0 if e.button() == Qt.LeftButton: for layer in self.group_pointers: # Check number of selections #number_features = layer.selectedFeatureCount() if r is not None: # Selection by rectange lRect = self.canvas.mapSettings().mapToLayerCoordinates( layer, r) layer.select(lRect, True) # True for leave previous selection # if CTRL pressed : unselect features if key == Qt.ControlModifier: layer.selectByRect(lRect, layer.RemoveFromSelection) else: # Selection one by one x = e.pos().x() y = e.pos().y() eventPoint = QPoint(x, y) (retval, result) = self.snapper.snapToBackgroundLayers(eventPoint) if result: # Check feature for snap_point in result: # Get the point #point = QgsPoint(snap_point.snappedVertex) snapp_feat = next( snap_point.layer.getFeatures( QgsFeatureRequest().setFilterFid( snap_point.snappedAtGeometry))) # LEAVE SELECTION snap_point.layer.select( [snap_point.snappedAtGeometry]) self.rubber_band.hide() def canvasMoveEvent(self, e): if not self.is_emitting_point: return self.end_point = self.toMapCoordinates(e.pos()) self.show_rect(self.start_point, self.end_point) def show_rect(self, start_point, end_point): self.rubber_band.reset(QGis.Polygon) if start_point.x() == end_point.x() or start_point.y() == end_point.y( ): return point1 = QgsPoint(start_point.x(), start_point.y()) point2 = QgsPoint(start_point.x(), end_point.y()) point3 = QgsPoint(end_point.x(), end_point.y()) point4 = QgsPoint(end_point.x(), start_point.y()) self.rubber_band.addPoint(point1, False) self.rubber_band.addPoint(point2, False) self.rubber_band.addPoint(point3, False) self.rubber_band.addPoint(point4, True) # true to update canvas self.rubber_band.show() def rectangle(self): if self.start_point is None or self.end_point is None: return None elif self.start_point.x() == self.end_point.x() or self.start_point.y( ) == self.end_point.y(): return None return QgsRectangle(self.start_point, self.end_point) def deactivate(self): self.rubber_band.hide() QgsMapTool.deactivate(self) def activate(self): self.group_layers = ["Wjoin", "Fountain", "Greentap", "Tap"] self.group_pointers = [] for layer_name in self.group_layers: layer = QgsMapLayerRegistry.instance().mapLayersByName(layer_name) if layer: layer = layer[0] self.group_pointers.append(layer) # Set active layer self.layer_connec = None self.layer_connec = QgsMapLayerRegistry.instance().mapLayersByName( "Edit connec")[0] self.iface.setActiveLayer(self.layer_connec) self.canvas.connect(self.canvas, SIGNAL("xyCoordinates(const QgsPoint&)"), self.mouse_move) def mouse_move(self, p): map_point = self.canvas.getCoordinateTransform().transform(p) x = map_point.x() y = map_point.y() event_point = QPoint(x, y) # Snapping (retval, result) = self.snapper.snapToCurrentLayer(event_point, 2) # @UnusedVariable # That's the snapped point if result: # Check feature for snapPoint in result: #self.controller.log_info(str(snapPoint)) if snapPoint.layer.name() == 'Edit connec': point = QgsPoint(snapPoint.snappedVertex) # Add marker self.vertex_marker.setCenter(point) self.vertex_marker.show() else: self.vertex_marker.hide()
class ManNodeDialog(ParentDialog): def __init__(self, dialog, layer, feature): """ Constructor class """ self.geom_type = "node" self.field_id = "node_id" self.id = utils_giswater.getWidgetText(self.field_id, False) super(ManNodeDialog, self).__init__(dialog, layer, feature) self.init_config_form() self.controller.manage_translation('ud_man_node', dialog) if dialog.parent(): dialog.parent().setFixedSize(625, 660) def init_config_form(self): """ Custom form initial configuration """ # Define class variables self.filter = self.field_id + " = '" + str(self.id) + "'" # Get widget controls self.tab_main = self.dialog.findChild(QTabWidget, "tab_main") self.tbl_element = self.dialog.findChild(QTableView, "tbl_element") self.tbl_document = self.dialog.findChild(QTableView, "tbl_document") self.tbl_event_element = self.dialog.findChild(QTableView, "tbl_event_element") self.tbl_event = self.dialog.findChild(QTableView, "tbl_event_node") self.tbl_scada = self.dialog.findChild(QTableView, "tbl_scada") self.tbl_scada_value = self.dialog.findChild(QTableView, "tbl_scada_value") self.tbl_costs = self.dialog.findChild(QTableView, "tbl_masterplan") self.nodecat_id = self.dialog.findChild(QLineEdit, 'nodecat_id') self.node_type = self.dialog.findChild(QComboBox, 'node_type') state_type = self.dialog.findChild(QComboBox, 'state_type') dma_id = self.dialog.findChild(QComboBox, 'dma_id') # Tables self.tbl_upstream = self.dialog.findChild(QTableView, "tbl_upstream") self.tbl_upstream.setSelectionBehavior(QAbstractItemView.SelectRows) self.tbl_downstream = self.dialog.findChild(QTableView, "tbl_downstream") self.tbl_downstream.setSelectionBehavior(QAbstractItemView.SelectRows) self.dialog.findChild(QPushButton, "btn_catalog").clicked.connect( partial(self.catalog, 'ud', 'node')) self.tbl_upstream.doubleClicked.connect( partial(self.open_up_down_stream, self.tbl_upstream)) self.tbl_downstream.doubleClicked.connect( partial(self.open_up_down_stream, self.tbl_downstream)) feature = self.feature layer = self.iface.activeLayer() # Toolbar actions action = self.dialog.findChild(QAction, "actionEnabled") action.setChecked(layer.isEditable()) self.dialog.findChild(QAction, "actionCopyPaste").setEnabled(layer.isEditable()) self.dialog.findChild(QAction, "actionRotation").setEnabled(layer.isEditable()) self.dialog.findChild(QAction, "actionZoom").triggered.connect( partial(self.action_zoom_in, feature, self.canvas, layer)) self.dialog.findChild(QAction, "actionCentered").triggered.connect( partial(self.action_centered, feature, self.canvas, layer)) self.dialog.findChild(QAction, "actionEnabled").triggered.connect( partial(self.action_enabled, action, layer)) self.dialog.findChild(QAction, "actionZoomOut").triggered.connect( partial(self.action_zoom_out, feature, self.canvas, layer)) self.dialog.findChild(QAction, "actionRotation").triggered.connect( self.action_rotation) self.dialog.findChild(QAction, "actionCopyPaste").triggered.connect( partial(self.action_copy_paste, self.geom_type)) self.dialog.findChild(QAction, "actionLink").triggered.connect( partial(self.check_link, True)) self.dialog.findChild(QAction, "actionHelp").triggered.connect( partial(self.action_help, 'ud', 'node')) # Manage custom fields cat_feature_id = utils_giswater.getWidgetText(self.node_type) tab_custom_fields = 1 self.manage_custom_fields(cat_feature_id, tab_custom_fields) # Manage tab 'Scada' self.manage_tab_scada() # Check if exist URL from field 'link' in main tab self.check_link() # Check topology for new features continue_insert = True node_over_node = True check_topology_node = self.controller.plugin_settings_value( "check_topology_node", "0") check_topology_arc = self.controller.plugin_settings_value( "check_topology_arc", "0") # Check if feature has geometry object geometry = self.feature.geometry() if geometry: self.controller.log_info("check") if self.id.upper() == 'NULL' and check_topology_node == "0": self.get_topology_parameters() (continue_insert, node_over_node) = self.check_topology_node() if continue_insert and not node_over_node: if self.id.upper() == 'NULL' and check_topology_arc == "0": self.check_topology_arc() # Create thread thread1 = Thread(self, self.controller, 3) thread1.start() self.filter = "node_id = '" + str(self.id) + "'" table_name = self.controller.schema_name + ".v_ui_node_x_connection_upstream" self.fill_table(self.tbl_upstream, table_name, self.filter) self.set_configuration(self.tbl_upstream, "v_ui_node_x_connection_upstream") table_name = self.controller.schema_name + ".v_ui_node_x_connection_downstream" self.fill_table(self.tbl_downstream, table_name, self.filter) self.set_configuration(self.tbl_downstream, "v_ui_node_x_connection_downstream") # Manage tab signal self.tab_connections_loaded = False self.tab_element_loaded = False self.tab_document_loaded = False self.tab_om_loaded = False self.tab_scada_loaded = False self.tab_cost_loaded = False self.tab_main.currentChanged.connect(self.tab_activation) # Load default settings widget_id = self.dialog.findChild(QLineEdit, 'node_id') if utils_giswater.getWidgetText(widget_id).lower() == 'null': self.load_default() self.load_type_default("nodecat_id", "nodecat_vdefault") self.load_state_type(state_type, self.geom_type) self.load_dma(dma_id, self.geom_type) def open_up_down_stream(self, qtable): """ Open selected node from @qtable """ selected_list = qtable.selectionModel().selectedRows() if len(selected_list) == 0: message = "Any record selected" self.controller.show_warning(message) return row = selected_list[0].row() feature_id = qtable.model().record(row).value("feature_id") featurecat_id = qtable.model().record(row).value("featurecat_id") # Get sys_feature_cat.id from cat_feature.id sql = ("SELECT sys_feature_cat.id FROM " + self.controller.schema_name + ".cat_feature" " INNER JOIN " + self.controller.schema_name + ".sys_feature_cat ON cat_feature.system_id = sys_feature_cat.id" " WHERE cat_feature.id = '" + featurecat_id + "'") row = self.controller.get_row(sql) if not row: return layer = self.get_layer(row[0]) if layer: field_id = self.controller.get_layer_primary_key(layer) aux = "\"" + field_id + "\" = " aux += "'" + str(feature_id) + "'" expr = QgsExpression(aux) if expr.hasParserError(): message = "Expression Error" self.controller.show_warning( message, parameter=expr.parserErrorString()) return it = layer.getFeatures(QgsFeatureRequest(expr)) features = [i for i in it] if features != []: self.iface.openFeatureForm(layer, features[0]) else: message = "Layer not found" self.controller.show_warning(message, parameter=row[0]) def get_topology_parameters(self): """ Get parameters 'node_proximity' and 'node2arc' from config table """ self.node_proximity = 0.5 self.node2arc = 0.5 sql = "SELECT node_proximity, node2arc FROM " + self.schema_name + ".config" row = self.controller.get_row(sql) if row: self.node_proximity = row['node_proximity'] self.node2arc = row['node2arc'] def check_topology_arc(self): """ Check topology: Inserted node is over an existing arc? """ # Initialize plugin parameters self.controller.plugin_settings_set_value("check_topology_arc", "0") self.controller.plugin_settings_set_value("close_dlg", "0") # Get selected srid and coordinates. Set SQL to check topology srid = self.controller.plugin_settings_value('srid') point = self.feature.geometry().asPoint() node_geom = "ST_SetSRID(ST_Point(" + str(point.x()) + ", " + str( point.y()) + "), " + str(srid) + ")" sql = ("SELECT arc_id, state FROM " + self.schema_name + ".v_edit_arc" " WHERE ST_DWithin(" + node_geom + ", v_edit_arc.the_geom, " + str(self.node2arc) + ")" " ORDER BY ST_Distance(v_edit_arc.the_geom, " + node_geom + ")" " LIMIT 1") row = self.controller.get_row(sql) if row: msg = ( "We have detected you are trying to divide an arc with state " + str(row['state']) + "" "\nRemember that:" "\n\nIn case of arc has state 0, you are allowed to insert a new node, because state 0 has not topology rules, and as a result arc will not be broken." "\nIn case of arc has state 1, only nodes with state=1 can be part of node1 or node2 from arc. If the new node has state 0 or state 2 arc will be broken." "\nIn case of arc has state 2, nodes with state 1 or state 2 are enabled. If the new node has state 0 arc will not be broken" "\n\nWould you like to continue?") answer = self.controller.ask_question(msg, "Divide intersected arc?") if answer: self.controller.plugin_settings_set_value( "check_topology_arc", "1") else: self.controller.plugin_settings_set_value("close_dlg", "1") def check_topology_node(self): """ Check topology: Inserted node is over an existing node? """ node_over_node = False continue_insert = True # Initialize plugin parameters self.controller.plugin_settings_set_value("check_topology_node", "0") self.controller.plugin_settings_set_value("close_dlg", "0") # Get selected srid and coordinates. Set SQL to check topology srid = self.controller.plugin_settings_value('srid') point = self.feature.geometry().asPoint() node_geom = "ST_SetSRID(ST_Point(" + str(point.x()) + ", " + str( point.y()) + "), " + str(srid) + ")" sql = ("SELECT node_id, state FROM " + self.schema_name + ".v_edit_node" " WHERE ST_Intersects(ST_Buffer(" + node_geom + ", " + str(self.node_proximity) + "), the_geom)" " ORDER BY ST_Distance(" + node_geom + ", the_geom)" " LIMIT 1") row = self.controller.get_row(sql) if row: node_over_node = True msg = ( "We have detected you are trying to insert one node over another node with state " + str(row['state']) + "" "\nRemember that:" "\n\nIn case of old or new node has state 0, you are allowed to insert new one, because state 0 has not topology rules." "\nIn the rest of cases, remember that the state topology rules of Giswater only enables one node with the same state at the same position." "\n\nWould you like to continue?") answer = self.controller.ask_question(msg, "Insert node over node?") if answer: self.controller.plugin_settings_set_value( "check_topology_node", "1") else: self.controller.plugin_settings_set_value("close_dlg", "1") continue_insert = False return (continue_insert, node_over_node) def action_rotation(self): # Set map tool emit point and signals self.emit_point = QgsMapToolEmitPoint(self.canvas) self.canvas.setMapTool(self.emit_point) self.snapper = QgsMapCanvasSnapper(self.canvas) self.canvas.xyCoordinates.connect(self.action_rotation_mouse_move) self.emit_point.canvasClicked.connect( self.action_rotation_canvas_clicked) # Store user snapping configuration self.snapper_manager = SnappingConfigManager(self.iface) self.snapper_manager.store_snapping_options() # Clear snapping self.snapper_manager.clear_snapping() # Set snapping layer = self.controller.get_layer_by_tablename("v_edit_arc") self.snapper_manager.snap_to_layer(layer) layer = self.controller.get_layer_by_tablename("v_edit_connec") self.snapper_manager.snap_to_layer(layer) layer = self.controller.get_layer_by_tablename("v_edit_node") self.snapper_manager.snap_to_layer(layer) # Set marker color = QColor(255, 100, 255) self.vertex_marker = QgsVertexMarker(self.canvas) self.vertex_marker.setIconType(QgsVertexMarker.ICON_CROSS) self.vertex_marker.setColor(color) self.vertex_marker.setIconSize(15) self.vertex_marker.setPenWidth(3) def action_rotation_mouse_move(self, point): """ Slot function when mouse is moved in the canvas. Add marker if any feature is snapped """ # Hide marker and get coordinates self.vertex_marker.hide() map_point = self.canvas.getCoordinateTransform().transform(point) x = map_point.x() y = map_point.y() event_point = QPoint(x, y) # Snapping (retval, result) = self.snapper.snapToBackgroundLayers( event_point) # @UnusedVariable if not result: return # Check snapped features for snapped_point in result: point = QgsPoint(snapped_point.snappedVertex) self.vertex_marker.setCenter(point) self.vertex_marker.show() break def action_rotation_canvas_clicked(self, point, btn): if btn == Qt.RightButton: self.disable_rotation() return viewname = self.controller.get_layer_source_table_name(self.layer) sql = ("SELECT ST_X(the_geom), ST_Y(the_geom)" " FROM " + self.schema_name + "." + viewname + "" " WHERE node_id = '" + self.id + "'") row = self.controller.get_row(sql) if row: existing_point_x = row[0] existing_point_y = row[1] sql = ("UPDATE " + self.schema_name + ".node" " SET hemisphere = (SELECT degrees(ST_Azimuth(ST_Point(" + str(existing_point_x) + ", " + str(existing_point_y) + "), " " ST_Point(" + str(point.x()) + ", " + str(point.y()) + "))))" " WHERE node_id = '" + str(self.id) + "'") status = self.controller.execute_sql(sql) if not status: self.disable_rotation() return sql = ("SELECT degrees(ST_Azimuth(ST_Point(" + str(existing_point_x) + ", " + str(existing_point_y) + ")," " ST_Point( " + str(point.x()) + ", " + str(point.y()) + ")))") row = self.controller.get_row(sql) if row: utils_giswater.setWidgetText("hemisphere", str(row[0])) message = "Hemisphere of the node has been updated. Value is" self.controller.show_info(message, parameter=str(row[0])) self.disable_rotation() def disable_rotation(self): """ Disable actionRotation and set action 'Identify' """ action_widget = self.dialog.findChild(QAction, "actionRotation") if action_widget: action_widget.setChecked(False) try: self.snapper_manager.recover_snapping_options() self.vertex_marker.hide() self.set_action_identify() self.canvas.xyCoordinates.disconnect() self.emit_point.canvasClicked.disconnect() except: pass def tab_activation(self): """ Call functions depend on tab selection """ # Get index of selected tab index_tab = self.tab_main.currentIndex() # Tab 'Connections' if index_tab == ( 2 - self.tabs_removed) and not self.tab_connections_loaded: self.fill_tab_connections() self.tab_connections_loaded = True # Tab 'Element' elif index_tab == (3 - self.tabs_removed) and not self.tab_element_loaded: self.fill_tab_element() self.tab_element_loaded = True # Tab 'Document' elif index_tab == (4 - self.tabs_removed) and not self.tab_document_loaded: self.fill_tab_document() self.tab_document_loaded = True # Tab 'O&M' elif index_tab == (5 - self.tabs_removed) and not self.tab_om_loaded: self.fill_tab_om() self.tab_om_loaded = True # Tab 'Scada' elif index_tab == (6 - self.tabs_removed) and not self.tab_scada_loaded: self.fill_tab_scada() self.tab_scada_loaded = True # Tab 'Cost' elif index_tab == (7 - self.tabs_removed) and not self.tab_cost_loaded: self.fill_tab_cost() self.tab_cost_loaded = True def fill_tab_connections(self): """ Fill tab 'Connections' """ self.fill_tables(self.tbl_upstream, "v_ui_node_x_connection_upstream") self.fill_tables(self.tbl_downstream, "v_ui_node_x_connection_downstream") def fill_tab_element(self): """ Fill tab 'Element' """ table_element = "v_ui_element_x_node" self.fill_tbl_element_man(self.tbl_element, table_element, self.filter) self.set_configuration(self.tbl_element, table_element) def fill_tab_document(self): """ Fill tab 'Document' """ table_document = "v_ui_doc_x_node" self.fill_tbl_document_man(self.tbl_document, table_document, self.filter) self.set_configuration(self.tbl_document, table_document) def fill_tab_om(self): """ Fill tab 'O&M' (event) """ table_event_node = "v_ui_om_visit_x_node" self.fill_tbl_event(self.tbl_event, self.schema_name + "." + table_event_node, self.filter) self.tbl_event.doubleClicked.connect(self.open_selected_document_event) self.set_configuration(self.tbl_event, table_event_node) def fill_tab_scada(self): """ Fill tab 'Scada' """ pass def fill_tab_cost(self): """ Fill tab 'Cost' """ table_costs = "v_plan_node" self.fill_table(self.tbl_costs, self.schema_name + "." + table_costs, self.filter) self.set_configuration(self.tbl_costs, table_costs)
class ParentManage(ParentAction, object): def __init__(self, iface, settings, controller, plugin_dir): """ Class to keep common functions of classes 'ManageDocument', 'ManageElement' and 'ManageVisit' of toolbar 'edit'.""" super(ParentManage, self).__init__(iface, settings, controller, plugin_dir) self.x = "" self.y = "" self.canvas = self.iface.mapCanvas() self.plan_om = None self.previous_map_tool = None self.autocommit = True self.lazy_widget = None self.workcat_id_end = None self.xyCoordinates_conected = False self.remove_ids = True def reset_lists(self): """ Reset list of selected records """ self.ids = [] self.list_ids = {} self.list_ids['arc'] = [] self.list_ids['node'] = [] self.list_ids['connec'] = [] self.list_ids['gully'] = [] self.list_ids['element'] = [] def reset_layers(self): """ Reset list of layers """ self.layers = {} self.layers['arc'] = [] self.layers['node'] = [] self.layers['connec'] = [] self.layers['gully'] = [] self.layers['element'] = [] def reset_model(self, dialog, table_object, geom_type): """ Reset model of the widget """ table_relation = table_object + "_x_" + geom_type widget_name = "tbl_" + table_relation widget = utils_giswater.getWidget(dialog, widget_name) if widget: widget.setModel(None) def remove_selection(self, remove_groups=True): """ Remove all previous selections """ layer = self.controller.get_layer_by_tablename("v_edit_arc") if layer: layer.removeSelection() layer = self.controller.get_layer_by_tablename("v_edit_node") if layer: layer.removeSelection() layer = self.controller.get_layer_by_tablename("v_edit_connec") if layer: layer.removeSelection() layer = self.controller.get_layer_by_tablename("v_edit_element") if layer: layer.removeSelection() if self.project_type == 'ud': layer = self.controller.get_layer_by_tablename("v_edit_gully") if layer: layer.removeSelection() try: if remove_groups: for layer in self.layers['arc']: layer.removeSelection() for layer in self.layers['node']: layer.removeSelection() for layer in self.layers['connec']: layer.removeSelection() for layer in self.layers['gully']: layer.removeSelection() for layer in self.layers['element']: layer.removeSelection() except: pass self.canvas.refresh() def reset_widgets(self, dialog, table_object): """ Clear contents of input widgets """ if table_object == "doc": utils_giswater.setWidgetText(dialog, "doc_type", "") utils_giswater.setWidgetText(dialog, "observ", "") utils_giswater.setWidgetText(dialog, "path", "") elif table_object == "element": utils_giswater.setWidgetText(dialog, "elementcat_id", "") utils_giswater.setWidgetText(dialog, "state", "") utils_giswater.setWidgetText(dialog, "expl_id","") utils_giswater.setWidgetText(dialog, "ownercat_id", "") utils_giswater.setWidgetText(dialog, "location_type", "") utils_giswater.setWidgetText(dialog, "buildercat_id", "") utils_giswater.setWidgetText(dialog, "workcat_id", "") utils_giswater.setWidgetText(dialog, "workcat_id_end", "") utils_giswater.setWidgetText(dialog, "comment", "") utils_giswater.setWidgetText(dialog, "observ", "") utils_giswater.setWidgetText(dialog, "path", "") utils_giswater.setWidgetText(dialog, "rotation", "") utils_giswater.setWidgetText(dialog, "verified", "") utils_giswater.setWidgetText(dialog, dialog.num_elements, "") def fill_widgets(self, dialog, table_object, row): """ Fill input widgets with data int he @row """ if table_object == "doc": utils_giswater.setWidgetText(dialog, "doc_type", row["doc_type"]) utils_giswater.setWidgetText(dialog, "observ", row["observ"]) utils_giswater.setWidgetText(dialog, "path", row["path"]) elif table_object == "element": state = "" if row['state']: sql = ("SELECT name FROM " + self.schema_name + ".value_state" " WHERE id = '" + str(row['state']) + "'") row_aux = self.controller.get_row(sql, commit=self.autocommit) if row_aux: state = row_aux[0] expl_id = "" if row['expl_id']: sql = ("SELECT name FROM " + self.schema_name + ".exploitation" " WHERE expl_id = '" + str(row['expl_id']) + "'") row_aux = self.controller.get_row(sql, commit=self.autocommit) if row_aux: expl_id = row_aux[0] utils_giswater.setWidgetText(dialog, "code", row['code']) sql = ("SELECT elementtype_id FROM " + self.schema_name + ".cat_element" " WHERE id = '" + str(row['elementcat_id']) + "'") row_type = self.controller.get_row(sql) if row_type: utils_giswater.setWidgetText(dialog, "element_type", row_type[0]) utils_giswater.setWidgetText(dialog, "elementcat_id", row['elementcat_id']) utils_giswater.setWidgetText(dialog, "num_elements", row['num_elements']) utils_giswater.setWidgetText(dialog, "state", state) utils_giswater.setWidgetText(dialog, "expl_id", expl_id) utils_giswater.setWidgetText(dialog, "ownercat_id", row['ownercat_id']) utils_giswater.setWidgetText(dialog, "location_type", row['location_type']) utils_giswater.setWidgetText(dialog, "buildercat_id", row['buildercat_id']) builtdate = QDate.fromString(str(row['builtdate']), 'yyyy-MM-dd') dialog.builtdate.setDate(builtdate) utils_giswater.setWidgetText(dialog, "workcat_id", row['workcat_id']) utils_giswater.setWidgetText(dialog, "workcat_id_end", row['workcat_id_end']) utils_giswater.setWidgetText(dialog, "comment", row['comment']) utils_giswater.setWidgetText(dialog, "observ", row['observ']) utils_giswater.setWidgetText(dialog, "link", row['link']) utils_giswater.setWidgetText(dialog, "verified", row['verified']) utils_giswater.setWidgetText(dialog, "rotation", row['rotation']) if str(row['undelete']) == 'True': dialog.undelete.setChecked(True) def get_records_geom_type(self, dialog, table_object, geom_type): """ Get records of @geom_type associated to selected @table_object """ object_id = utils_giswater.getWidgetText(dialog, table_object + "_id") table_relation = table_object + "_x_" + geom_type widget_name = "tbl_" + table_relation exists = self.controller.check_table(table_relation) if not exists: self.controller.log_info("Not found: " + str(table_relation)) return sql = ("SELECT " + geom_type + "_id" " FROM " + self.schema_name + "." + table_relation + "" " WHERE " + table_object + "_id = '" + str(object_id) + "'") rows = self.controller.get_rows(sql, log_info=False) if rows: for row in rows: self.list_ids[geom_type].append(str(row[0])) self.ids.append(str(row[0])) expr_filter = self.get_expr_filter(geom_type) self.set_table_model(dialog, widget_name, geom_type, expr_filter) def exist_object(self, dialog, table_object): """ Check if selected object (document or element) already exists """ # Reset list of selected records self.reset_lists() field_object_id = "id" if table_object == "element": field_object_id = table_object + "_id" object_id = utils_giswater.getWidgetText(dialog, table_object + "_id") # Check if we already have data with selected object_id sql = ("SELECT * " " FROM " + self.schema_name + "." + str(table_object) + "" " WHERE " + str(field_object_id) + " = '" + str(object_id) + "'") row = self.controller.get_row(sql, log_info=False) # If object_id not found: Clear data if not row: self.reset_widgets(dialog, table_object) if table_object == 'element': self.set_combo(dialog, 'state', 'value_state', 'state_vdefault', field_name='name') self.set_combo(dialog, 'expl_id', 'exploitation', 'exploitation_vdefault', field_id='expl_id',field_name='name') self.set_calendars(dialog, 'builtdate', 'config_param_user', 'value', 'builtdate_vdefault') self.set_combo(dialog, 'workcat_id', 'cat_work', 'workcat_vdefault', field_id='id', field_name='id') if hasattr(self, 'single_tool_mode'): # some tools can work differently if standalone or integrated in # another tool if self.single_tool_mode: self.remove_selection(True) else: self.remove_selection(True) self.reset_model(dialog, table_object, "arc") self.reset_model(dialog, table_object, "node") self.reset_model(dialog, table_object, "connec") self.reset_model(dialog, table_object, "element") if self.project_type == 'ud': self.reset_model(dialog, table_object, "gully") return # Fill input widgets with data of the @row self.fill_widgets(dialog, table_object, row) # Check related 'arcs' self.get_records_geom_type(dialog, table_object, "arc") # Check related 'nodes' self.get_records_geom_type(dialog, table_object, "node") # Check related 'connecs' self.get_records_geom_type(dialog, table_object, "connec") # Check related 'elements' self.get_records_geom_type(dialog, table_object, "element") # Check related 'gullys' if self.project_type == 'ud': self.get_records_geom_type(dialog, table_object, "gully") def populate_combo(self, dialog, widget, table_name, field_name="id"): """ Executes query and fill combo box """ sql = ("SELECT " + field_name + "" " FROM " + self.schema_name + "." + table_name + "" " ORDER BY " + field_name) rows = self.controller.get_rows(sql, commit=self.autocommit) utils_giswater.fillComboBox(dialog, widget, rows) if rows: utils_giswater.setCurrentIndex(dialog, widget, 0) def set_combo(self, dialog, widget, table_name, parameter, field_id='id', field_name='id'): """ Executes query and set combo box """ sql = ("SELECT t1." + field_name + " FROM " + self.schema_name + "." + table_name + " as t1" " INNER JOIN " + self.schema_name + ".config_param_user as t2 ON t1." + field_id + "::text = t2.value::text" " WHERE parameter = '" + parameter + "' AND cur_user = current_user") row = self.controller.get_row(sql) if row: utils_giswater.setWidgetText(dialog, widget, row[0]) def set_calendars(self, dialog, widget, table_name, value, parameter): """ Executes query and set QDateEdit """ sql = ("SELECT " + value + " FROM " + self.schema_name + "." + table_name + "" " WHERE parameter = '" + parameter + "' AND cur_user = current_user") row = self.controller.get_row(sql) if row: date = QDate.fromString(row[0], 'yyyy-MM-dd') else: date = QDate.currentDate() utils_giswater.setCalendarDate(dialog, widget, date) def add_point(self): """ Create the appropriate map tool and connect to the corresponding signal """ active_layer = self.iface.activeLayer() if active_layer is None: active_layer = self.controller.get_layer_by_tablename('version') self.iface.setActiveLayer(active_layer) # Vertex marker self.vertex_marker = QgsVertexMarker(self.canvas) self.vertex_marker.setColor(QColor(255, 100, 255)) self.vertex_marker.setIconSize(15) self.vertex_marker.setIconType(QgsVertexMarker.ICON_CROSS) self.vertex_marker.setPenWidth(3) # Snapper self.snapper = QgsMapCanvasSnapper(self.canvas) self.emit_point = QgsMapToolEmitPoint(self.canvas) self.previous_map_tool = self.canvas.mapTool() self.canvas.setMapTool(self.emit_point) #self.canvas.connect(self.canvas, SIGNAL("xyCoordinates(const QgsPoint&)"), self.mouse_move) self.canvas.xyCoordinates.connect(self.mouse_move) self.xyCoordinates_conected = True self.emit_point.canvasClicked.connect(partial(self.get_xy)) def mouse_move(self, p): self.snapped_point = None self.vertex_marker.hide() map_point = self.canvas.getCoordinateTransform().transform(p) x = map_point.x() y = map_point.y() eventPoint = QPoint(x, y) # Snapping (retval, result) = self.snapper.snapToBackgroundLayers(eventPoint) # @UnusedVariable # That's the snapped point if result: # Check feature for snapped_point in result: self.snapped_point = QgsPoint(snapped_point.snappedVertex) self.vertex_marker.setCenter(self.snapped_point) self.vertex_marker.show() else: self.vertex_marker.hide() def get_xy(self, point): """ Get coordinates of selected point """ if self.snapped_point: self.x = self.snapped_point.x() self.y = self.snapped_point.y() else: self.x = point.x() self.y = point.y() message = "Geometry has been added!" self.controller.show_info(message) self.emit_point.canvasClicked.disconnect() self.canvas.xyCoordinates.disconnect() self.xyCoordinates_conected = False self.iface.mapCanvas().refreshAllLayers() self.vertex_marker.hide() def get_values_from_form(self, dialog): self.enddate = utils_giswater.getCalendarDate(dialog, "enddate") self.workcat_id_end = utils_giswater.getWidgetText(dialog, "workcat_id_end") self.description = utils_giswater.getWidgetText(dialog, "descript") def tab_feature_changed(self, dialog, table_object, feature_id=None): """ Set geom_type and layer depending selected tab @table_object = ['doc' | 'element' | 'cat_work'] """ self.get_values_from_form(dialog) if dialog.tab_feature.currentIndex() == 3: dialog.btn_snapping.setEnabled(False) else: dialog.btn_snapping.setEnabled(True) tab_position = dialog.tab_feature.currentIndex() if tab_position == 0: self.geom_type = "arc" elif tab_position == 1: self.geom_type = "node" elif tab_position == 2: self.geom_type = "connec" elif tab_position == 3: self.geom_type = "element" elif tab_position == 4: self.geom_type = "gully" self.hide_generic_layers() widget_name = "tbl_" + table_object + "_x_" + str(self.geom_type) viewname = "v_edit_" + str(self.geom_type) self.widget = utils_giswater.getWidget(dialog, widget_name) # Adding auto-completion to a QLineEdit self.set_completer_feature_id(dialog.feature_id, self.geom_type, viewname) self.iface.actionPan().trigger() def set_completer_object(self, dialog, table_object): """ Set autocomplete of widget @table_object + "_id" getting id's from selected @table_object """ widget = utils_giswater.getWidget(dialog, table_object + "_id") if not widget: return # Set SQL field_object_id = "id" if table_object == "element": field_object_id = table_object + "_id" sql = ("SELECT DISTINCT(" + field_object_id + ")" " FROM " + self.schema_name + "." + table_object) row = self.controller.get_rows(sql, commit=self.autocommit) for i in range(0, len(row)): aux = row[i] row[i] = str(aux[0]) # Set completer and model: add autocomplete in the widget self.completer = QCompleter() self.completer.setCaseSensitivity(Qt.CaseInsensitive) widget.setCompleter(self.completer) model = QStringListModel() model.setStringList(row) self.completer.setModel(model) def set_completer_widget(self, tablename, widget, field_id): """ Set autocomplete of widget @table_object + "_id" getting id's from selected @table_object """ if not widget: return # Set SQL sql = ("SELECT DISTINCT(" + field_id + ")" " FROM " + self.schema_name + "." + tablename +"" " ORDER BY "+ field_id + "") row = self.controller.get_rows(sql) for i in range(0, len(row)): aux = row[i] row[i] = str(aux[0]) # Set completer and model: add autocomplete in the widget self.completer = QCompleter() self.completer.setCaseSensitivity(Qt.CaseInsensitive) widget.setCompleter(self.completer) model = QStringListModel() model.setStringList(row) self.completer.setModel(model) def set_completer_feature_id(self, widget, geom_type, viewname): """ Set autocomplete of widget 'feature_id' getting id's from selected @viewname """ # Adding auto-completion to a QLineEdit self.completer = QCompleter() self.completer.setCaseSensitivity(Qt.CaseInsensitive) widget.setCompleter(self.completer) model = QStringListModel() sql = ("SELECT " + geom_type + "_id" " FROM " + self.schema_name + "." + viewname) row = self.controller.get_rows(sql, commit=self.autocommit) if row: for i in range(0, len(row)): aux = row[i] row[i] = str(aux[0]) model.setStringList(row) self.completer.setModel(model) def get_expr_filter(self, geom_type): """ Set an expression filter with the contents of the list. Set a model with selected filter. Attach that model to selected table """ list_ids = self.list_ids[geom_type] field_id = geom_type + "_id" if len(list_ids) == 0: return None # Set expression filter with features in the list expr_filter = field_id + " IN (" for i in range(len(list_ids)): expr_filter += "'" + str(list_ids[i]) + "', " expr_filter = expr_filter[:-2] + ")" # Check expression (is_valid, expr) = self.check_expression(expr_filter) if not is_valid: return None # Select features of layers applying @expr self.select_features_by_ids(geom_type, expr) return expr_filter def reload_table(self, dialog, table_object, geom_type, expr_filter): """ Reload @widget with contents of @tablename applying selected @expr_filter """ if type(table_object) is str: widget_name = "tbl_" + table_object + "_x_" + geom_type widget = utils_giswater.getWidget(dialog, widget_name) if not widget: message = "Widget not found" self.controller.log_info(message, parameter=widget_name) return None elif type(table_object) is QTableView: widget = table_object else: message = "Table_object is not a table name or QTableView" self.controller.log_info(message) return None expr = self.set_table_model(dialog, widget, geom_type, expr_filter) return expr def set_table_model(self, dialog, table_object, geom_type, expr_filter): """ Sets a TableModel to @widget_name attached to @table_name and filter @expr_filter """ expr = None if expr_filter: # Check expression (is_valid, expr) = self.check_expression(expr_filter) #@UnusedVariable if not is_valid: return expr # Set a model with selected filter expression table_name = "v_edit_" + geom_type if self.schema_name not in table_name: table_name = self.schema_name + "." + table_name # Set the model model = QSqlTableModel() model.setTable(table_name) model.setEditStrategy(QSqlTableModel.OnManualSubmit) model.select() if model.lastError().isValid(): self.controller.show_warning(model.lastError().text()) return expr # Attach model to selected widget if type(table_object) is str: widget = utils_giswater.getWidget(dialog, table_object) if not widget: message = "Widget not found" self.controller.log_info(message, parameter=table_object) return expr elif type(table_object) is QTableView: widget = table_object else: message = "Table_object is not a table name or QTableView" self.controller.log_info(message) return expr if expr_filter: widget.setModel(model) widget.model().setFilter(expr_filter) widget.model().select() else: widget.setModel(None) return expr def apply_lazy_init(self, widget): """Apply the init function related to the model. It's necessary a lazy init because model is changed everytime is loaded.""" if self.lazy_widget is None: return if widget != self.lazy_widget: return self.lazy_init_function(self.lazy_widget) def lazy_configuration(self, widget, init_function): """set the init_function where all necessary events are set. This is necessary to allow a lazy setup of the events because set_table_events can create a table with a None model loosing any event connection.""" # TODO: create a dictionary with key:widged.objectName value:initFuction # to allow multiple lazy initialization self.lazy_widget = widget self.lazy_init_function = init_function def select_features_by_ids(self, geom_type, expr): """ Select features of layers of group @geom_type applying @expr """ # Build a list of feature id's and select them for layer in self.layers[geom_type]: if expr is None: layer.removeSelection() else: it = layer.getFeatures(QgsFeatureRequest(expr)) id_list = [i.id() for i in it] if len(id_list) > 0: layer.selectByIds(id_list) else: layer.removeSelection() def delete_records(self, dialog, table_object, query=False): """ Delete selected elements of the table """ self.disconnect_signal_selection_changed() if type(table_object) is str: widget_name = "tbl_" + table_object + "_x_" + self.geom_type widget = utils_giswater.getWidget(dialog, widget_name) if not widget: message = "Widget not found" self.controller.show_warning(message, parameter=widget_name) return elif type(table_object) is QTableView: widget = table_object else: message = "Table_object is not a table name or QTableView" self.controller.log_info(message) return # Get selected rows selected_list = widget.selectionModel().selectedRows() if len(selected_list) == 0: message = "Any record selected" self.controller.show_info_box(message) return if query: full_list = widget.model() for x in range(0, full_list.rowCount()): self.ids.append(widget.model().record(x).value(str(self.geom_type)+"_id")) else: self.ids = self.list_ids[self.geom_type] field_id = self.geom_type + "_id" del_id = [] inf_text = "" list_id = "" for i in range(0, len(selected_list)): row = selected_list[i].row() id_feature = widget.model().record(row).value(field_id) inf_text += str(id_feature) + ", " list_id = list_id + "'" + str(id_feature) + "', " del_id.append(id_feature) inf_text = inf_text[:-2] list_id = list_id[:-2] message = "Are you sure you want to delete these records?" title = "Delete records" answer = self.controller.ask_question(message, title, inf_text) if answer: for el in del_id: self.ids.remove(el) else: return expr_filter = None expr = None if len(self.ids) > 0: # Set expression filter with features in the list expr_filter = "\"" + field_id + "\" IN (" for i in range(len(self.ids)): expr_filter += "'" + str(self.ids[i]) + "', " expr_filter = expr_filter[:-2] + ")" # Check expression (is_valid, expr) = self.check_expression(expr_filter) #@UnusedVariable if not is_valid: return # Update model of the widget with selected expr_filter if query: self.delete_feature_at_plan(dialog, self.geom_type, list_id) self.reload_qtable(dialog, self.geom_type, self.plan_om) else: self.reload_table(dialog, table_object, self.geom_type, expr_filter) self.apply_lazy_init(table_object) # Select features with previous filter # Build a list of feature id's and select them self.select_features_by_ids(self.geom_type, expr) if query: self.remove_selection() # Update list self.list_ids[self.geom_type] = self.ids self.enable_feature_type(dialog) self.connect_signal_selection_changed(dialog, table_object) def manage_close(self, dialog, table_object, cur_active_layer=None): """ Close dialog and disconnect snapping """ if cur_active_layer: self.iface.setActiveLayer(cur_active_layer) if hasattr(self, 'single_tool_mode'): # some tools can work differently if standalone or integrated in # another tool if self.single_tool_mode: self.remove_selection(True) else: self.remove_selection(True) self.reset_model(dialog, table_object, "arc") self.reset_model(dialog, table_object, "node") self.reset_model(dialog, table_object, "connec") self.reset_model(dialog, table_object, "element") if self.project_type == 'ud': self.reset_model(dialog, table_object, "gully") self.close_dialog(dialog) self.hide_generic_layers() self.disconnect_snapping() self.disconnect_signal_selection_changed() # reset previous dialog in not in single_tool_mode # if hasattr(self, 'single_tool_mode') and not self.single_tool_mode: # if hasattr(self, 'previous_dialog'): def selection_init(self, dialog, table_object, query=False): """ Set canvas map tool to an instance of class 'MultipleSelection' """ multiple_selection = MultipleSelection(self.iface, self.controller, self.layers[self.geom_type], parent_manage=self, table_object=table_object, dialog=dialog) self.previous_map_tool = self.canvas.mapTool() self.canvas.setMapTool(multiple_selection) self.disconnect_signal_selection_changed() self.connect_signal_selection_changed(dialog, table_object, query) cursor = self.get_cursor_multiple_selection() self.canvas.setCursor(cursor) def selection_changed(self, dialog, table_object, geom_type, query=False): """ Slot function for signal 'canvas.selectionChanged' """ self.disconnect_signal_selection_changed() field_id = geom_type + "_id" if self.remove_ids: self.ids = [] # Iterate over all layers of the group for layer in self.layers[self.geom_type]: if layer.selectedFeatureCount() > 0: # Get selected features of the layer features = layer.selectedFeatures() for feature in features: # Append 'feature_id' into the list selected_id = feature.attribute(field_id) if selected_id not in self.ids: self.ids.append(selected_id) if geom_type == 'arc': self.list_ids['arc'] = self.ids elif geom_type == 'node': self.list_ids['node'] = self.ids elif geom_type == 'connec': self.list_ids['connec'] = self.ids elif geom_type == 'gully': self.list_ids['gully'] = self.ids elif geom_type == 'element': self.list_ids['element'] = self.ids expr_filter = None if len(self.ids) > 0: # Set 'expr_filter' with features that are in the list expr_filter = "\"" + field_id + "\" IN (" for i in range(len(self.ids)): expr_filter += "'" + str(self.ids[i]) + "', " expr_filter = expr_filter[:-2] + ")" # Check expression (is_valid, expr) = self.check_expression(expr_filter) #@UnusedVariable if not is_valid: return self.select_features_by_ids(geom_type, expr) # Reload contents of table 'tbl_@table_object_x_@geom_type' if query: self.insert_feature_to_plan(dialog, self.geom_type) if self.plan_om == 'plan': self.remove_selection() self.reload_qtable(dialog, geom_type, self.plan_om) else: self.reload_table(dialog, table_object, self.geom_type, expr_filter) self.apply_lazy_init(table_object) # Remove selection in generic 'v_edit' layers if self.plan_om == 'plan': self.remove_selection(False) self.enable_feature_type(dialog) self.connect_signal_selection_changed(dialog, table_object) def delete_feature_at_plan(self, dialog, geom_type, list_id): """ Delete features_id to table plan_@geom_type_x_psector""" value = utils_giswater.getWidgetText(dialog, dialog.psector_id) sql = ("DELETE FROM " + self.schema_name + "." + self.plan_om + "_psector_x_" + geom_type + "" " WHERE " + geom_type + "_id IN (" + list_id + ") AND psector_id = '" + str(value) + "'") self.controller.execute_sql(sql) def enable_feature_type(self, dialog): feature_type = dialog.findChild(QComboBox, 'feature_type') assigned_to = dialog.findChild(QComboBox, 'cmb_assigned_to') visit_class = dialog.findChild(QComboBox, 'cmb_visit_class') table = dialog.findChild(QTableView, 'tbl_relation') if feature_type is not None and table is not None: if len(self.ids) > 0: feature_type.setEnabled(False) if assigned_to is not None: assigned_to.setEnabled(False) if assigned_to is not None: visit_class.setEnabled(False) else: feature_type.setEnabled(True) if assigned_to is not None: assigned_to.setEnabled(True) if assigned_to is not None: visit_class.setEnabled(True) def insert_feature(self, dialog, table_object, query=False, remove_ids=True): """ Select feature with entered id. Set a model with selected filter. Attach that model to selected table """ self.disconnect_signal_selection_changed() # Clear list of ids if remove_ids: self.ids = [] field_id = self.geom_type + "_id" feature_id = utils_giswater.getWidgetText(dialog, "feature_id") if feature_id == 'null': message = "You need to enter a feature id" self.controller.show_info_box(message) return # Iterate over all layers of the group for layer in self.layers[self.geom_type]: if layer.selectedFeatureCount() > 0: # Get selected features of the layer features = layer.selectedFeatures() for feature in features: # Append 'feature_id' into the list selected_id = feature.attribute(field_id) if selected_id not in self.ids: self.ids.append(selected_id) if feature_id not in self.ids: # If feature id doesn't exist in list -> add self.ids.append(str(feature_id)) # Set expression filter with features in the list expr_filter = "\"" + field_id + "\" IN (" for i in range(len(self.ids)): expr_filter += "'" + str(self.ids[i]) + "', " expr_filter = expr_filter[:-2] + ")" # Check expression (is_valid, expr) = self.check_expression(expr_filter) if not is_valid: return # Select features with previous filter # Build a list of feature id's and select them for layer in self.layers[self.geom_type]: it = layer.getFeatures(QgsFeatureRequest(expr)) id_list = [i.id() for i in it] if len(id_list) > 0: layer.selectByIds(id_list) # Reload contents of table 'tbl_???_x_@geom_type' if query: self.insert_feature_to_plan(dialog, self.geom_type) self.remove_selection() else: self.reload_table(dialog, table_object, self.geom_type, expr_filter) self.apply_lazy_init(table_object) # Update list self.list_ids[self.geom_type] = self.ids self.enable_feature_type(dialog) self.connect_signal_selection_changed(dialog, table_object) def insert_feature_to_plan(self, dialog, geom_type): """ Insert features_id to table plan_@geom_type_x_psector""" value = utils_giswater.getWidgetText(dialog, dialog.psector_id) for i in range(len(self.ids)): sql = ("SELECT " + geom_type + "_id" " FROM " + self.schema_name + "." + self.plan_om + "_psector_x_" + geom_type + "" " WHERE " + geom_type + "_id = '" + str(self.ids[i]) + "' AND psector_id = '" + str(value) + "'") row = self.controller.get_row(sql) if not row: sql = ("INSERT INTO " + self.schema_name + "." + self.plan_om + "_psector_x_" + geom_type + "" "(" + geom_type + "_id, psector_id) VALUES('" + str(self.ids[i]) + "', '" + str(value) + "')") self.controller.execute_sql(sql) self.reload_qtable(dialog, geom_type, self.plan_om) def reload_qtable(self, dialog, geom_type, plan_om): """ Reload QtableView """ value = utils_giswater.getWidgetText(dialog, dialog.psector_id) sql = ("SELECT * FROM " + self.schema_name + "." + plan_om + "_psector_x_" + geom_type + "" " WHERE psector_id = '" + str(value) + "'") qtable = utils_giswater.getWidget(dialog, 'tbl_psector_x_' + geom_type) self.fill_table_by_query(qtable, sql) self.set_table_columns(dialog, qtable, plan_om + "_psector_x_"+geom_type) self.refresh_map_canvas() def disconnect_snapping(self): """ Select 'Pan' as current map tool and disconnect snapping """ try: self.iface.actionPan().trigger() self.canvas.xyCoordinates.disconnect() if self.emit_point: self.emit_point.canvasClicked.disconnect() except: pass def fill_table_object(self, widget, table_name, expr_filter=None): """ Set a model with selected filter. Attach that model to selected table """ if self.schema_name not in table_name: table_name = self.schema_name + "." + table_name # Set model model = QSqlTableModel() model.setTable(table_name) model.setEditStrategy(QSqlTableModel.OnManualSubmit) model.sort(0, 1) if expr_filter: model.setFilter(expr_filter) model.select() # Check for errors if model.lastError().isValid(): self.controller.show_warning(model.lastError().text()) # Attach model to table view widget.setModel(model) def filter_by_id(self, dialog, widget_table, widget_txt, table_object, field_object_id='id'): field_object_id = "id" if table_object == "element": field_object_id = table_object + "_id" object_id = utils_giswater.getWidgetText(dialog, widget_txt) if object_id != 'null': expr = field_object_id + "::text ILIKE '%" + str(object_id) + "%'" # Refresh model with selected filter widget_table.model().setFilter(expr) widget_table.model().select() else: self.fill_table_object(widget_table, self.schema_name + "." + table_object) def delete_selected_object(self, widget, table_object): """ Delete selected objects of the table (by object_id) """ # Get selected rows selected_list = widget.selectionModel().selectedRows() if len(selected_list) == 0: message = "Any record selected" self.controller.show_warning(message) return inf_text = "" list_id = "" field_object_id = "id" if table_object == "element": field_object_id = table_object + "_id" elif "v_ui_om_visitman_x_" in table_object: field_object_id = "visit_id" for i in range(0, len(selected_list)): row = selected_list[i].row() id_ = widget.model().record(row).value(str(field_object_id)) inf_text += str(id_) + ", " list_id = list_id + "'" + str(id_) + "', " inf_text = inf_text[:-2] list_id = list_id[:-2] message = "Are you sure you want to delete these records?" title = "Delete records" answer = self.controller.ask_question(message, title, inf_text) if answer: sql = ("DELETE FROM " + self.schema_name + "." + table_object + "" " WHERE " + field_object_id + " IN (" + list_id + ")") self.controller.execute_sql(sql, commit=self.autocommit) widget.model().select() def open_selected_object(self, dialog, widget, table_object): """ Open object form with selected record of the table """ selected_list = widget.selectionModel().selectedRows() if len(selected_list) == 0: message = "Any record selected" self.controller.show_warning(message) return row = selected_list[0].row() # Get object_id from selected row field_object_id = "id" widget_id = table_object + "_id" if table_object == "element": field_object_id = table_object + "_id" if table_object == "v_ui_om_visit": widget_id = "visit_id" elif "v_ui_om_visitman_x_" in table_object: field_object_id = "visit_id" selected_object_id = widget.model().record(row).value(field_object_id) # Close this dialog and open selected object dialog.close() # set previous dialog # if hasattr(self, 'previous_dialog'): if table_object == "doc": self.manage_document() utils_giswater.setWidgetText(self.dlg_add_doc, widget_id, selected_object_id) elif table_object == "element": self.manage_element(new_element_id=False) utils_giswater.setWidgetText(self.dlg_add_element, widget_id, selected_object_id) elif table_object == "v_ui_om_visit": self.manage_visit(visit_id=selected_object_id) elif "v_ui_om_visitman_x_" in table_object: self.manage_visit(visit_id=selected_object_id) def set_selectionbehavior(self, dialog): # Get objects of type: QTableView widget_list = dialog.findChildren(QTableView) for widget in widget_list: widget.setSelectionBehavior(QAbstractItemView.SelectRows) def hide_generic_layers(self, visible=False): """ Hide generic layers """ layer = self.controller.get_layer_by_tablename("v_edit_arc") if layer: self.iface.legendInterface().setLayerVisible(layer, visible) layer = self.controller.get_layer_by_tablename("v_edit_node") if layer: self.iface.legendInterface().setLayerVisible(layer, visible) layer = self.controller.get_layer_by_tablename("v_edit_connec") if layer: self.iface.legendInterface().setLayerVisible(layer, visible) layer = self.controller.get_layer_by_tablename("v_edit_element") if layer: self.iface.legendInterface().setLayerVisible(layer, visible) if self.project_type == 'ud': layer = self.controller.get_layer_by_tablename("v_edit_gully") if layer: self.iface.legendInterface().setLayerVisible(layer, visible) def connect_signal_selection_changed(self, dialog, table_object, query=False): """ Connect signal selectionChanged """ try: self.canvas.selectionChanged.connect(partial(self.selection_changed, dialog, table_object, self.geom_type, query)) except Exception: pass def disconnect_signal_selection_changed(self): """ Disconnect signal selectionChanged """ try: self.canvas.selectionChanged.disconnect() except Exception: pass def fill_widget_with_fields(self, dialog, data_object, field_names): """Fill the Widget with value get from data_object limited to the list of field_names.""" for field_name in field_names: value = getattr(data_object, field_name) if not hasattr(dialog, field_name): continue widget = getattr(dialog, field_name) if type(widget) in [QDateEdit, QDateTimeEdit]: widget.setDateTime(value if value else QDate.currentDate() ) if type(widget) in [QLineEdit, QTextEdit]: if value: widget.setText(value) else: widget.clear() if type(widget) in [QComboBox]: if not value: widget.setCurrentIndex(0) continue # look the value in item text index = widget.findText(str(value)) if index >= 0: widget.setCurrentIndex(index) continue # look the value in itemData index = widget.findData(value) if index >= 0: widget.setCurrentIndex(index) continue def set_model_to_table(self, widget, table_name, expr_filter): """ Set a model with selected filter. Attach that model to selected table """ # Set model model = QSqlTableModel(); model.setTable(table_name) model.setEditStrategy(QSqlTableModel.OnManualSubmit) model.setFilter(expr_filter) model.select() # Check for errors if model.lastError().isValid(): self.controller.show_warning(model.lastError().text()) # Attach model to table view if widget: widget.setModel(model) else: self.controller.log_info("set_model_to_table: widget not found")
class ObstacleAreaJigCreateArea(QgsMapTool): def __init__(self, canvas, areaType): QgsMapTool.__init__(self, canvas) self.mCanvas = canvas self.areaType = areaType self.annotation = None self.rubberBand = QgsRubberBand(canvas, QGis.Point) self.rubberBand.setColor(Qt.red) self.rubberBand.setWidth(10) self.rubberBandClick = QgsRubberBand(canvas, QGis.Point) self.rubberBandClick.setColor(Qt.green) self.rubberBandClick.setWidth(3) self.obstaclesLayerList = QgisHelper.getSurfaceLayers(SurfaceTypes.Obstacles) self.demLayerList = QgisHelper.getSurfaceLayers(SurfaceTypes.DEM) self.mRubberBand = None self.mRubberBand0 = QgsRubberBand( self.mCanvas, QGis.Polygon ) self.mCursor = Qt.ArrowCursor self.mFillColor = QColor( 254, 178, 76, 63 ) self.mBorderColour = QColor( 254, 58, 29, 100 ) self.mRubberBand0.setBorderColor( self.mBorderColour ) self.polygonGeom = None self.drawFlag = False self.mSnapper = QgsMapCanvasSnapper(canvas) self.resultPolylineArea = PolylineArea() # self.constructionLayer = constructionLayer self.menuString = "" self.isPrimaryPolylineStarted = False self.primaryPolyline = PolylineArea() def createContextMenu(self, areaType, isStarted = False): menu = QMenu() # h = QHBoxLayout(menu) # c = QCalendarWidget() # h.addWidget(c) if areaType == ProtectionAreaType.Primary: actionEnter = QgisHelper.createAction(menu, "Enter", self.menuEnterClick) actionCancel = QgisHelper.createAction(menu, "Cancel", self.menuCancelClick) actionArc = QgisHelper.createAction(menu, "Arc", self.menuArcClick) actionUndo = QgisHelper.createAction(menu, "Undo", self.menuUndoClick) menu.addAction( actionEnter ) menu.addAction( actionCancel ) menu.addAction( actionArc ) menu.addAction( actionUndo ) elif areaType == ProtectionAreaType.Secondary: if not isStarted: actionEnter = QgisHelper.createAction(menu, "Enter", self.menuEnterClick) actionCancel = QgisHelper.createAction(menu, "Cancel", self.menuCancelClick) actionUndo = QgisHelper.createAction(menu, "Undo", self.menuUndoClick) actionPrimatyPolylineStart = QgisHelper.createAction(menu, "Strat INNER edge of the secondary area", self.menuPrimaryStartClick) actionPrimatyPolylineEnd = QgisHelper.createAction(menu, "End INNER edge of the secondary area", self.menuPrimaryEndClick) menu.addAction( actionEnter ) menu.addAction( actionCancel ) menu.addAction( actionUndo ) menu.addAction( actionPrimatyPolylineStart ) menu.addAction( actionPrimatyPolylineEnd ) actionPrimatyPolylineStart.setEnabled(not self.isPrimaryPolylineStarted) actionPrimatyPolylineEnd.setEnabled(self.isPrimaryPolylineStarted) else: actionPrimatyPolylineStart = QgisHelper.createAction(menu, "Strat INNER edge of the secondary area", self.menuPrimaryStartClick) actionPrimatyPolylineEnd = QgisHelper.createAction(menu, "End INNER edge of the secondary area", self.menuPrimaryEndClick) menu.addAction( actionPrimatyPolylineStart ) menu.addAction( actionPrimatyPolylineEnd ) actionPrimatyPolylineStart.setEnabled(not self.isPrimaryPolylineStarted) actionPrimatyPolylineEnd.setEnabled(self.isPrimaryPolylineStarted) return menu def menuPrimaryStartClick(self): self.primaryPolyline = PolylineArea() self.isPrimaryPolylineStarted = True # self.menuString = "Enter" def menuPrimaryEndClick(self): self.isPrimaryPolylineStarted = False # self.menuString = "Enter" def menuEnterClick(self): self.menuString = "Enter" def menuCancelClick(self): self.menuString = "Cancel" def menuArcClick(self): self.menuString = "Arc" def menuUndoClick(self): self.menuString = "Undo" def reset(self): self.Point = None def canvasPressEvent( self, e ): define._messageLabel.setText("") self.menuString = "" pointBackground = e.pos() # self.Point = QgisHelper.snapPoint(e.pos(), self.mSnapper, define._canvas) self.Point, self.pointID, self.layer= self.snapPoint(e.pos()) self.selectedLayerFromSnapPoint = None if ( self.mRubberBand == None ): self.resultPolylineArea = PolylineArea() self.mRubberBand0.reset( QGis.Polygon ) # define._canvas.clearCache () self.mRubberBand = QgsRubberBand( self.mCanvas, QGis.Polygon ) self.mRubberBand0 = QgsRubberBand( self.mCanvas, QGis.Polygon ) self.mRubberBand.setFillColor( self.mFillColor ) self.mRubberBand.setBorderColor( self.mBorderColour ) self.mRubberBand0.setFillColor( QColor(255, 255, 255, 100) ) self.mRubberBand0.setBorderColor( QColor(0, 0, 0) ) if ( e.button() == Qt.LeftButton ): if self.Point == None: self.mRubberBand.addPoint( self.toMapCoordinates( e.pos() ) ) self.resultPolylineArea.Add(PolylineAreaPoint(self.toMapCoordinates( e.pos() ))) if self.isPrimaryPolylineStarted: self.primaryPolyline.Add(PolylineAreaPoint(self.toMapCoordinates( e.pos() ))) else: self.mRubberBand.addPoint( self.Point ) self.resultPolylineArea.Add(PolylineAreaPoint(self.Point)) if self.isPrimaryPolylineStarted: self.primaryPolyline.Add(PolylineAreaPoint(self.toMapCoordinates( e.pos() ))) else: menu = None if self.areaType == ProtectionAreaType.Secondary and len(self.resultPolylineArea) == 0: menu = self.createContextMenu(self.areaType, True) menu.exec_( define._canvas.mapToGlobal(e.pos() )) return if ( self.mRubberBand.numberOfVertices() > 2 ): self.polygonGeom = self.mRubberBand.asGeometry() else: return # QgsMapToolSelectUtils.setSelectFeatures( self.mCanvas, polygonGeom, e ) menu = self.createContextMenu(self.areaType) menu.exec_( define._canvas.mapToGlobal(e.pos() )) if self.menuString == "Cancel" or self.menuString == "Arc": return elif self.menuString == "Undo": if ( self.mRubberBand.numberOfVertices() > 0 ): self.mRubberBand = None QgisHelper.ClearRubberBandInCanvas(define._canvas) self.mRubberBand = QgsRubberBand( self.mCanvas, QGis.Polygon ) self.mRubberBand.setFillColor( self.mFillColor ) self.mRubberBand.setBorderColor( self.mBorderColour ) self.resultPolylineArea[self.resultPolylineArea.Count - 2].bulge = 0.0 self.resultPolylineArea.pop(self.resultPolylineArea.Count - 1) if self.isPrimaryPolylineStarted and len(self.primaryPolyline) > 0: self.primaryPolyline.pop(self.primaryPolyline.Count - 1) for pt in self.resultPolylineArea.method_14(): self.mRubberBand.addPoint(pt) return elif self.menuString == "Enter": # if self.areaType == ProtectionAreaType.Secondary: # if self.resultPolylineArea.Count != 4: # define._messageLabel.setText("The count of point of Secondary Area must be 4.") # return self.mRubberBand.reset( QGis.Polygon ) self.mRubberBand0.reset( QGis.Polygon ) # define._canvas.clearCache () self.mRubberBand0 = QgsRubberBand( self.mCanvas, QGis.Polygon ) self.mRubberBand0.setFillColor( QColor(255, 255, 255, 100) ) self.mRubberBand0.setBorderColor( QColor(0, 0, 0) ) for pt in self.resultPolylineArea.method_14(): self.mRubberBand0.addPoint(pt) # self.mRubberBand0.addGeometry(self.polygonGeom, None) n = self.mRubberBand0.numberOfVertices() self.mRubberBand0.show() self.mRubberBand = None area = None if self.areaType == ProtectionAreaType.Primary: area = PrimaryObstacleArea(self.resultPolylineArea) elif self.areaType == ProtectionAreaType.Secondary: if len(self.resultPolylineArea) == 4: area = SecondaryObstacleArea(self.resultPolylineArea[0].Position, self.resultPolylineArea[1].Position, self.resultPolylineArea[3].Position, self.resultPolylineArea[2].Position, MathHelper.getBearing(self.resultPolylineArea[0].Position, self.resultPolylineArea[1].Position)) else: if self.primaryPolyline.Count < 2: define._messageLabel.setText("The PrimaryLine in Secondary Area must exist.") return if self.isPrimaryPolylineStarted: define._messageLabel.setText("You must finish the input of PrimaryLine.") return area = SecondaryObstacleAreaWithManyPoints(self.resultPolylineArea, self.primaryPolyline) self.emit(SIGNAL("outputResult"), area, self.mRubberBand0) n = 0 def canvasMoveEvent( self, e ): self.rubberBand.reset(QGis.Point) # snapPoint = QgisHelper.snapPoint(e.pos(), self.mSnapper , define._canvas, True) snapPoint, snapPointID, layer = self.snapPoint(e.pos(), True) if snapPoint != None: self.rubberBand.addPoint(snapPoint) self.rubberBand.show() if ( self.mRubberBand == None ): return if ( self.mRubberBand.numberOfVertices() > 0 ): if self.menuString != "Undo": self.mRubberBand.removeLastPoint( 0 ) else: self.menuString = "" point2 = None if snapPoint != None: self.mRubberBand.addPoint( snapPoint) point2 = snapPoint else: self.mRubberBand.addPoint( self.toMapCoordinates( e.pos() ) ) point2 = self.toMapCoordinates( e.pos() ) if self.menuString == "Arc": point0 = self.resultPolylineArea[self.resultPolylineArea.Count - 2].Position point1 = self.resultPolylineArea[self.resultPolylineArea.Count - 1].Position # point2 = self.mRubberBand.getPoint(self.mRubberBand.numberOfVertices() - 1) bulge = MathHelper.smethod_60(point0, point1, point2) self.resultPolylineArea[self.resultPolylineArea.Count - 2].bulge = bulge self.mRubberBand = None QgisHelper.ClearRubberBandInCanvas(define._canvas) self.mRubberBand = QgsRubberBand( self.mCanvas, QGis.Polygon ) self.mRubberBand.setFillColor( self.mFillColor ) self.mRubberBand.setBorderColor( self.mBorderColour ) for pt in self.resultPolylineArea.method_14(): self.mRubberBand.addPoint(pt) self.mRubberBand.addPoint(point2) def snapPoint(self, p, bNone = False): if define._snapping == False: return (define._canvas.getCoordinateTransform().toMapCoordinates( p ), None, None) snappingResults = self.mSnapper.snapToBackgroundLayers( p ) if ( snappingResults[0] != 0 or len(snappingResults[1]) < 1 ): if bNone: return (None, None, None) else: return (define._canvas.getCoordinateTransform().toMapCoordinates( p ), None, None) else: return (snappingResults[1][0].snappedVertex, snappingResults[1][0].snappedAtGeometry, snappingResults[1][0].layer) def deactivate(self): self.rubberBand.reset(QGis.Point) QgsMapTool.deactivate(self) self.emit(SIGNAL("deactivated()"))
class MapToolInteractive(QgsMapTool): """Tool to interact with map, including panning, zooming, and snapping""" def __init__(self, canvas, snappingEnabled=False): super(MapToolInteractive, self).__init__(canvas) self._active = False self._dragging = False self._panningEnabled = False self._zoomingEnabled = False self._zoomRubberBand = None # QgsRubberBand() self._zoomRect = None # QRect() self._snappingEnabled = snappingEnabled self._snapper = None # QgsMapCanvasSnapper() self._snappingMarker = None # QgsVertexMarker() def __del__(self): if self._active: self.deactivate() def isActive(self): return self._active def activate(self): super(MapToolInteractive, self).activate() self._active = True self._startSnapping() def deactivate(self): self._active = False if self._snappingEnabled: self._stopSnapping() if (self._zoomRubberBand is not None): self.canvas().scene().removeItem(self._zoomRubberBand) self._zoomRubberBand = None super(MapToolInteractive, self).deactivate() def setAction(self, action): super(MapToolInteractive, self).setAction(action) self.action().triggered.connect(self._activate) def _activate(self): self.canvas().setMapTool(self) def panningEnabled(self): return self._panningEnabled def setPanningEnabled(self, enabled): self._panningEnabled = enabled def zoomingEnabled(self): return self._zoomingEnabled def setZoomingEnabled(self, enabled): self._zoomingEnabled = enabled def snappingEnabled(self): return self._snappingEnabled def setSnappingEnabled(self, enabled): if (self._snappingEnabled == enabled): return self._snappingEnabled = enabled if not self._active: return if enabled: self._startSnapping() else: self._stopSnapping() def _startSnapping(self): self._snapper = QgsMapCanvasSnapper() self._snapper.setMapCanvas(self.canvas()) def _stopSnapping(self): self._deleteSnappingMarker() self._snapper = None def canvasMoveEvent(self, e): super(MapToolInteractive, self).canvasMoveEvent(e) if not self._active: return e.ignore() if (self._panningEnabled and e.buttons() & Qt.LeftButton): # Pan map mode if not self._dragging: self._dragging = True self.setCursor(QCursor(Qt.ClosedHandCursor)) self.canvas().panAction(e) e.accept() elif (self._zoomingEnabled and e.buttons() & Qt.RightButton): # Zoom map mode if not self._dragging: self._dragging = True self.setCursor(QCursor(Qt.ClosedHandCursor)) self._zoomRubberBand = QgsRubberBand(self.canvas(), QGis.Polygon) color = QColor(Qt.blue) color.setAlpha(63) self._zoomRubberBand.setColor(color) self._zoomRect = QRect(0, 0, 0, 0) self._zoomRect.setTopLeft(e.pos()) self._zoomRect.setBottomRight(e.pos()) if self._zoomRubberBand is not None: self._zoomRubberBand.setToCanvasRectangle(self._zoomRect) self._zoomRubberBand.show() e.accept() elif self._snappingEnabled: mapPoint, mapPointV2, snapped = self._snapCursorPoint(e.pos()) if (snapped): self._createSnappingMarker(mapPoint) else: self._deleteSnappingMarker() def canvasReleaseEvent(self, e): super(MapToolInteractive, self).canvasReleaseEvent(e) e.ignore() if (e.button() == Qt.LeftButton): if self._dragging: # Pan map mode self.canvas().panActionEnd(e.pos()) self.setCursor(CapturePointCursor) self._dragging = False e.accept() elif (e.button() == Qt.RightButton): if self._dragging: # Zoom mode self._zoomRect.setBottomRight(e.pos()) if (self._zoomRect.topLeft() != self._zoomRect.bottomRight()): coordinateTransform = self.canvas().getCoordinateTransform( ) ll = coordinateTransform.toMapCoordinates( self._zoomRect.left(), self._zoomRect.bottom()) ur = coordinateTransform.toMapCoordinates( self._zoomRect.right(), self._zoomRect.top()) r = QgsRectangle() r.setXMinimum(ll.x()) r.setYMinimum(ll.y()) r.setXMaximum(ur.x()) r.setYMaximum(ur.y()) r.normalize() if (r.width() != 0 and r.height() != 0): self.canvas().setExtent(r) self.canvas().refresh() self._dragging = False if (self._zoomRubberBand is not None): self.canvas().scene().removeItem(self._zoomRubberBand) self._zoomRubberBand = None e.accept() def keyPressEvent(self, e): super(MapToolInteractive, self).keyPressEvent(e) if (e.key() == Qt.Key_Escape): self.canvas().unsetMapTool(self) e.accept() def _snapCursorPoint(self, cursorPoint): res, snapResults = self._snapper.snapToBackgroundLayers(cursorPoint) if (res != 0 or len(snapResults) < 1): clicked = self.toMapCoordinates(cursorPoint) clickedV2 = QgsPointV2(clicked) return clicked, clickedV2, False else: # Take a copy as QGIS will delete the result! snapped = QgsPoint(snapResults[0].snappedVertex) snappedV2 = QgsPointV2(snapped) return snapped, snappedV2, True def _createSnappingMarker(self, snapPoint): if (self._snappingMarker is None): self._snappingMarker = QgsVertexMarker(self.canvas()) self._snappingMarker.setIconType(QgsVertexMarker.ICON_CROSS) self._snappingMarker.setColor(Qt.magenta) self._snappingMarker.setPenWidth(3) self._snappingMarker.setCenter(snapPoint) def _deleteSnappingMarker(self): if (self._snappingMarker is not None): self.canvas().scene().removeItem(self._snappingMarker) self._snappingMarker = None