def capture_position(self, event):
        """
        Record the position of the mouse pointer and adjust if keyboard modifier is pressed

        :type event: qgis.gui.QgsMapMouseEvent
        """
        # adjust dimension on the fly if Shift is pressed
        if QApplication.keyboardModifiers() == Qt.ShiftModifier:
            end_point = QgsPointXY(self.toMapCoordinates(event.pos()))
            rect = QgsRectangle(self.startPoint, end_point)

            # return if start and endpoint are the same
            if rect.width() + rect.height() == 0:
                self.endPoint = self.toMapCoordinates(event.pos())
                return

            if rect.width() > rect.height():
                # make height (y) same as width in the correct direction
                if self.startPoint.y() < end_point.y():
                    end_point.setY(self.startPoint.y() + rect.width())
                else:
                    end_point.setY(self.startPoint.y() - rect.width())
            else:
                # make width (x) same as height in the correct direction
                if self.startPoint.x() < end_point.x():
                    end_point.setX(self.startPoint.x() + rect.height())
                else:
                    end_point.setX(self.startPoint.x() - rect.height())

            self.endPoint = end_point
        else:
            self.endPoint = self.toMapCoordinates(event.pos())
    def find_geometric_center(self, list_wp):
        """
        Finds geometric center from a list of waypoints

        :param list_wp: list of waypoints
        :return: geometric center of the list of waypoints
        """
        center = QgsPointXY()
        max_x = None
        min_x = None
        max_y = None
        min_y = None

        # Geometric center
        for i in range(0, len(list_wp)):
            point = list_wp[i]
            if max_x is None or point.x() > max_x:
                max_x = point.x()
            if min_x is None or point.x() < min_x:
                min_x = point.x()
            if max_y is None or point.y() > max_y:
                max_y = point.y()
            if min_y is None or point.y() < min_y:
                min_y = point.y()

        center.setX((max_x + min_x)/2)
        center.setY((max_y + min_y)/2)

        return center
Esempio n. 3
0
    def processAlgorithm(self, parameters, context, feedback):
        layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_VECTOR), context)

        rasterPath = str(self.getParameterValue(self.INPUT_RASTER))

        rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
        geoTransform = rasterDS.GetGeoTransform()
        rasterDS = None

        fields = QgsFields()
        fields.append(QgsField('id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('poly_id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('point_id', QVariant.Int, '', 10, 0))

        writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter(fields, QgsWkbTypes.Point,
                                                                           layer.crs(), context)

        outFeature = QgsFeature()
        outFeature.setFields(fields)

        fid = 0
        polyId = 0
        pointId = 0

        features = QgsProcessingUtils.getFeatures(layer, context)
        total = 100.0 / layer.featureCount() if layer.featureCount() else 0
        for current, f in enumerate(features):
            geom = f.geometry()
            bbox = geom.boundingBox()

            xMin = bbox.xMinimum()
            xMax = bbox.xMaximum()
            yMin = bbox.yMinimum()
            yMax = bbox.yMaximum()

            (startRow, startColumn) = raster.mapToPixel(xMin, yMax, geoTransform)
            (endRow, endColumn) = raster.mapToPixel(xMax, yMin, geoTransform)

            # use prepared geometries for faster intersection tests
            engine = QgsGeometry.createGeometryEngine(geom.geometry())
            engine.prepareGeometry()

            for row in range(startRow, endRow + 1):
                for col in range(startColumn, endColumn + 1):
                    (x, y) = raster.pixelToMap(row, col, geoTransform)
                    point = QgsPointXY()
                    point.setX(x)
                    point.setY(y)

                    if engine.contains(point):
                        outFeature.setGeometry(QgsGeometry(point))
                        outFeature['id'] = fid
                        outFeature['poly_id'] = polyId
                        outFeature['point_id'] = pointId

                        fid += 1
                        pointId += 1

                        writer.addFeature(outFeature, QgsFeatureSink.FastInsert)

            pointId = 0
            polyId += 1

            feedback.setProgress(int(current * total))

        del writer
Esempio n. 4
0
class MapTool(QgsMapTool):
    MODE_NONE = 0
    MODE_PAN = 1
    MODE_ROTATE = 2
    MODE_SCALE = 3
    MODE_SCALE_X = 4
    MODE_SCALE_Y = 5
    MODE_PAN_RESULT = 6
    MODE_NODE = 7
    NODE_NAMES = ['A', 'B', 'C', 'D']

    def __init__(self, widget):
        QgsMapTool.__init__(self, widget.canvas)
        self.widget = widget
        self.canvas = widget.canvas
        self.mode = self.MODE_NONE
        self.selected_node = None

        # clicked point
        self.p0 = None

        # centre rectangle
        self.pX = None

        # rectangle vertices (handles)
        self.pA = None  # hg
        self.pB = None  # hd
        self.pC = None  # bd
        self.pD = None  # bg
        self.zoneWidth = None
        self.zoneDepth = None

        # eye (rotation)
        self.pY = None

        # rectangle
        self.rb = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry)
        self.rb.setStrokeColor(Qt.blue)
        self.rb.setWidth(3)

        self.rbFoc = QgsRubberBand(self.canvas, QgsWkbTypes.LineGeometry)
        self.rbFoc.setStrokeColor(Qt.blue)
        self.rbFoc.setWidth(1)

        # SCALE nodes
        self.rbPA = QgsRubberBand(self.canvas, QgsWkbTypes.PointGeometry)
        self.rbPA.setColor(Qt.red)
        self.rbPA.setWidth(8)
        self.rbPB = QgsRubberBand(self.canvas, QgsWkbTypes.PointGeometry)
        self.rbPB.setColor(Qt.red)
        self.rbPB.setWidth(8)
        self.rbPC = QgsRubberBand(self.canvas, QgsWkbTypes.PointGeometry)
        self.rbPC.setColor(Qt.red)
        self.rbPC.setWidth(8)
        self.rbPD = QgsRubberBand(self.canvas, QgsWkbTypes.PointGeometry)
        self.rbPD.setColor(QColor(255, 50, 150, 255))
        self.rbPD.setWidth(8)
        # scale Y node
        self.rbPH = QgsRubberBand(self.canvas, QgsWkbTypes.PointGeometry)
        self.rbPH.setColor(Qt.red)
        self.rbPH.setWidth(8)
        # scale X node
        self.rbPL = QgsRubberBand(self.canvas, QgsWkbTypes.PointGeometry)
        self.rbPL.setColor(Qt.red)
        self.rbPL.setWidth(8)

        # final pan
        self.rbPan = QgsRubberBand(self.canvas, QgsWkbTypes.PointGeometry)
        self.rbPan.setColor(QColor(0, 200, 50, 255))
        self.rbPan.setWidth(8)

        # ROTATE node
        self.rbPY = QgsRubberBand(self.canvas, QgsWkbTypes.PointGeometry)
        self.rbPY.setColor(Qt.blue)
        self.rbPY.setWidth(6)
        self.rotation = 0.0

        # cutting lines
        self.rbLines = QgsRubberBand(self.canvas, QgsWkbTypes.LineGeometry)
        self.rbLines.setColor(QColor(40, 180, 30, 255))
        self.rbLines.setWidth(1.5)

        # plots
        self.rbPlots = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry)
        self.rbPlots.setStrokeColor(QColor(200, 120, 70, 150))
        self.rbPlots.setWidth(0.8)

        self.rubbers = [
            self.rb,
            self.rbPA,
            self.rbPB,
            self.rbPC,
            self.rbPD,
            self.rbPY,
            self.rbPH,
            self.rbPL,
            self.rbPan,
            self.rbLines,
            self.rbPlots,
            self.rbFoc,
        ]

        self.rowLines = None
        self.columnLines = None
        self.allLines = None

    def hide(self):
        for rb in self.rubbers:
            rb.reset()

    def updateRubberGeom(self):
        if self.pA is None:
            return

        self.zoneWidth = self.pA.distance(self.pB)
        self.zoneDepth = self.pA.distance(self.pD)
        self.pM = QgsPointXY((self.pC.x() + self.pD.x()) / 2,
                             (self.pC.y() + self.pD.y()) / 2)
        self.d0 = self.pM.distance(self.pY)
        # self.widget.updateZ(self.pY)

        self.rb.setToGeometry(
            QgsGeometry.fromPolygonXY(
                [[self.pD, self.pA, self.pB, self.pC, self.pD]]))
        self.rbFoc.setToGeometry(
            QgsGeometry.fromPolylineXY([self.pD, self.pY, self.pC]))

        for p, rb in [
            [self.pA, self.rbPA],
            [self.pB, self.rbPB],
            [self.pC, self.rbPC],
            [self.pD, self.rbPD],
            [self.pY, self.rbPY],
            [self.pH, self.rbPH],
            [self.pL, self.rbPL],
        ]:
            rb.setToGeometry(QgsGeometry.fromPointXY(p))

        leftEdge = (QgsGeometry.fromPolylineXY([
            self.pA, self.pD
        ]).densifyByCount(self.widget.rowCount.value() - 1).asPolyline())
        rightEdge = (QgsGeometry.fromPolylineXY([
            self.pB, self.pC
        ]).densifyByCount(self.widget.rowCount.value() - 1).asPolyline())

        # Plot edges lines
        polyline = list(zip(leftEdge, rightEdge))

        backSide = (QgsGeometry.fromPolylineXY([
            self.pA, self.pB
        ]).densifyByCount(self.widget.columnCount.value() - 1).asPolyline())
        frontSide = (QgsGeometry.fromPolylineXY([
            self.pD, self.pC
        ]).densifyByCount(self.widget.columnCount.value() - 1).asPolyline())
        polylineX = list(zip(frontSide[:], backSide[:]))

        self.finalWidth = self.zoneWidth

        self.rowLines = polyline
        self.columnLines = polylineX
        self.allLines = polyline + polylineX
        self.rbLines.setToGeometry(
            QgsGeometry.fromMultiPolylineXY(
                polylineX + polyline + polyline[::max(1, 1 + len(polyline))]))
        if self.widget.cbReverseRows.isChecked():
            if self.widget.cbReverseColumns.isChecked():
                self.rbPC.setColor(Qt.red)
                self.rbPD.setColor(Qt.red)
                self.rbPA.setColor(Qt.red)
                self.rbPB.setColor(QColor(0, 200, 150, 255))
            else:
                self.rbPC.setColor(Qt.red)
                self.rbPD.setColor(Qt.red)
                self.rbPB.setColor(Qt.red)
                self.rbPA.setColor(QColor(0, 200, 150, 255))
        else:
            if self.widget.cbReverseColumns.isChecked():
                self.rbPA.setColor(Qt.red)
                self.rbPB.setColor(Qt.red)
                self.rbPD.setColor(Qt.red)
                self.rbPC.setColor(QColor(0, 200, 150, 255))
            else:
                self.rbPA.setColor(Qt.red)
                self.rbPB.setColor(Qt.red)
                self.rbPC.setColor(Qt.red)
                self.rbPD.setColor(QColor(0, 200, 150, 255))

        self.widget.alert.setText("Total plots: {}".format(
            self.widget.columnCount.value() * self.widget.rowCount.value()))

    def getLines(self):
        return QgsGeometry.fromMultiPolylineXY(self.rowLines)

    def getSampleLines(self):
        return (
            [self.rowLines[0], self.rowLines[1]] +
            self.rowLines[2:-1][::max(1, 1 +
                                      int((len(self.rowLines) - 3) / 9))] +
            [self.rowLines[-1]])

    def newRubber(self):
        if self.pX is not None:
            self.updateRubberGeom()
            return

        # default parameters
        h = 2 * self.widget.canvas.extent().height() / 3 / 20

        # first bbox, according to current view
        h = self.canvas.extent().height() / 6
        c = self.canvas.extent().center()
        rubberExtent = QgsRectangle(QgsPointXY(c.x() - h,
                                               c.y() - h),
                                    QgsPointXY(c.x() + h,
                                               c.y() + h))
        self.rotation = 0.0
        width = rubberExtent.xMaximum() - rubberExtent.xMinimum()
        height = rubberExtent.yMaximum() - rubberExtent.yMinimum()

        # centre rectangle
        self.pX = QgsPointXY(rubberExtent.xMinimum() + width / 2,
                             rubberExtent.yMinimum() + height / 2)

        self.pA = QgsPointXY(rubberExtent.xMinimum(), rubberExtent.yMaximum())
        self.pB = QgsPointXY(rubberExtent.xMaximum(), rubberExtent.yMaximum())
        self.pC = QgsPointXY(rubberExtent.xMaximum(), rubberExtent.yMinimum())
        self.pD = QgsPointXY(rubberExtent.xMinimum(), rubberExtent.yMinimum())

        # handles H / L
        self.pH = QgsPointXY((self.pA.x() + self.pB.x()) / 2,
                             (self.pA.y() + self.pB.y()) / 2)
        self.pL = QgsPointXY((self.pB.x() + self.pC.x()) / 2,
                             (self.pB.y() + self.pC.y()) / 2)

        # eye (rotation)
        self.pY = QgsPointXY(self.pX.x(), self.pX.y() - 2 * height / 3)

        self.pM = QgsPointXY((self.pC.x() + self.pD.x()) / 2,
                             (self.pC.y() + self.pD.y()) / 2)

        self.rotation_init = self.rotation
        self.pA_init = QgsPointXY(self.pA)
        self.pB_init = QgsPointXY(self.pB)
        self.pC_init = QgsPointXY(self.pC)
        self.pD_init = QgsPointXY(self.pD)
        self.pX_init = QgsPointXY(self.pX)
        self.pY_init = QgsPointXY(self.pY)
        self.pH_init = QgsPointXY(self.pH)
        self.pL_init = QgsPointXY(self.pL)

        self.updateRubberGeom()

    def canvasPressEvent(self, event):
        x = event.pos().x()
        y = event.pos().y()
        self.p0 = self.canvas.getCoordinateTransform().toMapCoordinates(x, y)

        distPA = self.p0.distance(self.pA) / self.canvas.mapUnitsPerPixel()
        distPB = self.p0.distance(self.pB) / self.canvas.mapUnitsPerPixel()
        distPC = self.p0.distance(self.pC) / self.canvas.mapUnitsPerPixel()
        distPD = self.p0.distance(self.pD) / self.canvas.mapUnitsPerPixel()
        distPY = self.p0.distance(self.pY) / self.canvas.mapUnitsPerPixel()
        distPH = self.p0.distance(self.pH) / self.canvas.mapUnitsPerPixel()
        distPL = self.p0.distance(self.pL) / self.canvas.mapUnitsPerPixel()

        edit_individual_node = self.widget.cbIndividualNode.isChecked()

        if distPA < 6 or distPB < 6 or distPC < 6 or distPD < 6:
            if edit_individual_node:
                self.mode = self.MODE_NODE
                val, idx = min(
                    (val, idx)
                    for (idx,
                         val) in enumerate([distPA, distPB, distPC, distPD]))
                self.selected_node = self.NODE_NAMES[idx]
            else:
                self.mode = self.MODE_SCALE
            return

        if distPH < 6:
            self.mode = self.MODE_SCALE_Y
            return

        if distPL < 6:
            self.mode = self.MODE_SCALE_X
            return

        if distPY < 6:
            self.mode = self.MODE_ROTATE
            return

        if self.rb.asGeometry().contains(self.p0):
            self.mode = self.MODE_PAN
            return

    def canvasMoveEvent(self, event):
        if self.mode == self.MODE_NONE:
            return

        x = event.pos().x()
        y = event.pos().y()
        pt = self.canvas.getCoordinateTransform().toMapCoordinates(x, y)
        dx = pt.x() - self.p0.x()
        dy = pt.y() - self.p0.y()

        # node name
        if self.mode == self.MODE_NODE:
            if self.selected_node == 'A':
                self.pA.setX(self.pA_init.x() + dx)
                self.pA.setY(self.pA_init.y() + dy)
            elif self.selected_node == 'B':
                self.pB.setX(self.pB_init.x() + dx)
                self.pB.setY(self.pB_init.y() + dy)
            elif self.selected_node == 'C':
                self.pC.setX(self.pC_init.x() + dx)
                self.pC.setY(self.pC_init.y() + dy)
            elif self.selected_node == 'D':
                self.pD.setX(self.pD_init.x() + dx)
                self.pD.setY(self.pD_init.y() + dy)

        # pan mode
        if self.mode == self.MODE_PAN:
            for p, p_ini in [
                [self.pA, self.pA_init],
                [self.pB, self.pB_init],
                [self.pC, self.pC_init],
                [self.pD, self.pD_init],
                [self.pX, self.pX_init],
                [self.pY, self.pY_init],
                [self.pH, self.pH_init],
                [self.pL, self.pL_init],
            ]:
                p.setX(p_ini.x() + dx)
                p.setY(p_ini.y() + dy)

        # horizontal + vertical sizing
        if self.mode == self.MODE_SCALE:
            d_old = self.pA_init.distance(self.pX_init)
            d_new = pt.distance(self.pX_init)
            dd = d_new / d_old

            for p, p_ini in [
                [self.pA, self.pA_init],
                [self.pB, self.pB_init],
                [self.pC, self.pC_init],
                [self.pD, self.pD_init],
                [self.pY, self.pY_init],
                [self.pH, self.pH_init],
                [self.pL, self.pL_init],
            ]:
                dx = dd * (p_ini.x() - self.pX.x())
                dy = dd * (p_ini.y() - self.pX.y())
                p.setX(self.pX.x() + dx)
                p.setY(self.pX.y() + dy)

        # horizontal sizing
        if self.mode == self.MODE_SCALE_X:
            d_old = self.pL_init.distance(self.pX_init)
            d_new = pt.distance(self.pX_init)
            dd = d_new / d_old
            if dd < 0.001:
                dd = 0.001

            dx = dd * (self.pL_init.x() - self.pX.x())
            dy = dd * (self.pL_init.y() - self.pX.y())
            self.pL.setX(self.pX.x() + dx)
            self.pL.setY(self.pX.y() + dy)

            centre = self.pH
            for p, p_ini in [[self.pA, self.pA_init], [self.pB, self.pB_init]]:
                dx = dd * (p_ini.x() - centre.x())
                dy = dd * (p_ini.y() - centre.y())
                p.setX(centre.x() + dx)
                p.setY(centre.y() + dy)

            centre = self.pM
            for p, p_ini in [[self.pC, self.pC_init], [self.pD, self.pD_init]]:
                dx = dd * (p_ini.x() - centre.x())
                dy = dd * (p_ini.y() - centre.y())
                p.setX(centre.x() + dx)
                p.setY(centre.y() + dy)

        # vertical sizing
        if self.mode == self.MODE_SCALE_Y:
            d_old = self.pH_init.distance(self.pX_init)
            d_new = pt.distance(self.pX_init)
            dd = d_new / d_old
            if dd < 0.001:
                dd = 0.001

            dx = dd * (self.pH_init.x() - self.pX.x())
            dy = dd * (self.pH_init.y() - self.pX.y())
            self.pH.setX(self.pX.x() + dx)
            self.pH.setY(self.pX.y() + dy)

            centre = self.pL
            for p, p_ini in [[self.pB, self.pB_init], [self.pC, self.pC_init]]:
                dx = dd * (p_ini.x() - centre.x())
                dy = dd * (p_ini.y() - centre.y())
                p.setX(centre.x() + dx)
                p.setY(centre.y() + dy)

            centre = QgsPointXY((self.pA.x() + self.pD.x()) / 2,
                                (self.pA.y() + self.pD.y()) / 2)
            for p, p_ini in [[self.pA, self.pA_init], [self.pD, self.pD_init]]:
                dx = dd * (p_ini.x() - centre.x())
                dy = dd * (p_ini.y() - centre.y())
                p.setX(centre.x() + dx)
                p.setY(centre.y() + dy)

        if self.mode == self.MODE_ROTATE:
            self.pY.setX(self.pY_init.x() + dx)
            self.pY.setY(self.pY_init.y() + dy)

            azimuth = self.pX.azimuth(pt)
            theta = azimuth - self.rotation_init + 180
            self.rotation = self.rotation_init + theta

            for a, i in [
                [self.pA, self.pA_init],
                [self.pB, self.pB_init],
                [self.pC, self.pC_init],
                [self.pD, self.pD_init],
                [self.pH, self.pH_init],
                [self.pL, self.pL_init],
            ]:
                A = QgsGeometry.fromPointXY(i)
                A.rotate(theta, self.pX)
                a.setX(A.asPoint().x())
                a.setY(A.asPoint().y())

        self.updateRubberGeom()

    def canvasReleaseEvent(self, event):
        self.pA_init = QgsPointXY(self.pA)
        self.pB_init = QgsPointXY(self.pB)
        self.pC_init = QgsPointXY(self.pC)
        self.pD_init = QgsPointXY(self.pD)
        self.pX_init = QgsPointXY(self.pX)
        self.pY_init = QgsPointXY(self.pY)
        self.pH_init = QgsPointXY(self.pH)
        self.pL_init = QgsPointXY(self.pL)
        self.rotation_init = self.rotation

        self.mode = self.MODE_NONE

    def activate(self):
        pass

    def deactivate(self):
        self.hide()

    def isZoomTool(self):
        return False

    def isTransient(self):
        return False

    def isEditTool(self):
        return True
Esempio n. 5
0
    def processAlgorithm(self, parameters, context, feedback):
        # gather parameters
        extent = self.parameterAsExtent(parameters, self.PrmExtent, context,
                                        epsg4326)
        lineDistance = self.parameterAsDouble(parameters, self.PrmLineDistance,
                                              context)
        traceInterval = self.parameterAsDouble(parameters,
                                               self.PrmTraceInterval, context)
        distanceTolerance = self.parameterAsDouble(parameters,
                                                   self.PrmDistanceTolerance,
                                                   context)
        variationTolerance = self.parameterAsDouble(parameters,
                                                    self.PrmVariationTolerance,
                                                    context)
        units = self.parameterAsInt(parameters, self.PrmUnitsOfMeasure,
                                    context)
        measureFactor = conversionToMeters(units)

        # adjust linear units
        lineDistance *= measureFactor
        traceInterval *= measureFactor
        distanceTolerance *= measureFactor

        f = QgsFields()
        f.append(QgsField("trace", QVariant.Int))
        f.append(QgsField("variation", QVariant.Double))

        # obtain our output sink
        (sink, dest_id) = self.parameterAsSink(parameters, self.PrmOutputLayer,
                                               context, f,
                                               QgsWkbTypes.LineString,
                                               epsg4326)

        # Determine the longitude step direction based on sign of the variation in the extent's center,
        # so that we start on the side of the extent such that we will fill in partial lines at the corner.
        # TODO: this is not ideal when the extent intersects an agonic line.
        centerVar = geomag.declination(extent.center().y(),
                                       extent.center().x(), 0, date.today())
        start = QgsPointXY(extent.xMinimum(), extent.yMinimum())
        if centerVar > 0:
            lineDistance = -lineDistance
            start.setX(extent.xMaximum())

        # We trace between points at a fixed longitude interval, so that the distance-preservation logic below
        # is straightforward and we can compare points in successive traces easily.
        traceIntervalDeg = traceInterval * metersToDeg
        numTraces = math.ceil(extent.height() / traceIntervalDeg)
        traceY = extent.height() / numTraces

        lineCount = 0
        lastStartPoints = []

        # Our major (longitude) loop starts here
        while not feedback.isCanceled():
            # Initialize our line at the start
            empty = True
            line = []
            startPoints = []

            # Add the first point
            p1 = start
            if p1.x() >= extent.xMinimum() and p1.x() <= extent.xMaximum():
                line.append(p1)
                empty = False

            # Now we will trace the line in the field direction until we are out of the rectangle's Y range,
            # restarting a new line whenever the horizontal step gets out of whack due to latitude change.

            for t in range(0, numTraces + 1):
                if feedback.isCanceled():
                    break

                y = extent.yMinimum() + (t * traceY)

                # get the variation at this point
                variation = geomag.declination(p1.y(), p1.x(), 0, date.today())
                if t == 0:
                    lastVariation = variation  # record last used variation in this polyline for error computation

                # determine a 1-meter vector in the direction of magnetic north
                # and scale this to find a vector taking us from p1 to the next latitude step
                magN = projectBearing(p1, 1, variation)
                magN.multiply(
                    (y - p1.y()) / magN.y()
                )  # note that Y magnitude will be nonzero for reasonable variations
                p2 = addPoints(p1, magN)

                if p2.x() >= extent.xMinimum() and p2.x() <= extent.xMaximum():
                    line.append(p2)
                    empty = False

                # start a new, longitudinally adjusted line if distance exceeds tolerance
                if distanceTolerance > 0 and len(lastStartPoints) > t:
                    lastP2 = lastStartPoints[t]
                    (factor, nextX) = self.adjustLongForVariation(
                        lastP2, lineDistance, variation)
                    if abs(p2.x() - nextX) > distanceTolerance * factor:
                        # Flush any line that is in progress
                        if len(line) >= 2:
                            feature = QgsFeature()
                            feature.setAttributes([lineCount, variation])
                            feature.setGeometry(
                                QgsGeometry.fromPolylineXY(line))
                            sink.addFeature(feature)

                        # Now start a new line, properly spaced from the previous trace
                        p2 = QgsPointXY(nextX, p2.y())
                        line = []
                        if p2.x() >= extent.xMinimum() and p2.x(
                        ) <= extent.xMaximum():
                            line.append(p2)
                            empty = False

                # if we didn't do that, and variation error exceeds tolerance, then start a new line in the same spot
                elif variationTolerance > 0 and abs(
                        variation - lastVariation) > variationTolerance:
                    # Flush any line that is in progress and start a new line in the same spot
                    if len(line) >= 2:
                        feature = QgsFeature()
                        feature.setAttributes([lineCount, variation])
                        feature.setGeometry(QgsGeometry.fromPolylineXY(line))
                        sink.addFeature(feature)
                    line = [p2]
                    lastVariation = variation

                startPoints.append(p2)
                p1 = p2

            # end field tracing loop

            # Flush any accumulated points to a polyline
            if len(line) >= 2:
                feature = QgsFeature()
                feature.setAttributes([lineCount, variation])
                feature.setGeometry(QgsGeometry.fromPolylineXY(line))
                sink.addFeature(feature)

            # If we did not manage to find any points inside the extent on this trace, we're done
            if empty:
                break

            # hold onto our point list for spacing check on the next trace
            lastStartPoints = startPoints

            # now advance the start point longitude, correcting for the variation angle
            variation = geomag.declination(start.y(), start.x(), 0,
                                           date.today())
            (factor,
             nextX) = self.adjustLongForVariation(start, lineDistance,
                                                  variation)
            start.setX(nextX)

            lineCount += 1
            if lineDistance > 0:
                feedback.setProgress(100 * (start.x() - extent.xMinimum()) /
                                     extent.width())
            else:
                feedback.setProgress(100 * (extent.xMaximum() - start.x()) /
                                     extent.width())

        # end longitude loop

        if context.willLoadLayerOnCompletion(dest_id):
            context.layerToLoadOnCompletionDetails(dest_id).setPostProcessor(
                StylePostProcessor.create(self))

        return {self.PrmOutputLayer: dest_id}
Esempio n. 6
0
    def t0_Update_Pipeline_Layer(self):
        nodes_file = self.dlg.lineEdit_22.text()
        # ogr2ogr.main(["","-f", "ESRI Shapefile", "-s_srs", "epsg:32643", "-t_srs", "epsg:4326", "newp.shp", nodes_file])
        nodeLyr = QgsVectorLayer(nodes_file, "nodes", "ogr")
        pipes_file = self.dlg.lineEdit_21.text()
        # ogr2ogr.main(["","-f", "ESRI Shapefile", "-s_srs", "epsg:32643", "-t_srs", "epsg:4326", "newl.shp", pipes_file])
        # pipeLyr = QgsVectorLayer(pipes_file, "updated pipes", "ogr")
        vl = QgsVectorLayer("Point?crs=epsg:4326", "temporary_points",
                            "memory")
        pr = vl.dataProvider()

        #setting up reprojection for temporary points
        epsg4326 = QgsCoordinateReferenceSystem(
            4326, QgsCoordinateReferenceSystem.EpsgCrsId)
        self.reprojectgeographic = QgsCoordinateTransform(
            self.iface.mapCanvas().mapSettings().destinationCrs(), epsg4326,
            QgsProject.instance())
        # Enter editing mode
        vl.startEditing()
        # add fields
        pr.addAttributes([
            QgsField("id", QVariant.Int),
            QgsField("Name", QVariant.String),
            # QgsField("Latitude", QVariant.String),
            # QgsField("Longuitude", QVariant.String),
            # QgsField("Coordinates", QVariant.String),
            QgsField("GL(m)", QVariant.String),
            # QgsField("Dem.(lps)", QVariant.Int),
            # QgsField("Active", QVariant.String),
            QgsField("Dem.(lps)", QVariant.String)
        ])
        vl.commitChanges()
        pt = QgsPointXY()
        fields = vl.fields()
        feature = QgsFeature()
        feature.setFields(fields)
        feature = feature.attributes()
        outFeature = QgsFeature()
        # QgsProject.instance().addMapLayer(vl)
        caps = vl.dataProvider().capabilities()
        # attrs = vl.feature()
        if caps & QgsVectorDataProvider.AddFeatures:
            for feat in nodeLyr.getFeatures():
                # feat = QgsFeature(vl.fields())
                feature[0] = feat.attributes()[0]
                feature[1] = feat.attributes()[1]
                feature[2] = feat.attributes()[5].split(' ')[0]
                # feature[3] = NULL
                pt.setX(float(feat["Coordinates"].split(',')[0]))
                pt.setY(float(feat["Coordinates"].split(',')[1]))
                # pt.setX(float(feat["X"]))
                # pt.setY(float(feat["Y"]))
                outFeature.setGeometry(QgsGeometry.fromPointXY(pt))
                outFeature.setAttributes(feature)
                # outFeature.setGeometry(float(feat["Longitude"]),float(feat["Latitude"]))
                pr.addFeature(outFeature)
                vl.updateExtents()
            # outLayer.addFeature(outFeature)
            # geom = feature.geometry()
            # geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType())
            # res, outFeats = vl.addFeature(outFeature)
        error_node = QgsVectorFileWriter.writeAsVectorFormat(
            vl, pipes_file, "UTF-8", epsg4326, "ESRI Shapefile")
        # QgsProject.instance().addMapLayer(vl)
        Lyr = QgsVectorLayer(pipes_file, "Nodes", "ogr")
        QgsProject.instance().addMapLayer(Lyr)
        QgsProject.instance().addMapLayer(vl)
        return
Esempio n. 7
0
    def writeShapefile(self, filename, shape_type):

        if filename[-4:] != '.shp':
            filename += '.shp'

        proj = QgsProject.instance()
        crs = proj.crs()
        #Create new shapefile object, loop trough triangle edges and add each
        # edge as a line.
        if shape_type == 'points':
            shape = QgsWkbTypes.Point
            fields = QgsFields()
            fields.append(QgsField("Id", QVariant.Int, 'integer', 9, 0))
            fields.append(QgsField("Depth", QVariant.Double, 'double', 9, 3))
            fields.append(QgsField("Connect", QVariant.Int, 'integer', 2, 0))

        elif shape_type == 'edges':
            shape = QgsWkbTypes.LineString
            fields = QgsFields()
            fields.append(QgsField("Id", QVariant.Int, 'integer', 9, 0))
            fields.append(QgsField("Flag", QVariant.Int, 'integer', 2, 0))
            fields.append(QgsField("Name", QVariant.String, 'string', 10, 0))

        elif shape_type == 'faces':
            shape = QgsWkbTypes.Polygon
            fields = QgsFields()
            fields.append(QgsField("Id", QVariant.Int, 'integer', 9, 0))
            fields.append(QgsField("Node1", QVariant.Int, 'integer', 11, 0))
            fields.append(QgsField("Node2", QVariant.Int, 'integer', 11, 0))
            fields.append(QgsField("Node3", QVariant.Int, 'integer', 11, 0))
            fields.append(QgsField("Node4", QVariant.Int, 'integer', 11, 0))
            fields.append(QgsField("type", QVariant.Int, 'integer', 1, 0))
            fields.append(QgsField("area", QVariant.Int, 'integer', 9, 0))
            fields.append(QgsField("volume", QVariant.Int, 'integer', 9, 0))
            fields.append(QgsField("depth", QVariant.Double, 'double', 9, 2))
            fields.append(QgsField("resolution", QVariant.Int, 'integer', 9,
                                   0))
            fields.append(QgsField("ETA", QVariant.Double, 'double', 3, 2))
            fields.append(QgsField("NSR", QVariant.Double, 'double', 3, 2))
            fields.append(QgsField("Angle", QVariant.Double, 'double', 3, 2))

        fileWriter = QgsVectorFileWriter(filename, "system", fields, shape,
                                         crs, "ESRI Shapefile")

        if fileWriter.hasError() != QgsVectorFileWriter.NoError:
            raise Exception('Error when creating shapefile ' + filename +
                            ' : ' + str(fileWriter.hasError()))

        if shape_type == 'points':
            for node in range(0, len(self.x)):
                point = QgsPointXY()
                point.setX(self.x[node])
                point.setY(self.y[node])
                newFeature = QgsFeature()
                newFeature.setGeometry(QgsGeometry.fromPointXY(point))
                newFeature.setFields(fields)
                newFeature.setAttributes([
                    int(node + 1),
                    float('%9.3f' % self.z[node]),
                    int(self.conn[node])
                ])
                fileWriter.addFeature(newFeature)

        if shape_type == 'edges':

            for key in self.physical:
                edgID = np.nonzero(
                    np.logical_or(self.physicalID == self.physical[key][0],
                                  np.asarray(self.physicalID) == 0))[0]
                points = []
                edgeN = 0
                for i, edg in enumerate(edgID):
                    if self.physicalID[edg] > 0:
                        points.append(
                            QgsPointXY(self.x[self.edges[edg]],
                                       self.y[self.edges[edg]]))
                    elif len(points) > 0:
                        newFeature = QgsFeature()
                        newFeature.setGeometry(
                            QgsGeometry.fromPolylineXY(points))
                        newFeature.setFields(fields)
                        newFeature.setAttributes(
                            [int(edgeN + 1),
                             int(self.physical[key][0]), key])
                        fileWriter.addFeature(newFeature)
                        points = []
                        edgeN += 1

        if shape_type == 'faces':
            for ie in range(0, len(self.faces)):
                if self.faces[ie, -1] < 0:
                    nface = 3
                else:
                    nface = 4

                points = []
                for fc in range(0, nface):
                    i = self.faces[ie, fc]
                    points.append(QgsPointXY(self.x[i], self.y[i]))

                i = self.faces[ie, 0]
                points.append(QgsPointXY(self.x[i], self.y[i]))
                newFeature = QgsFeature()
                newFeature.setGeometry(QgsGeometry.fromPolygonXY([points]))
                newFeature.setFields(fields)
                newFeature.setAttributes([int(ie+1),\
                    int(self.faces[ie,0]+1),int(self.faces[ie,1]+1),int(self.faces[ie,2]+1),int(self.faces[ie,3]+1),\
                    int(nface),\
                    float('%9.f' % self.areas[ie]),float('%9.f' % self.volumes[ie]),float('%9.2f' % self.zctr[ie]),float('%9.f' % self.res[ie]),\
                    float('%3.2f' % self.eta[ie]),float('%3.2f' % self.nsr[ie]),float('%3.2f' % self.min_angle[ie])])
                fileWriter.addFeature(newFeature)

        del fileWriter