def testCreateLayerMultiPoint(self):
        layer = QgsVectorLayer("MultiPoint?crs=epsg:3111&field=id:integer&field=fldtxt:string&field=fldint:integer",
                               "addfeat", "memory")
        pr = layer.dataProvider()
        f = QgsFeature()
        f.setAttributes([1, "test", 1])
        f.setGeometry(QgsGeometry.fromWkt('MultiPoint(1 2, 3 4)'))
        f2 = QgsFeature()
        f2.setAttributes([2, "test2", 3])
        f3 = QgsFeature()
        f3.setAttributes([3, "test2", NULL])
        f3.setGeometry(QgsGeometry.fromWkt('MultiPoint(7 8)'))
        pr.addFeatures([f, f2, f3])

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

        new_layer = QgsVectorLayer(uri, 'new', 'mssql')
        self.assertTrue(new_layer.isValid())
        self.assertEqual(new_layer.wkbType(), QgsWkbTypes.MultiPoint)
        self.assertEqual(new_layer.crs().authid(), 'EPSG:3111')
        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]])
        geom = [f.geometry().asWkt() for f in new_layer.getFeatures()]
        self.assertEqual(geom, ['MultiPoint ((1 2),(3 4))', '', 'MultiPoint ((7 8))'])
Exemple #2
0
 def testExportLayerToExistingDatabase(self):
     fields = QgsFields()
     fields.append(QgsField('f1', QVariant.Int))
     tmpfile = os.path.join(self.basetestpath, 'testCreateNewGeopackage.gpkg')
     options = {}
     options['update'] = True
     options['driverName'] = 'GPKG'
     options['layerName'] = 'table1'
     exporter = QgsVectorLayerExporter(tmpfile, "ogr", fields, QgsWkbTypes.Polygon, QgsCoordinateReferenceSystem(3111), False, options)
     self.assertFalse(exporter.errorCode(),
                      'unexpected export error {}: {}'.format(exporter.errorCode(), exporter.errorMessage()))
     options['layerName'] = 'table2'
     exporter = QgsVectorLayerExporter(tmpfile, "ogr", fields, QgsWkbTypes.Point, QgsCoordinateReferenceSystem(3113), False, options)
     self.assertFalse(exporter.errorCode(),
                      'unexpected export error {} : {}'.format(exporter.errorCode(), exporter.errorMessage()))
     del exporter
     # make sure layers exist
     lyr = QgsVectorLayer('{}|layername=table1'.format(tmpfile), "lyr1", "ogr")
     self.assertTrue(lyr.isValid())
     self.assertEqual(lyr.crs().authid(), 'EPSG:3111')
     self.assertEqual(lyr.wkbType(), QgsWkbTypes.Polygon)
     lyr2 = QgsVectorLayer('{}|layername=table2'.format(tmpfile), "lyr2", "ogr")
     self.assertTrue(lyr2.isValid())
     self.assertEqual(lyr2.crs().authid(), 'EPSG:3113')
     self.assertEqual(lyr2.wkbType(), QgsWkbTypes.Point)
    def testLayerGeometry(self):
        layer = QgsVectorLayer("Point", "test", "memory")

        myMessage = "Expected: %s\nGot: %s\n" % (QGis.Point, layer.geometryType())
        assert layer.geometryType() == QGis.Point, myMessage

        myMessage = "Expected: %s\nGot: %s\n" % (QGis.WKBPoint, layer.wkbType())
        assert layer.wkbType() == QGis.WKBPoint, myMessage
Exemple #4
0
    def testTriangleTINPolyhedralSurface(self):
        """ Test support for Triangles (mapped to Polygons) """
        testsets = (
            ("Triangle((0 0, 0 1, 1 1, 0 0))", QgsWkbTypes.Triangle, "Triangle ((0 0, 0 1, 1 1, 0 0))"),
            ("Triangle Z((0 0 1, 0 1 2, 1 1 3, 0 0 1))", QgsWkbTypes.TriangleZ, "TriangleZ ((0 0 1, 0 1 2, 1 1 3, 0 0 1))"),
            ("Triangle M((0 0 4, 0 1 5, 1 1 6, 0 0 4))", QgsWkbTypes.TriangleM, "TriangleM ((0 0 4, 0 1 5, 1 1 6, 0 0 4))"),
            ("Triangle ZM((0 0 0 1, 0 1 2 3, 1 1 4 5, 0 0 0 1))", QgsWkbTypes.TriangleZM, "TriangleZM ((0 0 0 1, 0 1 2 3, 1 1 4 5, 0 0 0 1))"),

            ("TIN (((0 0, 0 1, 1 1, 0 0)),((0 0, 1 0, 1 1, 0 0)))", QgsWkbTypes.MultiPolygon, "MultiPolygon (((0 0, 0 1, 1 1, 0 0)),((0 0, 1 0, 1 1, 0 0)))"),
            ("TIN Z(((0 0 0, 0 1 1, 1 1 1, 0 0 0)),((0 0 0, 1 0 0, 1 1 1, 0 0 0)))", QgsWkbTypes.MultiPolygonZ, "MultiPolygonZ (((0 0 0, 0 1 1, 1 1 1, 0 0 0)),((0 0 0, 1 0 0, 1 1 1, 0 0 0)))"),
            ("TIN M(((0 0 0, 0 1 2, 1 1 3, 0 0 0)),((0 0 0, 1 0 4, 1 1 3, 0 0 0)))", QgsWkbTypes.MultiPolygonM, "MultiPolygonM (((0 0 0, 0 1 2, 1 1 3, 0 0 0)),((0 0 0, 1 0 4, 1 1 3, 0 0 0)))"),
            ("TIN ZM(((0 0 0 0, 0 1 1 2, 1 1 1 3, 0 0 0 0)),((0 0 0 0, 1 0 0 4, 1 1 1 3, 0 0 0 0)))", QgsWkbTypes.MultiPolygonZM, "MultiPolygonZM (((0 0 0 0, 0 1 1 2, 1 1 1 3, 0 0 0 0)),((0 0 0 0, 1 0 0 4, 1 1 1 3, 0 0 0 0)))"),

            ("PolyhedralSurface (((0 0, 0 1, 1 1, 0 0)),((0 0, 1 0, 1 1, 0 0)))", QgsWkbTypes.MultiPolygon, "MultiPolygon (((0 0, 0 1, 1 1, 0 0)),((0 0, 1 0, 1 1, 0 0)))"),
            ("PolyhedralSurface Z(((0 0 0, 0 1 1, 1 1 1, 0 0 0)),((0 0 0, 1 0 0, 1 1 1, 0 0 0)))", QgsWkbTypes.MultiPolygonZ, "MultiPolygonZ (((0 0 0, 0 1 1, 1 1 1, 0 0 0)),((0 0 0, 1 0 0, 1 1 1, 0 0 0)))"),
            ("PolyhedralSurface M(((0 0 0, 0 1 2, 1 1 3, 0 0 0)),((0 0 0, 1 0 4, 1 1 3, 0 0 0)))", QgsWkbTypes.MultiPolygonM, "MultiPolygonM (((0 0 0, 0 1 2, 1 1 3, 0 0 0)),((0 0 0, 1 0 4, 1 1 3, 0 0 0)))"),
            ("PolyhedralSurface ZM(((0 0 0 0, 0 1 1 2, 1 1 1 3, 0 0 0 0)),((0 0 0 0, 1 0 0 4, 1 1 1 3, 0 0 0 0)))", QgsWkbTypes.MultiPolygonZM, "MultiPolygonZM (((0 0 0 0, 0 1 1 2, 1 1 1 3, 0 0 0 0)),((0 0 0 0, 1 0 0 4, 1 1 1 3, 0 0 0 0)))")
        )
        for row in testsets:
            datasource = os.path.join(self.basetestpath, 'test.csv')
            with open(datasource, 'wt') as f:
                f.write('id,WKT\n')
                f.write('1,"%s"' % row[0])

            vl = QgsVectorLayer(datasource, 'test', 'ogr')
            self.assertTrue(vl.isValid())
            self.assertEqual(vl.wkbType(), row[1])

            f = QgsFeature()
            self.assertTrue(vl.getFeatures(QgsFeatureRequest(1)).nextFeature(f))
            self.assertTrue(f.geometry())
            self.assertEqual(f.geometry().constGet().asWkt(), row[2])
    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)'])
Exemple #6
0
    def processAlgorithm(self, feedback):
        layers = self.getParameterValue(self.INPUT_DATASOURCES)
        query = self.getParameterValue(self.INPUT_QUERY)
        uid_field = self.getParameterValue(self.INPUT_UID_FIELD)
        geometry_field = self.getParameterValue(self.INPUT_GEOMETRY_FIELD)
        geometry_type = self.getParameterValue(self.INPUT_GEOMETRY_TYPE)
        geometry_crs = self.getParameterValue(self.INPUT_GEOMETRY_CRS)

        df = QgsVirtualLayerDefinition()
        layerIdx = 1
        if layers:
            for layerSource in layers.split(';'):
                layer = dataobjects.getObjectFromUri(layerSource)
                if layer:
                    df.addSource('input{}'.format(layerIdx), layer.id())
                layerIdx += 1

        if query == '':
            raise GeoAlgorithmExecutionException(
                self.tr('Empty SQL. Please enter valid SQL expression and try again.'))
        else:
            df.setQuery(query)

        if uid_field:
            df.setUid(uid_field)

        if geometry_type == 1:  # no geometry
            df.setGeometryWkbType(QgsWkbTypes.NullGeometry)
        else:
            if geometry_field:
                df.setGeometryField(geometry_field)
            if geometry_type > 1:
                df.setGeometryWkbType(geometry_type - 1)
            if geometry_crs:
                crs = QgsCoordinateReferenceSystem(geometry_crs)
                if crs.isValid():
                    df.setGeometrySrid(crs.postgisSrid())

        vLayer = QgsVectorLayer(df.toString(), "temp_vlayer", "virtual")
        if not vLayer.isValid():
            raise GeoAlgorithmExecutionException(vLayer.dataProvider().error().message())

        writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter(
            vLayer.fields().toList(),
            # Create a point layer (without any points) if 'no geometry' is chosen
            vLayer.wkbType() if geometry_type != 1 else 1,
            vLayer.crs())

        features = vector.features(vLayer)
        total = 100.0 / len(features)
        outFeat = QgsFeature()
        for current, inFeat in enumerate(features):
            outFeat.setAttributes(inFeat.attributes())
            if geometry_type != 1:
                outFeat.setGeometry(inFeat.geometry())
            writer.addFeature(outFeat)
            feedback.setProgress(int(current * total))
        del writer
    def testLayerGeometry(self):
        testVectors = [("Point", QGis.Point, QGis.WKBPoint),
                       ("LineString", QGis.Line, QGis.WKBLineString),
                       ("Polygon", QGis.Polygon, QGis.WKBPolygon),
                       ("MultiPoint", QGis.Point, QGis.WKBMultiPoint),
                       ("MultiLineString", QGis.Line, QGis.WKBMultiLineString),
                       ("MultiPolygon", QGis.Polygon, QGis.WKBMultiPolygon),
                       ("None", QGis.NoGeometry, QGis.WKBNoGeometry)]
        for v in testVectors:
            layer = QgsVectorLayer(v[0], "test", "memory")

            myMessage = ('Expected: %s\nGot: %s\n' %
                         (v[1], layer.geometryType()))
            assert layer.geometryType() == v[1], myMessage

            myMessage = ('Expected: %s\nGot: %s\n' %
                         (v[2], layer.wkbType()))
            assert layer.wkbType() == v[2], myMessage
    def testLayerGeometry(self):
        testVectors = [("Point", QgsWkbTypes.PointGeometry, QgsWkbTypes.Point),
                       ("LineString", QgsWkbTypes.LineGeometry, QgsWkbTypes.LineString),
                       ("Polygon", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.Polygon),
                       ("MultiPoint", QgsWkbTypes.PointGeometry, QgsWkbTypes.MultiPoint),
                       ("MultiLineString", QgsWkbTypes.LineGeometry, QgsWkbTypes.MultiLineString),
                       ("MultiPolygon", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.MultiPolygon),
                       ("PointZ", QgsWkbTypes.PointGeometry, QgsWkbTypes.PointZ),
                       ("LineStringZ", QgsWkbTypes.LineGeometry, QgsWkbTypes.LineStringZ),
                       ("PolygonZ", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.PolygonZ),
                       ("MultiPointZ", QgsWkbTypes.PointGeometry, QgsWkbTypes.MultiPointZ),
                       ("MultiLineStringZ", QgsWkbTypes.LineGeometry, QgsWkbTypes.MultiLineStringZ),
                       ("MultiPolygonZ", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.MultiPolygonZ),
                       ("PointM", QgsWkbTypes.PointGeometry, QgsWkbTypes.PointM),
                       ("LineStringM", QgsWkbTypes.LineGeometry, QgsWkbTypes.LineStringM),
                       ("PolygonM", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.PolygonM),
                       ("MultiPointM", QgsWkbTypes.PointGeometry, QgsWkbTypes.MultiPointM),
                       ("MultiLineStringM", QgsWkbTypes.LineGeometry, QgsWkbTypes.MultiLineStringM),
                       ("MultiPolygonM", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.MultiPolygonM),
                       ("PointZM", QgsWkbTypes.PointGeometry, QgsWkbTypes.PointZM),
                       ("LineStringZM", QgsWkbTypes.LineGeometry, QgsWkbTypes.LineStringZM),
                       ("PolygonZM", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.PolygonZM),
                       ("MultiPointZM", QgsWkbTypes.PointGeometry, QgsWkbTypes.MultiPointZM),
                       ("MultiLineStringZM", QgsWkbTypes.LineGeometry, QgsWkbTypes.MultiLineStringZM),
                       ("MultiPolygonZM", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.MultiPolygonZM),
                       ("Point25D", QgsWkbTypes.PointGeometry, QgsWkbTypes.Point25D),
                       ("LineString25D", QgsWkbTypes.LineGeometry, QgsWkbTypes.LineString25D),
                       ("Polygon25D", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.Polygon25D),
                       ("MultiPoint25D", QgsWkbTypes.PointGeometry, QgsWkbTypes.MultiPoint25D),
                       ("MultiLineString25D", QgsWkbTypes.LineGeometry, QgsWkbTypes.MultiLineString25D),
                       ("MultiPolygon25D", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.MultiPolygon25D),
                       ("None", QgsWkbTypes.NullGeometry, QgsWkbTypes.NoGeometry)]
        for v in testVectors:
            layer = QgsVectorLayer(v[0], "test", "pythonprovider")

            myMessage = ('Expected: %s\nGot: %s\n' %
                         (v[1], layer.geometryType()))
            assert layer.geometryType() == v[1], myMessage

            myMessage = ('Expected: %s\nGot: %s\n' %
                         (v[2], layer.wkbType()))
            assert layer.wkbType() == v[2], myMessage
    def testMultipatch(self):
        """Check that we can deal with multipatch shapefiles, returned natively by OGR as GeometryCollection of TIN"""

        testPath = TEST_DATA_DIR + '/' + 'multipatch.shp'
        vl = QgsVectorLayer(testPath, 'test', 'ogr')
        self.assertTrue(vl.isValid())
        self.assertEqual(vl.wkbType(), QgsWkbTypes.MultiPolygonZ)
        f = next(vl.getFeatures())
        self.assertEqual(f.geometry().wkbType(), QgsWkbTypes.MultiPolygonZ)
        self.assertEqual(f.geometry().constGet().asWkt(),
                         'MultiPolygonZ (((0 0 0, 0 1 0, 1 1 0, 0 0 0)),((0 0 0, 1 1 0, 1 0 0, 0 0 0)),((0 0 0, 0 -1 0, 1 -1 0, 0 0 0)),((0 0 0, 1 -1 0, 1 0 0, 0 0 0)))')
Exemple #10
0
    def testGeometryTypeKnownAtSecondFeature(self):

        datasource = os.path.join(self.basetestpath, "testGeometryTypeKnownAtSecondFeature.csv")
        with open(datasource, "wt") as f:
            f.write("id,WKT\n")
            f.write("1,\n")
            f.write("2,POINT(2 49)\n")

        vl = QgsVectorLayer(u"{}|layerid=0".format(datasource), u"test", u"ogr")
        self.assertTrue(vl.isValid())
        self.assertEqual(vl.wkbType(), QgsWkbTypes.Point)
    def loadData(self, resultFile, chunkId):
        """ Load data to the map """
        
        if isMimeTypeVector(self.mimeType, True) != None:                 
            # Memory layer:
            geometryTypes = ["Point","LineString","Polygon","Unknown", "NoGeometry"]
            vlayer = QgsVectorLayer(resultFile, "chunk", "ogr")

            if self.__bFirstChunk:    
                self.__bFirstChunk = False
                self.__geometryType = geometryTypes[vlayer.geometryType()]
                self.__bGeomMulti = vlayer.wkbType() in [4,5,6,11,12,13]
                self.__memoryLayer = QgsVectorLayer(self.__geometryType,"Streamed data","memory")
                self.__memoryLayer.dataProvider().addAttributes(vlayer.pendingFields().values())
                self.__memoryLayer.updateFieldMap()            

            provider = vlayer.dataProvider()
            allAttrs = provider.attributeIndexes()
            vlayer.select(allAttrs)  
            
            # Visualize temporal geometries during the downloading process
            # Don't add temporal geometries if last chunk
            if self.DEBUG: print "Loaded chunkId:",chunkId           
            res = self.__memoryLayer.dataProvider().addFeatures( [feat for feat in vlayer] )
            self.__deliveredChunks += 1      
            
            if not self.allChunksDelivered():
                inFeat = QgsFeature()
                inGeom = QgsGeometry()
                self.createTempGeometry(chunkId, self.__geometryType)
                while provider.nextFeature( inFeat ):
                    inGeom = inFeat.geometry()
                    featList = self.extractAsSingle(self.__geometryType, inGeom) if self.__bGeomMulti else [inGeom]
                    for geom in featList:
                        self.addTempGeometry(chunkId, self.__geometryType, geom)  
            else:
                self.finishLoading()
                                
        # Raster data
        elif isMimeTypeRaster(self.mimeType, True) != None:
            # We can directly attach the new layer
            if self.__bFirstChunk:    
                self.__bFirstChunk = False
                self.__groupIndex = self.__legend.addGroup("Streamed-raster")
                
            rLayer = QgsRasterLayer(resultFile, "raster_"+str(chunkId))
            bLoaded = QgsMapLayerRegistry.instance().addMapLayer(rLayer)
            self.stretchRaster(rLayer)
            self.__legend.moveLayer(rLayer, self.__groupIndex + 1)
            
            self.__deliveredChunks += 1
            
            if self.allChunksDelivered():
                self.finishLoading()
Exemple #12
0
    def testGeometryTypeKnownAtSecondFeature(self):

        datasource = os.path.join(self.basetestpath, 'testGeometryTypeKnownAtSecondFeature.csv')
        with open(datasource, 'wt') as f:
            f.write('id,WKT\n')
            f.write('1,\n')
            f.write('2,POINT(2 49)\n')

        vl = QgsVectorLayer('{}|layerid=0'.format(datasource), 'test', 'ogr')
        self.assertTrue(vl.isValid())
        self.assertEqual(vl.wkbType(), QgsWkbTypes.Point)
Exemple #13
0
    def _openShapefile(self):
        layer = QgsVectorLayer(self.shapePath, self.fileName, "ogr")

        wkbType = layer.wkbType()
        if wkbType != QgsWkbTypes.PointZ:
            self.importError.emit(
                self.tr("File has incorrect WKB type '{}'. Please select layer "
                        "with 'PointZ' WKB type.".format(QgsWkbTypes.displayString(wkbType))))
            return None

        return layer
    def processAlgorithm(self, parameters, context, feedback):
        layers = self.parameterAsLayerList(parameters, self.INPUT_DATASOURCES, context)
        query = self.parameterAsString(parameters, self.INPUT_QUERY, context)
        uid_field = self.parameterAsString(parameters, self.INPUT_UID_FIELD, context)
        geometry_field = self.parameterAsString(parameters, self.INPUT_GEOMETRY_FIELD, context)
        geometry_type = self.parameterAsEnum(parameters, self.INPUT_GEOMETRY_TYPE, context)
        geometry_crs = self.parameterAsCrs(parameters, self.INPUT_GEOMETRY_CRS, context)

        df = QgsVirtualLayerDefinition()
        for layerIdx, layer in enumerate(layers):
            df.addSource('input{}'.format(layerIdx + 1), layer.id())

        if query == '':
            raise QgsProcessingException(
                self.tr('Empty SQL. Please enter valid SQL expression and try again.'))
        else:
            localContext = self.createExpressionContext(parameters, context)
            expandedQuery = QgsExpression.replaceExpressionText(query, localContext)
            df.setQuery(expandedQuery)

        if uid_field:
            df.setUid(uid_field)

        if geometry_type == 1:  # no geometry
            df.setGeometryWkbType(QgsWkbTypes.NoGeometry)
        else:
            if geometry_field:
                df.setGeometryField(geometry_field)
            if geometry_type > 1:
                df.setGeometryWkbType(geometry_type - 1)
            if geometry_crs.isValid():
                df.setGeometrySrid(geometry_crs.postgisSrid())

        vLayer = QgsVectorLayer(df.toString(), "temp_vlayer", "virtual")
        if not vLayer.isValid():
            raise QgsProcessingException(vLayer.dataProvider().error().message())

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
                                               vLayer.fields(), vLayer.wkbType() if geometry_type != 1 else 1, vLayer.crs())
        if sink is None:
            raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT))

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

            sink.addFeature(inFeat, QgsFeatureSink.FastInsert)
            feedback.setProgress(int(current * total))
        return {self.OUTPUT: dest_id}
Exemple #15
0
    def __snap(self):

        self.report_message.emit(self.layer_id, 'preparing ...')
        orig_layer = QgsMapLayerRegistry.instance().mapLayer(self.layer_id)
        # create a copy of the layer just for editing
        layer = QgsVectorLayer(orig_layer.source(), orig_layer.name(), orig_layer.providerType())
        geom_type = layer.geometryType()
        # layer.wkbType() does not return reliable results
        wkb_type = layer.wkbType()

        if self.create_backup:
            self.report_message.emit(self.layer_id, 'creating backup ...')
            self.__create_backup_file(orig_layer)

        self.report_message.emit(self.layer_id, 'preparing ...')
        layer.startEditing()
        request = QgsFeatureRequest().setFilterRect(self.snap_extent)
        total_features = 0
        for feature in layer.getFeatures(request):
            total_features += 1

        QgsMessageLog.logMessage(self.plugin.tr('Features to be snapped in layer <{0}>: {1}').
                                 format(orig_layer.name(), total_features), self.plugin.tr('Vertex Tools'),
                                 QgsMessageLog.INFO)
        if total_features == 0:
            self.report_message.emit(self.layer_id, 'no features')

        count = 0
        for feature in layer.getFeatures(request):
            with QMutexLocker(self.mutex):
                if self.stopped:
                    layer.rollBack()
                    return

            if geom_type == QGis.Point:
                snapped_geom = self.__point_grid(feature, wkb_type)
            elif geom_type == QGis.Line:
                snapped_geom = self.__line_grid(feature, wkb_type)
            elif geom_type == QGis.Polygon:
                snapped_geom = self.__polygon_grid(feature, wkb_type)

            layer.changeGeometry(feature.id(), snapped_geom)

            count += 1
            self.run_progressed.emit(self.layer_id, count, total_features)

        layer.commitChanges()

        self.completed = True
Exemple #16
0
    def test_zm(self):
        """Test Z dimension and M value"""
        l = QgsVectorLayer("dbname=%s table='test_z' (geometry) key='id'" % self.dbname, "test_z", "spatialite")
        self.assertTrue(l.isValid())
        self.assertTrue(QgsWkbTypes.hasZ(l.wkbType()))
        feature = l.getFeature(1)
        geom = feature.geometry().constGet()
        self.assertEqual(geom.z(), 1.0)

        l = QgsVectorLayer("dbname=%s table='test_m' (geometry) key='id'" % self.dbname, "test_m", "spatialite")
        self.assertTrue(l.isValid())
        self.assertTrue(QgsWkbTypes.hasM(l.wkbType()))
        feature = l.getFeature(1)
        geom = feature.geometry().constGet()
        self.assertEqual(geom.m(), 1.0)

        l = QgsVectorLayer("dbname=%s table='test_zm' (geometry) key='id'" % self.dbname, "test_zm", "spatialite")
        self.assertTrue(l.isValid())
        self.assertTrue(QgsWkbTypes.hasZ(l.wkbType()))
        self.assertTrue(QgsWkbTypes.hasM(l.wkbType()))
        feature = l.getFeature(1)
        geom = feature.geometry().constGet()
        self.assertEqual(geom.z(), 1.0)
        self.assertEqual(geom.m(), 1.0)
    def test_zm(self):
        """Test Z dimension and M value"""
        l = QgsVectorLayer("dbname=%s table='test_z' (geometry) key='id'" % self.dbname, "test_z", "spatialite")
        self.assertTrue(l.isValid())
        self.assertTrue(QgsWkbTypes.hasZ(l.wkbType()))
        feature = l.getFeature(1)
        geom = feature.geometry().constGet()
        self.assertEqual(geom.z(), 1.0)

        l = QgsVectorLayer("dbname=%s table='test_m' (geometry) key='id'" % self.dbname, "test_m", "spatialite")
        self.assertTrue(l.isValid())
        self.assertTrue(QgsWkbTypes.hasM(l.wkbType()))
        feature = l.getFeature(1)
        geom = feature.geometry().constGet()
        self.assertEqual(geom.m(), 1.0)

        l = QgsVectorLayer("dbname=%s table='test_zm' (geometry) key='id'" % self.dbname, "test_zm", "spatialite")
        self.assertTrue(l.isValid())
        self.assertTrue(QgsWkbTypes.hasZ(l.wkbType()))
        self.assertTrue(QgsWkbTypes.hasM(l.wkbType()))
        feature = l.getFeature(1)
        geom = feature.geometry().constGet()
        self.assertEqual(geom.z(), 1.0)
        self.assertEqual(geom.m(), 1.0)
Exemple #18
0
    def testTriangleTINPolyhedralSurface(self):
        """ Test support for Triangles (mapped to Polygons) """
        testsets = (
            ("Triangle((0 0, 0 1, 1 1, 0 0))", QgsWkbTypes.Triangle, "Triangle ((0 0, 0 1, 1 1, 0 0))"),
            ("Triangle Z((0 0 1, 0 1 2, 1 1 3, 0 0 1))", QgsWkbTypes.TriangleZ,
             "TriangleZ ((0 0 1, 0 1 2, 1 1 3, 0 0 1))"),
            ("Triangle M((0 0 4, 0 1 5, 1 1 6, 0 0 4))", QgsWkbTypes.TriangleM,
             "TriangleM ((0 0 4, 0 1 5, 1 1 6, 0 0 4))"),
            ("Triangle ZM((0 0 0 1, 0 1 2 3, 1 1 4 5, 0 0 0 1))", QgsWkbTypes.TriangleZM,
             "TriangleZM ((0 0 0 1, 0 1 2 3, 1 1 4 5, 0 0 0 1))"),

            ("TIN (((0 0, 0 1, 1 1, 0 0)),((0 0, 1 0, 1 1, 0 0)))", QgsWkbTypes.MultiPolygon,
             "MultiPolygon (((0 0, 0 1, 1 1, 0 0)),((0 0, 1 0, 1 1, 0 0)))"),
            ("TIN Z(((0 0 0, 0 1 1, 1 1 1, 0 0 0)),((0 0 0, 1 0 0, 1 1 1, 0 0 0)))", QgsWkbTypes.MultiPolygonZ,
             "MultiPolygonZ (((0 0 0, 0 1 1, 1 1 1, 0 0 0)),((0 0 0, 1 0 0, 1 1 1, 0 0 0)))"),
            ("TIN M(((0 0 0, 0 1 2, 1 1 3, 0 0 0)),((0 0 0, 1 0 4, 1 1 3, 0 0 0)))", QgsWkbTypes.MultiPolygonM,
             "MultiPolygonM (((0 0 0, 0 1 2, 1 1 3, 0 0 0)),((0 0 0, 1 0 4, 1 1 3, 0 0 0)))"),
            ("TIN ZM(((0 0 0 0, 0 1 1 2, 1 1 1 3, 0 0 0 0)),((0 0 0 0, 1 0 0 4, 1 1 1 3, 0 0 0 0)))",
             QgsWkbTypes.MultiPolygonZM,
             "MultiPolygonZM (((0 0 0 0, 0 1 1 2, 1 1 1 3, 0 0 0 0)),((0 0 0 0, 1 0 0 4, 1 1 1 3, 0 0 0 0)))"),

            ("PolyhedralSurface (((0 0, 0 1, 1 1, 0 0)),((0 0, 1 0, 1 1, 0 0)))", QgsWkbTypes.MultiPolygon,
             "MultiPolygon (((0 0, 0 1, 1 1, 0 0)),((0 0, 1 0, 1 1, 0 0)))"),
            ("PolyhedralSurface Z(((0 0 0, 0 1 1, 1 1 1, 0 0 0)),((0 0 0, 1 0 0, 1 1 1, 0 0 0)))",
             QgsWkbTypes.MultiPolygonZ,
             "MultiPolygonZ (((0 0 0, 0 1 1, 1 1 1, 0 0 0)),((0 0 0, 1 0 0, 1 1 1, 0 0 0)))"),
            ("PolyhedralSurface M(((0 0 0, 0 1 2, 1 1 3, 0 0 0)),((0 0 0, 1 0 4, 1 1 3, 0 0 0)))",
             QgsWkbTypes.MultiPolygonM,
             "MultiPolygonM (((0 0 0, 0 1 2, 1 1 3, 0 0 0)),((0 0 0, 1 0 4, 1 1 3, 0 0 0)))"),
            ("PolyhedralSurface ZM(((0 0 0 0, 0 1 1 2, 1 1 1 3, 0 0 0 0)),((0 0 0 0, 1 0 0 4, 1 1 1 3, 0 0 0 0)))",
             QgsWkbTypes.MultiPolygonZM,
             "MultiPolygonZM (((0 0 0 0, 0 1 1 2, 1 1 1 3, 0 0 0 0)),((0 0 0 0, 1 0 0 4, 1 1 1 3, 0 0 0 0)))")
        )
        for row in testsets:
            datasource = os.path.join(self.basetestpath, 'test.csv')
            with open(datasource, 'wt') as f:
                f.write('id,WKT\n')
                f.write('1,"%s"' % row[0])

            vl = QgsVectorLayer(datasource, 'test', 'ogr')
            self.assertTrue(vl.isValid())
            self.assertEqual(vl.wkbType(), row[1])

            f = QgsFeature()
            self.assertTrue(vl.getFeatures(QgsFeatureRequest(1)).nextFeature(f))
            self.assertTrue(f.geometry())
            self.assertEqual(f.geometry().constGet().asWkt(), row[2])
Exemple #19
0
    def processAlgorithm(self, parameters, context, feedback):
        layers = self.parameterAsLayerList(parameters, self.INPUT_DATASOURCES, context)
        query = self.parameterAsString(parameters, self.INPUT_QUERY, context)
        uid_field = self.parameterAsString(parameters, self.INPUT_UID_FIELD, context)
        geometry_field = self.parameterAsString(parameters, self.INPUT_GEOMETRY_FIELD, context)
        geometry_type = self.parameterAsEnum(parameters, self.INPUT_GEOMETRY_TYPE, context)
        geometry_crs = self.parameterAsCrs(parameters, self.INPUT_GEOMETRY_CRS, context)

        df = QgsVirtualLayerDefinition()
        for layerIdx, layer in enumerate(layers):
            df.addSource('input{}'.format(layerIdx + 1), layer.id())

        if query == '':
            raise QgsProcessingException(
                self.tr('Empty SQL. Please enter valid SQL expression and try again.'))
        else:
            df.setQuery(query)

        if uid_field:
            df.setUid(uid_field)

        if geometry_type == 1:  # no geometry
            df.setGeometryWkbType(QgsWkbTypes.NullGeometry)
        else:
            if geometry_field:
                df.setGeometryField(geometry_field)
            if geometry_type > 1:
                df.setGeometryWkbType(geometry_type - 1)
            if geometry_crs.isValid():
                df.setGeometrySrid(geometry_crs.postgisSrid())

        vLayer = QgsVectorLayer(df.toString(), "temp_vlayer", "virtual")
        if not vLayer.isValid():
            raise QgsProcessingException(vLayer.dataProvider().error().message())

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
                                               vLayer.fields(), vLayer.wkbType() if geometry_type != 1 else 1, vLayer.crs())

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

            sink.addFeature(inFeat, QgsFeatureSink.FastInsert)
            feedback.setProgress(int(current * total))
        return {self.OUTPUT: dest_id}
    def testReadingLayerGeometryTypes(self):

        tests = [(osgeo.ogr.wkbPoint, 'Point (0 0)', QgsWkbTypes.Point, 'Point (0 0)'),
                 (osgeo.ogr.wkbPoint25D, 'Point Z (0 0 1)', QgsWkbTypes.PointZ, 'PointZ (0 0 1)'),
                 (osgeo.ogr.wkbPointM, 'Point M (0 0 1)', QgsWkbTypes.PointM, 'PointM (0 0 1)'),
                 (osgeo.ogr.wkbPointZM, 'Point ZM (0 0 1 2)', QgsWkbTypes.PointZM, 'PointZM (0 0 1 2)'),
                 (osgeo.ogr.wkbLineString, 'LineString (0 0, 1 1)', QgsWkbTypes.MultiLineString, 'MultiLineString ((0 0, 1 1))'),
                 (osgeo.ogr.wkbLineString25D, 'LineString Z (0 0 10, 1 1 10)', QgsWkbTypes.MultiLineStringZ, 'MultiLineStringZ ((0 0 10, 1 1 10))'),
                 (osgeo.ogr.wkbLineStringM, 'LineString M (0 0 10, 1 1 10)', QgsWkbTypes.MultiLineStringM, 'MultiLineStringM ((0 0 10, 1 1 10))'),
                 (osgeo.ogr.wkbLineStringZM, 'LineString ZM (0 0 10 20, 1 1 10 20)', QgsWkbTypes.MultiLineStringZM, 'MultiLineStringZM ((0 0 10 20, 1 1 10 20))'),
                 (osgeo.ogr.wkbPolygon, 'Polygon ((0 0,0 1,1 1,0 0))', QgsWkbTypes.MultiPolygon, 'MultiPolygon (((0 0, 0 1, 1 1, 0 0)))'),
                 (osgeo.ogr.wkbPolygon25D, 'Polygon Z ((0 0 10, 0 1 10, 1 1 10, 0 0 10))', QgsWkbTypes.MultiPolygonZ, 'MultiPolygonZ (((0 0 10, 0 1 10, 1 1 10, 0 0 10)))'),
                 (osgeo.ogr.wkbPolygonM, 'Polygon M ((0 0 10, 0 1 10, 1 1 10, 0 0 10))', QgsWkbTypes.MultiPolygonM, 'MultiPolygonM (((0 0 10, 0 1 10, 1 1 10, 0 0 10)))'),
                 (osgeo.ogr.wkbPolygonZM, 'Polygon ZM ((0 0 10 20, 0 1 10 20, 1 1 10 20, 0 0 10 20))', QgsWkbTypes.MultiPolygonZM, 'MultiPolygonZM (((0 0 10 20, 0 1 10 20, 1 1 10 20, 0 0 10 20)))'),
                 (osgeo.ogr.wkbMultiPoint, 'MultiPoint (0 0,1 1)', QgsWkbTypes.MultiPoint, 'MultiPoint ((0 0),(1 1))'),
                 (osgeo.ogr.wkbMultiPoint25D, 'MultiPoint Z ((0 0 10), (1 1 10))', QgsWkbTypes.MultiPointZ, 'MultiPointZ ((0 0 10),(1 1 10))'),
                 (osgeo.ogr.wkbMultiPointM, 'MultiPoint M ((0 0 10), (1 1 10))', QgsWkbTypes.MultiPointM, 'MultiPointM ((0 0 10),(1 1 10))'),
                 (osgeo.ogr.wkbMultiPointZM, 'MultiPoint ZM ((0 0 10 20), (1 1 10 20))', QgsWkbTypes.MultiPointZM, 'MultiPointZM ((0 0 10 20),(1 1 10 20))'),
                 (osgeo.ogr.wkbMultiLineString, 'MultiLineString ((0 0, 1 1))', QgsWkbTypes.MultiLineString, 'MultiLineString ((0 0, 1 1))'),
                 (osgeo.ogr.wkbMultiLineString25D, 'MultiLineString Z ((0 0 10, 1 1 10))', QgsWkbTypes.MultiLineStringZ, 'MultiLineStringZ ((0 0 10, 1 1 10))'),
                 (osgeo.ogr.wkbMultiLineStringM, 'MultiLineString M ((0 0 10, 1 1 10))', QgsWkbTypes.MultiLineStringM, 'MultiLineStringM ((0 0 10, 1 1 10))'),
                 (osgeo.ogr.wkbMultiLineStringZM, 'MultiLineString ZM ((0 0 10 20, 1 1 10 20))', QgsWkbTypes.MultiLineStringZM, 'MultiLineStringZM ((0 0 10 20, 1 1 10 20))'),
                 (osgeo.ogr.wkbMultiPolygon, 'MultiPolygon (((0 0,0 1,1 1,0 0)))', QgsWkbTypes.MultiPolygon, 'MultiPolygon (((0 0, 0 1, 1 1, 0 0)))'),
                 (osgeo.ogr.wkbMultiPolygon25D, 'MultiPolygon Z (((0 0 10, 0 1 10, 1 1 10, 0 0 10)))', QgsWkbTypes.MultiPolygonZ, 'MultiPolygonZ (((0 0 10, 0 1 10, 1 1 10, 0 0 10)))'),
                 (osgeo.ogr.wkbMultiPolygonM, 'MultiPolygon M (((0 0 10, 0 1 10, 1 1 10, 0 0 10)))', QgsWkbTypes.MultiPolygonM, 'MultiPolygonM (((0 0 10, 0 1 10, 1 1 10, 0 0 10)))'),
                 (osgeo.ogr.wkbMultiPolygonZM, 'MultiPolygon ZM (((0 0 10 20, 0 1 10 20, 1 1 10 20, 0 0 10 20)))', QgsWkbTypes.MultiPolygonZM, 'MultiPolygonZM (((0 0 10 20, 0 1 10 20, 1 1 10 20, 0 0 10 20)))'),
                 ]
        for ogr_type, wkt, qgis_type, expected_wkt in tests:

            filename = 'testPromoteToMulti'
            tmpfile = os.path.join(self.basetestpath, filename)
            ds = osgeo.ogr.GetDriverByName('ESRI Shapefile').CreateDataSource(tmpfile)
            lyr = ds.CreateLayer(filename, geom_type=ogr_type)
            f = osgeo.ogr.Feature(lyr.GetLayerDefn())
            f.SetGeometry(osgeo.ogr.CreateGeometryFromWkt(wkt))
            lyr.CreateFeature(f)
            ds = None

            vl = QgsVectorLayer(tmpfile, 'test', 'ogr')
            self.assertTrue(vl.isValid())
            self.assertEqual(vl.wkbType(), qgis_type)
            f = next(vl.getFeatures())
            self.assertEqual(f.geometry().constGet().asWkt(), expected_wkt)
            del vl

            osgeo.ogr.GetDriverByName('ESRI Shapefile').DeleteDataSource(tmpfile)
Exemple #21
0
 def __init__(self, uri='', providerOptions=QgsDataProvider.ProviderOptions()):
     super().__init__(uri)
     # Use the memory layer to parse the uri
     mlayer = QgsVectorLayer(uri, 'ml', 'memory')
     self.setNativeTypes(mlayer.dataProvider().nativeTypes())
     self._uri = uri
     self._fields = mlayer.fields()
     self._wkbType = mlayer.wkbType()
     self._features = {}
     self._extent = QgsRectangle()
     self._extent.setMinimal()
     self._subset_string = ''
     self._crs = mlayer.crs()
     self._spatialindex = None
     self._provider_options = providerOptions
     if 'index=yes'in self._uri:
         self.createSpatialIndex()
Exemple #22
0
 def __init__(self, uri='', providerOptions=QgsDataProvider.ProviderOptions()):
     super().__init__(uri)
     # Use the memory layer to parse the uri
     mlayer = QgsVectorLayer(uri, 'ml', 'memory')
     self.setNativeTypes(mlayer.dataProvider().nativeTypes())
     self._uri = uri
     self._fields = mlayer.fields()
     self._wkbType = mlayer.wkbType()
     self._features = {}
     self._extent = QgsRectangle()
     self._extent.setMinimal()
     self._subset_string = ''
     self._crs = mlayer.crs()
     self._spatialindex = None
     self._provider_options = providerOptions
     if 'index=yes'in self._uri:
         self.createSpatialIndex()
Exemple #23
0
 def testCurveGeometries(self):
     geomtypes = [
         'CompoundCurveM', 'CurvePolygonM', 'CircularStringM',
         'CompoundCurveZM', 'CurvePolygonZM', 'CircularStringZM',
         'CompoundCurveZ', 'CurvePolygonZ', 'CircularStringZ',
         'CompoundCurve', 'CurvePolygon', 'CircularString'
     ]
     geoms = [
         'CompoundCurveM ((0 -23.43778 10, 0 23.43778 10),CircularStringM (0 23.43778 10, -45 33.43778 10, -90 23.43778 10),(-90 23.43778 10, -90 -23.43778 10),CircularStringM (-90 -23.43778 10, -45 -23.43778 10, 0 -23.43778 10))',
         'CurvePolygonM (CompoundCurveM ((0 -23.43778 10, 0 -15.43778 10, 0 23.43778 10),CircularStringM (0 23.43778 10, -45 100 10, -90 23.43778 10),(-90 23.43778 10, -90 -23.43778 10),CircularStringM (-90 -23.43778 10, -45 -16.43778 10, 0 -23.43778 10)),CompoundCurveM (CircularStringM (-30 0 10, -48 -12 10, -60 0 10, -48 -6 10, -30 0 10)))',
         'CircularStringM (0 0 10, 0.14644660940672 0.35355339059327 10, 0.5 0.5 10, 0.85355339059327 0.35355339059327 10, 1 0 10, 0.85355339059327 -0.35355339059327 10, 0.5 -0.5 10, 0.14644660940672 -0.35355339059327 10, 0 0 10)',
         'CompoundCurveZM ((0 -23.43778 2 10, 0 23.43778 2 10),CircularStringZM (0 23.43778 2 10, -45 33.43778 2 10, -90 23.43778 2 10),(-90 23.43778 2 10, -90 -23.43778 2 10),CircularStringZM (-90 -23.43778 2 10, -45 -23.43778 2 10, 0 -23.43778 2 10))',
         'CurvePolygonZM (CompoundCurveZM ((0 -23.43778 5 10, 0 -15.43778 8 10, 0 23.43778 6 10),CircularStringZM (0 23.43778 6 10, -45 100 6 10, -90 23.43778 6 10),(-90 23.43778 6 10, -90 -23.43778 5 10),CircularStringZM (-90 -23.43778 5 10, -45 -16.43778 5 10, 0 -23.43778 5 10)),CompoundCurveZM (CircularStringZM (-30 0 10 10, -48 -12 10 10, -60 0 10 10, -48 -6 10 10, -30 0 10 10)))',
         'CircularStringZM (0 0 1 10, 0.14644660940672 0.35355339059327 1 10, 0.5 0.5 1 10, 0.85355339059327 0.35355339059327 1 10, 1 0 1 10, 0.85355339059327 -0.35355339059327 1 10, 0.5 -0.5 1 10, 0.14644660940672 -0.35355339059327 1 10, 0 0 1 10)',
         'CompoundCurveZ ((0 -23.43778 2, 0 23.43778 2),CircularStringZ (0 23.43778 2, -45 33.43778 2, -90 23.43778 2),(-90 23.43778 2, -90 -23.43778 2),CircularStringZ (-90 -23.43778 2, -45 -23.43778 2, 0 -23.43778 2))',
         'CurvePolygonZ (CompoundCurveZ ((0 -23.43778 5, 0 -15.43778 8, 0 23.43778 6),CircularStringZ (0 23.43778 6, -45 100 6, -90 23.43778 6),(-90 23.43778 6, -90 -23.43778 5),CircularStringZ (-90 -23.43778 5, -45 -16.43778 5, 0 -23.43778 5)),CompoundCurveZ (CircularStringZ (-30 0 10, -48 -12 10, -60 0 10, -48 -6 10, -30 0 10)))',
         'CircularStringZ (0 0 1, 0.14644660940672 0.35355339059327 1, 0.5 0.5 1, 0.85355339059327 0.35355339059327 1, 1 0 1, 0.85355339059327 -0.35355339059327 1, 0.5 -0.5 1, 0.14644660940672 -0.35355339059327 1, 0 0 1)',
         'CompoundCurve ((0 -23.43778, 0 23.43778),CircularString (0 23.43778, -45 33.43778, -90 23.43778),(-90 23.43778, -90 -23.43778),CircularString (-90 -23.43778, -45 -23.43778, 0 -23.43778))',
         'CurvePolygon (CompoundCurve ((0 -23.43778, 0 -15.43778, 0 23.43778),CircularString (0 23.43778, -45 100, -90 23.43778),(-90 23.43778, -90 -23.43778),CircularString (-90 -23.43778, -45 -16.43778, 0 -23.43778)),CompoundCurve (CircularString (-30 0, -48 -12, -60 0, -48 -6, -30 0)))',
         'CircularString (0 0, 0.14644660940672 0.35355339059327, 0.5 0.5, 0.85355339059327 0.35355339059327, 1 0, 0.85355339059327 -0.35355339059327, 0.5 -0.5, 0.14644660940672 -0.35355339059327, 0 0)'
     ]
     for idx, t in enumerate(geoms):
         f = QgsFeature()
         g = QgsGeometry.fromWkt(t)
         f.setGeometry(g)
         layer = QgsVectorLayer(geomtypes[idx] + "?crs=epsg:4326",
                                "addfeat", "memory")
         pr = layer.dataProvider()
         pr.addFeatures([f])
         uri = self.dbconn + ' table="qgis_test"."new_table_curvegeom_' + str(
             idx) + '" sql='
         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(), g.wkbType())
         self.assertEqual(new_layer.crs().authid(), 'EPSG:4326')
         result_geoms = [
             f.geometry().asWkt(14) for f in new_layer.getFeatures()
         ]
         self.assertEqual(result_geoms, [t])
         self.execSQLCommand(
             'DROP TABLE IF EXISTS [qgis_test].[new_table_curvegeom_{}]'.
             format(str(idx)))
Exemple #24
0
 def processAlgorithm(self, parameters, context, feedback):
     """Actual processing steps."""
     uri = self._buildUri(parameters, context)
     vlayer = QgsVectorLayer(uri, "layername", "delimitedtext")
     if not vlayer.isValid():
         QgsMessageLog.logMessage(
             'CSV Tools: Cannot add layer with URI {}'.format(
                 vlayer.dataProvider().dataSourceUri()
             ),
             'Processing',
             Qgis.Critical
         )
         QgsMessageLog.logMessage(
             'CSV Tools: {}'.format(
                 vlayer.dataProvider().error().message()
             ),
             'Processing',
             Qgis.Critical
         )
         raise QgsProcessingException(
             '{}: {}'.format(
                 vlayer.dataProvider().dataSourceUri(),
                 vlayer.dataProvider().error().message()
             )
         )
     # We consider that having CSV data loaded is half the way
     feedback.setProgress(50)
     (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT,
                                            context, vlayer.fields(),
                                            vlayer.wkbType(), vlayer.crs())
     if sink is None:
         raise QgsProcessingException(
             self.invalidSinkError(parameters, self.OUTPUT)
         )
     count = vlayer.featureCount()
     total = 100.0 / count if count else 0
     features = vlayer.getFeatures()
     for i, feature in enumerate(features):
         if feedback.isCanceled():
             break
         sink.addFeature(feature, QgsFeatureSink.FastInsert)
         # Update the progress bar
         feedback.setProgress(50 + int(i * total))
     return {self.OUTPUT: dest_id}
    def test_046_M(self):
        # Create test layer
        srcpath = os.path.join(TEST_DATA_DIR, 'provider')
        basetestfile = os.path.join(srcpath, 'delimited_xyzm.csv')

        url = MyUrl.fromLocalFile(basetestfile)
        url.addQueryItem("crs", "epsg:4326")
        url.addQueryItem("type", "csv")
        url.addQueryItem("xField", "X")
        url.addQueryItem("yField", "Y")
        url.addQueryItem("mField", "M")
        url.addQueryItem("spatialIndex", "no")
        url.addQueryItem("subsetIndex", "no")
        url.addQueryItem("watchFile", "no")

        vl = QgsVectorLayer(url.toString(), 'test', 'delimitedtext')
        assert vl.isValid(), "{} is invalid".format(basetestfile)
        assert vl.wkbType() == QgsWkbTypes.PointM, "wrong wkb type, should be PointM"
        assert vl.getFeature(2).geometry().asWkt() == "PointM (-71.12300000000000466 78.23000000000000398 2)", "wrong PointM geometry"
            def f():
                crs = iface.mapCanvas().mapRenderer().destinationCrs()
                uri = "%s?srsname=%s&typename=geonode:%s&version=1.0.0&request=GetFeature&service=WFS" % (url, crs.authid(), name)
                qgslayer = QgsVectorLayer(uri, name, "WFS")
                if not qgslayer.isValid():
                    raise Exception ("Layer at %s is not a valid layer" % uri)

                fieldname = self._getTimeField(qgslayer)

                if fieldname is None:
                    QgsMapLayerRegistry.instance().addMapLayers([qgslayer])
                else:
                    memlayer = QgsVectorLayer("%s?crs=%s" % (GEOM_TYPE_MAP[qgslayer.wkbType()], crs.authid()), name, "memory")
                    memlayer.startEditing()
                    for field in qgslayer.pendingFields():
                        memlayer.addAttribute(field)
                    for feat in qgslayer.getFeatures():
                        memlayer.addFeatures([feat])
                    memlayer.commitChanges()
                    QgsMapLayerRegistry.instance().addMapLayers([memlayer])
                    memlayer.setSelectedFeatures([])
                    addWfsAnimation(memlayer, fieldname)
    def testShzSupport(self):
        ''' Test support for single layer compressed shapefiles (.shz) '''

        if int(osgeo.gdal.VersionInfo('VERSION_NUM')) < GDAL_COMPUTE_VERSION(
                3, 1, 0):
            return

        tmpfile = os.path.join(self.basetestpath, 'testShzSupport.shz')
        ds = osgeo.ogr.GetDriverByName('ESRI Shapefile').CreateDataSource(
            tmpfile)
        lyr = ds.CreateLayer('testShzSupport', geom_type=osgeo.ogr.wkbPoint)
        lyr.CreateField(osgeo.ogr.FieldDefn('attr', osgeo.ogr.OFTInteger))
        f = osgeo.ogr.Feature(lyr.GetLayerDefn())
        f.SetField('attr', 1)
        f.SetGeometry(osgeo.ogr.CreateGeometryFromWkt('POINT(0 0)'))
        lyr.CreateFeature(f)
        f = None
        ds = None

        vl = QgsVectorLayer(tmpfile, 'test', 'ogr')
        self.assertTrue(vl.isValid())
        self.assertEqual(vl.wkbType(), QgsWkbTypes.Point)
        f = next(vl.getFeatures())
        assert f['attr'] == 1
        self.assertEqual(f.geometry().constGet().asWkt(), 'Point (0 0)')

        self.assertTrue(vl.startEditing())
        self.assertTrue(vl.changeAttributeValue(f.id(), 0, -1))
        self.assertTrue(vl.commitChanges())

        f = next(vl.getFeatures())
        assert f['attr'] == -1

        # Check DataItem
        registry = QgsApplication.dataItemProviderRegistry()
        ogrprovider = next(provider for provider in registry.providers()
                           if provider.name() == 'OGR')
        item = ogrprovider.createDataItem(tmpfile, None)
        self.assertTrue(item.uri().endswith('testShzSupport.shz'))
Exemple #28
0
    def testInsertPolygonInMultiPolygon(self):
        layer = QgsVectorLayer("MultiPolygon?crs=epsg:4326&field=id:integer",
                               "addfeat", "memory")
        pr = layer.dataProvider()
        f = QgsFeature()
        f.setAttributes([1])
        f.setGeometry(
            QgsGeometry.fromWkt(
                'MultiPolygon(((0 0, 1 0, 1 1, 0 1, 0 0)),((10 0, 11 0, 11 1, 10 1, 10 0)))'
            ))
        pr.addFeatures([f])

        uri = '{} table="qgis_test"."new_table_multipolygon" 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.MultiPolygon)
        geom = [f.geometry().asWkt() for f in new_layer.getFeatures()]
        self.assertEqual(geom, [
            'MultiPolygon (((0 0, 1 0, 1 1, 0 1, 0 0)),((10 0, 11 0, 11 1, 10 1, 10 0)))'
        ])

        # add single part
        f2 = QgsFeature()
        f2.setAttributes([2])
        f2.setGeometry(
            QgsGeometry.fromWkt('Polygon((30 0, 31 0, 31 1, 30 1, 30 0))'))
        self.assertTrue(new_layer.dataProvider().addFeatures([f2]))

        # should become multipart
        geom = [f.geometry().asWkt() for f in new_layer.getFeatures()]
        self.assertEqual(geom, [
            'MultiPolygon (((0 0, 1 0, 1 1, 0 1, 0 0)),((10 0, 11 0, 11 1, 10 1, 10 0)))',
            'MultiPolygon (((30 0, 31 0, 31 1, 30 1, 30 0)))'
        ])
Exemple #29
0
    def vector_to_gdf(cls,
                      qgis_vector_lyr: QgsVectorLayer) -> gpd.GeoDataFrame:
        def _catch_null(attribute):
            try:
                if attribute.isNull():
                    return None
            except AttributeError:
                return attribute

        feature_list = [[_catch_null(attr) for attr in feature.attributes()] +
                        [feature.geometry().asWkt()]
                        for feature in qgis_vector_lyr.getFeatures()]

        columns = [field.name() for field in qgis_vector_lyr.fields()]
        columns.append('geometry')
        df = pd.DataFrame(feature_list, columns=columns)
        df['geometry'] = df['geometry'].apply(wkt.loads)
        if qgis_vector_lyr.wkbType() == 6:  # if geometry is MultiPolygon
            df['geometry'] = df['geometry'].apply(lambda x: x[0]
                                                  if len(x) == 1 else x)
        return gpd.GeoDataFrame(df,
                                crs=qgis_vector_lyr.crs().toWkt(),
                                geometry='geometry')
Exemple #30
0
    def test_saveLayerToGpkg(self):
        testLayerA = QgsVectorLayer(('{type}?crs=epsg:27700&index=yes'.format(
            type=QgsWkbTypes.displayString(QgsWkbTypes.MultiLineString))),
                                    'testA', 'memory')
        self.assertEqual(testLayerA.wkbType(), QgsWkbTypes.MultiLineString)
        #print ('++++++ testLayerA type: {}'.format(QgsWkbTypes.displayString(testLayerA.wkbType())))

        testProviderA = testLayerA.dataProvider()

        testLineString1 = QgsGeometry.fromPolylineXY(
            [QgsPointXY(0, 0), QgsPointXY(1, 0)])

        testProviderA.addAttributes([
            QgsField("GeometryID", QVariant.String),
            QgsField("RestrictionTypeID", QVariant.Int),
            QgsField("GeomShapeID", QVariant.Int),
            QgsField("AzimuthToRoadCentreLine", QVariant.Double)
        ])
        testFieldsA = testProviderA.fields()
        """for field in testFields:
            print ('** {}'.format(field.name()))"""

        testFeature1 = QgsFeature(testFieldsA)
        testFeature1.setGeometry(testLineString1)
        testFeature1.setAttributes(["Smith", 101, 1, 0])
        testProviderA.addFeatures([testFeature1])
        testLayerA.reload()

        fileName = 'C:\\Users\\marie_000\\Documents\\MHTC\\tmp\\test1.gpkg'
        self.testClass.saveLayerToGpkg(testLayerA, fileName)

        ds = ogr.Open(fileName)
        lyr = ds.GetLayerByName('testA')
        self.assertIsNotNone(lyr)
        f = lyr.GetNextFeature()
        self.assertEqual(f['GeometryID'], 'Smith')
Exemple #31
0
    def test_processLayer(self):
        testLayerA = QgsVectorLayer(('{type}?crs=epsg:27700&index=yes'.format(
            type=QgsWkbTypes.displayString(QgsWkbTypes.MultiLineString))),
                                    'testA', 'memory')
        self.assertEqual(testLayerA.wkbType(), QgsWkbTypes.MultiLineString)
        # print ('++++++ testLayerA type: {}'.format(QgsWkbTypes.displayString(testLayerA.wkbType())))

        testProviderA = testLayerA.dataProvider()

        testLineString1 = QgsGeometry.fromPolylineXY(
            [QgsPointXY(0, 0), QgsPointXY(1, 0)])

        testProviderA.addAttributes([
            QgsField("GeometryID", QVariant.String),
            QgsField("RestrictionTypeID", QVariant.Int),
            QgsField("GeomShapeID", QVariant.Int),
            QgsField("AzimuthToRoadCentreLine", QVariant.Double)
        ])
        testFieldsA = testProviderA.fields()
        """for field in testFields:
            print ('** {}'.format(field.name()))"""

        testFeature1 = QgsFeature(testFieldsA)
        testFeature1.setGeometry(testLineString1)
        testFeature1.setAttributes(["Smith", 101, 1, 0])
        testProviderA.addFeatures([testFeature1])
        testLayerA.reload()

        requiredFields = ["GeometryID", "RestrictionTypeID"]
        outputLayersList = self.testClass.processLayer(testLayerA,
                                                       requiredFields)
        self.assertEqual(len(outputLayersList), 1)
        self.assertEqual(len(outputLayersList[0][1].fields()), 2)

        # TODO: Need to include tests for relations - finding lookup fields and returning values ...
        """ Cases are:
Exemple #32
0
 def from_layer(layer: QgsVectorLayer) -> 'LayerType':
     for l_type in LayerType:
         if layer.wkbType() in l_type.wkb_types:
             return l_type
Exemple #33
0
    def testWFS10(self):
        """Test WFS 1.0 read-only"""

        endpoint = self.__class__.basetestpath + '/fake_qgis_http_endpoint_WFS1.0'

        with open(sanitize(endpoint, '?SERVICE=WFS?REQUEST=GetCapabilities?VERSION=1.0.0'), 'wb') as f:
            f.write("""
<WFS_Capabilities version="1.0.0" xmlns="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc">
  <FeatureTypeList>
    <FeatureType>
      <Name>my:typename</Name>
      <Title>Title</Title>
      <Abstract>Abstract</Abstract>
      <SRS>EPSG:4326</SRS>
      <LatLongBoundingBox minx="-71.123" miny="66.33" maxx="-65.32" maxy="78.3"/>
    </FeatureType>
  </FeatureTypeList>
</WFS_Capabilities>""")

        with open(sanitize(endpoint, '?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=1.0.0&TYPENAME=my:typename'), 'wb') as f:
            f.write("""
<xsd:schema xmlns:my="http://my" xmlns:gml="http://www.opengis.net/gml" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://my">
  <xsd:import namespace="http://www.opengis.net/gml"/>
  <xsd:complexType name="my:typenameType">
    <xsd:complexContent>
      <xsd:extension base="gml:AbstractFeatureType">
        <xsd:sequence>
          <xsd:element maxOccurs="1" minOccurs="0" name="INTFIELD" nillable="true" type="xsd:int"/>
          <xsd:element maxOccurs="1" minOccurs="0" name="GEOMETRY" nillable="true" type="xsd:int"/>
          <xsd:element maxOccurs="1" minOccurs="0" name="longfield" nillable="true" type="xsd:long"/>
          <xsd:element maxOccurs="1" minOccurs="0" name="stringfield" nillable="true" type="xsd:string"/>
          <xsd:element maxOccurs="1" minOccurs="0" name="geometryProperty" nillable="true" type="gml:PointPropertyType"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>
  <xsd:element name="typename" substitutionGroup="gml:_Feature" type="my:typenameType"/>
</xsd:schema>
""")

        vl = QgsVectorLayer(u"url='http://" + endpoint + u"' typename='my:typename' version='1.0.0'", u'test', u'WFS')
        assert vl.isValid()
        self.assertEqual(vl.wkbType(), QgsWKBTypes.Point)
        self.assertEqual(len(vl.fields()), 4)
        self.assertEqual(vl.featureCount(), 0)
        reference = QgsGeometry.fromRect(
            QgsRectangle(-71.123, 66.33, -65.32, 78.3))
        vl_extent = QgsGeometry.fromRect(vl.extent())
        assert QgsGeometry.compare(vl_extent.asPolygon(), reference.asPolygon(), 0.00001), 'Expected {}, got {}'.format(reference.exportToWkt(), vl_extent.exportToWkt())

        with open(sanitize(endpoint, '?SERVICE=WFS&REQUEST=GetFeature&VERSION=1.0.0&TYPENAME=my:typename&SRSNAME=EPSG:4326'), 'wb') as f:
            f.write("""
<wfs:FeatureCollection
                       xmlns:wfs="http://www.opengis.net/wfs"
                       xmlns:gml="http://www.opengis.net/gml"
                       xmlns:my="http://my">
  <gml:boundedBy><gml:null>unknown</gml:null></gml:boundedBy>
  <gml:featureMember>
    <my:typename fid="typename.0">
      <my:geometryProperty>
          <gml:Point srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"><gml:coordinates decimal="." cs="," ts=" ">2,49</gml:coordinates></gml:Point></my:geometryProperty>
      <my:INTFIELD>1</my:INTFIELD>
      <my:GEOMETRY>2</my:GEOMETRY>
      <my:longfield>1234567890123</my:longfield>
      <my:stringfield>foo</my:stringfield>
    </my:typename>
  </gml:featureMember>
</wfs:FeatureCollection>""")

        values = [f['INTFIELD'] for f in vl.getFeatures()]
        self.assertEqual(values, [1])

        values = [f['GEOMETRY'] for f in vl.getFeatures()]
        self.assertEqual(values, [2])

        values = [f['longfield'] for f in vl.getFeatures()]
        self.assertEqual(values, [1234567890123])

        values = [f['stringfield'] for f in vl.getFeatures()]
        self.assertEqual(values, ['foo'])

        got = [f.geometry() for f in vl.getFeatures()][0].geometry()
        self.assertEqual((got.x(), got.y()), (2.0, 49.0))

        self.assertEqual(vl.featureCount(), 1)

        self.assertEqual(vl.dataProvider().capabilities(), 0)

        (ret, _) = vl.dataProvider().addFeatures([QgsFeature()])
        assert not ret

        assert not vl.dataProvider().deleteFeatures([0])
Exemple #34
0
    def test_valid_import_geom_3d_to_db_gpkg(self):
        print(
            '\nINFO: Validating ETL-Model from [ Point, PointZ, PointM, PointZM ] to Point geometries...'
        )
        result = self.db_pg.test_connection()
        result_distinct = self.db_distinct_geoms.test_connection()
        self.assertTrue(result[0],
                        'The test connection is not working for empty db')
        self.assertTrue(result_distinct[0],
                        'The test connection is not working for distinct db')
        self.assertIsNotNone(self.db_pg.names.OP_BOUNDARY_POINT_T,
                             'Names is None')

        test_layer = self.qgis_utils.get_layer(
            self.db_pg, self.db_pg.names.OP_BOUNDARY_POINT_T, load=True)

        print("Validating Point to Point")
        uri = self.gpkg_path + '|layername={layername}'.format(
            layername='points')
        point_layer = QgsVectorLayer(uri, 'points', 'ogr')
        self.assertTrue(point_layer.isValid())
        self.assertEqual(point_layer.wkbType(), QgsWkbTypes.Point)
        run_etl_model(self.db_pg.names, point_layer, test_layer,
                      self.db_pg.names.OP_BOUNDARY_POINT_T)
        print("Info: Validating geometry Point...")
        self.assertEqual(test_layer.wkbType(), QgsWkbTypes.PointZ)
        self.assertEqual(test_layer.featureCount(), 51)

        delete_features(test_layer)
        self.assertEqual(test_layer.featureCount(), 0)

        print("Validating PointZ to Point")
        uri = self.gpkg_path + '|layername={layername}'.format(
            layername='points_Z')
        point_layer = QgsVectorLayer(uri, 'points_Z', 'ogr')
        self.assertTrue(point_layer.isValid())
        self.assertIn(point_layer.wkbType(),
                      [QgsWkbTypes.PointZ, QgsWkbTypes.Point25D])
        output = run_etl_model(self.db_pg.names, point_layer, test_layer,
                               self.db_pg.names.OP_BOUNDARY_POINT_T)
        print("Info: Validating geometry PointZ...", test_layer.wkbType())
        self.assertEqual(test_layer.wkbType(), QgsWkbTypes.PointZ)
        self.assertEqual(test_layer.featureCount(), 51)

        delete_features(test_layer)
        self.assertEqual(test_layer.featureCount(), 0)

        print("Validating PointM To Point")
        uri = self.gpkg_path + '|layername={layername}'.format(
            layername='points_M')
        point_layer = QgsVectorLayer(uri, 'points', 'ogr')
        self.assertTrue(point_layer.isValid())
        self.assertEqual(point_layer.wkbType(), QgsWkbTypes.PointM)
        run_etl_model(self.db_pg.names, point_layer, test_layer,
                      self.db_pg.names.OP_BOUNDARY_POINT_T)
        print("Info: Validating geometry PointM...", test_layer.wkbType())
        self.assertEqual(test_layer.wkbType(), QgsWkbTypes.PointZ)
        self.assertEqual(test_layer.featureCount(), 51)

        delete_features(test_layer)
        self.assertEqual(test_layer.featureCount(), 0)

        # PointZM To Point
        print("Validating PointZM To Point")
        uri = self.gpkg_path + '|layername={layername}'.format(
            layername='points_ZM')
        point_layer = QgsVectorLayer(uri, 'points', 'ogr')
        self.assertTrue(point_layer.isValid())
        self.assertEqual(point_layer.wkbType(), QgsWkbTypes.PointZM)
        run_etl_model(self.db_pg.names, point_layer, test_layer,
                      self.db_pg.names.OP_BOUNDARY_POINT_T)
        print("Info: Validating geometry PointZM...", test_layer.wkbType())
        self.assertEqual(test_layer.wkbType(), QgsWkbTypes.PointZ)
        self.assertEqual(test_layer.featureCount(), 51)

        delete_features(test_layer)
        self.assertEqual(test_layer.featureCount(), 0)
Exemple #35
0
    def processAlgorithm(self, parameters, context, feedback):

        # Dummy function to enable running an alg inside an alg
        def no_post_process(alg, context, feedback):
            pass

        # Retrieve parameters
        connection = self.parameterAsString(parameters, self.DATABASE, context)
        db = postgis.GeoDB.from_name(connection)

        schema = self.parameterAsString(parameters, self.SCHEMA, context)
        geopackage = parameters[self.GEOPACKAGE]

        # Debugging info
        feedback.pushInfo('Parâmetros de entrada')
        feedback.pushInfo('connection = ' + connection)
        feedback.pushInfo('db = ' + str(db))
        feedback.pushInfo('schema = ' + schema)
        feedback.pushInfo('geopackage = ' + geopackage)
        feedback.pushInfo('')

        # Raise error if reamb isn't in schema name
        if not 'reamb' in schema:
            raise QgsProcessingException(
                'a palavra reamb precisa fazer parte do nome do esquema')

        # Connect with Geopackage
        feedback.pushInfo('Listing non-empty layers from geopackage')
        with lite.connect(geopackage) as con:
            feedback.pushInfo('Con = ' + str(con))

            layers_import = []  # will store the non-empty tables

            # Create cursor
            cur = con.cursor()

            # Fetch layer names
            cur.execute("SELECT table_name FROM gpkg_geometry_columns")
            rows = cur.fetchall()
            layer_names = [camada[0] for camada in rows]
            feedback.pushInfo('Layers = ' + str(layer_names))

            # Append non-empty geometry layers to list
            for layer in layer_names:
                # Count rows
                cur.execute("SELECT COUNT(1) FROM {}".format(layer))

                rows = cur.fetchall()
                rows_count = rows[0][0]
                #feedback.pushInfo('Rows = ' + str(rows_count))

                # Append to list
                if rows_count > 0:
                    #feedback.pushInfo('Table non-empty = ' + str(rows_count))
                    layers_import.append(layer)

        feedback.pushInfo('Non-empty tables = ' + str(layers_import))
        feedback.pushInfo('')

        # Connect with PostGIS database
        uri = db.uri

        con = psycopg2.connect(user=uri.username(),
                               password=uri.password(),
                               host=uri.host(),
                               port=uri.port(),
                               database=uri.database())

        feedback.pushInfo('Uri = ' + str(uri))
        feedback.pushInfo('Uri text = ' + uri.uri())
        feedback.pushInfo('Connection = ' + str(con))

        # Clean PostGIS schema if marked
        #cleanSchema = self.parameterAsBool(parameters, self.CLEAN_SCHEMA, context)
        cleanSchema = False

        if cleanSchema:
            with con:
                select_schema_tables = "SELECT table_name FROM information_schema.tables " \
                                        "WHERE table_type = '{}' AND table_schema = '{}'".format('BASE TABLE', schema)

                cur = con.cursor()

                cur.execute(select_schema_tables)

                rows = cur.fetchall()

                schema_tables = [table[0] for table in rows]

                for table in schema_tables:
                    feedback.pushInfo("Deleting from {}.{}".format(
                        schema, table))
                    cur.execute("DELETE FROM {}.{}".format(schema, table))
                    con.commit()

        cur.close()
        con.close()

        feedback.pushInfo('')

        # =============================================================================
        #         # Testing
        #         nome = 'cbge_trecho_arruamento_l'
        #         # QGIS Vector Layer from geopackage layer
        #         uri_geopackage = geopackage + '|layername=' + nome
        #         vlayer = QgsVectorLayer(uri_geopackage, 'geopackage_layer', 'ogr')
        #
        #         # Use database table as QGIS Vector Layer
        #         uri_tabela = uri
        #         uri_tabela.setDataSource(schema, nome, 'geom')
        #         uri_tabela.setWkbType(vlayer.wkbType())
        #         uri_tabela.setSrid(str(vlayer.sourceCrs().postgisSrid()))
        #         target = QgsVectorLayer(uri_tabela.uri(), 'teste', 'postgres')
        #         feedback.pushInfo(uri_tabela.uri())
        #         feedback.pushInfo('Validade = ' + str(target.isValid()))
        #
        #
        #         processing.run("script:appendfeaturestolayer", {'SOURCE_LAYER':vlayer, 'TARGET_LAYER':target, 'ACTION_ON_DUPLICATE':0}, context=context, feedback=feedback, onFinish=no_post_process)
        # =============================================================================

        # Import layers
        for layer in layers_import:
            feedback.pushInfo("Importing {}.{}".format(schema, layer))

            # QGIS Vector Layer from source
            uri_geopackage = geopackage + '|layername=' + layer
            source = QgsVectorLayer(uri_geopackage, 'geopackage_layer', 'ogr')
            if not source.isValid():
                raise QgsProcessingException('Source layer not valid')

            # QGIS Vector Layer from target
            uri_table = uri
            uri_table.setDataSource(schema, layer, 'geom')
            uri_table.setWkbType(source.wkbType())
            uri_table.setSrid(str(source.sourceCrs().postgisSrid()))
            target = QgsVectorLayer(uri_table.uri(), 'schema_table',
                                    'postgres')
            if not target.isValid():
                raise QgsProcessingException('Target layer not valid')

            # Run QGIS script for importing
            processing.run("script:appendfeaturestolayer", {
                'SOURCE_LAYER': source,
                'TARGET_LAYER': target,
                'ACTION_ON_DUPLICATE': 0
            },
                           context=context,
                           feedback=feedback,
                           onFinish=no_post_process)
            feedback.pushInfo('')

        return {'Result': 'Layers imported'}
    def run(self):
        self.mutex.lock()
        self.stopMe = 0
        self.mutex.unlock()

        interrupted = False

        # create attribute list with uniquie fields
        # from all selected layers
        mergedFields = []
        self.emit(SIGNAL("rangeChanged( PyQt_PyObject )"), len(self.shapes))
        self.emit(SIGNAL("checkStarted()"))

        shapeIndex = 0
        fieldMap = {}
        for fileName in self.shapes:
            layerPath = QFileInfo(self.baseDir + "/" + fileName).absoluteFilePath()
            newLayer = QgsVectorLayer(layerPath, QFileInfo(layerPath).baseName(), "ogr")
            if not newLayer.isValid():
                continue

            newLayer.setProviderEncoding(self.inputEncoding)
            vprovider = newLayer.dataProvider()
            fieldMap[shapeIndex] = {}
            fieldIndex = 0
            for layerField in vprovider.fields():
                fieldFound = False
                for mergedFieldIndex, mergedField in enumerate(mergedFields):
                    if mergedField.name() == layerField.name() and mergedField.type() == layerField.type():
                        fieldFound = True
                        fieldMap[shapeIndex][fieldIndex] = mergedFieldIndex

                        if mergedField.length() < layerField.length():
                            # suit the field size to the field of this layer
                            mergedField.setLength(layerField.length())
                        break

                if not fieldFound:
                    fieldMap[shapeIndex][fieldIndex] = len(mergedFields)
                    mergedFields.append(layerField)

                fieldIndex += 1

            shapeIndex += 1
            self.emit(SIGNAL("featureProcessed()"))
        self.emit(SIGNAL("checkFinished()"))

        # get information about shapefiles
        layerPath = QFileInfo(self.baseDir + "/" + self.shapes[0]).absoluteFilePath()
        newLayer = QgsVectorLayer(layerPath, QFileInfo(layerPath).baseName(), "ogr")
        self.crs = newLayer.crs()
        self.geom = newLayer.wkbType()
        vprovider = newLayer.dataProvider()

        fields = QgsFields()
        for f in mergedFields:
            fields.append(f)

        writer = QgsVectorFileWriter(
            self.outputFileName, self.outputEncoding,
            fields, self.geom, self.crs)

        shapeIndex = 0
        for fileName in self.shapes:
            layerPath = QFileInfo(self.baseDir + "/" + fileName).absoluteFilePath()
            newLayer = QgsVectorLayer(layerPath, QFileInfo(layerPath).baseName(), "ogr")
            if not newLayer.isValid():
                continue
            newLayer.setProviderEncoding(self.inputEncoding)
            vprovider = newLayer.dataProvider()
            nFeat = vprovider.featureCount()
            self.emit(SIGNAL("rangeChanged( PyQt_PyObject )"), nFeat)
            self.emit(SIGNAL("fileNameChanged( PyQt_PyObject )"), fileName)
            inFeat = QgsFeature()
            outFeat = QgsFeature()
            inGeom = QgsGeometry()
            fit = vprovider.getFeatures()
            while fit.nextFeature(inFeat):
                mergedAttrs = [""] * len(mergedFields)

                # fill available attributes with values
                fieldIndex = 0
                for v in inFeat.attributes():
                    if shapeIndex in fieldMap and fieldIndex in fieldMap[shapeIndex]:
                        mergedAttrs[fieldMap[shapeIndex][fieldIndex]] = v
                    fieldIndex += 1

                if inFeat.geometry() is not None:
                    inGeom = QgsGeometry(inFeat.geometry())
                    outFeat.setGeometry(inGeom)
                outFeat.setAttributes(mergedAttrs)
                writer.addFeature(outFeat)
                self.emit(SIGNAL("featureProcessed()"))

            self.emit(SIGNAL("shapeProcessed()"))
            self.mutex.lock()
            s = self.stopMe
            self.mutex.unlock()

            if s == 1:
                interrupted = True
                break

            shapeIndex += 1

        del writer

        if not interrupted:
            self.emit(SIGNAL("processingFinished()"))
        else:
            self.emit(SIGNAL("processingInterrupted()"))
Exemple #37
0
    def processAlgorithm(self, parameters, context, feedback):
        layers = self.parameterAsLayerList(parameters, self.INPUT_DATASOURCES,
                                           context)
        query = self.parameterAsString(parameters, self.INPUT_QUERY, context)
        uid_field = self.parameterAsString(parameters, self.INPUT_UID_FIELD,
                                           context)
        geometry_field = self.parameterAsString(parameters,
                                                self.INPUT_GEOMETRY_FIELD,
                                                context)
        geometry_type = self.parameterAsEnum(parameters,
                                             self.INPUT_GEOMETRY_TYPE, context)
        geometry_crs = self.parameterAsCrs(parameters, self.INPUT_GEOMETRY_CRS,
                                           context)

        df = QgsVirtualLayerDefinition()
        for layerIdx, layer in enumerate(layers):

            # Issue https://github.com/qgis/QGIS/issues/24041
            # When using this algorithm from the graphic modeler, it may try to
            # access (thanks the QgsVirtualLayerProvider) to memory layer that
            # belongs to temporary QgsMapLayerStore, not project.
            # So, we write them to disk is this is the case.
            if context.project() and not context.project().mapLayer(
                    layer.id()):
                basename = "memorylayer." + QgsVectorFileWriter.supportedFormatExtensions(
                )[0]
                tmp_path = QgsProcessingUtils.generateTempFilename(basename)
                QgsVectorFileWriter.writeAsVectorFormat(
                    layer, tmp_path,
                    layer.dataProvider().encoding())
                df.addSource('input{}'.format(layerIdx + 1), tmp_path, "ogr")
            else:
                df.addSource('input{}'.format(layerIdx + 1), layer.id())

        if query == '':
            raise QgsProcessingException(
                self.
                tr('Empty SQL. Please enter valid SQL expression and try again.'
                   ))
        localContext = self.createExpressionContext(parameters, context)
        expandedQuery = QgsExpression.replaceExpressionText(
            query, localContext)
        df.setQuery(expandedQuery)

        if uid_field:
            df.setUid(uid_field)

        if geometry_type == 1:  # no geometry
            df.setGeometryWkbType(QgsWkbTypes.NoGeometry)
        else:
            if geometry_field:
                df.setGeometryField(geometry_field)
            if geometry_type > 1:
                df.setGeometryWkbType(geometry_type - 1)
            if geometry_crs.isValid():
                df.setGeometrySrid(geometry_crs.postgisSrid())

        vLayer = QgsVectorLayer(df.toString(), "temp_vlayer", "virtual")
        if not vLayer.isValid():
            raise QgsProcessingException(
                vLayer.dataProvider().error().message())

        if vLayer.wkbType() == QgsWkbTypes.Unknown:
            raise QgsProcessingException(self.tr("Cannot find geometry field"))

        (sink, dest_id) = self.parameterAsSink(
            parameters, self.OUTPUT, context, vLayer.fields(),
            vLayer.wkbType() if geometry_type != 1 else 1, vLayer.crs())
        if sink is None:
            raise QgsProcessingException(
                self.invalidSinkError(parameters, self.OUTPUT))

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

            sink.addFeature(inFeat, QgsFeatureSink.FastInsert)
            feedback.setProgress(int(current * total))
        return {self.OUTPUT: dest_id}
    def processAlgorithm(self, parameters, context, feedback):
        destination = self.parameterAsFile(parameters, self.DESTINATION,
                                           context)

        try:
            db = postgis.GeoDB.from_name(destination)
            is_geopackage = False
            schema = self.parameterAsFile(parameters, self.SCHEMA, context)
        except QgsProcessingException:
            is_geopackage = True
            schema = None

        if is_geopackage:
            if not destination.lower().endswith('.gpkg'):
                destination += '.gpkg'
            uri = destination
        else:
            database_uri = db.uri
            info = database_uri.connectionInfo(True)
            conn = psycopg2.connect(info)
            cur = conn.cursor()
            sql = "DROP VIEW IF EXISTS {}.{};".format(schema, self.VIEW_NAME)
            feedback.pushInfo(sql)
            cur.execute(sql)
            conn.commit()

        crs = self.parameterAsCrs(parameters, self.CRS, context)

        options = dict()
        options['update'] = True

        if is_geopackage:
            options['layerOptions'] = ['FID=id']
            options['fileEncoding'] = 'UTF-8'

        output_layers = []
        for table, geom in MAPPING.items():
            # create virtual layer
            if geom[0]:
                vl_path = '{}?crs={}&'.format(geom[0], crs.authid())
            else:
                vl_path = 'None?'

            csv_path = resources_path('data_models', '{}.csv'.format(table))
            csv = QgsVectorLayer(csv_path, table, 'ogr')
            if not csv.isValid():
                csv_path = resources_path('data_models',
                                          '{}.csv'.format(table))
                raise QgsProcessingException(
                    tr('* ERROR: Can\'t load CSV {}').format(csv_path))

            fields = []
            for c_f in csv.getFeatures():
                fields.append('field={}:{}'.format(c_f['name'],
                                                   c_f['typeName']))
            del csv

            vl_path += '&'.join(fields)
            LOGGER.debug('Memory layer "{}" created with {}'.format(
                table, vl_path))
            vl = QgsVectorLayer(vl_path, table, 'memory')

            if vl.fields().count() != len(fields):
                raise QgsProcessingException(
                    tr('* ERROR while creating fields in layer "{}"').format(
                        table))

            # export layer
            options['layerName'] = vl.name()
            if not is_geopackage:
                uri = QgsDataSourceUri(database_uri)
                if Qgis.QGIS_VERSION_INT >= 31000:
                    uri.setTable(vl.name())
                    if vl.isSpatial():
                        uri.setGeometryColumn('geom')
                else:
                    uri_string = uri.uri(True)
                    if vl.isSpatial():
                        uri_string = uri_string.replace(
                            'table=""', 'table="{}" (geom)'.format(vl.name()))
                    else:
                        uri_string = uri_string.replace(
                            'table=""', 'table="{}"'.format(vl.name()))
                    uri = QgsDataSourceUri(uri_string)
                # Schema is updating the table name,
                # so after search&replace
                uri.setSchema(schema)
                uri.setKeyColumn(vl.fields().at(0).name())

            exporter = QgsVectorLayerExporter(
                uri if is_geopackage else uri.uri(),
                'ogr' if is_geopackage else 'postgres', vl.fields(),
                vl.wkbType(), vl.crs(), True, options)

            # result
            if exporter.errorCode() != QgsVectorLayerExporter.NoError:
                source = uri if is_geopackage else uri.uri()
                raise QgsProcessingException(
                    tr('* ERROR while exporting the layer to "{}":"{}"').
                    format(source, exporter.errorMessage()))

            # Do create sequence
            if geom[2] and not is_geopackage:
                cur = conn.cursor()
                sql = "CREATE SEQUENCE {}.{}_{}_seq;".format(
                    schema, table, geom[2])
                cur.execute(sql)
                conn.commit()
                sql = ("ALTER TABLE {0}.{1} "
                       "ALTER COLUMN {2} "
                       "SET DEFAULT nextval('{0}.{1}_{2}_seq'::regclass);"
                       ).format(schema, table, geom[2])
                cur.execute(sql)
                conn.commit()

            # connection troncon_rereau_classif in geopackage
            if is_geopackage:
                dest_layer = QgsVectorLayer(
                    '{}|layername={}'.format(uri, table), table, 'ogr')
            else:
                uri = QgsDataSourceUri(database_uri)
                if Qgis.QGIS_VERSION_INT >= 31000:
                    uri.setTable(vl.name())
                    if vl.isSpatial():
                        uri.setGeometryColumn('geom')
                else:
                    uri_string = uri.uri(True)
                    if vl.isSpatial():
                        uri_string = uri_string.replace(
                            'table=""', 'table="{}" (geom)'.format(vl.name()))
                    else:
                        uri_string = uri_string.replace(
                            'table=""', 'table="{}"'.format(vl.name()))
                    uri = QgsDataSourceUri(uri_string)
                # Schema is updating the table name,
                # so after search&replace
                uri.setSchema(schema)
                uri.setKeyColumn(vl.fields().at(0).name())
                dest_layer = QgsVectorLayer(uri.uri(False), table, 'postgres')
            if not dest_layer.isValid():
                source = uri if is_geopackage else uri.uri()
                raise QgsProcessingException(
                    tr('* ERROR: Can\'t load table "{}" in URI "{}"').format(
                        table, source))

            feedback.pushInfo('The layer {} has been created'.format(table))

            output_layers.append(dest_layer.id())

            # Add layer to project
            context.temporaryLayerStore().addMapLayer(dest_layer)
            context.addLayerToLoadOnCompletion(
                dest_layer.id(),
                QgsProcessingContext.LayerDetails(table, context.project(),
                                                  self.OUTPUT_LAYERS))

        # Get connection
        if is_geopackage:
            conn = spatialite_connect(uri)

        # Do create view
        cur = conn.cursor()
        prefix = ''
        view_destination = self.VIEW_NAME
        if not is_geopackage:
            prefix = '{}.'.format(schema)
            view_destination = '{}{}'.format(prefix, view_destination)
        sql = ("CREATE VIEW {0} AS "
               "SELECT r.id, r.caa, r.id_geom_regard, r.id_file, g.geom "
               "FROM {1}regard r, {1}geom_regard g "
               "WHERE r.id_geom_regard = g.id;").format(
                   view_destination, prefix)
        feedback.pushInfo(sql)
        cur.execute(sql)
        conn.commit()

        if is_geopackage:
            sql = ("INSERT INTO gpkg_contents "
                   "(table_name, identifier, data_type, srs_id) "
                   "VALUES ( '{0}', '{0}', 'features', {1});").format(
                       self.VIEW_NAME, crs.postgisSrid())
            feedback.pushInfo(sql)
            cur.execute(sql)
            conn.commit()
            sql = (
                "INSERT INTO gpkg_geometry_columns "
                "(table_name, column_name, geometry_type_name, srs_id, z, m) "
                "VALUES ('{0}', 'geom', 'POINT', {1}, 0, 0);").format(
                    self.VIEW_NAME, crs.postgisSrid())
            feedback.pushInfo(sql)
            cur.execute(sql)
            conn.commit()

        conn.close()

        # Connexion à la couche view_regard_localized dans le Geopackage
        if is_geopackage:
            view_layer = QgsVectorLayer(
                '{}|layername={}'.format(uri, self.VIEW_NAME), self.VIEW_NAME,
                'ogr')
        else:
            uri = QgsDataSourceUri(database_uri)
            if Qgis.QGIS_VERSION_INT >= 31000:
                uri.setTable(self.VIEW_NAME)
                uri.setGeometryColumn('geom')
            else:
                uri_string = uri.uri(True)
                uri_string = uri_string.replace(
                    'table=""', 'table="{}" (geom)'.format(self.VIEW_NAME))
                uri = QgsDataSourceUri(uri_string)
            # Schema is updating the table name,
            # so after search&replace
            uri.setSchema(schema)
            uri.setKeyColumn('id')
            view_layer = QgsVectorLayer(uri.uri(False), self.VIEW_NAME,
                                        'postgres')
        if not view_layer.isValid():
            source = uri if is_geopackage else uri.uri()
            raise QgsProcessingException(
                tr('* ERROR: Can\'t load layer {} in {}').format(
                    self.VIEW_NAME, source))

        output_layers.append(view_layer.id())

        # Add layer to project
        context.temporaryLayerStore().addMapLayer(view_layer)
        context.addLayerToLoadOnCompletion(
            view_layer.id(),
            QgsProcessingContext.LayerDetails(self.VIEW_NAME,
                                              context.project(),
                                              self.OUTPUT_LAYERS))

        feedback.pushInfo('The data model has been created in {}'.format(uri))

        return {self.DESTINATION: uri, self.OUTPUT_LAYERS: output_layers}
Exemple #39
0
    def processAlgorithm(self, progress):
        inLayers = self.getParameterValue(self.LAYERS)
        paths = inLayers.split(';')

        layers = []
        fields = QgsFields()
        totalFeatureCount = 0
        for x in range(len(paths)):
            layer = QgsVectorLayer(paths[x], str(x), 'ogr')

            if (len(layers) > 0):
                if (layer.wkbType() != layers[0].wkbType()):
                    raise GeoAlgorithmExecutionException(
                        self.tr('All layers must have same geometry type!'))

            layers.append(layer)
            totalFeatureCount += layer.featureCount()

            for sindex, sfield in enumerate(layer.fields()):
                found = None
                for dfield in fields:
                    if (dfield.name().upper() == sfield.name().upper()):
                        found = dfield
                        if (dfield.type() != sfield.type()):
                            raise GeoAlgorithmExecutionException(
                                self.tr('{} field in layer {} has different '
                                        'data type than in other layers.'))

                if not found:
                    fields.append(sfield)

        total = 100.0 / totalFeatureCount
        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            fields.toList(), layers[0].wkbType(), layers[0].crs())

        featureCount = 0
        for layer in layers:
            for feature in layer.getFeatures():
                sattributes = feature.attributes()
                dattributes = []
                for dindex, dfield in enumerate(fields):
                    if (dfield.type() == QVariant.Int, QVariant.UInt,
                            QVariant.LongLong, QVariant.ULongLong):
                        dattribute = 0
                    elif (dfield.type() == QVariant.Double):
                        dattribute = 0.0
                    else:
                        dattribute = ''

                    for sindex, sfield in enumerate(layer.fields()):
                        if (sfield.name().upper() == dfield.name().upper()):
                            if (sfield.type() != dfield.type()):
                                raise GeoAlgorithmExecutionException(
                                    self.tr('Attribute type mismatch'))
                            dattribute = sattributes[sindex]
                            break

                    dattributes.append(dattribute)

                feature.setAttributes(dattributes)
                writer.addFeature(feature)
                featureCount += 1
                progress.setPercentage(int(featureCount * total))

        del writer
    def cloneToMemory(self):
        curlayer = self.iface.mapCanvas().currentLayer()
        selectedFeatCount = curlayer.selectedFeatureCount()
        geo = QgsWkbTypes.displayString(
            curlayer.wkbType())  # wkbType string name of geometry

        targetLayer = QgsVectorLayer(geo, self.dlg.lineEdit_2.text(), "memory")
        targetLayer.setCrs(curlayer.sourceCrs())
        QgsProject.instance().addMapLayer(targetLayer, False)
        root = QgsProject.instance().layerTreeRoot()

        self.setStyleLayer(targetLayer)

        if self.dlg.checkBoxAtrib.isChecked():  #copy attributes
            curlayer_attribute_list = curlayer.fields().toList()
            targetLayer_attribute_list = []
            targetLayerpr = targetLayer.dataProvider()

            for attrib in curlayer_attribute_list:
                if targetLayer.fields().lookupField(attrib.name()) == -1:
                    targetLayer_attribute_list.append(
                        QgsField(attrib.name(), attrib.type()))
            with edit(targetLayer):
                for attr in targetLayer_attribute_list:
                    if attr.type(
                    ) == 1:  # иначе игнорируется поле с типом 1 (bool)
                        attr = QgsField(
                            attr.name(),
                            QVariant.String)  # конвертируем bool в string
                    res_add = targetLayer.addAttribute(attr)
                    if not res_add:
                        print(u'Не создано поле {}'.format(attr.name()))
            targetLayer.updateFields()

        # for feat in curlayer.selectedFeatures(): # not work more
        #     targetLayer.dataProvider().addFeatures([feat]) # not work more

        # ИЗ МОДУЛЯ Apend Features To layer -----------------------------------------------
        # В старом варианте в QGIS3 при добавлении объектов с отличающимся набором аттрибутов
        # происходила задержка с выводом сообщений в логи. Что затягивало процесс.
        mapping = dict()
        for target_idx in targetLayer.fields().allAttributesList():
            target_field = targetLayer.fields().field(target_idx)
            source_idx = curlayer.fields().indexOf(target_field.name())
            if source_idx != -1:
                mapping[target_idx] = source_idx

        features = curlayer.selectedFeatures()
        destType = targetLayer.geometryType()
        destIsMulti = QgsWkbTypes.isMultiType(targetLayer.wkbType())
        new_features = []

        for current, in_feature in enumerate(features):
            attrs = {
                target_idx: in_feature[source_idx]
                for target_idx, source_idx in mapping.items()
            }
            geom = QgsGeometry()
            if in_feature.hasGeometry() and targetLayer.isSpatial():
                # Convert geometry to match destination layer
                # Adapted from QGIS qgisapp.cpp, pasteFromClipboard()
                geom = in_feature.geometry()
                if destType != QgsWkbTypes.UnknownGeometry:
                    newGeometry = geom.convertToType(destType, destIsMulti)
                    if newGeometry.isNull():
                        continue
                    geom = newGeometry
                # Avoid intersection if enabled in digitize settings
                geom.avoidIntersections(
                    QgsProject.instance().avoidIntersectionsLayers())

            new_feature = QgsVectorLayerUtils().createFeature(
                targetLayer, geom, attrs)
            new_features.append(new_feature)

        with edit(targetLayer):
            res = targetLayer.addFeatures(new_features)
        # ИЗ МОДУЛЯ Apend Features To layer -----------------------------------------------end

        root.insertLayer(0, targetLayer)
        self.iface.messageBar().clearWidgets()
        self.iface.setActiveLayer(targetLayer)
        curlayer.selectByIds([])

        if res:
            self.iface.messageBar().pushMessage(
                u"Выполнено",
                u"Склонировано {0}/{1} объектов".format(
                    len(new_features), selectedFeatCount),
                duration=5,
                level=0)
 def from_layer(layer: QgsVectorLayer) -> "LayerType":
     for l_type in LayerType:
         if layer.wkbType() in l_type.wkb_types:
             return l_type
     return LayerType.Unknown
Exemple #42
0
    def testWFS10(self):
        """Test WFS 1.0 read-only"""

        endpoint = self.__class__.basetestpath + '/fake_qgis_http_endpoint_WFS1.0'

        with open(
                sanitize(endpoint,
                         '?SERVICE=WFS?REQUEST=GetCapabilities?VERSION=1.0.0'),
                'wb') as f:
            f.write("""
<WFS_Capabilities version="1.0.0" xmlns="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc">
  <FeatureTypeList>
    <FeatureType>
      <Name>my:typename</Name>
      <Title>Title</Title>
      <Abstract>Abstract</Abstract>
      <SRS>EPSG:4326</SRS>
      <LatLongBoundingBox minx="-71.123" miny="66.33" maxx="-65.32" maxy="78.3"/>
    </FeatureType>
  </FeatureTypeList>
</WFS_Capabilities>""")

        with open(
                sanitize(
                    endpoint,
                    '?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=1.0.0&TYPENAME=my:typename'
                ), 'wb') as f:
            f.write("""
<xsd:schema xmlns:my="http://my" xmlns:gml="http://www.opengis.net/gml" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://my">
  <xsd:import namespace="http://www.opengis.net/gml"/>
  <xsd:complexType name="my:typenameType">
    <xsd:complexContent>
      <xsd:extension base="gml:AbstractFeatureType">
        <xsd:sequence>
          <xsd:element maxOccurs="1" minOccurs="0" name="INTFIELD" nillable="true" type="xsd:int"/>
          <xsd:element maxOccurs="1" minOccurs="0" name="GEOMETRY" nillable="true" type="xsd:int"/>
          <xsd:element maxOccurs="1" minOccurs="0" name="longfield" nillable="true" type="xsd:long"/>
          <xsd:element maxOccurs="1" minOccurs="0" name="stringfield" nillable="true" type="xsd:string"/>
          <xsd:element maxOccurs="1" minOccurs="0" name="geometryProperty" nillable="true" type="gml:PointPropertyType"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>
  <xsd:element name="typename" substitutionGroup="gml:_Feature" type="my:typenameType"/>
</xsd:schema>
""")

        vl = QgsVectorLayer(
            u"url='http://" + endpoint +
            u"' typename='my:typename' version='1.0.0'", u'test', u'WFS')
        assert vl.isValid()
        self.assertEquals(vl.wkbType(), QgsWKBTypes.Point)
        self.assertEquals(len(vl.fields()), 4)
        self.assertEquals(vl.featureCount(), 0)
        reference = QgsGeometry.fromRect(
            QgsRectangle(-71.123, 66.33, -65.32, 78.3))
        vl_extent = QgsGeometry.fromRect(vl.extent())
        assert QgsGeometry.compare(vl_extent.asPolygon(),
                                   reference.asPolygon(),
                                   0.00001), 'Expected {}, got {}'.format(
                                       reference.exportToWkt(),
                                       vl_extent.exportToWkt())

        with open(
                sanitize(
                    endpoint,
                    '?SERVICE=WFS&REQUEST=GetFeature&VERSION=1.0.0&TYPENAME=my:typename&SRSNAME=EPSG:4326'
                ), 'wb') as f:
            f.write("""
<wfs:FeatureCollection
                       xmlns:wfs="http://www.opengis.net/wfs"
                       xmlns:gml="http://www.opengis.net/gml"
                       xmlns:my="http://my">
  <gml:boundedBy><gml:null>unknown</gml:null></gml:boundedBy>
  <gml:featureMember>
    <my:typename fid="typename.0">
      <my:geometryProperty>
          <gml:Point srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"><gml:coordinates decimal="." cs="," ts=" ">2,49</gml:coordinates></gml:Point></my:geometryProperty>
      <my:INTFIELD>1</my:INTFIELD>
      <my:GEOMETRY>2</my:GEOMETRY>
      <my:longfield>1234567890123</my:longfield>
      <my:stringfield>foo</my:stringfield>
    </my:typename>
  </gml:featureMember>
</wfs:FeatureCollection>""")

        values = [f['INTFIELD'] for f in vl.getFeatures()]
        self.assertEquals(values, [1])

        values = [f['GEOMETRY'] for f in vl.getFeatures()]
        self.assertEquals(values, [2])

        values = [f['longfield'] for f in vl.getFeatures()]
        self.assertEquals(values, [1234567890123])

        values = [f['stringfield'] for f in vl.getFeatures()]
        self.assertEquals(values, ['foo'])

        got = [f.geometry() for f in vl.getFeatures()][0].geometry()
        self.assertEquals((got.x(), got.y()), (2.0, 49.0))

        self.assertEquals(vl.featureCount(), 1)

        self.assertEquals(vl.dataProvider().capabilities(), 0)

        (ret, _) = vl.dataProvider().addFeatures([QgsFeature()])
        assert not ret

        assert not vl.dataProvider().deleteFeatures([0])
Exemple #43
0
    def testWFS20Paging(self):
        """Test WFS 2.0 paging"""

        endpoint = self.__class__.basetestpath + '/fake_qgis_http_endpoint_WFS_2.0_paging'

        with open(
                sanitize(
                    endpoint,
                    '?SERVICE=WFS?REQUEST=GetCapabilities?ACCEPTVERSIONS=2.0.0,1.1.0,1.0.0'
                ), 'wb') as f:
            f.write("""
<wfs:WFS_Capabilities version="2.0.0" xmlns="http://www.opengis.net/wfs/2.0" xmlns:wfs="http://www.opengis.net/wfs/2.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:gml="http://schemas.opengis.net/gml/3.2" xmlns:fes="http://www.opengis.net/fes/2.0" xmlns:xlink="http://www.w3.org/1999/xlink">
  <ows:OperationsMetadata>
    <ows:Operation name="GetFeature">
      <ows:Constraint name="CountDefault">
        <ows:NoValues/>
        <ows:DefaultValue>1</ows:DefaultValue>
      </ows:Constraint>
    </ows:Operation>
    <ows:Constraint name="ImplementsResultPaging">
      <ows:NoValues/>
      <ows:DefaultValue>TRUE</ows:DefaultValue>
    </ows:Constraint>
  </ows:OperationsMetadata>
  <FeatureTypeList>
    <FeatureType>
      <Name>my:typename</Name>
      <Title>Title</Title>
      <Abstract>Abstract</Abstract>
      <DefaultCRS>urn:ogc:def:crs:EPSG::4326</DefaultCRS>
      <ows:WGS84BoundingBox>
        <ows:LowerCorner>-71.123 66.33</ows:LowerCorner>
        <ows:UpperCorner>-65.32 78.3</ows:UpperCorner>
      </ows:WGS84BoundingBox>
    </FeatureType>
  </FeatureTypeList>
</wfs:WFS_Capabilities>""")

        with open(
                sanitize(
                    endpoint,
                    '?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=2.0.0&TYPENAME=my:typename'
                ), 'wb') as f:
            f.write("""
<xsd:schema xmlns:my="http://my" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://my">
  <xsd:import namespace="http://www.opengis.net/gml/3.2"/>
  <xsd:complexType name="my:typenameType">
    <xsd:complexContent>
      <xsd:extension base="gml:AbstractFeatureType">
        <xsd:sequence>
          <xsd:element maxOccurs="1" minOccurs="0" name="id" nillable="true" type="xsd:int"/>
          <xsd:element maxOccurs="1" minOccurs="0" name="geometryProperty" nillable="true" type="gml:GeometryPropertyType"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>
  <xsd:element name="typename" substitutionGroup="gml:_Feature" type="my:typenameType"/>
</xsd:schema>
""")

        with open(
                sanitize(
                    endpoint,
                    '?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=my:typename&STARTINDEX=0&COUNT=1&SRSNAME=urn:ogc:def:crs:EPSG::4326'
                ), 'wb') as f:
            f.write("""
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs/2.0"
                       xmlns:gml="http://www.opengis.net/gml/3.2"
                       xmlns:my="http://my"
                       numberMatched="2" numberReturned="1" timeStamp="2016-03-25T14:51:48.998Z">
  <wfs:member>
    <my:typename gml:id="typename.100">
      <my:geometryProperty><gml:Point srsName="urn:ogc:def:crs:EPSG::4326" gml:id="typename.geom.0"><gml:pos>66.33 -70.332</gml:pos></gml:Point></my:geometryProperty>
      <my:id>1</my:id>
    </my:typename>
  </wfs:member>
</wfs:FeatureCollection>""")

        # Create test layer
        vl = QgsVectorLayer(
            u"url='http://" + endpoint + u"' typename='my:typename'", u'test',
            u'WFS')
        assert vl.isValid()
        self.assertEquals(vl.wkbType(), QgsWKBTypes.Point)

        with open(
                sanitize(
                    endpoint,
                    '?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=my:typename&STARTINDEX=1&COUNT=1&SRSNAME=urn:ogc:def:crs:EPSG::4326'
                ), 'wb') as f:
            f.write("""
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs/2.0"
                       xmlns:gml="http://www.opengis.net/gml/3.2"
                       xmlns:my="http://my"
                       numberMatched="2" numberReturned="1" timeStamp="2016-03-25T14:51:48.998Z">
  <wfs:member>
    <my:typename gml:id="typename.200">
      <my:geometryProperty><gml:Point srsName="urn:ogc:def:crs:EPSG::4326" gml:id="typename.geom.0"><gml:pos>66.33 -70.332</gml:pos></gml:Point></my:geometryProperty>
      <my:id>2</my:id>
    </my:typename>
  </wfs:member>
</wfs:FeatureCollection>""")

        with open(
                sanitize(
                    endpoint,
                    '?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=my:typename&STARTINDEX=2&COUNT=1&SRSNAME=urn:ogc:def:crs:EPSG::4326'
                ), 'wb') as f:
            f.write("""
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs/2.0"
                       xmlns:gml="http://www.opengis.net/gml/3.2"
                       xmlns:my="http://my"
                       numberMatched="2" numberReturned="0" timeStamp="2016-03-25T14:51:48.998Z">
</wfs:FeatureCollection>""")

        values = [f['id'] for f in vl.getFeatures()]
        self.assertEquals(values, [1, 2])

        # Suppress GetFeature responses to demonstrate that the cache is used
        os.unlink(
            sanitize(
                endpoint,
                '?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=my:typename&STARTINDEX=0&COUNT=1&SRSNAME=urn:ogc:def:crs:EPSG::4326'
            ))
        os.unlink(
            sanitize(
                endpoint,
                '?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=my:typename&STARTINDEX=1&COUNT=1&SRSNAME=urn:ogc:def:crs:EPSG::4326'
            ))
        os.unlink(
            sanitize(
                endpoint,
                '?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=my:typename&STARTINDEX=2&COUNT=1&SRSNAME=urn:ogc:def:crs:EPSG::4326'
            ))

        values = [f['id'] for f in vl.getFeatures()]
        self.assertEquals(values, [1, 2])

        # No need for hits since the download went to its end
        self.assertEquals(vl.featureCount(), 2)

        vl.dataProvider().reloadData()

        # Hits not working
        self.assertEquals(vl.featureCount(), 0)

        vl.dataProvider().reloadData()

        # Hits working
        with open(
                sanitize(
                    endpoint,
                    '?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=my:typename&RESULTTYPE=hits'
                ), 'wb') as f:
            f.write("""
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs/2.0"
                       xmlns:gml="http://www.opengis.net/gml/3.2"
                       xmlns:my="http://my"
                       numberMatched="2" numberReturned="0" timeStamp="2016-03-25T14:51:48.998Z">
</wfs:FeatureCollection>""")
        self.assertEquals(vl.featureCount(), 2)
Exemple #44
0
    def testWFSGetOnlyFeaturesInViewExtent(self):
        """Test 'get only features in view extent' """

        endpoint = self.__class__.basetestpath + '/fake_qgis_http_endpoint_only_features_in_view_extent'

        with open(
                sanitize(
                    endpoint,
                    '?SERVICE=WFS?REQUEST=GetCapabilities?ACCEPTVERSIONS=2.0.0,1.1.0,1.0.0'
                ), 'wb') as f:
            f.write("""
<wfs:WFS_Capabilities version="1.1.0" xmlns="http://www.opengis.net/wfs" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:gml="http://schemas.opengis.net/gml">
  <ows:OperationsMetadata>
    <ows:Operation name="GetFeature">
      <ows:Parameter name="resultType">
        <ows:Value>results</ows:Value>
        <ows:Value>hits</ows:Value>
      </ows:Parameter>
    </ows:Operation>
    <ows:Constraint name="DefaultMaxFeatures">
      <ows:Value>2</ows:Value>
    </ows:Constraint>
  </ows:OperationsMetadata>
  <FeatureTypeList>
    <FeatureType>
      <Name>my:typename</Name>
      <Title>Title</Title>
      <Abstract>Abstract</Abstract>
      <DefaultCRS>urn:ogc:def:crs:EPSG::4326</DefaultCRS>
      <ows:WGS84BoundingBox>
        <ows:LowerCorner>-80 60</ows:LowerCorner>
        <ows:UpperCorner>-50 80</ows:UpperCorner>
      </ows:WGS84BoundingBox>
    </FeatureType>
  </FeatureTypeList>
</wfs:WFS_Capabilities>""")

        with open(
                sanitize(
                    endpoint,
                    '?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=1.1.0&TYPENAME=my:typename'
                ), 'wb') as f:
            f.write("""
<xsd:schema xmlns:my="http://my" xmlns:gml="http://www.opengis.net/gml" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://my">
  <xsd:import namespace="http://www.opengis.net/gml"/>
  <xsd:complexType name="my:typenameType">
    <xsd:complexContent>
      <xsd:extension base="gml:AbstractFeatureType">
        <xsd:sequence>
          <xsd:element maxOccurs="1" minOccurs="0" name="id" nillable="true" type="xsd:int"/>
          <xsd:element maxOccurs="1" minOccurs="0" name="geometryProperty" nillable="true" type="gml:PointPropertyType"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>
  <xsd:element name="typename" substitutionGroup="gml:_Feature" type="my:typenameType"/>
</xsd:schema>
""")

        # Create test layer
        vl = QgsVectorLayer(
            u"url='http://" + endpoint +
            u"' typename='my:typename' retrictToRequestBBOX=1", u'test',
            u'WFS')
        assert vl.isValid()
        self.assertEquals(vl.wkbType(), QgsWKBTypes.Point)

        last_url = sanitize(
            endpoint,
            '?SERVICE=WFS&REQUEST=GetFeature&VERSION=1.1.0&TYPENAME=my:typename&MAXFEATURES=2&SRSNAME=urn:ogc:def:crs:EPSG::4326&BBOX=60,-70,80,-60'
        )
        with open(last_url, 'wb') as f:
            f.write("""
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs"
                       xmlns:gml="http://www.opengis.net/gml"
                       xmlns:my="http://my"
                       numberOfFeatures="1" timeStamp="2016-03-25T14:51:48.998Z">
  <gml:featureMembers>
    <my:typename gml:id="typename.200">
      <my:geometryProperty><gml:Point srsName="urn:ogc:def:crs:EPSG::4326"><gml:pos>70 -65</gml:pos></gml:Point></my:geometryProperty>
      <my:id>2</my:id>
    </my:typename>
  </gml:featureMembers>
</wfs:FeatureCollection>""")

        extent = QgsRectangle(-70, 60, -60, 80)
        request = QgsFeatureRequest().setFilterRect(extent)
        values = [f['id'] for f in vl.getFeatures(request)]
        self.assertEquals(values, [2])

        # To show that if we zoom-in, we won't issue a new request
        with open(last_url, 'wb') as f:
            f.write("""
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs"
                       xmlns:gml="http://www.opengis.net/gml"
                       xmlns:my="http://my"
                       numberOfFeatures="1" timeStamp="2016-03-25T14:51:48.998Z">
  <gml:featureMembers>
    <my:typename gml:id="typename.20000">
      <my:geometryProperty><gml:Point srsName="urn:ogc:def:crs:EPSG::4326"><gml:pos>70 -65</gml:pos></gml:Point></my:geometryProperty>
      <my:id>200</my:id>
    </my:typename>
  </gml:featureMembers>
</wfs:FeatureCollection>""")

        extent = QgsRectangle(-66, 62, -62, 78)
        request = QgsFeatureRequest().setFilterRect(extent)
        values = [f['id'] for f in vl.getFeatures(request)]
        self.assertEquals(values, [2])

        # Move to a neighbouring area, and reach the download limit
        last_url = sanitize(
            endpoint,
            '?SERVICE=WFS&REQUEST=GetFeature&VERSION=1.1.0&TYPENAME=my:typename&MAXFEATURES=2&SRSNAME=urn:ogc:def:crs:EPSG::4326&BBOX=65,-70,90,-60'
        )
        with open(last_url, 'wb') as f:
            f.write("""
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs"
                       xmlns:gml="http://www.opengis.net/gml"
                       xmlns:my="http://my"
                       numberOfFeatures="1" timeStamp="2016-03-25T14:51:48.998Z">
  <gml:featureMembers>
    <my:typename gml:id="typename.200">
      <my:geometryProperty><gml:Point srsName="urn:ogc:def:crs:EPSG::4326"><gml:pos>70 -65</gml:pos></gml:Point></my:geometryProperty>
      <my:id>2</my:id>
    </my:typename>
    <my:typename gml:id="typename.300">
      <my:geometryProperty><gml:Point srsName="urn:ogc:def:crs:EPSG::4326"><gml:pos>85 -65</gml:pos></gml:Point></my:geometryProperty>
      <my:id>3</my:id>
    </my:typename>
  </gml:featureMembers>
</wfs:FeatureCollection>""")

        extent = QgsRectangle(-70, 65, -60, 90)
        request = QgsFeatureRequest().setFilterRect(extent)
        values = [f['id'] for f in vl.getFeatures(request)]
        self.assertEquals(values, [2, 3])

        # Zoom-in again, and bring more features
        last_url = sanitize(
            endpoint,
            '?SERVICE=WFS&REQUEST=GetFeature&VERSION=1.1.0&TYPENAME=my:typename&MAXFEATURES=2&SRSNAME=urn:ogc:def:crs:EPSG::4326&BBOX=66,-69,89,-61'
        )
        with open(last_url, 'wb') as f:
            f.write("""
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs"
                       xmlns:gml="http://www.opengis.net/gml"
                       xmlns:my="http://my"
                       numberOfFeatures="1" timeStamp="2016-03-25T14:51:48.998Z">
  <gml:featureMembers>
    <my:typename gml:id="typename.200">
      <my:geometryProperty><gml:Point srsName="urn:ogc:def:crs:EPSG::4326"><gml:pos>70 -65</gml:pos></gml:Point></my:geometryProperty>
      <my:id>2</my:id>
    </my:typename>
    <my:typename gml:id="typename.400">
      <my:geometryProperty><gml:Point srsName="urn:ogc:def:crs:EPSG::4326"><gml:pos>84 -64</gml:pos></gml:Point></my:geometryProperty>
      <my:id>4</my:id>
    </my:typename>
  </gml:featureMembers>
</wfs:FeatureCollection>""")

        extent = QgsRectangle(-69, 66, -61, 89)
        request = QgsFeatureRequest().setFilterRect(extent)
        values = [f['id'] for f in vl.getFeatures(request)]
        self.assertEquals(values, [2, 3, 4])

        # Test RESULTTYPE=hits
        last_url = sanitize(
            endpoint,
            '?SERVICE=WFS&REQUEST=GetFeature&VERSION=1.1.0&TYPENAME=my:typename&RESULTTYPE=hits'
        )
        with open(last_url, 'wb') as f:
            f.write("""
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs"
                       numberOfFeatures="10" timeStamp="2016-03-25T14:51:48.998Z"/>"""
                    )

        self.assertEquals(vl.featureCount(), 10)

        # Combine BBOX and FILTER
        last_url = sanitize(
            endpoint,
            """?SERVICE=WFS&REQUEST=GetFeature&VERSION=1.1.0&TYPENAME=my:typename&MAXFEATURES=2&SRSNAME=urn:ogc:def:crs:EPSG::4326&FILTER=<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml">
 <ogc:And>
  <ogc:BBOX>
   <ogc:PropertyName>geometryProperty</ogc:PropertyName>
   <gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326">
    <gml:lowerCorner>66 -69</gml:lowerCorner>
    <gml:upperCorner>89 -61</gml:upperCorner>
   </gml:Envelope>
  </ogc:BBOX>
  <ogc:PropertyIsEqualTo xmlns:ogc="http://www.opengis.net/ogc">
   <ogc:PropertyName xmlns:ogc="http://www.opengis.net/ogc">id</ogc:PropertyName>
   <ogc:Literal xmlns:ogc="http://www.opengis.net/ogc">101</ogc:Literal>
  </ogc:PropertyIsEqualTo>
 </ogc:And>
</ogc:Filter>
""")
        with open(last_url, 'wb') as f:
            f.write("""
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs"
                       xmlns:gml="http://www.opengis.net/gml"
                       xmlns:my="http://my"
                       numberOfFeatures="1" timeStamp="2016-03-25T14:51:48.998Z">
  <gml:featureMembers>
    <my:typename gml:id="typename.101">
      <my:geometryProperty><gml:Point srsName="urn:ogc:def:crs:EPSG::4326"><gml:pos>70 -65</gml:pos></gml:Point></my:geometryProperty>
      <my:id>101</my:id>
    </my:typename>
  </gml:featureMembers>
</wfs:FeatureCollection>""")

        vl.dataProvider().setSubsetString('id = 101')
        extent = QgsRectangle(-69, 66, -61, 89)
        request = QgsFeatureRequest().setFilterRect(extent)
        values = [f['id'] for f in vl.getFeatures(request)]
        self.assertEquals(values, [101])
Exemple #45
0
    def testWFS20Paging(self):
        """Test WFS 2.0 paging"""

        endpoint = self.__class__.basetestpath + '/fake_qgis_http_endpoint_WFS_2.0_paging'

        with open(sanitize(endpoint, '?SERVICE=WFS?REQUEST=GetCapabilities?ACCEPTVERSIONS=2.0.0,1.1.0,1.0.0'), 'wb') as f:
            f.write("""
<wfs:WFS_Capabilities version="2.0.0" xmlns="http://www.opengis.net/wfs/2.0" xmlns:wfs="http://www.opengis.net/wfs/2.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:gml="http://schemas.opengis.net/gml/3.2" xmlns:fes="http://www.opengis.net/fes/2.0" xmlns:xlink="http://www.w3.org/1999/xlink">
  <ows:OperationsMetadata>
    <ows:Operation name="GetFeature">
      <ows:Constraint name="CountDefault">
        <ows:NoValues/>
        <ows:DefaultValue>1</ows:DefaultValue>
      </ows:Constraint>
    </ows:Operation>
    <ows:Constraint name="ImplementsResultPaging">
      <ows:NoValues/>
      <ows:DefaultValue>TRUE</ows:DefaultValue>
    </ows:Constraint>
  </ows:OperationsMetadata>
  <FeatureTypeList>
    <FeatureType>
      <Name>my:typename</Name>
      <Title>Title</Title>
      <Abstract>Abstract</Abstract>
      <DefaultCRS>urn:ogc:def:crs:EPSG::4326</DefaultCRS>
      <ows:WGS84BoundingBox>
        <ows:LowerCorner>-71.123 66.33</ows:LowerCorner>
        <ows:UpperCorner>-65.32 78.3</ows:UpperCorner>
      </ows:WGS84BoundingBox>
    </FeatureType>
  </FeatureTypeList>
</wfs:WFS_Capabilities>""")

        with open(sanitize(endpoint, '?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=2.0.0&TYPENAME=my:typename'), 'wb') as f:
            f.write("""
<xsd:schema xmlns:my="http://my" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://my">
  <xsd:import namespace="http://www.opengis.net/gml/3.2"/>
  <xsd:complexType name="my:typenameType">
    <xsd:complexContent>
      <xsd:extension base="gml:AbstractFeatureType">
        <xsd:sequence>
          <xsd:element maxOccurs="1" minOccurs="0" name="id" nillable="true" type="xsd:int"/>
          <xsd:element maxOccurs="1" minOccurs="0" name="geometryProperty" nillable="true" type="gml:GeometryPropertyType"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>
  <xsd:element name="typename" substitutionGroup="gml:_Feature" type="my:typenameType"/>
</xsd:schema>
""")

        with open(sanitize(endpoint, '?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=my:typename&STARTINDEX=0&COUNT=1&SRSNAME=urn:ogc:def:crs:EPSG::4326'), 'wb') as f:
            f.write("""
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs/2.0"
                       xmlns:gml="http://www.opengis.net/gml/3.2"
                       xmlns:my="http://my"
                       numberMatched="2" numberReturned="1" timeStamp="2016-03-25T14:51:48.998Z">
  <wfs:member>
    <my:typename gml:id="typename.100">
      <my:geometryProperty><gml:Point srsName="urn:ogc:def:crs:EPSG::4326" gml:id="typename.geom.0"><gml:pos>66.33 -70.332</gml:pos></gml:Point></my:geometryProperty>
      <my:id>1</my:id>
    </my:typename>
  </wfs:member>
</wfs:FeatureCollection>""")

        # Create test layer
        vl = QgsVectorLayer(u"url='http://" + endpoint + u"' typename='my:typename'", u'test', u'WFS')
        assert vl.isValid()
        self.assertEqual(vl.wkbType(), QgsWKBTypes.Point)

        with open(sanitize(endpoint, '?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=my:typename&STARTINDEX=1&COUNT=1&SRSNAME=urn:ogc:def:crs:EPSG::4326'), 'wb') as f:
            f.write("""
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs/2.0"
                       xmlns:gml="http://www.opengis.net/gml/3.2"
                       xmlns:my="http://my"
                       numberMatched="2" numberReturned="1" timeStamp="2016-03-25T14:51:48.998Z">
  <wfs:member>
    <my:typename gml:id="typename.200">
      <my:geometryProperty><gml:Point srsName="urn:ogc:def:crs:EPSG::4326" gml:id="typename.geom.0"><gml:pos>66.33 -70.332</gml:pos></gml:Point></my:geometryProperty>
      <my:id>2</my:id>
    </my:typename>
  </wfs:member>
</wfs:FeatureCollection>""")

        with open(sanitize(endpoint, '?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=my:typename&STARTINDEX=2&COUNT=1&SRSNAME=urn:ogc:def:crs:EPSG::4326'), 'wb') as f:
            f.write("""
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs/2.0"
                       xmlns:gml="http://www.opengis.net/gml/3.2"
                       xmlns:my="http://my"
                       numberMatched="2" numberReturned="0" timeStamp="2016-03-25T14:51:48.998Z">
</wfs:FeatureCollection>""")

        values = [f['id'] for f in vl.getFeatures()]
        self.assertEqual(values, [1, 2])

        # Suppress GetFeature responses to demonstrate that the cache is used
        os.unlink(sanitize(endpoint, '?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=my:typename&STARTINDEX=0&COUNT=1&SRSNAME=urn:ogc:def:crs:EPSG::4326'))
        os.unlink(sanitize(endpoint, '?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=my:typename&STARTINDEX=1&COUNT=1&SRSNAME=urn:ogc:def:crs:EPSG::4326'))
        os.unlink(sanitize(endpoint, '?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=my:typename&STARTINDEX=2&COUNT=1&SRSNAME=urn:ogc:def:crs:EPSG::4326'))

        values = [f['id'] for f in vl.getFeatures()]
        self.assertEqual(values, [1, 2])

        # No need for hits since the download went to its end
        self.assertEqual(vl.featureCount(), 2)

        vl.dataProvider().reloadData()

        # Hits not working
        self.assertEqual(vl.featureCount(), 0)

        vl.dataProvider().reloadData()

        # Hits working
        with open(sanitize(endpoint, '?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=my:typename&RESULTTYPE=hits'), 'wb') as f:
            f.write("""
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs/2.0"
                       xmlns:gml="http://www.opengis.net/gml/3.2"
                       xmlns:my="http://my"
                       numberMatched="2" numberReturned="0" timeStamp="2016-03-25T14:51:48.998Z">
</wfs:FeatureCollection>""")
        self.assertEqual(vl.featureCount(), 2)
Exemple #46
0
    def change_layer(self, layer: QgsVectorLayer):
        '''
        sets given layer to being the input of the geocoding,
        add field checks depending on given layer to UI and preset layer-related
        UI elements

        Parameters
        ----------
        layer : QgsVectorLayer
            the layer to change the UI to
        '''
        self.request_start_button.setEnabled(False)
        if not layer:
            return
        # set layer combo to given layer if it is not set to it
        if self.layer_combo.currentLayer().id() != layer.id():
            idx = -1
            for idx in range(len(self.layer_combo)):
                if self.layer_combo.layer(idx).id() == layer.id():
                    break
            self.layer_combo.setCurrentIndex(idx)

        self.input = LayerWrapper(layer)

        # layer can only be updated in place if it has a point geometry
        if layer.wkbType() != QgsWkbTypes.Point:
            self.update_input_layer_check.setChecked(False)
            self.update_input_layer_check.setEnabled(False)
        else:
            self.update_input_layer_check.setEnabled(True)
            # by default store results in selected layer if it is an output
            # layer. otherwise use create a new output layer when geocoding
            # (can be overridden by user)
            self.update_input_layer_check.setChecked(
                layer.id() in self.output_layer_ids)

        # set selected encoding in combobox to encoding of layer
        encoding = layer.dataProvider().encoding()
        self.encoding_combo.blockSignals(True)
        self.encoding_combo.setCurrentText(encoding)
        self.encoding_combo.blockSignals(False)

        # get field map with previous settings if layer was already used as
        # input before
        self.field_map = self.field_map_cache.get(layer.id(), None)
        if not self.field_map or not self.field_map.valid(layer):
            # if no field map was set yet, create it with the known BKG
            # keywords
            # ignore result fields (can't be mapped)
            bkg_f = [
                f[0].field_name_comp(layer)
                for f in self.result_fields.values()
            ]
            self.field_map = FieldMap(layer,
                                      ignore=bkg_f,
                                      keywords=BKGGeocoder.keywords)
            self.field_map_cache[layer.id()] = self.field_map
        # remove old widgets
        clear_layout(self.parameter_grid)

        # create a list of checkable items out of the fields of the layer
        for i, field_name in enumerate(self.field_map.fields()):
            checkbox = QCheckBox()
            checkbox.setText(field_name)
            # combobox for user-selection of a API-keyword matching the field
            combo = QComboBox()
            combo.addItem('Volltextsuche', None)
            for key, (text, regex) in BKGGeocoder.keywords.items():
                combo.addItem(text, key)

            def checkbox_changed(state: bool, combo: QComboBox,
                                 field_name: str):
                checked = state != 0
                self.field_map.set_active(field_name, checked)
                combo.setEnabled(checked)
                self.toggle_start_button()

            # apply changes to field map and combobox on check-state change
            checkbox.stateChanged.connect(
                lambda s, c=combo, f=field_name: checkbox_changed(s, c, f))
            # set initial check state
            checkbox_changed(self.field_map.active(field_name), combo,
                             field_name)

            def combo_changed(idx: int, combo: QComboBox, field_name: str):
                self.field_map.set_keyword(field_name, combo.itemData(idx))

            # apply changes field map when selecting different keyword
            combo.currentIndexChanged.connect(
                lambda i, c=combo, f=field_name: combo_changed(i, c, f))
            # set initial combo index
            cur_idx = combo.findData(self.field_map.keyword(field_name))
            combo_changed(cur_idx, combo, field_name)

            self.parameter_grid.addWidget(checkbox, i, 0)
            self.parameter_grid.addWidget(combo, i, 1)

            # initial state
            checked = self.field_map.active(field_name)
            keyword = self.field_map.keyword(field_name)
            checkbox.setChecked(checked)
            if keyword is not None:
                combo_idx = combo.findData(keyword)
                combo.setCurrentIndex(combo_idx)
                combo.setEnabled(checked)

        # label selection
        self.label_field_combo.blockSignals(True)
        self.label_field_combo.clear()
        self.label_field_combo.addItem('kein Label')
        aliases = {
            f[0].field_name_comp(layer): f[0].alias
            for f in self.result_fields.values()
        }
        for field in layer.fields():
            field_name = field.name()
            alias = aliases.get(field_name)
            self.label_field_combo.addItem(alias or field_name, field_name)
        self.label_field_combo.blockSignals(False)

        # try to set prev. selected field
        label_field = self.label_cache.get(layer.id())
        if label_field is None and self.output and self.output.layer:
            label_field = self.label_cache.get(self.output.id)
        idx = self.label_field_combo.findData(label_field)
        self.label_field_combo.setCurrentIndex(max(idx, 0))

        self.toggle_start_button()
Exemple #47
0
    def testWFSGetOnlyFeaturesInViewExtent(self):
        """Test 'get only features in view extent' """

        endpoint = self.__class__.basetestpath + '/fake_qgis_http_endpoint_only_features_in_view_extent'

        with open(sanitize(endpoint, '?SERVICE=WFS?REQUEST=GetCapabilities?ACCEPTVERSIONS=2.0.0,1.1.0,1.0.0'), 'wb') as f:
            f.write("""
<wfs:WFS_Capabilities version="1.1.0" xmlns="http://www.opengis.net/wfs" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:ows="http://www.opengis.net/ows" xmlns:gml="http://schemas.opengis.net/gml">
  <ows:OperationsMetadata>
    <ows:Operation name="GetFeature">
      <ows:Parameter name="resultType">
        <ows:Value>results</ows:Value>
        <ows:Value>hits</ows:Value>
      </ows:Parameter>
    </ows:Operation>
    <ows:Constraint name="DefaultMaxFeatures">
      <ows:Value>2</ows:Value>
    </ows:Constraint>
  </ows:OperationsMetadata>
  <FeatureTypeList>
    <FeatureType>
      <Name>my:typename</Name>
      <Title>Title</Title>
      <Abstract>Abstract</Abstract>
      <DefaultCRS>urn:ogc:def:crs:EPSG::4326</DefaultCRS>
      <ows:WGS84BoundingBox>
        <ows:LowerCorner>-80 60</ows:LowerCorner>
        <ows:UpperCorner>-50 80</ows:UpperCorner>
      </ows:WGS84BoundingBox>
    </FeatureType>
  </FeatureTypeList>
</wfs:WFS_Capabilities>""")

        with open(sanitize(endpoint, '?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=1.1.0&TYPENAME=my:typename'), 'wb') as f:
            f.write("""
<xsd:schema xmlns:my="http://my" xmlns:gml="http://www.opengis.net/gml" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://my">
  <xsd:import namespace="http://www.opengis.net/gml"/>
  <xsd:complexType name="my:typenameType">
    <xsd:complexContent>
      <xsd:extension base="gml:AbstractFeatureType">
        <xsd:sequence>
          <xsd:element maxOccurs="1" minOccurs="0" name="id" nillable="true" type="xsd:int"/>
          <xsd:element maxOccurs="1" minOccurs="0" name="geometryProperty" nillable="true" type="gml:PointPropertyType"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>
  <xsd:element name="typename" substitutionGroup="gml:_Feature" type="my:typenameType"/>
</xsd:schema>
""")

        # Create test layer
        vl = QgsVectorLayer(u"url='http://" + endpoint + u"' typename='my:typename' retrictToRequestBBOX=1", u'test', u'WFS')
        assert vl.isValid()
        self.assertEqual(vl.wkbType(), QgsWKBTypes.Point)

        last_url = sanitize(endpoint, '?SERVICE=WFS&REQUEST=GetFeature&VERSION=1.1.0&TYPENAME=my:typename&MAXFEATURES=2&SRSNAME=urn:ogc:def:crs:EPSG::4326&BBOX=60,-70,80,-60')
        with open(last_url, 'wb') as f:
            f.write("""
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs"
                       xmlns:gml="http://www.opengis.net/gml"
                       xmlns:my="http://my"
                       numberOfFeatures="1" timeStamp="2016-03-25T14:51:48.998Z">
  <gml:featureMembers>
    <my:typename gml:id="typename.200">
      <my:geometryProperty><gml:Point srsName="urn:ogc:def:crs:EPSG::4326"><gml:pos>70 -65</gml:pos></gml:Point></my:geometryProperty>
      <my:id>2</my:id>
    </my:typename>
  </gml:featureMembers>
</wfs:FeatureCollection>""")

        extent = QgsRectangle(-70, 60, -60, 80)
        request = QgsFeatureRequest().setFilterRect(extent)
        values = [f['id'] for f in vl.getFeatures(request)]
        self.assertEqual(values, [2])

        # To show that if we zoom-in, we won't issue a new request
        with open(last_url, 'wb') as f:
            f.write("""
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs"
                       xmlns:gml="http://www.opengis.net/gml"
                       xmlns:my="http://my"
                       numberOfFeatures="1" timeStamp="2016-03-25T14:51:48.998Z">
  <gml:featureMembers>
    <my:typename gml:id="typename.20000">
      <my:geometryProperty><gml:Point srsName="urn:ogc:def:crs:EPSG::4326"><gml:pos>70 -65</gml:pos></gml:Point></my:geometryProperty>
      <my:id>200</my:id>
    </my:typename>
  </gml:featureMembers>
</wfs:FeatureCollection>""")

        extent = QgsRectangle(-66, 62, -62, 78)
        request = QgsFeatureRequest().setFilterRect(extent)
        values = [f['id'] for f in vl.getFeatures(request)]
        self.assertEqual(values, [2])

        # Move to a neighbouring area, and reach the download limit
        last_url = sanitize(endpoint, '?SERVICE=WFS&REQUEST=GetFeature&VERSION=1.1.0&TYPENAME=my:typename&MAXFEATURES=2&SRSNAME=urn:ogc:def:crs:EPSG::4326&BBOX=65,-70,90,-60')
        with open(last_url, 'wb') as f:
            f.write("""
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs"
                       xmlns:gml="http://www.opengis.net/gml"
                       xmlns:my="http://my"
                       numberOfFeatures="1" timeStamp="2016-03-25T14:51:48.998Z">
  <gml:featureMembers>
    <my:typename gml:id="typename.200">
      <my:geometryProperty><gml:Point srsName="urn:ogc:def:crs:EPSG::4326"><gml:pos>70 -65</gml:pos></gml:Point></my:geometryProperty>
      <my:id>2</my:id>
    </my:typename>
    <my:typename gml:id="typename.300">
      <my:geometryProperty><gml:Point srsName="urn:ogc:def:crs:EPSG::4326"><gml:pos>85 -65</gml:pos></gml:Point></my:geometryProperty>
      <my:id>3</my:id>
    </my:typename>
  </gml:featureMembers>
</wfs:FeatureCollection>""")

        extent = QgsRectangle(-70, 65, -60, 90)
        request = QgsFeatureRequest().setFilterRect(extent)
        values = [f['id'] for f in vl.getFeatures(request)]
        self.assertEqual(values, [2, 3])

        # Zoom-in again, and bring more features
        last_url = sanitize(endpoint, '?SERVICE=WFS&REQUEST=GetFeature&VERSION=1.1.0&TYPENAME=my:typename&MAXFEATURES=2&SRSNAME=urn:ogc:def:crs:EPSG::4326&BBOX=66,-69,89,-61')
        with open(last_url, 'wb') as f:
            f.write("""
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs"
                       xmlns:gml="http://www.opengis.net/gml"
                       xmlns:my="http://my"
                       numberOfFeatures="1" timeStamp="2016-03-25T14:51:48.998Z">
  <gml:featureMembers>
    <my:typename gml:id="typename.200">
      <my:geometryProperty><gml:Point srsName="urn:ogc:def:crs:EPSG::4326"><gml:pos>70 -65</gml:pos></gml:Point></my:geometryProperty>
      <my:id>2</my:id>
    </my:typename>
    <my:typename gml:id="typename.400">
      <my:geometryProperty><gml:Point srsName="urn:ogc:def:crs:EPSG::4326"><gml:pos>84 -64</gml:pos></gml:Point></my:geometryProperty>
      <my:id>4</my:id>
    </my:typename>
  </gml:featureMembers>
</wfs:FeatureCollection>""")

        extent = QgsRectangle(-69, 66, -61, 89)
        request = QgsFeatureRequest().setFilterRect(extent)
        values = [f['id'] for f in vl.getFeatures(request)]
        self.assertEqual(values, [2, 3, 4])

        # Test RESULTTYPE=hits
        last_url = sanitize(endpoint, '?SERVICE=WFS&REQUEST=GetFeature&VERSION=1.1.0&TYPENAME=my:typename&RESULTTYPE=hits')
        with open(last_url, 'wb') as f:
            f.write("""
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs"
                       numberOfFeatures="10" timeStamp="2016-03-25T14:51:48.998Z"/>""")

        self.assertEqual(vl.featureCount(), 10)

        # Combine BBOX and FILTER
        last_url = sanitize(endpoint, """?SERVICE=WFS&REQUEST=GetFeature&VERSION=1.1.0&TYPENAME=my:typename&MAXFEATURES=2&SRSNAME=urn:ogc:def:crs:EPSG::4326&FILTER=<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml">
 <ogc:And>
  <ogc:BBOX>
   <ogc:PropertyName>geometryProperty</ogc:PropertyName>
   <gml:Envelope srsName="urn:ogc:def:crs:EPSG::4326">
    <gml:lowerCorner>66 -69</gml:lowerCorner>
    <gml:upperCorner>89 -61</gml:upperCorner>
   </gml:Envelope>
  </ogc:BBOX>
  <ogc:PropertyIsEqualTo xmlns:ogc="http://www.opengis.net/ogc">
   <ogc:PropertyName xmlns:ogc="http://www.opengis.net/ogc">id</ogc:PropertyName>
   <ogc:Literal xmlns:ogc="http://www.opengis.net/ogc">101</ogc:Literal>
  </ogc:PropertyIsEqualTo>
 </ogc:And>
</ogc:Filter>
""")
        with open(last_url, 'wb') as f:
            f.write("""
<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs"
                       xmlns:gml="http://www.opengis.net/gml"
                       xmlns:my="http://my"
                       numberOfFeatures="1" timeStamp="2016-03-25T14:51:48.998Z">
  <gml:featureMembers>
    <my:typename gml:id="typename.101">
      <my:geometryProperty><gml:Point srsName="urn:ogc:def:crs:EPSG::4326"><gml:pos>70 -65</gml:pos></gml:Point></my:geometryProperty>
      <my:id>101</my:id>
    </my:typename>
  </gml:featureMembers>
</wfs:FeatureCollection>""")

        vl.dataProvider().setSubsetString('id = 101')
        extent = QgsRectangle(-69, 66, -61, 89)
        request = QgsFeatureRequest().setFilterRect(extent)
        values = [f['id'] for f in vl.getFeatures(request)]
        self.assertEqual(values, [101])
Exemple #48
0
    def processAlgorithm(self, progress):
        inLayers = self.getParameterValue(self.LAYERS)
        paths = inLayers.split(";")

        layers = []
        fields = QgsFields()
        totalFeatureCount = 0
        for x in range(len(paths)):
            layer = QgsVectorLayer(paths[x], str(x), "ogr")

            if len(layers) > 0:
                if layer.wkbType() != layers[0].wkbType():
                    raise GeoAlgorithmExecutionException(self.tr("All layers must have same geometry type!"))

            layers.append(layer)
            totalFeatureCount += layer.featureCount()

            for sindex, sfield in enumerate(layer.fields()):
                found = None
                for dfield in fields:
                    if dfield.name().upper() == sfield.name().upper():
                        found = dfield
                        if dfield.type() != sfield.type():
                            raise GeoAlgorithmExecutionException(
                                self.tr("{} field in layer {} has different " "data type than in other layers.")
                            )

                if not found:
                    fields.append(sfield)

        total = 100.0 / totalFeatureCount
        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            fields.toList(), layers[0].wkbType(), layers[0].crs()
        )

        featureCount = 0
        for layer in layers:
            for feature in layer.getFeatures():
                sattributes = feature.attributes()
                dattributes = []
                for dindex, dfield in enumerate(fields):
                    if (dfield.type() == QVariant.Int, QVariant.UInt, QVariant.LongLong, QVariant.ULongLong):
                        dattribute = 0
                    elif dfield.type() == QVariant.Double:
                        dattribute = 0.0
                    else:
                        dattribute = ""

                    for sindex, sfield in enumerate(layer.fields()):
                        if sfield.name().upper() == dfield.name().upper():
                            if sfield.type() != dfield.type():
                                raise GeoAlgorithmExecutionException(self.tr("Attribute type mismatch"))
                            dattribute = sattributes[sindex]
                            break

                    dattributes.append(dattribute)

                feature.setAttributes(dattributes)
                writer.addFeature(feature)
                featureCount += 1
                progress.setPercentage(int(featureCount * total))

        del writer
Exemple #49
0
class NewObject(QDockWidget, Ui_NewObject):
    def __init__(self, iface, objecttype, project, lang_dict, lang):
        # setup UI and connect the buttons
        QDockWidget.__init__(self)
        self.iface = iface
        self.setupUi(self)

        # get variable references from "GeODinQGIS_Main"
        self.obj_type = objecttype.name
        self.loctype = objecttype.gen_desc
        self.path = project.parent.filepath
        self.dbtype = project.parent.options["connection"]
        self.alias = project.parent.name
        self.project_names = project.name
        self.proj_ID = project.id
        self.plugin_dir = os.path.dirname(__file__)
        self.saveFileFolder = self.plugin_dir + "/tmp/"

        self.lgr = logging.getLogger('GeODinQGIS.NewObject')

        self.lang_dict = lang_dict
        self.lang = lang

        # select whole table row instead of single cell
        self.coord_tab.setSelectionBehavior(QAbstractItemView.SelectRows)

        # some empty lists to store coordinates from map canvas
        self.x_list = []
        self.y_list = []
        self.id_list = []
        self.rows = []
        self.attrs_list = []

        self.shortname = None
        self.easting = None
        self.northing = None

        # reference to the map canvas
        self.canvas = self.iface.mapCanvas()

        # define button signals for vector file management
        self.btn_createshp.clicked.connect(self.createVector)
        self.btn_openshp.clicked.connect(self.openVector)
        self.btn_dragshp.clicked.connect(self.dragVector)

        # set behavior to load an existing vector file from layer registry to coordinate table
        self.open = False
        self.drag = False

        #self.btn_dragshp.setEnabled(False)
        self.btn_geodin.setEnabled(False)
        self.btn_del.setEnabled(False)
        self.btn_desel.setEnabled(False)
        self.cmb_short.setEnabled(True)

        # connect buttons to their functions
        self.btn_geodin.clicked.connect(self.geodin)
        self.btn_close.clicked.connect(self.close)
        self.btn_del.clicked.connect(self.delete)
        self.btn_desel.clicked.connect(self.deselect)
        self.cmb_short.currentIndexChanged.connect(self.shortNameChoose)
        self.cmb_east.currentIndexChanged.connect(self.eastingChoose)
        self.cmb_north.currentIndexChanged.connect(self.northingChoose)

        # manage button icons
        self.btn_createshp.setIcon(
            QIcon(":\plugins\GeODinQGIS\icons\point_create_n.png"))
        self.btn_openshp.setIcon(
            QIcon(":\plugins\GeODinQGIS\icons\point_add_n.png"))
        self.btn_dragshp.setIcon(
            QIcon(":\plugins\GeODinQGIS\icons\point_drag_n.png"))
        self.btn_del.setIcon(QIcon(":\plugins\GeODinQGIS\icons\delete.png"))
        self.btn_geodin.setIcon(QIcon(":\plugins\GeODinQGIS\icons\logo.png"))
        self.btn_desel.setIcon(QIcon(":\plugins\GeODinQGIS\icons\minus.png"))
        self.btn_del.setIconSize(QSize(24, 24))
        self.btn_geodin.setIconSize(QSize(24, 24))
        self.btn_desel.setIconSize(QSize(24, 24))
        self.btn_createshp.setIconSize(QSize(24, 24))
        self.btn_openshp.setIconSize(QSize(24, 24))
        self.btn_dragshp.setIconSize(QSize(24, 24))

        # manage tool tips
        createshp = self.lang_dict.getWord(self.lang, "Create new shape file")
        loadshp = self.lang_dict.getWord(self.lang,
                                         "Load shape file from file system")
        dragshp = self.lang_dict.getWord(self.lang,
                                         "Load shape file from layers panel")

        deleteRow = self.lang_dict.getWord(self.lang, "Delete selected rows")
        deselectRow = self.lang_dict.getWord(self.lang, "Deselect rows")
        openGeodin = self.lang_dict.getWord(self.lang, "Import to GeODin")

        self.btn_createshp.setToolTip(createshp)
        self.btn_openshp.setToolTip(loadshp)
        self.btn_dragshp.setToolTip(dragshp)

        self.btn_del.setToolTip(deleteRow)
        self.btn_desel.setToolTip(deselectRow)
        self.btn_geodin.setToolTip(openGeodin)

        # # set headers for child nodes
        # if self.obj_type == "All Objects":
        # self.le_obtyp.setText("All Objects")

        # else:
        # self.le_obtyp.setText(self.obj_type)

        self.delete = False
        self.editMode = False

        # clear coordinate table
        self.coord_tab.setRowCount(0)

        # decimal places
        self.dp = 8

        #
        self.coord_tab.itemChanged.connect(self.Changed)
        #self.coord_tab.cellClicked.connect(self.clicked)

        self.coord_tab.itemSelectionChanged.connect(self.selectionChanged)

        self.root = QgsProject.instance().layerTreeRoot()

    def dragVector(self):
        # open layer list table to drag shape into coordinate table
        sel = DragShp(self.iface, self.lang_dict, self.lang)
        sel.show()
        sel.exec_()

        # set open file name for shape (filePath)
        # add shape to coordinate table
        if sel.accepted:
            self.drag = True
            self.openName = sel.filePath
            self.loadVector()

    def onremovedChildren(self, node, indexFrom, indexTo):
        # execute if a layer has been removed from QGIS layer list
        # ,ap over layer ID's in layer list
        ids = self.root.findLayerIds()

        # deleted, if layer ID cannot be found in layer list
        if self.layerID not in ids:
            # if layer was loaded in coordinate table, empty it
            self.coord_tab.setRowCount(0)

    def Started(self):
        # if editing mode has been toggled on
        self.editMode = True
        self.cmb_short.setEnabled(False)
        # table cell is only editable if has been double clicked
        if not QAbstractItemView == None:
            self.coord_tab.setEditTriggers(QAbstractItemView.DoubleClicked)

        # if one or more item have been selected, deletion allowed
        if len(self.coord_tab.selectedItems()) > 0:
            self.btn_del.setEnabled(True)

    def Stopped(self):
        # turn edit triggers and deletion off
        self.editMode = False
        if not QAbstractItemView == None:
            self.coord_tab.setEditTriggers(QAbstractItemView.NoEditTriggers)

        self.btn_del.setEnabled(False)
        self.cmb_short.setEnabled(True)

        if len(self.cmb_short.currentText()) > 0:
            self.shortname = self.cmb_short.currentText()
        else:
            self.shortname = None

        if len(self.cmb_east.currentText()) > 0:
            self.easting = self.cmb_east.currentText()
        else:
            self.easting = None

        if len(self.cmb_north.currentText()) > 0:
            self.northing = self.cmb_north.currentText()
        else:
            self.northing = None

        # read attribute table and insert items into coordinate table
        self.insertItem()

        self.v_points.updateFields()
        self.selectionChanged()

    def Changed(self, item):
        # if item has been changed in coordinate table
        # editing mode is required
        # print self.coord_tab.currentColumn()
        # print self.coord_tab.currentRow()
        if self.v_points.isEditable():
            # print self.coord_tab.currentItem()
            # print self.coord_tab.currentColumn()
            # print self.coord_tab.currentRow()
            # coordinate which has been edited (only one at a time)
            coord_edit = float(self.coord_tab.currentItem().text())

            # change coordinate equals "coord_edit"
            if self.coord_tab.currentColumn() == 1:
                x = coord_edit
                y = float(self.coord_tab.item(self.rows[0], 2).text())

            elif self.coord_tab.currentColumn() == 2:
                x = float(self.coord_tab.item(self.rows[0], 1).text())
                y = coord_edit

            # QGIS internal functions
            # move vertex to new coordinates
            ch = QgsVectorLayerEditUtils(self.v_points)
            ch.moveVertex(x, y, self.rows[0], 0)

    def selectionChanged(self):
        #its = self.coord_tab.selectedItems()
        # write list with indices of all selected rows
        lines = self.coord_tab.selectionModel().selectedRows()

        self.btn_desel.setEnabled(True)

        # new empty list
        # loop over lines and add to rowlist
        # sort reversed
        self.rows = []
        for idx in lines:
            self.rows.append(idx.row())

        self.rows.sort(reverse=True)

        if len(self.rows) == 1:
            # get coordinates from selection
            self.coord_x = self.coord_tab.item(self.rows[0], 1).text()
            self.coord_y = self.coord_tab.item(self.rows[0], 2).text()
            self.name = self.coord_tab.item(self.rows[0], 0).text()
            self.btn_geodin.setEnabled(True)
        else:
            self.btn_geodin.setEnabled(False)

        self.sel_x = []
        self.sel_y = []
        self.sel_id = []
        self.sel_attrs = []

        for i in self.rows:
            id = self.id_list[i]
            self.sel_id.append(id)
            x_coord = self.x_list[i]
            self.sel_x.append(x_coord)
            y_coord = self.y_list[i]
            self.sel_y.append(y_coord)

        if self.editMode:
            self.btn_del.setEnabled(True)

    def delete(self):
        self.delete = True

        # delete entries from coordinate list and from temporary shape file
        #	self.le_east.clear()
        #	self.le_north.clear()
        self.rows.sort(reverse=True)

        # map over vector layer and get attributes
        features = self.v_points.getFeatures()
        for f in features:
            fid = str(f.id())
            # map over selected ID's
            # check if feature ID matches selected ID
            for i in self.sel_id:
                if i == fid:
                    self.v_points.deleteFeature(f.id())
                    self.v_points.dataProvider().forceReload()
                    self.v_points.triggerRepaint()
                    #delete from self.coord_tab

        for row in self.rows:
            self.coord_tab.removeRow(row)

        self.rows = []
        self.btn_del.setEnabled(False)

        self.delete = False

    def openVector(self):
        # load vector file from file system
        self.open = True

        # get path of vector file
        self.openName = QFileDialog.getOpenFileName(self, "Load Vector Layer",
                                                    ".", "Shape (*.shp)")

        # if open dialog has been aborted
        if not self.openName:
            return

        # take file path and load vector file
        self.loadVector()

    def loadVector(self):
        self.v_points = None
        # name of loaded shape file equals geodin object type
        self.display_name = self.obj_type

        # get reference of shape
        self.v_points = QgsVectorLayer(self.openName, self.display_name, "ogr")

        # vector file must be a point shape
        # important for vector drag from layer list
        if not self.v_points.wkbType() == QgsWkbTypes.Point:
            QMessageBox.information(
                None, self.lang_dict.getWord(self.lang, "Wrong Datatype"),
                self.lang_dict.getWord(self.lang,
                                       "You must load a Point Shape"))
            return

        # if vector file has been loaded from file system
        if self.open == True:
            # add file to map canvas
            QgsProject.instance().addMapLayer(self.v_points)
            self.addVector()
            self.open = False

        # if vector file has been dragged from layer list
        elif self.drag == True:
            self.addVector()
            self.drag = False

    def addVector(self):
        # get reference from layer list to loaded vector layer
        # build coordinate table
        # map over layer list
        layers = QgsProject.instance().mapLayers()

        # split into layer ID and layer instance
        for ID, layer in layers.iteritems():
            source = layer.source()

            # if paths of vector layer equal each other
            # take instance of vector layer from layer list
            if self.openName == source:
                self.v_points = layer
                self.layerID = ID

        # execute if layer has been removed
        self.root.removedChildren.connect(self.onremovedChildren)

        # select short name, easting and northing from attribute table
        self.cmb_short.clear()
        self.cmb_east.clear()
        self.cmb_north.clear()

        self.cmb_short.addItem("")
        self.cmb_east.addItem("")
        self.cmb_north.addItem("")

        for field in self.v_points.pendingFields():
            self.cmb_short.addItem(field.name())
            self.cmb_east.addItem(field.name())
            self.cmb_north.addItem(field.name())

        # fill coordinate table and update attribute table
        self.insertItem()

        # toggle editing modes
        self.v_points.editingStarted.connect(self.Started)
        self.v_points.editingStopped.connect(self.Stopped)

    def createVector(self):
        # name of shape file equals object type
        self.display_name = self.obj_type

        # create temporary shape file
        tmplayer = QgsVectorLayer("Point", self.display_name, "memory")

        provider = tmplayer.dataProvider()

        # Enter editing mode
        tmplayer.startEditing()

        # add attribute fields to shape
        provider.addAttributes([
            QgsField("INVID", QVariant.String),
            QgsField("SHORTNAME", QVariant.String),
            QgsField("LONGNAME", QVariant.String),
            QgsField("XCOORD", QVariant.Double),
            QgsField("YCOORD", QVariant.Double),
            QgsField("DBTYPE", QVariant.String),
            QgsField("DATABASE", QVariant.String),
            QgsField("PRJNAME", QVariant.String),
            QgsField("PRJID", QVariant.String),
            QgsField("OBJECTTYPE", QVariant.String)
        ])

        tmplayer.commitChanges()

        # get file name to be saved
        outName = QFileDialog.getSaveFileName(
            self, "Save Vector Layer",
            self.saveFileFolder + self.display_name.replace(" ", "_"),
            "Shape (*.shp)")
        if not outName:
            return
        self.saveFileFolder = os.path.dirname(outName) + "/"

        # declare options for temporary shape layer
        QgsVectorFileWriter.writeAsVectorFormat(tmplayer, outName, "CP1250",
                                                None, "ESRI Shapefile")

        # turn temporary layer into QGIS vector layer
        self.v_points = QgsVectorLayer(outName, self.display_name, "ogr")

        # add vector file to QGIS layer registry
        QgsMapLayerRegistry.instance().addMapLayer(self.v_points)

        # find layer ID's of all layer in layer registry
        ids = self.root.findLayerIds()

        # if layer registry is empty, return
        if not ids:
            return
        # if layer registry is not empty, take top level layer ID
        else:
            self.layerID = ids[0]

        # exeute if layer has been removed
        self.root.removedChildren.connect(self.onremovedChildren)

        # toggle editing modes
        self.v_points.editingStarted.connect(self.Started)
        self.v_points.editingStopped.connect(self.Stopped)

    def shortNameChoose(self, shortname):
        self.shortname = shortname
        self.insertItem(True)

    def eastingChoose(self, easting):
        self.easting = easting
        self.insertItem(True)

    def northingChoose(self, northing):
        self.northing = northing
        self.insertItem(True)

    def insertItem(self, chooseField=False):

        #print shortname, easting, northing
        # create empty coordinate and ID lists
        self.x_list = []
        self.y_list = []
        self.id_list = []
        self.short_list = []

        # touch vector file and get feature information
        features = self.v_points.getFeatures()
        fields = self.v_points.pendingFields()

        # map over features (row in attribute table, object/point in canvas)
        for f in features:

            fid = str(f.id())
            geom = f.geometry()
            #print f.attributes()

            # get feature coordinates from the map
            x = str(round(geom.asPoint().x(), self.dp))
            y = str(round(geom.asPoint().y(), self.dp))
            attrs = f.attributes()
            #			a = attrs[1]

            # build lists with feature information

            if self.easting:
                if fields[fields.fieldNameIndex(self.easting)].type() == 6:
                    self.x_list.append(f[self.easting])
                else:
                    self.x_list.append('')
            else:
                self.x_list.append(x)

            if self.northing:
                if fields[fields.fieldNameIndex(self.northing)].type() == 6:
                    self.y_list.append(f[self.northing])
                else:
                    self.y_list.append('')
            else:
                self.y_list.append(y)

            self.id_list.append(fid)

            # short name is None, if nothing was selected, 1st column will be empty
            # if short name exists, append to list to write into table

            if self.shortname and not f[self.shortname] == None:
                self.short_list.append(f[self.shortname])
            else:
                self.short_list.append('')

        self.coord_tab.setRowCount(len(self.x_list))

        try:

            # insert short name into table
            for i, row in enumerate(self.short_list):
                short_input = QTableWidgetItem(row)
                self.coord_tab.setItem(i, 0, short_input)

            # insert x-coordinate into table
            for j, row in enumerate(self.x_list):
                x_input = QTableWidgetItem(str(row))
                self.coord_tab.setItem(j, 1, x_input)

            # insert y-coordinate into table
            for k, row in enumerate(self.y_list):
                y_input = QTableWidgetItem(str(row))
                self.coord_tab.setItem(k, 2, y_input)
        except TabError as te:
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Critical)
            msg.setText(str(te))
            msg.exec_()
        except Exception as ex:
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Critical)
            msg.setText(str(ex))
            msg.exec_()

        # touch vector file again and update attribute table
        # important if information had been changed in coordinate table
        # need to be in editing mode
        # features = self.v_points.getFeatures()

        if not chooseField:
            caps = self.v_points.dataProvider().capabilities()
            for i, f in enumerate(features):
                fid = f.id()

                # get coordinates from coordinate table
                x = self.coord_tab.item(i, 1).text()
                y = self.coord_tab.item(i, 2).text()

                # enter information into attribute table
                if caps & QgsVectorDataProvider.ChangeAttributeValues:
                    attrs = {
                        3: x,
                        4: y,
                        5: self.dbtype,
                        6: self.path,
                        7: self.project_names,
                        8: self.proj_ID,
                        9: self.obj_type
                    }

                    self.v_points.dataProvider().changeAttributeValues(
                        {fid: attrs})

    def keyPressEvent(self, event):
        #Did the user press the Enter key?
        if event.key() == Qt.Key_Return or event.key(
        ) == Qt.Key_Enter or event.key(
        ) == Qt.Key_Tab:  #QtCore.Qt.Key_Escape is a value that equates to what the operating system passes to python from the keyboard when the escape key is pressed.
            #Yes: Close the window
            print("key pressed")
        #No:  Do nothing.

    def clicked(self, currentRow):
        print("clicked")
        # write list with indices of all selected rows
        line = self.coord_tab.selectionModel().selectedRows()

        self.btn_desel.setEnabled(True)

        # new empty list
        # loop over lines and add to rowlist
        # sort reversed
        self.rows = []
        for idx in line:
            self.rows.append(idx.row())

        self.rows.sort(reverse=True)

        if len(self.rows) == 1:
            self.btn_geodin.setEnabled(True)

        self.sel_x = []
        self.sel_y = []
        self.sel_id = []
        self.sel_attrs = []

        # get coordinates from selection
        self.coord_x = self.coord_tab.item(self.rows[0], 1).text()
        self.coord_y = self.coord_tab.item(self.rows[0], 2).text()
        self.name = self.coord_tab.item(self.rows[0], 0).text()

        for i in self.rows:
            id = self.id_list[i]
            self.sel_id.append(id)
            x_coord = self.x_list[i]
            self.sel_x.append(x_coord)
            y_coord = self.y_list[i]
            self.sel_y.append(y_coord)

    #	self.le_east.clear()
    #	self.le_north.clear()

    #	self.le_east.insert(self.coord_x)
    #	self.le_north.insert(self.coord_y)

        if len(self.rows) != 1:
            #	self.le_east.clear()
            #	self.le_north.clear()
            self.btn_geodin.setEnabled(False)

        if self.editMode:
            self.btn_del.setEnabled(True)

    def geodin(self):
        #self.lgr.warning('GeODin COM')
        # connect to GeODin COM functions

        for cell in self.coord_tab.selectedItems():
            shortname = cell.text()
            break

        FieldValues = ""
        features = self.v_points.getFeatures()
        for feature in features:
            if feature[self.shortname] == shortname:
                for field in feature.fields():
                    #print field.name().lower()
                    #if field.name() != self.shortname and field.name() != self.easting and field.name() != self.northing and field.name().lower() != 'invid' and field.name().lower() != 'objecttype':
                    if not str(feature[field.name()]) == 'NULL' and not str(
                            feature[field.name()]) == '':
                        FieldValues += field.name() + "=" + str(
                            feature[field.name()]) + "\n"

        try:
            GeODin = win32com.client.Dispatch("GeODin.GeODinApplication")

            #	x = self.le_east.text()
            #	y = self.le_north.text()
            short = "NAME=B101"

            if len(self.coord_x) == 0:
                QMessageBox.information(
                    None, self.lang_dict.getWord(self.lang, "Selection Error"),
                    self.lang_dict.getWord(
                        self.lang,
                        "Nothing to read. Please select the row to be written into GeODin."
                    ))

            else:
                # select object type in GeODin obeject manager
                Params = "[Params]\n"
                Database = "Database="
                Username = "******"
                Password = "******"
                Objecttype = "\nObjectType=1"
                Parentnode = "\nParentNode=ProjectQueries"
                Object_ID = "\nObjectID="
                Expand = "\nExpand=true"

                params = Params + Database + self.alias + Username + Password + Objecttype + Parentnode + Object_ID + self.proj_ID + Expand
                print(params)
                #self.lgr.warning(params)
                # execute method
                GeODin.SelectObject(params)

                # set parameters to create a new object
                Params = "[Params]\n"
                ApplyFieldValues = "ApplyFieldValues=True"
                XCOORDS = "\nXCOORD="
                YCOORDS = "\nYCOORD="
                OBJECTTYPE = "\nOBJECTTYPE="
                NAME = "\nNAME="
                PRJID = "\nPRJID="
                FieldValueSection = "\n[FieldValues]\n"

                params = Params + ApplyFieldValues + XCOORDS + self.coord_x + YCOORDS + self.coord_y + OBJECTTYPE + self.loctype + NAME + self.name + PRJID + self.proj_ID + FieldValueSection + FieldValues
                print(params)
                #self.lgr.warning(params)
                # execute method to create new object
                error = GeODin.ExecuteMethodParams(39, params)
                if error:
                    #print "Error ID:"+ str(GeODin.ExceptionValue)
                    self.lgr.info("Error ID: " + str(GeODin.ExceptionValue))
                    #print "Error Message:"+GeODin.ExceptionMsg
                    self.lgr.info("Error Message: " + GeODin.ExceptionMsg)

            time.sleep(3)
        except:
            print("Unexpected error:", sys.exc_info()[0])
        GeODin = None

    def deselect(self):
        self.rows = []
        self.sel_x = []
        self.sel_y = []

        selected = self.coord_tab.selectedRanges()
        for i in range(len(selected)):
            self.coord_tab.setRangeSelected(selected[i], False)

    #	self.le_east.clear()
    #	self.le_north.clear()

        self.btn_desel.setEnabled(False)
Exemple #50
0
    def testImageServer(self):
        """
        Test connecting to a image server endpoints works as a footprint featureserver
        """
        endpoint = self.basetestpath + '/imageserver_fake_qgis_http_endpoint'
        with open(sanitize(endpoint, '?f=json'), 'wb') as f:
            f.write("""
        {
 "currentVersion": 10.51,
 "serviceDescription": "test",
 "name": "test",
 "description": "test",
 "extent": {
  "xmin": 1,
  "ymin": 1,
  "xmax": 2,
  "ymax": 2,
  "spatialReference": {
   "wkid": 102100,
   "latestWkid": 3857
  }
 },
 "initialExtent": {
  "xmin": 1,
  "ymin": 1,
  "xmax": 2,
  "ymax": 2,
  "spatialReference": {
   "wkid": 102100,
   "latestWkid": 3857
  }
 },
 "fullExtent": {
  "xmin": 1,
  "ymin": 1,
  "xmax": 2,
  "ymax": 2,
  "spatialReference": {
   "wkid": 102100,
   "latestWkid": 3857
  }
 },
 "heightModelInfo": {
  "heightModel": "orthometric",
  "heightUnit": "meter"
 },
 "pixelSizeX": 30,
 "pixelSizeY": 30,
 "bandCount": 1,
 "pixelType": "U8",
 "minPixelSize": 38,
 "maxPixelSize": 156543,
 "copyrightText": "",
 "serviceDataType": "esriImageServiceDataTypeGeneric",
 "minValues": [
  0
 ],
 "maxValues": [
  30
 ],
 "meanValues": [
  5
 ],
 "stdvValues": [
  4
 ],
 "objectIdField": "OBJECTID",
 "fields": [
  {
   "name": "OBJECTID",
   "type": "esriFieldTypeOID",
   "alias": "OBJECTID",
   "domain": null
  },
  {
   "name": "Shape",
   "type": "esriFieldTypeGeometry",
   "alias": "Shape",
   "domain": null
  },
  {
   "name": "Name",
   "type": "esriFieldTypeString",
   "alias": "Name",
   "domain": null,
   "length": 50
  },
  {
   "name": "MinPS",
   "type": "esriFieldTypeDouble",
   "alias": "MinPS",
   "domain": null
  },
  {
   "name": "MaxPS",
   "type": "esriFieldTypeDouble",
   "alias": "MaxPS",
   "domain": null
  },
  {
   "name": "LowPS",
   "type": "esriFieldTypeDouble",
   "alias": "LowPS",
   "domain": null
  },
  {
   "name": "HighPS",
   "type": "esriFieldTypeDouble",
   "alias": "HighPS",
   "domain": null
  }
 ],
 "capabilities": "Catalog,Mensuration,Image,Metadata",
 "defaultMosaicMethod": "Northwest",
 "allowedMosaicMethods": "NorthWest,Center,LockRaster,ByAttribute,Nadir,Viewpoint,Seamline,None",
 "sortField": "",
 "sortValue": null,
 "mosaicOperator": "First",
 "maxDownloadSizeLimit": 4096,
 "defaultCompressionQuality": 75,
 "defaultResamplingMethod": "Nearest",
 "maxImageHeight": 4100,
 "maxImageWidth": 15000,
 "maxRecordCount": 2147483647,
 "maxDownloadImageCount": 200,
 "maxMosaicImageCount": 2147483647,
 "singleFusedMapCache": true,
 "tileInfo": {
  "rows": 256,
  "cols": 256,
  "dpi": 96,
  "format": "MIXED",
  "compressionQuality": 75,
  "origin": {
   "x": 2,
   "y": 2
  },
  "spatialReference": {
   "wkid": 102100,
   "latestWkid": 3857
  },
  "lods": [
   {
    "level": 0,
    "resolution": 156543.033928,
    "scale": 5.91657527591555E8
   },
   {
    "level": 1,
    "resolution": 78271.5169639999,
    "scale": 2.95828763795777E8
   }
  ]
 },
 "cacheType": "Map",
 "allowRasterFunction": true,
 "rasterFunctionInfos": [
  {
   "name": "Classified",
   "description": "A raster function template.",
   "help": ""
  },
  {
   "name": "None",
   "description": "",
   "help": ""
  }
 ],
 "rasterTypeInfos": [
  {
   "name": "Raster Dataset",
   "description": "Supports all ArcGIS Raster Datasets",
   "help": ""
  }
 ],
 "mensurationCapabilities": "Basic",
 "hasHistograms": true,
 "hasColormap": false,
 "hasRasterAttributeTable": false,
 "minScale": 5,
 "maxScale": 144447,
 "exportTilesAllowed": false,
 "hasMultidimensions": false,
 "supportsStatistics": true,
 "supportsAdvancedQueries": true,
 "editFieldsInfo": null,
 "ownershipBasedAccessControlForRasters": null,
 "allowComputeTiePoints": false,
 "useStandardizedQueries": true,
 "advancedQueryCapabilities": {
  "useStandardizedQueries": true,
  "supportsStatistics": true,
  "supportsOrderBy": true,
  "supportsDistinct": true,
  "supportsPagination": true
 },
 "spatialReference": {
  "wkid": 102100,
  "latestWkid": 3857
 }
}""".encode(
                'UTF-8'))

        with open(sanitize(endpoint, '/query?f=json_where=1=1&returnIdsOnly=true'), 'wb') as f:
            f.write("""
        {
         "objectIdFieldName": "OBJECTID",
         "objectIds": [
          1,
          2,
          3
         ]
        }
        """.encode('UTF-8'))

        # Create test layer
        vl = QgsVectorLayer("url='http://" + endpoint + "' crs='epsg:4326'", 'test', 'arcgisfeatureserver')

        self.assertTrue(vl.isValid())
        self.assertEqual(vl.wkbType(), QgsWkbTypes.Polygon)
Exemple #51
0
    def processAlgorithm(self, feedback):
        layers = self.getParameterValue(self.INPUT_DATASOURCES)
        query = self.getParameterValue(self.INPUT_QUERY)
        uid_field = self.getParameterValue(self.INPUT_UID_FIELD)
        geometry_field = self.getParameterValue(self.INPUT_GEOMETRY_FIELD)
        geometry_type = self.getParameterValue(self.INPUT_GEOMETRY_TYPE)
        geometry_crs = self.getParameterValue(self.INPUT_GEOMETRY_CRS)

        df = QgsVirtualLayerDefinition()
        layerIdx = 1
        if layers:
            for layerSource in layers.split(';'):
                layer = dataobjects.getLayerFromString(layerSource)
                if layer:
                    df.addSource('input{}'.format(layerIdx), layer.id())
                layerIdx += 1

        if query == '':
            raise GeoAlgorithmExecutionException(
                self.
                tr('Empty SQL. Please enter valid SQL expression and try again.'
                   ))
        else:
            df.setQuery(query)

        if uid_field:
            df.setUid(uid_field)

        if geometry_type == 1:  # no geometry
            df.setGeometryWkbType(QgsWkbTypes.NullGeometry)
        else:
            if geometry_field:
                df.setGeometryField(geometry_field)
            if geometry_type > 1:
                df.setGeometryWkbType(geometry_type - 1)
            if geometry_crs:
                crs = QgsCoordinateReferenceSystem(geometry_crs)
                if crs.isValid():
                    df.setGeometrySrid(crs.postgisSrid())

        vLayer = QgsVectorLayer(df.toString(), "temp_vlayer", "virtual")
        if not vLayer.isValid():
            raise GeoAlgorithmExecutionException(
                vLayer.dataProvider().error().message())

        writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter(
            vLayer.fields().toList(),
            # Create a point layer (without any points) if 'no geometry' is chosen
            vLayer.wkbType() if geometry_type != 1 else 1,
            vLayer.crs())

        features = vector.features(vLayer)
        total = 100.0 / len(features)
        outFeat = QgsFeature()
        for current, inFeat in enumerate(features):
            outFeat.setAttributes(inFeat.attributes())
            if geometry_type != 1:
                outFeat.setGeometry(inFeat.geometry())
            writer.addFeature(outFeat)
            feedback.setProgress(int(current * total))
        del writer
    def test_valid_import_geom_2d_to_db_gpkg(self):
        print('\nINFO: Validating ETL-Model from [ Point, PointZ, PointM, PointZM ] to Point geometries...')

        # Layer in LADM for test
        test_layer = self.qgis_utils.get_layer(self.db_connection, BOUNDARY_POINT_TABLE, load=True)

        # Point To Point
        print("Validating Point to Point")
        uri = self.gpkg_path + '|layername={layername}'.format(layername='points')
        point_layer = QgsVectorLayer(uri, 'points', 'ogr')
        print("Is Valid layer :", point_layer.isValid())
        run_etl_model(point_layer, out_layer=test_layer)
        test_layer.startEditing()
        print("Info: Validating geometry Point...")
        self.assertEqual(QgsWkbTypes.PointGeometry, test_layer.type())
        self.assertEqual(QgsWkbTypes.Point, point_layer.wkbType())
        self.assertEqual(QgsWkbTypes.Point, test_layer.wkbType())
        self.assertEqual(test_layer.featureCount(), 51)
        clean_table('test_ladm_col', BOUNDARY_POINT_TABLE)
        test_layer.dataProvider().truncate()

        # PointZ To Point
        print("Validating PointZ to Point")
        uri = self.gpkg_path + '|layername={layername}'.format(layername='points_Z')
        point_layer = QgsVectorLayer(uri, 'points_Z', 'ogr')
        print("Is Valid layer :", point_layer.isValid())
        self.assertIn(point_layer.wkbType(), [QgsWkbTypes.PointZ, QgsWkbTypes.Point25D])
        output = run_etl_model(point_layer, out_layer=test_layer)
        print("Info: Validating geometry PointZ...", test_layer.wkbType())
        self.assertEqual(QgsWkbTypes.PointGeometry, test_layer.type())
        self.assertEqual(QgsWkbTypes.Point, test_layer.wkbType())
        self.assertEqual(test_layer.featureCount(), 51)
        clean_table('test_ladm_col', BOUNDARY_POINT_TABLE)
        test_layer.dataProvider().truncate()

        # PointM To Point
        print("Validating PointM To Point")
        uri = self.gpkg_path + '|layername={layername}'.format(layername='points_M')
        point_layer = QgsVectorLayer(uri, 'points', 'ogr')
        print("Is Valid layer :", point_layer.isValid())
        run_etl_model(point_layer, out_layer=test_layer)
        print("Info: Validating geometry PointZ...", test_layer.wkbType())
        self.assertEqual(QgsWkbTypes.PointGeometry, test_layer.type())
        self.assertEqual(QgsWkbTypes.PointM, point_layer.wkbType())
        self.assertEqual(QgsWkbTypes.Point, test_layer.wkbType())
        self.assertEqual(test_layer.featureCount(), 51)
        clean_table('test_ladm_col', BOUNDARY_POINT_TABLE)
        test_layer.dataProvider().truncate()

        # PointZM To Point
        print("Validating PointZM To Point")
        uri = self.gpkg_path + '|layername={layername}'.format(layername='points_ZM')
        point_layer = QgsVectorLayer(uri, 'points', 'ogr')
        print("Is Valid layer :", point_layer.isValid())
        run_etl_model(point_layer, out_layer=test_layer)
        print("Info: Validating geometry PointZ...", test_layer.wkbType())
        self.assertEqual(QgsWkbTypes.PointGeometry, test_layer.type())
        self.assertEqual(QgsWkbTypes.PointZM, point_layer.wkbType())
        self.assertEqual(QgsWkbTypes.Point, test_layer.wkbType())
        self.assertEqual(test_layer.featureCount(), 51)
        clean_table('test_ladm_col', BOUNDARY_POINT_TABLE)
        test_layer.dataProvider().truncate()
Exemple #53
-1
    def testInsertPolygonInMultiPolygon(self):
        layer = QgsVectorLayer("MultiPolygon?crs=epsg:4326&field=id:integer", "addfeat", "memory")
        pr = layer.dataProvider()
        f = QgsFeature()
        f.setAttributes([1])
        f.setGeometry(QgsGeometry.fromWkt('MultiPolygon(((0 0, 1 0, 1 1, 0 1, 0 0)),((10 0, 11 0, 11 1, 10 1, 10 0)))'))
        pr.addFeatures([f])

        uri = '{} table="qgis_test"."new_table_multipolygon" 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.MultiPolygon)
        geom = [f.geometry().asWkt() for f in new_layer.getFeatures()]
        self.assertEqual(geom, ['MultiPolygon (((0 0, 1 0, 1 1, 0 1, 0 0)),((10 0, 11 0, 11 1, 10 1, 10 0)))'])

        # add single part
        f2 = QgsFeature()
        f2.setAttributes([2])
        f2.setGeometry(QgsGeometry.fromWkt('Polygon((30 0, 31 0, 31 1, 30 1, 30 0))'))
        self.assertTrue(new_layer.dataProvider().addFeatures([f2]))

        # should become multipart
        geom = [f.geometry().asWkt() for f in new_layer.getFeatures()]
        self.assertEqual(geom, ['MultiPolygon (((0 0, 1 0, 1 1, 0 1, 0 0)),((10 0, 11 0, 11 1, 10 1, 10 0)))', 'MultiPolygon (((30 0, 31 0, 31 1, 30 1, 30 0)))'])