def processAlgorithm(self, parameters, context, feedback):
        raster =  self.parameterAsRasterLayer(parameters, self.PrmInput, context)
        out_path = self.parameterAsOutputLayer(parameters, self.PrmOutputRaster, context)
        north = self.parameterAsDouble(parameters, self.PrmNorthLatitude, context)
        south = self.parameterAsDouble(parameters, self.PrmSouthLatitude, context)
        east = self.parameterAsDouble(parameters, self.PrmEastLongitude, context)
        west = self.parameterAsDouble(parameters, self.PrmWestLongitude, context)
        rotation = self.parameterAsDouble(parameters, self.PrmRotation, context)

        if rotation == 0:
            status = processing.run("gdal:translate", {'INPUT': raster,
                    'EXTRA': '-a_srs EPSG:4326 -a_ullr {} {} {} {}'.format(west, north, east, south),
                    'DATA_TYPE': 0,
                    'OUTPUT': out_path})
        else:
            rwidth = raster.width()
            rheight = raster.height()
            center_x = (east + west) / 2.0
            center_y = (north + south)/ 2.0
            center_pt = QgsPointXY(center_x, center_y)
            ul_pt = QgsPointXY(west, north)
            ur_pt = QgsPointXY(east, north)
            lr_pt = QgsPointXY(east, south)
            ll_pt = QgsPointXY(west, south)
            distance = center_pt.distance(ul_pt)
            az = center_pt.azimuth(ul_pt) - rotation
            pt1 = center_pt.project(distance, az)
            az = center_pt.azimuth(ur_pt) - rotation
            pt2 = center_pt.project(distance, az)
            az = center_pt.azimuth(lr_pt) - rotation
            pt3 = center_pt.project(distance, az)
            az = center_pt.azimuth(ll_pt) - rotation
            pt4 = center_pt.project(distance, az)
            gcp1= '-gcp {} {} {} {}'.format(0,0, pt1.x(), pt1.y())
            gcp2= '-gcp {} {} {} {}'.format(rwidth,0, pt2.x(), pt2.y())
            gcp3= '-gcp {} {} {} {}'.format(rwidth, rheight, pt3.x(), pt3.y())
            gcp4= '-gcp {} {} {} {}'.format(0, rheight, pt4.x(), pt4.y())
            

            status = processing.run("gdal:translate", {'INPUT': raster,
                    'EXTRA': '-a_srs EPSG:4326 -a_nodata 0,0,0 {} {} {} {}'.format(gcp1, gcp2, gcp3, gcp4),
                    'DATA_TYPE': 0,
                    'OUTPUT': out_path})
        feedback.pushInfo('{}'.format(status))
        results = {}
        results[self.PrmOutputRaster] = out_path
        return (results)
    def theMaker(self, aDict, alayer):
        feats = []
        for i in range(0, len(aDict) - 1):
            frwrd = QgsPointXY(aDict[i][1])  # start point
            rvrs = QgsPointXY(aDict[i + 1][1])  # second point
            az = frwrd.azimuth(rvrs)
            distance = math.sqrt(frwrd.sqrDist(rvrs))
            c = Calculus.getSemiMajorAndSemiMinorAxis(self, alayer)
            a = Calculus.getGeographicCoordinates(self, alayer, rvrs.x(),
                                                  rvrs.y())
            conv = Calculus.calculateConvergence(self, a.x(), a.y(), c[0],
                                                 c[1])
            if az < 0:
                az += 360
            azm = az + conv
            longitude = Calculus.dd2dms(
                self,
                Calculus.getGeographicCoordinates(self, alayer,
                                                  aDict[i][1].x(),
                                                  aDict[i][1].y()).x())
            latitude = Calculus.dd2dms(
                self,
                Calculus.getGeographicCoordinates(self, alayer,
                                                  aDict[i][1].x(),
                                                  aDict[i][1].y()).y())
            fet = QgsFeature()
            geom = QgsGeometry().fromPointXY(aDict[0][1])
            fet.setGeometry(geom)
            feats.append(fet)
            fet.setAttributes([
                list(aDict.keys())[i], aDict[i][0], aDict[i][1].x(),
                aDict[i][1].y(), longitude, latitude, aDict[i + 1][0],
                Calculus.dd2dms(self, azm), distance
            ])

        return feats
Ejemplo n.º 3
0
    def testMeasureLineProjected(self):
        #   +-+
        #   | |
        # +-+ +
        # test setting/getting the source CRS
        da_3068 = QgsDistanceArea()
        da_wsg84 = QgsDistanceArea()

        da_3068.setSourceCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:3068'), QgsProject.instance().transformContext())
        if (da_3068.sourceCrs().isGeographic()):
            da_3068.setEllipsoid(da_3068.sourceCrs().ellipsoidAcronym())
        print(("setting [{}] srid [{}] description [{}]".format(u'Soldner Berlin', da_3068.sourceCrs().authid(), da_3068.sourceCrs().description())))
        self.assertEqual(da_3068.sourceCrs().authid(), 'EPSG:3068')
        da_wsg84.setSourceCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:4326'), QgsProject.instance().transformContext())
        if (da_wsg84.sourceCrs().isGeographic()):
            da_wsg84.setEllipsoid(da_wsg84.sourceCrs().ellipsoidAcronym())
        self.assertEqual(da_wsg84.sourceCrs().authid(), 'EPSG:4326')
        print(("setting [{}] srid [{}] description [{}] isGeographic[{}]".format(u'Wsg84', da_wsg84.sourceCrs().authid(), da_wsg84.sourceCrs().description(), da_wsg84.sourceCrs().isGeographic())))
        # print(("-- projectionAcronym[{}] ellipsoidAcronym[{}] toWkt[{}] mapUnits[{}] toProj4[{}]".format(da_wsg84.sourceCrs().projectionAcronym(),da_wsg84.sourceCrs().ellipsoidAcronym(), da_wsg84.sourceCrs().toWkt(),da_wsg84.sourceCrs().mapUnits(),da_wsg84.sourceCrs().toProj4())))
        print(("Testing Position change for[{}] years[{}]".format(u'Ampelanlage - Potsdamer Platz, Verkehrsinsel', u'1924 and 1998')))

        # 1924-10-24 SRID=3068;POINT(23099.49 20296.69)
        # 1924-10-24 SRID=4326;POINT(13.37650707988041 52.50952361017194)
        # 1998-10-02 SRID=3068;POINT(23082.30 20267.80)
        # 1998-10-02 SRID=4326;POINT(13.37625537334001 52.50926345498337)
        # values returned by SpatiaLite
        point_soldner_1924 = QgsPointXY(23099.49, 20296.69)
        point_soldner_1998 = QgsPointXY(23082.30, 20267.80)
        distance_soldner_meters = 33.617379
        azimuth_soldner_1924 = 3.678339
        # ST_Transform(point_soldner_1924,point_soldner_1998,4326)
        point_wsg84_1924 = QgsPointXY(13.37650707988041, 52.50952361017194)
        point_wsg84_1998 = QgsPointXY(13.37625537334001, 52.50926345498337)
        # ST_Distance(point_wsg84_1924,point_wsg84_1998,1)
        distance_wsg84_meters = 33.617302
        # ST_Distance(point_wsg84_1924,point_wsg84_1998)
        # distance_wsg84_mapunits=0.000362
        distance_wsg84_mapunits_format = QgsDistanceArea.formatDistance(0.000362, 7, QgsUnitTypes.DistanceDegrees, True)
        # ST_Azimuth(point_wsg84_1924,point_wsg84_1998)
        azimuth_wsg84_1924 = 3.674878
        # ST_Azimuth(point_wsg84_1998,point_wsg84_1998)
        azimuth_wsg84_1998 = 0.533282
        # ST_Project(point_wsg84_1924,33.617302,3.674878)
        # SRID=4326;POINT(13.37625537318728 52.50926345503591)
        point_soldner_1998_project = QgsPointXY(13.37625537318728, 52.50926345503591)
        # ST_Project(point_wsg84_1998,33.617302,0.533282)
        # SRID=4326;POINT(13.37650708009255 52.50952361009799)
        point_soldner_1924_project = QgsPointXY(13.37650708009255, 52.50952361009799)

        distance_qpoint = point_soldner_1924.distance(point_soldner_1998)
        azimuth_qpoint = point_soldner_1924.azimuth(point_soldner_1998)
        point_soldner_1998_result = point_soldner_1924.project(distance_qpoint, azimuth_qpoint)

        point_soldner_1924_result = QgsPointXY(0, 0)
        point_soldner_1998_result = QgsPointXY(0, 0)
        # Test meter based projected point from point_1924 to point_1998
        length_1998_mapunits, point_soldner_1998_result = da_3068.measureLineProjected(point_soldner_1924, distance_soldner_meters, azimuth_qpoint)
        self.assertEqual(point_soldner_1998_result.toString(6), point_soldner_1998.toString(6))
        # Test degree based projected point from point_1924 1 meter due East
        point_wsg84_meter_result = QgsPointXY(0, 0)
        point_wsg84_1927_meter = QgsPointXY(13.37652180838435, 52.50952361017102)
        length_meter_mapunits, point_wsg84_meter_result = da_wsg84.measureLineProjected(point_wsg84_1924, 1.0, (math.pi / 2))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, QgsUnitTypes.DistanceDegrees, True), '0.0000147 deg')
        self.assertEqual(point_wsg84_meter_result.toString(7), point_wsg84_1927_meter.toString(7))

        point_wsg84_1998_result = QgsPointXY(0, 0)
        length_1928_mapunits, point_wsg84_1998_result = da_wsg84.measureLineProjected(point_wsg84_1924, distance_wsg84_meters, azimuth_wsg84_1924)
        self.assertEqual(QgsDistanceArea.formatDistance(length_1928_mapunits, 7, QgsUnitTypes.DistanceDegrees, True), distance_wsg84_mapunits_format)
        self.assertEqual(point_wsg84_1998_result.toString(7), point_wsg84_1998.toString(7))
Ejemplo n.º 4
0
class GPSMarker(QgsMapCanvasItem):
    def __init__(self, canvas):
        super(GPSMarker, self).__init__(canvas)
        self.canvas = canvas
        self._quaility = 0
        self._heading = 0
        self.size = roam.config.settings.get('gps', {}).get('marker_size', 24)
        self.red = Qt.darkRed
        self.blue = QColor(129, 173, 210)
        self.green = Qt.darkGreen
        self._gpsinfo = QgsGpsInformation()

        self.pointbrush = QBrush(self.red)
        self.pointpen = QPen(Qt.black)
        self.pointpen.setWidth(1)
        self.map_pos = QgsPoint(0.0, 0.0)
        self.gps = None

    def setgps(self, gps):
        self.gps = gps

    def setSize(self, size):
        self.size = size

    def paint(self, painter, xxx, xxx2):
        self.setPos(self.toCanvasCoordinates(self.map_pos))

        halfSize = self.size / 2.0
        rect = QRectF(0 - halfSize, 0 - halfSize, self.size, self.size)
        painter.setRenderHint(QPainter.Antialiasing)
        if self.quality == 0:
            color = self.red
        elif self.quality == 1:
            color = self.green
        elif self.quality >= 2:
            color = self.blue
        else:
            color = self.red

        self.pointpen.setColor(Qt.gray)
        self.pointpen.setWidth(2)
        self.pointbrush.setColor(color)

        painter.setBrush(self.pointbrush)
        painter.setPen(self.pointpen)
        y = 0 - halfSize
        x = rect.width() / 2 - halfSize
        line = QLine(x, y, x, rect.height() - halfSize)
        y = rect.height() / 2 - halfSize
        x = 0 - halfSize
        line2 = QLine(x, y, rect.width() - halfSize, y)

        # Arrow
        p = QPolygonF()
        p.append(QPoint(0 - halfSize, 0))
        p.append(QPoint(0, -self.size))
        x = rect.width() - halfSize
        p.append(QPoint(x, 0))
        p.append(QPoint(0, 0))

        offsetp = QPolygonF()
        offsetp.append(QPoint(0 - halfSize, 0))
        offsetp.append(QPoint(0, -self.size))
        x = rect.width() - halfSize
        offsetp.append(QPoint(x, 0))
        offsetp.append(QPoint(0, 0))

        waypoint = self.gps.waypoint
        if waypoint:
            az = self.map_pos.azimuth(waypoint)

            painter.save()
            painter.rotate(az)
            self.pointbrush.setColor(Qt.red)
            painter.setBrush(self.pointbrush)
            path = QPainterPath()
            path.addPolygon(offsetp)
            painter.drawPath(path)
            painter.restore()

        painter.save()
        painter.rotate(self._heading)
        path = QPainterPath()
        path.addPolygon(p)
        painter.drawPath(path)

        painter.restore()
        painter.drawEllipse(rect)
        painter.drawLine(line)
        painter.drawLine(line2)

    def boundingRect(self):
        halfSize = self.size / 2.0
        size = self.size * 2
        return QRectF(-size, -size, 2.0 * size, 2.0 * size)

    @property
    def quality(self):
        return self._gpsinfo.quality

    @quality.setter
    def quality(self, value):
        self._quaility = value
        self.update()

    def setCenter(self, map_pos, gpsinfo):
        self._heading = gpsinfo.direction
        self._gpsinfo = gpsinfo
        self.map_pos = QgsPointXY(map_pos)
        self.setPos(self.toCanvasCoordinates(self.map_pos))

    def updatePosition(self):
        self.setCenter(self.map_pos, self._gpsinfo)
Ejemplo n.º 5
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
Ejemplo n.º 6
0
    def testMeasureLineProjected(self):
        #   +-+
        #   | |
        # +-+ +
        # test setting/getting the source CRS
        da_3068 = QgsDistanceArea()
        da_wsg84 = QgsDistanceArea()

        da_3068.setSourceCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:3068'), QgsProject.instance().transformContext())
        if (da_3068.sourceCrs().isGeographic()):
            da_3068.setEllipsoid(da_3068.sourceCrs().ellipsoidAcronym())
        print(("setting [{}] srid [{}] description [{}]".format(u'Soldner Berlin', da_3068.sourceCrs().authid(), da_3068.sourceCrs().description())))
        self.assertEqual(da_3068.sourceCrs().authid(), 'EPSG:3068')
        da_wsg84.setSourceCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:4326'), QgsProject.instance().transformContext())
        if (da_wsg84.sourceCrs().isGeographic()):
            da_wsg84.setEllipsoid(da_wsg84.sourceCrs().ellipsoidAcronym())
        self.assertEqual(da_wsg84.sourceCrs().authid(), 'EPSG:4326')
        print(("setting [{}] srid [{}] description [{}] isGeographic[{}]".format(u'Wsg84', da_wsg84.sourceCrs().authid(), da_wsg84.sourceCrs().description(), da_wsg84.sourceCrs().isGeographic())))
        # print(("-- projectionAcronym[{}] ellipsoidAcronym[{}] toWkt[{}] mapUnits[{}] toProj4[{}]".format(da_wsg84.sourceCrs().projectionAcronym(),da_wsg84.sourceCrs().ellipsoidAcronym(), da_wsg84.sourceCrs().toWkt(),da_wsg84.sourceCrs().mapUnits(),da_wsg84.sourceCrs().toProj4())))
        print(("Testing Position change for[{}] years[{}]".format(u'Ampelanlage - Potsdamer Platz, Verkehrsinsel', u'1924 and 1998')))

        # 1924-10-24 SRID=3068;POINT(23099.49 20296.69)
        # 1924-10-24 SRID=4326;POINT(13.37650707988041 52.50952361017194)
        # 1998-10-02 SRID=3068;POINT(23082.30 20267.80)
        # 1998-10-02 SRID=4326;POINT(13.37625537334001 52.50926345498337)
        # values returned by SpatiaLite
        point_soldner_1924 = QgsPointXY(23099.49, 20296.69)
        point_soldner_1998 = QgsPointXY(23082.30, 20267.80)
        distance_soldner_meters = 33.617379
        azimuth_soldner_1924 = 3.678339
        # ST_Transform(point_soldner_1924,point_soldner_1998,4326)
        point_wsg84_1924 = QgsPointXY(13.37650707988041, 52.50952361017194)
        point_wsg84_1998 = QgsPointXY(13.37625537334001, 52.50926345498337)
        # ST_Distance(point_wsg84_1924,point_wsg84_1998,1)
        distance_wsg84_meters = 33.617302
        # ST_Distance(point_wsg84_1924,point_wsg84_1998)
        # distance_wsg84_mapunits=0.000362
        distance_wsg84_mapunits_format = QgsDistanceArea.formatDistance(0.000362, 7, QgsUnitTypes.DistanceDegrees, True)
        # ST_Azimuth(point_wsg84_1924,point_wsg84_1998)
        azimuth_wsg84_1924 = 3.674878
        # ST_Azimuth(point_wsg84_1998,point_wsg84_1998)
        azimuth_wsg84_1998 = 0.533282
        # ST_Project(point_wsg84_1924,33.617302,3.674878)
        # SRID=4326;POINT(13.37625537318728 52.50926345503591)
        point_soldner_1998_project = QgsPointXY(13.37625537318728, 52.50926345503591)
        # ST_Project(point_wsg84_1998,33.617302,0.533282)
        # SRID=4326;POINT(13.37650708009255 52.50952361009799)
        point_soldner_1924_project = QgsPointXY(13.37650708009255, 52.50952361009799)

        distance_qpoint = point_soldner_1924.distance(point_soldner_1998)
        azimuth_qpoint = point_soldner_1924.azimuth(point_soldner_1998)
        point_soldner_1998_result = point_soldner_1924.project(distance_qpoint, azimuth_qpoint)

        point_soldner_1924_result = QgsPointXY(0, 0)
        point_soldner_1998_result = QgsPointXY(0, 0)
        # Test meter based projected point from point_1924 to point_1998
        length_1998_mapunits, point_soldner_1998_result = da_3068.measureLineProjected(point_soldner_1924, distance_soldner_meters, azimuth_qpoint)
        self.assertEqual(point_soldner_1998_result.toString(6), point_soldner_1998.toString(6))
        # Test degree based projected point from point_1924 1 meter due East
        point_wsg84_meter_result = QgsPointXY(0, 0)
        point_wsg84_1927_meter = QgsPointXY(13.37652180838435, 52.50952361017102)
        length_meter_mapunits, point_wsg84_meter_result = da_wsg84.measureLineProjected(point_wsg84_1924, 1.0, (math.pi / 2))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, QgsUnitTypes.DistanceDegrees, True), '0.0000147 deg')
        self.assertEqual(point_wsg84_meter_result.toString(7), point_wsg84_1927_meter.toString(7))

        point_wsg84_1998_result = QgsPointXY(0, 0)
        length_1928_mapunits, point_wsg84_1998_result = da_wsg84.measureLineProjected(point_wsg84_1924, distance_wsg84_meters, azimuth_wsg84_1924)
        self.assertEqual(QgsDistanceArea.formatDistance(length_1928_mapunits, 7, QgsUnitTypes.DistanceDegrees, True), distance_wsg84_mapunits_format)
        self.assertEqual(point_wsg84_1998_result.toString(7), point_wsg84_1998.toString(7))
Ejemplo n.º 7
0
    def processAlgorithm(self, parameters, context, feedback):
        self.parameters = parameters
        self.context = context
        self.feedback = feedback
        load_geotiffs = self.parameterAsInt(parameters, self.PrmLoadGeoTiffs,
                                            context)
        out_folder = self.parameterAsFile(parameters,
                                          self.PrmGroundOverlayFolder, context)
        input_file = self.parameterAsFile(parameters, self.PrmInput, context)
        f, extension = os.path.splitext(input_file)
        dirname = os.path.dirname(input_file)
        extension = extension.lower()
        try:
            if extension == '.kmz':
                kmz = ZipFile(input_file, 'r')
                kml = kmz.open('doc.kml', 'r')
            elif extension == '.kml':
                kml = open(input_file,
                           encoding="utf-8",
                           errors="backslashreplace")
            else:
                msg = "Invalid extension: Should be kml or kmz"
                raise QgsProcessingException(msg)
        except Exception:
            msg = "Failed to open file"
            raise QgsProcessingException(msg)

        parser = xml.sax.make_parser()

        self.overlays = []
        # Set up the handler for doing the main processing
        handler = GroundOverlayHandler(feedback)
        handler.groundoverlay.connect(self.groundoverlay)
        parser.setContentHandler(handler)
        try:
            input_source = xml.sax.xmlreader.InputSource()
            input_source.setByteStream(kml)
            input_source.setEncoding('utf-8')
            parser.parse(input_source)
        except Exception:
            '''s = traceback.format_exc()
            feedback.pushInfo(s)'''
            feedback.reportError(
                tr('Failure in kml extraction - May return partial results.'))
            handler.endDocument()

        # Iterate through each found overlay images
        for overlay in self.overlays:
            north = overlay[0]
            south = overlay[1]
            east = overlay[2]
            west = overlay[3]
            rotation = overlay[4]
            href = overlay[5]
            if href.startswith('http:') or href.startswith('https:'):
                feedback.reportError(
                    'Cannot process network images: {}'.format(href))
                continue
            if extension == '.kmz':
                try:
                    image = kmz.read(href)
                    output_file = os.path.basename(href)
                    file_name, ext = os.path.splitext(output_file)
                    # Write out a temporary image
                    temp_file_name = os.path.join(
                        out_folder, '{}_temp{}'.format(file_name, ext))
                    fp = open(temp_file_name, "wb")
                    fp.write(image)
                    fp.close()
                    raster = QgsRasterLayer(temp_file_name, "temp")
                except Exception:
                    feedback.reportError(
                        'Image does not exist: {}'.format(href))
                    continue
            else:
                # Check to see if it is a valid file name
                in_path = os.path.join(dirname, href)
                if not os.path.isfile(in_path):
                    # The path was not valid
                    feedback.reportError(
                        'Image file does not exist: {}'.format(in_path))
                    continue
                raster = QgsRasterLayer(in_path, "temp")
                output_file = os.path.basename(in_path)
                file_name, ext = os.path.splitext(output_file)
            if not raster.isValid():
                feedback.reportError('Invalid raster image: {}'.format(href))
                continue
            out_path = os.path.join(out_folder, file_name + ".tif")
            if rotation == 0:
                status = processing.run(
                    "gdal:translate", {
                        'INPUT':
                        raster,
                        'EXTRA':
                        '-a_srs EPSG:4326 -a_ullr {} {} {} {}'.format(
                            west, north, east, south),
                        'DATA_TYPE':
                        0,
                        'OUTPUT':
                        out_path
                    })
            else:
                rwidth = raster.width()
                rheight = raster.height()
                center_x = (east + west) / 2.0
                center_y = (north + south) / 2.0
                center_pt = QgsPointXY(center_x, center_y)
                ul_pt = QgsPointXY(west, north)
                ur_pt = QgsPointXY(east, north)
                lr_pt = QgsPointXY(east, south)
                ll_pt = QgsPointXY(west, south)
                distance = center_pt.distance(ul_pt)
                az = center_pt.azimuth(ul_pt) - rotation
                pt1 = center_pt.project(distance, az)
                az = center_pt.azimuth(ur_pt) - rotation
                pt2 = center_pt.project(distance, az)
                az = center_pt.azimuth(lr_pt) - rotation
                pt3 = center_pt.project(distance, az)
                az = center_pt.azimuth(ll_pt) - rotation
                pt4 = center_pt.project(distance, az)
                gcp1 = '-gcp {} {} {} {}'.format(0, 0, pt1.x(), pt1.y())
                gcp2 = '-gcp {} {} {} {}'.format(rwidth, 0, pt2.x(), pt2.y())
                gcp3 = '-gcp {} {} {} {}'.format(rwidth, rheight, pt3.x(),
                                                 pt3.y())
                gcp4 = '-gcp {} {} {} {}'.format(0, rheight, pt4.x(), pt4.y())

                status = processing.run(
                    "gdal:translate", {
                        'INPUT':
                        raster,
                        'EXTRA':
                        '-a_srs EPSG:4326 -a_nodata 0,0,0 {} {} {} {}'.format(
                            gcp1, gcp2, gcp3, gcp4),
                        'DATA_TYPE':
                        0,
                        'OUTPUT':
                        out_path
                    })
            if load_geotiffs:
                context.addLayerToLoadOnCompletion(
                    out_path,
                    context.LayerDetails(file_name, project=context.project()))

            del raster
            if extension == '.kmz':
                try:
                    os.remove(temp_file_name)
                    os.remove(temp_file_name + '.aux.xml')
                except Exception:
                    pass

        if extension == '.kmz':
            kmz.close()
        else:
            kml.close()

        # self.feedback.pushInfo('Number of overlays: {}'.format(len(self.overlays)))

        return ({})
Ejemplo n.º 8
0
def physiocap_filtrer(self,
                      src,
                      csv_sans_0,
                      csv_avec_0,
                      csv_0_seul,
                      nom_dir_segment,
                      nom_session,
                      chemin_session,
                      diametre_filtre,
                      nom_fichier_synthese,
                      err,
                      mindiam,
                      maxdiam,
                      max_sarments_metre,
                      segment_mini_vitesse,
                      segment_maxi_vitesse,
                      segment_mini_point,
                      segment_max_pdop,
                      segment_max_derive,
                      segment_pas_de_derive,
                      details,
                      eer,
                      eec,
                      d,
                      hv,
                      laProjectionCRS,
                      laProjectionTXT,
                      version_3="NO"):
    """Fonction de traitement.
    Filtre ligne brute par ligne brute les données de source (src) pour les valeurs 
    comprises entre mindiam et maxdiam et verifie si on n'a pas atteint le max_sarments_metre.
    Le résultat est écrit au fur et à mesure dans les fichiers 
    csv_sans_0, csv_avec_0 et depuis v3 dans csv_0_seul mais aussi diametre_filtre 
    La synthese est allongé
    "details" pilote l'ecriture de 5 parametres ou de la totalité des 10 parametres 
    """
    leModeDeTrace = self.fieldComboModeTrace.currentText()
    # S'il n'existe pas de données parcellaire, le script travaille avec les données brutes
    titre = ""
    titre_partie_details = " ; NBSARMM2 ; NBSARCEP ; BIOMMM2 ; BIOMGM2 ; BIOMGCEP "
    if version_3 == "NO":
        titre_sans_detail = "X ; Y ; XL93 ; YL93 ; NBSARM ; DIAM ; BIOM ; DATE ; VITESSE"
    else:  # Ajout en version 3 de l'altitude
        titre_sans_detail = "ID;X ; Y ; XL93 ; YL93 ; ALTITUDE; PDOP ; DISTANCE; DERIVE; AZIMUTH; NBSART; NBSARM ; DIAM ; BIOM ; DATE ; VITESSE"

    if details == "NO":
        titre = titre_sans_detail
    else:
        #S'il existe des données parcellaire, le script travaille avec les données brutes et les données calculées
        titre = titre_sans_detail + titre_partie_details

    # Ecriture de l'entete pour tous les cas
    csv_sans_0.write("{0}\n".format(titre))
    csv_avec_0.write("{0}\n".format(titre))
    csv_0_seul.write("{0}\n".format(titre))

    # Pour progress bar entre 15 et 40
    lignes_brutes = src.readlines()
    max_lignes = len(lignes_brutes)
    progress_step = int(max_lignes / 25)
    #physiocap_log("Bar step: " + str( progress_step), leModeDeTrace)
    progress_bar = 15
    barre = 1
    precedent = []
    on_coupe = "PREMIER"
    segment_en_cours = []
    gid_en_cours = []
    gid_sans_mesure = []
    manquant_en_cours = []
    info_en_cours = {}
    derive_en_cours = []
    mes_lignes_sans_coupure = []
    info_lignes_sans_coupure = []
    nombre_segments_sans_coupure = 0

    # Récuperer le CRS choisi, les extensions et le calculateur de distance
    distancearea, EXT_CRS_SHP, EXT_CRS_PRJ, EXT_CRS_RASTER, \
    laProjectionCRS, laProjectionTXT, EPSG_NUMBER = \
            physiocap_quelle_projection_et_lib_demandee( self)

    for numero_point, ligne_brute in enumerate(lignes_brutes):
        if not ligne_brute: break

        # Progress BAR de 15 à 40 %
        if (numero_point > barre * progress_step):
            progress_bar = progress_bar + 1
            barre = barre + 1
            self.progressBar.setValue(progress_bar)

        comptage = ligne_brute.count(",")  # compte le nombre de virgules
        result = ligne_brute.split(",")  # split en fonction des virgules

        try:  # Transform GPS en L93
            # on extrait les Colonnnes 1 à 8 (XY, puis GPS jusqu'à vitesse)
            # en on les transforme en float
            ### On utilise XY[0 et 1] puis Altitude XY[2] Pdop XY[5] et vitesse XY[7]
            XY = [float(x) for x in result[1:9]]

            # Puis on transforme les WGS84 (du capteur) en L93 (probablement utile)
            # TODO: ?V3.x autres EPSG ? et eviter cet appel dans la boucle
            crsDest = QgsCoordinateReferenceSystem.fromEpsgId(
                EPSG_NUMBER_L93)  # Lambert 93
            crsSrc = QgsCoordinateReferenceSystem.fromEpsgId(
                EPSG_NUMBER_GPS)  # WGS 84
            transformer = QgsCoordinateTransform()
            transformer.setSourceCrs(crsSrc)
            transformer.setDestinationCrs(crsDest)
            if not transformer.isValid():
                raise physiocap_exception_no_transform(numero_point)

            # On assure la tranformation par compatibilité du CVS en GPS et L93
            point_L93 = transformer.transform(QgsPointXY(XY[0], XY[1]))
            XY_L93 = [point_L93.x(), point_L93.y()]
            # aMsg = "Transformation faite X {0} et Y {1}". \
            #           format( XY_L93[0], XY_L93[1])
            # physiocap_log( aMsg , leModeDeTrace)
            # physiocap_log( "La projection {0}". format( laProjectionTXT), leModeDeTrace)
            if (laProjectionTXT == "GPS"):
                le_point_projete = QgsPointXY(XY[0], XY[1])
            else:  # Pour le moment seulement L93
                le_point_projete = QgsPointXY(XY_L93[0], XY_L93[1])
            XY_projete = [le_point_projete.x(), le_point_projete.y()]

        except:
            aMsg = "{0} Erreur bloquante durant tranformation SCR : pour la ligne brute numéro {1}". \
                format ( PHYSIOCAP_STOP,  numero_point)
            physiocap_error(self, aMsg)
            err.write(aMsg)  # on écrit la ligne dans le fichier ERREUR
            # monter directemenr exception
            raise

        # TODO: ?V3.x marquer les points à conserver (non filtré et dans un segment)
        # pour creer un 4eme csv POINTS_VALIDES
        # ce qui reste compliqué pour les segments courts que je ne connais pas encore

        try:  # SEGMENT si V3
            # On regarde les points sans mesure avant SEGMENT
            diams = [float(x) for x in result[9:NB_VIRGULES + 1]
                     ]  # on extrait les diams et on les transforme en float
            diamsF = [
                i for i in diams if i > mindiam and i < maxdiam
            ]  # on filtre les diams avec les paramètres entrés ci-dessus
            derive = 0.0
            ma_distance = 0.0
            mon_azimuth = 0.0
            # SEGMENT si V3
            if version_3 == "NO":
                pass
            elif precedent == [] or on_coupe == "PREMIER":
                #physiocap_log( "SEGMENT ==>> point {0} PREMIER".format( numero_point), TRACE_SEGMENT + "_DEBUG")
                # Stocker le premier point pour comparer au prochain tour
                # et la Date début
                precedent = XY_projete
                # TODO: ?V3.y passage en 3D mettre en Z la dérive
                info_en_cours[DATE_DEBUT] = result[0]
                if len(diamsF) == 0:
                    # On ne STOCKE pas les points sans MESURE
                    gid_sans_mesure.append(numero_point)
                else:
                    gid_en_cours.append(numero_point)
                derive_en_cours.append(0)
                segment_en_cours.append(QgsPointXY(le_point_projete))
                on_coupe = "NON"
            else:
                # On vérifie qualité de mesure
                # ################################################
                # Filtre des points pour découpage en SEGMENT ou
                # pour montrer les limites de la capture
                # On cherche si le point est dans la zone attendue
                # calcul basé sur la vitesse annoncé par GPS sur
                # le point en cours et PDOP
                # #################################################

                # Quand vitesse plus de 2.5 et moins de 8 et pdop reste cohérent segment_max_pdop
                if XY[7] >= segment_mini_vitesse and XY[
                        7] < segment_maxi_vitesse and XY[5] < segment_max_pdop:
                    # on est en vitesse de croisière
                    # Calcul de la distance théorique par rapport au precedent
                    # Introduire un calcul de distance length et l'azimuth
                    le_point_precedent = QgsPointXY(precedent[0], precedent[1])
                    ma_distance = distancearea.measureLine(
                        le_point_projete, le_point_precedent)
                    mon_azimuth = le_point_projete.azimuth(le_point_precedent)
                    # TODO: ?V3.y Traiter l'azimuth depuis le début du segment

                    distance_theorique = XY[
                        7] * 1000 / 3600  # On suppose une seconde d'avancement
                    derive = (ma_distance -
                              distance_theorique) / distance_theorique * 100
                    #                    physiocap_log( "Vitesse {3} Distance théorique {1:.2f} et ma distance {0:.2f}  \
                    #                        sont distantes de \n  {2:.1f} soit une derive de {4:.1f}".\
                    #                            format(ma_distance,  distance_theorique, \
                    #                            ( ma_distance - distance_theorique),  XY[7],  derive ), \
                    #                            TRACE_SEGMENT)
                    #remplacer le precedent par l'actuel
                    precedent = XY_projete

                    # Vérification de dérive
                    if abs(derive) > (segment_max_derive +
                                      (2 * segment_pas_de_derive)):
                        physiocap_log( "{0} DECOUPAGE point {1} : l'avancée dérive GRAVE ===> {2:.1f} ! ".\
                            format(PHYSIOCAP_WARNING,   numero_point,   derive ), \
                            TRACE_SEGMENT_DECOUPES)
                        on_coupe = "OUI"
                    elif abs(derive) > (segment_max_derive +
                                        segment_pas_de_derive):
                        physiocap_log( "{0} DECOUPAGE point {1} : l'avancée dérive de PLUS d'un PAS ==> {2:.1f} ! ".\
                            format(PHYSIOCAP_WARNING,   numero_point,   derive ), \
                            TRACE_SEGMENT_DECOUPES)
                        on_coupe = "OUI"
                    elif abs(derive) > segment_max_derive:
                        physiocap_log("{0} DECOUPAGE point {1} : l'avancée dérive => {2:.1f} ! ".\
                            format(PHYSIOCAP_WARNING,   numero_point,   derive ), \
                            TRACE_SEGMENT_DECOUPES)
                        on_coupe = "OUI"
                    else:
                        # La derive < segment_max_derive en % :
                        # Stocker ligne "droite" = orientation et sens d'avancement
                        # Créer un flux des avancement stables pour identifier l'écartement problable
                        # Ajouter un point à la ligne
                        segment_en_cours.append(QgsPointXY(le_point_projete))
                        info_en_cours[DATE_FIN] = result[0]
                        if len(diamsF) == 0:
                            # On ne STOCKE pas les points sans MESURE
                            gid_sans_mesure.append(numero_point)
                        else:
                            gid_en_cours.append(numero_point)
                        derive_en_cours.append(derive)
                        on_coupe = "NON"

                else:  # Cas d'arret (fin de rang) ou pdop
                    on_coupe = "OUI"
                    # Tracer cas decoupe vitessse
                    if XY[7] < segment_mini_vitesse:
                        if len(segment_en_cours) > 0:
                            physiocap_log("{0} DECOUPAGE point {1} : vitesse {2:.1f} alors que min est {3:.1f}! ".\
                            format(PHYSIOCAP_WARNING, numero_point, XY[7],  segment_mini_vitesse), \
                            TRACE_SEGMENT_DECOUPES)
                    if XY[7] > segment_maxi_vitesse:
                        if len(segment_en_cours) > 0:
                            physiocap_log("{0} DECOUPAGE point {1} : vitesse {2:.1f} que max est {3:.1f}! ".\
                            format(PHYSIOCAP_WARNING, numero_point, XY[7],  segment_maxi_vitesse), \
                            TRACE_SEGMENT_DECOUPES)
                    # Tracer cas decoupe pdop
                    if XY[5] >= segment_max_pdop:
                        physiocap_log("{0} DECOUPAGE point {1} : pdop {2:.1f} max est  {3:.1f}! ".\
                            format(PHYSIOCAP_WARNING, numero_point, XY[5], segment_max_pdop ), \
                            TRACE_SEGMENT_DECOUPES)

                if on_coupe == "OUI":  # Cas de fin de ligne
                    if len(segment_en_cours) > segment_mini_point:
                        # Le segment est à garder
                        manquant_en_cours.append(numero_point)
                        # Mémoriser la ligne des points cohérents
                        mes_lignes_sans_coupure.append(segment_en_cours)
                        info_en_cours[NUM_SEG] = nombre_segments_sans_coupure
                        info_en_cours[DATE_FIN] = result[0]
                        info_en_cours[NOMBRE] = len(segment_en_cours)
                        info_en_cours[GID_GARDE] = gid_en_cours
                        info_en_cours[GID_SANS_MESURE] = gid_sans_mesure
                        info_en_cours[GID_TROU] = manquant_en_cours
                        info_en_cours[DERIVE] = np.mean(derive_en_cours)
                        # stocker jour_heure début et fin et derive moyenne ...
                        info_lignes_sans_coupure.append(info_en_cours)
                        nombre_segments_sans_coupure = nombre_segments_sans_coupure + 1
                        manquant_en_cours = []

                    else:
                        # Vérifier les gid_sans_mesure
                        # On ne perd pas les points manquants qui seront ajouter dans GID_TROU pour le segment suivant
                        # On aditionne des gid en cours avec les manquants...
                        for gid_perdu in gid_en_cours:
                            manquant_en_cours.append(gid_perdu)
                        manquant_en_cours.append(numero_point)

                        if len(segment_en_cours) > 0:
                            physiocap_log("{0} SEGMENT {1} IGNORE : trop cours == {2} points, le mini est {3} ".\
                                format(PHYSIOCAP_WARNING, nombre_segments_sans_coupure,
                                len(segment_en_cours),  segment_mini_point ),
                                TRACE_SEGMENT_DECOUPES)

                    info_en_cours = {}
                    gid_en_cours = []
                    gid_sans_mesure = []
                    precedent = []
                    on_coupe = "PREMIER"
                    segment_en_cours = []

        except:
            aMsg = "{0} Erreur bloquante durant extraction des segments : pour la ligne brute numéro {1}". \
                format ( PHYSIOCAP_STOP,  numero_point)
            physiocap_error(self, aMsg)
            err.write(aMsg)  # on écrit la ligne dans le fichier ERREUR
            # monter directemenr exception
            raise

        try:  # On filtre vraiement
            if details == "NO":
                if len(
                        diamsF
                ) == 0:  # si le nombre de diamètre après filtrage = 0 alors pas de mesures
                    nbsarm = 0
                    nbsart = 0
                    diam = 0
                    biom = 0
                    # Ecrire les seuls_0 et aussi les points avec 0
                    if version_3 == "NO":
                        csv_0_seul.write("%.7f%s%.7f%s%.7f%s%.7f%s%i%s%i%s%i%s%s%s%0.2f\n" \
                            %(XY[0],";",XY[1],";",XY_L93[0],";",XY_L93[1],";",nbsarm,";",diam ,";",biom,";",result[0],";",XY[7]))  # on écrit la ligne dans le csv avec ZERO SEUL
                        csv_avec_0.write("%.7f%s%.7f%s%.7f%s%.7f%s%i%s%i%s%i%s%s%s%0.2f\n" \
                            %(XY[0],";",XY[1],";",XY_L93[0],";",XY_L93[1],";",nbsarm,";",diam ,";",biom,";",result[0],";",XY[7]))  # on écrit la ligne dans le fcsv avec ZERO
                    else:  # V3 on ajoute altitude, pdop, distance au point precedent et la dérive
                        # puis AZIMUTH et NBSART = 0
                        a_ecrire = "{0};{1:.7f};{2:.7f};{3:.7f};{4:.7f}; \
                                    {5:.2f};{6:.2f};{7:.2f};{8:.2f};{9:.2f};0;0;0;0;{10};{11:.7f}\n"                                                                                                    . \
                                format(numero_point, XY[0],XY[1],XY_L93[0],XY_L93[1], \
                                    XY[2],XY[5],ma_distance,derive,mon_azimuth,       result[0],XY[7])
                        csv_0_seul.write(a_ecrire)
                        csv_avec_0.write(a_ecrire)

                elif comptage == NB_VIRGULES and len(
                        diamsF
                ) > 0:  # si le nombre de diamètre après filtrage != 0 alors mesures
                    # Nombre sarment total
                    nbsart = len(diamsF)
                    if XY[7] != 0:  # Si vitesse non nulle
                        nbsarm = len(diamsF) / (XY[7] * 1000 / 3600)
                    else:
                        nbsarm = 0
                    if nbsarm > 1 and nbsarm < max_sarments_metre:
                        diam = sum(diamsF) / len(diamsF)
                        biom = 3.1416 * (diam / 2) * (diam / 2) * nbsarm
                        if version_3 == "NO":
                            csv_avec_0.write("%.7f%s%.7f%s%.7f%s%.7f%s%0.2f%s%.2f%s%.2f%s%s%s%0.2f\n" \
                                %(XY[0],";",XY[1],";",XY_L93[0],";",XY_L93[1],";",nbsarm,";",diam,";",biom,";",result[0],";",XY[7])) # on écrit la ligne dans le csv avec ZERO
                            csv_sans_0.write("%.7f%s%.7f%s%.7f%s%.7f%s%0.2f%s%.2f%s%.2f%s%s%s%0.2f\n" \
                                %(XY[0],";",XY[1],";",XY_L93[0],";",XY_L93[1],";",nbsarm,";",diam,";",biom,";",result[0],";",XY[7])) # on écrit la ligne dans le csv sans ZERO
                        else:  # V3 on ajoute altitude, pdop,distance au point precedent et risque de dérive
                            # puis AZIMUTH et NBSART
                            a_ecrire = "{0};{1:.7f};{2:.7f};{3:.7f};{4:.7f}; \
                                {5:.2f};{6:.2f};{7:.2f};{8:.2f};{9:.2f};{10}; \
                                {11:.2f}; {12:.2f};{13:.2f};{14};{15:.7f}\n"                                                                            . \
                                format( numero_point, XY[0],  XY[1], XY_L93[0] ,XY_L93[1], \
                                    XY[2],XY[5],ma_distance,derive,mon_azimuth,nbsart, \
                                    nbsarm,diam,biom,result[0],XY[7])
                            csv_avec_0.write(a_ecrire)
                            csv_sans_0.write(a_ecrire)

                        for n in range(len(diamsF)):
                            diametre_filtre.write("%f%s" % (diamsF[n], ";"))
            elif details == "YES":
                if len(
                        diamsF
                ) == 0:  # si le nombre de diamètre après filtrage = 0 alors pas de mesures
                    nbsart = 0
                    nbsarm = 0
                    diam = 0
                    biom = 0
                    nbsarmm2 = 0
                    nbsarcep = 0
                    biommm2 = 0
                    biomgm2 = 0
                    biomgcep = 0
                    if version_3 == "NO":
                        csv_0_seul.write("%.7f%s%.7f%s%.7f%s%.7f%s%i%s%i%s%i%s%s%s%0.2f%s%i%s%i%s%i%s%i%s%i\n" \
                        %(XY[0],";",XY[1],";",XY_L93[0],";",XY_L93[1],";",nbsarm,";",diam ,";",biom,";",result[0],";",XY[7],";",nbsarmm2,";",nbsarcep,";",biommm2,";",biomgm2,";",biomgcep))
                        csv_avec_0.write("%.7f%s%.7f%s%.7f%s%.7f%s%i%s%i%s%i%s%s%s%0.2f%s%i%s%i%s%i%s%i%s%i\n" \
                        %(XY[0],";",XY[1],";",XY_L93[0],";",XY_L93[1],";",nbsarm,";",diam ,";",biom,";",result[0],";",XY[7],";",nbsarmm2,";",nbsarcep,";",biommm2,";",biomgm2,";",biomgcep))
                    else:  # Q3 on ajoute altitude, pdop, distance au point precedent et la dérive
                        # puis AZIMUTH et NBSART = 0
                        a_ecrire = "{0};{1:.7f};{2:.7f};{3:.7f};{4:.7f}; \
                                    {5:.2f};{6:.2f};{7:.2f};{8:.2f};{9:.2f};0;0;0;0;{10};{11:.7f}"                                                                                                  . \
                                format(numero_point, XY[0],XY[1],XY_L93[0],XY_L93[1],
                                    XY[2],XY[5],ma_distance,derive,mon_azimuth,       result[0],XY[7])
                        a_ecrire_detail = ";0;0;0;0;0\n"
                        a_ecrire_complet = a_ecrire + a_ecrire_detail
                        csv_0_seul.write(a_ecrire_complet)
                        csv_avec_0.write(a_ecrire_complet)

                elif comptage == NB_VIRGULES and len(
                        diamsF
                ) > 0:  # si le nombre de diamètre après filtrage != 0 alors mesures
                    nbsart = len(diamsF)
                    if XY[7] != 0:
                        nbsarm = len(diamsF) / (XY[7] * 1000 / 3600)
                    else:
                        nbsarm = 0
                    if nbsarm > 1 and nbsarm < max_sarments_metre:
                        diam = sum(diamsF) / len(diamsF)
                        biom = 3.1416 * (diam / 2) * (diam / 2) * nbsarm
                        nbsarmm2 = nbsarm / eer * 100
                        nbsarcep = nbsarm * eec / 100
                        biommm2 = biom / eer * 100
                        biomgm2 = biom * d * hv / eer
                        biomgcep = biom * d * hv * eec / 100 / 100
                        if version_3 == "NO":
                            csv_avec_0.write("%.7f%s%.7f%s%.7f%s%.7f%s%.2f%s%.2f%s%.2f%s%s%s%.2f%s%.2f%s%.2f%s%.2f%s%.2f%s%.2f\n" \
                            %(XY[0],";",XY[1],";",XY_L93[0],";",XY_L93[1],";",nbsarm,";",diam ,";",biom,";",result[0],";",XY[7],";",nbsarmm2,";",nbsarcep,";",biommm2,";",biomgm2,";",biomgcep))
                            csv_sans_0.write("%.7f%s%.7f%s%.7f%s%.7f%s%.2f%s%.2f%s%.2f%s%s%s%.2f%s%.2f%s%.2f%s%.2f%s%.2f%s%.2f\n" \
                            %(XY[0],";",XY[1],";",XY_L93[0],";",XY_L93[1],";",nbsarm,";",diam ,";",biom,";",result[0],";",XY[7],";",nbsarmm2,";",nbsarcep,";",biommm2,";",biomgm2,";",biomgcep))
                        else:  # Q3 on ajoute altitude, pdop,distance au point precedent et risque de dérive
                            # puis AZIMUTH et NBSART
                            a_ecrire = "{0};{1:.7f};{2:.7f};{3:.7f};{4:.7f}; \
                                {5:.2f};{6:.2f};{7:.2f};{8:.2f};{9:.2f};{10}; \
                                {11:.2f}; {12:.2f};{13:.2f};{14};{15:.7f}"                                                                          . \
                                format( numero_point, XY[0],  XY[1], XY_L93[0] ,XY_L93[1],
                                    XY[2],XY[5],ma_distance,derive,mon_azimuth,nbsart,
                                    nbsarm,diam,biom,result[0],XY[7])
                            a_ecrire_detail = ";{0:.7f};{1:.7f};{2:.7f};{3:.7f};{4:.7f}\n". \
                                format( nbsarmm2, nbsarcep,biommm2,biomgm2,biomgcep)
                            a_ecrire_complet = a_ecrire + a_ecrire_detail
                            csv_avec_0.write(a_ecrire_complet)
                            csv_sans_0.write(a_ecrire_complet)

                        # Memorise diametre filtré pour histo
                        for n in range(len(diamsF)):
                            diametre_filtre.write("%f%s" % (diamsF[n], ";"))

        except:
            aMsg = "{0} Erreur bloquante durant filtrage : pour la ligne brute numéro {1}". \
                format ( PHYSIOCAP_STOP,  numero_point)
            physiocap_error(self, aMsg)
            err.write(aMsg)  # on écrit la ligne dans le fichier ERREUR
            # Pour monter directement exception
            raise physiocap_exception_err_csv(nom_court_csv_concat)

    if version_3 == "NO":
        vecteur_segment = None
        vecteur_segment_brise = None
    else:
        if len(info_lignes_sans_coupure) != nombre_segments_sans_coupure:
            physiocap_error( self, "{0} on a trouvé {1} segments et {2} infos". \
            format( PHYSIOCAP_INFO,  nombre_segments_sans_coupure, len( info_lignes_sans_coupure)))
            raise physiocap_exception_calcul_segment_invalid(
                "Segment et leurs infos sont différents")
        i = 0
        for info_segment in info_lignes_sans_coupure:
            i = i + 1
            try:
                physiocap_log( "{0} Segment {1} contient {2} points et une dérive moyenne de {3:.1f}". \
                    format( PHYSIOCAP_INFO,  i,  info_segment[NOMBRE],  info_segment[DERIVE]),  TRACE_SEGMENT)
                physiocap_log( "gid des points :{0} \net les sans mesure\n{1}". \
                    format(info_segment[GID_GARDE],  info_segment[GID_SANS_MESURE]), TRACE_SEGMENT)
            except:
                physiocap_error(
                    self, "Problème : manque attribut dans info segment")
                raise physiocap_exception_calcul_segment_invalid(
                    "Un  attribut n'est pas présent")
#            try:
#                physiocap_log( "Date début {0} et fin {1}". \
#                format( info_segment[DATE_DEBUT], info_segment[DATE_FIN]),
#                TRACE_SEGMENT)
#            except:
#                physiocap_error( self, "Problème : pas de date dans le segment")
#                raise physiocap_exception_calcul_segment_invalid( "Date non présente")

# Creer les lignes simplifiés ou brisés de ces segments et infos
        vecteur_segment = physiocap_segment_vers_vecteur(
            self, chemin_session, nom_dir_segment, nom_session,
            mes_lignes_sans_coupure, info_lignes_sans_coupure, version_3)
        vecteur_segment_brise = physiocap_segment_vers_vecteur(
            self, chemin_session, nom_dir_segment, nom_session,
            mes_lignes_sans_coupure, info_lignes_sans_coupure, version_3,
            "BRISE")

    physiocap_log( "{0} {1} Fin du filtrage OK des {2} lignes.". \
        format( PHYSIOCAP_INFO, PHYSIOCAP_UNI, str(numero_point - 1)), leModeDeTrace)
    return vecteur_segment, vecteur_segment_brise
Ejemplo n.º 9
0
    def generateFootprintsForFilmVertical(self):
        self.reloadFpLayer()
        self.reloadCpLayer()

        # Error wenn nur ein punkt vorhanden
        if self.cpLayer.featureCount() > 1:
            caps = self.fpLayer.dataProvider().capabilities()
            if caps & QgsVectorDataProvider.AddFeatures:
                #Get FORM1 from FilmInfoDict
                f1 = self.currentFilmInfoDict["form1"]  # Image height
                f2 = self.currentFilmInfoDict["form2"]  # Image width

                iterFeatures = self.cpLayer.getFeatures()
                iterNext = self.cpLayer.getFeatures()
                existingFootpints = QgsVectorLayerUtils.getValues(
                    self.fpLayer, "bildnummer")[0]
                ft = QgsFeature()
                ftNext = QgsFeature()
                iterNext.nextFeature(ftNext)
                fpFeats = []
                kappasToUpdate = {}
                # iterate over points from CP Layer > LON, LAT
                i = 0
                while iterFeatures.nextFeature(ft):
                    i += 1
                    iterNext.nextFeature(ftNext)
                    p = QgsPointXY(ft.geometry().asPoint())
                    if ft['bildnummer'] in existingFootpints:
                        pPrevGeom = QgsGeometry(ft.geometry())
                        #QMessageBox.warning(None, u"Bild Nummern", u"Footprint für das Bild mit der Nummer {0} wurde bereits erstellt.".format(ft['BILD']))
                        continue
                    if i == 1:
                        pPrevGeom = QgsGeometry(ftNext.geometry())
                    #if iterNext.isClosed():
                    #    #use pPrev as pNext
                    #    pNext = QgsPoint(pPrev)
                    #else:
                    #    pNext = QgsPoint(ftNext.geometry().asPoint())

                    #kappa = p.azimuth(pPrev)

                    #kappa = p.azimuth(pNext)

                    # d = math.sqrt(2*((f1/2 * ft['MASS']/1000)**2))
                    d1 = f1 / 2 * ft['massstab'] / 1000
                    d2 = f2 / 2 * ft['massstab'] / 1000
                    #QMessageBox.warning(None, u"Bild Nummern", "{0}".format(d))

                    calcCrs = QgsCoordinateReferenceSystem()
                    calcCrs.createFromProj4(self.Proj4Utm(p))
                    ctF = QgsCoordinateTransform(self.cpLayer.crs(), calcCrs,
                                                 QgsProject.instance())

                    cpMetric = QgsGeometry(ft.geometry())
                    cpMetric.transform(ctF)
                    pPrevGeom.transform(ctF)
                    pMetric = QgsPointXY(cpMetric.asPoint())
                    pPrevMetric = QgsPointXY(pPrevGeom.asPoint())
                    kappaMetric = pMetric.azimuth(pPrevMetric)
                    pPrevGeom = QgsGeometry(ft.geometry())
                    left = pMetric.x() - d2
                    bottom = pMetric.y() - d1
                    right = pMetric.x() + d2
                    top = pMetric.y() + d1

                    #R = 6371
                    #D = (d/1000)
                    #cpLat = math.radians(p.y())
                    #cpLon = math.radians(p.x())
                    #urLat = math.asin( math.sin(cpLat)*math.cos(D/R) + math.cos(cpLat)*math.sin(D/R)*math.cos(urBrng) )
                    #urLon = cpLon + math.atan2(math.sin(urBrng)*math.sin(D/R)*math.cos(cpLat), math.cos(D/R)-math.sin(cpLat)*math.sin(urLat))

                    #top = math.asin( math.sin(cpLat)*math.cos(D/R) + math.cos(cpLat)*math.sin(D/R) )
                    #bottom = math.asin( math.sin(cpLat)*math.cos(D/R) + math.cos(cpLat)*math.sin(D/R)*-1 )

                    #lat = math.asin( math.sin(cpLat)*math.cos(D/R) )
                    #right = cpLon + math.atan2(math.sin(D/R)*math.cos(cpLat), math.cos(D/R)-math.sin(cpLat)*math.sin(lat))
                    #left = cpLon + math.atan2(-1*math.sin(D/R)*math.cos(cpLat), math.cos(D/R)-math.sin(cpLat)*math.sin(lat))

                    #QMessageBox.warning(None, u"Bild Nummern", "{0}, {1}, {2}, {3}".format(math.degrees(top), math.degrees(bottom), math.degrees(left), math.degrees(right)))

                    #rect = QgsRectangle(math.degrees(left), math.degrees(bottom), math.degrees(right), math.degrees(top))
                    #l = math.degrees(left)
                    #b = math.degrees(bottom)
                    #r = math.degrees(right)
                    #t = math.degrees(top)
                    p1 = QgsGeometry.fromPointXY(QgsPointXY(left, bottom))
                    p2 = QgsGeometry.fromPointXY(QgsPointXY(right, bottom))
                    p3 = QgsGeometry.fromPointXY(QgsPointXY(right, top))
                    p4 = QgsGeometry.fromPointXY(QgsPointXY(left, top))
                    #p1.rotate(kappa+90, p)
                    #p2.rotate(kappa+90, p)
                    #p3.rotate(kappa+90, p)
                    #p4.rotate(kappa+90, p)
                    pol = [[
                        p1.asPoint(),
                        p2.asPoint(),
                        p3.asPoint(),
                        p4.asPoint()
                    ]]
                    geom = QgsGeometry.fromPolygonXY(pol)
                    geom.rotate(kappaMetric, pMetric)
                    #Transform to DestinationCRS
                    ctB = QgsCoordinateTransform(calcCrs, self.fpLayer.crs(),
                                                 QgsProject.instance())
                    geom.transform(ctB)

                    feat = QgsFeature(self.fpLayer.fields())
                    feat.setGeometry(geom)
                    feat.setAttribute('filmnummer', self.currentFilmNumber)
                    feat.setAttribute('bildnummer', ft['bildnummer'])
                    da = QgsDistanceArea()
                    da.setEllipsoid(self.fpLayer.crs().ellipsoidAcronym())
                    feat.setAttribute('shape_length',
                                      da.measurePerimeter(geom))
                    feat.setAttribute('shape_area', da.measureArea(geom))
                    fpFeats.append(feat)

                    # update Kappa in cpLayer
                    kappasToUpdate[ft.id()] = {
                        ft.fieldNameIndex('kappa'): kappaMetric
                    }

                iterFeatures.close()
                iterNext.close()

                resCAVs = self.cpLayer.dataProvider().changeAttributeValues(
                    kappasToUpdate)
                QgsMessageLog.logMessage(
                    f"Kappa Update for {kappasToUpdate}, Success: {resCAVs}",
                    tag="APIS",
                    level=Qgis.Success if resCAVs else Qgis.Critical)

                (res,
                 outFeats) = self.fpLayer.dataProvider().addFeatures(fpFeats)

                self.fpLayer.updateExtents()
                if self.canvas.isCachingEnabled():
                    self.fpLayer.triggerRepaint()
                else:
                    self.canvas.refresh()
            else:
                #Caps
                QMessageBox.warning(None, "Layer Capabilities!",
                                    "Layer Capabilities!")
        else:
            #small feature count
            QMessageBox.warning(
                None, "Footprints",
                "Zum Berechnen der senkrecht Footprint müssen mindestens zwei Bilder kartiert werden!"
            )
Ejemplo n.º 10
0
    def onSaveAddCenterPoint(self):
        #QMessageBox.warning(None, u"Film Nummer", u"{0},{1},{2}".format(self.imageCenterPoint.x(), self.imageCenterPoint.y(), type(self.imageCenterPoint)))
        self.reloadCpLayer()

        #Prepare Image Numbers
        if self.isOblique:
            fromImageNumber = self.uiImageNumberFromSpn.value()
            toImageNumber = self.uiImageNumberToSpn.value()
            if fromImageNumber > toImageNumber:
                QMessageBox.warning(
                    None, u"Bild Nummern",
                    u"Die erste Bildnummer darf nicht größer als die zweite sein."
                )
                return
            else:
                imageNumbers = range(fromImageNumber, toImageNumber + 1)
        else:
            imageNumbers = [self.uiImageNumberSpn.value()]

        # filmImageNumbers = []
        # for imageNumber in imageNumbers:
        #     filmImageNumbers.append('{0}.{1:03d}'.format(self.currentFilmNumber, imageNumber))

        # QMessageBox.warning(None, u"Bild Nummern", ",".join(imageNumbers))

        # for filmImageNumber in self.cpLayer.getValues("BILD"):
        #    QMessageBox.warning(None, u"Bild Nummern", "{0}".format(filmImageNumber))

        # Check if Image Number in Table
        for imageNumber in imageNumbers:
            # QMessageBox.warning(None, u"Bild Nummern", u"{0}".format(QgsVectorLayerUtils.getValues(self.cpLayer, "bildnummer_nn")))
            if imageNumber in QgsVectorLayerUtils.getValues(
                    self.cpLayer, "bildnummer_nn")[0]:
                QMessageBox.warning(
                    None, u"Bild Nummern",
                    u"Ein Bild mit der Nummer {0} wurde bereits kartiert".
                    format(imageNumber))
                return

        caps = self.cpLayer.dataProvider().capabilities()
        if caps & QgsVectorDataProvider.AddFeatures:
            features = []

            feat = QgsFeature(self.cpLayer.fields())
            feat.setGeometry(QgsGeometry.fromPointXY(self.imageCenterPoint))

            # From Film Table
            # filmFields = ["form1", "form2", "weise", "kammerkonstante"]
            feat.setAttribute(
                'filmnummer_hh_jjjj_mm',
                self.currentFilmInfoDict["filmnummer_hh_jjjj_mm"])
            feat.setAttribute('filmnummer_nn',
                              self.currentFilmInfoDict["filmnummer_nn"])
            feat.setAttribute('filmnummer', self.currentFilmNumber)

            #Date TODAY
            now = QDate.currentDate()
            feat.setAttribute('datum_ersteintrag', now.toString("yyyy-MM-dd"))
            feat.setAttribute('datum_aenderung', now.toString("yyyy-MM-dd"))

            # Iterate over Project Selection List und String mit ; trennung generieren
            feat.setAttribute('copyright',
                              self.currentFilmInfoDict["copyright"])

            # By Default Fix Value
            feat.setAttribute('etikett', 0)

            # Get Projects from Projekte Liste
            items = []
            # From Input (Radius, Höhe, Schlüsslewort, Beschreibung)
            if self.isOblique:
                feat.setAttribute('radius',
                                  float(self.uiImageDiameterSpn.value() / 2))
                feat.setAttribute('beschreibung',
                                  self.uiImageDescriptionEdit.text())
                h = self.uiFlightHeightObliqueSpn.value()
                for j in range(self.uiProjectObliqueList.count()):
                    items.append(self.uiProjectObliqueList.item(j))
            else:
                h = self.uiFlightHeightVerticalSpn.value()
                feat.setAttribute('fokus',
                                  self.currentFilmInfoDict["kammerkonstante"])
                if not self.currentFilmInfoDict[
                        "kammerkonstante"] or not self.currentFilmInfoDict[
                            "kammerkonstante"] > 0:
                    feat.setAttribute('massstab', 0)
                else:
                    feat.setAttribute(
                        'massstab',
                        h / self.currentFilmInfoDict["kammerkonstante"] * 1000)
                for j in range(self.uiProjectVerticalList.count()):
                    items.append(self.uiProjectVerticalList.item(j))

            feat.setAttribute('projekt', ";".join([i.text() for i in items]))
            feat.setAttribute('hoehe', h)

            # Calculated/Derived
            feat.setAttribute('longitude', self.imageCenterPoint.x())
            feat.setAttribute('latitude', self.imageCenterPoint.y())

            countryCode = self.getCountryCode()
            feat.setAttribute('land', countryCode)

            if countryCode == 'AUT':
                # get meridian and epsg Code
                meridian, epsgGK = GetMeridianAndEpsgGK(
                    self.imageCenterPoint.x())

                # get KG Coordinates
                gk = TransformGeometry(
                    QgsGeometry().fromPointXY(self.imageCenterPoint),
                    self.cpLayer.crs(),
                    QgsCoordinateReferenceSystem(f"EPSG:{epsgGK}"))
                gkx = gk.asPoint().y()  # Hochwert
                gky = gk.asPoint().x()  # Rechtswert
            else:
                meridian = None
                gkx = None
                gky = None

            feat.setAttribute('meridian', meridian)
            feat.setAttribute('gkx', gkx)  # Hochwert
            feat.setAttribute('gky', gky)  # Rechtswert

            for imageNumber in imageNumbers:
                f = QgsFeature(feat)
                f.setAttribute('bildnummer_nn', imageNumber)
                bn = '{0}.{1:03d}'.format(self.currentFilmNumber, imageNumber)
                f.setAttribute('bildnummer', bn)

                if self.isOblique:
                    image = os.path.normpath(
                        self.settings.value("APIS/image_dir") + '\\' +
                        self.currentFilmNumber + '\\' + bn.replace('.', '_') +
                        '.jpg')
                    exif = GetExifForImage(image,
                                           altitude=True,
                                           longitude=True,
                                           latitude=True,
                                           exposure_time=True,
                                           focal_length=True,
                                           fnumber=True)

                    if "altitude" in exif and exif["altitude"]:
                        f.setAttribute('hoehe', exif["altitude"])
                    f.setAttribute(
                        'gps_longitude',
                        exif["longitude"] if "longitude" in exif else None)
                    f.setAttribute(
                        'gps_latitude',
                        exif["latitude"] if "latitude" in exif else None)

                    if "longitude" in exif and "latitude" in exif and exif[
                            "longitude"] and exif["latitude"]:
                        capturePoint = QgsPointXY(exif["longitude"],
                                                  exif["latitude"])
                        kappa = capturePoint.azimuth(self.imageCenterPoint)
                    else:
                        kappa = None
                    f.setAttribute('kappa', kappa)

                    f.setAttribute(
                        'belichtungszeit', exif["exposure_time"]
                        if "exposure_time" in exif else None)
                    f.setAttribute('fokus',
                                   exif["focal_length"] if "focal_length"
                                   in exif else None)  # FocalLength
                    if "focal_length" in exif and "fnumber" in exif and exif[
                            "focal_length"] and exif["fnumber"]:
                        blende = exif["focal_length"] / exif[
                            "fnumber"]  # effecitve aperture (diameter of entrance pupil) = focalLength / fNumber
                    else:
                        blende = None
                    f.setAttribute('blende', blende)

                features.append(f)

            (res, outFeats) = self.cpLayer.dataProvider().addFeatures(features)
            self.cpLayer.updateExtents()

            if res and self.isOblique:
                self.generateFootprintsForFilmOblique()

            #QMessageBox.warning(None, u"Film Nummer", u"{0},{1}".format(res, outFeats))
        else:
            QMessageBox.warning(None, u"Layer Capabilities!")

        if self.canvas.isCachingEnabled():
            self.cpLayer.triggerRepaint()
        else:
            self.canvas.refresh()

        self.onCancelAddCenterPoint()