Example #1
0
    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())
Example #2
0
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)
Example #4
0
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()
Example #7
0
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)
Example #9
0
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)
Example #10
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)
Example #11
0
    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)
Example #12
0
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()
Example #13
0
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
Example #14
0
    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')
Example #15
0
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
Example #16
0
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()
Example #17
0
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)
Example #18
0
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()"))
Example #20
0
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