Esempio n. 1
0
    def testOperations(self):
        w = QgsCoordinateOperationWidget()
        self.assertFalse(w.hasSelection())
        spy = QSignalSpy(w.operationChanged)
        w.setSourceCrs(QgsCoordinateReferenceSystem('EPSG:26745'))
        self.assertEqual(len(spy), 0)
        w.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:3857'))
        self.assertEqual(len(spy), 1)
        self.assertTrue(w.hasSelection())
        self.assertGreaterEqual(len(w.availableOperations()), 6)

        self.assertEqual(
            w.defaultOperation().proj,
            '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=159 +z=175 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        )
        self.assertEqual(
            w.selectedOperation().proj,
            '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=159 +z=175 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        )
        self.assertTrue(w.selectedOperation().isAvailable)

        op = QgsCoordinateOperationWidget.OperationDetails()
        op.proj = '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        op.allowFallback = True
        w.setSelectedOperation(op)
        self.assertEqual(
            w.selectedOperation().proj,
            '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        )
        self.assertTrue(w.selectedOperation().allowFallback)
        self.assertEqual(len(spy), 2)
        w.setSelectedOperation(op)
        self.assertEqual(
            w.selectedOperation().proj,
            '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        )
        self.assertTrue(w.selectedOperation().allowFallback)
        self.assertEqual(len(spy), 2)

        op.proj = '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=159 +z=175 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        op.allowFallback = False
        w.setSelectedOperation(op)
        self.assertEqual(
            w.selectedOperation().proj,
            '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=159 +z=175 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        )
        self.assertFalse(w.selectedOperation().allowFallback)
        self.assertEqual(len(spy), 3)

        op.allowFallback = True
        w.setSelectedOperation(op)
        self.assertEqual(
            w.selectedOperation().proj,
            '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=159 +z=175 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        )
        self.assertTrue(w.selectedOperation().allowFallback)
        self.assertEqual(len(spy), 4)

        context = QgsCoordinateTransformContext()
        op.proj = '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        w.setSelectedOperation(op)
        w.setSelectedOperationUsingContext(context)
        # should go to default, because there's nothing in the context matching these crs
        self.assertEqual(
            w.selectedOperation().proj,
            '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=159 +z=175 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        )
        self.assertEqual(len(spy), 6)

        # put something in the context
        context.addCoordinateOperation(
            w.sourceCrs(), w.destinationCrs(),
            '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        )
        w.setSelectedOperationUsingContext(context)
        self.assertEqual(
            w.selectedOperation().proj,
            '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        )
        self.assertTrue(w.selectedOperation().allowFallback)
        self.assertEqual(len(spy), 7)

        context.addCoordinateOperation(
            w.sourceCrs(), w.destinationCrs(),
            '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84',
            False)
        w.setSelectedOperationUsingContext(context)
        self.assertEqual(
            w.selectedOperation().proj,
            '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84'
        )
        self.assertFalse(w.selectedOperation().allowFallback)
        self.assertEqual(len(spy), 8)
Esempio n. 2
0
    def search(self):
        fields = PLOTS_LAYER_DEFAULT_FIELDS + self.additional_output_fields

        self.layer_found.startEditing()
        self.layer_found.dataProvider().addAttributes(fields)

        self.layer_not_found.startEditing()
        self.layer_not_found.dataProvider().addAttributes([
            QgsField("tresc_bledu", QVariant.String),
        ])

        self.uldk_search = ULDKSearchPoint(
            "dzialka", ("geom_wkt", "wojewodztwo", "powiat", "gmina", "obreb",
                        "numer", "teryt"))

        self.uldk_search = ULDKSearchLogger(self.uldk_search)

        feature_iterator = self.source_layer.getSelectedFeatures(
        ) if self.selected_only else self.source_layer.getFeatures()
        source_geom_type = self.source_layer.wkbType()
        source_crs = self.source_layer.sourceCrs()
        self.geometries = []
        self.not_found_geometries = []
        self.parcels_geometry = QgsGeometry.fromMultiPolygonXY([])

        self.transformation = None
        if source_crs != CRS_2180:
            self.transformation = QgsCoordinateTransform(
                source_crs, CRS_2180, QgsCoordinateTransformContext())

        geom_type = self._get_non_z_geom_type(source_geom_type)
        if geom_type == QgsWkbTypes.Point or geom_type == QgsWkbTypes.MultiPoint:
            self.count_not_found_as_progressed = True

            for index, f in enumerate(feature_iterator):
                point = f.geometry().asPoint()

                if self.transformation:
                    point = self.transformation.transform(point)

                f.setGeometry(QgsGeometry.fromPointXY(point))
                self._process_feature(f, True)
        else:
            self.count_not_found_as_progressed = False

            if self.additional_output_fields:
                self.fields_to_add = QgsFields()
                for field in self.additional_output_fields:
                    self.fields_to_add.append(field)

            for f in feature_iterator:
                additional_attributes = []

                if self.additional_output_fields:
                    additional_attributes = [
                        f.attribute(field.name())
                        for field in self.additional_output_fields
                    ]

                points = self._feature_to_points(f, source_geom_type,
                                                 additional_attributes)
                continue_search = True

                while points != []:
                    saved_features = [
                        self._process_feature(point) for point in points
                    ]
                    if any(saved_features):
                        points = self._feature_to_points(
                            f, source_geom_type, additional_attributes)
                    else:
                        points = []
                self.__commit()
                self.progressed.emit(self.layer_found, self.layer_not_found,
                                     True, 0, False, True)

        self.finished.emit(self.layer_found, self.layer_not_found)
    def testStartEditingCommitRollBack(self):

        ml = QgsVectorLayer(
            'Point?crs=epsg:4326&field=int:integer&field=int2:integer', 'test',
            'memory')
        self.assertTrue(ml.isValid())

        # Layer A geopackage A
        d = QTemporaryDir()
        options = QgsVectorFileWriter.SaveVectorOptions()
        options.driverName = 'GPKG'
        options.layerName = 'layer_a'
        err, msg, newFileName, newLayer = QgsVectorFileWriter.writeAsVectorFormatV3(
            ml, os.path.join(d.path(), 'test_EditBufferGroup_A.gpkg'),
            QgsCoordinateTransformContext(), options)

        self.assertEqual(err, QgsVectorFileWriter.NoError)
        self.assertTrue(os.path.isfile(newFileName))

        layer_a = QgsVectorLayer(newFileName + '|layername=layer_a')

        self.assertTrue(layer_a.isValid())

        # Layer B geopackage B
        options.layerName = 'layer_b'
        err, msg, newFileName, newLayer = QgsVectorFileWriter.writeAsVectorFormatV3(
            ml, os.path.join(d.path(), 'test_EditBufferGroup_B.gpkg'),
            QgsCoordinateTransformContext(), options)

        self.assertEqual(err, QgsVectorFileWriter.NoError)
        self.assertTrue(os.path.isfile(newFileName))

        layer_b = QgsVectorLayer(newFileName + '|layername=layer_b')

        self.assertTrue(layer_b.isValid())

        # Layer C memory
        layer_c = QgsVectorLayer(
            'Point?crs=epsg:4326&field=int:integer&field=int2:integer', 'test',
            'memory')
        self.assertTrue(layer_c.isValid())

        project = QgsProject()
        project.addMapLayers([layer_a, layer_b, layer_c])
        project.setTransactionMode(Qgis.TransactionMode.BufferedGroups)

        editBufferGroup = project.editBufferGroup()

        # Check layers in group
        self.assertIn(layer_a, editBufferGroup.layers())
        self.assertIn(layer_b, editBufferGroup.layers())
        self.assertIn(layer_c, editBufferGroup.layers())

        self.assertFalse(editBufferGroup.isEditing())

        self.assertTrue(editBufferGroup.startEditing())
        self.assertTrue(editBufferGroup.isEditing())
        self.assertTrue(layer_a.editBuffer())
        self.assertTrue(layer_b.editBuffer())
        self.assertTrue(layer_c.editBuffer())
        self.assertEqual(len(editBufferGroup.modifiedLayers()), 0)

        commitErrors = []
        self.assertTrue(editBufferGroup.commitChanges(commitErrors, False))
        self.assertTrue(editBufferGroup.isEditing())
        self.assertTrue(editBufferGroup.commitChanges(commitErrors, True))
        self.assertFalse(editBufferGroup.isEditing())

        self.assertTrue(editBufferGroup.startEditing())
        self.assertTrue(editBufferGroup.isEditing())

        f = QgsFeature(layer_a.fields())
        f.setAttribute('int', 123)
        f.setGeometry(QgsGeometry.fromWkt('point(7 45)'))
        self.assertTrue(layer_a.addFeatures([f]))
        self.assertEqual(len(editBufferGroup.modifiedLayers()), 1)
        self.assertIn(layer_a, editBufferGroup.modifiedLayers())

        # Check feature in layer edit buffer but not in provider till commit
        self.assertEqual(layer_a.featureCount(), 1)
        self.assertEqual(layer_a.dataProvider().featureCount(), 0)

        rollbackErrors = []
        self.assertTrue(editBufferGroup.rollBack(rollbackErrors, False))
        self.assertTrue(editBufferGroup.isEditing())
        self.assertEqual(layer_a.featureCount(), 0)

        self.assertTrue(layer_a.addFeatures([f]))
        self.assertEqual(layer_a.featureCount(), 1)
        self.assertEqual(layer_a.dataProvider().featureCount(), 0)

        self.assertTrue(editBufferGroup.commitChanges(commitErrors, True))
        self.assertFalse(editBufferGroup.isEditing())
        self.assertEqual(layer_a.featureCount(), 1)
        self.assertEqual(layer_a.dataProvider().featureCount(), 1)
Esempio n. 4
0
crs: QgsCoordinateReferenceSystem = layer.crs()

print(crs)

if crs.isGeographic():
    raise TypeError("Cannot process data with geographic coordinate system.")

fields: QgsFields = layer.fields()

save_options = QgsVectorFileWriter.SaveVectorOptions()
save_options.fileEncoding = "UTF-8"

writer: QgsVectorFileWriter = QgsVectorFileWriter.create(
    str(path_data_output), fields, QgsWkbTypes.Point, layer.crs(),
    QgsCoordinateTransformContext(), save_options)

features: QgsFeatureIterator = layer.getFeatures()

feature: QgsFeature

for feature in features:

    new_feature = QgsFeature(fields)

    old_geom: QgsGeometry = feature.geometry()

    new_geom: QgsGeometry = old_geom.poleOfInaccessibility(precision)[0]

    new_feature.setAttributes(feature.attributes())
    new_feature.setGeometry(new_geom)
Esempio n. 5
0
    def testShapefilesWithNoAttributes(self):
        """Test issue GH #38834"""

        ml = QgsVectorLayer('Point?crs=epsg:4326', 'test', 'memory')
        self.assertTrue(ml.isValid())

        d = QTemporaryDir()
        options = QgsVectorFileWriter.SaveVectorOptions()
        options.driverName = 'ESRI Shapefile'
        options.layerName = 'writetest'
        err, _ = QgsVectorFileWriter.writeAsVectorFormatV2(ml, os.path.join(d.path(), 'writetest.shp'), QgsCoordinateTransformContext(), options)
        self.assertEqual(err, QgsVectorFileWriter.NoError)
        self.assertTrue(os.path.isfile(os.path.join(d.path(), 'writetest.shp')))

        vl = QgsVectorLayer(os.path.join(d.path(), 'writetest.shp'))
        self.assertTrue(bool(vl.dataProvider().capabilities() & QgsVectorDataProvider.AddFeatures))

        # Let's try if we can really add features
        feature = QgsFeature(vl.fields())
        geom = QgsGeometry.fromWkt('POINT(9 45)')
        feature.setGeometry(geom)
        self.assertTrue(vl.startEditing())
        self.assertTrue(vl.addFeatures([feature]))
        self.assertTrue(vl.commitChanges())
        del (vl)

        vl = QgsVectorLayer(os.path.join(d.path(), 'writetest.shp'))
        self.assertEqual(vl.featureCount(), 1)
Esempio n. 6
0
        def _test(autoTransaction):
            """Test buffer methods within and without transactions

            - create a feature
            - save
            - retrieve the feature
            - change geom and attrs
            - test changes are seen in the buffer
            """
            def _check_feature(wkt):

                f = next(layer_a.getFeatures())
                self.assertEqual(f.geometry().asWkt().upper(), wkt)
                f = list(buffer.addedFeatures().values())[0]
                self.assertEqual(f.geometry().asWkt().upper(), wkt)

            ml = QgsVectorLayer(
                'Point?crs=epsg:4326&field=int:integer&field=int2:integer',
                'test', 'memory')
            self.assertTrue(ml.isValid())

            d = QTemporaryDir()
            options = QgsVectorFileWriter.SaveVectorOptions()
            options.driverName = 'GPKG'
            options.layerName = 'layer_a'
            err, msg, newFileName, newLayer = QgsVectorFileWriter.writeAsVectorFormatV3(
                ml, os.path.join(d.path(), 'transaction_test.gpkg'),
                QgsCoordinateTransformContext(), options)

            self.assertEqual(err, QgsVectorFileWriter.NoError)
            self.assertTrue(os.path.isfile(newFileName))

            layer_a = QgsVectorLayer(newFileName + '|layername=layer_a')

            self.assertTrue(layer_a.isValid())

            project = QgsProject()
            project.setAutoTransaction(autoTransaction)
            project.addMapLayers([layer_a])

            ###########################################
            # Tests with a new feature

            self.assertTrue(layer_a.startEditing())
            buffer = layer_a.editBuffer()

            f = QgsFeature(layer_a.fields())
            f.setAttribute('int', 123)
            f.setGeometry(QgsGeometry.fromWkt('point(7 45)'))
            self.assertTrue(layer_a.addFeatures([f]))

            _check_feature('POINT (7 45)')

            # Need to fetch the feature because its ID is NULL (-9223372036854775808)
            f = next(layer_a.getFeatures())

            self.assertEqual(len(buffer.addedFeatures()), 1)
            layer_a.undoStack().undo()
            self.assertEqual(len(buffer.addedFeatures()), 0)
            layer_a.undoStack().redo()
            self.assertEqual(len(buffer.addedFeatures()), 1)
            f = list(buffer.addedFeatures().values())[0]
            self.assertEqual(f.attribute('int'), 123)

            # Now change attribute
            self.assertEqual(buffer.changedAttributeValues(), {})
            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.changeAttributeValue(f.id(), 1, 321)
            self.assertEqual(len(spy_attribute_changed), 1)
            self.assertEqual(spy_attribute_changed[0], [f.id(), 1, 321])

            self.assertEqual(len(buffer.addedFeatures()), 1)
            # This is surprising: because it was a new feature it has been changed directly
            self.assertEqual(buffer.changedAttributeValues(), {})
            f = list(buffer.addedFeatures().values())[0]
            self.assertEqual(f.attribute('int'), 321)

            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.undoStack().undo()
            self.assertEqual(len(spy_attribute_changed), 1)
            self.assertEqual(spy_attribute_changed[0], [f.id(), 1, 123])
            self.assertEqual(buffer.changedAttributeValues(), {})
            f = list(buffer.addedFeatures().values())[0]
            self.assertEqual(f.attribute('int'), 123)
            f = next(layer_a.getFeatures())
            self.assertEqual(f.attribute('int'), 123)

            # Change multiple attributes
            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.changeAttributeValues(f.id(), {1: 321, 2: 456})
            self.assertEqual(len(spy_attribute_changed), 2)
            self.assertEqual(spy_attribute_changed[0], [f.id(), 1, 321])
            self.assertEqual(spy_attribute_changed[1], [f.id(), 2, 456])
            buffer = layer_a.editBuffer()
            # This is surprising: because it was a new feature it has been changed directly
            self.assertEqual(buffer.changedAttributeValues(), {})

            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.undoStack().undo()
            # This is because QgsVectorLayerUndoCommandChangeAttribute plural
            if not autoTransaction:
                layer_a.undoStack().undo()
            f = next(layer_a.getFeatures())
            self.assertEqual(f.attribute('int'), 123)
            self.assertEqual(f.attribute('int2'), None)
            self.assertEqual(len(spy_attribute_changed), 2)
            self.assertEqual(
                spy_attribute_changed[1 if autoTransaction else 0],
                [f.id(), 2, None])
            self.assertEqual(
                spy_attribute_changed[0 if autoTransaction else 1],
                [f.id(), 1, 123])

            # Change geometry
            f = next(layer_a.getFeatures())
            spy_geometry_changed = QSignalSpy(layer_a.geometryChanged)
            self.assertTrue(
                layer_a.changeGeometry(f.id(),
                                       QgsGeometry.fromWkt('point(9 43)')))
            self.assertTrue(len(spy_geometry_changed), 1)
            self.assertEqual(spy_geometry_changed[0][0], f.id())
            self.assertEqual(spy_geometry_changed[0][1].asWkt(),
                             QgsGeometry.fromWkt('point(9 43)').asWkt())

            _check_feature('POINT (9 43)')
            self.assertEqual(buffer.changedGeometries(), {})

            layer_a.undoStack().undo()

            _check_feature('POINT (7 45)')
            self.assertEqual(buffer.changedGeometries(), {})

            self.assertTrue(
                layer_a.changeGeometry(f.id(),
                                       QgsGeometry.fromWkt('point(9 43)')))
            _check_feature('POINT (9 43)')

            self.assertTrue(
                layer_a.changeGeometry(f.id(),
                                       QgsGeometry.fromWkt('point(10 44)')))
            _check_feature('POINT (10 44)')

            # This is another surprise: geometry edits get collapsed into a single
            # one because they have the same hardcoded id
            layer_a.undoStack().undo()
            _check_feature('POINT (7 45)')

            self.assertTrue(layer_a.commitChanges())

            ###########################################
            # Tests with the existing feature

            # Get the feature
            f = next(layer_a.getFeatures())
            self.assertTrue(f.isValid())
            self.assertEqual(f.attribute('int'), 123)
            self.assertEqual(f.geometry().asWkt().upper(), 'POINT (7 45)')

            # Change single attribute
            self.assertTrue(layer_a.startEditing())
            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.changeAttributeValue(f.id(), 1, 321)
            self.assertEqual(len(spy_attribute_changed), 1)
            self.assertEqual(spy_attribute_changed[0], [f.id(), 1, 321])
            buffer = layer_a.editBuffer()
            self.assertEqual(buffer.changedAttributeValues(), {1: {1: 321}})

            f = next(layer_a.getFeatures())
            self.assertEqual(f.attribute(1), 321)

            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.undoStack().undo()
            f = next(layer_a.getFeatures())
            self.assertEqual(f.attribute(1), 123)
            self.assertEqual(len(spy_attribute_changed), 1)
            self.assertEqual(spy_attribute_changed[0], [f.id(), 1, 123])
            self.assertEqual(buffer.changedAttributeValues(), {})

            # Change attributes
            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.changeAttributeValues(f.id(), {1: 111, 2: 654})
            self.assertEqual(len(spy_attribute_changed), 2)
            self.assertEqual(spy_attribute_changed[0], [1, 1, 111])
            self.assertEqual(spy_attribute_changed[1], [1, 2, 654])
            f = next(layer_a.getFeatures())
            self.assertEqual(f.attributes(), [1, 111, 654])
            self.assertEqual(buffer.changedAttributeValues(),
                             {1: {
                                 1: 111,
                                 2: 654
                             }})

            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.undoStack().undo()
            # This is because QgsVectorLayerUndoCommandChangeAttribute plural
            if not autoTransaction:
                layer_a.undoStack().undo()
            self.assertEqual(len(spy_attribute_changed), 2)
            self.assertEqual(
                spy_attribute_changed[0 if autoTransaction else 1],
                [1, 1, 123])
            self.assertEqual(
                spy_attribute_changed[1 if autoTransaction else 0],
                [1, 2, None])
            f = next(layer_a.getFeatures())
            self.assertEqual(f.attributes(), [1, 123, None])
            self.assertEqual(buffer.changedAttributeValues(), {})

            # Change geometry
            spy_geometry_changed = QSignalSpy(layer_a.geometryChanged)
            self.assertTrue(
                layer_a.changeGeometry(f.id(),
                                       QgsGeometry.fromWkt('point(9 43)')))
            self.assertEqual(spy_geometry_changed[0][0], 1)
            self.assertEqual(spy_geometry_changed[0][1].asWkt(),
                             QgsGeometry.fromWkt('point(9 43)').asWkt())

            f = next(layer_a.getFeatures())
            self.assertEqual(f.geometry().asWkt().upper(), 'POINT (9 43)')
            self.assertEqual(buffer.changedGeometries()[1].asWkt().upper(),
                             'POINT (9 43)')

            spy_geometry_changed = QSignalSpy(layer_a.geometryChanged)
            layer_a.undoStack().undo()
            self.assertEqual(spy_geometry_changed[0][0], 1)
            self.assertEqual(spy_geometry_changed[0][1].asWkt(),
                             QgsGeometry.fromWkt('point(7 45)').asWkt())
            self.assertEqual(buffer.changedGeometries(), {})
            f = next(layer_a.getFeatures())

            self.assertEqual(f.geometry().asWkt().upper(), 'POINT (7 45)')
            self.assertEqual(buffer.changedGeometries(), {})

            # Delete an existing feature
            self.assertTrue(layer_a.deleteFeature(f.id()))
            with self.assertRaises(StopIteration):
                next(layer_a.getFeatures())
            self.assertEqual(buffer.deletedFeatureIds(), [f.id()])

            layer_a.undoStack().undo()
            self.assertTrue(layer_a.getFeature(f.id()).isValid())
            self.assertEqual(buffer.deletedFeatureIds(), [])

            ###########################################
            # Test delete

            # Delete a new feature
            f = QgsFeature(layer_a.fields())
            f.setAttribute('int', 555)
            f.setGeometry(QgsGeometry.fromWkt('point(8 46)'))
            self.assertTrue(layer_a.addFeatures([f]))
            f = [
                f for f in layer_a.getFeatures() if f.attribute('int') == 555
            ][0]
            self.assertTrue(f.id() in buffer.addedFeatures())
            self.assertTrue(layer_a.deleteFeature(f.id()))
            self.assertFalse(f.id() in buffer.addedFeatures())
            self.assertFalse(f.id() in buffer.deletedFeatureIds())

            layer_a.undoStack().undo()
            self.assertTrue(f.id() in buffer.addedFeatures())

            ###########################################
            # Add attribute

            field = QgsField('attr1', QVariant.String)
            self.assertTrue(layer_a.addAttribute(field))
            self.assertNotEqual(layer_a.fields().lookupField(field.name()), -1)
            self.assertEqual(buffer.addedAttributes(), [field])

            layer_a.undoStack().undo()
            self.assertEqual(layer_a.fields().lookupField(field.name()), -1)
            self.assertEqual(buffer.addedAttributes(), [])

            layer_a.undoStack().redo()
            self.assertNotEqual(layer_a.fields().lookupField(field.name()), -1)
            self.assertEqual(buffer.addedAttributes(), [field])

            self.assertTrue(layer_a.commitChanges())

            ###########################################
            # Remove attribute

            self.assertTrue(layer_a.startEditing())
            buffer = layer_a.editBuffer()

            attr_idx = layer_a.fields().lookupField(field.name())
            self.assertNotEqual(attr_idx, -1)

            self.assertTrue(layer_a.deleteAttribute(attr_idx))
            self.assertEqual(buffer.deletedAttributeIds(), [attr_idx])
            self.assertEqual(layer_a.fields().lookupField(field.name()), -1)

            layer_a.undoStack().undo()
            self.assertEqual(buffer.deletedAttributeIds(), [])
            self.assertEqual(layer_a.fields().lookupField(field.name()),
                             attr_idx)

            # This is totally broken at least on OGR/GPKG: the rollback
            # does not restore the original fields
            if False:

                layer_a.undoStack().redo()
                self.assertEqual(buffer.deletedAttributeIds(), [attr_idx])
                self.assertEqual(layer_a.fields().lookupField(field.name()),
                                 -1)

                # Rollback!
                self.assertTrue(layer_a.rollBack())

                self.assertIn('attr1', layer_a.dataProvider().fields().names())
                self.assertIn('attr1', layer_a.fields().names())
                self.assertEqual(layer_a.fields().names(),
                                 layer_a.dataProvider().fields().names())

                attr_idx = layer_a.fields().lookupField(field.name())
                self.assertNotEqual(attr_idx, -1)

                self.assertTrue(layer_a.startEditing())
                attr_idx = layer_a.fields().lookupField(field.name())
                self.assertNotEqual(attr_idx, -1)

            ###########################################
            # Rename attribute

            attr_idx = layer_a.fields().lookupField(field.name())
            self.assertEqual(layer_a.fields().lookupField('new_name'), -1)
            self.assertTrue(layer_a.renameAttribute(attr_idx, 'new_name'))
            self.assertEqual(layer_a.fields().lookupField('new_name'),
                             attr_idx)

            layer_a.undoStack().undo()
            self.assertEqual(layer_a.fields().lookupField(field.name()),
                             attr_idx)
            self.assertEqual(layer_a.fields().lookupField('new_name'), -1)

            layer_a.undoStack().redo()
            self.assertEqual(layer_a.fields().lookupField('new_name'),
                             attr_idx)
            self.assertEqual(layer_a.fields().lookupField(field.name()), -1)

            #############################################
            # Try hard to make this fail for transactions
            if autoTransaction:
                self.assertTrue(layer_a.commitChanges())
                self.assertTrue(layer_a.startEditing())
                f = next(layer_a.getFeatures())

                # Do
                for i in range(10):
                    spy_attribute_changed = QSignalSpy(
                        layer_a.attributeValueChanged)
                    layer_a.changeAttributeValue(f.id(), 2, i)
                    self.assertEqual(len(spy_attribute_changed), 1)
                    self.assertEqual(spy_attribute_changed[0], [f.id(), 2, i])
                    buffer = layer_a.editBuffer()
                    self.assertEqual(buffer.changedAttributeValues(),
                                     {f.id(): {
                                          2: i
                                      }})
                    f = next(layer_a.getFeatures())
                    self.assertEqual(f.attribute(2), i)

                # Undo/redo
                for i in range(9):

                    # Undo
                    spy_attribute_changed = QSignalSpy(
                        layer_a.attributeValueChanged)
                    layer_a.undoStack().undo()
                    f = next(layer_a.getFeatures())
                    self.assertEqual(f.attribute(2), 8 - i)
                    self.assertEqual(len(spy_attribute_changed), 1)
                    self.assertEqual(spy_attribute_changed[0],
                                     [f.id(), 2, 8 - i])
                    buffer = layer_a.editBuffer()
                    self.assertEqual(buffer.changedAttributeValues(),
                                     {f.id(): {
                                          2: 8 - i
                                      }})

                    # Redo
                    spy_attribute_changed = QSignalSpy(
                        layer_a.attributeValueChanged)
                    layer_a.undoStack().redo()
                    f = next(layer_a.getFeatures())
                    self.assertEqual(f.attribute(2), 9 - i)
                    self.assertEqual(len(spy_attribute_changed), 1)
                    self.assertEqual(spy_attribute_changed[0],
                                     [f.id(), 2, 9 - i])

                    # Undo again
                    spy_attribute_changed = QSignalSpy(
                        layer_a.attributeValueChanged)
                    layer_a.undoStack().undo()
                    f = next(layer_a.getFeatures())
                    self.assertEqual(f.attribute(2), 8 - i)
                    self.assertEqual(len(spy_attribute_changed), 1)
                    self.assertEqual(spy_attribute_changed[0],
                                     [f.id(), 2, 8 - i])
                    buffer = layer_a.editBuffer()
                    self.assertEqual(buffer.changedAttributeValues(),
                                     {f.id(): {
                                          2: 8 - i
                                      }})

                    # Last check
                    f = next(layer_a.getFeatures())
                    self.assertEqual(f.attribute(2), 8 - i)

                self.assertEqual(buffer.changedAttributeValues(),
                                 {f.id(): {
                                      2: 0
                                  }})
                layer_a.undoStack().undo()
                buffer = layer_a.editBuffer()
                self.assertEqual(buffer.changedAttributeValues(), {})
                f = next(layer_a.getFeatures())
                self.assertEqual(f.attribute(2), None)
def create_shapefile_full_layer_data_provider(path, name, srid, attributes, types, values, coords):
    """
    Creates a shapefile using the Shapefile Data Provider

    Parameters
    ----------
    path : `str`
        folder where the shapefile is to be saved
    name : `str`
        name of the shapefile
    srid : `str`
        CRS of the newly created shapefile
    attributes: array_like
        list of attribute (field) names
    types : array_like
        list of types (field) types, in sync with the `attributes` parameter
    values : array_like
        coordinates and attribute data, one array for each feature (F, C + A),
        F for features, C for coordinates and A for attribute data
    coords : array_like
        indices of the coordinate values within the `values` array

    Returns
    -------
    vl : `QgsVectorLayer`
        the newly-created layer

    """
    # create new layer with given attributes
    filename = path + "/" + name + ".shp"

    # create an instance of vector file writer, which will create the vector file.
    writer = None
    options = QgsVectorFileWriter.SaveVectorOptions()
    options.driverName = "ESRI Shapefile"
    options.fileEncoding = 'utf-8'
    if len(coords) == 2:
        type = 'point'
        writer = QgsVectorFileWriter.create(filename, QgsFields(), QgsWkbTypes.Point, srid,
                                            QgsCoordinateTransformContext(), options)
    elif len(coords) == 4:
        type = 'line'
        writer = QgsVectorFileWriter.create(filename, QgsFields(), QgsWkbTypes.LineString, srid,
                                            QgsCoordinateTransformContext(), options)
    if writer.hasError() != QgsVectorFileWriter.NoError:
        print("Error when creating shapefile: ", writer.hasError())
        return None
    del writer
    # open the newly created file
    vl = QgsVectorLayer(filename, name, "ogr")

    pr = vl.dataProvider()

    # create the required fields
    for i, attr in enumerate(attributes):
        pr.addAttributes([QgsField(attr, types[i])])
    vl.commitChanges()
    # add features by iterating the values
    feat = QgsFeature()
    for i, val in enumerate(values):
        # add geometry
        try:
            if type == 'point':
                geometry = QgsGeometry.fromPoint([QgsPoint(float(val[coords[0]]),
                                                           float(val[coords[1]]))])
            elif type == 'line':
                geometry = QgsGeometry.fromPolyline([QgsPoint(float(val[coords[0]]),
                                                              float(val[coords[1]])),
                                                     QgsPoint(float(val[coords[2]]),
                                                              float(val[coords[3]]))])
            feat.setGeometry(geometry)
        except:
            pass
        # add attributes
        attrs = []
        for j, attr in enumerate(attributes):
            attrs.append(val[j])
        feat.setAttributes(attrs)
        pr.addFeature(feat)
    vl.updateExtents()

    vl = QgsVectorLayer(filename, name, "ogr")

    if not vl.isValid():
        raise IOError("Layer could not be created")
        return None
    return vl
Esempio n. 8
0
    def testOperations(self):
        w = QgsCoordinateOperationWidget()
        self.assertFalse(w.hasSelection())
        spy = QSignalSpy(w.operationChanged)
        w.setSourceCrs(QgsCoordinateReferenceSystem('EPSG:28355'))
        self.assertEqual(len(spy), 0)
        w.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:7855'))
        self.assertEqual(len(spy), 1)
        self.assertTrue(w.hasSelection())
        self.assertEqual(len(w.availableOperations()), 3)

        self.assertEqual(
            w.defaultOperation().proj,
            '+proj=pipeline +step +inv +proj=utm +zone=55 +south +ellps=GRS80 +step +proj=push +v_3 +step +proj=cart +ellps=GRS80 +step +proj=helmert +x=0.06155 +y=-0.01087 +z=-0.04019 +rx=-0.0394924 +ry=-0.0327221 +rz=-0.0328979 +s=-0.009994 +convention=coordinate_frame +step +inv +proj=cart +ellps=GRS80 +step +proj=pop +v_3 +step +proj=utm +zone=55 +south +ellps=GRS80'
        )
        self.assertEqual(
            w.selectedOperation().proj,
            '+proj=pipeline +step +inv +proj=utm +zone=55 +south +ellps=GRS80 +step +proj=push +v_3 +step +proj=cart +ellps=GRS80 +step +proj=helmert +x=0.06155 +y=-0.01087 +z=-0.04019 +rx=-0.0394924 +ry=-0.0327221 +rz=-0.0328979 +s=-0.009994 +convention=coordinate_frame +step +inv +proj=cart +ellps=GRS80 +step +proj=pop +v_3 +step +proj=utm +zone=55 +south +ellps=GRS80'
        )
        self.assertTrue(w.selectedOperation().isAvailable)

        op = QgsCoordinateOperationWidget.OperationDetails()
        op.proj = '+proj=pipeline +step +inv +proj=utm +zone=55 +south +ellps=GRS80 +step +proj=hgridshift +grids=GDA94_GDA2020_conformal_and_distortion.gsb +step +proj=utm +zone=55 +south +ellps=GRS80'
        w.setSelectedOperation(op)
        self.assertEqual(
            w.selectedOperation().proj,
            '+proj=pipeline +step +inv +proj=utm +zone=55 +south +ellps=GRS80 +step +proj=hgridshift +grids=GDA94_GDA2020_conformal_and_distortion.gsb +step +proj=utm +zone=55 +south +ellps=GRS80'
        )
        self.assertEqual(len(spy), 2)
        w.setSelectedOperation(op)
        self.assertEqual(
            w.selectedOperation().proj,
            '+proj=pipeline +step +inv +proj=utm +zone=55 +south +ellps=GRS80 +step +proj=hgridshift +grids=GDA94_GDA2020_conformal_and_distortion.gsb +step +proj=utm +zone=55 +south +ellps=GRS80'
        )
        self.assertEqual(len(spy), 2)

        op.proj = '+proj=pipeline +step +inv +proj=utm +zone=55 +south +ellps=GRS80 +step +proj=push +v_3 +step +proj=cart +ellps=GRS80 +step +proj=helmert +x=0.06155 +y=-0.01087 +z=-0.04019 +rx=-0.0394924 +ry=-0.0327221 +rz=-0.0328979 +s=-0.009994 +convention=coordinate_frame +step +inv +proj=cart +ellps=GRS80 +step +proj=pop +v_3 +step +proj=utm +zone=55 +south +ellps=GRS80'
        w.setSelectedOperation(op)
        self.assertEqual(
            w.selectedOperation().proj,
            '+proj=pipeline +step +inv +proj=utm +zone=55 +south +ellps=GRS80 +step +proj=push +v_3 +step +proj=cart +ellps=GRS80 +step +proj=helmert +x=0.06155 +y=-0.01087 +z=-0.04019 +rx=-0.0394924 +ry=-0.0327221 +rz=-0.0328979 +s=-0.009994 +convention=coordinate_frame +step +inv +proj=cart +ellps=GRS80 +step +proj=pop +v_3 +step +proj=utm +zone=55 +south +ellps=GRS80'
        )
        self.assertEqual(len(spy), 3)

        context = QgsCoordinateTransformContext()
        op.proj = '+proj=pipeline +step +inv +proj=utm +zone=55 +south +ellps=GRS80 +step +proj=hgridshift +grids=GDA94_GDA2020_conformal_and_distortion.gsb +step +proj=utm +zone=55 +south +ellps=GRS80'
        w.setSelectedOperation(op)
        w.setSelectedOperationUsingContext(context)
        # should go to default, because there's nothing in the context matching these crs
        self.assertEqual(
            w.selectedOperation().proj,
            '+proj=pipeline +step +inv +proj=utm +zone=55 +south +ellps=GRS80 +step +proj=push +v_3 +step +proj=cart +ellps=GRS80 +step +proj=helmert +x=0.06155 +y=-0.01087 +z=-0.04019 +rx=-0.0394924 +ry=-0.0327221 +rz=-0.0328979 +s=-0.009994 +convention=coordinate_frame +step +inv +proj=cart +ellps=GRS80 +step +proj=pop +v_3 +step +proj=utm +zone=55 +south +ellps=GRS80'
        )
        self.assertEqual(len(spy), 5)

        # put something in the context
        context.addCoordinateOperation(
            w.sourceCrs(), w.destinationCrs(),
            '+proj=pipeline +step +inv +proj=utm +zone=55 +south +ellps=GRS80 +step +proj=hgridshift +grids=GDA94_GDA2020_conformal_and_distortion.gsb +step +proj=utm +zone=55 +south +ellps=GRS80'
        )
        w.setSelectedOperationUsingContext(context)
        self.assertEqual(
            w.selectedOperation().proj,
            '+proj=pipeline +step +inv +proj=utm +zone=55 +south +ellps=GRS80 +step +proj=hgridshift +grids=GDA94_GDA2020_conformal_and_distortion.gsb +step +proj=utm +zone=55 +south +ellps=GRS80'
        )
        self.assertEqual(len(spy), 6)
Esempio n. 9
0
    def testWriteReadXmlProj6(self):
        # setup a context
        context = QgsCoordinateTransformContext()

        proj_1 = '+proj=pipeline +step +proj=axisswap +order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 +step +proj=cart +ellps=intl +step +proj=helmert +x=-18.944 +y=-379.364 +z=-24.063 +rx=-0.04 +ry=0.764 +rz=-6.431 +s=3.657 +convention=coordinate_frame +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1'
        proj_2 = '+proj=pipeline +step +proj=axisswap +order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 +step +proj=cart +ellps=intl +step +proj=helmert +x=-150 +y=-250 +z=-1 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1'
        proj_3 = '+proj=pipeline +step +proj=axisswap +order=2,1'

        self.assertTrue(
            context.addCoordinateOperation(
                QgsCoordinateReferenceSystem('EPSG:4204'),
                QgsCoordinateReferenceSystem('EPSG:4326'), proj_1, True))
        self.assertTrue(
            context.addCoordinateOperation(
                QgsCoordinateReferenceSystem('EPSG:4205'),
                QgsCoordinateReferenceSystem('EPSG:4326'), proj_2, False))

        # also insert a crs with no authid available
        self.assertTrue(
            context.addCoordinateOperation(
                QgsCoordinateReferenceSystem.fromProj(
                    "+proj=longlat +a=6378137 +rf=298.25722356300003 +no_defs"
                ), QgsCoordinateReferenceSystem('EPSG:4326'), proj_3, False))

        self.assertEqual(
            context.coordinateOperations(), {
                ('EPSG:4204', 'EPSG:4326'): proj_1,
                ('EPSG:4205', 'EPSG:4326'): proj_2,
                ('', 'EPSG:4326'): proj_3
            })

        # save to xml
        doc = QDomDocument("testdoc")
        elem = doc.createElement("test")
        context.writeXml(elem, QgsReadWriteContext())

        # restore from xml
        context2 = QgsCoordinateTransformContext()
        context2.readXml(elem, QgsReadWriteContext())

        # check result
        self.assertEqual(
            context2.coordinateOperations(), {
                ('EPSG:4204', 'EPSG:4326'): proj_1,
                ('EPSG:4205', 'EPSG:4326'): proj_2,
                ('', 'EPSG:4326'): proj_3
            })
        self.assertEqual(
            context2.calculateCoordinateOperation(
                QgsCoordinateReferenceSystem.fromProj(
                    "+proj=longlat +a=6378137 +rf=298.25722356300003 +no_defs"
                ), QgsCoordinateReferenceSystem('EPSG:4326')),
            '+proj=pipeline +step +proj=axisswap +order=2,1')
        self.assertFalse(
            context2.mustReverseCoordinateOperation(
                QgsCoordinateReferenceSystem.fromProj(
                    "+proj=longlat +a=6378137 +rf=298.25722356300003 +no_defs"
                ), QgsCoordinateReferenceSystem('EPSG:4326')))
        self.assertEqual(
            context2.calculateCoordinateOperation(
                QgsCoordinateReferenceSystem('EPSG:4326'),
                QgsCoordinateReferenceSystem.fromProj(
                    "+proj=longlat +a=6378137 +rf=298.25722356300003 +no_defs")
            ), '+proj=pipeline +step +proj=axisswap +order=2,1')
        self.assertTrue(
            context2.mustReverseCoordinateOperation(
                QgsCoordinateReferenceSystem('EPSG:4326'),
                QgsCoordinateReferenceSystem.fromProj(
                    "+proj=longlat +a=6378137 +rf=298.25722356300003 +no_defs")
            ))
        self.assertTrue(
            context2.allowFallbackTransform(
                QgsCoordinateReferenceSystem('EPSG:4204'),
                QgsCoordinateReferenceSystem('EPSG:4326')))
        self.assertFalse(
            context2.allowFallbackTransform(
                QgsCoordinateReferenceSystem('EPSG:4205'),
                QgsCoordinateReferenceSystem('EPSG:4326')))
Esempio n. 10
0
def get_feature_ids_that_intersect_bbox(layer, rect, crs):
    request = (QgsFeatureRequest()
               .setFilterRect(rect)
               .setDestinationCrs(crs=crs, context=QgsCoordinateTransformContext())
               .setNoAttributes().setFlags(QgsFeatureRequest.NoGeometry))
    return [f.id() for f in layer.getFeatures(request)]
        def _test(autoTransaction):
            """Test buffer methods within and without transactions

            - create a feature
            - save
            - retrieve the feature
            - change geom and attrs
            - test changes are seen in the buffer
            """

            def _check_feature(wkt):

                f = next(layer_a.getFeatures())
                self.assertEqual(f.geometry().asWkt().upper(), wkt)
                f = list(buffer.addedFeatures().values())[0]
                self.assertEqual(f.geometry().asWkt().upper(), wkt)

            ml = QgsVectorLayer('Point?crs=epsg:4326&field=int:integer', 'test', 'memory')
            self.assertTrue(ml.isValid())

            d = QTemporaryDir()
            options = QgsVectorFileWriter.SaveVectorOptions()
            options.driverName = 'GPKG'
            options.layerName = 'layer_a'
            err, _ = QgsVectorFileWriter.writeAsVectorFormatV2(ml, os.path.join(d.path(), 'transaction_test.gpkg'), QgsCoordinateTransformContext(), options)

            self.assertEqual(err, QgsVectorFileWriter.NoError)
            self.assertTrue(os.path.isfile(os.path.join(d.path(), 'transaction_test.gpkg')))

            options.layerName = 'layer_b'
            options.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteLayer
            err, _ = QgsVectorFileWriter.writeAsVectorFormatV2(ml, os.path.join(d.path(), 'transaction_test.gpkg'), QgsCoordinateTransformContext(), options)

            layer_a = QgsVectorLayer(os.path.join(d.path(), 'transaction_test.gpkg|layername=layer_a'))

            self.assertTrue(layer_a.isValid())

            project = QgsProject()
            project.setAutoTransaction(autoTransaction)
            project.addMapLayers([layer_a])

            ###########################################
            # Tests with a new feature

            self.assertTrue(layer_a.startEditing())
            buffer = layer_a.editBuffer()

            f = QgsFeature(layer_a.fields())
            f.setAttribute('int', 123)
            f.setGeometry(QgsGeometry.fromWkt('point(7 45)'))
            self.assertTrue(layer_a.addFeatures([f]))

            _check_feature('POINT (7 45)')

            # Need to fetch the feature because its ID is NULL (-9223372036854775808)
            f = next(layer_a.getFeatures())

            self.assertEqual(len(buffer.addedFeatures()), 1)
            layer_a.undoStack().undo()
            self.assertEqual(len(buffer.addedFeatures()), 0)
            layer_a.undoStack().redo()
            self.assertEqual(len(buffer.addedFeatures()), 1)
            f = list(buffer.addedFeatures().values())[0]
            self.assertEqual(f.attribute('int'), 123)

            # Now change attribute
            self.assertEqual(buffer.changedAttributeValues(), {})
            layer_a.changeAttributeValue(f.id(), 1, 321)

            self.assertEqual(len(buffer.addedFeatures()), 1)
            # This is surprising: because it was a new feature it has been changed directly
            self.assertEqual(buffer.changedAttributeValues(), {})
            f = list(buffer.addedFeatures().values())[0]
            self.assertEqual(f.attribute('int'), 321)

            layer_a.undoStack().undo()
            self.assertEqual(buffer.changedAttributeValues(), {})
            f = list(buffer.addedFeatures().values())[0]
            self.assertEqual(f.attribute('int'), 123)
            f = next(layer_a.getFeatures())
            self.assertEqual(f.attribute('int'), 123)

            # Change geometry
            f = next(layer_a.getFeatures())
            self.assertTrue(layer_a.changeGeometry(f.id(), QgsGeometry.fromWkt('point(9 43)')))

            _check_feature('POINT (9 43)')
            self.assertEqual(buffer.changedGeometries(), {})

            layer_a.undoStack().undo()

            _check_feature('POINT (7 45)')
            self.assertEqual(buffer.changedGeometries(), {})

            self.assertTrue(layer_a.changeGeometry(f.id(), QgsGeometry.fromWkt('point(9 43)')))
            _check_feature('POINT (9 43)')

            self.assertTrue(layer_a.changeGeometry(f.id(), QgsGeometry.fromWkt('point(10 44)')))
            _check_feature('POINT (10 44)')

            # This is anothr surprise: geometry edits get collapsed into a single
            # one because they have the same hardcoded id
            layer_a.undoStack().undo()
            _check_feature('POINT (7 45)')

            self.assertTrue(layer_a.commitChanges())

            ###########################################
            # Tests with the existing feature

            # Get the feature
            f = next(layer_a.getFeatures())
            self.assertTrue(f.isValid())
            self.assertEqual(f.attribute('int'), 123)
            self.assertEqual(f.geometry().asWkt().upper(), 'POINT (7 45)')

            self.assertTrue(layer_a.startEditing())
            layer_a.changeAttributeValue(f.id(), 1, 321)
            buffer = layer_a.editBuffer()
            self.assertEqual(buffer.changedAttributeValues(), {1: {1: 321}})
            layer_a.undoStack().undo()
            self.assertEqual(buffer.changedAttributeValues(), {})

            # Change geometry
            self.assertTrue(layer_a.changeGeometry(f.id(), QgsGeometry.fromWkt('point(9 43)')))
            f = next(layer_a.getFeatures())
            self.assertEqual(f.geometry().asWkt().upper(), 'POINT (9 43)')
            self.assertEqual(buffer.changedGeometries()[1].asWkt().upper(), 'POINT (9 43)')
            layer_a.undoStack().undo()
            self.assertEqual(buffer.changedGeometries(), {})
            f = next(layer_a.getFeatures())

            self.assertEqual(f.geometry().asWkt().upper(), 'POINT (7 45)')
            self.assertEqual(buffer.changedGeometries(), {})

            # Delete an existing feature
            self.assertTrue(layer_a.deleteFeature(f.id()))
            with self.assertRaises(StopIteration):
                next(layer_a.getFeatures())
            self.assertEqual(buffer.deletedFeatureIds(), [f.id()])

            layer_a.undoStack().undo()
            self.assertTrue(layer_a.getFeature(f.id()).isValid())
            self.assertEqual(buffer.deletedFeatureIds(), [])

            ###########################################
            # Test delete

            # Delete a new feature
            f = QgsFeature(layer_a.fields())
            f.setAttribute('int', 555)
            f.setGeometry(QgsGeometry.fromWkt('point(8 46)'))
            self.assertTrue(layer_a.addFeatures([f]))
            f = [f for f in layer_a.getFeatures() if f.attribute('int') == 555][0]
            self.assertTrue(f.id() in buffer.addedFeatures())
            self.assertTrue(layer_a.deleteFeature(f.id()))
            self.assertFalse(f.id() in buffer.addedFeatures())
            self.assertFalse(f.id() in buffer.deletedFeatureIds())

            layer_a.undoStack().undo()
            self.assertTrue(f.id() in buffer.addedFeatures())

            ###########################################
            # Add attribute

            field = QgsField('attr1', QVariant.String)
            self.assertTrue(layer_a.addAttribute(field))
            self.assertNotEqual(layer_a.fields().lookupField(field.name()), -1)
            self.assertEqual(buffer.addedAttributes(), [field])

            layer_a.undoStack().undo()
            self.assertEqual(layer_a.fields().lookupField(field.name()), -1)
            self.assertEqual(buffer.addedAttributes(), [])

            layer_a.undoStack().redo()
            self.assertNotEqual(layer_a.fields().lookupField(field.name()), -1)
            self.assertEqual(buffer.addedAttributes(), [field])

            self.assertTrue(layer_a.commitChanges())

            ###########################################
            # Remove attribute

            self.assertTrue(layer_a.startEditing())
            buffer = layer_a.editBuffer()

            attr_idx = layer_a.fields().lookupField(field.name())
            self.assertNotEqual(attr_idx, -1)

            self.assertTrue(layer_a.deleteAttribute(attr_idx))
            self.assertEqual(buffer.deletedAttributeIds(), [2])
            self.assertEqual(layer_a.fields().lookupField(field.name()), -1)

            layer_a.undoStack().undo()
            self.assertEqual(buffer.deletedAttributeIds(), [])
            self.assertEqual(layer_a.fields().lookupField(field.name()), attr_idx)

            layer_a.undoStack().redo()
            self.assertEqual(buffer.deletedAttributeIds(), [2])
            self.assertEqual(layer_a.fields().lookupField(field.name()), -1)

            self.assertTrue(layer_a.rollBack())

            ###########################################
            # Rename attribute

            self.assertTrue(layer_a.startEditing())

            attr_idx = layer_a.fields().lookupField(field.name())
            self.assertNotEqual(attr_idx, -1)

            self.assertEqual(layer_a.fields().lookupField('new_name'), -1)
            self.assertTrue(layer_a.renameAttribute(attr_idx, 'new_name'))
            self.assertEqual(layer_a.fields().lookupField('new_name'), attr_idx)

            layer_a.undoStack().undo()
            self.assertEqual(layer_a.fields().lookupField(field.name()), attr_idx)
            self.assertEqual(layer_a.fields().lookupField('new_name'), -1)

            layer_a.undoStack().redo()
            self.assertEqual(layer_a.fields().lookupField('new_name'), attr_idx)
            self.assertEqual(layer_a.fields().lookupField(field.name()), -1)
Esempio n. 12
0
    def run(self):
        """Run method that performs all the real work"""

        # Create the dialog with elements (after translation) and keep reference
        # Only create GUI ONCE in callback, so that it will only load when the plugin is started
        if self.first_start == True:
            self.first_start = False
            self.dlg = HarmonyQGISDialog()

        # get stored settings
        settings = QgsSettings()

        # Fetch the currently loaded layers
        layers = QgsProject.instance().layerTreeRoot().children()
        layerNames = [layer.name() for layer in layers]

        # Clear the contents of the comboBox from previous runs
        self.dlg.comboBox.clear()
        # Populate the comboBox with names of all the loaded layers
        self.dlg.comboBox.addItems(layerNames)

        # use the previous layer as the default if it is in the existing layers
        # layerName = settings.value("harmony_qgis/layer")
        # if layerName and layerName in layerNames:
        #     self.dlg.comboBox.setCurrentIndex(layerNames.index(layerName))
        layer = self.iface.activeLayer()
        if layer:
            self.dlg.comboBox.setCurrentIndex(layerNames.index(layer.name()))

        # fill the harmnoy url input with the saved setting if available
        harmonyUrl = settings.value("harmony_qgis/harmony_url")
        if harmonyUrl:
            self.dlg.harmonyUrlLineEdit.setText(harmonyUrl)

        collectionId = settings.value("harmony_qgis/collection_id")
        if collectionId:
            self.dlg.collectionField.setText(collectionId)

        version = settings.value("harmony_qgis/version") or "1.0.0"
        self.dlg.versionField.setText(version)

        variable = settings.value("harmony_qgis/variable")
        if variable:
            self.dlg.variableField.setText(variable)

        # clear the table
        self.dlg.tableWidget.setRowCount(0)

        # set the table header
        self.dlg.tableWidget.setHorizontalHeaderLabels('Parameter;Value'.split(';'))

        # add a parameter/value when the 'Add' button is clicked
        self.dlg.addButton.clicked.connect(self.addSearchParameter)

        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:

            collectionId = str(self.dlg.collectionField.text())
            version = str(self.dlg.versionField.text())
            variable = str(self.dlg.variableField.text())

            layerName = str(self.dlg.comboBox.currentText())
            # TODO handle the case where there is more than one layer by this name
            layer = QgsProject.instance().mapLayersByName(layerName)[0]
            opts = QgsVectorFileWriter.SaveVectorOptions()
            opts.driverName = 'GeoJson'
            tempFile = '/tmp/qgis.json'
            QgsVectorFileWriter.writeAsVectorFormatV2(layer, tempFile, QgsCoordinateTransformContext(), opts)

            harmonyUrl = self.dlg.harmonyUrlLineEdit.text()
            path = collectionId + "/" + "ogc-api-coverages/" + version + "/collections/" + variable + "/coverage/rangeset"
            url = harmonyUrl + "/" + path
            print(url)

            tempFileHandle = open(tempFile, 'r')
            contents = tempFileHandle.read()
            tempFileHandle.close()
            geoJson = rewind(contents)
            tempFileHandle = open(tempFile, 'w')
            tempFileHandle.write(geoJson)
            tempFileHandle.close()
            tempFileHandle = open(tempFile, 'rb')

            multipart_form_data = {
                'shapefile': (layerName + '.geojson', tempFileHandle, 'application/geo+json')
            }

            rowCount = self.dlg.tableWidget.rowCount()
            for row in range(rowCount):
                parameter = self.dlg.tableWidget.item(row, 0).text()
                value = self.dlg.tableWidget.item(row, 1).text()
                multipart_form_data[parameter] = (None, value)

            resp = requests.post(url, files=multipart_form_data, stream=True)
            tempFileHandle.close()
            # print(resp)
            # print(resp.text)
            with open('/tmp/harmony_output_image.tif', 'wb') as fd:
                for chunk in resp.iter_content(chunk_size=128):
                    fd.write(chunk)

            os.remove(tempFile)

            self.iface.addRasterLayer('/tmp/harmony_output_image.tif', layerName + '-' + variable)
            # QgsRasterLayer('/tmp/harmony_output_image.tif', layerName)

            # save settings
            if collectionId != "":
                settings.setValue("harmony_qgis/collection_id", collectionId)
            if version != "":
                settings.setValue("harmony_qgis/version", version)
            if variable != "":
                settings.setValue("harmony_qgis/variable", variable)
            if harmonyUrl != "":
                settings.setValue("harmony_qgis/harmony_url", harmonyUrl)
            settings.setValue("harmony_qgis/layer", layerName)
Esempio n. 13
0
    def test_nested_groups(self):
        """
        Test logic relating to nested groups with group layers
        """
        p = QgsProject()
        layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory")
        p.addMapLayer(layer, False)
        layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2",
                                "memory")
        p.addMapLayer(layer2, False)
        layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3",
                                "memory")
        p.addMapLayer(layer3, False)
        layer4 = QgsVectorLayer("Point?field=fldtxt:string", "layer4",
                                "memory")
        p.addMapLayer(layer4, False)

        group_node = p.layerTreeRoot().addGroup('my group')
        group_node.addLayer(layer)
        group_node.addLayer(layer2)

        child_group = group_node.addGroup('child')
        layer3_node = child_group.addLayer(layer3)

        grandchild_group = child_group.addGroup('grandchild')
        layer4_node = grandchild_group.addLayer(layer4)

        self.assertEqual(p.layerTreeRoot().layerOrder(),
                         [layer, layer2, layer3, layer4])
        self.assertEqual(p.layerTreeRoot().checkedLayers(),
                         [layer, layer2, layer3, layer4])

        spy = QSignalSpy(p.layerTreeRoot().layerOrderChanged)

        options = QgsGroupLayer.LayerOptions(QgsCoordinateTransformContext())
        group_layer = group_node.convertToGroupLayer(options)
        p.addMapLayer(group_layer, False)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [layer4, layer3, layer2, layer])
        spy_count = len(spy)
        self.assertEqual(spy_count, 1)

        grandchild_group_layer = grandchild_group.convertToGroupLayer(options)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [grandchild_group_layer, layer3, layer2, layer])
        self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        layer4_node.setItemVisibilityChecked(False)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [grandchild_group_layer, layer3, layer2, layer])
        self.assertEqual(grandchild_group_layer.childLayers(), [])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        layer4_node.setItemVisibilityChecked(True)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [grandchild_group_layer, layer3, layer2, layer])
        self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        grandchild_group.setItemVisibilityChecked(False)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(), [layer3, layer2, layer])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        grandchild_group.setItemVisibilityChecked(True)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [grandchild_group_layer, layer3, layer2, layer])
        self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        child_group_layer = child_group.convertToGroupLayer(options)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [child_group_layer, layer2, layer])
        self.assertEqual(child_group_layer.childLayers(),
                         [grandchild_group_layer, layer3])
        self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        layer4_node.setItemVisibilityChecked(False)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [child_group_layer, layer2, layer])
        self.assertEqual(child_group_layer.childLayers(),
                         [grandchild_group_layer, layer3])
        self.assertEqual(grandchild_group_layer.childLayers(), [])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        layer4_node.setItemVisibilityChecked(True)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [child_group_layer, layer2, layer])
        self.assertEqual(child_group_layer.childLayers(),
                         [grandchild_group_layer, layer3])
        self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        grandchild_group.setItemVisibilityChecked(False)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [child_group_layer, layer2, layer])
        self.assertEqual(child_group_layer.childLayers(), [layer3])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        grandchild_group.setItemVisibilityChecked(True)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [child_group_layer, layer2, layer])
        self.assertEqual(child_group_layer.childLayers(),
                         [grandchild_group_layer, layer3])
        self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        layer3_node.setItemVisibilityChecked(False)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [child_group_layer, layer2, layer])
        self.assertEqual(child_group_layer.childLayers(),
                         [grandchild_group_layer])
        self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        layer3_node.setItemVisibilityChecked(True)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [child_group_layer, layer2, layer])
        self.assertEqual(child_group_layer.childLayers(),
                         [grandchild_group_layer, layer3])
        self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        grandchild_group.setGroupLayer(None)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [child_group_layer, layer2, layer])
        self.assertEqual(child_group_layer.childLayers(), [layer4, layer3])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        child_group.setGroupLayer(None)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [layer4, layer3, layer2, layer])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        group_node.setGroupLayer(None)
        self.assertEqual(p.layerTreeRoot().layerOrder(),
                         [layer, layer2, layer3, layer4])
        self.assertEqual(p.layerTreeRoot().checkedLayers(),
                         [layer, layer2, layer3, layer4])
        self.assertGreater(len(spy), spy_count)
    def processAlgorithm(self, parameters, context, model_feedback):
        # Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the
        # overall progress through the model
        feedback = QgsProcessingMultiStepFeedback(25, model_feedback)
        results = {}
        outputs = {}

        nlcd_rast_output = self.parameterAsBool(parameters,
                                                "OutputNLCDLandCoverRaster",
                                                context)
        nlcd_vect_output = self.parameterAsBool(parameters,
                                                "OutputNLCDLandCoverVector",
                                                context)
        nlcd_rast_imp_output = self.parameterAsBool(
            parameters, "OutputNLCDImperviousRaster", context)
        soil_output = self.parameterAsBool(parameters, "OutputSoilLayer",
                                           context)
        curve_number_output = self.parameterAsBool(parameters,
                                                   "OutputCurveNumberLayer",
                                                   context)

        # Assiging Default CN_Lookup Table
        if parameters["cnlookup"] == None:
            csv_uri = ("file:///" + os.path.join(cmd_folder, "CN_Lookup.csv") +
                       "?delimiter=,")
            csv = QgsVectorLayer(csv_uri, "CN_Lookup.csv", "delimitedtext")
            parameters["cnlookup"] = csv

        area_layer = self.parameterAsVectorLayer(parameters, "areaboundary",
                                                 context)

        EPSGCode = area_layer.crs().authid()
        origEPSGCode = EPSGCode  # preserve orignal EPSGCode to project back to it
        # feedback.pushInfo(str(EPSGCode))

        if check_crs_acceptable(EPSGCode):
            pass
        else:
            # Reproject layer to EPSG:5070
            alg_params = {
                "INPUT": parameters["areaboundary"],
                "OPERATION": "",
                "TARGET_CRS": QgsCoordinateReferenceSystem("EPSG:5070"),
                "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT,
            }
            outputs["ReprojectLayer5070"] = processing.run(
                "native:reprojectlayer",
                alg_params,
                context=context,
                feedback=feedback,
                is_child_algorithm=True,
            )
            area_layer = context.takeResultLayer(
                outputs["ReprojectLayer5070"]["OUTPUT"])

            EPSGCode = area_layer.crs().authid()

        # Check if area of the extent is less than 100,000 Acres
        d = QgsDistanceArea()
        tr_cont = QgsCoordinateTransformContext()
        d.setSourceCrs(area_layer.crs(), tr_cont)
        # d.setEllipsoid(area_layer.crs().ellipsoidAcronym())
        extent_area = d.measureArea(QgsGeometry().fromRect(
            area_layer.extent()))
        area_acres = d.convertAreaMeasurement(extent_area,
                                              QgsUnitTypes.AreaAcres)

        if area_acres > 500000:
            feedback.reportError(
                f"Area Boundary layer extent area should be less than 500,000 acres.\nArea Boundary layer extent area is {round(area_acres,4):,} acres.\n\nExecution Failed",
                True,
            )
            return results
        elif area_acres > 100000:
            feedback.reportError(
                f"Your Area Boundary layer extent area is {round(area_acres,4):,} acres. The recommended extent area is 100,000 acres or less. If the Algorithm fails, rerun with a smaller input layer.\n",
                False,
            )
        else:
            feedback.pushInfo(
                f"Area Boundary layer extent area is {round(area_acres,4):,} acres\n"
            )

        # Get extent of the area boundary layer
        xmin = area_layer.extent().xMinimum()
        ymin = area_layer.extent().yMinimum()
        xmax = area_layer.extent().xMaximum()
        ymax = area_layer.extent().yMaximum()

        BBOX_width = (xmax - xmin) / 30
        BBOX_height = (ymax - ymin) / 30
        BBOX_width_int = round(BBOX_width)
        BBOX_height_int = round(BBOX_height)

        # NLCD Impervious Raster
        if nlcd_rast_imp_output == True:
            request_URL = f"https://www.mrlc.gov/geoserver/mrlc_display/NLCD_2016_Impervious_L48/ows?version=1.3.0&service=WMS&layers=NLCD_2016_Impervious_L48&styles&crs={str(EPSGCode)}&format=image/geotiff&request=GetMap&width={str(BBOX_width_int)}&height={str(BBOX_height_int)}&BBOX={str(xmin)},{str(ymin)},{str(xmax)},{str(ymax)}&"

            # Download NLCD Impervious Raster
            try:
                ping_URL = "https://www.mrlc.gov/geoserver/mrlc_display/NLCD_2016_Impervious_L48/ows"
                r = requests.head(ping_URL, verify=False)
                r.raise_for_status()

                alg_params = {
                    "URL": request_URL,
                    "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT,
                }
                outputs["DownloadNlcdImp"] = processing.run(
                    "native:filedownloader",
                    alg_params,
                    context=context,
                    feedback=feedback,
                    is_child_algorithm=True,
                )
            except (QgsProcessingException,
                    requests.exceptions.HTTPError) as e:
                feedback.reportError(
                    f"Error: {str(e)}\n\nError requesting land use data from 'www.mrlc.gov'. Most probably because either their server is down or there is a certification issue.\nThis should be temporary. Try again later.\n",
                    True,
                )
                return results

            feedback.setCurrentStep(1)
            if feedback.isCanceled():
                return {}

            # reproject to original crs
            # Warp (reproject)
            if EPSGCode != origEPSGCode:
                alg_params = {
                    "DATA_TYPE": 0,
                    "EXTRA": "",
                    "INPUT": outputs["DownloadNlcdImp"]["OUTPUT"],
                    "MULTITHREADING": False,
                    "NODATA": None,
                    "OPTIONS": "",
                    "RESAMPLING": 0,
                    "SOURCE_CRS": None,
                    "TARGET_CRS":
                    QgsCoordinateReferenceSystem(str(origEPSGCode)),
                    "TARGET_EXTENT": None,
                    "TARGET_EXTENT_CRS": None,
                    "TARGET_RESOLUTION": None,
                    "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT,
                }
                outputs["DownloadNlcdImp"] = processing.run(
                    "gdal:warpreproject",
                    alg_params,
                    context=context,
                    feedback=feedback,
                    is_child_algorithm=True,
                )

            # Set layer style
            alg_params = {
                "INPUT": outputs["DownloadNlcdImp"]["OUTPUT"],
                "STYLE": os.path.join(cmd_folder, "NLCD_Raster_Imp.qml"),
            }

            try:  # for QGIS Version later than 3.12
                outputs["SetLayerStyle"] = processing.run(
                    "native:setlayerstyle",
                    alg_params,
                    context=context,
                    feedback=feedback,
                    is_child_algorithm=True,
                )
            except:  # for QGIS Version older than 3.12
                outputs["SetStyleForRasterLayer"] = processing.run(
                    "qgis:setstyleforrasterlayer",
                    alg_params,
                    context=context,
                    feedback=feedback,
                    is_child_algorithm=True,
                )

            feedback.setCurrentStep(2)
            if feedback.isCanceled():
                return {}

        # NLCD Land Cover Data
        if (curve_number_output == True or nlcd_vect_output == True
                or nlcd_rast_output == True):
            request_URL = f"https://www.mrlc.gov/geoserver/mrlc_display/NLCD_2016_Land_Cover_L48/ows?version=1.3.0&service=WMS&layers=NLCD_2016_Land_Cover_L48&styles&crs={str(EPSGCode)}&format=image/geotiff&request=GetMap&width={str(BBOX_width_int)}&height={str(BBOX_height_int)}&BBOX={str(xmin)},{str(ymin)},{str(xmax)},{str(ymax)}&"

            # Download NLCD
            try:
                ping_URL = "https://www.mrlc.gov/geoserver/mrlc_display/NLCD_2016_Land_Cover_L48/ows"
                r = requests.head(ping_URL, verify=False)
                r.raise_for_status()

                alg_params = {
                    "URL": request_URL,
                    "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT,
                }
                outputs["DownloadNlcd"] = processing.run(
                    "native:filedownloader",
                    alg_params,
                    context=context,
                    feedback=feedback,
                    is_child_algorithm=True,
                )
            except (QgsProcessingException,
                    requests.exceptions.HTTPError) as e:
                feedback.reportError(
                    f"Error: {str(e)}\n\nError requesting land use data from 'www.mrlc.gov'. Most probably because either their server is down or there is a certification issue.\nThis should be temporary. Try again later.\n",
                    True,
                )
                return results

            feedback.setCurrentStep(3)
            if feedback.isCanceled():
                return {}

            # reproject to original crs
            # Warp (reproject)
            if EPSGCode != origEPSGCode:
                alg_params = {
                    "DATA_TYPE": 0,
                    "EXTRA": "",
                    "INPUT": outputs["DownloadNlcd"]["OUTPUT"],
                    "MULTITHREADING": False,
                    "NODATA": None,
                    "OPTIONS": "",
                    "RESAMPLING": 0,
                    "SOURCE_CRS": None,
                    "TARGET_CRS":
                    QgsCoordinateReferenceSystem(str(origEPSGCode)),
                    "TARGET_EXTENT": None,
                    "TARGET_EXTENT_CRS": None,
                    "TARGET_RESOLUTION": None,
                    "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT,
                }
                outputs["DownloadNlcd"] = processing.run(
                    "gdal:warpreproject",
                    alg_params,
                    context=context,
                    feedback=feedback,
                    is_child_algorithm=True,
                )

            # Reclassify by table
            alg_params = {
                "DATA_TYPE":
                5,
                "INPUT_RASTER":
                outputs["DownloadNlcd"]["OUTPUT"],
                "NODATA_FOR_MISSING":
                False,
                "NO_DATA":
                -9999,
                "RANGE_BOUNDARIES":
                0,
                "RASTER_BAND":
                1,
                "TABLE":
                QgsExpression(
                    "'0,1,11,1,2,12,2,3,21,3,4,22,4,5,23,5,6,24,6,7,31,7,8,32,8,9,41,9,10,42,10,11,43,11,12,51,12,13,52,13,14,71,14,15,72,15,16,73,16,17,74,17,18,81,18,19,82,19,20,90,20,21,95'"
                ).evaluate(),
                "OUTPUT":
                QgsProcessing.TEMPORARY_OUTPUT,
            }
            outputs["ReclassifyByTable"] = processing.run(
                "native:reclassifybytable",
                alg_params,
                context=context,
                feedback=feedback,
                is_child_algorithm=True,
            )

            feedback.setCurrentStep(4)
            if feedback.isCanceled():
                return {}

            # Set layer style
            alg_params = {
                "INPUT": outputs["ReclassifyByTable"]["OUTPUT"],
                "STYLE": os.path.join(cmd_folder, "NLCD_Raster.qml"),
            }

            try:  # for QGIS Version later than 3.12
                outputs["SetLayerStyle"] = processing.run(
                    "native:setlayerstyle",
                    alg_params,
                    context=context,
                    feedback=feedback,
                    is_child_algorithm=True,
                )
            except:  # for QGIS Version older than 3.12
                outputs["SetStyleForRasterLayer"] = processing.run(
                    "qgis:setstyleforrasterlayer",
                    alg_params,
                    context=context,
                    feedback=feedback,
                    is_child_algorithm=True,
                )

            feedback.setCurrentStep(5)
            if feedback.isCanceled():
                return {}

            if curve_number_output == True or nlcd_vect_output == True:
                # Polygonize (raster to vector)
                alg_params = {
                    "BAND": 1,
                    "EIGHT_CONNECTEDNESS": False,
                    "EXTRA": "",
                    "FIELD": "VALUE",
                    "INPUT": outputs["ReclassifyByTable"]["OUTPUT"],
                    "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT,
                }
                outputs["PolygonizeRasterToVector"] = processing.run(
                    "gdal:polygonize",
                    alg_params,
                    context=context,
                    feedback=feedback,
                    is_child_algorithm=True,
                )

                feedback.setCurrentStep(6)
                if feedback.isCanceled():
                    return {}

                # Fix geometries
                alg_params = {
                    "INPUT": outputs["PolygonizeRasterToVector"]["OUTPUT"],
                    "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT,
                }
                outputs["FixGeometries"] = processing.run(
                    "native:fixgeometries",
                    alg_params,
                    context=context,
                    feedback=feedback,
                    is_child_algorithm=True,
                )

                feedback.setCurrentStep(7)
                if feedback.isCanceled():
                    return {}

                # Set layer style
                alg_params = {
                    "INPUT": outputs["FixGeometries"]["OUTPUT"],
                    "STYLE": os.path.join(cmd_folder, "NLCD_Vector.qml"),
                }
                try:  # for QGIS Version 3.12 and later
                    outputs["SetLayerStyle"] = processing.run(
                        "native:setlayerstyle",
                        alg_params,
                        context=context,
                        feedback=feedback,
                        is_child_algorithm=True,
                    )
                except:  # for QGIS Version older than 3.12
                    outputs["SetStyleForVectorLayer"] = processing.run(
                        "qgis:setstyleforvectorlayer",
                        alg_params,
                        context=context,
                        feedback=feedback,
                        is_child_algorithm=True,
                    )

                feedback.setCurrentStep(8)
                if feedback.isCanceled():
                    return {}

        # Soil Layer
        if soil_output == True or curve_number_output == True:

            # Reproject layer
            alg_params = {
                "INPUT": parameters["areaboundary"],
                "OPERATION": "",
                "TARGET_CRS": QgsCoordinateReferenceSystem("EPSG:4326"),
                "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT,
            }
            outputs["ReprojectLayer4326"] = processing.run(
                "native:reprojectlayer",
                alg_params,
                context=context,
                feedback=feedback,
                is_child_algorithm=True,
            )

            feedback.setCurrentStep(9)
            if feedback.isCanceled():
                return {}

            # Get Area Boundary layer extent in EPSG:4326
            area_layer_reprojected = context.takeResultLayer(
                outputs["ReprojectLayer4326"]["OUTPUT"])

            # Download Soil

            try:  # request using post rest

                # create vector layer structure to store data
                feedback.pushInfo("Creating POST request...")
                uri = "Polygon?crs=epsg:4326"
                soil_layer = QgsVectorLayer(uri, "soil layer", "memory")
                provider = soil_layer.dataProvider()
                attributes = []
                attr_dict = [
                    {
                        "name": "musym",
                        "type": "str"
                    },
                    {
                        "name": "muname",
                        "type": "str"
                    },
                    {
                        "name": "mustatus",
                        "type": "str"
                    },
                    {
                        "name": "slopegraddcp",
                        "type": "str"
                    },
                    {
                        "name": "slopegradwta",
                        "type": "str"
                    },
                    {
                        "name": "brockdepmin",
                        "type": "str"
                    },
                    {
                        "name": "wtdepannmin",
                        "type": "str"
                    },
                    {
                        "name": "wtdepaprjunmin",
                        "type": "str"
                    },
                    {
                        "name": "flodfreqdcd",
                        "type": "str"
                    },
                    {
                        "name": "flodfreqmax",
                        "type": "str"
                    },
                    {
                        "name": "pondfreqprs",
                        "type": "str"
                    },
                    {
                        "name": "aws025wta",
                        "type": "str"
                    },
                    {
                        "name": "aws050wta",
                        "type": "str"
                    },
                    {
                        "name": "aws0100wta",
                        "type": "str"
                    },
                    {
                        "name": "aws0150wta",
                        "type": "str"
                    },
                    {
                        "name": "drclassdcd",
                        "type": "str"
                    },
                    {
                        "name": "drclasswettest",
                        "type": "str"
                    },
                    {
                        "name": "hydgrpdcd",
                        "type": "str"
                    },
                    {
                        "name": "iccdcd",
                        "type": "str"
                    },
                    {
                        "name": "iccdcdpct",
                        "type": "str"
                    },
                    {
                        "name": "niccdcd",
                        "type": "str"
                    },
                    {
                        "name": "niccdcdpct",
                        "type": "str"
                    },
                    {
                        "name": "engdwobdcd",
                        "type": "str"
                    },
                    {
                        "name": "engdwbdcd",
                        "type": "str"
                    },
                    {
                        "name": "engdwbll",
                        "type": "str"
                    },
                    {
                        "name": "engdwbml",
                        "type": "str"
                    },
                    {
                        "name": "engstafdcd",
                        "type": "str"
                    },
                    {
                        "name": "engstafll",
                        "type": "str"
                    },
                    {
                        "name": "engstafml",
                        "type": "str"
                    },
                    {
                        "name": "engsldcd",
                        "type": "str"
                    },
                    {
                        "name": "engsldcp",
                        "type": "str"
                    },
                    {
                        "name": "englrsdcd",
                        "type": "str"
                    },
                    {
                        "name": "engcmssdcd",
                        "type": "str"
                    },
                    {
                        "name": "engcmssmp",
                        "type": "str"
                    },
                    {
                        "name": "urbrecptdcd",
                        "type": "str"
                    },
                    {
                        "name": "urbrecptwta",
                        "type": "str"
                    },
                    {
                        "name": "forpehrtdcp",
                        "type": "str"
                    },
                    {
                        "name": "hydclprs",
                        "type": "str"
                    },
                    {
                        "name": "awmmfpwwta",
                        "type": "str"
                    },
                    {
                        "name": "mukey",
                        "type": "str"
                    },
                    {
                        "name": "mupolygonkey",
                        "type": "str"
                    },
                    {
                        "name": "areasymbol",
                        "type": "str"
                    },
                    {
                        "name": "nationalmusym",
                        "type": "str"
                    },
                ]

                # initialize fields
                for field in attr_dict:
                    attributes.append(QgsField(field["name"], QVariant.String))
                    provider.addAttributes(attributes)
                    soil_layer.updateFields()

                # get area layer extent polygon as WKT in 4326
                aoi_reproj_wkt = area_layer_reprojected.extent().asWktPolygon()

                # send post request
                body = {
                    "format":
                    "JSON",
                    "query":
                    f"select Ma.*, M.mupolygonkey, M.areasymbol, M.nationalmusym, M.mupolygongeo from mupolygon M, muaggatt Ma where M.mupolygonkey in (select * from SDA_Get_Mupolygonkey_from_intersection_with_WktWgs84('{aoi_reproj_wkt.lower()}')) and M.mukey=Ma.mukey",
                }
                url = "https://sdmdataaccess.sc.egov.usda.gov/TABULAR/post.rest"
                soil_response = requests.post(url, json=body).json()

                feedback.setCurrentStep(10)
                if feedback.isCanceled():
                    return {}

                for row in soil_response["Table"]:
                    # None attribute for empty data
                    row = [None if not attr else attr for attr in row]
                    feat = QgsFeature(soil_layer.fields())
                    # populate data
                    for index, col in enumerate(row):
                        if index != len(attr_dict):
                            feat.setAttribute(attr_dict[index]["name"], col)
                        else:
                            feat.setGeometry(QgsGeometry.fromWkt(col))
                    provider.addFeatures([feat])

                feedback.setCurrentStep(11)
                if feedback.isCanceled():
                    return {}

            except:  # try wfs request
                feedback.reportError(
                    "Error getting soil data through post request. Your input layer maybe too large. Trying WFS download now.\nIf the Algorithm get stuck during download. Terminate the Algorithm and rerun with a smaller input layer.",
                    False,
                )
                xmin_reprojected = area_layer_reprojected.extent().xMinimum()
                ymin_reprojected = area_layer_reprojected.extent().yMinimum()
                xmax_reprojected = area_layer_reprojected.extent().xMaximum()
                ymax_reprojected = area_layer_reprojected.extent().yMaximum()

                request_URL_soil = f"https://sdmdataaccess.sc.egov.usda.gov/Spatial/SDMWGS84GEOGRAPHIC.wfs?SERVICE=WFS&VERSION=1.1.0&REQUEST=GetFeature&TYPENAME=mapunitpolyextended&SRSNAME=EPSG:4326&BBOX={str(xmin_reprojected)},{str(ymin_reprojected)},{str(xmax_reprojected)},{str(ymax_reprojected)}"

                alg_params = {
                    "URL": request_URL_soil,
                    "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT,
                }
                outputs["DownloadSoil"] = processing.run(
                    "native:filedownloader",
                    alg_params,
                    context=context,
                    feedback=feedback,
                    is_child_algorithm=True,
                )

                feedback.setCurrentStep(12)
                if feedback.isCanceled():
                    return {}

                # Swap X and Y coordinates
                alg_params = {
                    "INPUT": outputs["DownloadSoil"]["OUTPUT"],
                    "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT,
                }
                outputs["SwapXAndYCoordinates"] = processing.run(
                    "native:swapxy",
                    alg_params,
                    context=context,
                    feedback=feedback,
                    is_child_algorithm=True,
                )

                feedback.setCurrentStep(13)
                if feedback.isCanceled():
                    return {}

                soil_layer = outputs["SwapXAndYCoordinates"]["OUTPUT"]

            # Fix soil layer geometries
            alg_params = {
                "INPUT": soil_layer,
                "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT
            }
            outputs["FixGeometries2"] = processing.run(
                "native:fixgeometries",
                alg_params,
                context=context,
                feedback=feedback,
                is_child_algorithm=True,
            )

            feedback.setCurrentStep(14)
            if feedback.isCanceled():
                return {}

            # Clip Soil Layer
            alg_params = {
                "INPUT": outputs["FixGeometries2"]["OUTPUT"],
                "OVERLAY": parameters["areaboundary"],
                "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT,
            }
            outputs["Clip"] = processing.run(
                "native:clip",
                alg_params,
                context=context,
                feedback=feedback,
                is_child_algorithm=True,
            )

            feedback.setCurrentStep(15)
            if feedback.isCanceled():
                return {}

            # Reproject Soil
            alg_params = {
                "INPUT": outputs["Clip"]["OUTPUT"],
                "OPERATION": "",
                "TARGET_CRS": QgsCoordinateReferenceSystem(origEPSGCode),
                "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT,
            }
            outputs["ReprojectSoil"] = processing.run(
                "native:reprojectlayer",
                alg_params,
                context=context,
                feedback=feedback,
                is_child_algorithm=True,
            )

            feedback.setCurrentStep(16)
            if feedback.isCanceled():
                return {}

            # Fix soil layer geometries second time
            alg_params = {
                "INPUT": outputs["ReprojectSoil"]["OUTPUT"],
                "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT,
            }
            outputs["FixGeometries3"] = processing.run(
                "native:fixgeometries",
                alg_params,
                context=context,
                feedback=feedback,
                is_child_algorithm=True,
            )

            feedback.setCurrentStep(17)
            if feedback.isCanceled():
                return {}

            # Set layer style
            alg_params = {
                "INPUT": outputs["FixGeometries3"]["OUTPUT"],
                "STYLE": os.path.join(cmd_folder, "Soil_Layer.qml"),
            }
            try:  # for QGIS Version 3.12 and later
                outputs["SetLayerStyle"] = processing.run(
                    "native:setlayerstyle",
                    alg_params,
                    context=context,
                    feedback=feedback,
                    is_child_algorithm=True,
                )
            except:  # for QGIS Version older than 3.12
                outputs["SetStyleForVectorLayer"] = processing.run(
                    "qgis:setstyleforvectorlayer",
                    alg_params,
                    context=context,
                    feedback=feedback,
                    is_child_algorithm=True,
                )

            feedback.setCurrentStep(18)
            if feedback.isCanceled():
                return {}

        # Curve Number Calculations
        if curve_number_output == True:

            feedback.pushInfo(
                "Generating Curve Number Layer. This may take a while. Do not cancel."
            )
            # Intersection
            alg_params = {
                "INPUT": outputs["FixGeometries3"]["OUTPUT"],
                "INPUT_FIELDS": ["MUSYM", "HYDGRPDCD", "MUNAME"],
                "OVERLAY": outputs["FixGeometries"]["OUTPUT"],
                "OVERLAY_FIELDS": ["VALUE"],
                "OVERLAY_FIELDS_PREFIX": "",
                "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT,
            }
            outputs["Intersection"] = processing.run(
                "native:intersection",
                alg_params,
                context=context,
                feedback=feedback,
                is_child_algorithm=True,
            )

            feedback.setCurrentStep(19)
            if feedback.isCanceled():
                return {}

            # Create GDCodeTemp
            alg_params = {
                "FIELD_LENGTH": 5,
                "FIELD_NAME": "GDCodeTemp",
                "FIELD_PRECISION": 3,
                "FIELD_TYPE": 2,
                "FORMULA":
                'IF ("HYDGRPDCD" IS NOT NULL, "Value" || "HYDGRPDCD", IF (("MUSYM" = \'W\' OR lower("MUSYM") = \'water\' OR lower("MUNAME") = \'water\' OR "MUNAME" = \'W\'), 11, "VALUE"))',
                "INPUT": outputs["Intersection"]["OUTPUT"],
                "NEW_FIELD": True,
                "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT,
            }
            outputs["CreateGdcodetemp"] = processing.run(
                "qgis:fieldcalculator",
                alg_params,
                context=context,
                feedback=feedback,
                is_child_algorithm=True,
            )

            feedback.setCurrentStep(20)
            if feedback.isCanceled():
                return {}

            # Create GDCode
            alg_params = {
                "FIELD_LENGTH": 5,
                "FIELD_NAME": "GDCode",
                "FIELD_PRECISION": 3,
                "FIELD_TYPE": 2,
                "FORMULA":
                "if( var('drainedsoilsleaveuncheckedifnotsure') = True,replace(\"GDCodeTemp\", '/D', ''),replace(\"GDCodeTemp\", map('A/', '', 'B/', '', 'C/', '')))",
                "INPUT": outputs["CreateGdcodetemp"]["OUTPUT"],
                "NEW_FIELD": True,
                "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT,
            }
            outputs["CreateGdcode"] = processing.run(
                "qgis:fieldcalculator",
                alg_params,
                context=context,
                feedback=feedback,
                is_child_algorithm=True,
            )

            feedback.setCurrentStep(21)
            if feedback.isCanceled():
                return {}

            # Create NLCD_LU
            alg_params = {
                "FIELD_LENGTH": 2,
                "FIELD_NAME": "NLCD_LU",
                "FIELD_PRECISION": 3,
                "FIELD_TYPE": 1,
                "FORMULA": '"Value"',
                "INPUT": outputs["CreateGdcode"]["OUTPUT"],
                "NEW_FIELD": True,
                "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT,
            }
            outputs["CreateNlcd_lu"] = processing.run(
                "qgis:fieldcalculator",
                alg_params,
                context=context,
                feedback=feedback,
                is_child_algorithm=True,
            )

            feedback.setCurrentStep(22)
            if feedback.isCanceled():
                return {}

            # Join with CNLookup
            alg_params = {
                "DISCARD_NONMATCHING": False,
                "FIELD": "GDCode",
                "FIELDS_TO_COPY": ["CN_Join"],
                "FIELD_2": "GDCode",
                "INPUT": outputs["CreateNlcd_lu"]["OUTPUT"],
                "INPUT_2": parameters["cnlookup"],
                "METHOD": 1,
                "PREFIX": "",
                "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT,
            }
            outputs["JoinWithCnlookup"] = processing.run(
                "native:joinattributestable",
                alg_params,
                context=context,
                feedback=feedback,
                is_child_algorithm=True,
            )

            feedback.setCurrentStep(23)
            if feedback.isCanceled():
                return {}

            # Create Integer CN
            alg_params = {
                "FIELD_LENGTH": 3,
                "FIELD_NAME": "CN",
                "FIELD_PRECISION": 0,
                "FIELD_TYPE": 1,
                "FORMULA": "CN_Join  * 1",
                "INPUT": outputs["JoinWithCnlookup"]["OUTPUT"],
                "NEW_FIELD": True,
                "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT,
            }
            outputs["CreateIntegerCn"] = processing.run(
                "qgis:fieldcalculator",
                alg_params,
                context=context,
                feedback=feedback,
                is_child_algorithm=True,
            )

            feedback.setCurrentStep(24)
            if feedback.isCanceled():
                return {}

            # Drop field(s)
            alg_params = {
                "COLUMN": ["VALUE", "GDCodeTemp", "CN_Join"],
                "INPUT": outputs["CreateIntegerCn"]["OUTPUT"],
                "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT,
            }
            outputs["DropFields"] = processing.run(
                "qgis:deletecolumn",
                alg_params,
                context=context,
                feedback=feedback,
                is_child_algorithm=True,
            )

            feedback.setCurrentStep(25)
            if feedback.isCanceled():
                return {}

            # Set layer style
            alg_params = {
                "INPUT": outputs["DropFields"]["OUTPUT"],
                "STYLE": os.path.join(cmd_folder, "CN_Grid.qml"),
            }
            try:  # for QGIS Version 3.12 and later
                outputs["SetLayerStyle"] = processing.run(
                    "native:setlayerstyle",
                    alg_params,
                    context=context,
                    feedback=feedback,
                    is_child_algorithm=True,
                )
            except:  # for QGIS Version older than 3.12
                outputs["SetStyleForVectorLayer"] = processing.run(
                    "qgis:setstyleforvectorlayer",
                    alg_params,
                    context=context,
                    feedback=feedback,
                    is_child_algorithm=True,
                )

        if nlcd_rast_output:
            # Load NLCD Raster into project
            alg_params = {
                "INPUT": outputs["ReclassifyByTable"]["OUTPUT"],
                "NAME": "NLCD Land Cover Raster",
            }
            outputs["LoadLayerIntoProject1"] = processing.run(
                "native:loadlayer",
                alg_params,
                context=context,
                feedback=feedback,
                is_child_algorithm=True,
            )

        if nlcd_vect_output:
            # Load NLCD Vector Layer into project
            alg_params = {
                "INPUT": outputs["FixGeometries"]["OUTPUT"],
                "NAME": "NLCD Land Cover Vector",
            }
            outputs["LoadLayerIntoProject2"] = processing.run(
                "native:loadlayer",
                alg_params,
                context=context,
                feedback=feedback,
                is_child_algorithm=True,
            )

        if nlcd_rast_imp_output:
            # Load NLCD Impervious Raster into project
            alg_params = {
                "INPUT": outputs["DownloadNlcdImp"]["OUTPUT"],
                "NAME": "NLCD Impervious Raster",
            }
            outputs["LoadLayerIntoProject3"] = processing.run(
                "native:loadlayer",
                alg_params,
                context=context,
                feedback=feedback,
                is_child_algorithm=True,
            )

        if soil_output:
            # Load Soil Layer into project
            alg_params = {
                "INPUT": outputs["FixGeometries3"]["OUTPUT"],
                "NAME": "SSURGO Soil Layer",
            }
            outputs["LoadLayerIntoProject4"] = processing.run(
                "native:loadlayer",
                alg_params,
                context=context,
                feedback=feedback,
                is_child_algorithm=True,
            )

        if curve_number_output:
            # Load Curve Number Layer into project
            alg_params = {
                "INPUT": outputs["DropFields"]["OUTPUT"],
                "NAME": "Curve Number Layer",
            }
            outputs["LoadLayerIntoProject5"] = processing.run(
                "native:loadlayer",
                alg_params,
                context=context,
                feedback=feedback,
                is_child_algorithm=True,
            )

        # log usage
        with open(os.path.join(cmd_folder, "usage_counter.log"), "r+") as f:
            counter = int(f.readline())
            f.seek(0)
            f.write(str(counter + 1))

        # check if counter is milestone
        if (counter + 1) % 25 == 0:
            appeal_file = NamedTemporaryFile("w", suffix=".html", delete=False)
            self.createHTML(appeal_file.name, counter + 1)
            results["Message"] = appeal_file.name

        return results
Esempio n. 15
0
    def convert_to_gpkg(self, target_path):
        """
        Convert a layer to geopackage in the target path and adjust its datasource. If
        a layer is already a geopackage, the dataset will merely be copied to the target
        path.

        :param layer: The layer to copy
        :param target_path: A path to a folder into which the data will be copied
        :param keep_existent: if True and target file already exists, keep it as it is
        """

        if not self.layer.type(
        ) == QgsMapLayer.VectorLayer or not self.layer.isValid():
            return

        file_path = self.filename
        suffix = ""
        uri_parts = self.layer.source().split("|", 1)
        if len(uri_parts) > 1:
            suffix = uri_parts[1]

        dest_file = ""
        new_source = ""
        # check if the source is a geopackage, and merely copy if it's the case
        if (os.path.isfile(file_path)
                and self.layer.dataProvider().storageType() == "GPKG"):
            source_path, file_name = os.path.split(file_path)
            dest_file = os.path.join(target_path, file_name)
            if not os.path.isfile(dest_file):
                shutil.copy(os.path.join(source_path, file_name), dest_file)

            if self.provider_metadata is not None:
                metadata = self.metadata
                metadata["path"] = dest_file
                new_source = self.provider_metadata.encodeUri(metadata)

            if new_source == "":
                new_source = os.path.join(target_path, file_name)
                if suffix != "":
                    new_source = "{}|{}".format(new_source, suffix)

        layer_subset_string = self.layer.subsetString()
        if new_source == "":
            pattern = re.compile("[\W_]+")  # NOQA
            cleaned_name = pattern.sub("", self.layer.name())
            dest_file = os.path.join(target_path,
                                     "{}.gpkg".format(cleaned_name))
            suffix = 0
            while os.path.isfile(dest_file):
                suffix += 1
                dest_file = os.path.join(
                    target_path, "{}_{}.gpkg".format(cleaned_name, suffix))

            # clone vector layer and strip it of filter, joins, and virtual fields
            source_layer = self.layer.clone()
            source_layer.setSubsetString("")
            source_layer_joins = source_layer.vectorJoins()
            for join in source_layer_joins:
                source_layer.removeJoin(join.joinLayerId())
            fields = source_layer.fields()
            virtual_field_count = 0
            for i in range(0, len(fields)):
                if fields.fieldOrigin(i) == QgsFields.OriginExpression:
                    source_layer.removeExpressionField(i - virtual_field_count)
                    virtual_field_count += 1

            options = QgsVectorFileWriter.SaveVectorOptions()
            options.fileEncoding = "UTF-8"
            options.driverName = "GPKG"
            (error,
             returned_dest_file) = QgsVectorFileWriter.writeAsVectorFormatV2(
                 source_layer, dest_file, QgsCoordinateTransformContext(),
                 options)
            if error != QgsVectorFileWriter.NoError:
                return
            if returned_dest_file:
                new_source = returned_dest_file
            else:
                new_source = dest_file

        self._change_data_source(new_source, "ogr")
        if layer_subset_string:
            self.layer.setSubsetString(layer_subset_string)

        return dest_file
Esempio n. 16
0
    def test_geocode(self):
        geocoder = QgsGoogleMapsGeocoder('my key')
        geocoder.setEndpoint(self.endpoint)

        with open(
                geocoder.requestUrl(
                    '20 green st, twaddlingham').toString().replace(
                        'file://', ''), 'wb') as f:
            f.write("""
        {
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "1600",
               "short_name" : "1600",
               "types" : [ "street_number" ]
            },
            {
               "long_name" : "Amphitheatre Pkwy",
               "short_name" : "Amphitheatre Pkwy",
               "types" : [ "route" ]
            },
            {
               "long_name" : "Mountain View",
               "short_name" : "Mountain View",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "Santa Clara County",
               "short_name" : "Santa Clara County",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "California",
               "short_name" : "CA",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "United States",
               "short_name" : "US",
               "types" : [ "country", "political" ]
            },
            {
               "long_name" : "94043",
               "short_name" : "94043",
               "types" : [ "postal_code" ]
            }
         ],
         "formatted_address" : "1600 Amphitheatre Parkway, Mountain View, CA 94043, USA",
         "geometry" : {
            "location" : {
               "lat" : 37.4224764,
               "lng" : -122.0842499
            },
            "location_type" : "ROOFTOP",
            "viewport" : {
               "northeast" : {
                  "lat" : 37.4238253802915,
                  "lng" : -122.0829009197085
               },
               "southwest" : {
                  "lat" : 37.4211274197085,
                  "lng" : -122.0855988802915
               }
            }
         },
         "place_id" : "ChIJ2eUgeAK6j4ARbn5u_wAGqWA",
         "plus_code": {
            "compound_code": "CWC8+W5 Mountain View, California, United States",
            "global_code": "849VCWC8+W5"
         },
         "types" : [ "street_address" ]
      }
   ],
   "status" : "OK"
}
        """.encode('UTF-8'))

        context = QgsGeocoderContext(QgsCoordinateTransformContext())
        results = geocoder.geocodeString('20 green st, twaddlingham', context)
        self.assertEqual(len(results), 1)

        self.assertEqual(
            results[0].identifier(),
            '1600 Amphitheatre Parkway, Mountain View, CA 94043, USA')
        self.assertEqual(results[0].geometry().asWkt(1), 'Point (-122.1 37.4)')
        self.assertEqual(
            results[0].additionalAttributes(), {
                'administrative_area_level_1': 'California',
                'administrative_area_level_2': 'Santa Clara County',
                'country': 'United States',
                'formatted_address':
                '1600 Amphitheatre Parkway, Mountain View, CA 94043, USA',
                'locality': 'Mountain View',
                'location_type': 'ROOFTOP',
                'place_id': 'ChIJ2eUgeAK6j4ARbn5u_wAGqWA',
                'postal_code': '94043',
                'route': 'Amphitheatre Pkwy',
                'street_number': '1600'
            })
Esempio n. 17
0
    def search(self):
        plots_found = []
        features_not_found = []

        fields = PLOTS_LAYER_DEFAULT_FIELDS + self.additional_output_fields

        self.layer_found.startEditing()
        self.layer_found.dataProvider().addAttributes(fields)

        self.layer_not_found.startEditing()
        self.layer_not_found.dataProvider().addAttributes([
            QgsField("tresc_bledu", QVariant.String),
        ])

        features = []
        features_iterator = self.source_layer.getSelectedFeatures(
        ) if self.selected_only else self.source_layer.getFeatures()
        source_crs = self.source_layer.sourceCrs()
        if source_crs != CRS_2180:
            transformation = (QgsCoordinateTransform(
                source_crs, CRS_2180, QgsCoordinateTransformContext()))
            for f in features_iterator:
                point = f.geometry().asPoint()
                point = transformation.transform(point)
                f.setGeometry(QgsGeometry.fromPointXY(point))
                features.append(f)
        else:
            transformation = None
            features = features_iterator

        uldk_search = self.uldk_api.ULDKSearchPoint(
            "dzialka", ("geom_wkt", "wojewodztwo", "powiat", "gmina", "obreb",
                        "numer", "teryt"))

        found_features = []

        for source_feature in features:
            if QThread.currentThread().isInterruptionRequested():
                self.__commit()
                self.interrupted.emit(self.layer_found, self.layer_not_found)
                return

            skip = False
            for found_feature in found_features:
                if found_feature.geometry().intersects(
                        source_feature.geometry()):
                    if not self.skip_duplicates:
                        self.layer_found.dataProvider().addFeature(
                            found_feature)
                    skip = True
            if skip:
                self.progressed.emit(True, 1 if self.skip_duplicates else 0)
                continue

            point = source_feature.geometry().asPoint()
            uldk_point = self.uldk_api.ULDKPoint(point.x(), point.y(), 2180)

            try:
                uldk_response_row = uldk_search.search(uldk_point)
                additional_attributes = []
                for field in self.additional_output_fields:
                    additional_attributes.append(source_feature[field.name()])
                found_feature = uldk_response_to_qgs_feature(
                    uldk_response_row, additional_attributes)
                found_features.append(found_feature)
                self.layer_found.dataProvider().addFeature(found_feature)
                self.progressed.emit(True, 0)
            except Exception as e:
                not_found_feature = self.__make_not_found_feature(
                    source_feature.geometry(), e)
                self.layer_not_found.dataProvider().addFeature(
                    not_found_feature)
                self.progressed.emit(False, 0)

        self.__commit()
        self.finished.emit(self.layer_found, self.layer_not_found)
Esempio n. 18
0
 def setUp(self):
     """Prepare tc"""
     super(TestQgsRasterLayerTransformContext, self).setUp()
     self.ctx = QgsCoordinateTransformContext()
     self.ctx.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857), 1234, 1235)
     self.rpath = os.path.join(unitTestDataPath(), 'landsat.tif')
    def testSourceDestinationDatumTransformsProj6(self):
        context = QgsCoordinateTransformContext()
        self.assertEqual(context.sourceDestinationDatumTransforms(), {})
        proj_string = '+proj=pipeline +step +inv +proj=lcc +lat_0=-37 +lon_0=145 +lat_1=-36 +lat_2=-38 +x_0=2500000 +y_0=2500000 +ellps=GRS80 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1'
        self.assertFalse(
            context.hasTransform(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283')))
        self.assertFalse(context.mustReverseCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283')))
        self.assertFalse(context.mustReverseCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:4283'),
                                                                QgsCoordinateReferenceSystem('EPSG:3111')))
        self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:3111'),
                                                       QgsCoordinateReferenceSystem('EPSG:4283'), proj_string))
        self.assertTrue(
            context.hasTransform(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283')))
        self.assertFalse(
            context.hasTransform(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4326')))
        self.assertFalse(
            context.hasTransform(QgsCoordinateReferenceSystem('EPSG:3113'), QgsCoordinateReferenceSystem('EPSG:4283')))
        self.assertEqual(context.coordinateOperations(), {('EPSG:3111', 'EPSG:4283'): proj_string})
        self.assertTrue(context.mustReverseCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:4283'),
                                                               QgsCoordinateReferenceSystem('EPSG:3111')))

        self.assertTrue(
            context.hasTransform(QgsCoordinateReferenceSystem('EPSG:4283'), QgsCoordinateReferenceSystem('EPSG:3111')))

        self.assertEqual(context.calculateCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:3111'),
                                                              QgsCoordinateReferenceSystem('EPSG:4283')), proj_string)
        self.assertFalse(context.mustReverseCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:3111'),
                                                                QgsCoordinateReferenceSystem('EPSG:4283')))
        # ideally not equal, but for now it's all we can do, and return True for mustReverseCoordinateOperation here
        self.assertEqual(context.calculateCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:4283'),
                                                              QgsCoordinateReferenceSystem('EPSG:3111')), proj_string)
        self.assertTrue(context.mustReverseCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:4283'),
                                                               QgsCoordinateReferenceSystem('EPSG:3111')))
        proj_string_2 = 'dummy'
        self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:4283'),
                                                       QgsCoordinateReferenceSystem('EPSG:3111'), proj_string_2))
        self.assertEqual(context.calculateCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:4283'),
                                                              QgsCoordinateReferenceSystem('EPSG:3111')), proj_string_2)
        self.assertFalse(context.mustReverseCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:4283'),
                                                                QgsCoordinateReferenceSystem('EPSG:3111')))
        context.removeCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:4283'),
                                          QgsCoordinateReferenceSystem('EPSG:3111'))

        proj_string_2 = '+proj=pipeline +step +inv +proj=utm +zone=56 +south +ellps=GRS80 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1'
        self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:28356'),
                                                       QgsCoordinateReferenceSystem(4283), proj_string_2))
        self.assertEqual(context.coordinateOperations(), {('EPSG:3111', 'EPSG:4283'): proj_string,
                                                          ('EPSG:28356', 'EPSG:4283'): proj_string_2})
        proj_string_3 = '+proj=pipeline +step +inv +proj=utm +zone=56 +south +ellps=GRS80 +step +proj=utm +zone=57 +south +ellps=GRS80'
        self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:28356'),
                                                       QgsCoordinateReferenceSystem(28357), proj_string_3))
        self.assertEqual(context.coordinateOperations(), {('EPSG:3111', 'EPSG:4283'): proj_string,
                                                          ('EPSG:28356', 'EPSG:4283'): proj_string_2,
                                                          ('EPSG:28356', 'EPSG:28357'): proj_string_3})
        self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:28356'),
                                                       QgsCoordinateReferenceSystem('EPSG:28357'),
                                                       'some other proj string'))
        self.assertEqual(context.coordinateOperations(), {('EPSG:3111', 'EPSG:4283'): proj_string,
                                                          ('EPSG:28356', 'EPSG:4283'): proj_string_2,
                                                          ('EPSG:28356', 'EPSG:28357'): 'some other proj string'})

        # invalid additions
        self.assertFalse(context.addCoordinateOperation(QgsCoordinateReferenceSystem(),
                                                        QgsCoordinateReferenceSystem('EPSG:28357'), 'bad proj'))
        self.assertEqual(context.coordinateOperations(), {('EPSG:3111', 'EPSG:4283'): proj_string,
                                                          ('EPSG:28356', 'EPSG:4283'): proj_string_2,
                                                          ('EPSG:28356', 'EPSG:28357'): 'some other proj string'})
        self.assertFalse(context.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:3111'),
                                                        QgsCoordinateReferenceSystem(), 'bad proj'))
        self.assertEqual(context.coordinateOperations(), {('EPSG:3111', 'EPSG:4283'): proj_string,
                                                          ('EPSG:28356', 'EPSG:4283'): proj_string_2,
                                                          ('EPSG:28356', 'EPSG:28357'): 'some other proj string'})

        # indicate no transform required
        self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem(28357),
                                                       QgsCoordinateReferenceSystem(28356), ''))
        self.assertEqual(context.coordinateOperations(), {('EPSG:3111', 'EPSG:4283'): proj_string,
                                                          ('EPSG:28356', 'EPSG:4283'): proj_string_2,
                                                          ('EPSG:28356', 'EPSG:28357'): 'some other proj string',
                                                          ('EPSG:28357', 'EPSG:28356'): ''})

        # remove non-existing
        context.removeCoordinateOperation(QgsCoordinateReferenceSystem(3113), QgsCoordinateReferenceSystem(3111))
        self.assertEqual(context.coordinateOperations(), {('EPSG:3111', 'EPSG:4283'): proj_string,
                                                          ('EPSG:28356', 'EPSG:4283'): proj_string_2,
                                                          ('EPSG:28356', 'EPSG:28357'): 'some other proj string',
                                                          ('EPSG:28357', 'EPSG:28356'): ''})

        # remove existing
        context.removeCoordinateOperation(QgsCoordinateReferenceSystem(3111),
                                          QgsCoordinateReferenceSystem(4283))
        self.assertEqual(context.coordinateOperations(), {('EPSG:28356', 'EPSG:4283'): proj_string_2,
                                                          ('EPSG:28356', 'EPSG:28357'): 'some other proj string',
                                                          ('EPSG:28357', 'EPSG:28356'): ''})
        context.removeCoordinateOperation(QgsCoordinateReferenceSystem(28356),
                                          QgsCoordinateReferenceSystem(28357))
        self.assertEqual(context.coordinateOperations(), {('EPSG:28356', 'EPSG:4283'): proj_string_2,
                                                          ('EPSG:28357', 'EPSG:28356'): ''})

        context.clear()
        self.assertEqual(context.coordinateOperations(), {})
Esempio n. 20
0
    def test_insert_srsName(self):
        """Test srsName is respected when insering"""

        post_data = """
        <Transaction xmlns="http://www.opengis.net/wfs" xsi:schemaLocation="http://www.qgis.org/gml http://localhost:8000/?SERVICE=WFS&amp;REQUEST=DescribeFeatureType&amp;VERSION=1.0.0&amp;TYPENAME=as_symbols" service="WFS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="{version}" xmlns:gml="http://www.opengis.net/gml">
            <Insert xmlns="http://www.opengis.net/wfs">
                <as_symbols xmlns="http://www.qgis.org/gml">
                <name xmlns="http://www.qgis.org/gml">{name}</name>
                <geometry xmlns="http://www.qgis.org/gml">
                    <gml:Point srsName="{srsName}">
                    <gml:coordinates cs="," ts=" ">{coordinates}</gml:coordinates>
                    </gml:Point>
                </geometry>
                </as_symbols>
            </Insert>
        </Transaction>
        """

        project = self.testdata_path + \
            "test_project_wms_grouped_layers.qgs"
        assert os.path.exists(project), "Project file not found: " + project

        query_string = '?SERVICE=WFS&MAP={}'.format(
            urllib.parse.quote(project))
        request = post_data.format(name='4326-test1',
                                   version='1.1.0',
                                   srsName='EPSG:4326',
                                   coordinates='10.67,52.48')
        header, body = self._execute_request(
            query_string,
            requestMethod=QgsServerRequest.PostMethod,
            data=request.encode('utf-8'))

        # Verify
        vl = QgsVectorLayer(
            self.testdata_path +
            'test_project_wms_grouped_layers.gpkg|layername=as_symbols',
            'as_symbols')
        self.assertTrue(vl.isValid())
        feature = next(
            vl.getFeatures(
                QgsFeatureRequest(QgsExpression('"name" = \'4326-test1\''))))
        geom = feature.geometry()

        tr = QgsCoordinateTransform(
            QgsCoordinateReferenceSystem.fromEpsgId(4326), vl.crs(),
            QgsCoordinateTransformContext())

        geom_4326 = QgsGeometry.fromWkt('point( 10.67 52.48)')
        geom_4326.transform(tr)
        self.assertEqual(geom.asWkt(0), geom_4326.asWkt(0))

        # Now: insert a feature in layer's CRS
        request = post_data.format(name='25832-test1',
                                   version='1.1.0',
                                   srsName='EPSG:25832',
                                   coordinates='613412,5815738')
        header, body = self._execute_request(
            query_string,
            requestMethod=QgsServerRequest.PostMethod,
            data=request.encode('utf-8'))

        feature = next(
            vl.getFeatures(
                QgsFeatureRequest(QgsExpression('"name" = \'25832-test1\''))))
        geom = feature.geometry()
        self.assertEqual(geom.asWkt(0), geom_4326.asWkt(0))

        # Tests for inverted axis issue GH #36584
        # Cleanup
        self.assertTrue(vl.startEditing())
        vl.selectByExpression('"name" LIKE \'4326-test%\'')
        vl.deleteSelectedFeatures()
        self.assertTrue(vl.commitChanges())

        self.i = 0

        def _test(version, srsName, lat_lon=False):
            self.i += 1
            name = '4326-test_%s' % self.i
            request = post_data.format(
                name=name,
                version=version,
                srsName=srsName,
                coordinates='52.48,10.67' if lat_lon else '10.67,52.48')
            header, body = self._execute_request(
                query_string,
                requestMethod=QgsServerRequest.PostMethod,
                data=request.encode('utf-8'))
            feature = next(
                vl.getFeatures(
                    QgsFeatureRequest(QgsExpression('"name" = \'%s\'' %
                                                    name))))
            geom = feature.geometry()
            self.assertEqual(
                geom.asWkt(0), geom_4326.asWkt(0),
                "Transaction Failed: %s , %s, lat_lon=%s" %
                (version, srsName, lat_lon))

        _test('1.1.0', 'urn:ogc:def:crs:EPSG::4326', lat_lon=True)
        _test('1.1.0',
              'http://www.opengis.net/def/crs/EPSG/0/4326',
              lat_lon=True)
        _test('1.1.0',
              'http://www.opengis.net/gml/srs/epsg.xml#4326',
              lat_lon=False)
        _test('1.1.0', 'EPSG:4326', lat_lon=False)

        _test('1.0.0', 'urn:ogc:def:crs:EPSG::4326', lat_lon=True)
        _test('1.0.0',
              'http://www.opengis.net/def/crs/EPSG/0/4326',
              lat_lon=True)
        _test('1.0.0',
              'http://www.opengis.net/gml/srs/epsg.xml#4326',
              lat_lon=False)
        _test('1.0.0', 'EPSG:4326', lat_lon=False)

        def _test_getFeature(version, srsName, lat_lon=False):
            # Now get the feature through WFS using BBOX filter
            bbox = QgsGeometry.fromWkt('point( 10.7006 52.4317)').boundingBox()
            bbox.grow(0.0001)
            bbox_text = "%s,%s,%s,%s" % (
                (bbox.yMinimum(), bbox.xMinimum(), bbox.yMaximum(),
                 bbox.xMaximum()) if lat_lon else
                (bbox.xMinimum(), bbox.yMinimum(), bbox.xMaximum(),
                 bbox.yMaximum()))
            req = query_string + '&REQUEST=GetFeature&VERSION={version}&TYPENAME=as_symbols&SRSNAME={srsName}&BBOX={bbox},{srsName}'.format(
                version=version, srsName=srsName, bbox=bbox_text)
            header, body = self._execute_request(req)
            self.assertTrue(
                b'gid>7' in body, "GetFeature Failed: %s , %s, lat_lon=%s" %
                (version, srsName, lat_lon))

        _test_getFeature('1.1.0', 'urn:ogc:def:crs:EPSG::4326', lat_lon=True)
        _test_getFeature('1.1.0', 'EPSG:4326', lat_lon=False)

        _test_getFeature('1.0.0', 'urn:ogc:def:crs:EPSG::4326', lat_lon=True)
        _test_getFeature('1.0.0', 'EPSG:4326', lat_lon=False)

        # Cleanup
        self.assertTrue(vl.startEditing())
        vl.selectByExpression('"name" LIKE \'4326-test%\'')
        vl.deleteSelectedFeatures()
        self.assertTrue(vl.commitChanges())
Esempio n. 21
0
    def testSuccess(self):
        """test successfully writing a layer"""
        path = os.path.join(unitTestDataPath(), 'raster', 'with_color_table.tif')
        raster_layer = QgsRasterLayer(path, "test")
        self.assertTrue(raster_layer.isValid())

        pipe = QgsRasterPipe()
        self.assertTrue(pipe.set(raster_layer.dataProvider().clone()))

        tmp = create_temp_filename('success.tif')
        writer = QgsRasterFileWriter(tmp)

        task = QgsRasterFileWriterTask(writer, pipe, 100, 100, raster_layer.extent(), raster_layer.crs(), QgsCoordinateTransformContext())

        task.writeComplete.connect(self.onSuccess)
        task.errorOccurred.connect(self.onFail)

        QgsApplication.taskManager().addTask(task)
        while not self.success and not self.fail:
            QCoreApplication.processEvents()

        self.assertTrue(self.success)
        self.assertFalse(self.fail)
        self.assertTrue(os.path.exists(tmp))
Esempio n. 22
0
    def response_geotiff_mode(self, request):
        """
        Export raster as geotiff
        i.e:
        192.168.1.137:8006/raster/api/geotiff/qdjango/190/sfondo_clip_c60533a4_743e_4734_9b95_514ac765ec4e/
        192.168.1.137:8006/raster/api/geotiff/qdjango/190/europa_dem_8f0a9c30_5b96_4661_b747_8ce4f2679d6b/?map_extent=10.515901325263899%2C43.875701513907146%2C10.55669628723769%2C43.92294901234999

        :param request: Http Django request object
        :return: http response with attached file
        """

        #if not self.layer.download:
        #     return HttpResponseForbidden()


        tmp_dir = tempfile.TemporaryDirectory()

        filename = f"{self.metadata_layer.qgis_layer.name()}.tif"

        file_path = os.path.join(tmp_dir.name, filename)

        writer = QgsRasterFileWriter(file_path)
        provider = self.metadata_layer.qgis_layer.dataProvider()
        renderer = self.metadata_layer.qgis_layer.renderer()

        # Check for Url Params
        if request.query_params.get('map_extent'):
            me = request.query_params.get('map_extent').split(',')
            orig_extent =provider.extent()
            extent = QgsRectangle(float(me[0]), float(me[1]), float(me[2]), float(me[3]))

            # If crs layer is not equal to project crs
            if self.reproject:
                ct = QgsCoordinateTransform(
                    QgsCoordinateReferenceSystem(f'EPSG:{self.layer.project.group.srid.srid}'),
                    self.metadata_layer.qgis_layer.crs(),
                    QgsCoordinateTransformContext()
                )
                extent = ct.transform(extent)

            # Calc columns and rows
            cols = int((extent.xMaximum() - extent.xMinimum()) /
                      (orig_extent.xMaximum() - orig_extent.xMinimum()) * provider.xSize())
            rows = int((extent.yMaximum() - extent.yMinimum()) /
                      (orig_extent.yMaximum() - orig_extent.yMinimum()) * provider.ySize())

            # For cols or rows lower than 0, we have to recalculate extent to guarantee minimal raster cell
            if cols < 1:
                cols = 1
                new_wide_x_extent = (orig_extent.xMaximum() - orig_extent.xMinimum()) / provider.xSize()
                off = (new_wide_x_extent - (extent.xMaximum() - extent.xMinimum())) / 2
                extent.setXMinimum(extent.xMinimum() - off)
                extent.setXMaximum(extent.xMaximum() + off)

            if rows < 1:
                rows = 1
                new_wide_y_extent = (orig_extent.yMaximum() - orig_extent.yMinimum()) / provider.ySize()
                off = (new_wide_y_extent - (extent.yMaximum() - extent.yMinimum())) / 2
                extent.setYMinimum(extent.yMinimum() - off)
                extent.setYMaximum(extent.yMaximum() + off)

        else:
            extent = provider.extent()
            cols = provider.xSize()
            rows = provider.ySize()

        pipe = QgsRasterPipe()
        pipe.set(provider.clone())
        pipe.set(renderer.clone())

        error_code = writer.writeRaster(
            pipe,
            cols,
            rows,
            extent,
            self.metadata_layer.qgis_layer.crs(),
            self.metadata_layer.qgis_layer.transformContext()
        )

        if error_code != QgsRasterFileWriter.NoError:
            tmp_dir.cleanup()
            raise APIException(f"An error occoured on create raster file for export")

        # Grab ZIP file from in-memory, make response with correct MIME-type
        response = HttpResponse(
            open(file_path, 'rb').read(), content_type='image/tif')

        response['Content-Disposition'] = f'attachment; filename={filename}'
        response.set_cookie('fileDownload', 'true')
        return response
Esempio n. 23
0
    def testLayerRemovalBeforeRun(self):
        """test behavior when layer is removed before task begins"""
        path = os.path.join(unitTestDataPath(), 'raster', 'with_color_table.tif')
        raster_layer = QgsRasterLayer(path, "test")
        self.assertTrue(raster_layer.isValid())

        pipe = QgsRasterPipe()
        self.assertTrue(pipe.set(raster_layer.dataProvider().clone()))

        tmp = create_temp_filename('remove_layer.tif')
        writer = QgsRasterFileWriter(tmp)

        task = QgsRasterFileWriterTask(writer, pipe, 100, 100, raster_layer.extent(), raster_layer.crs(), QgsCoordinateTransformContext())

        task.writeComplete.connect(self.onSuccess)
        task.errorOccurred.connect(self.onFail)

        # remove layer
        raster_layer = None

        QgsApplication.taskManager().addTask(task)
        while not self.success and not self.fail:
            QCoreApplication.processEvents()

        # in this case will still get a positive result - since the pipe is cloned before the task
        # begins the task is no longer dependent on the original layer
        self.assertTrue(self.success)
        self.assertFalse(self.fail)
        self.assertTrue(os.path.exists(tmp))
Esempio n. 24
0
    def testContextProj6(self):
        """
        Various tests to ensure that datum transforms are correctly set respecting context
        """
        context = QgsCoordinateTransformContext()
        context.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:28356'),
                                       QgsCoordinateReferenceSystem('EPSG:4283'),
                                       'proj')

        transform = QgsCoordinateTransform(QgsCoordinateReferenceSystem('EPSG:28354'), QgsCoordinateReferenceSystem('EPSG:28353'), context)
        self.assertEqual(list(transform.context().coordinateOperations().keys()), [('EPSG:28356', 'EPSG:4283')])
        # should be no coordinate operation
        self.assertEqual(transform.coordinateOperation(), '')
        # should default to allowing fallback transforms
        self.assertTrue(transform.allowFallbackTransforms())

        transform = QgsCoordinateTransform(QgsCoordinateReferenceSystem('EPSG:28356'),
                                           QgsCoordinateReferenceSystem('EPSG:4283'), context)
        self.assertTrue(transform.allowFallbackTransforms())
        context.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:28356'),
                                       QgsCoordinateReferenceSystem('EPSG:4283'),
                                       'proj', False)
        transform = QgsCoordinateTransform(QgsCoordinateReferenceSystem('EPSG:28356'),
                                           QgsCoordinateReferenceSystem('EPSG:4283'), context)
        self.assertFalse(transform.allowFallbackTransforms())

        # matching source
        transform = QgsCoordinateTransform(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:28353'), context)
        self.assertEqual(transform.coordinateOperation(), '')
        # matching dest
        transform = QgsCoordinateTransform(QgsCoordinateReferenceSystem('EPSG:28354'),
                                           QgsCoordinateReferenceSystem('EPSG:4283'), context)
        self.assertEqual(transform.coordinateOperation(), '')
        # matching src/dest pair
        transform = QgsCoordinateTransform(QgsCoordinateReferenceSystem('EPSG:28356'),
                                           QgsCoordinateReferenceSystem('EPSG:4283'), context)
        self.assertEqual(transform.coordinateOperation(), 'proj')

        # test manual overwriting
        transform.setCoordinateOperation('proj2')
        self.assertEqual(transform.coordinateOperation(), 'proj2')
        transform.setAllowFallbackTransforms(False)
        self.assertFalse(transform.allowFallbackTransforms())
        transform.setAllowFallbackTransforms(True)
        self.assertTrue(transform.allowFallbackTransforms())

        # test that auto operation setting occurs when updating src/dest crs
        transform.setSourceCrs(QgsCoordinateReferenceSystem('EPSG:28356'))
        self.assertEqual(transform.coordinateOperation(), 'proj')
        transform.setCoordinateOperation('proj2')

        transform.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:4283'))
        self.assertEqual(transform.coordinateOperation(), 'proj')
        transform.setCoordinateOperation('proj2')

        # delayed context set
        transform = QgsCoordinateTransform()
        self.assertEqual(transform.coordinateOperation(), '')
        transform.setSourceCrs(QgsCoordinateReferenceSystem('EPSG:28356'))
        transform.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:4283'))
        self.assertEqual(transform.coordinateOperation(), '')
        transform.setContext(context)
        self.assertEqual(transform.coordinateOperation(), 'proj')
        self.assertEqual(list(transform.context().coordinateOperations().keys()), [('EPSG:28356', 'EPSG:4283')])
def to_layer(features, crs, encoding, geom_type, layer_type, path):
    first_feat = features[0]
    fields = first_feat.fields()
    layer = None
    if layer_type == 'memory':
        layer = QgsVectorLayer(geom_type + '?crs=' + crs.authid(), path,
                               "memory")
        pr = layer.dataProvider()
        pr.addAttributes(fields.toList())
        layer.updateFields()
        layer.startEditing()
        pr.addFeatures(features)
        layer.commitChanges()

    elif layer_type == 'shapefile':

        wkbTypes = {
            'Point': QgsWkbTypes.Point,
            'Linestring': QgsWkbTypes.LineString,
            'Polygon': QgsWkbTypes.Polygon
        }
        options = QgsVectorFileWriter.SaveVectorOptions()
        options.driverName = "ESRI Shapefile"
        options.fileEncoding = encoding
        file_writer = QgsVectorFileWriter.create(
            path, fields, wkbTypes[geom_type], crs,
            QgsCoordinateTransformContext(), options)
        if file_writer.hasError() != QgsVectorFileWriter.NoError:
            print("Error when creating shapefile: ",
                  file_writer.errorMessage())
        del file_writer
        layer = QgsVectorLayer(path, ntpath.basename(path)[:-4], "ogr")
        pr = layer.dataProvider()
        layer.startEditing()
        pr.addFeatures(features)
        layer.commitChanges()

    elif layer_type == 'postgis':

        # this is needed to load the table later
        # uri = connstring + """ type=""" + geom_types[geom_type] + """ table=\"""" + schema_name + """\".\"""" + table_name + """\" (geom) """

        connstring, schema_name, table_name = path
        uri = connstring + """ type=""" + geom_type + """ table=\"""" + schema_name + """\".\"""" + table_name + """\" (geom) """
        crs_id = crs.postgisSrid()
        try:
            con = psycopg2.connect(connstring)
            cur = con.cursor()
            create_query = cur.mogrify(
                """DROP TABLE IF EXISTS "%s"."%s"; CREATE TABLE "%s"."%s"( geom geometry(%s, %s))""",
                (AsIs(schema_name), AsIs(table_name), AsIs(schema_name),
                 AsIs(table_name), geom_type, AsIs(crs_id)))
            cur.execute(create_query)
            con.commit()
            post_q_flds = {
                2: 'bigint',
                6: 'numeric',
                1: 'bool',
                'else': 'text',
                4: 'numeric'
            }
            for f in fields:
                f_type = f.type()
                if f_type not in [2, 6, 1]:
                    f_type = 'else'
                attr_query = cur.mogrify(
                    """ALTER TABLE "%s"."%s" ADD COLUMN "%s" %s""",
                    (AsIs(schema_name), AsIs(table_name), AsIs(
                        f.name()), AsIs(post_q_flds[f_type])))
                cur.execute(attr_query)
                con.commit()
            field_names = ",".join(['"' + f.name() + '"' for f in fields])
            for feature in features:
                attrs = [i if i else None for i in feature.attributes()]
                insert_query = cur.mogrify(
                    """INSERT INTO "%s"."%s" (%s, geom) VALUES %s, ST_GeomFromText(%s,%s))""",
                    (AsIs(schema_name), AsIs(table_name), AsIs(field_names),
                     tuple(attrs), feature.geometry().asWkt(), AsIs(crs_id)))
                idx = insert_query.find(b', ST_GeomFromText') - 1
                insert_query = insert_query[:idx] + insert_query[(idx + 1):]
                # QgsMessageLog.logMessage('sql query %s' % insert_query, level=Qgis.Critical)
                cur.execute(insert_query)
                # con.commit()
            pkey_query = cur.mogrify(
                """ALTER TABLE "%s"."%s" DROP COLUMN IF EXISTS rcl_id; ALTER TABLE "%s"."%s" ADD COLUMN rcl_id serial PRIMARY KEY NOT NULL;""",
                (AsIs(schema_name), AsIs(table_name), AsIs(schema_name),
                 AsIs(table_name)))
            cur.execute(pkey_query)
            con.commit()
            con.close()
            layer = QgsVectorLayer(uri, table_name, 'postgres')
        except psycopg2.DatabaseError as e:
            print(e)
    return layer