Ejemplo n.º 1
1
def save2PointShape(shapePath, geodata, attribName,
                    attribData, label, spatialRef):
    """
    :param label:
    :param shapePath: Pfad wo Shapefile agespeichert wird
    :param geodata: Koordinaten der Punkte
    :param attribName: Attributname (Feldname) von zusätzlichen Werten
    :param attribData: Werte für Attribute
    :param spatialRef: Räumliche Referenz
    """

    # define fields for feature attributes. A QgsFields object is needed
    fields = QgsFields()
    fields.append(QgsField("StuetzenNr", QVariant.String))
    fields.append(QgsField(attribName, QVariant.Int))
    writer = QgsVectorFileWriter(shapePath, "UTF8", fields, QgsWkbTypes.PointZ,
                                 spatialRef, "ESRI Shapefile")

    if writer.hasError() != QgsVectorFileWriter.NoError:
        # TODO
        raise Exception("Vector Writer")

    for idx, (coords, attrib) in enumerate(zip(geodata, attribData)):
        feature = QgsFeature()
        feature.setFields(fields)
        # TODO: Nicht 3D weil Methode fromPoint() nicht existiert. Wird evtl. in der Zukunft implementiert
        feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(coords[0], coords[1])))
        feature.setId(idx)
        feature.setAttribute("StuetzenNr", label[idx])
        feature.setAttribute(attribName, attrib)
        writer.addFeature(feature)
        del feature

    # delete the writer to flush features to disk
    del writer
Ejemplo n.º 2
0
 def testWFSPointsMultipleEdits(self):
     """
     Adds some points, then check.
     Modify 2 points, then checks and clear all
     """
     layer_name = 'test_point'
     layer = self._getLayer(layer_name)
     wfs_layer = self._getWFSLayer(layer_name)
     feat1 = QgsFeature(wfs_layer.pendingFields())
     feat1['id'] = 11
     feat1['name'] = 'name 11'
     feat1.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(9, 45)))
     feat2 = QgsFeature(wfs_layer.pendingFields())
     feat2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(9.5, 45.5)))
     feat2['id'] = 12
     feat2['name'] = 'name 12'
     old_features = [feat1, feat2]
     # Change feat1 and feat2
     new_feat1 = QgsFeature(wfs_layer.pendingFields())
     new_feat1['id'] = 121
     new_feat1['name'] = 'name 121'
     new_feat1.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(10, 46)))
     new_feat2 = QgsFeature(wfs_layer.pendingFields())
     new_feat2['id'] = 122
     new_feat2['name'] = 'name 122'
     new_feat2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(10.5, 47)))
     new_features = [new_feat1, new_feat2]
     self._testLayer(wfs_layer, layer, old_features, new_features)
Ejemplo n.º 3
0
    def testDeleteMultipleFeatures(self):
        # test deleting multiple features from an edit buffer

        # make a layer with two features
        layer = createEmptyLayer()
        self.assertTrue(layer.startEditing())

        # add two features
        f1 = QgsFeature(layer.fields(), 1)
        f1.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(1, 2)))
        f1.setAttributes(["test", 123])
        self.assertTrue(layer.addFeature(f1))

        f2 = QgsFeature(layer.fields(), 2)
        f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(2, 4)))
        f2.setAttributes(["test2", 246])
        self.assertTrue(layer.addFeature(f2))

        layer.commitChanges()
        layer.startEditing()

        self.assertEqual(layer.editBuffer().deletedFeatureIds(), [])
        self.assertFalse(layer.editBuffer().isFeatureDeleted(1))
        self.assertFalse(layer.editBuffer().isFeatureDeleted(2))

        # delete features
        layer.deleteFeatures([1, 2])

        # test contents of buffer
        self.assertEqual(set(layer.editBuffer().deletedFeatureIds()), set([1, 2]))
        self.assertTrue(layer.editBuffer().isFeatureDeleted(1))
        self.assertTrue(layer.editBuffer().isFeatureDeleted(2))
Ejemplo n.º 4
0
    def testAddMultipleFeatures(self):
        # test adding multiple features to an edit buffer
        layer = createEmptyLayer()
        self.assertTrue(layer.startEditing())

        self.assertEqual(layer.editBuffer().addedFeatures(), {})
        self.assertFalse(layer.editBuffer().isFeatureAdded(1))
        self.assertFalse(layer.editBuffer().isFeatureAdded(3))

        # add two features
        f1 = QgsFeature(layer.fields(), 1)
        f1.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(1, 2)))
        f1.setAttributes(["test", 123])
        f2 = QgsFeature(layer.fields(), 2)
        f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(2, 4)))
        f2.setAttributes(["test2", 246])

        self.assertTrue(layer.addFeatures([f1, f2]))

        # test contents of buffer
        added = layer.editBuffer().addedFeatures()
        new_feature_ids = list(added.keys())
        self.assertEqual(added[new_feature_ids[0]]['fldtxt'], 'test2')
        self.assertEqual(added[new_feature_ids[0]]['fldint'], 246)
        self.assertEqual(added[new_feature_ids[1]]['fldtxt'], 'test')
        self.assertEqual(added[new_feature_ids[1]]['fldint'], 123)

        self.assertTrue(layer.editBuffer().isFeatureAdded(new_feature_ids[0]))
        self.assertTrue(layer.editBuffer().isFeatureAdded(new_feature_ids[1]))
Ejemplo n.º 5
0
    def testProxyFeatureSink(self):
        fields = QgsFields()
        fields.append(QgsField('fldtxt', QVariant.String))
        fields.append(QgsField('fldint', QVariant.Int))

        store = QgsFeatureStore(fields, QgsCoordinateReferenceSystem())
        proxy = QgsProxyFeatureSink(store)
        self.assertEqual(proxy.destinationSink(), store)

        self.assertEqual(len(store), 0)

        f = QgsFeature()
        f.setAttributes(["test", 123])
        f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100, 200)))
        proxy.addFeature(f)
        self.assertEqual(len(store), 1)
        self.assertEqual(store.features()[0]['fldtxt'], 'test')

        f2 = QgsFeature()
        f2.setAttributes(["test2", 457])
        f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(200, 200)))
        f3 = QgsFeature()
        f3.setAttributes(["test3", 888])
        f3.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(300, 200)))
        proxy.addFeatures([f2, f3])
        self.assertEqual(len(store), 3)
        self.assertEqual(store.features()[1]['fldtxt'], 'test2')
        self.assertEqual(store.features()[2]['fldtxt'], 'test3')
Ejemplo n.º 6
0
    def testCreateLayer(self):
        layer = QgsVectorLayer("Point?field=id:integer&field=fldtxt:string&field=fldint:integer",
                               "addfeat", "memory")
        pr = layer.dataProvider()
        f = QgsFeature()
        f.setAttributes([1, "test", 1])
        f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(1, 2)))
        f2 = QgsFeature()
        f2.setAttributes([2, "test2", 3])
        f3 = QgsFeature()
        f3.setAttributes([3, "test2", NULL])
        f3.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(3, 2)))
        f4 = QgsFeature()
        f4.setAttributes([4, NULL, 3])
        f4.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(4, 3)))
        pr.addFeatures([f, f2, f3, f4])

        uri = '{} table="qgis_test"."new_table" sql='.format(self.dbconn)
        error, message = QgsVectorLayerExporter.exportLayer(layer, uri, 'mssql', QgsCoordinateReferenceSystem('EPSG:4326'))
        self.assertEqual(error, QgsVectorLayerExporter.NoError)

        new_layer = QgsVectorLayer(uri, 'new', 'mssql')
        self.assertTrue(new_layer.isValid())
        self.assertEqual(new_layer.wkbType(), QgsWkbTypes.Point)
        self.assertEqual([f.name() for f in new_layer.fields()], ['qgs_fid', 'id', 'fldtxt', 'fldint'])

        features = [f.attributes() for f in new_layer.getFeatures()]
        self.assertEqual(features, [[1, 1, 'test', 1],
                                    [2, 2, 'test2', 3],
                                    [3, 3, 'test2', NULL],
                                    [4, 4, NULL, 3]])
        geom = [f.geometry().asWkt() for f in new_layer.getFeatures()]
        self.assertEqual(geom, ['Point (1 2)', '', 'Point (3 2)', 'Point (4 3)'])
Ejemplo n.º 7
0
    def testFeatureSourceInput(self):
        # create a memory layer and add to project and context
        layer = QgsVectorLayer("Point?crs=epsg:3857&field=fldtxt:string&field=fldint:integer",
                               "testmem", "memory")
        self.assertTrue(layer.isValid())
        pr = layer.dataProvider()
        f = QgsFeature()
        f.setAttributes(["test", 123])
        f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100, 200)))
        f2 = QgsFeature()
        f2.setAttributes(["test2", 457])
        f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(110, 200)))
        self.assertTrue(pr.addFeatures([f, f2]))
        self.assertEqual(layer.featureCount(), 2)

        # select first feature
        layer.selectByIds([next(layer.getFeatures()).id()])
        self.assertEqual(len(layer.selectedFeatureIds()), 1)

        QgsProject.instance().addMapLayer(layer)
        context = QgsProcessingContext()
        context.setProject(QgsProject.instance())

        alg = QgsApplication.processingRegistry().createAlgorithmById('grass7:v.buffer')
        self.assertIsNotNone(alg)
        temp_file = os.path.join(self.temp_dir, 'grass_output_sel.shp')
        parameters = {'input': QgsProcessingFeatureSourceDefinition('testmem', True),
                      'cats': '',
                      'where': '',
                      'type': [0, 1, 4],
                      'distance': 1,
                      'minordistance': None,
                      'angle': 0,
                      'column': None,
                      'scale': 1,
                      'tolerance': 0.01,
                      '-s': False,
                      '-c': False,
                      '-t': False,
                      'output': temp_file,
                      'GRASS_REGION_PARAMETER': None,
                      'GRASS_SNAP_TOLERANCE_PARAMETER': -1,
                      'GRASS_MIN_AREA_PARAMETER': 0.0001,
                      'GRASS_OUTPUT_TYPE_PARAMETER': 0,
                      'GRASS_VECTOR_DSCO': '',
                      'GRASS_VECTOR_LCO': ''}
        feedback = QgsProcessingFeedback()

        results, ok = alg.run(parameters, context, feedback)
        self.assertTrue(ok)
        self.assertTrue(os.path.exists(temp_file))

        # make sure that layer has correct features
        res = QgsVectorLayer(temp_file, 'res')
        self.assertTrue(res.isValid())
        self.assertEqual(res.featureCount(), 1)

        QgsProject.instance().removeMapLayer(layer)
Ejemplo n.º 8
0
    def test_updateFeatures(self):
        ol, offline_layer = self._testInit()
        # Edit feature 2
        feat2 = self._getFeatureByAttribute(offline_layer, 'name', "'name 2'")
        self.assertTrue(offline_layer.startEditing())
        self.assertTrue(offline_layer.changeAttributeValue(feat2.id(), offline_layer.fields().lookupField('name'), 'name 2 edited'))
        self.assertTrue(offline_layer.changeGeometry(feat2.id(), QgsGeometry.fromPointXY(QgsPointXY(33.0, 60.0))))
        self.assertTrue(offline_layer.commitChanges())
        feat2 = self._getFeatureByAttribute(offline_layer, 'name', "'name 2 edited'")
        self.assertTrue(ol.isOfflineProject())
        # Sync
        ol.synchronize()
        sleep(2)
        # Does anybody know why the sleep is needed? Is that a threaded WFS consequence?
        online_layer = list(self.registry.mapLayers().values())[0]
        self.assertTrue(online_layer.isValid())
        self.assertFalse(online_layer.name().find('(offline)') > -1)
        self.assertEqual(len([f for f in online_layer.getFeatures()]), len(TEST_FEATURES))
        # Check that data have changed in the backend (raise exception if not found)
        feat2 = self._getFeatureByAttribute(self._getLayer('test_point'), 'name', "'name 2 edited'")
        feat2 = self._getFeatureByAttribute(online_layer, 'name', "'name 2 edited'")
        self.assertEqual(feat2.geometry().asPoint().toString(), QgsPointXY(33.0, 60.0).toString())
        # Check that all other features have not changed
        layer = self._getLayer('test_point')
        self.assertTrue(self._compareFeature(layer, TEST_FEATURES[1 - 1]))
        self.assertTrue(self._compareFeature(layer, TEST_FEATURES[3 - 1]))
        self.assertTrue(self._compareFeature(layer, TEST_FEATURES[4 - 1]))

        # Test for regression on double sync (it was a SEGFAULT)
        # goes offline
        ol = QgsOfflineEditing()
        offline_layer = list(self.registry.mapLayers().values())[0]
        # Edit feature 2
        feat2 = self._getFeatureByAttribute(offline_layer, 'name', "'name 2 edited'")
        self.assertTrue(offline_layer.startEditing())
        self.assertTrue(offline_layer.changeAttributeValue(feat2.id(), offline_layer.fields().lookupField('name'), 'name 2'))
        self.assertTrue(offline_layer.changeGeometry(feat2.id(), QgsGeometry.fromPointXY(TEST_FEATURES[1][2])))
        # Edit feat 4
        feat4 = self._getFeatureByAttribute(offline_layer, 'name', "'name 4'")
        self.assertTrue(offline_layer.changeAttributeValue(feat4.id(), offline_layer.fields().lookupField('name'), 'name 4 edited'))
        self.assertTrue(offline_layer.commitChanges())
        # Sync
        ol.synchronize()
        # Does anybody knows why the sleep is needed? Is that a threaded WFS consequence?
        sleep(1)
        online_layer = list(self.registry.mapLayers().values())[0]
        layer = self._getLayer('test_point')
        # Check that data have changed in the backend (raise exception if not found)
        feat4 = self._getFeatureByAttribute(layer, 'name', "'name 4 edited'")
        feat4 = self._getFeatureByAttribute(online_layer, 'name', "'name 4 edited'")
        feat2 = self._getFeatureByAttribute(layer, 'name', "'name 2'")
        feat2 = self._getFeatureByAttribute(online_layer, 'name', "'name 2'")
        # Check that all other features have not changed
        layer = self._getLayer('test_point')
        self.assertTrue(self._compareFeature(layer, TEST_FEATURES[1 - 1]))
        self.assertTrue(self._compareFeature(layer, TEST_FEATURES[2 - 1]))
        self.assertTrue(self._compareFeature(layer, TEST_FEATURES[3 - 1]))
Ejemplo n.º 9
0
    def testAddFeatures(self):
        # test adding features to an edit buffer
        layer = createEmptyLayer()
        self.assertTrue(layer.startEditing())

        self.assertEqual(layer.editBuffer().addedFeatures(), {})
        self.assertFalse(layer.editBuffer().isFeatureAdded(1))
        self.assertFalse(layer.editBuffer().isFeatureAdded(3))

        # add two features
        f1 = QgsFeature(layer.fields(), 1)
        f1.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(1, 2)))
        f1.setAttributes(["test", 123])
        self.assertTrue(layer.addFeature(f1))

        f2 = QgsFeature(layer.fields(), 2)
        f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(2, 4)))
        f2.setAttributes(["test2", 246])

        self.assertTrue(layer.addFeature(f2))

        # test contents of buffer
        added = layer.editBuffer().addedFeatures()
        new_feature_ids = list(added.keys())
        self.assertEqual(added[new_feature_ids[0]]['fldtxt'], 'test2')
        self.assertEqual(added[new_feature_ids[0]]['fldint'], 246)
        self.assertEqual(added[new_feature_ids[1]]['fldtxt'], 'test')
        self.assertEqual(added[new_feature_ids[1]]['fldint'], 123)

        self.assertTrue(layer.editBuffer().isFeatureAdded(new_feature_ids[0]))
        self.assertTrue(layer.editBuffer().isFeatureAdded(new_feature_ids[1]))

        # check if error in case adding not adaptable geometry
        # eg. a Multiline in a Line
        layer = createEmptyLinestringLayer()
        self.assertTrue(layer.startEditing())

        self.assertEqual(layer.editBuffer().addedFeatures(), {})
        self.assertFalse(layer.editBuffer().isFeatureAdded(1))
        self.assertFalse(layer.editBuffer().isFeatureAdded(3))

        # add a features with a multi line geometry of not touched lines =>
        # cannot be forced to be linestring
        multiline = [
            [QgsPointXY(1, 1), QgsPointXY(2, 2)],
            [QgsPointXY(3, 3), QgsPointXY(4, 4)],
        ]
        f1 = QgsFeature(layer.fields(), 1)
        f1.setGeometry(QgsGeometry.fromMultiPolylineXY(multiline))
        f1.setAttributes(["test", 123])
        self.assertTrue(layer.addFeatures([f1]))
        self.assertFalse(layer.commitChanges())
Ejemplo n.º 10
0
def createReferencingLayer():
    layer = QgsVectorLayer("Point?field=fldtxt:string&field=foreignkey:integer",
                           "referencinglayer", "memory")
    pr = layer.dataProvider()
    f1 = QgsFeature()
    f1.setFields(layer.fields())
    f1.setAttributes(["test1", 123])
    f1.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100, 200)))
    f2 = QgsFeature()
    f2.setFields(layer.fields())
    f2.setAttributes(["test2", 123])
    f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(101, 201)))
    assert pr.addFeatures([f1, f2])
    return layer
Ejemplo n.º 11
0
def get_utm_epsg(longitude, latitude, crs=None):
    """Return epsg code of the utm zone according to X, Y coordinates.

    By default, the CRS is EPSG:4326. If the CRS is provided, first X,Y will
    be reprojected from the input CRS to WGS84.

    The code is based on the code:
    http://gis.stackexchange.com/questions/34401

    :param longitude: The longitude.
    :type longitude: float

    :param latitude: The latitude.
    :type latitude: float

    :param crs: The coordinate reference system of the latitude, longitude.
    :type crs: QgsCoordinateReferenceSystem
    """
    if crs is None or crs.authid() == 'EPSG:4326':
        epsg = 32600
        if latitude < 0.0:
            epsg += 100
        epsg += get_utm_zone(longitude)
        return epsg
    else:
        epsg_4326 = QgsCoordinateReferenceSystem('EPSG:4326')
        transform = QgsCoordinateTransform(
            crs, epsg_4326, QgsProject.instance())
        geom = QgsGeometry.fromPointXY(QgsPointXY(longitude, latitude))
        geom.transform(transform)
        point = geom.asPoint()
        # The point is now in 4326, we can call the function again.
        return get_utm_epsg(point.x(), point.y())
Ejemplo n.º 12
0
    def test_expressionRequiresFormScope(self):

        res = list(QgsValueRelationFieldFormatter.expressionFormAttributes("current_value('ONE') AND current_value('TWO')"))
        res = sorted(res)
        self.assertEqual(res, ['ONE', 'TWO'])

        res = list(QgsValueRelationFieldFormatter.expressionFormVariables("@current_geometry"))
        self.assertEqual(res, ['current_geometry'])

        self.assertFalse(QgsValueRelationFieldFormatter.expressionRequiresFormScope(""))
        self.assertTrue(QgsValueRelationFieldFormatter.expressionRequiresFormScope("current_value('TWO')"))
        self.assertTrue(QgsValueRelationFieldFormatter.expressionRequiresFormScope("current_value ( 'TWO' )"))
        self.assertTrue(QgsValueRelationFieldFormatter.expressionRequiresFormScope("@current_geometry"))

        self.assertTrue(QgsValueRelationFieldFormatter.expressionIsUsable("", QgsFeature()))
        self.assertFalse(QgsValueRelationFieldFormatter.expressionIsUsable("@current_geometry", QgsFeature()))
        self.assertFalse(QgsValueRelationFieldFormatter.expressionIsUsable("current_value ( 'TWO' )", QgsFeature()))

        layer = QgsVectorLayer("none?field=pkid:integer&field=decoded:string",
                               "layer", "memory")
        self.assertTrue(layer.isValid())
        QgsProject.instance().addMapLayer(layer)
        f = QgsFeature(layer.fields())
        f.setAttributes([1, 'value'])
        point = QgsGeometry.fromPointXY(QgsPointXY(123, 456))
        f.setGeometry(point)
        self.assertTrue(QgsValueRelationFieldFormatter.expressionIsUsable("current_geometry", f))
        self.assertFalse(QgsValueRelationFieldFormatter.expressionIsUsable("current_value ( 'TWO' )", f))
        self.assertTrue(QgsValueRelationFieldFormatter.expressionIsUsable("current_value ( 'pkid' )", f))
        self.assertTrue(QgsValueRelationFieldFormatter.expressionIsUsable("@current_geometry current_value ( 'pkid' )", f))

        QgsProject.instance().removeMapLayer(layer.id())
Ejemplo n.º 13
0
    def testGetGeometry(self):
        idx = QgsSpatialIndex()
        idx2 = QgsSpatialIndex(QgsSpatialIndex.FlagStoreFeatureGeometries)
        fid = 0
        for y in range(5):
            for x in range(10, 15):
                ft = QgsFeature()
                ft.setId(fid)
                ft.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(x, y)))
                idx.insertFeature(ft)
                idx2.insertFeature(ft)
                fid += 1

        # not storing geometries, a keyerror should be raised
        with self.assertRaises(KeyError):
            idx.geometry(-100)
        with self.assertRaises(KeyError):
            idx.geometry(1)
        with self.assertRaises(KeyError):
            idx.geometry(2)
        with self.assertRaises(KeyError):
            idx.geometry(1000)

        self.assertEqual(idx2.geometry(1).asWkt(1), 'Point (11 0)')
        self.assertEqual(idx2.geometry(2).asWkt(1), 'Point (12 0)')
        with self.assertRaises(KeyError):
            idx2.geometry(-100)
        with self.assertRaises(KeyError):
            idx2.geometry(1000)
Ejemplo n.º 14
0
    def processAlgorithm(self, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.INPUT, context)
        pointCount = self.parameterAsDouble(parameters, self.POINTS_NUMBER, context)
        minDistance = self.parameterAsDouble(parameters, self.MIN_DISTANCE, context)

        bbox = source.sourceExtent()
        sourceIndex = QgsSpatialIndex(source, feedback)

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

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
                                               fields, QgsWkbTypes.Point, source.sourceCrs())

        nPoints = 0
        nIterations = 0
        maxIterations = pointCount * 200
        total = 100.0 / pointCount if pointCount else 1

        index = QgsSpatialIndex()
        points = dict()

        random.seed()

        while nIterations < maxIterations and nPoints < pointCount:
            if feedback.isCanceled():
                break

            rx = bbox.xMinimum() + bbox.width() * random.random()
            ry = bbox.yMinimum() + bbox.height() * random.random()

            p = QgsPointXY(rx, ry)
            geom = QgsGeometry.fromPointXY(p)
            ids = sourceIndex.intersects(geom.buffer(5, 5).boundingBox())
            if len(ids) > 0 and \
                    vector.checkMinDistance(p, index, minDistance, points):
                request = QgsFeatureRequest().setFilterFids(ids).setSubsetOfAttributes([])
                for f in source.getFeatures(request):
                    if feedback.isCanceled():
                        break

                    tmpGeom = f.geometry()
                    if geom.within(tmpGeom):
                        f = QgsFeature(nPoints)
                        f.initAttributes(1)
                        f.setFields(fields)
                        f.setAttribute('id', nPoints)
                        f.setGeometry(geom)
                        sink.addFeature(f, QgsFeatureSink.FastInsert)
                        index.insertFeature(f)
                        points[nPoints] = p
                        nPoints += 1
                        feedback.setProgress(int(nPoints * total))
            nIterations += 1

        if nPoints < pointCount:
            feedback.pushInfo(self.tr('Could not generate requested number of random points. '
                                      'Maximum number of attempts exceeded.'))

        return {self.OUTPUT: dest_id}
Ejemplo n.º 15
0
    def processAlgorithm(self, parameters, context, feedback):
        if parameters[self.INPUT] == parameters[self.HUBS]:
            raise QgsProcessingException(
                self.tr('Same layer given for both hubs and spokes'))

        point_source = self.parameterAsSource(parameters, self.INPUT, context)
        hub_source = self.parameterAsSource(parameters, self.HUBS, context)
        fieldName = self.parameterAsString(parameters, self.FIELD, context)

        units = self.UNITS[self.parameterAsEnum(parameters, self.UNIT, context)]

        fields = point_source.fields()
        fields.append(QgsField('HubName', QVariant.String))
        fields.append(QgsField('HubDist', QVariant.Double))

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
                                               fields, QgsWkbTypes.Point, point_source.sourceCrs())

        index = QgsSpatialIndex(hub_source.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([]).setDestinationCrs(point_source.sourceCrs(), context.transformContext())))

        distance = QgsDistanceArea()
        distance.setSourceCrs(point_source.sourceCrs(), context.transformContext())
        distance.setEllipsoid(context.project().ellipsoid())

        # Scan source points, find nearest hub, and write to output file
        features = point_source.getFeatures()
        total = 100.0 / point_source.featureCount() if point_source.featureCount() else 0
        for current, f in enumerate(features):
            if feedback.isCanceled():
                break

            if not f.hasGeometry():
                sink.addFeature(f, QgsFeatureSink.FastInsert)
                continue

            src = f.geometry().boundingBox().center()

            neighbors = index.nearestNeighbor(src, 1)
            ft = next(hub_source.getFeatures(QgsFeatureRequest().setFilterFid(neighbors[0]).setSubsetOfAttributes([fieldName], hub_source.fields()).setDestinationCrs(point_source.sourceCrs(), context.transformContext())))
            closest = ft.geometry().boundingBox().center()
            hubDist = distance.measureLine(src, closest)

            if units != self.LAYER_UNITS:
                hub_dist_in_desired_units = distance.convertLengthMeasurement(hubDist, units)
            else:
                hub_dist_in_desired_units = hubDist

            attributes = f.attributes()
            attributes.append(ft[fieldName])
            attributes.append(hub_dist_in_desired_units)

            feat = QgsFeature()
            feat.setAttributes(attributes)

            feat.setGeometry(QgsGeometry.fromPointXY(src))

            sink.addFeature(feat, QgsFeatureSink.FastInsert)
            feedback.setProgress(int(current * total))

        return {self.OUTPUT: dest_id}
Ejemplo n.º 16
0
 def test_SetGeometry(self):
     feat = QgsFeature()
     feat.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(123, 456)))
     myGeometry = feat.geometry()
     myExpectedGeometry = "!None"
     myMessage = '\nExpected: %s\nGot: %s' % (myExpectedGeometry, myGeometry)
     assert myGeometry is not None, myMessage
Ejemplo n.º 17
0
    def testIndex(self):
        idx = QgsSpatialIndex()
        fid = 0
        for y in range(5, 15, 5):
            for x in range(5, 25, 5):
                ft = QgsFeature()
                ft.setId(fid)
                ft.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(x, y)))
                idx.insertFeature(ft)
                fid += 1

        # intersection test
        rect = QgsRectangle(7.0, 3.0, 17.0, 13.0)
        fids = idx.intersects(rect)
        myExpectedValue = 4
        myValue = len(fids)
        myMessage = 'Expected: %s Got: %s' % (myExpectedValue, myValue)
        self.assertEqual(myValue, myExpectedValue, myMessage)
        fids.sort()
        myMessage = ('Expected: %s\nGot: %s\n' %
                     ([1, 2, 5, 6], fids))
        assert fids == [1, 2, 5, 6], myMessage

        # nearest neighbor test
        fids = idx.nearestNeighbor(QgsPointXY(8.75, 6.25), 3)
        myExpectedValue = 0
        myValue = len(fids)
        myMessage = 'Expected: %s Got: %s' % (myExpectedValue, myValue)

        fids.sort()
        myMessage = ('Expected: %s\nGot: %s\n' %
                     ([0, 1, 5], fids))
        assert fids == [0, 1, 5], myMessage
Ejemplo n.º 18
0
    def testSettingFeature(self):
        """ test that feature is set when item moves """
        a = QgsTextAnnotation()
        a.setFrameSizeMm(QSizeF(300 / 3.7795275, 200 / 3.7795275))
        a.setFrameOffsetFromReferencePointMm(QPointF(40 / 3.7795275, 50 / 3.7795275))
        a.setHasFixedMapPosition(True)
        a.setMapPosition(QgsPointXY(12, 34))
        a.setMapPositionCrs(QgsCoordinateReferenceSystem(4326))

        canvas = QgsMapCanvas()
        canvas.setDestinationCrs(QgsCoordinateReferenceSystem(4326))
        canvas.setFrameStyle(0)
        canvas.resize(600, 400)

        canvas.setExtent(QgsRectangle(10, 30, 20, 35))

        i = QgsMapCanvasAnnotationItem(a, canvas)  # NOQA

        layer = QgsVectorLayer("Point?crs=EPSG:4326&field=station:string&field=suburb:string",
                               'test', "memory")
        canvas.setLayers([layer])
        f = QgsFeature(layer.fields())
        f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(14, 31)))
        f.setValid(True)
        f.setAttributes(['hurstbridge', 'somewhere'])
        self.assertTrue(layer.dataProvider().addFeatures([f]))
        a.setMapLayer(layer)
        self.assertFalse(a.associatedFeature().isValid())

        a.setMapPosition(QgsPointXY(14, 31))
        self.assertTrue(a.associatedFeature().isValid())
        self.assertEqual(a.associatedFeature().attributes()[0], 'hurstbridge')

        a.setMapPosition(QgsPointXY(17, 31))
        self.assertFalse(a.associatedFeature().isValid())
Ejemplo n.º 19
0
    def writePoint(self, xy, gipodId, owner, description, startDateTime, endDateTime, importantHindrance, detail, cities=[], initiator=None, recurrencePattern=None):
        fet = QgsFeature(self.fields)
        fet['gipodId'] = gipodId
        fet['owner'] = owner
        fet['description'] = description
        if self.KML:
          fet['begin'] = startDateTime.split("T")[0]
          fet['end'] = endDateTime.split("T")[0]
          if importantHindrance: fet['icon'] = "http://api.gipod.vlaanderen.be/ws/v1/icon/workassignment?important=true"
          else: fet['icon'] = "http://api.gipod.vlaanderen.be/ws/v1/icon/workassignment?important=false"

        fet['beginDate'] = startDateTime
        fet['endDate'] = endDateTime
        fet['hinder'] = importantHindrance
        fet['link'] = detail
        fet['cities'] = ", ".join(cities)
        if initiator and self.manifestation:
          fet['intiatief'] = initiator
        if recurrencePattern and self.manifestation:
          fet['patroon'] = recurrencePattern
    
        prjPt = self._makeCRSpoint( xy )
        fet.setGeometry(QgsGeometry.fromPointXY(prjPt))
    
        self.gipodProvider.addFeatures([ fet ])
Ejemplo n.º 20
0
    def testAddZ(self):
        """Check adding z values to non z input."""
        input = QgsVectorLayer(
            'Point?crs=epsg:4326&field=name:string(20)',
            'test',
            'memory')

        self.assertTrue(input.isValid(), 'Provider not initialized')

        ft = QgsFeature()
        ft.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(10, 10)))
        myResult, myFeatures = input.dataProvider().addFeatures([ft])
        self.assertTrue(myResult)
        self.assertTrue(myFeatures)

        dest_file_name = os.path.join(str(QDir.tempPath()), 'add_z.geojson')
        options = QgsVectorFileWriter.SaveVectorOptions()
        options.overrideGeometryType = QgsWkbTypes.PointZ
        options.driverName = 'GeoJSON'
        write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat(
            input,
            dest_file_name,
            options)
        self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message)

        # Open result and check
        created_layer = QgsVectorLayer(dest_file_name, 'test', 'ogr')
        self.assertTrue(created_layer.isValid())
        f = next(created_layer.getFeatures(QgsFeatureRequest()))
        self.assertEqual(f.geometry().asWkt(), 'PointZ (10 10 0)')
Ejemplo n.º 21
0
 def test_CreateFeature(self):
     feat = QgsFeature()
     feat.initAttributes(1)
     feat.setAttribute(0, "text")
     feat.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(123, 456)))
     myId = feat.id()
     myExpectedId = 0
     myMessage = '\nExpected: %s\nGot: %s' % (myExpectedId, myId)
     assert myId == myExpectedId, myMessage
Ejemplo n.º 22
0
    def testCreateFeature(self):
        """ test creating a feature respecting defaults and constraints """
        layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer&field=flddbl:double",
                               "addfeat", "memory")
        # add a bunch of features
        f = QgsFeature()
        f.setAttributes(["test", 123, 1.0])
        f1 = QgsFeature(2)
        f1.setAttributes(["test_1", 124, 1.1])
        f2 = QgsFeature(3)
        f2.setAttributes(["test_2", 125, 2.4])
        f3 = QgsFeature(4)
        f3.setAttributes(["test_3", 126, 1.7])
        f4 = QgsFeature(5)
        f4.setAttributes(["superpig", 127, 0.8])
        self.assertTrue(layer.dataProvider().addFeatures([f, f1, f2, f3, f4]))

        # no layer
        self.assertFalse(QgsVectorLayerUtils.createFeature(None).isValid())

        # basic tests
        f = QgsVectorLayerUtils.createFeature(layer)
        self.assertTrue(f.isValid())
        self.assertEqual(f.fields(), layer.fields())
        self.assertFalse(f.hasGeometry())
        self.assertEqual(f.attributes(), [NULL, NULL, NULL])

        # set geometry
        g = QgsGeometry.fromPointXY(QgsPointXY(100, 200))
        f = QgsVectorLayerUtils.createFeature(layer, g)
        self.assertTrue(f.hasGeometry())
        self.assertEqual(f.geometry().asWkt(), g.asWkt())

        # using attribute map
        f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'a', 2: 6.0})
        self.assertEqual(f.attributes(), ['a', NULL, 6.0])

        # layer with default value expression
        layer.setDefaultValueDefinition(2, QgsDefaultValue('3*4'))
        f = QgsVectorLayerUtils.createFeature(layer)
        self.assertEqual(f.attributes(), [NULL, NULL, 12.0])
        # we expect the default value expression to take precedence over the attribute map
        f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'a', 2: 6.0})
        self.assertEqual(f.attributes(), ['a', NULL, 12.0])
        # layer with default value expression based on geometry
        layer.setDefaultValueDefinition(2, QgsDefaultValue('3*$x'))
        f = QgsVectorLayerUtils.createFeature(layer, g)
        self.assertEqual(f.attributes(), [NULL, NULL, 300.0])
        layer.setDefaultValueDefinition(2, QgsDefaultValue(None))

        # test with violated unique constraints
        layer.setFieldConstraint(1, QgsFieldConstraints.ConstraintUnique)
        f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'test_1', 1: 123})
        self.assertEqual(f.attributes(), ['test_1', 128, NULL])
        layer.setFieldConstraint(0, QgsFieldConstraints.ConstraintUnique)
        f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'test_1', 1: 123})
        self.assertEqual(f.attributes(), ['test_4', 128, NULL])
Ejemplo n.º 23
0
    def testAdd(self):
        self.layer.startEditing()

        f = QgsFeature()
        f.setAttributes(["test", 8])
        f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100, 200)))
        self.layer.addFeature(f)

        self.assertEqual(self.am.rowCount(), 11)
Ejemplo n.º 24
0
def createReferencedLayer():
    layer = QgsVectorLayer(
        "Point?field=x:string&field=y:integer&field=z:integer",
        "referencedlayer", "memory")
    pr = layer.dataProvider()
    f1 = QgsFeature()
    f1.setFields(layer.fields())
    f1.setAttributes(["foo", 123, 321])
    f1.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(1, 1)))
    f2 = QgsFeature()
    f2.setFields(layer.fields())
    f2.setAttributes(["bar", 456, 654])
    f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(2, 2)))
    f3 = QgsFeature()
    f3.setFields(layer.fields())
    f3.setAttributes(["foobar'bar", 789, 554])
    f3.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(2, 3)))
    assert pr.addFeatures([f1, f2, f3])
    return layer
Ejemplo n.º 25
0
 def createLayerWithOnePoint(self):
     self.layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer",
                                 "addfeat", "memory")
     pr = self.layer.dataProvider()
     f = QgsFeature()
     f.setAttributes(["test", 123])
     f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100, 200)))
     self.assertTrue(pr.addFeatures([f]))
     self.assertEqual(self.layer.featureCount(), 1)
     return self.layer
Ejemplo n.º 26
0
 def setUp(self):
     """
     create a layer with one feature
     """
     self.layer = QgsVectorLayer("Point?crs=EPSG:21781&field=fldtxt:string&field=fldint:integer",
                                 "addfeat", "memory")
     pr = self.layer.dataProvider()  # NOQA
     f = QgsFeature()
     f.setAttributes(["Hello World", 123])
     f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(600000, 200000)))
Ejemplo n.º 27
0
def createLayerWithOnePoint():
    layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer",
                           "addfeat", "memory")
    pr = layer.dataProvider()
    f = QgsFeature()
    f.setAttributes(["test", 123])
    f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100, 200)))
    assert pr.addFeatures([f])
    assert layer.featureCount() == 1
    return layer
Ejemplo n.º 28
0
    def save_sample_points(self, pointData, profileName="", layername="elevation_samples", saveToFile=None, sender=None):
        ''
        attributes = [ QgsField("name", QVariant.String),
          QgsField("Dist", QVariant.Double), QgsField("z_taw", QVariant.Double) ]
    
        if not QgsProject.instance().mapLayer(self.sampleslayerid) :
            self.sampleslayer = QgsVectorLayer("Point", layername, "memory")
            self.samplesProvider = self.sampleslayer.dataProvider()
            self.samplesProvider.addAttributes(attributes)
            self.sampleslayer.updateFields()    
        
        fields= self.sampleslayer.fields()
        
        for point in pointData:
            #create the geometry
            pt = QgsPointXY( point[1], point[2] )

            # add a feature
            fet = QgsFeature(fields)

            #set geometry
            fromCrs = QgsCoordinateReferenceSystem(4326)
            xform = QgsCoordinateTransform( fromCrs, self.sampleslayer.crs(), QgsProject.instance() )
            prjPt = xform.transform( pt )
            fet.setGeometry(QgsGeometry.fromPointXY(prjPt))
      
            fet['name'] = profileName
            fet['dist'] =  point[0]
            if  point[3] > -9999 : fet['z_taw'] =  point[3]            
      
            self.samplesProvider.addFeatures([ fet ])
            self.sampleslayer.updateExtents()
    
        if saveToFile and not QgsProject.instance().mapLayer(self.sampleslayerid):
            save = self._saveToFile( sender, os.path.join( self.startFolder, layername))
            if save:
              fpath, flType = save
              error, msg = QgsVectorFileWriter.writeAsVectorFormat(layer=self.sampleslayer, 
                                              fileName=fpath, fileEncoding="utf-8", driverName=flType ) 
              if error == QgsVectorFileWriter.NoError:
                  self.sampleslayer = QgsVectorLayer( fpath , layername, "ogr")
                  self.samplesProvider = self.sampleslayer.dataProvider()
              else: 
                  del self.sampleslayer, self.samplesProvider 
                  return 
            else:
              del self.sampleslayer, self.samplesProvider 
              return 

        # add layer if not already
        print( QgsProject.instance().addMapLayer(self.sampleslayer) )

        # store layer id and refresh
        self.sampleslayerid = self.sampleslayer.id()
        self.iface.mapCanvas().refresh()
Ejemplo n.º 29
0
    def testChangeAttributeValues(self):
        # test changing attributes values from an edit buffer

        # make a layer with two features
        layer = createEmptyLayer()
        self.assertTrue(layer.startEditing())

        # add two features
        f1 = QgsFeature(layer.fields(), 1)
        f1.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(1, 2)))
        f1.setAttributes(["test", 123])
        self.assertTrue(layer.addFeature(f1))

        f2 = QgsFeature(layer.fields(), 2)
        f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(2, 4)))
        f2.setAttributes(["test2", 246])
        self.assertTrue(layer.addFeature(f2))

        layer.commitChanges()
        layer.startEditing()

        self.assertEqual(layer.editBuffer().changedAttributeValues(), {})
        self.assertFalse(layer.editBuffer().isFeatureAttributesChanged(1))
        self.assertFalse(layer.editBuffer().isFeatureAttributesChanged(2))

        # change attribute values
        layer.changeAttributeValue(1, 0, 'a')

        # test contents of buffer
        self.assertEqual(list(layer.editBuffer().changedAttributeValues().keys()), [1])
        self.assertEqual(layer.editBuffer().changedAttributeValues()[1], {0: 'a'})
        self.assertTrue(layer.editBuffer().isFeatureAttributesChanged(1))
        self.assertFalse(layer.editBuffer().isFeatureAttributesChanged(2))

        layer.changeAttributeValue(2, 1, 5)

        # test contents of buffer
        self.assertEqual(set(layer.editBuffer().changedAttributeValues().keys()), set([1, 2]))
        self.assertEqual(layer.editBuffer().changedAttributeValues()[1], {0: 'a'})
        self.assertEqual(layer.editBuffer().changedAttributeValues()[2], {1: 5})
        self.assertTrue(layer.editBuffer().isFeatureAttributesChanged(1))
        self.assertTrue(layer.editBuffer().isFeatureAttributesChanged(2))
Ejemplo n.º 30
0
    def processAlgorithm(self, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.INPUT, context)
        strategy = self.parameterAsEnum(parameters, self.STRATEGY, context)
        minDistance = self.parameterAsDouble(parameters, self.MIN_DISTANCE,
                                             context)

        expression = QgsExpression(
            self.parameterAsString(parameters, self.EXPRESSION, context))
        if expression.hasParserError():
            raise ProcessingException(expression.parserErrorString())

        expressionContext = self.createExpressionContext(parameters, context)
        if not expression.prepare(expressionContext):
            raise ProcessingException(
                self.tr('Evaluation error: {0}').format(
                    expression.evalErrorString()))

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

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT,
                                               context, fields,
                                               QgsWkbTypes.Point,
                                               source.sourceCrs())

        da = QgsDistanceArea()
        da.setSourceCrs(source.sourceCrs(), context.transformContext())
        da.setEllipsoid(context.project().ellipsoid())

        total = 100.0 / source.featureCount() if source.featureCount() else 0
        for current, f in enumerate(source.getFeatures()):
            if feedback.isCanceled():
                break

            expressionContext.setFeature(f)
            value = expression.evaluate(expressionContext)
            if expression.hasEvalError():
                feedback.pushInfo(
                    self.tr('Evaluation error for feature ID {}: {}').format(
                        f.id(), expression.evalErrorString()))
                continue

            fGeom = f.geometry()
            bbox = fGeom.boundingBox()
            if strategy == 0:
                pointCount = int(value)
            else:
                pointCount = int(round(value * da.measureArea(fGeom)))

            if pointCount == 0:
                feedback.pushInfo(
                    "Skip feature {} as number of points for it is 0.")
                continue

            index = QgsSpatialIndex()
            points = dict()

            nPoints = 0
            nIterations = 0
            maxIterations = pointCount * 200
            total = 100.0 / pointCount if pointCount else 1

            random.seed()

            while nIterations < maxIterations and nPoints < pointCount:
                if feedback.isCanceled():
                    break

                rx = bbox.xMinimum() + bbox.width() * random.random()
                ry = bbox.yMinimum() + bbox.height() * random.random()

                p = QgsPointXY(rx, ry)
                geom = QgsGeometry.fromPointXY(p)
                if geom.within(fGeom) and \
                        vector.checkMinDistance(p, index, minDistance, points):
                    f = QgsFeature(nPoints)
                    f.initAttributes(1)
                    f.setFields(fields)
                    f.setAttribute('id', nPoints)
                    f.setGeometry(geom)
                    sink.addFeature(f, QgsFeatureSink.FastInsert)
                    index.insertFeature(f)
                    points[nPoints] = p
                    nPoints += 1
                    feedback.setProgress(int(nPoints * total))
                nIterations += 1

            if nPoints < pointCount:
                feedback.pushInfo(
                    self.tr('Could not generate requested number of random '
                            'points. Maximum number of attempts exceeded.'))

            feedback.setProgress(0)

        return {self.OUTPUT: dest_id}
Ejemplo n.º 31
0
def add_point_to_layer(writer, point, attributes):
    geometry = QgsGeometry.fromPointXY(point)
    feature = QgsFeature()
    feature.setAttributes(attributes)
    feature.setGeometry(geometry)
    writer.addFeature(feature)
Ejemplo n.º 32
0
    def processAlgorithm(self, parameters, context, feedback):
        uavImage = self.parameterAsRasterLayer(parameters, self.INPUT, context)
        feedback.pushInfo(self.tr('Processing image source: ')+self.tr(uavImage.source()))

        sourceCRS = self.parameterAsCrs(parameters, self.SOURCE_CRS, context)
        if sourceCRS is None or not sourceCRS.isValid():
            sourceCRS = uavImage.crs()

        destinationCRS = self.parameterAsCrs(parameters, self.DESTINATION_CRS, context)
        if destinationCRS is None or not destinationCRS.isValid():
            feedback.pushInfo(self.tr('Getting destination CRS from source image'))
            destinationCRS = sourceCRS

        feedback.pushInfo(self.tr('Source CRS is: ')+self.tr(sourceCRS.authid()))
        feedback.pushInfo(self.tr('Destination CRS is: ')+self.tr(destinationCRS.authid()))

        # set fields for footprint and nadir vectors
        fields = QgsFields()
        # fields.append(QgsField('gimball_pitch', QVariant.Double))
        # fields.append(QgsField('gimball_roll', QVariant.Double))
        # fields.append(QgsField('gimball_jaw', QVariant.Double))
        # fields.append(QgsField('relative_altitude', QVariant.Double))
        # fields.append(QgsField('image', QVariant.String))
        # fields.append(QgsField('camera_model', QVariant.String))
        # fields.append(QgsField('camera_vertical_FOV', QVariant.Double))
        # fields.append(QgsField('camera_horizontal_FOV', QVariant.Double))

        # (footprintSink, footprint_dest_id) = self.parameterAsSink(
        #     parameters,
        #     self.OUTPUT_FOOTPRINT,
        #     context,
        #     fields,
        #     QgsWkbTypes.Polygon,
        #     destinationCRS)
        # if footprintSink is None:
        #     raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT_FOOTPRINT))

        (nadirSink, nadir_dest_id) = self.parameterAsSink(
            parameters,
            self.OUTPUT_NADIR,
            context,
            fields,
            QgsWkbTypes.Point,
            destinationCRS)
        if nadirSink is None:
            raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT_NADIR))

        horizontalFOV = self.parameterAsDouble(parameters, self.HORIZONTAL_FOV, context)
        verticalFOV = self.parameterAsDouble(parameters, self.VERTICAL_FOV, context)
        useImageRatio = self.parameterAsBoolean(parameters, self.USE_IMAGE_RATIO_FOR_VERTICAL_FOV, context)
        verticalFOV_multiplier = self.parameterAsDouble(parameters, self.VERTICAL_FOV_MULTIPLIER, context)

        nadirToBottomOffset = self.parameterAsDouble(parameters, self.NADIR_TO_BOTTOM_OFFSET, context)
        nadirToupperOffset = self.parameterAsDouble(parameters, self.NADIR_TO_UPPPER_OFFSET, context)

        # extract exif and XMP data
        try:
            gdal.UseExceptions()
            dataFrame = gdal.Open(uavImage.source(), gdal.GA_ReadOnly)
            domains = dataFrame.GetMetadataDomainList()

            # get exif metadata
            exifTags = dataFrame.GetMetadata()
            for key, value in exifTags.items():
                #print(key, ':', value)
                pass

            # select metadata from XMP domain only
            droneMetadata = {}
            for domain in domains:
                metadata = dataFrame.GetMetadata(domain)

                # skip not relevant tags
                if isinstance(metadata, dict):
                    for key, value in metadata.items():
                        #print(domain, "--", key, ":", value)
                        pass

                # probably XMPs
                if isinstance(metadata, list):
                    if domain == 'xml:XMP':
                        # parse xml
                        root = ElementTree.XML(metadata[0])
                        xmldict = XmlDictConfig(root)

                        # skip first element containing only description and domain info
                        subdict = list(xmldict.values())[0]

                        # get XMP tags
                        subdict = list(subdict.values())[0]
                        # parse XMP stuffs removing head namespace in the key 
                        # e.g.
                        #    {http://www.dji.com/drone-dji/1.0/}AbsoluteAltitude
                        # become
                        #    AbsoluteAltitude
                        for key, value in subdict.items():
                            #print(domain, '--', key, value)
                            key = key.split('}')[1]
                            droneMetadata[key] = value

        except Exception as ex:
            raise QgsProcessingException(str(ex))
        
        # extract all important tagged information about the image

        # get image lat/lon that will be the coordinates of nadir point
        # converted to destination CRS
        lat = _convert_to_degress(exifTags['EXIF_GPSLatitude'])
        emisphere = exifTags['EXIF_GPSLatitudeRef']
        lon = _convert_to_degress(exifTags['EXIF_GPSLongitude'])
        lonReference = exifTags['EXIF_GPSLongitudeRef']

        if emisphere == 'S':
            lat = -lat
        if lonReference == 'W':
            lon = -lon

        exifDateTime = exifTags['EXIF_DateTime']
        feedback.pushInfo("EXIF_DateTime: "+exifDateTime)

        exifImageWidth = exifTags['EXIF_PixelXDimension']
        exifImageLength = exifTags['EXIF_PixelYDimension']
        imageRatio = float(exifImageWidth)/float(exifImageLength)
        feedback.pushInfo("EXIF_PixelXDimension: "+exifImageWidth)
        feedback.pushInfo("EXIF_PixelYDimension: "+exifImageLength)
        feedback.pushInfo("Image ratio: "+str(imageRatio))

        # drone especific metadata
        droneMaker = exifTags['EXIF_Make']
        droneModel = exifTags['EXIF_Model']
        feedback.pushInfo("EXIF_Make: "+droneMaker)
        feedback.pushInfo("EXIF_Model: "+droneModel)

        # drone maker substitute XMP drone dictKey
        dictKey = droneMaker

        relativeAltitude = float(droneMetadata['RelativeAltitude'])
        feedback.pushInfo(self.tr("XMP {}:RelativeAltitude: ".format(dictKey))+str(relativeAltitude))

        gimballRoll = float(droneMetadata['GimbalRollDegree'])
        gimballPitch = float(droneMetadata['GimbalPitchDegree'])
        gimballYaw = float(droneMetadata['GimbalYawDegree'])
        feedback.pushInfo("XMP {}:GimbalRollDegree: ".format(dictKey)+str(gimballRoll))
        feedback.pushInfo("XMP {}:GimbalPitchDegree: ".format(dictKey)+str(gimballPitch))
        feedback.pushInfo("XMP {}:GimbalYawDegree: ".format(dictKey)+str(gimballYaw))

        flightRoll = float(droneMetadata['FlightRollDegree'])
        flightPitch = float(droneMetadata['FlightPitchDegree'])
        flightYaw = float(droneMetadata['FlightYawDegree'])
        feedback.pushInfo("XMP {}:FlightRollDegree: ".format(dictKey)+str(flightRoll))
        feedback.pushInfo("XMP {}:FlightPitchDegree: ".format(dictKey)+str(flightPitch))
        feedback.pushInfo("XMP {}:FlightYawDegree: ".format(dictKey)+str(flightYaw))

        feedback.pushInfo(self.tr("Horizontal FOV: ")+str(horizontalFOV))
        if useImageRatio:
            verticalFOV = (horizontalFOV/imageRatio)*verticalFOV_multiplier
            feedback.pushInfo(self.tr("Vertical FOV basing on image ratio: ")+str(verticalFOV))
        else:
            feedback.pushInfo(self.tr("Vertical FOV: ")+str(verticalFOV))

        # do calculation inspired by:
        # https://photo.stackexchange.com/questions/56596/how-do-i-calculate-the-ground-footprint-of-an-aerial-camera
        # distance of the nearest point to nadir (bottom distance)
        bottomDistance = relativeAltitude*(math.tan(math.radians(90 - gimballPitch - 0.5*verticalFOV)))
        # distance of the farest point to nadir (upper distance)
        upperDistance = relativeAltitude*(math.tan(math.radians(90 - gimballPitch + 0.5*verticalFOV)))

        feedback.pushInfo(self.tr("Northing (degree): ")+str(gimballYaw))
        feedback.pushInfo(self.tr("Nadir to bottom distance (metre): ")+str(bottomDistance))
        feedback.pushInfo(self.tr("Nadir to upper distance (metre): ")+str(upperDistance))

        # populate nadir layer
        droneLocation = QgsPoint(lon, lat)
        tr = QgsCoordinateTransform(sourceCRS, destinationCRS, QgsProject.instance())
        droneLocation.transform(tr)
        feedback.pushInfo(self.tr("Nadir coordinates (lon, lat): ")+'{}, {}'.format(droneLocation.x(), droneLocation.y()))

        nadirGeometry = QgsGeometry.fromPointXY(QgsPointXY(droneLocation.x(), droneLocation.y()))
        feature = QgsFeature()
        feature.setGeometry(nadirGeometry)
        nadirSink.addFeature(feature, QgsFeatureSink.FastInsert)

        # create a memory layer with nadir point to be input to "native:wedgebuffers" algorithm
        # it's not possible to use directly the FeatureSink becaseu can't be accepted by processing.run.
        # the reason is that a generic sink can be also NOT a layer but a more generic sink where features
        # can't be recovered.
        tempNadirLayer = QgsVectorLayer('Point?crs={}'.format(destinationCRS.authid()), 'tempNadirLayer', 'memory' )
        provider = tempNadirLayer.dataProvider()
        feature = QgsFeature()
        feature.setGeometry(nadirGeometry)
        provider.addFeatures([feature])

        # create polygon using wedge buffer processign algorithm
        parameters = {
            'INPUT': tempNadirLayer,
            'AZIMUTH': gimballYaw,
            'WIDTH': horizontalFOV,
            'OUTER_RADIUS': abs(bottomDistance) + nadirToBottomOffset,
            'INNER_RADIUS': abs(upperDistance) + nadirToupperOffset,
            'OUTPUT': parameters[self.OUTPUT_FOOTPRINT]
        }
        wedge_buffer_result = processing.run("native:wedgebuffers", 
                                            parameters,
                                            is_child_algorithm=True,
                                            context = context,
                                            feedback = feedback)

        # Return the results
        results = {
            self.OUTPUT_FOOTPRINT: wedge_buffer_result['OUTPUT'],
            self.OUTPUT_NADIR: nadir_dest_id,
        }
        return results
Ejemplo n.º 33
0
    def processAlgorithm(self, parameters, context, feedback):
        if parameters[self.INPUT] == parameters[self.HUBS]:
            raise QgsProcessingException(
                self.tr('Same layer given for both hubs and spokes'))

        point_source = self.parameterAsSource(parameters, self.INPUT, context)
        if point_source is None:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.INPUT))

        hub_source = self.parameterAsSource(parameters, self.HUBS, context)
        if hub_source is None:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.HUBS))

        fieldName = self.parameterAsString(parameters, self.FIELD, context)

        units = self.UNITS[self.parameterAsEnum(parameters, self.UNIT,
                                                context)]

        fields = point_source.fields()
        fields.append(QgsField('HubName', QVariant.String))
        fields.append(QgsField('HubDist', QVariant.Double))

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT,
                                               context, fields,
                                               QgsWkbTypes.Point,
                                               point_source.sourceCrs())
        if sink is None:
            raise QgsProcessingException(
                self.invalidSinkError(parameters, self.OUTPUT))

        index = QgsSpatialIndex(
            hub_source.getFeatures(QgsFeatureRequest().setSubsetOfAttributes(
                []).setDestinationCrs(point_source.sourceCrs(),
                                      context.transformContext())))

        distance = QgsDistanceArea()
        distance.setSourceCrs(point_source.sourceCrs(),
                              context.transformContext())
        distance.setEllipsoid(context.project().ellipsoid())

        # Scan source points, find nearest hub, and write to output file
        features = point_source.getFeatures()
        total = 100.0 / point_source.featureCount(
        ) if point_source.featureCount() else 0
        for current, f in enumerate(features):
            if feedback.isCanceled():
                break

            if not f.hasGeometry():
                sink.addFeature(f, QgsFeatureSink.FastInsert)
                continue

            src = f.geometry().boundingBox().center()

            neighbors = index.nearestNeighbor(src, 1)
            ft = next(
                hub_source.getFeatures(QgsFeatureRequest().setFilterFid(
                    neighbors[0]).setSubsetOfAttributes(
                        [fieldName], hub_source.fields()).setDestinationCrs(
                            point_source.sourceCrs(),
                            context.transformContext())))
            closest = ft.geometry().boundingBox().center()
            hubDist = distance.measureLine(src, closest)

            if units != self.LAYER_UNITS:
                hub_dist_in_desired_units = distance.convertLengthMeasurement(
                    hubDist, units)
            else:
                hub_dist_in_desired_units = hubDist

            attributes = f.attributes()
            attributes.append(ft[fieldName])
            attributes.append(hub_dist_in_desired_units)

            feat = QgsFeature()
            feat.setAttributes(attributes)

            feat.setGeometry(QgsGeometry.fromPointXY(src))

            sink.addFeature(feat, QgsFeatureSink.FastInsert)
            feedback.setProgress(int(current * total))

        return {self.OUTPUT: dest_id}
    def processAlgorithm(self, parameters, context, feedback):

        layer = self.parameterAsVectorLayer(parameters, self.Polygons, context)
        aMethod = parameters[self.Method]
        Threshold = parameters[self.T]
        mDict = {0: "Centerlines", 1: "All", 2: "Circles"}
        Method = mDict[aMethod]

        context.setInvalidGeometryCheck(QgsFeatureRequest.GeometryNoCheck)

        def densify(polyline,
                    interval):  #based on DensifyGeometriesInterval.py
            output = []
            for i in range(len(polyline) - 1):
                p1 = polyline[i]
                p2 = polyline[i + 1]
                output.append(p1)

                # Calculate necessary number of points between p1 and p2
                pointsNumber = math.sqrt(p1.sqrDist(p2)) / interval
                if pointsNumber > 1:
                    multiplier = 1.0 / float(pointsNumber)
                else:
                    multiplier = 1
                for j in range(int(pointsNumber)):
                    delta = multiplier * (j + 1)
                    x = p1.x() + delta * (p2.x() - p1.x())
                    y = p1.y() + delta * (p2.y() - p1.y())
                    output.append(QgsPointXY(x, y))
                    if j + 1 == pointsNumber:
                        break
            output.append(polyline[len(polyline) - 1])
            return output

        field_check = layer.fields().indexFromName('ID')

        if field_check == -1:
            pr = layer.dataProvider()
            pr.addAttributes([QgsField("ID", QVariant.Int)])
            layer.updateFields()

        layer.startEditing()
        for feature in layer.getFeatures():
            feature['ID'] = feature.id()
            layer.updateFeature(feature)
        layer.commitChanges()

        fet = QgsFeature()
        fields = QgsFields()
        fields.append(QgsField("ID", QVariant.Int))
        field_names = ['Distance', 'RDistance', 'SP_Dist', 'SP_RDist']

        for name in field_names:
            fields.append(QgsField(name, QVariant.Double))

        fet2 = QgsFeature(fields)
        (writer2, dest_id) = self.parameterAsSink(parameters, self.Output,
                                                  context, fields,
                                                  QgsWkbTypes.LineString,
                                                  layer.sourceCrs())

        outDir = os.path.join(tempfile.gettempdir(), 'GA')
        if not os.path.exists(outDir):
            os.mkdir(outDir)

        fname = ''.join(
            random.choice(string.ascii_lowercase) for i in range(10))
        infc = os.path.join(outDir, '%s.shp' % (fname))
        Densify_Interval = parameters[self.Densify]

        Precision, tol = 6, 1e-6

        keepNodes = set([])
        fields = QgsFields()
        fields.append(QgsField("ID", QVariant.Int))
        writer = QgsVectorFileWriter(
            infc, "CP1250", fields, QgsWkbTypes.Point, layer.sourceCrs(),
            "ESRI Shapefile")  #.shp requirement of SAGA

        feedback.pushInfo(
            QCoreApplication.translate('Update', 'Creating Vertices'))
        total = 100.0 / layer.featureCount()

        for enum, feature in enumerate(layer.getFeatures()):
            if total != -1:
                feedback.setProgress(int(enum * total))

            geomType = feature.geometry()
            geom = []
            if geomType.wkbType() == QgsWkbTypes.Polygon:
                polygon = geomType.asPolygon()
                if Densify_Interval == 0:
                    geom = chain(*polygon)
                else:
                    for ring in polygon:
                        geom.extend(densify(ring, Densify_Interval))
            else:
                polygons = geomType.asMultiPolygon()
                if Densify_Interval == 0:
                    geom = chain(*chain(*polygons))
                else:
                    for poly in polygons:
                        p = []
                        for ring in poly:
                            p.extend(densify(ring, Densify_Interval))
                        geom.extend(p)
            for points in geom:
                if (round(points.x(),
                          Precision), round(points.y(),
                                            Precision)) not in keepNodes:
                    pnt = QgsGeometry.fromPointXY(
                        QgsPointXY(points.x(), points.y()))
                    fet.setGeometry(pnt)
                    fet.setAttributes([feature['ID']])
                    writer.addFeature(fet)
                    keepNodes.update([(round(points.x(), Precision),
                                       round(points.y(), Precision))])

        feedback.pushInfo(
            QCoreApplication.translate('Update', 'Creating Voronoi Polygons'))
        del writer

        tempVP = os.path.join(outDir, 'VL.shp')  #.shp requirement of SAGA

        param = {'POINTS': infc, 'POLYGONS': tempVP, 'FRAME': 10.0}
        Voronoi = st.run("saga:thiessenpolygons",
                         param,
                         context=context,
                         feedback=feedback)

        del keepNodes
        edges = {}

        feedback.pushInfo(
            QCoreApplication.translate('Update', 'Calculating Edges'))

        param = {'INPUT': Voronoi['POLYGONS'], 'OUTPUT': 'memory:'}
        lines = st.run("qgis:polygonstolines",
                       param,
                       context=context,
                       feedback=feedback)

        param = {'INPUT': lines['OUTPUT'], 'OUTPUT': 'memory:'}
        exploded = st.run("native:explodelines",
                          param,
                          context=context,
                          feedback=feedback)
        param = {
            'INPUT': exploded['OUTPUT'],
            'PREDICATE': 6,
            'INTERSECT': layer,
            'METHOD': 0
        }
        st.run("native:selectbylocation",
               param,
               context=context,
               feedback=feedback)
        total = 100.0 / exploded['OUTPUT'].selectedFeatureCount()

        for enum, feature in enumerate(exploded['OUTPUT'].selectedFeatures()):
            try:
                if total != -1:
                    feedback.setProgress(int(enum * total))
                part = feature.geometry().asPolyline()
                startx = None
                for point in part:
                    if startx == None:
                        startx, starty = (round(point.x(), Precision),
                                          round(point.y(), Precision))
                        continue
                    endx, endy = (round(point.x(), Precision),
                                  round(point.y(), Precision))
                    geom = QgsGeometry.fromPolylineXY(
                        [QgsPointXY(startx, starty),
                         QgsPointXY(endx, endy)])
                    ID = feature['ID']
                    Length = geom.length()
                    if Length > tol:
                        if ID in edges:
                            edges[ID].add_edge((startx, starty), (endx, endy),
                                               weight=Length)
                        else:
                            Graph = nx.Graph()
                            Graph.add_edge((startx, starty), (endx, endy),
                                           weight=Length)
                            edges[ID] = Graph
                    startx, starty = endx, endy

            except Exception as e:
                feedback.reportError(
                    QCoreApplication.translate('Error', '%s' % (e)))

        feedback.pushInfo(
            QCoreApplication.translate(
                'Update', 'Calculating %s Centerlines' % (len(edges))))

        if edges:
            total = 100.0 / len(edges)
            for enum, FID in enumerate(edges):

                feedback.setProgress(int(enum * total))
                G = edges[FID]
                G = max(nx.connected_component_subgraphs(G),
                        key=len)  #Largest Connected Graph
                try:
                    if Threshold > 0:
                        Threshold = int(Threshold)
                        G2 = G.copy()
                        G3 = G.copy()
                        for n in range(int(Threshold)):
                            degree = G2.degree()
                            removeNodes = [k for k, v in degree if v == 1]
                            G2.remove_nodes_from(removeNodes)

                        degree = G2.degree()
                        if len(G2) < 2:
                            feedback.reportError(
                                QCoreApplication.translate(
                                    'Update',
                                    'No centerline found after trimming dangles for polygon ID %s - skipping'
                                    % (FID)))
                            continue

                        endPoints = [k for k, v in degree if v == 1]

                        G3.remove_edges_from(G2.edges)

                        for source in endPoints:
                            length, path = nx.single_source_dijkstra(
                                G3, source, weight='weight')
                            Index = max(length, key=length.get)
                            G2.add_path(path[Index])

                        del G3

                        source = list(
                            G2.nodes())[0]  #Get length along all paths
                        for n in range(2):
                            length, path = nx.single_source_dijkstra(
                                G, source, weight='weight')
                            Index = max(length, key=length.get)
                            source = path[Index][-1]
                        length2, path2 = nx.single_source_dijkstra(
                            G, source, weight='weight')

                        for p in G2.edges:
                            points = []
                            points.append(QgsPointXY(p[0][0], p[0][1]))
                            points.append(QgsPointXY(p[1][0], p[1][1]))

                            D = max([
                                length[(p[0][0], p[0][1])],
                                length[(p[1][0], p[1][1])]
                            ])
                            D2 = max([
                                length2[(p[0][0], p[0][1])],
                                length2[(p[1][0], p[1][1])]
                            ])

                            dx = path[Index][0][0] - p[1][0]
                            dy = path[Index][0][1] - p[1][1]
                            dx2 = path[Index][0][0] - p[0][0]
                            dy2 = path[Index][0][1] - p[0][1]
                            SP = max([
                                math.sqrt((dx**2) + (dy**2)),
                                math.sqrt((dx2**2) + (dy2**2))
                            ])

                            dx = path[Index][-1][0] - p[1][0]
                            dy = path[Index][-1][1] - p[1][1]
                            dx2 = path[Index][-1][0] - p[0][0]
                            dy2 = path[Index][-1][1] - p[0][1]
                            SP2 = max([
                                math.sqrt((dx**2) + (dy**2)),
                                math.sqrt((dx2**2) + (dy2**2))
                            ])

                            fet2.setGeometry(
                                QgsGeometry.fromPolylineXY(points))
                            fet2.setAttributes([FID, D, D2, SP, SP2])
                            writer2.addFeature(fet2)

                        del G2

                    elif Method == 'All':

                        curLen = 0
                        G2 = G.copy()
                        while len(G2) != curLen:
                            curLen = len(G2)
                            degree = G2.degree()
                            removeNodes = [k for k, v in degree if v == 1]
                            G2.remove_nodes_from(removeNodes)

                        source = list(G.nodes())[0]
                        for n in range(2):
                            length, path = nx.single_source_dijkstra(
                                G, source, weight='weight')
                            Index = max(length, key=length.get)
                            source = path[Index][-1]

                        G2.add_path(path[Index])

                        source = list(
                            G2.nodes())[0]  #Get length along all paths
                        for n in range(2):
                            length, path = nx.single_source_dijkstra(
                                G, source, weight='weight')
                            Index = max(length, key=length.get)
                            source = path[Index][-1]
                        length2, path2 = nx.single_source_dijkstra(
                            G, source, weight='weight')

                        for p in G2.edges:
                            points = []
                            points.append(QgsPointXY(p[0][0], p[0][1]))
                            points.append(QgsPointXY(p[1][0], p[1][1]))

                            D = max([
                                length[(p[0][0], p[0][1])],
                                length[(p[1][0], p[1][1])]
                            ])
                            D2 = max([
                                length2[(p[0][0], p[0][1])],
                                length2[(p[1][0], p[1][1])]
                            ])

                            dx = path[Index][0][0] - p[1][0]
                            dy = path[Index][0][1] - p[1][1]
                            dx2 = path[Index][0][0] - p[0][0]
                            dy2 = path[Index][0][1] - p[0][1]
                            SP = max([
                                math.sqrt((dx**2) + (dy**2)),
                                math.sqrt((dx2**2) + (dy2**2))
                            ])

                            dx = path[Index][-1][0] - p[1][0]
                            dy = path[Index][-1][1] - p[1][1]
                            dx2 = path[Index][-1][0] - p[0][0]
                            dy2 = path[Index][-1][1] - p[0][1]
                            SP2 = max([
                                math.sqrt((dx**2) + (dy**2)),
                                math.sqrt((dx2**2) + (dy2**2))
                            ])

                            fet2.setGeometry(
                                QgsGeometry.fromPolylineXY(points))
                            fet2.setAttributes([FID, D, D2, SP, SP2])
                            writer2.addFeature(fet2)

                        del G2

                    elif Method == 'Circles':

                        curLen = 0
                        G2 = G.copy()
                        while len(G2) != curLen:
                            curLen = len(G2)
                            degree = G2.degree()
                            removeNodes = [k for k, v in degree if v == 1]
                            G2.remove_nodes_from(removeNodes)

                        for p in G2.edges:
                            points = []
                            points.append(QgsPointXY(p[0][0], p[0][1]))
                            points.append(QgsPointXY(p[1][0], p[1][1]))

                            fet2.setGeometry(
                                QgsGeometry.fromPolylineXY(points))
                            fet2.setAttributes([FID])
                            writer2.addFeature(fet2)

                        del G2

                    else:
                        source = list(G.nodes())[0]
                        for n in range(2):
                            length, path = nx.single_source_dijkstra(
                                G, source, weight='weight')
                            Index = max(length, key=length.get)
                            source = path[Index][-1]
                        length2, path2 = nx.single_source_dijkstra(
                            G, source, weight='weight')
                        sx = None
                        for p in path[Index]:
                            if sx == None:
                                sx, sy = p[0], p[1]
                                continue
                            ex, ey = p[0], p[1]
                            D = max([length[(sx, sy)], length[(ex, ey)]])
                            D2 = max([length2[(sx, sy)], length2[(ex, ey)]])
                            dx = path[Index][0][0] - ex
                            dy = path[Index][0][1] - ey
                            dx2 = path[Index][0][0] - sx
                            dy2 = path[Index][0][1] - sy
                            SP = max([
                                math.sqrt((dx**2) + (dy**2)),
                                math.sqrt((dx2**2) + (dy2**2))
                            ])

                            dx = path[Index][-1][0] - ex
                            dy = path[Index][-1][1] - ey
                            dx2 = path[Index][-1][0] - sx
                            dy2 = path[Index][-1][1] - sy
                            SP2 = max([
                                math.sqrt((dx**2) + (dy**2)),
                                math.sqrt((dx2**2) + (dy2**2))
                            ])

                            points = [QgsPointXY(sx, sy), QgsPointXY(ex, ey)]
                            fet2.setGeometry(
                                QgsGeometry.fromPolylineXY(points))
                            fet2.setAttributes([FID, D, D2, SP, SP2])
                            writer2.addFeature(fet2)
                            sx, sy = ex, ey

                except Exception:
                    feedback.reportError(
                        QCoreApplication.translate(
                            'Update',
                            'No centerline found for polygon ID %s - skipping'
                            % (FID)))
                    continue
                finally:
                    G.clear()

        del writer2, edges

        return {self.Output: dest_id}
Ejemplo n.º 35
0
    def run(self):

        global almacen
        #coloco el puntero arriba del todo
        QgsProject.instance().layerTreeRegistryBridge().setLayerInsertionPoint(
            QgsProject.instance().layerTreeRoot(), 0)

        #genero una lista con los sistemas de referencia
        misdatos = [["Etrs89 Zona30 (25830)", "25830"],
                    ["Etrs89 Zona29 (25829)", "25829"],
                    ["ED50 Zona30 (23030)", "23030"],
                    ["ED50_Zona29 (23029)", "23029"],
                    ["WGS84 geograficas sexagesimales(4326)", "4326"],
                    ["WGS84 geograficas centesimales(4326)", "4258"]]
        self.dlg.comboBox_src.clear()
        for element in misdatos:
            self.dlg.comboBox_src.addItem(element[0])
        """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

        #leo la cache
        rutacache = os.path.join(QgsApplication.qgisSettingsDirPath(),
                                 r"python\plugins\zoomSigmena\cache.txt")
        if os.path.isfile(rutacache) == True:
            filecache = open(rutacache, "r")
            filecacheleido = filecache.readlines()
            try:
                import ast
                almacen = ast.literal_eval((filecacheleido[0].replace(
                    '\n', '')).replace(" [[",
                                       "[[").replace("]] ",
                                                     "]]"))  #.split(','))
                cache_utm = int(almacen[0])
                cache_geo = int(almacen[1])
                cache_escala = almacen[2]

                print(cache_escala)
                print(almacen)
                #miscomarcas=(filecacheleido[3].replace('\n','')).strip('][').split(',') #convierto una str en una list
                #mismunicipios=ast.literal_eval((filecacheleido[4].replace('\n','')).replace(" [[","[[").replace("]] ","]]"))#.split(',')) #convierto una str en una list
                filecache.close()

            except:
                print("esta no encuentra el file cache")
            self.dlg.lineEdit_escala.setText(str(cache_escala))
            self.dlg.checkBox_utm.setChecked(cache_utm)
            self.dlg.checkBox_geo.setChecked(cache_geo)
        # show the dialog
        self.dlg.show()

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

            # Do something useful here - delete the line containing pass and
            # substitute with your code.

            def deg_to_dms(deg, type='lat'):
                decimals, number = math.modf(deg)
                d = int(number)
                m = int(decimals * 60)
                s = (deg - d - m / 60) * 3600.00
                compass = {'lat': ('N', 'S'), 'lon': ('E', 'W')}
                compass_str = compass[type][0 if d >= 0 else 1]
                return '{}º{}\'{:.2f}"{}'.format(abs(d), abs(m), abs(s),
                                                 compass_str)

            #saco de  aqui variables que estan en las cajitas
            src_seleccionado = self.dlg.comboBox_src.currentIndex()

            # Get the coordinates and scale factor from the dialog
            x = self.dlg.XX.text()  ##displayText()
            y = self.dlg.YY.text()  ##displayText()
            escala = self.dlg.lineEdit_escala.text()

            x = x.replace(',', '.')
            y = y.replace(',', '.')
            escala = int(escala.replace('.', ''))
            src = misdatos[int(src_seleccionado)][1]

            if src == "4326":
                latext = y
                longtext = x

                lag = float(latext.split()[0])
                lam = float(latext.split()[1])
                las = float(latext.split()[2])
                log = float(longtext.split()[0])
                lom = float(longtext.split()[1])
                los = float(longtext.split()[2])

                lon = -1 * (log + (lom / 60) + (los / 3600))
                lat = lag + (lam / 60) + (las / 3600)

                x = float(lon)
                y = float(lat)
                print(x)
                print(y)
                huso = 30
                destinoProj = pyproj.Proj(proj="utm",
                                          zone=huso,
                                          ellps="WGS84",
                                          units="m")
                origenProj = pyproj.Proj(proj='longlat',
                                         ellps='WGS84',
                                         datum='WGS84')
                UTM_X, UTM_Y = pyproj.transform(origenProj, destinoProj, lon,
                                                lat)

            if src == "4258":
                print("por el camino adecuado")
                lat = float(y)
                lonn = float(x)
                lon = -1.0 * lonn

                print(lat)
                print(lon)

                huso = 30
                destinoProj = pyproj.Proj(proj="utm",
                                          zone=huso,
                                          ellps="WGS84",
                                          units="m")
                origenProj = pyproj.Proj(proj='longlat',
                                         ellps='WGS84',
                                         datum='WGS84')
                UTM_X, UTM_Y = pyproj.transform(origenProj, destinoProj, lon,
                                                lat)
                print(UTM_X)
                print(UTM_Y)
                x = lon
                y = lat

            #creo una capa temporal con las coordenadas

            # create layer
            vl2 = QgsVectorLayer("Point?crs=EPSG:" + src, "Zoom", "memory")
            pr2 = vl2.dataProvider()

            vl2.startEditing()
            # add fields

            pr2.addAttributes([
                QgsField("x", QVariant.Double),
                QgsField("y", QVariant.Double),
                QgsField("xx", QVariant.String),
                QgsField("yy", QVariant.String),
                QgsField("xxx", QVariant.Double),
                QgsField("yyy", QVariant.Double)
            ])
            vl2.updateFields()
            # tell the vector layer to fetch changes from the provider

            #$add a feature
            fet = QgsFeature()
            print("punto")
            print(x)
            print(y)
            fet.setGeometry(
                QgsGeometry.fromPointXY(QgsPointXY(float(x), float(y))))
            if src == "25830":
                huso = 30
                origenProj = pyproj.Proj(proj="utm",
                                         zone=huso,
                                         ellps="WGS84",
                                         units="m")
                destinoProj = pyproj.Proj(proj='longlat',
                                          ellps='WGS84',
                                          datum='WGS84')
                xxx, yyy = pyproj.transform(origenProj, destinoProj, x, y)

                xx = (deg_to_dms(xxx, 'lon'))
                yy = (deg_to_dms(yyy))

            if src == "25829":
                huso = 29
                origenProj = pyproj.Proj(proj="utm",
                                         zone=huso,
                                         ellps="WGS84",
                                         units="m")
                destinoProj = pyproj.Proj(proj='longlat',
                                          ellps='WGS84',
                                          datum='WGS84')
                xxx, yyy = pyproj.transform(origenProj, destinoProj, x, y)

                xx = (deg_to_dms(xxx, 'lon'))
                yy = (deg_to_dms(yyy))

            if src == "23030":
                huso = 30
                origenProj = pyproj.Proj(proj="utm",
                                         zone=huso,
                                         ellps="intl",
                                         units="m")
                destinoProj = pyproj.Proj(proj='longlat',
                                          ellps='WGS84',
                                          datum='WGS84')
                xxx, yyy = pyproj.transform(origenProj, destinoProj, x, y)

                xx = (deg_to_dms(xxx, 'lon'))
                yy = (deg_to_dms(yyy))

            if src == "23029":
                huso = 29
                origenProj = pyproj.Proj(proj="utm",
                                         zone=huso,
                                         ellps="intl",
                                         units="m")
                destinoProj = pyproj.Proj(proj='longlat',
                                          ellps='WGS84',
                                          datum='WGS84')
                xxx, yyy = pyproj.transform(origenProj, destinoProj, x, y)

                xx = (deg_to_dms(xxx, 'lon'))
                yy = (deg_to_dms(yyy))

            #para que lo pase a utms en pantalla
            if src == "4326":
                x = int(UTM_X)
                y = int(UTM_Y)
                #xx=longtext
                #yy=latext
                huso = 30
                origenProj = pyproj.Proj(proj="utm",
                                         zone=huso,
                                         ellps="intl",
                                         units="m")
                destinoProj = pyproj.Proj(proj='longlat',
                                          ellps='WGS84',
                                          datum='WGS84')
                xxx, yyy = pyproj.transform(origenProj, destinoProj, x, y)
                xx = (deg_to_dms(xxx, 'lon'))
                yy = (deg_to_dms(yyy))
            #para que lo pase a utms en pantalla
            if src == "4258":
                x = int(UTM_X)
                y = int(UTM_Y)

                xxx = lon
                yyy = lat
                xx = (deg_to_dms(xxx, 'lon'))
                yy = (deg_to_dms(yyy))
            fet.setAttributes(
                [float(x),
                 float(y),
                 str(xx),
                 str(yy),
                 float(xxx),
                 float(yyy)])
            pr2.addFeatures([fet])

            #cambio la simbologia
            symbol = QgsMarkerSymbol.createSimple({
                'name': 'circle',
                'color': 'red',
                'size': '3',
            })
            vl2.renderer().setSymbol(symbol)

            # update layer's extent when new features have been added
            # because change of extent in provider is not propagated to the layer

            layer_settings = QgsPalLayerSettings()
            text_format = QgsTextFormat()

            text_format.setFont(QFont("Arial", 12))
            text_format.setSize(12)
            text_format.setColor(QColor("Orange"))

            layer_settings.setFormat(text_format)
            layer_settings.placement = 1
            layer_settings.xOffset = 0.0
            layer_settings.yOffset = 10.0
            mostrar = True
            if self.dlg.checkBox_utm.isChecked(
            ) and self.dlg.checkBox_geo.isChecked():
                layer_settings.fieldName = '''concat('X: ',"X",' Y: ',"Y",'\n','Lon: ',"xx",' Lat: ',"yy" )'''
                almacen = [1, 1]

            else:
                if self.dlg.checkBox_utm.isChecked():
                    layer_settings.fieldName = '''concat('X: ',"X",' Y: ',"Y" )'''
                    almacen = [1, 0]
                    print("caso1")
                if self.dlg.checkBox_geo.isChecked():
                    layer_settings.fieldName = '''concat('Lon: ',"xx",' Lat: ',"yy" )'''
                    almacen = [0, 1]
                    print("caso2")
                if not self.dlg.checkBox_utm.isChecked(
                ) and not self.dlg.checkBox_geo.isChecked():
                    mostrar = False
                    almacen = [0, 0]
                    print("caso3")
            print("almacen despues de etiquetar", almacen)
            layer_settings.isExpression = True

            print(mostrar)
            layer_settings.enabled = mostrar

            layer_settings = QgsVectorLayerSimpleLabeling(layer_settings)
            vl2.setLabelsEnabled(True)
            vl2.setLabeling(layer_settings)
            vl2.triggerRepaint()

            # update layer's extent when new features have been added
            # because change of extent in provider is not propagated to the layer
            vl2.updateExtents()
            vl2.commitChanges()
            vl2.updateExtents()
            canvas = self.iface.mapCanvas()
            canvas.setExtent(vl2.extent())

            crsSrc = QgsCoordinateReferenceSystem('EPSG:' + str(src))
            crsDest = QgsProject.instance().crs()

            if crsSrc != crsDest:

                xform = QgsCoordinateTransform(crsSrc, crsDest,
                                               QgsProject.instance())
                canvas.setExtent(xform.transform(vl2.extent()))

            self.iface.mapCanvas().zoomScale(escala)
            #self.limpiar_pressed()
            almacen.append(escala)
            #lo escribo en el txt, mavhacando lo que ya tenia
            f = open(rutacache, "w")
            escribir = str(almacen)
            f.write(escribir)
            f.close()
            print(almacen)
            QgsProject.instance().addMapLayer(vl2)
Ejemplo n.º 36
0
    def accept(self):
        try:
            distance = float(self.distLineEdit.text())
            azimuth = float(self.azimuthLineEdit.text())
            units = self.unitsComboBox.currentIndex(
            )  # 0 km, 1 m, 2 nm, 3 miles, 4 yards, 5 ft, 6 inches, 7 cm
            start = self.checkBox.isChecked()
        except:
            self.iface.messageBar().pushMessage(
                "",
                tr("Either distance or azimuth were invalid"),
                level=Qgis.Warning,
                duration=4)
            return
        layer = self.iface.activeLayer()
        if layer is None:
            self.iface.messageBar().pushMessage(
                "",
                tr("No point or line layer selected"),
                level=Qgis.Warning,
                duration=4)
            return

        measureFactor = conversionToMeters(units)

        distance = distance * measureFactor
        pt = self.pt
        destCRS = layer.crs()
        transform = QgsCoordinateTransform(epsg4326, destCRS,
                                           QgsProject.instance())
        if layer.wkbType() == QgsWkbTypes.Point:
            g = geod.Direct(pt.y(), pt.x(), azimuth, distance,
                            Geodesic.LATITUDE | Geodesic.LONGITUDE)
            if start:
                ptStart = transform.transform(self.pt.x(), self.pt.y())
                feat = QgsFeature(layer.fields())
                feat.setGeometry(QgsGeometry.fromPointXY(ptStart))
                layer.addFeature(feat)
            pt = transform.transform(g['lon2'], g['lat2'])
            feat = QgsFeature(layer.fields())
            feat.setGeometry(QgsGeometry.fromPointXY(pt))
            layer.addFeature(feat)
        else:  # It will either be a LineString or MultiLineString
            maxseglen = settings.maxSegLength * 1000.0  # Needs to be in meters
            maxSegments = settings.maxSegments
            l = geod.Line(pt.y(), pt.x(), azimuth)
            n = int(math.ceil(distance / maxseglen))
            if n > maxSegments:
                n = maxSegments
            seglen = distance / n
            pts = []
            for i in range(0, n + 1):
                s = seglen * i
                g = l.Position(
                    s, Geodesic.LATITUDE | Geodesic.LONGITUDE
                    | Geodesic.LONG_UNROLL)
                ptc = transform.transform(g['lon2'], g['lat2'])
                pts.append(ptc)
            feat = QgsFeature(layer.fields())
            if layer.wkbType() == QgsWkbTypes.LineString:
                feat.setGeometry(QgsGeometry.fromPolylineXY(pts))
            else:
                feat.setGeometry(QgsGeometry.fromMultiPolylineXY([pts]))
            layer.addFeatures([feat])

        layer.updateExtents()
        self.iface.mapCanvas().refresh()
        self.close()
Ejemplo n.º 37
0
    def create_project(self):
        self.project = self.project_manager.create_project(self.project_name)
        self.project_areas = None
        source_crs = self.area_layer.crs()
        target_crs = QgsCoordinateReferenceSystem(f'epsg:{self.epsg}')
        self.project_areas = Teilflaechen.features(project=self.project,
                                                   create=True)

        # remove z-values from imported areas (they might mess up the geometries
        # later)
        try:
            parameters = {
                'INPUT': self.area_layer,
                'DROP_Z_VALUES': True,
                'OUTPUT': 'memory:'
            }
            area_layer = processing.run('native:dropmzvalues',
                                        parameters)['OUTPUT']
        # native:dropmzvalues is not always available (e.g. in tests)
        except QgsProcessingException:
            area_layer = self.area_layer
        layer_features = list(area_layer.getFeatures())

        self.log(f'Neues Projekt angelegt im Ordner {self.project.path}')
        self.set_progress(10)

        trans_geoms = []

        self.log(f'Füge {len(layer_features)} Fläche(n) hinzu...')
        tr = QgsCoordinateTransform(source_crs, target_crs,
                                    QgsProject.instance())
        if not layer_features:
            raise Exception(
                'Es wurden keine Flächen im Eingangslayer gefunden')
        for area in layer_features:
            geom = area.geometry()
            geom.transform(tr)
            trans_geoms.append(geom)

        # gather additional information about areas

        basedata = self.project_manager.basedata
        ags_feats = get_ags(layer_features,
                            basedata,
                            source_crs=source_crs,
                            use_centroid=True)
        ags = [f.AGS for f in ags_feats]
        gem_names = [f.GEN for f in ags_feats]
        gem_types = [f.Gemeindetyp for f in ags_feats]
        if len(np.unique(ags)) > 1:
            raise Exception("Die Teilflächen liegen nicht in "
                            "der selben Gemeinde")
        project_ags = ags[0]

        centroids = [geom.centroid().asPoint() for geom in trans_geoms]
        xs = [centroid.x() for centroid in centroids]
        ys = [centroid.y() for centroid in centroids]
        project_centroid = QgsPointXY(np.mean(xs), np.mean(ys))

        max_dist = getattr(settings, 'MAX_AREA_DISTANCE', None)

        self.set_progress(33)

        self.log(f'Überprüfe die Flächenlage...')
        if max_dist is not None and len(layer_features) > 1:
            distances = []
            for i in range(len(layer_features)):
                for j in range(i):
                    dist = np.linalg.norm(
                        np.subtract((xs[i], ys[i]), (xs[j], ys[j])))
                    distances.append(dist)
            if distances and max(distances) > max_dist:
                raise Exception("Der Abstand zwischen den Schwerpunkten der "
                                "Teilflächen darf nicht größer "
                                "als {} m sein!".format(max_dist))
        self.set_progress(50)

        traffic_connectors = Connectors.features(project=self.project,
                                                 create=True)

        self.log(f'Berechne Projektrahmendaten...')
        # create areas and connections to roads
        now = datetime.now()
        for i, feature in enumerate(layer_features):
            area = self.project_areas.add(
                nutzungsart=Nutzungsart.UNDEFINIERT.value,
                name=f'Flaeche_{i+1}',
                validiert=0,
                aufsiedlungsdauer=1,
                beginn_nutzung=now.year,
                ags_bkg=ags[i],
                gemeinde_name=gem_names[i],
                gemeinde_typ=gem_types[i],
                geom=trans_geoms[i])
            traffic_connectors.add(id_teilflaeche=area.id,
                                   name_teilflaeche=area.name,
                                   geom=centroids[i])
        self.set_progress(50)

        # general project data
        project_frame = Projektrahmendaten.features(project=self.project,
                                                    create=True)
        local_versions = self.project_manager.local_versions(
            settings.basedata_path)
        # newest local version
        basedata_version = local_versions[0]
        project_frame.add(ags=ags[0],
                          gemeinde_name=gem_names[0],
                          gemeinde_typ=gem_types[0],
                          projekt_name=self.project.name,
                          geom=project_centroid,
                          datum=now.strftime("%d.%m.%Y"),
                          basisdaten_version=basedata_version['version'],
                          basisdaten_datum=basedata_version['date'])
        self.set_progress(60)

        # create selectable centers around the areas for the market competition
        # domain

        sk_radius = getattr(settings, 'PROJECT_RADIUS', 20000)
        self.log(
            f'Ermittle Gemeinden im Umkreis von {int(sk_radius/1000)} km...')

        workspace = basedata.get_workspace('Basisdaten_deutschland')
        vg_table = workspace.get_table('Verwaltungsgemeinschaften')
        buffer = QgsGeometry.fromPointXY(QgsPointXY(*project_centroid)).buffer(
            sk_radius, 20)
        vg_table.spatial_filter(buffer.asWkt())
        centers = Centers.features(project=self.project, create=True)
        rs_list = []
        for row in vg_table:
            centers.add(
                name=row['GEN'],
                rs=row['RS'],
                geom=row['geom'],
                # -1 indicates that it is a vg for selection and output only
                nutzerdefiniert=-1)
            rs_list.append(row['RS'])

        project_rs = None
        gem_table = workspace.get_table('bkg_gemeinden')
        for row in gem_table:
            cut_rs = row['RS'][:9]
            ags = row['AGS']
            if cut_rs in rs_list:
                if ags == project_ags:
                    project_rs = cut_rs
                centers.add(
                    name=row['GEN'],
                    rs=cut_rs,
                    ags=ags,
                    geom=row['geom'],
                    # 0 indicates gemeinden, for calculations only
                    nutzerdefiniert=0)

        # preselect the VG the project is in
        if project_rs:
            project_vg = centers.get(rs=project_rs, nutzerdefiniert=-1)
            project_vg.auswahl = -1
            project_vg.save()

        self.set_progress(100)

        return self.project
Ejemplo n.º 38
0
    def calculate_locally(self):
        if not self.sqi_setup_tab.use_custom.isChecked():
            QtWidgets.QMessageBox.critical(None, self.tr("Error"),
                                       self.tr("Due to the options you have chosen, this calculation must occur offline. You MUST select a custom land cover dataset."))
            return
            
        if len(self.sqi_setup_tab.use_custom_pm.layer_list) == 0:
            QtWidgets.QMessageBox.critical(None, self.tr("Error"),
                                       self.tr("You must add an parent material layer to your map before you can run the calculation."))
            return

        if len(self.sqi_setup_tab.use_custom_rock_frag.layer_list) == 0:
            QtWidgets.QMessageBox.critical(None, self.tr("Error"),
                                       self.tr("You must add a rock fragment layer to your map before you can run the calculation."))
            return
        
        if len(self.sqi_setup_tab.use_custom_texture.layer_list) == 0:
            QtWidgets.QMessageBox.critical(None, self.tr("Error"),
                                       self.tr("You must add a soil texture layer to your map before you can run the calculation."))
            return

        if len(self.sqi_setup_tab.use_custom_drainage.layer_list) == 0:
            QtWidgets.QMessageBox.critical(None, self.tr("Error"),
                                       self.tr("You must add a drainage layer to your map before you can run the calculation."))
            return

        # select the parent material, slope, soil texture, drainage and rock fragment datasets 
        pm_vrt = self.sqi_setup_tab.use_custom_pm.get_vrt()
        drainage_vrt = self.sqi_setup_tab.use_custom_drainage.get_vrt()
        texture_vrt = self.sqi_setup_tab.use_custom_texture.get_vrt()
        rock_frag_vrt = self.sqi_setup_tab.use_custom_rock_frag.get_vrt()

        soil_depth = self.sqi_setup_tab.use_depth.value()

        if self.aoi.calc_frac_overlap(QgsGeometry.fromRect(self.sqi_setup_tab.use_custom_pm.get_layer().extent())) < .99:
            QtWidgets.QMessageBox.critical(None, self.tr("Error"),
                                       self.tr("Area of interest is not entirely within the parent material layer."))
            return

        if self.aoi.calc_frac_overlap(QgsGeometry.fromRect(self.sqi_setup_tab.use_custom_drainage.get_layer().extent())) < .99:
            QtWidgets.QMessageBox.critical(None, self.tr("Error"),
                                       self.tr("Area of interest is not entirely within the drainage layer."))
            return
        if self.aoi.calc_frac_overlap(QgsGeometry.fromRect(self.sqi_setup_tab.use_custom_rock_frag.get_layer().extent())) < .99:
            QtWidgets.QMessageBox.critical(None, self.tr("Error"),
                                       self.tr("Area of interest is not entirely within the rock fragment layer."))
            return

        if self.aoi.calc_frac_overlap(QgsGeometry.fromRect(self.sqi_setup_tab.use_custom_texture.get_layer().extent())) < .99:
            QtWidgets.QMessageBox.critical(None, self.tr("Error"),
                                       self.tr("Area of interest is not entirely within the soil texture layer."))
            return

        out_f = self.get_save_raster()
        if not out_f:
            return

        self.close()

        crosses_180th, geojsons = self.aoi.bounding_box_gee_geojson()
        val = []
        n = 1

        if self.area_tab.area_fromfile.isChecked():
            for f in self.aoi.get_layer_wgs84().getFeatures():
                # Get an OGR geometry from the QGIS geometry
                geom = f.geometry()
                val.append(geom)
                n += 1

            # stringify json object 
            val_string = '{}'.format(json.loads(val[0].asJson()))

            # create ogr geometry
            val_geom = ogr.CreateGeometryFromJson(val_string)
            # simplify polygon to tolerance of 0.003
            val_geom_simplified = val_geom.Simplify(0.003)

            # fetch coordinates from json  
            coords= json.loads(val_geom_simplified.ExportToJson())['coordinates']
            geometries = {
                "coordinates":coords,
                "type":"Polygon"
            }
        elif self.area_tab.area_fromadmin.isChecked():
            geometries ={
                "coordinates":self.get_admin_poly_geojson()['geometry']['coordinates'][0],
                "type":"Polygon"
            }
        elif self.area_tab.area_frompoint.isChecked():
            point = QgsPointXY(float(self.area_tab.area_frompoint_point_x.text()), float(self.area_tab.area_frompoint_point_y.text()))
            crs_src = QgsCoordinateReferenceSystem(self.area_tab.canvas.mapSettings().destinationCrs().authid())
            point = QgsCoordinateTransform(crs_src, self.aoi.crs_dst, QgsProject.instance()).transform(point)
            geometries = json.loads(QgsGeometry.fromPointXY(point).asJson())

        # write aoi geometry to file for masking output
        aoi_geom = {
            "type": "FeatureCollection",
            "features": [
                {
                "type": "Feature",
                "properties": {},
                "geometry": geometries
                }
            ]
        }

        aoi_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data', 'aoi.geojson')
        with open(aoi_file, 'w') as filetowrite:
            filetowrite.write(json.dumps(aoi_geom))

        # Add the sqi layers to a VRT in case they don't match in resolution, 
        # and set proper output bounds
        sqi_files = [pm_vrt, texture_vrt, drainage_vrt, rock_frag_vrt]
        # in_vrt = tempfile.NamedTemporaryFile(suffix='.vrt').name
        sqi_vrts = []

        for i in range(len(sqi_files)):
            f = tempfile.NamedTemporaryFile(suffix='.vrt').name
            gdal.BuildVRT(f,
                        sqi_files[i], 
                        bandList=[i + 1],
                        resolution='highest', 
                        resampleAlg=gdal.GRA_NearestNeighbour,
                        outputBounds=self.aoi.get_aligned_output_bounds_deprecated(texture_vrt),
                        separate=True)

            sqi_vrts.append(f)

        slope_v = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data', 'slope.tif')

        if not os.path.exists(slope_v):
            slope_zip = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data', 'slope.zip')
            slope_unzip = ZipFile(slope_zip)
            slope_unzip.extractall(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data'))

            slope_unzip.close()
            log("Extracting slope file...")

        else:
            log("Slope.tif already exists")

        in_files = [slope_v]
        in_files.extend(sqi_vrts)
        in_vrt = tempfile.NamedTemporaryFile(suffix='.vrt').name
        log(u'Saving SQI input files to {}'.format(in_vrt))

        gdal.BuildVRT(in_vrt,
                        in_files, 
                        resolution='highest', 
                        resampleAlg=gdal.GRA_NearestNeighbour,
                        outputBounds=self.aoi.get_aligned_output_bounds_deprecated(texture_vrt),
                        separate=True)

        # sqi_band_nums = np.arange(len(lc_files)) + 6

        sqi_worker = StartWorker(SoilQualityWorker,
                                       'calculating soil quality index', soil_depth, in_vrt, 
                                       out_f )

        if not sqi_worker.success:
            QtWidgets.QMessageBox.critical(None, self.tr("Error"),
                                       self.tr("Error calculating soil quality index."), None)
            return

        band_info = [BandInfo("Soil Quality Index (cm deep)", add_to_map=True, metadata={'depth': soil_depth})]
        out_json = os.path.splitext(out_f)[0] + '.json'
        create_local_json_metadata(out_json, out_f, band_info)
        schema = BandInfoSchema()
        for band_number in range(len(band_info)):
            b = schema.dump(band_info[band_number])
            if b['add_to_map']:
                # The +1 is because band numbers start at 1, not zero
                add_layer(out_f, band_number + 1, b)
Ejemplo n.º 39
0
def create_points_at(startpoint, endpoint, distance, geom, fid, force, fo_fila,
                     divide):
    """Creating Points at coordinates along the line
    """
    # don't allow distance to be zero and loop endlessly
    if fo_fila:
        distance = 0

    if distance <= 0:
        distance = geom.length()

    length = geom.length()

    if length < endpoint:
        endpoint = length

    if divide > 0:
        length2 = length
        if startpoint > 0:
            length2 = length - startpoint
        if endpoint > 0:
            length2 = endpoint
        if startpoint > 0 and endpoint > 0:
            length2 = endpoint - startpoint
        distance = length2 / divide
        current_distance = distance
    else:
        current_distance = distance

    feats = []

    if endpoint > 0:
        length = endpoint

    # set the first point at startpoint
    point = geom.interpolate(startpoint)
    # convert 3D geometry to 2D geometry as OGR seems to have problems with this
    point = QgsGeometry.fromPointXY(point.asPoint())

    field_id = QgsField(name="id", type=QVariant.Int)
    field = QgsField(name="dist", type=QVariant.Double)
    fields = QgsFields()

    fields.append(field_id)
    fields.append(field)

    feature = QgsFeature(fields)
    feature['dist'] = startpoint
    feature['id'] = fid

    feature.setGeometry(point)
    feats.append(feature)

    while startpoint + current_distance <= length:
        # Get a point along the line at the current distance
        point = geom.interpolate(startpoint + current_distance)
        # Create a new QgsFeature and assign it the new geometry
        feature = QgsFeature(fields)
        feature['dist'] = (startpoint + current_distance)
        feature['id'] = fid
        feature.setGeometry(point)
        feats.append(feature)
        # Increase the distance
        current_distance = current_distance + distance

    # set the last point at endpoint if wanted
    if force is True:
        end = geom.length()
        point = geom.interpolate(end)
        feature = QgsFeature(fields)
        feature['dist'] = end
        feature['id'] = fid
        feature.setGeometry(point)
        feats.append(feature)
    return feats
Ejemplo n.º 40
0
    def calculate_on_GEE(self, method, biomass_data):
        self.close()

        crosses_180th, geojsons = self.aoi.bounding_box_gee_geojson()
        val = []
        n = 1

        if self.area_tab.area_fromfile.isChecked():
            for f in self.aoi.get_layer_wgs84().getFeatures():
                # Get an OGR geometry from the QGIS geometry
                geom = f.geometry()
                val.append(geom)
                n += 1

            # stringify json object
            val_string = '{}'.format(json.loads(val[0].asJson()))

            # create ogr geometry
            val_geom = ogr.CreateGeometryFromJson(val_string)
            # simplify polygon to tolerance of 0.003
            val_geom_simplified = val_geom.Simplify(0.003)

            # fetch coordinates from json
            coords = json.loads(
                val_geom_simplified.ExportToJson())['coordinates']
            geometries = json.dumps([{
                "coordinates": coords,
                "type": "Polygon"
            }])

        elif self.area_tab.area_fromadmin.isChecked():
            geometries = json.dumps([{
                "coordinates":
                self.get_admin_poly_geojson()['geometry']['coordinates'][0],
                "type":
                "Polygon"
            }])
        elif self.area_tab.area_frompoint.isChecked():
            point = QgsPointXY(
                float(self.area_tab.area_frompoint_point_x.text()),
                float(self.area_tab.area_frompoint_point_y.text()))
            crs_src = QgsCoordinateReferenceSystem(
                self.area_tab.canvas.mapSettings().destinationCrs().authid())
            point = QgsCoordinateTransform(
                crs_src, self.aoi.crs_dst,
                QgsProject.instance()).transform(point)
            geometries = json.dumps(
                json.loads(QgsGeometry.fromPointXY(point).asJson()))

        payload = {
            'year_start': self.hansen_bl_year.date().year(),
            'year_end': self.hansen_tg_year.date().year(),
            'fc_threshold':
            int(self.hansen_fc_threshold.text().replace('%', '')),
            'method': method,
            'biomass_data': biomass_data,
            #    'geojsons':json.dumps(geojsons),
            'geojsons': geometries,
            'crs': self.aoi.get_crs_dst_wkt(),
            'crosses_180th': crosses_180th,
            'task_name': self.options_tab.task_name.text(),
            'task_notes': self.options_tab.task_notes.toPlainText()
        }

        resp = run_script(get_script_slug('total-carbon'), payload)

        if resp:
            mb.pushMessage(
                QtWidgets.QApplication.translate("MISLAND", "Submitted"),
                QtWidgets.QApplication.translate(
                    "MISLAND",
                    "Total carbon submitted to Google Earth Engine."),
                level=0,
                duration=5)
        else:
            mb.pushMessage(
                QtWidgets.QApplication.translate("MISLAND", "Error"),
                QtWidgets.QApplication.translate(
                    "MISLAND",
                    "Unable to submit total carbon task to Google Earth Engine."
                ),
                level=0,
                duration=5)
Ejemplo n.º 41
0
    def testDateTimeWriteShapefile(self):
        """Check writing date and time fields to an ESRI shapefile."""
        ml = QgsVectorLayer(
            ('Point?crs=epsg:4326&field=id:int&'
             'field=date_f:date&field=time_f:time&field=dt_f:datetime'),
            'test', 'memory')

        self.assertTrue(ml.isValid())
        provider = ml.dataProvider()
        self.assertIsNotNone(provider)

        ft = QgsFeature()
        ft.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(10, 10)))
        ft.setAttributes([
            1,
            QDate(2014, 3, 5),
            QTime(13, 45, 22),
            QDateTime(QDate(2014, 3, 5), QTime(13, 45, 22))
        ])
        res, features = provider.addFeatures([ft])
        self.assertTrue(res)
        self.assertTrue(features)

        dest_file_name = os.path.join(str(QDir.tempPath()), 'datetime.shp')
        crs = QgsCoordinateReferenceSystem()
        crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
        write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat(
            ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile')
        self.assertEqual(write_result, QgsVectorFileWriter.NoError,
                         error_message)

        # Open result and check
        created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name),
                                       'test', 'ogr')

        fields = created_layer.dataProvider().fields()
        self.assertEqual(
            fields.at(fields.indexFromName('date_f')).type(), QVariant.Date)
        # shapefiles do not support time types, result should be string
        self.assertEqual(
            fields.at(fields.indexFromName('time_f')).type(), QVariant.String)
        # shapefiles do not support datetime types, result should be string
        self.assertEqual(
            fields.at(fields.indexFromName('dt_f')).type(), QVariant.String)

        f = next(created_layer.getFeatures(QgsFeatureRequest()))

        date_idx = created_layer.fields().lookupField('date_f')
        self.assertIsInstance(f.attributes()[date_idx], QDate)
        self.assertEqual(f.attributes()[date_idx], QDate(2014, 3, 5))
        time_idx = created_layer.fields().lookupField('time_f')
        # shapefiles do not support time types
        self.assertIsInstance(f.attributes()[time_idx], str)
        self.assertEqual(f.attributes()[time_idx], '13:45:22')
        # shapefiles do not support datetime types
        datetime_idx = created_layer.fields().lookupField('dt_f')
        self.assertIsInstance(f.attributes()[datetime_idx], str)
        self.assertEqual(
            f.attributes()[datetime_idx],
            QDateTime(QDate(2014, 3, 5),
                      QTime(13, 45, 22)).toString("yyyy/MM/dd hh:mm:ss.zzz"))
    def testChangeGeometry(self):
        # test changing geometries values from an edit buffer

        # make a layer with two features
        layer = createEmptyLayer()
        self.assertTrue(layer.startEditing())

        # add two features
        f1 = QgsFeature(layer.fields(), 1)
        f1.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(1, 2)))
        f1.setAttributes(["test", 123])
        self.assertTrue(layer.addFeature(f1))

        f2 = QgsFeature(layer.fields(), 2)
        f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(2, 4)))
        f2.setAttributes(["test2", 246])
        self.assertTrue(layer.addFeature(f2))

        layer.commitChanges()
        layer.startEditing()

        self.assertEqual(layer.editBuffer().changedGeometries(), {})
        self.assertFalse(layer.editBuffer().isFeatureGeometryChanged(1))
        self.assertFalse(layer.editBuffer().isFeatureGeometryChanged(2))

        # change geometry
        layer.changeGeometry(1, QgsGeometry.fromPointXY(QgsPointXY(10, 20)))

        # test contents of buffer
        self.assertEqual(list(layer.editBuffer().changedGeometries().keys()),
                         [1])
        self.assertEqual(
            layer.editBuffer().changedGeometries()[1].constGet().x(), 10)
        self.assertTrue(layer.editBuffer().isFeatureGeometryChanged(1))
        self.assertFalse(layer.editBuffer().isFeatureGeometryChanged(2))
        self.assertEqual(layer.undoStack().count(), 1)

        self.assertEqual(layer.getFeature(1).geometry().constGet().x(), 10)
        self.assertEqual(layer.getFeature(2).geometry().constGet().x(), 2)

        # apply second change to same feature
        layer.beginEditCommand(
            'second change'
        )  # need to use an edit command to avoid the two geometry changes being merged
        layer.changeGeometry(1, QgsGeometry.fromPointXY(QgsPointXY(100, 200)))
        layer.endEditCommand()

        # test contents of buffer
        self.assertEqual(list(layer.editBuffer().changedGeometries().keys()),
                         [1])
        self.assertEqual(
            layer.editBuffer().changedGeometries()[1].constGet().x(), 100)
        self.assertTrue(layer.editBuffer().isFeatureGeometryChanged(1))
        self.assertFalse(layer.editBuffer().isFeatureGeometryChanged(2))
        self.assertEqual(layer.undoStack().count(), 2)

        self.assertEqual(layer.getFeature(1).geometry().constGet().x(), 100)
        self.assertEqual(layer.getFeature(2).geometry().constGet().x(), 2)

        layer.changeGeometry(2, QgsGeometry.fromPointXY(QgsPointXY(20, 40)))

        # test contents of buffer
        self.assertEqual(set(layer.editBuffer().changedGeometries().keys()),
                         set([1, 2]))
        self.assertEqual(
            layer.editBuffer().changedGeometries()[1].constGet().x(), 100)
        self.assertEqual(
            layer.editBuffer().changedGeometries()[2].constGet().x(), 20)
        self.assertTrue(layer.editBuffer().isFeatureGeometryChanged(1))
        self.assertTrue(layer.editBuffer().isFeatureGeometryChanged(2))
        self.assertEqual(layer.undoStack().count(), 3)

        self.assertEqual(layer.getFeature(1).geometry().constGet().x(), 100)
        self.assertEqual(layer.getFeature(2).geometry().constGet().x(), 20)

        layer.undoStack().undo()

        self.assertEqual(list(layer.editBuffer().changedGeometries().keys()),
                         [1])
        self.assertEqual(
            layer.editBuffer().changedGeometries()[1].constGet().x(), 100)
        self.assertTrue(layer.editBuffer().isFeatureGeometryChanged(1))
        self.assertFalse(layer.editBuffer().isFeatureGeometryChanged(2))

        self.assertEqual(layer.getFeature(1).geometry().constGet().x(), 100)
        self.assertEqual(layer.getFeature(2).geometry().constGet().x(), 2)

        layer.undoStack().undo()
        self.assertEqual(list(layer.editBuffer().changedGeometries().keys()),
                         [1])
        self.assertTrue(layer.editBuffer().isFeatureGeometryChanged(1))
        self.assertFalse(layer.editBuffer().isFeatureGeometryChanged(2))

        self.assertEqual(layer.getFeature(1).geometry().constGet().x(), 10)
        self.assertEqual(layer.getFeature(2).geometry().constGet().x(), 2)

        layer.undoStack().undo()
        self.assertEqual(list(layer.editBuffer().changedGeometries().keys()),
                         [])
        self.assertFalse(layer.editBuffer().isFeatureGeometryChanged(1))
        self.assertFalse(layer.editBuffer().isFeatureGeometryChanged(2))

        self.assertEqual(layer.getFeature(1).geometry().constGet().x(), 1)
        self.assertEqual(layer.getFeature(2).geometry().constGet().x(), 2)
Ejemplo n.º 43
0
    def test_updateFeatures(self):
        ol, offline_layer = self._testInit()
        # Edit feature 2
        feat2 = self._getFeatureByAttribute(offline_layer, 'name', "'name 2'")
        self.assertTrue(offline_layer.startEditing())
        self.assertTrue(
            offline_layer.changeAttributeValue(
                feat2.id(),
                offline_layer.fields().lookupField('name'), 'name 2 edited'))
        self.assertTrue(
            offline_layer.changeGeometry(
                feat2.id(), QgsGeometry.fromPointXY(QgsPointXY(33.0, 60.0))))
        self.assertTrue(offline_layer.commitChanges())
        feat2 = self._getFeatureByAttribute(offline_layer, 'name',
                                            "'name 2 edited'")
        self.assertTrue(ol.isOfflineProject())
        # Sync
        ol.synchronize()
        sleep(2)
        # Does anybody know why the sleep is needed? Is that a threaded WFS consequence?
        online_layer = list(self.registry.mapLayers().values())[0]
        self.assertTrue(online_layer.isValid())
        self.assertFalse(online_layer.name().find('(offline)') > -1)
        self.assertEqual(len([f for f in online_layer.getFeatures()]),
                         len(TEST_FEATURES))
        # Check that data have changed in the backend (raise exception if not found)
        feat2 = self._getFeatureByAttribute(self._getLayer('test_point'),
                                            'name', "'name 2 edited'")
        feat2 = self._getFeatureByAttribute(online_layer, 'name',
                                            "'name 2 edited'")
        self.assertEqual(feat2.geometry().asPoint().toString(),
                         QgsPointXY(33.0, 60.0).toString())
        # Check that all other features have not changed
        layer = self._getLayer('test_point')
        self.assertTrue(self._compareFeature(layer, TEST_FEATURES[1 - 1]))
        self.assertTrue(self._compareFeature(layer, TEST_FEATURES[3 - 1]))
        self.assertTrue(self._compareFeature(layer, TEST_FEATURES[4 - 1]))

        # Test for regression on double sync (it was a SEGFAULT)
        # goes offline
        ol = QgsOfflineEditing()
        offline_layer = list(self.registry.mapLayers().values())[0]
        # Edit feature 2
        feat2 = self._getFeatureByAttribute(offline_layer, 'name',
                                            "'name 2 edited'")
        self.assertTrue(offline_layer.startEditing())
        self.assertTrue(
            offline_layer.changeAttributeValue(
                feat2.id(),
                offline_layer.fields().lookupField('name'), 'name 2'))
        self.assertTrue(
            offline_layer.changeGeometry(
                feat2.id(), QgsGeometry.fromPointXY(TEST_FEATURES[1][2])))
        # Edit feat 4
        feat4 = self._getFeatureByAttribute(offline_layer, 'name', "'name 4'")
        self.assertTrue(
            offline_layer.changeAttributeValue(
                feat4.id(),
                offline_layer.fields().lookupField('name'), 'name 4 edited'))
        self.assertTrue(offline_layer.commitChanges())
        # Sync
        ol.synchronize()
        # Does anybody knows why the sleep is needed? Is that a threaded WFS consequence?
        sleep(1)
        online_layer = list(self.registry.mapLayers().values())[0]
        layer = self._getLayer('test_point')
        # Check that data have changed in the backend (raise exception if not found)
        feat4 = self._getFeatureByAttribute(layer, 'name', "'name 4 edited'")
        feat4 = self._getFeatureByAttribute(online_layer, 'name',
                                            "'name 4 edited'")
        feat2 = self._getFeatureByAttribute(layer, 'name', "'name 2'")
        feat2 = self._getFeatureByAttribute(online_layer, 'name', "'name 2'")
        # Check that all other features have not changed
        layer = self._getLayer('test_point')
        self.assertTrue(self._compareFeature(layer, TEST_FEATURES[1 - 1]))
        self.assertTrue(self._compareFeature(layer, TEST_FEATURES[2 - 1]))
        self.assertTrue(self._compareFeature(layer, TEST_FEATURES[3 - 1]))
Ejemplo n.º 44
0
    def testCreateFeature(self):
        """ test creating a feature respecting defaults and constraints """
        layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer&field=flddbl:double",
                               "addfeat", "memory")
        # add a bunch of features
        f = QgsFeature()
        f.setAttributes(["test", 123, 1.0])
        f1 = QgsFeature(2)
        f1.setAttributes(["test_1", 124, 1.1])
        f2 = QgsFeature(3)
        f2.setAttributes(["test_2", 125, 2.4])
        f3 = QgsFeature(4)
        f3.setAttributes(["test_3", 126, 1.7])
        f4 = QgsFeature(5)
        f4.setAttributes(["superpig", 127, 0.8])
        self.assertTrue(layer.dataProvider().addFeatures([f, f1, f2, f3, f4]))

        # no layer
        self.assertFalse(QgsVectorLayerUtils.createFeature(None).isValid())

        # basic tests
        f = QgsVectorLayerUtils.createFeature(layer)
        self.assertTrue(f.isValid())
        self.assertEqual(f.fields(), layer.fields())
        self.assertFalse(f.hasGeometry())
        self.assertEqual(f.attributes(), [NULL, NULL, NULL])

        # set geometry
        g = QgsGeometry.fromPointXY(QgsPointXY(100, 200))
        f = QgsVectorLayerUtils.createFeature(layer, g)
        self.assertTrue(f.hasGeometry())
        self.assertEqual(f.geometry().asWkt(), g.asWkt())

        # using attribute map
        f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'a', 2: 6.0})
        self.assertEqual(f.attributes(), ['a', NULL, 6.0])

        # layer with default value expression
        layer.setDefaultValueDefinition(2, QgsDefaultValue('3*4'))
        f = QgsVectorLayerUtils.createFeature(layer)
        self.assertEqual(f.attributes(), [NULL, NULL, 12])
        # we do not expect the default value expression to take precedence over the attribute map
        f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'a', 2: 6.0})
        self.assertEqual(f.attributes(), ['a', NULL, 6.0])
        # layer with default value expression based on geometry
        layer.setDefaultValueDefinition(2, QgsDefaultValue('3*$x'))
        f = QgsVectorLayerUtils.createFeature(layer, g)
        #adjusted so that input value and output feature are the same
        self.assertEqual(f.attributes(), [NULL, NULL, 300.0])
        layer.setDefaultValueDefinition(2, QgsDefaultValue(None))

        # test with violated unique constraints
        layer.setFieldConstraint(1, QgsFieldConstraints.ConstraintUnique)
        f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'test_1', 1: 123})
        # since field 1 has Unique Constraint, it ignores value 123 that already has been set and sets to 128
        self.assertEqual(f.attributes(), ['test_1', 128, NULL])
        layer.setFieldConstraint(0, QgsFieldConstraints.ConstraintUnique)
        # since field 0 and 1 already have values test_1 and 123, the output must be a new unique value
        f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'test_1', 1: 123})
        self.assertEqual(f.attributes(), ['test_4', 128, NULL])

        # test with violated unique constraints and default value expression providing unique value
        layer.setDefaultValueDefinition(1, QgsDefaultValue('130'))
        f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'test_1', 1: 123})
        # since field 1 has Unique Constraint, it ignores value 123 that already has been set and adds the default value
        self.assertEqual(f.attributes(), ['test_4', 130, NULL])
        # fallback: test with violated unique constraints and default value expression providing already existing value
        # add the feature with the default value:
        self.assertTrue(layer.dataProvider().addFeatures([f]))
        f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'test_1', 1: 123})
        # since field 1 has Unique Constraint, it ignores value 123 that already has been set and adds the default value
        # and since the default value providing an already existing value (130) it generates a unique value (next int: 131)
        self.assertEqual(f.attributes(), ['test_5', 131, NULL])
        layer.setDefaultValueDefinition(1, QgsDefaultValue(None))

        # test with manually correct unique constraint
        f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'test_1', 1: 132})
        self.assertEqual(f.attributes(), ['test_5', 132, NULL])

        """ test creating a feature respecting unique values of postgres provider """
        layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer&field=flddbl:double",
                               "addfeat", "memory")

        # init connection string
        dbconn = 'dbname=\'qgis_test\''
        if 'QGIS_PGTEST_DB' in os.environ:
            dbconn = os.environ['QGIS_PGTEST_DB']

        # create a vector layer
        pg_layer = QgsVectorLayer('{} table="qgis_test"."authors" sql='.format(dbconn), "authors", "postgres")
        self.assertTrue(pg_layer.isValid())
        # check the default clause
        default_clause = 'nextval(\'qgis_test.authors_pk_seq\'::regclass)'
        self.assertEqual(pg_layer.dataProvider().defaultValueClause(0), default_clause)

        # though default_clause is after the first create not unique (until save), it should fill up all the features with it
        pg_layer.startEditing()
        f = QgsVectorLayerUtils.createFeature(pg_layer)
        self.assertEqual(f.attributes(), [default_clause, NULL])
        self.assertTrue(pg_layer.addFeatures([f]))
        self.assertTrue(QgsVectorLayerUtils.valueExists(pg_layer, 0, default_clause))
        f = QgsVectorLayerUtils.createFeature(pg_layer)
        self.assertEqual(f.attributes(), [default_clause, NULL])
        self.assertTrue(pg_layer.addFeatures([f]))
        f = QgsVectorLayerUtils.createFeature(pg_layer)
        self.assertEqual(f.attributes(), [default_clause, NULL])
        self.assertTrue(pg_layer.addFeatures([f]))
        # if a unique value is passed, use it
        f = QgsVectorLayerUtils.createFeature(pg_layer, attributes={0: 40, 1: NULL})
        self.assertEqual(f.attributes(), [40, NULL])
        # and if a default value is configured use it as well
        pg_layer.setDefaultValueDefinition(0, QgsDefaultValue('11*4'))
        f = QgsVectorLayerUtils.createFeature(pg_layer)
        self.assertEqual(f.attributes(), [44, NULL])
        pg_layer.rollBack()
Ejemplo n.º 45
0
    def t0_Update_Pipeline_Layer(self):
        nodes_file = self.dlg.lineEdit_22.text()
        # ogr2ogr.main(["","-f", "ESRI Shapefile", "-s_srs", "epsg:32643", "-t_srs", "epsg:4326", "newp.shp", nodes_file])
        nodeLyr = QgsVectorLayer(nodes_file, "nodes", "ogr")
        pipes_file = self.dlg.lineEdit_21.text()
        # ogr2ogr.main(["","-f", "ESRI Shapefile", "-s_srs", "epsg:32643", "-t_srs", "epsg:4326", "newl.shp", pipes_file])
        # pipeLyr = QgsVectorLayer(pipes_file, "updated pipes", "ogr")
        vl = QgsVectorLayer("Point?crs=epsg:4326", "temporary_points",
                            "memory")
        pr = vl.dataProvider()

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

        layer = self.parameterAsVectorLayer(parameters, self.INPUT, context)

        #on ajoute un nouveau champ 'Aberrant' dans la couche en sortie
        new_fields = layer.fields()

        if not parameters['BOOLEAN']:
            new_fields.append(QgsField('Aberrant', QVariant.Double))

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT,
                                               context, new_fields,
                                               layer.wkbType(),
                                               layer.sourceCrs())
        method = self.parameterAsEnum(parameters, self.INPUT_METHOD, context)
        int_confiance = self.parameterAsEnum(parameters, self.INPUT_CONFIANCE,
                                             context)
        nb_sd = self.parameterAsInt(parameters, self.INPUT_SD, context)
        field_to_filter = self.parameterAsString(parameters, self.FIELD,
                                                 context)

        if feedback.isCanceled():
            return {}

        #on créer une matrice avec les coordonnées
        features = layer.getFeatures()
        coordinates_arr = np.array(
            [[feat.geometry().asPoint()[k] for k in range(2)]
             for feat in features])

        #création de la matrice de distance
        dist_array = distance.cdist(coordinates_arr, coordinates_arr)

        #tri de la matrice selon les lignes
        sort_array = np.sort(dist_array, axis=1)

        if parameters['BOOLEAN_DISTANCE']:
            min_dist_array = np.where(
                sort_array > parameters['INPUT_DISTANCE'], np.nan, sort_array)
            #on supprime le point des données pour IDW
            if method == 2:
                min_dist_array = min_dist_array[:, 1:]
        #selection d'uniquement les premières "colonnes" : donc les plus proches voisins
        #creation d'une matrice ou chaque ligne correspond a une liste des distances des plus proches voisin pour un point (indiceligne = indice du point)
        else:
            min_dist_array = np.delete(sort_array, parameters['INPUT_VOISINS'],
                                       1)
            for k in range(parameters['INPUT_VOISINS'] + 1,
                           len(sort_array[0]) - 1):
                min_dist_array = np.delete(min_dist_array,
                                           parameters['INPUT_VOISINS'], 1)
            #on supprime le point des données pour IDW
            if method == 2:
                min_dist_array = np.delete(min_dist_array, 0, 1)

        if feedback.isCanceled():
            return {}

        #nombre de points dans le shp
        nb_points = len(coordinates_arr)

        #creation d'une liste de liste : liste des index des voisins les plus proches pour chaque point
        neighbors = []
        for k in range(nb_points):
            l = np.nonzero(np.in1d(dist_array[k],
                                   min_dist_array[k]))[0].tolist()
            neighbors.append(l)

        #création du dataframe de données
        features = layer.getFeatures()

        #liste contenant les noms des champs
        field_list = [field.name() for field in layer.fields()]

        #on créé une matrice ou 1 ligne = 1 feature
        data = np.array([[feat[field_name] for field_name in field_list]
                         for feat in features])

        #on créer le dataframe avec les données et les noms des colonnes
        df = pd.DataFrame(data, columns=field_list)

        if feedback.isCanceled():
            return {}

        if method == 0:
            int_confiance += 1
            mean = []
            sd = []
            for k in range(nb_points):
                mean.append(df.iloc[neighbors[k]][field_to_filter].mean())
                sd.append(df.iloc[neighbors[k]][field_to_filter].std())
            df['mean'] = mean
            df['sd'] = sd

            #met 1 quand c'est aberrant, 0 sinon
            df['Aberrant'] = np.where(
                (df[field_to_filter] > df['mean'] - int_confiance * df['sd']) &
                (df[field_to_filter] < df['mean'] + int_confiance * df['sd']),
                0, 1)
            df = df.drop(columns='mean')
            df = df.drop(columns='sd')

        elif method == 1:

            mean = []
            sd = []
            nb_neighbors = []
            for k in range(nb_points):
                mean.append(df.iloc[neighbors[k]][field_to_filter].mean())
                sd.append(df.iloc[neighbors[k]][field_to_filter].std())
                nb_neighbors.append(len(neighbors[k]))

            df['mean'] = mean
            df['sd'] = sd
            df['CV_neighbors'] = 100 * (df['sd'] / df['mean'])
            df = df.drop(columns='sd')
            df = df.drop(columns='mean')
            df['nb_neighbors'] = nb_neighbors

            nb_high_cv = []
            for k in range(nb_points):
                nb_high_cv.append(
                    len(df.iloc[neighbors[k]][
                        df['CV_neighbors'] > parameters['INPUT_CV_MAX']]))
            df['nb_high_cv'] = nb_high_cv

            df['Aberrant'] = np.where(
                (df['nb_neighbors'] - 1 <= df['nb_high_cv']), 1, 0)

            df = df.drop(columns='CV_neighbors')
            df = df.drop(columns='nb_neighbors')
            df = df.drop(columns='nb_high_cv')

        else:
            sd = []
            denominateur = []
            numerateur = []
            df_distances = pd.DataFrame(min_dist_array)
            denom = (1 / (df_distances**2)).sum(axis=1)
            values = []
            for k in range(nb_points):
                sd.append(df.iloc[neighbors[k]][field_to_filter].std())
                values.append(
                    df.iloc[neighbors[k]][field_to_filter].values.tolist())
            df['sd'] = sd
            df_values = pd.DataFrame(values)
            num = (df_values * (1 / (df_distances**2))).sum(axis=1)
            df['interpolation'] = num / denom

            df['Aberrant'] = np.where(
                (df[field_to_filter] > df['interpolation'] - nb_sd * df['sd'])
                &
                (df[field_to_filter] < df['interpolation'] + nb_sd * df['sd']),
                0, 1)
            df = df.drop(columns='sd')
            df = df.drop(columns='interpolation')

        if feedback.isCanceled():
            return {}

        #on va créer un dataframe avec les coordonnées, normalement les features sont parcourrues dans le même ordre

        coordinates = pd.DataFrame(coordinates_arr, columns=['X', 'Y'])
        df['X'] = coordinates['X']
        df['Y'] = coordinates['Y']

        if parameters['BOOLEAN']:
            indexNames = df[df['Aberrant'] == 1].index
            df.drop(indexNames, inplace=True)
            df.drop(columns='Aberrant')

        #on transforme le dataframe en liste pour les attributs
        df_list = df.values.tolist()

        if feedback.isCanceled():
            return {}

        featureList = []

        #on va parcourrir chaque ligne, ie chaque feature
        for row in df_list:
            feat = QgsFeature()
            feat.setAttributes(
                row[0:-2]
            )  #row = une ligne, on exclu les deux dernières colonnes qui sont les coordonnées
            feat.setGeometry(
                QgsGeometry.fromPointXY(QgsPointXY(
                    row[-2],
                    row[-1])))  #on définit la position de chaque point
            featureList.append(feat)  #on ajoute la feature à la liste

            if feedback.isCanceled():
                return {}

        #on ajoute la liste des features à la couche de sortie
        sink.addFeatures(featureList)

        return {self.OUTPUT: dest_id}
Ejemplo n.º 47
0
    def move_feature(self, feat, dx, dy):
        self.new_feat = feat.copy()
        self.geometry = feat["geometry"]
        if self.geometry.wkbType() == 1:  # Point
            self.geom = self.geometry.asPoint()
            self.newGeom = QgsPointXY(self.geom[0] + dx, self.geom[1] + dy)
            self.newGeometry = QgsGeometry.fromPointXY(self.newGeom)
            self.new_feat["geometry"] = self.newGeometry

        elif self.geometry.wkbType() == 2:  # LineString
            self.geom = self.geometry.asPolyline()
            self.newGeom = [
                QgsPointXY(i[0] + dx, i[1] + dy) for i in self.geom
            ]
            self.newGeometry = QgsGeometry.fromPolylineXY(self.newGeom)
            self.new_feat["geometry"] = self.newGeometry

        elif self.geometry.wkbType() == 3:  # Polygon
            self.geom = self.geometry.buffer(0, 5).asPolygon()
            self.newGeom = []
            for g in self.geom:
                self.g1 = []
                for gg in g:
                    self.new_gg = QgsPointXY(gg[0] + dx, gg[1] + dy)
                    self.g1.append(self.new_gg)
                self.newGeom.append(self.g1)

            self.newGeometry = QgsGeometry.fromPolygonXY(self.newGeom)
            self.new_feat["geometry"] = self.newGeometry

        elif self.geometry.wkbType() == 4:  # MultiPoint
            self.geom = self.geometry.asMultiPoint()
            self.newGeom = [
                QgsPointXY(i[0] + dx, i[1] + dy) for i in self.geom
            ]
            self.newGeometry = QgsGeometry.fromMultiPointXY(self.newGeom)
            self.new_feat["geometry"] = self.newGeometry

        elif self.geometry.wkbType() == 5:  # MultiLineString
            self.geom = self.geometry.asMultiPolyline()
            self.newGeom = []
            for g in self.geom:
                self.g1 = []
                for gg in g:
                    self.new_gg = QgsPointXY(gg[0] + dx, gg[1] + dy)
                    self.g1.append(self.new_gg)
                self.newGeom.append(self.g1)

            self.newGeometry = QgsGeometry.fromMultiPolylineXY(self.newGeom)
            self.new_feat["geometry"] = self.newGeometry

        elif self.geometry.wkbType() == 6:  # MultiPolygon
            self.geom = self.geometry.asMultiPolygon()
            self.newGeom = []
            for g in self.geom:
                self.g1 = []
                for gg in g:
                    self.g2 = []
                    for ggg in gg:
                        self.new_ggg = QgsPointXY(ggg[0] + dx, ggg[1] + dy)
                        self.g2.append(self.new_ggg)
                    self.g1.append(self.g2)
                self.newGeom.append(self.g1)

            self.newGeometry = QgsGeometry.fromMultiPolygonXY(self.newGeom)
            self.new_feat["geometry"] = self.newGeometry

        return self.new_feat
Ejemplo n.º 48
0
 def testQgsGeometryRepr(self):
     p = QgsPointXY(123.456, 987.654)
     g = QgsGeometry.fromPointXY(p)
     self.assertTrue(
         g.__repr__().startswith('<QgsGeometry: Point (123.456'))
Ejemplo n.º 49
0
    def processAlgorithm(self, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.INPUT, context)
        if source is None:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.INPUT))

        pointCount = self.parameterAsDouble(parameters, self.POINTS_NUMBER,
                                            context)
        minDistance = self.parameterAsDouble(parameters, self.MIN_DISTANCE,
                                             context)

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

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT,
                                               context, fields,
                                               QgsWkbTypes.Point,
                                               source.sourceCrs())
        if sink is None:
            raise QgsProcessingException(
                self.invalidSinkError(parameters, self.OUTPUT))

        nPoints = 0
        nIterations = 0
        maxIterations = pointCount * 200
        featureCount = source.featureCount()
        total = 100.0 / pointCount if pointCount else 1

        index = QgsSpatialIndex()
        points = dict()

        da = QgsDistanceArea()
        da.setSourceCrs(source.sourceCrs(), context.transformContext())
        da.setEllipsoid(context.project().ellipsoid())

        request = QgsFeatureRequest()

        random.seed()

        while nIterations < maxIterations and nPoints < pointCount:
            if feedback.isCanceled():
                break

            # pick random feature
            fid = random.randint(0, featureCount - 1)
            f = next(
                source.getFeatures(
                    request.setFilterFid(fid).setSubsetOfAttributes([])))
            fGeom = f.geometry()

            if fGeom.isMultipart():
                lines = fGeom.asMultiPolyline()
                # pick random line
                lineId = random.randint(0, len(lines) - 1)
                vertices = lines[lineId]
            else:
                vertices = fGeom.asPolyline()

            # pick random segment
            if len(vertices) == 2:
                vid = 0
            else:
                vid = random.randint(0, len(vertices) - 2)
            startPoint = vertices[vid]
            endPoint = vertices[vid + 1]
            length = da.measureLine(startPoint, endPoint)
            dist = length * random.random()

            if dist > minDistance:
                d = dist / (length - dist)
                rx = (startPoint.x() + d * endPoint.x()) / (1 + d)
                ry = (startPoint.y() + d * endPoint.y()) / (1 + d)

                # generate random point
                p = QgsPointXY(rx, ry)
                geom = QgsGeometry.fromPointXY(p)
                if vector.checkMinDistance(p, index, minDistance, points):
                    f = QgsFeature(nPoints)
                    f.initAttributes(1)
                    f.setFields(fields)
                    f.setAttribute('id', nPoints)
                    f.setGeometry(geom)
                    sink.addFeature(f, QgsFeatureSink.FastInsert)
                    index.insertFeature(f)
                    points[nPoints] = p
                    nPoints += 1
                    feedback.setProgress(int(nPoints * total))
            nIterations += 1

        if nPoints < pointCount:
            feedback.pushInfo(
                self.tr(
                    'Could not generate requested number of random points. '
                    'Maximum number of attempts exceeded.'))

        return {self.OUTPUT: dest_id}
Ejemplo n.º 50
0
    def testFeatureSourceInput(self):
        # create a memory layer and add to project and context
        layer = QgsVectorLayer(
            "Point?crs=epsg:3857&field=fldtxt:string&field=fldint:integer",
            "testmem", "memory")
        self.assertTrue(layer.isValid())
        pr = layer.dataProvider()
        f = QgsFeature()
        f.setAttributes(["test", 123])
        f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100, 200)))
        f2 = QgsFeature()
        f2.setAttributes(["test2", 457])
        f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(110, 200)))
        self.assertTrue(pr.addFeatures([f, f2]))
        self.assertEqual(layer.featureCount(), 2)

        # select first feature
        layer.selectByIds([next(layer.getFeatures()).id()])
        self.assertEqual(len(layer.selectedFeatureIds()), 1)

        QgsProject.instance().addMapLayer(layer)
        context = QgsProcessingContext()
        context.setProject(QgsProject.instance())

        alg = QgsApplication.processingRegistry().createAlgorithmById(
            'grass7:v.buffer')
        self.assertIsNotNone(alg)
        temp_file = os.path.join(self.temp_dir, 'grass_output_sel.shp')
        parameters = {
            'input': QgsProcessingFeatureSourceDefinition('testmem', True),
            'cats': '',
            'where': '',
            'type': [0, 1, 4],
            'distance': 1,
            'minordistance': None,
            'angle': 0,
            'column': None,
            'scale': 1,
            'tolerance': 0.01,
            '-s': False,
            '-c': False,
            '-t': False,
            'output': temp_file,
            'GRASS_REGION_PARAMETER': None,
            'GRASS_SNAP_TOLERANCE_PARAMETER': -1,
            'GRASS_MIN_AREA_PARAMETER': 0.0001,
            'GRASS_OUTPUT_TYPE_PARAMETER': 0,
            'GRASS_VECTOR_DSCO': '',
            'GRASS_VECTOR_LCO': ''
        }
        feedback = QgsProcessingFeedback()

        results, ok = alg.run(parameters, context, feedback)
        self.assertTrue(ok)
        self.assertTrue(os.path.exists(temp_file))

        # make sure that layer has correct features
        res = QgsVectorLayer(temp_file, 'res')
        self.assertTrue(res.isValid())
        self.assertEqual(res.featureCount(), 1)

        QgsProject.instance().removeMapLayer(layer)
Ejemplo n.º 51
0
    def doGeocode(self):

        if self.dockwidget.apiKeyEdit.text() == '':
            self.iface.messageBar().pushMessage("Erro",
                                                u"API key não definida!",
                                                level=Qgis.Critical,
                                                duration=5)
            return

        progressDialog = QProgressDialog()
        progressDialog.setMinimum(0)
        progressDialog.setCancelButtonText('Cancelar')
        progressDialog.setWindowModality(Qt.WindowModal)
        progressDialog.setMinimumWidth(300)
        progressDialog.show()

        inputFile = self.dockwidget.inputFileWidget.filePath()
        errorFile = self.dockwidget.errorOutputFileWidget.filePath()

        addrPartsIdxs = []
        inputAddrList = []

        if self.dockwidget.toolBox.currentIndex() == 0:
            addrPartsIdxs.append(self.dockwidget.addressCombo.currentIndex())
            if self.dockwidget.neighborhoodCombo.currentIndex(
            ) != self.dockwidget.neighborhoodCombo.count() - 1:
                addrPartsIdxs.append(
                    self.dockwidget.neighborhoodCombo.currentIndex())
            if self.dockwidget.cityCombo.currentIndex(
            ) != self.dockwidget.cityCombo.count() - 1:
                addrPartsIdxs.append(self.dockwidget.cityCombo.currentIndex())
            if self.dockwidget.stateCombo.currentIndex(
            ) != self.dockwidget.stateCombo.count() - 1:
                addrPartsIdxs.append(self.dockwidget.stateCombo.currentIndex())
            if self.dockwidget.countryCombo.currentIndex(
            ) != self.dockwidget.countryCombo.count() - 1:
                addrPartsIdxs.append(
                    self.dockwidget.countryCombo.currentIndex())

        else:
            addrPartsIdxs.append(
                self.dockwidget.fullAddressCombo.currentIndex())

        with open(inputFile, 'r') as iFile:
            csv_reader = csv.reader(iFile, delimiter=';')
            lineCount = 0

            for row in csv_reader:
                if lineCount == 0:
                    lineCount += 1
                else:
                    addr = ', '.join(row[i] for i in addrPartsIdxs)
                    addr = '"' + addr + '"'
                    inputAddrList.append(addr)

        # geolocator = Bing(api_key=apiKey)
        geolocator = self.getGeocoder()

        temp = QgsVectorLayer("Point?crs=epsg:4326", "Geocoding output",
                              "memory")
        temp_data = temp.dataProvider()
        temp.startEditing()

        fl = open(inputFile, 'r')
        fo = open(errorFile, 'w')

        header = fl.readline()
        header = header.replace('\n', '')
        header = header.split(';')
        temp_data.addAttributes(
            [QgsField(header[i], QVariant.String) for i in range(len(header))])
        temp_data.addAttributes([QgsField('addr_geocoded', QVariant.String)])
        temp.updateFields()

        fo.writelines(';'.join(header))

        totalAddresses = len(inputAddrList)
        progressDialog.setWindowTitle(u'Geocodificando ' +
                                      str(totalAddresses) + u' endereços...')
        progressDialog.setMaximum(totalAddresses)

        counter = 2
        for a in inputAddrList:
            if progressDialog.wasCanceled():
                self.iface.messageBar().clearWidgets()
                self.iface.messageBar().pushMessage(
                    u"Geocodificação cancelada",
                    u'Salvos ' + str(counter - 2) + u' endereços.',
                    level=Qgis.Info,
                    duration=5)
                break
            address, (latitude, longitude) = geolocator.reverse(a)
            print(counter, address, latitude, longitude)
            counter += 1

            feat = QgsFeature()
            feat.setGeometry(
                QgsGeometry.fromPointXY(QgsPointXY(longitude, latitude)))
            attributes = fl.readline().replace('\n', '').split(';')
            attributes.append(address)
            feat.setAttributes(attributes)
            temp.addFeatures([feat])
            temp.updateExtents()

            # progress.setValue(counter-2)
            progressDialog.setValue(counter - 2)
            self.iface.mainWindow().repaint()

        temp.commitChanges()

        QgsProject.instance().addMapLayer(temp)

        self.iface.messageBar().clearWidgets()
        self.iface.messageBar().pushMessage(
            u"Successo",
            u'Geocodificados ' + str(totalAddresses) + u' endereços!',
            level=Qgis.Success,
            duration=5)
Ejemplo n.º 52
0
    def testCreateFeature(self):
        """ test creating a feature respecting defaults and constraints """
        layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer&field=flddbl:double",
                               "addfeat", "memory")
        # add a bunch of features
        f = QgsFeature()
        f.setAttributes(["test", 123, 1.0])
        f1 = QgsFeature(2)
        f1.setAttributes(["test_1", 124, 1.1])
        f2 = QgsFeature(3)
        f2.setAttributes(["test_2", 125, 2.4])
        f3 = QgsFeature(4)
        f3.setAttributes(["test_3", 126, 1.7])
        f4 = QgsFeature(5)
        f4.setAttributes(["superpig", 127, 0.8])
        self.assertTrue(layer.dataProvider().addFeatures([f, f1, f2, f3, f4]))

        # no layer
        self.assertFalse(QgsVectorLayerUtils.createFeature(None).isValid())

        # basic tests
        f = QgsVectorLayerUtils.createFeature(layer)
        self.assertTrue(f.isValid())
        self.assertEqual(f.fields(), layer.fields())
        self.assertFalse(f.hasGeometry())
        self.assertEqual(f.attributes(), [NULL, NULL, NULL])

        # set geometry
        g = QgsGeometry.fromPointXY(QgsPointXY(100, 200))
        f = QgsVectorLayerUtils.createFeature(layer, g)
        self.assertTrue(f.hasGeometry())
        self.assertEqual(f.geometry().asWkt(), g.asWkt())

        # using attribute map
        f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'a', 2: 6.0})
        self.assertEqual(f.attributes(), ['a', NULL, 6.0])

        # layer with default value expression
        layer.setDefaultValueDefinition(2, QgsDefaultValue('3*4'))
        f = QgsVectorLayerUtils.createFeature(layer)
        self.assertEqual(f.attributes(), [NULL, NULL, 12])
        # we do not expect the default value expression to take precedence over the attribute map
        f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'a', 2: 6.0})
        self.assertEqual(f.attributes(), ['a', NULL, 6.0])
        # layer with default value expression based on geometry
        layer.setDefaultValueDefinition(2, QgsDefaultValue('3*$x'))
        f = QgsVectorLayerUtils.createFeature(layer, g)
        #adjusted so that input value and output feature are the same
        self.assertEqual(f.attributes(), [NULL, NULL, 300.0])
        layer.setDefaultValueDefinition(2, QgsDefaultValue(None))

        # test with violated unique constraints
        layer.setFieldConstraint(1, QgsFieldConstraints.ConstraintUnique)
        f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'test_1', 1: 123})
        # since field 1 has Unique Constraint, it ignores value 123 that already has been set and sets to 128
        self.assertEqual(f.attributes(), ['test_1', 128, NULL])
        layer.setFieldConstraint(0, QgsFieldConstraints.ConstraintUnique)
        # since field 0 and 1 already have values test_1 and 123, the output must be a new unique value
        f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'test_1', 1: 123})
        self.assertEqual(f.attributes(), ['test_4', 128, NULL])

        # test with violated unique constraints and default value expression providing unique value
        layer.setDefaultValueDefinition(1, QgsDefaultValue('130'))
        f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'test_1', 1: 123})
        # since field 1 has Unique Constraint, it ignores value 123 that already has been set and adds the default value
        self.assertEqual(f.attributes(), ['test_4', 130, NULL])
        # fallback: test with violated unique constraints and default value expression providing already existing value
        # add the feature with the default value:
        self.assertTrue(layer.dataProvider().addFeatures([f]))
        f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'test_1', 1: 123})
        # since field 1 has Unique Constraint, it ignores value 123 that already has been set and adds the default value
        # and since the default value providing an already existing value (130) it generates a unique value (next int: 131)
        self.assertEqual(f.attributes(), ['test_5', 131, NULL])
        layer.setDefaultValueDefinition(1, QgsDefaultValue(None))

        # test with manually correct unique constraint
        f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'test_1', 1: 132})
        self.assertEqual(f.attributes(), ['test_5', 132, NULL])
Ejemplo n.º 53
0
    def testCreateFeature(self):
        """ test creating a feature respecting defaults and constraints """
        layer = QgsVectorLayer(
            "Point?field=fldtxt:string&field=fldint:integer&field=flddbl:double",
            "addfeat", "memory")
        # add a bunch of features
        f = QgsFeature()
        f.setAttributes(["test", 123, 1.0])
        f1 = QgsFeature(2)
        f1.setAttributes(["test_1", 124, 1.1])
        f2 = QgsFeature(3)
        f2.setAttributes(["test_2", 125, 2.4])
        f3 = QgsFeature(4)
        f3.setAttributes(["test_3", 126, 1.7])
        f4 = QgsFeature(5)
        f4.setAttributes(["superpig", 127, 0.8])
        self.assertTrue(layer.dataProvider().addFeatures([f, f1, f2, f3, f4]))

        # no layer
        self.assertFalse(QgsVectorLayerUtils.createFeature(None).isValid())

        # basic tests
        f = QgsVectorLayerUtils.createFeature(layer)
        self.assertTrue(f.isValid())
        self.assertEqual(f.fields(), layer.fields())
        self.assertFalse(f.hasGeometry())
        self.assertEqual(f.attributes(), [NULL, NULL, NULL])

        # set geometry
        g = QgsGeometry.fromPointXY(QgsPointXY(100, 200))
        f = QgsVectorLayerUtils.createFeature(layer, g)
        self.assertTrue(f.hasGeometry())
        self.assertEqual(f.geometry().asWkt(), g.asWkt())

        # using attribute map
        f = QgsVectorLayerUtils.createFeature(layer,
                                              attributes={
                                                  0: 'a',
                                                  2: 6.0
                                              })
        self.assertEqual(f.attributes(), ['a', NULL, 6.0])

        # layer with default value expression
        layer.setDefaultValueDefinition(2, QgsDefaultValue('3*4'))
        f = QgsVectorLayerUtils.createFeature(layer)
        self.assertEqual(f.attributes(), [NULL, NULL, 12.0])
        # we expect the default value expression to take precedence over the attribute map
        f = QgsVectorLayerUtils.createFeature(layer,
                                              attributes={
                                                  0: 'a',
                                                  2: 6.0
                                              })
        self.assertEqual(f.attributes(), ['a', NULL, 12.0])
        # layer with default value expression based on geometry
        layer.setDefaultValueDefinition(2, QgsDefaultValue('3*$x'))
        f = QgsVectorLayerUtils.createFeature(layer, g)
        self.assertEqual(f.attributes(), [NULL, NULL, 300.0])
        layer.setDefaultValueDefinition(2, QgsDefaultValue(None))

        # test with violated unique constraints
        layer.setFieldConstraint(1, QgsFieldConstraints.ConstraintUnique)
        f = QgsVectorLayerUtils.createFeature(layer,
                                              attributes={
                                                  0: 'test_1',
                                                  1: 123
                                              })
        self.assertEqual(f.attributes(), ['test_1', 128, NULL])
        layer.setFieldConstraint(0, QgsFieldConstraints.ConstraintUnique)
        f = QgsVectorLayerUtils.createFeature(layer,
                                              attributes={
                                                  0: 'test_1',
                                                  1: 123
                                              })
        self.assertEqual(f.attributes(), ['test_4', 128, NULL])
Ejemplo n.º 54
0
    def create_point_layer(self):
        """ Create an temporary point layer in the Qgis canvas """
        try:
            QApplication.setOverrideCursor(Qt.WaitCursor)  ## Start the 'wait' cursor
            if self.list_points:

                # create layer
                vl = QgsVectorLayer("Point?crs=" + self.selected_epsg, self.layer_name, "memory")
                pr = vl.dataProvider()

                # add fields
                pr.addAttributes([QgsField("id_point", QVariant.Int),
                                  QgsField("nom",  QVariant.String),
                                  QgsField("pfp",  QVariant.Int),
                                  QgsField("pfa", QVariant.Int),
                                  QgsField("ty",  QVariant.String),
                                  QgsField("date_rep",  QVariant.String),
                                  QgsField("ordre",  QVariant.String),
                                  QgsField("num_carte",  QVariant.String),
                                  QgsField("coordY",  QVariant.Double, "double", 12, 4),
                                  QgsField("coordX",  QVariant.Double, "double", 12, 4),
                                  QgsField("coord_prov",  QVariant.String),
                                  QgsField("altitudeH",  QVariant.Double, "double", 10, 4),
                                  QgsField("altitude_prov",  QVariant.String),
                                  QgsField("coord_code",  QVariant.String),
                                  QgsField("geoide_cote",  QVariant.String),
                                  QgsField("geoide_prov",  QVariant.String),
                                  QgsField("ellips_code",  QVariant.String),
                                  QgsField("dev_vert_ETA",  QVariant.String),
                                  QgsField("dev_vert_XI",  QVariant.String),
                                  QgsField("dev_vert_prov",  QVariant.String),
                                  QgsField("dev_vert_ETA0",  QVariant.String),
                                  QgsField("dev_vert_XI0",  QVariant.String),
                                  QgsField("dev_vert_prov0",  QVariant.String),
                                  QgsField("code_raumtri",  QVariant.String),
                                  QgsField("num_cont",  QVariant.String),
                                  QgsField("flag_gps",  QVariant.String),
                                  QgsField("num_sess_gps",  QVariant.String),
                                  QgsField("num_zone",  QVariant.String),
                                  QgsField("reserve",  QVariant.String)])

                vl.updateFields()  # tell the vector layer to fetch changes from the provider

                # add features
                for item in self.list_points:
                    pos_y = float(item[8])
                    pos_x = float(item[9])

                    fet = QgsFeature()
                    fet.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(pos_y,pos_x)))
                    fet.setAttributes(list(item))
                    pr.addFeatures([fet])

                # add preconfigured qgis.qml style file
                plugin_folder = os.path.dirname(os.path.dirname(__file__))
                qml_file = Path(plugin_folder) / "qml" / self.qml_style_point
                if qml_file.is_file():  # Test if file exist, avoid error if he is missing
                    vl.loadNamedStyle(str(qml_file))

                # update layer's extent when new features have been added
                vl.updateExtents()

                # zoom to the layer extent
                if self.zoom:
                    canvas = iface.mapCanvas()
                    canvas.setExtent(vl.extent())

                # Show in project
                self.rmv_old_qgs_point_layer()
                QgsProject.instance().addMapLayer(vl)
        except:
            QApplication.restoreOverrideCursor()  ## Stop the 'wait' cursor
            print("Point -> Failed to create a new Qgis point layer (def create_point_layer)")
        finally:
            QApplication.restoreOverrideCursor()  ## Stop the 'wait' cursor
Ejemplo n.º 55
0
    def clickTool(self):
        self.rubberBand.reset(QgsWkbTypes.GeometryType(3))
        click_point_geom = QgsGeometry.fromPointXY(self.geometry_class.geometry)
        buffer_geom = click_point_geom.buffer(self.settingsWidget.spinBox_searchArea.value(),20)

        lines_layers = self.getLayers(1)
        polygons_layers = self.getLayers(2)
        len_line_layers = 0
        len_polygon_layers = 0

        try:
            len_line_layers += len(lines_layers)
        except TypeError:
            pass

        try:
            len_polygon_layers += len(polygons_layers)
        except TypeError:
            pass

        if len_polygon_layers == 0 and len_line_layers == 0:
            QMessageBox.warning(None,'Missing restrictive layers', 'Select one of the settings')
            return

        self.target_geom = None

        # Polygon layers
        if self.settingsWidget.checkBoxPolygon.isChecked() and len_polygon_layers > 0:
            for l in polygons_layers:
                poly_layer = l[0]
                
                for f in poly_layer.getFeatures(buffer_geom.boundingBox()):
                    f_geom = f.geometry()
                    if f_geom.intersects(click_point_geom):
                        QMessageBox.warning(None,'No space to fill', 'No space to fill, choose a different location')
                        return
                        
                    if f_geom.intersects(buffer_geom):
                        buffer_geom = buffer_geom.difference(f_geom)

                if not poly_layer.isEditable():
                    poly_layer.startEditing()
                
                for part in buffer_geom.parts():
                    part_wkt = part.asWkt()
                    part_geom = QgsGeometry.fromWkt(part_wkt)
                    if part_geom.intersects(click_point_geom):
                        target_geom = part_geom
                        break 

        # Line layers
        if self.settingsWidget.checkBoxLine.isChecked():
            for l in lines_layers:
                line_layer = l[0]
                features = [i.geometry() for i in line_layer.getFeatures(buffer_geom.boundingBox())]
                buffer_geom_linestring = self.polygon2Linestring(buffer_geom)
                if buffer_geom_linestring != None:
                    features.append(buffer_geom_linestring)
                features_unary_geom = QgsGeometry.unaryUnion(features)
                features_unary_geom_parts = [QgsGeometry.fromWkt(i.asWkt()) for i in features_unary_geom.parts()]
                features_polygonize = QgsGeometry.polygonize(features_unary_geom_parts)

                for part in features_polygonize.parts():
                    part_geom = QgsGeometry.fromWkt(part.asWkt())
                    if part_geom.intersects(click_point_geom):
                        if target_geom == None:
                            target_geom = part_geom
                        else:
                            target_geom = target_geom.intersection(part_geom)
                        break 

        target_geom.convertGeometryCollectionToSubclass(2)

        for part in target_geom.parts():
            if part != None:
                part_geom = QgsGeometry.fromWkt(part.asWkt())
                if part_geom.intersects(click_point_geom):
                    self.target_geom = part_geom

        if self.target_geom != None:
            self.rubberBand.setToGeometry(self.target_geom,None)

            if self.settingsWidget.checkBox_askTargetLayer.isChecked():
                self.addMenu()
            else:
                t_layer = self.getTargetLayer()

                if t_layer == None:
                    QMessageBox.warning(None,'Missing target layer', 'Select one of the settings')
                    return
                else:
                    self.addFeature(t_layer)
Ejemplo n.º 56
0
    def doCheck(self, method, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)

        (valid_output_sink,
         valid_output_dest_id) = self.parameterAsSink(parameters,
                                                      self.VALID_OUTPUT,
                                                      context, source.fields(),
                                                      source.wkbType(),
                                                      source.sourceCrs())
        valid_count = 0

        invalid_fields = source.fields()
        invalid_fields.append(
            QgsField('_errors', QVariant.String, 'string', 255))
        (invalid_output_sink, invalid_output_dest_id) = self.parameterAsSink(
            parameters, self.INVALID_OUTPUT, context, invalid_fields,
            source.wkbType(), source.sourceCrs())
        invalid_count = 0

        error_fields = QgsFields()
        error_fields.append(QgsField('message', QVariant.String, 'string',
                                     255))
        (error_output_sink, error_output_dest_id) = self.parameterAsSink(
            parameters, self.ERROR_OUTPUT, context, error_fields,
            QgsWkbTypes.Point, source.sourceCrs())
        error_count = 0

        features = source.getFeatures(
            QgsFeatureRequest(),
            QgsProcessingFeatureSource.FlagSkipGeometryValidityChecks)
        total = 100.0 / source.featureCount() if source.featureCount() else 0
        for current, inFeat in enumerate(features):
            if feedback.isCanceled():
                break
            geom = inFeat.geometry()
            attrs = inFeat.attributes()

            valid = True
            if not geom.isNull() and not geom.isEmpty():
                errors = list(geom.validateGeometry(method))
                if errors:
                    # QGIS method return a summary at the end
                    if method == 1:
                        errors.pop()
                    valid = False
                    reasons = []
                    for error in errors:
                        errFeat = QgsFeature()
                        error_geom = QgsGeometry.fromPointXY(error.where())
                        errFeat.setGeometry(error_geom)
                        errFeat.setAttributes([error.what()])
                        if error_output_sink:
                            error_output_sink.addFeature(
                                errFeat, QgsFeatureSink.FastInsert)
                        error_count += 1

                        reasons.append(error.what())

                    reason = "\n".join(reasons)
                    if len(reason) > 255:
                        reason = reason[:252] + '…'
                    attrs.append(reason)

            outFeat = QgsFeature()
            outFeat.setGeometry(geom)
            outFeat.setAttributes(attrs)

            if valid:
                if valid_output_sink:
                    valid_output_sink.addFeature(outFeat,
                                                 QgsFeatureSink.FastInsert)
                valid_count += 1

            else:
                if invalid_output_sink:
                    invalid_output_sink.addFeature(outFeat,
                                                   QgsFeatureSink.FastInsert)
                invalid_count += 1

            feedback.setProgress(int(current * total))

        results = {
            self.VALID_COUNT: valid_count,
            self.INVALID_COUNT: invalid_count,
            self.ERROR_COUNT: error_count
        }
        if valid_output_sink:
            results[self.VALID_OUTPUT] = valid_output_dest_id
        if invalid_output_sink:
            results[self.INVALID_OUTPUT] = invalid_output_dest_id
        if error_output_sink:
            results[self.ERROR_OUTPUT] = error_output_dest_id
        return results
Ejemplo n.º 57
0
    def legend_test(self):
        self.atlas_map.setAtlasDriven(True)
        self.atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Auto)
        self.atlas_map.setAtlasMargin(0.10)

        # add a point layer
        ptLayer = QgsVectorLayer(
            "Point?crs=epsg:4326&field=attr:int(1)&field=label:string(20)",
            "points", "memory")

        pr = ptLayer.dataProvider()
        f1 = QgsFeature(1)
        f1.initAttributes(2)
        f1.setAttribute(0, 1)
        f1.setAttribute(1, "Test label 1")
        f1.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(-0.638, 48.954)))
        f2 = QgsFeature(2)
        f2.initAttributes(2)
        f2.setAttribute(0, 2)
        f2.setAttribute(1, "Test label 2")
        f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(-1.682, 48.550)))
        pr.addFeatures([f1, f2])

        # categorized symbology
        r = QgsCategorizedSymbolRenderer("attr", [
            QgsRendererCategory(
                1,
                QgsMarkerSymbol.createSimple({
                    "color": "255,0,0",
                    'outline_color': 'black'
                }), "red"),
            QgsRendererCategory(
                2,
                QgsMarkerSymbol.createSimple({
                    "color": "0,0,255",
                    'outline_color': 'black'
                }), "blue")
        ])
        ptLayer.setRenderer(r)

        QgsProject.instance().addMapLayer(ptLayer)

        # add the point layer to the map settings
        layers = self.layers
        layers = [ptLayer] + layers
        self.atlas_map.setLayers(layers)
        self.overview.setLayers(layers)

        # add a legend
        legend = QgsLayoutItemLegend(self.layout)
        legend.attemptMove(QgsLayoutPoint(200, 100))
        # sets the legend filter parameter
        legend.setLinkedMap(self.atlas_map)
        legend.setLegendFilterOutAtlas(True)
        self.layout.addLayoutItem(legend)

        self.atlas.beginRender()

        self.atlas.seekTo(0)
        self.mLabel1.adjustSizeToText()

        checker = QgsLayoutChecker('atlas_legend', self.layout)
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(myTestResult, myMessage)

        self.atlas.endRender()

        # restore state
        self.atlas_map.setLayers([layers[1]])
        self.layout.removeLayoutItem(legend)
        QgsProject.instance().removeMapLayer(ptLayer.id())
Ejemplo n.º 58
0
    def processAlgorithm(self, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.INPUT, context)
        if source is None:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.INPUT))

        pointCount = self.parameterAsDouble(parameters, self.POINTS_NUMBER,
                                            context)
        minDistance = self.parameterAsDouble(parameters, self.MIN_DISTANCE,
                                             context)

        bbox = source.sourceExtent()
        sourceIndex = QgsSpatialIndex(source, feedback)

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

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT,
                                               context, fields,
                                               QgsWkbTypes.Point,
                                               source.sourceCrs())
        if sink is None:
            raise QgsProcessingException(
                self.invalidSinkError(parameters, self.OUTPUT))

        nPoints = 0
        nIterations = 0
        maxIterations = pointCount * 200
        total = 100.0 / pointCount if pointCount else 1

        index = QgsSpatialIndex()
        points = dict()

        random.seed()

        while nIterations < maxIterations and nPoints < pointCount:
            if feedback.isCanceled():
                break

            rx = bbox.xMinimum() + bbox.width() * random.random()
            ry = bbox.yMinimum() + bbox.height() * random.random()

            p = QgsPointXY(rx, ry)
            geom = QgsGeometry.fromPointXY(p)
            ids = sourceIndex.intersects(geom.buffer(5, 5).boundingBox())
            if len(ids) > 0 and \
                    vector.checkMinDistance(p, index, minDistance, points):
                request = QgsFeatureRequest().setFilterFids(
                    ids).setSubsetOfAttributes([])
                for f in source.getFeatures(request):
                    if feedback.isCanceled():
                        break

                    tmpGeom = f.geometry()
                    if geom.within(tmpGeom):
                        f = QgsFeature(nPoints)
                        f.initAttributes(1)
                        f.setFields(fields)
                        f.setAttribute('id', nPoints)
                        f.setGeometry(geom)
                        sink.addFeature(f, QgsFeatureSink.FastInsert)
                        index.insertFeature(f)
                        points[nPoints] = p
                        nPoints += 1
                        feedback.setProgress(int(nPoints * total))
            nIterations += 1

        if nPoints < pointCount:
            feedback.pushInfo(
                self.tr(
                    'Could not generate requested number of random points. '
                    'Maximum number of attempts exceeded.'))

        return {self.OUTPUT: dest_id}
Ejemplo n.º 59
0
    def processAlgorithm(self, parameters, context, feedback):
        """
        RUN PROCESS
        """
        # INPUT
        linelayer = self.parameterAsSource(parameters, self.INPUT, context)
        tol = self.parameterAsDouble(parameters, self.TOLERANCE, context)
        nmask = self.parameterAsString(parameters, self.NODE_MASK, context)
        nini = self.parameterAsInt(parameters, self.NODE_INI, context)
        ninc = self.parameterAsInt(parameters, self.NODE_INC, context)
        lmask = self.parameterAsString(parameters, self.LINK_MASK, context)
        lini = self.parameterAsInt(parameters, self.LINK_INI, context)
        linc = self.parameterAsInt(parameters, self.LINK_INC, context)

        # SEND INFORMATION TO THE USER
        feedback.pushInfo('=' * 40)
        crsid = linelayer.sourceCrs().authid()
        if crsid:
            feedback.pushInfo('CRS is {}.'.format(crsid))
        else:
            feedback.pushInfo('WARNING: CRS is not set!')

        if linelayer.wkbType() == QgsWkbTypes.MultiLineString:
            feedback.reportError('ERROR: Source geometry is MultiLineString!')

        # READ LINESTRINGS AS WKT
        lines = []
        for feature in linelayer.getFeatures():
            line = []
            for point in feature.geometry().asPolyline():
                line.append((point.x(), point.y()))
            lines.append(line)
        for line in lines:
            if tools.dist2p(line[0], line[-1]) < tol:
                feedback.reportError('ERROR: Looped LineString!')
                return {}

        # SHOW INFO
        feedback.pushInfo('Read: {} LineStrings.'.format(len(lines)))

        # CONFIG
        def n_format(index):
            return tools.format_id(nini + index * ninc, nmask)

        def l_format(index):
            return tools.format_id(lini + index * linc, lmask)

        # CALCULATE NETWORK
        nodes, links = tools.net_from_linestrings(lines, tol)

        # GENERATE NODE LAYER
        newfields = QgsFields()
        newfields.append(QgsField("id", QVariant.String))
        newfields.append(QgsField("type", QVariant.String))
        newfields.append(QgsField("elevation", QVariant.Double))
        (node_sink,
         node_id) = self.parameterAsSink(parameters, self.NODE_OUTPUT, context,
                                         newfields, QgsWkbTypes.Point,
                                         linelayer.sourceCrs())

        # ADD FEATURES
        ncnt = 0
        f = QgsFeature()
        for x, y in nodes[:]:
            nodeid = n_format(ncnt)
            f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(x, y)))
            f.setAttributes([nodeid, '', 0.0])
            node_sink.addFeature(f)
            ncnt += 1

            # SHOW PROGRESS
            if ncnt % 100 == 0:
                feedback.setProgress(50 * ncnt / len(nodes))

        # GENERATE LINK LAYER
        newfields = QgsFields()
        newfields.append(QgsField("id", QVariant.String))
        newfields.append(QgsField("start", QVariant.String))
        newfields.append(QgsField("end", QVariant.String))
        newfields.append(QgsField("type", QVariant.String))
        newfields.append(QgsField("length", QVariant.Double))
        newfields.extend(linelayer.fields())
        (link_sink,
         link_id) = self.parameterAsSink(parameters, self.LINK_OUTPUT, context,
                                         newfields, QgsWkbTypes.LineString,
                                         linelayer.sourceCrs())

        # ADD FEATURES
        lcnt = 0
        g = QgsFeature()
        for f in linelayer.getFeatures():
            link = links[lcnt]
            linkid = l_format(lcnt)
            start = n_format(link[0])
            end = n_format(link[1])
            poly = []
            for x, y in links[lcnt][2][:]:
                poly.append(QgsPointXY(x, y))
            length = tools.length2d(poly)
            attr = [linkid, start, end, 'PIPE', length]
            attr.extend(f.attributes())
            g.setGeometry(QgsGeometry.fromPolylineXY(poly))
            g.setAttributes(attr)
            link_sink.addFeature(g)
            lcnt += 1

            # SHOW PROGRESS
            if lcnt % 100 == 0:
                feedback.setProgress(50 + 50 * lcnt / len(links))
        feedback.pushInfo('Network was generated successfully.')
        feedback.pushInfo('Node number: {}.'.format(ncnt))
        feedback.pushInfo('Link number: {}.'.format(lcnt))
        feedback.pushInfo('=' * 40)

        # PROCCES CANCELED
        if feedback.isCanceled():
            return {}

        # OUTPUT
        return {self.NODE_OUTPUT: node_id, self.LINK_OUTPUT: link_id}
Ejemplo n.º 60
-1
    def legend_test(self):
        self.atlas_map.setAtlasDriven(True)
        self.atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Auto)
        self.atlas_map.setAtlasMargin(0.10)

        # add a point layer
        ptLayer = QgsVectorLayer("Point?crs=epsg:4326&field=attr:int(1)&field=label:string(20)", "points", "memory")

        pr = ptLayer.dataProvider()
        f1 = QgsFeature(1)
        f1.initAttributes(2)
        f1.setAttribute(0, 1)
        f1.setAttribute(1, "Test label 1")
        f1.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(-0.638, 48.954)))
        f2 = QgsFeature(2)
        f2.initAttributes(2)
        f2.setAttribute(0, 2)
        f2.setAttribute(1, "Test label 2")
        f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(-1.682, 48.550)))
        pr.addFeatures([f1, f2])

        # categorized symbology
        r = QgsCategorizedSymbolRenderer("attr", [QgsRendererCategory(1, QgsMarkerSymbol.createSimple({"color": "255,0,0", 'outline_color': 'black'}), "red"),
                                                  QgsRendererCategory(2, QgsMarkerSymbol.createSimple({"color": "0,0,255", 'outline_color': 'black'}), "blue")])
        ptLayer.setRenderer(r)

        QgsProject.instance().addMapLayer(ptLayer)

        # add the point layer to the map settings
        layers = self.layers
        layers = [ptLayer] + layers
        self.atlas_map.setLayers(layers)
        self.overview.setLayers(layers)

        # add a legend
        legend = QgsLayoutItemLegend(self.layout)
        legend.setTitle("Legend")
        legend.attemptMove(QgsLayoutPoint(200, 100))
        # sets the legend filter parameter
        legend.setLinkedMap(self.atlas_map)
        legend.setLegendFilterOutAtlas(True)
        self.layout.addLayoutItem(legend)

        self.atlas.beginRender()

        self.atlas.seekTo(0)
        self.mLabel1.adjustSizeToText()

        checker = QgsLayoutChecker('atlas_legend', self.layout)
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(myTestResult, myMessage)

        self.atlas.endRender()

        # restore state
        self.atlas_map.setLayers([layers[1]])
        self.layout.removeLayoutItem(legend)
        QgsProject.instance().removeMapLayer(ptLayer.id())