예제 #1
0
    def __init__(self, settings: PlotSettings = None):
        if settings is None:
            settings = PlotSettings('scatter')

        self.settings = settings
        self.raw_plot = None
        self.plot_path = None

        if not settings.x and settings.source_layer_id:
            # not using hardcoded values, collect values now
            source_layer = QgsProject.instance().mapLayer(settings.source_layer_id)
            if source_layer:
                # todo - fix for single layer iteration instead
                selected_features_only = settings.properties['selected_features_only']
                xx = QgsVectorLayerUtils.getValues(source_layer, settings.properties['x_name'],
                                                   selectedOnly=settings.properties['selected_features_only'])[0]
                yy = QgsVectorLayerUtils.getValues(source_layer, settings.properties['y_name'],
                                                   selectedOnly=selected_features_only)[0]
                zz = QgsVectorLayerUtils.getValues(source_layer, settings.properties['z_name'],
                                                   selectedOnly=selected_features_only)[0]
                settings.feature_ids = getIds(source_layer, selected_features_only)
                settings.additional_hover_text = QgsVectorLayerUtils.getValues(
                    source_layer,
                    settings.layout['additional_info_expression'],
                    selectedOnly=selected_features_only)[0]

                # call the function that will clean the data from NULL values
                settings.x, settings.y, settings.z, = cleanData(xx, yy, zz)

        self.trace = self._build_trace()
        self.layout = self._build_layout()
예제 #2
0
    def calcErrMatrix(self):
        if self.started:
            self.featLayer.commitChanges()

            self.startButton.setEnabled(True)
            self.startButton.setDefault(True)
            self.availLayersCombo.setEnabled(True)
            self.classNameCombo.setEnabled(True)
            self.classNameOutCombo.setEnabled(True)
            self.featProcessedCombo.setEnabled(True)
            self.visitProcessedCheckBox.setEnabled(True)

            self.nextButton.setDisabled(True)
            self.prevButton.setDisabled(True)
            self.assignButton.setDisabled(True)
            self.classifiedLabel.setDisabled(True)
            self.fidLabel.setDisabled(True)
            self.classesCombo.setDisabled(True)
            self.goToButton.setDisabled(True)
            self.goToTextField.setDisabled(True)
            self.changeScaleButton.setDisabled(True)
            self.scaleOptionsTextLine.setDisabled(True)
            self.addClassButton.setDisabled(True)
            self.addClassField.setDisabled(True)
        self.started = False

        outCSVFilePath = QW.QFileDialog.getSaveFileName(
            self, 'SaveErrorMatrixCSV', '',
            'CSV(*.csv)')  #(self, 'Save Error Matrix CSV', '', '*.csv')
        if outCSVFilePath:
            featsClassNamesImgList = QgsVectorLayerUtils.getValues(
                self.featLayer, self.selectedClassFieldName)[0]
            featsClassNamesGrdList = QgsVectorLayerUtils.getValues(
                self.featLayer, self.selectedClassOutFieldName)[0]
            numClasses = len(self.classNamesList)

            errMatrix = numpy.zeros((numClasses, numClasses),
                                    dtype=numpy.float)

            for i in range(self.numFeats):
                imgClass = featsClassNamesImgList[i]
                imgClassIdx = self.classNamesList.index(imgClass)
                grdClass = featsClassNamesGrdList[i]
                grdClassIdx = self.classNamesList.index(grdClass)
                errMatrix[imgClassIdx,
                          grdClassIdx] = errMatrix[imgClassIdx,
                                                   grdClassIdx] + 1

            errMatrixPercent = (errMatrix / numpy.sum(errMatrix)) * 100

            producerAcc = numpy.zeros(numClasses, dtype=numpy.float)
            userAcc = numpy.zeros(numClasses, dtype=numpy.float)
            producerAccCount = numpy.zeros(numClasses, dtype=numpy.float)
            userAccCount = numpy.zeros(numClasses, dtype=numpy.float)
            overallCorrCount = 0.0

            for i in range(numClasses):
                corVal = float(errMatrix[i, i])
                sumRow = float(numpy.sum(errMatrix[i, ]))
                sumCol = float(numpy.sum(errMatrix[..., i]))
                overallCorrCount = overallCorrCount + corVal
                if sumRow == 0:
                    userAcc[i] = 0
                    userAccCount[i] = 0
                else:
                    userAcc[i] = corVal / sumRow
                    userAccCount[i] = sumRow
                if sumCol == 0:
                    producerAcc[i] = 0
                    producerAccCount[i] = 0
                else:
                    producerAcc[i] = corVal / sumCol
                    producerAccCount[i] = sumCol

            overallAcc = (overallCorrCount / numpy.sum(errMatrix)) * 100
            producerAcc = producerAcc * 100
            userAcc = userAcc * 100

            kappaPartA = overallCorrCount * numpy.sum(producerAccCount)
            kappaPartB = numpy.sum(userAccCount * producerAccCount)
            kappaPartC = numpy.sum(errMatrix) * numpy.sum(errMatrix)

            kappa = float(kappaPartA - kappaPartB) / float(kappaPartC -
                                                           kappaPartB)

            with open(outCSVFilePath[0],
                      'w') as csvfile:  #(outCSVFilePath, 'wb')
                accWriter = csv.writer(csvfile,
                                       delimiter=',',
                                       quotechar='|',
                                       quoting=csv.QUOTE_MINIMAL)

                accWriter.writerow(
                    ['Overall Accuracy (%)',
                     round(overallAcc, 2)])
                accWriter.writerow(['kappa', round(kappa, 2)])

                accWriter.writerow([])
                accWriter.writerow(['Counts:'])

                colNames = [' ']
                for i in range(numClasses):
                    colNames.append(self.classNamesList[i])
                colNames.append('User')
                accWriter.writerow(colNames)

                for i in range(numClasses):
                    row = []
                    row.append(self.classNamesList[i])
                    for j in range(numClasses):
                        row.append(errMatrix[i, j])
                    row.append(round(userAccCount[i], 2))
                    accWriter.writerow(row)

                prodRow = ['Producer']
                for i in range(numClasses):
                    prodRow.append(round(producerAccCount[i], 2))
                prodRow.append(overallCorrCount)
                accWriter.writerow(prodRow)

                accWriter.writerow([])
                accWriter.writerow(['Percentage:'])

                colNames = [' ']
                for i in range(numClasses):
                    colNames.append(self.classNamesList[i])
                colNames.append('User (%)')
                accWriter.writerow(colNames)

                for i in range(numClasses):
                    row = []
                    row.append(self.classNamesList[i])
                    for j in range(numClasses):
                        row.append(round(errMatrixPercent[i, j], 2))
                    row.append(round(userAcc[i], 2))
                    accWriter.writerow(row)

                prodRow = ['Producer (%)']
                for i in range(numClasses):
                    prodRow.append(round(producerAcc[i], 2))
                prodRow.append(round(overallAcc, 2))
                accWriter.writerow(prodRow)
예제 #3
0
    def startProcessing(self):
        """ Starting Processing """
        if not self.started:

            qgisIface = qgis.utils.iface

            mCanvas = qgisIface.mapCanvas()
            mCanvas.setSelectionColor(QtGui.QColor("yellow"))

            selectedIdx = self.availLayersCombo.currentIndex()
            selectedName = self.availLayersCombo.itemText(selectedIdx)

            self.selectedClassFieldIdx = self.classNameCombo.currentIndex()
            self.selectedClassFieldName = self.classNameCombo.itemText(
                self.selectedClassFieldIdx)

            self.selectedClassOutFieldIdx = self.classNameOutCombo.currentIndex(
            )
            self.selectedClassOutFieldName = self.classNameOutCombo.itemText(
                self.selectedClassOutFieldIdx)

            self.selectedFeatProcessedFieldIdx = self.featProcessedCombo.currentIndex(
            )
            self.selectedFeatProcessedFieldName = self.featProcessedCombo.itemText(
                self.selectedFeatProcessedFieldIdx)

            allLayers = mCanvas.layers()
            found = False
            for layer in allLayers:
                if layer.name() == selectedName:
                    self.featLayer = layer
                    break

            self.selectedClassFieldIdx = self.featLayer.fields().indexFromName(
                self.selectedClassFieldName)
            self.selectedClassFieldOutIdx = self.featLayer.fields(
            ).indexFromName(self.selectedClassOutFieldName)
            self.selectedFeatProcessedFieldIdx = self.featLayer.fields(
            ).indexFromName(self.selectedFeatProcessedFieldName)

            self.onlyGoToUnProcessedFeats = True
            if self.visitProcessedCheckBox.checkState() == QtCore.Qt.Checked:
                self.onlyGoToUnProcessedFeats = False

            self.classNamesTmpList = QgsVectorLayerUtils.getValues(
                self.featLayer, self.selectedClassFieldName)
            self.classNamesList = list(set(self.classNamesTmpList[0]))

            classOutNamesTmpList = QgsVectorLayerUtils.getValues(
                self.featLayer, self.selectedClassOutFieldName)
            classOutNamesList = list(set(classOutNamesTmpList[0]))

            for classOutName in classOutNamesList:
                if (not classOutName in self.classNamesList) and (
                        not classOutName == 'NULL') and (not classOutName
                                                         == None):
                    self.classNamesList.append(str(classOutName))

            for className in self.classNamesList:
                self.classesCombo.addItem(str(className))

            self.numFeats = self.featLayer.featureCount()
            self.cFeatN = 0

            self.featLayer.selectByIds([])

            self.featIter = self.featLayer.getFeatures()
            self.cFeat = next(self.featIter)
            if self.cFeatN < self.numFeats:

                availFeats = True
                if self.onlyGoToUnProcessedFeats:
                    foundUnProcessedFeat = False
                    while not foundUnProcessedFeat:
                        if int(self.cFeat[
                                self.selectedFeatProcessedFieldIdx]) == 0:
                            foundUnProcessedFeat = True
                        else:
                            self.cFeatN = self.cFeatN + 1
                            if self.cFeatN < self.numFeats:
                                self.cFeat = next(self.featIter)
                            else:
                                availFeats = False
                                break

                if availFeats:
                    self.featLayer.startEditing()
                    self.featLayer.selectByIds([self.cFeat.id()])

                    cClassName = str(self.cFeat[self.selectedClassFieldIdx])
                    self.classifiedLabel.setText(cClassName)

                    outClassName = str(
                        self.cFeat[self.selectedClassOutFieldIdx])
                    if (outClassName
                            == None) or (outClassName.strip() == "") or (not (
                                outClassName.strip() in self.classNamesList)):
                        self.classesCombo.setCurrentIndex(
                            self.classNamesList.index(cClassName))
                    else:
                        self.classesCombo.setCurrentIndex(
                            self.classNamesList.index(outClassName))

                    self.fidLabel.setText(
                        str(self.cFeat.id() + 1) + " of " + str(self.numFeats))

                    box = self.featLayer.boundingBoxOfSelected()
                    box = box.buffered(self.cScaleBuffer)
                    mCanvas.setExtent(box)
                    mCanvas.refresh()

                    self.nextButton.setEnabled(True)
                    self.nextButton.setDefault(True)
                    self.prevButton.setEnabled(True)
                    self.assignButton.setEnabled(True)
                    self.classifiedLabel.setEnabled(True)
                    self.fidLabel.setEnabled(True)
                    self.classesCombo.setEnabled(True)
                    self.goToButton.setEnabled(True)
                    self.goToTextField.setEnabled(True)
                    self.classesCombo.setFocus()
                    self.changeScaleButton.setEnabled(True)
                    self.scaleOptionsTextLine.setEnabled(True)
                    self.addClassButton.setEnabled(True)
                    self.addClassField.setEnabled(True)
                    self.calcErrorMatrixButton.setEnabled(True)

                    self.startButton.setDisabled(True)
                    self.availLayersCombo.setDisabled(True)
                    self.classNameCombo.setDisabled(True)
                    self.classNameOutCombo.setDisabled(True)
                    self.featProcessedCombo.setDisabled(True)
                    self.visitProcessedCheckBox.setDisabled(True)

            else:
                self.featLayer.commitChanges()

                self.startButton.setEnabled(True)
                self.startButton.setDefault(True)
                self.availLayersCombo.setEnabled(True)
                self.classNameCombo.setEnabled(True)
                self.classNameOutCombo.setEnabled(True)
                self.featProcessedCombo.setEnabled(True)
                self.visitProcessedCheckBox.setEnabled(True)

                self.nextButton.setDisabled(True)
                self.prevButton.setDisabled(True)
                self.assignButton.setDisabled(True)
                self.classifiedLabel.setDisabled(True)
                self.classesCombo.setDisabled(True)
                self.goToButton.setDisabled(True)
                self.goToTextField.setDisabled(True)
                self.changeScaleButton.setDisabled(True)
                self.scaleOptionsTextLine.setDisabled(True)
                self.addClassButton.setDisabled(True)
                self.addClassField.setDisabled(True)

            if availFeats:
                self.started = True
예제 #4
0
    def generateFootprintsForFilmOblique(self):
        self.reloadFpLayer()
        self.reloadCpLayer()

        caps = self.fpLayer.dataProvider().capabilities()
        if caps & QgsVectorDataProvider.AddFeatures:
            if self.cpLayer.dataProvider().featureCount() > 0:
                iter = self.cpLayer.getFeatures()
                existingFootpints = QgsVectorLayerUtils.getValues(
                    self.fpLayer, "bildnummer")[0]
                cpFt = QgsFeature()
                fpFts = []
                #iterate over points from CP Layer > LON, LAT
                while iter.nextFeature(cpFt):
                    if cpFt['bildnummer'] in existingFootpints:
                        #QMessageBox.warning(None, u"Bild Nummern", u"Footprint für das Bild mit der Nummer {0} wurde bereits erstellt.".format(ft['BILD']))
                        continue
                    cp = cpFt.geometry()
                    cpMetric = QgsGeometry(cp)
                    destCrs = QgsCoordinateReferenceSystem()
                    destCrs.createFromProj4(self.Proj4Utm(cp.asPoint()))
                    coordTransformF = QgsCoordinateTransform(
                        self.cpLayer.crs(), destCrs, QgsProject.instance())
                    coordTransformB = QgsCoordinateTransform(
                        destCrs, self.cpLayer.crs(), QgsProject.instance())
                    cpMetric.transform(coordTransformF)
                    if cpFt['radius'] == '':
                        r = 175
                    else:
                        r = float(cpFt['radius'])
                    fpMetric = QgsGeometry(cpMetric.buffer(r, 18))
                    fp = QgsGeometry(fpMetric)
                    fp.transform(coordTransformB)

                    fpFt = QgsFeature(self.fpLayer.fields())
                    fpFt.setGeometry(fp)
                    fpFt.setAttribute("bildnummer", cpFt["bildnummer"])
                    fpFt.setAttribute("filmnummer", cpFt["filmnummer"])
                    da = QgsDistanceArea()
                    da.setEllipsoid(self.fpLayer.crs().ellipsoidAcronym())
                    fpFt.setAttribute('shape_length', da.measurePerimeter(fp))
                    fpFt.setAttribute('shape_area', da.measureArea(fp))
                    fpFts.append(fpFt)

                (res,
                 outFeats) = self.fpLayer.dataProvider().addFeatures(fpFts)
                self.fpLayer.updateExtents()
                if self.canvas.isCachingEnabled():
                    self.fpLayer.triggerRepaint()
                else:
                    self.canvas.refresh()
            else:
                QMessageBox.warning(
                    None, "Keine Bildmittelpunkte",
                    "Keine Bildmittelpunkte für den Film {0} vorhanden.".
                    format(self.currentFilmNumber))
        else:
            QMessageBox.warning(
                None, "Layer Capabilities",
                "AddFeature is not enabled ({0})".format(
                    self.fpLayer.dataProvider().capabilitiesString()))
예제 #5
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!"
            )
예제 #6
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()