示例#1
0
    def test_geometry_conversion(self):
        query = toPercent("select geomfromtext('multipoint((0 0),(1 1))') as geom")
        l = QgsVectorLayer("?query=%s&geometry=geom:multipoint:0" % query, "tt", "virtual", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l.isValid(), True)
        for f in l.getFeatures():
            self.assertEqual(f.geometry().asWkt().lower().startswith("multipoint"), True)
            self.assertEqual("),(" in f.geometry().asWkt(), True)  # has two points

        query = toPercent("select geomfromtext('multipolygon(((0 0,1 0,1 1,0 1,0 0)),((0 1,1 1,1 2,0 2,0 1)))') as geom")
        l = QgsVectorLayer("?query=%s&geometry=geom:multipolygon:0" % query, "tt", "virtual", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l.isValid(), True)
        for f in l.getFeatures():
            self.assertEqual(f.geometry().asWkt().lower().startswith("multipolygon"), True)
            self.assertEqual(")),((" in f.geometry().asWkt(), True)  # has two polygons

        query = toPercent("select geomfromtext('multilinestring((0 0,1 0,1 1,0 1,0 0),(0 1,1 1,1 2,0 2,0 1))') as geom")
        l = QgsVectorLayer("?query=%s&geometry=geom:multilinestring:0" % query, "tt", "virtual", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l.isValid(), True)
        for f in l.getFeatures():
            self.assertEqual(f.geometry().asWkt().lower().startswith("multilinestring"), True)
            self.assertEqual("),(" in f.geometry().asWkt(), True)  # has two linestrings
示例#2
0
    def test_lazy(self):
        l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "françéà", "ogr", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l1.isValid(), True)
        QgsProject.instance().addMapLayer(l1)

        df = QgsVirtualLayerDefinition()
        df.setQuery('select * from "françéà"')
        df.setLazy(True)

        vl = QgsVectorLayer(df.toString(), "testq", "virtual")
        self.assertEqual(vl.isValid(), True)
        ids = [f.id() for f in vl.getFeatures()]
        self.assertEqual(len(ids), 0)

        vl.reload()
        ids = [f.id() for f in vl.getFeatures()]
        self.assertEqual(len(ids), 4)

        QgsProject.instance().removeMapLayer(l1.id())
示例#3
0
    def test_sql(self):
        l1 = QgsVectorLayer(QUrl.fromLocalFile(os.path.join(self.testDataDir, "delimitedtext/test.csv")).toString() + "?type=csv&geomType=none&subsetIndex=no&watchFile=no", "test", "delimitedtext", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l1.isValid(), True)
        QgsProject.instance().addMapLayer(l1)

        l3 = QgsVectorLayer("?query=SELECT * FROM test", "tt", "virtual")

        self.assertEqual(l3.isValid(), True)
        s = sum(f.id() for f in l3.getFeatures())
        self.assertEqual(s, 15)
示例#4
0
 def test_rowid(self):
     source = toPercent(os.path.join(self.testDataDir, "france_parts.shp"))
     query = toPercent("select rowid as uid, * from vtab limit 1 offset 3")
     l = QgsVectorLayer("?layer=ogr:%s:vtab&query=%s" % (source, query), "vtab2", "virtual", QgsVectorLayer.LayerOptions(False))
     # the last line must have a fixed rowid (not an autoincrement)
     for f in l.getFeatures():
         lid = f.attributes()[0]
     self.assertEqual(lid, 3)
示例#5
0
    def standalone_table_to_QgsVectorLayer(
            layer: StandaloneTable,  # pylint: disable=too-many-locals,too-many-branches
            input_file,
            context: Context):
        """
        Converts a standalone table to a vector layer
        """
        subset_string = ''
        if layer.definition_query:
            subset_string = ExpressionConverter.convert_esri_sql(
                layer.definition_query)

        base, _ = os.path.split(input_file)

        uri, wkb_type, provider, encoding, file_name = VectorLayerConverter.get_uri(
            source_layer=layer,
            obj=layer,
            base=base,
            crs=QgsCoordinateReferenceSystem(),
            subset=subset_string,
            context=context)

        if wkb_type is None:
            wkb_type = QgsWkbTypes.NoGeometry
        context.layer_type_hint = wkb_type

        if provider == 'ogr' and (not file_name
                                  or not os.path.exists(file_name)
                                  ) and context.invalid_layer_resolver:
            res = context.invalid_layer_resolver(layer.name, uri, wkb_type)
            uri = res.uri
            provider = res.providerKey

        if Qgis.QGIS_VERSION_INT >= 31000:
            opts = QgsVectorLayer.LayerOptions()
            if wkb_type is not None:
                opts.fallbackWkbType = wkb_type

            if provider == 'ogr' and subset_string:
                uri += '|subset={}'.format(subset_string)

            vl = QgsVectorLayer(uri, layer.name, provider, opts)
        else:
            vl = QgsMemoryProviderUtils.createMemoryLayer(
                layer.name, QgsFields(), wkb_type,
                QgsCoordinateReferenceSystem())

        metadata = vl.metadata()
        metadata.setAbstract(layer.description)
        vl.setMetadata(metadata)  #

        if Qgis.QGIS_VERSION_INT < 31000:
            vl.setDataSource(uri, layer.name, provider)

        if encoding:
            vl.dataProvider().setEncoding(encoding)

        if subset_string:
            vl.setSubsetString(subset_string)

        for e in layer.extensions:
            if e.__class__.__name__ == 'ServerLayerExtension':
                if 'CopyrightText' in e.properties.properties:
                    layer_credits = e.properties.properties['CopyrightText']
                    metadata = vl.metadata()
                    rights = metadata.rights()
                    rights.append(layer_credits)
                    metadata.setRights(rights)
                    vl.setMetadata(metadata)

        # setup joins
        join_layer = VectorLayerConverter.add_joined_layer(
            source_layer=layer,
            input_file=input_file,
            base_layer=vl,
            context=context)

        context.dataset_name = ''

        vl.setLegend(QgsMapLayerLegend.defaultVectorLegend(vl))

        res = [vl]
        if join_layer:
            res.append(join_layer)

        return res
示例#6
0
    def test_refLayers(self):
        l1 = QgsVectorLayer(QUrl.fromLocalFile(os.path.join(self.testDataDir, "delimitedtext/test.csv")).toString() + "?type=csv&geomType=none&subsetIndex=no&watchFile=no", "test", "delimitedtext", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l1.isValid(), True)
        QgsProject.instance().addMapLayer(l1)

        # cf qgis bug #12266
        for i in range(10):
            q = toPercent("select * from t" + str(i))
            l2 = QgsVectorLayer("?layer_ref=%s:t%d&query=%s&uid=id" % (l1.id(), i, q), "vtab", "virtual", QgsVectorLayer.LayerOptions(False))
            QgsProject.instance().addMapLayer(l2)
            self.assertEqual(l2.isValid(), True)
            s = sum([f.id() for f in l2.dataProvider().getFeatures()])  # NOQA
            self.assertEqual(sum([f.id() for f in l2.getFeatures()]), 21)
            QgsProject.instance().removeMapLayer(l2.id())
示例#7
0
    def test_QueryTableName(self):
        l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "france_parts", "ogr", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l1.isValid(), True)
        QgsProject.instance().addMapLayer(l1)

        query = toPercent("SELECT * FROM vt")
        l2 = QgsVectorLayer("?layer_ref=%s:vt&query=%s&uid=ObJeCtId&nogeometry" % (l1.id(), query), "vtab", "virtual", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l2.isValid(), True)
        self.assertEqual(l2.dataProvider().wkbType(), 100)  # NoGeometry

        QgsProject.instance().removeMapLayer(l1.id())
示例#8
0
    def test_sql_field_types(self):
        query = toPercent(
            "SELECT 42 as t, 'ok'||'ok' as t2, GeomFromText('') as t3, 3.14*2 as t4"
        )
        l4 = QgsVectorLayer("?query=%s" % query, "tt", "virtual",
                            QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l4.isValid(), True)
        self.assertEqual(l4.dataProvider().fields().at(0).name(), "t")
        self.assertEqual(l4.dataProvider().fields().at(0).type(), QVariant.Int)
        self.assertEqual(l4.dataProvider().fields().at(1).name(), "t2")
        self.assertEqual(l4.dataProvider().fields().at(1).type(),
                         QVariant.String)
        self.assertEqual(l4.dataProvider().fields().at(2).name(), "t3")
        self.assertEqual(l4.dataProvider().fields().at(2).type(),
                         QVariant.String)
        self.assertEqual(l4.dataProvider().fields().at(3).name(), "t4")
        self.assertEqual(l4.dataProvider().fields().at(3).type(),
                         QVariant.Double)

        # with type annotations
        query = toPercent(
            "SELECT '42.0' as t /*:real*/, 3 as t2/*:text  */, GeomFromText('') as t3 /*:multiPoInT:4326 */, 3.14*2 as t4/*:int*/"
        )
        l4 = QgsVectorLayer("?query=%s" % query, "tt", "virtual",
                            QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l4.isValid(), True)
        self.assertEqual(l4.dataProvider().fields().at(0).name(), "t")
        self.assertEqual(l4.dataProvider().fields().at(0).type(),
                         QVariant.Double)
        self.assertEqual(l4.dataProvider().fields().at(1).name(), "t2")
        self.assertEqual(l4.dataProvider().fields().at(1).type(),
                         QVariant.String)
        self.assertEqual(l4.dataProvider().fields().at(2).name(), "t4")
        self.assertEqual(l4.dataProvider().fields().at(2).type(), QVariant.Int)
        self.assertEqual(l4.dataProvider().wkbType(), 4)  # multipoint

        # test value types (!= from declared column types)
        for f in l4.getFeatures():
            self.assertEqual(f.attributes()[0], "42.0")
            self.assertEqual(f.attributes()[1], 3)
            self.assertEqual(f.attributes()[2], 6.28)

        # with type annotations and url options
        query = toPercent(
            "SELECT 1 as id /*:int*/, geomfromtext('point(0 0)',4326) as geometry/*:point:4326*/"
        )
        l4 = QgsVectorLayer("?query=%s&geometry=geometry" % query, "tt",
                            "virtual", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l4.isValid(), True)
        self.assertEqual(l4.dataProvider().wkbType(), 1)  # point

        # with type annotations and url options (2)
        query = toPercent(
            "SELECT 1 as id /*:int*/, 3.14 as f, geomfromtext('point(0 0)',4326) as geometry/*:point:4326*/"
        )
        l4 = QgsVectorLayer(
            "?query=%s&geometry=geometry&field=id:text" % query, "tt",
            "virtual", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l4.isValid(), True)
        self.assertEqual(l4.dataProvider().fields().at(0).name(), "id")
        self.assertEqual(l4.dataProvider().fields().at(0).type(),
                         QVariant.String)
        self.assertEqual(l4.dataProvider().fields().at(1).name(), "f")
        self.assertEqual(l4.dataProvider().fields().at(1).type(),
                         QVariant.Double)
        self.assertEqual(l4.dataProvider().wkbType(), 1)  # point
示例#9
0
    def test_DynamicGeometry(self):
        l1 = QgsVectorLayer(QUrl.fromLocalFile(os.path.join(self.testDataDir, "delimitedtext/testextpt.txt")).toString() + "?type=csv&delimiter=%7C&geomType=none&subsetIndex=no&watchFile=no", "test", "delimitedtext", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l1.isValid(), True)
        QgsProject.instance().addMapLayer(l1)

        query = toPercent("select *,makepoint(x,y) as geom from vtab1")
        l2 = QgsVectorLayer("?layer_ref=%s&query=%s&geometry=geom:point:0&uid=id" % (l1.id(), query), "vtab", "virtual", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l2.isValid(), True)

        QgsProject.instance().removeMapLayer(l1)
示例#10
0
    def test_QueryUrlEncoding(self):
        l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "france_parts", "ogr", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l1.isValid(), True)
        QgsProject.instance().addMapLayer(l1)

        query = toPercent("SELECT * FROM vtab1")
        l2 = QgsVectorLayer("?layer_ref=%s&query=%s&uid=ObjectId&nogeometry" % (l1.id(), query), "vtab", "virtual", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l2.isValid(), True)

        QgsProject.instance().removeMapLayer(l1.id())
示例#11
0
    def test(self):
        l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "françéà", "ogr", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l1.isValid(), True)
        QgsProject.instance().addMapLayer(l1)

        df = QgsVirtualLayerDefinition()
        df.setQuery('select * from "françéà"')
        self.task = QgsVirtualLayerTask(df)

        ids = [f.id() for f in self.task.layer().getFeatures()]
        self.assertEqual(len(ids), 0)

        self.task.taskCompleted.connect(self.onSuccess)
        self.task.taskTerminated.connect(self.onFail)

        QgsApplication.taskManager().addTask(self.task)
        while not self._success and not self._fail:
            QCoreApplication.processEvents()

        self.assertTrue(self._success)
        self.assertFalse(self._fail)

        self.assertEqual(len(self.ids), 4)

        # Test exception
        self._success = False
        self._fail = False
        df.setQuery('select *')
        self.task = QgsVirtualLayerTask(df)
        self.task.taskCompleted.connect(self.onSuccess)
        self.task.taskTerminated.connect(self.onFail)
        QgsApplication.taskManager().addTask(self.task)
        while not self._success and not self._fail:
            QCoreApplication.processEvents()

        self.assertFalse(self._success)
        self.assertTrue(self._fail)
        self.assertEqual(self._exceptionText, 'Query preparation error on PRAGMA table_info(_tview): no tables specified', self._exceptionText)
示例#12
0
    def accept(self):
        """Do PetaBencana download and display it in QGIS.

        .. versionadded: 3.3
        """

        self.save_state()
        try:
            self.require_directory()
        except CanceledImportDialogError:
            return

        QgsApplication.instance().setOverrideCursor(
            QtGui.QCursor(QtCore.Qt.WaitCursor))

        source = self.define_url()
        # save the file as json first
        name = 'jakarta_flood.json'
        output_directory = self.output_directory.text()
        output_prefix = self.filename_prefix.text()
        overwrite = self.overwrite_flag.isChecked()
        date_stamp_flag = self.include_date_flag.isChecked()
        output_base_file_path = self.get_output_base_path(
            output_directory, output_prefix, date_stamp_flag, name, overwrite)

        title = self.tr("Can't access API")

        try:
            self.download(source, output_base_file_path)

            # Open downloaded file as QgsMapLayer
            options = QgsVectorLayer.LayerOptions(False)
            layer = QgsVectorLayer(output_base_file_path, 'flood', 'ogr',
                                   options)
        except Exception as e:
            disable_busy_cursor()
            QMessageBox.critical(self, title, str(e))
            return

        self.time_stamp = time.strftime('%d-%b-%Y %H:%M:%S')
        # Now save as shp
        name = 'jakarta_flood.shp'
        output_base_file_path = self.get_output_base_path(
            output_directory, output_prefix, date_stamp_flag, name, overwrite)
        QgsVectorFileWriter.writeAsVectorFormat(layer, output_base_file_path,
                                                'CP1250',
                                                QgsCoordinateTransform(),
                                                'ESRI Shapefile')
        # Get rid of the GeoJSON layer and rather use local shp
        del layer

        self.copy_style(output_base_file_path)

        self.copy_keywords(output_base_file_path)
        layer = self.add_flooded_field(output_base_file_path)

        # check if the layer has feature or not
        if layer.featureCount() <= 0:
            city = self.city_combo_box.currentText()
            message = self.tr('There are no floods data available on {city} '
                              'at this time.').format(city=city)
            display_warning_message_box(self, self.tr('No data'), message)
            disable_busy_cursor()
        else:
            # add the layer to the map
            project = QgsProject.instance()
            project.addMapLayer(layer)
            disable_busy_cursor()
            self.done(QDialog.Accepted)
示例#13
0
    def add_joined_layer(
            source_layer: Union[FeatureLayer, StandaloneTable],  # pylint: disable=too-many-branches
            input_file,
            base_layer: QgsVectorLayer,
            context: Context):
        """
        Adds joined layers
        """
        if not source_layer.join:
            return None

        if isinstance(source_layer.join, MemoryRelationshipClassName):
            if isinstance(source_layer.join.origin_name, RelQueryTableName):
                if context.unsupported_object_callback:
                    context.unsupported_object_callback(
                        '{}: Nested joins are not supported in QGIS'.format(
                            context.layer_name),
                        level=Context.CRITICAL)

                return None

            join_info = QgsVectorLayerJoinInfo()

            join_info.setJoinFieldName(source_layer.join.origin_primary_key)
            join_info.setTargetFieldName(source_layer.join.origin_foreign_key)

            base, _ = os.path.split(input_file)

            source_layer_props = DatasetNameConverter.convert(
                name=source_layer.join.destination_name,
                base=base,
                crs=QgsCoordinateReferenceSystem(),
                context=context)
            context.layer_type_hint = source_layer_props.wkb_type

            name = 'join'
            if hasattr(source_layer.join.destination_name, 'name'):
                name = source_layer.join.destination_name.name
                join_info.setPrefix(name + '.')

            if Qgis.QGIS_VERSION_INT >= 30800:
                opts = QgsVectorLayer.LayerOptions()
                if source_layer_props.wkb_type is not None:
                    opts.fallbackWkbType = source_layer_props.wkb_type

                vl = QgsVectorLayer(source_layer_props.uri, name,
                                    source_layer_props.provider, opts)
            else:
                vl = QgsVectorLayer(source_layer_props.uri, name,
                                    source_layer_props.provider)
            if not vl.isValid() and Qgis.QGIS_VERSION_INT < 30600:
                if source_layer_props.provider == 'ogr' and not os.path.exists(
                        source_layer_props.file_name
                ) and context.invalid_layer_resolver:
                    res = context.invalid_layer_resolver(
                        source_layer.join.name, source_layer_props.uri,
                        source_layer_props.wkb_type)
                    source_layer_props.uri = res.uri
                    source_layer_props.provider = res.providerKey

                vl = QgsVectorLayer(source_layer_props.uri, 'join',
                                    source_layer_props.provider)

            # todo layer name
            vl.setRenderer(QgsNullSymbolRenderer())

            try:
                vl.setFlags(vl.flags() | QgsMapLayer.Private)
            except AttributeError:
                pass

            join_info.setJoinLayer(vl)
            base_layer.addJoin(join_info)

            return vl

        else:
            if context.unsupported_object_callback:
                context.unsupported_object_callback(
                    '{}: Join layers of type {} are not yet supported'.format(
                        context.layer_name,
                        source_layer.join.__class__.__name__),
                    level=Context.CRITICAL)

            return None
示例#14
0
    def test_Query(self):
        l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"),
                            "france_parts", "ogr",
                            QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l1.isValid(), True)
        QgsProject.instance().addMapLayer(l1)
        ref_sum = sum(f.attributes()[0] for f in l1.getFeatures())

        query = toPercent("SELECT * FROM vtab1")
        l2 = QgsVectorLayer(
            "?layer_ref=%s&geometry=geometry:3:4326&query=%s&uid=OBJECTID" %
            (l1.id(), query), "vtab", "virtual",
            QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l2.isValid(), True)
        self.assertEqual(l2.dataProvider().wkbType(), 3)

        ref_sum2 = sum(f.attributes()[0] for f in l2.getFeatures())
        ref_sum3 = sum(f.id() for f in l2.getFeatures())
        # check we have the same rows
        self.assertEqual(ref_sum, ref_sum2)
        # check the id is OK
        self.assertEqual(ref_sum, ref_sum3)

        # the same, without specifying the geometry column name
        l2 = QgsVectorLayer(
            "?layer_ref=%s&query=%s&uid=OBJECTID" % (l1.id(), query), "vtab",
            "virtual", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l2.isValid(), True)
        self.assertEqual(l2.dataProvider().wkbType(), 6)
        ref_sum2 = sum(f.attributes()[0] for f in l2.getFeatures())
        ref_sum3 = sum(f.id() for f in l2.getFeatures())
        # check we have the same rows
        self.assertEqual(ref_sum, ref_sum2)
        # check the id is OK
        self.assertEqual(ref_sum, ref_sum3)

        # with two geometry columns
        query = toPercent("SELECT *,geometry as geom FROM vtab1")
        l2 = QgsVectorLayer(
            "?layer_ref=%s&query=%s&uid=OBJECTID&geometry=geom:3:4326" %
            (l1.id(), query), "vtab", "virtual",
            QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l2.isValid(), True)
        self.assertEqual(l2.dataProvider().wkbType(), 3)
        ref_sum2 = sum(f.attributes()[0] for f in l2.getFeatures())
        ref_sum3 = sum(f.id() for f in l2.getFeatures())
        # check we have the same rows
        self.assertEqual(ref_sum, ref_sum2)
        # check the id is OK
        self.assertEqual(ref_sum, ref_sum3)

        # with two geometry columns, but no geometry column specified (will take the first)
        l2 = QgsVectorLayer(
            "?layer_ref=%s&query=%s&uid=OBJECTID" % (l1.id(), query), "vtab",
            "virtual", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l2.isValid(), True)
        self.assertEqual(l2.dataProvider().wkbType(), 6)
        ref_sum2 = sum(f.attributes()[0] for f in l2.getFeatures())
        ref_sum3 = sum(f.id() for f in l2.getFeatures())
        # check we have the same rows
        self.assertEqual(ref_sum, ref_sum2)
        # check the id is OK
        self.assertEqual(ref_sum, ref_sum3)

        # the same, without geometry
        query = toPercent("SELECT * FROM ww")
        l2 = QgsVectorLayer(
            "?layer_ref=%s:ww&query=%s&uid=ObJeCtId&nogeometry" %
            (l1.id(), query), "vtab", "virtual",
            QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l2.isValid(), True)
        self.assertEqual(l2.dataProvider().wkbType(), 100)  # NoGeometry
        ref_sum2 = sum(f.attributes()[0] for f in l2.getFeatures())
        ref_sum3 = sum(f.id() for f in l2.getFeatures())
        self.assertEqual(ref_sum, ref_sum2)
        self.assertEqual(ref_sum, ref_sum3)

        # check that it fails when a query has a wrong geometry column
        l2 = QgsVectorLayer(
            "?layer_ref=%s&query=%s&geometry=geo" % (l1.id(), query), "vtab",
            "virtual", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l2.isValid(), False)

        QgsProject.instance().removeMapLayer(l1.id())
示例#15
0
    def test_Join(self):
        l1 = QgsVectorLayer(os.path.join(self.testDataDir, "points.shp"), "points", "ogr", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l1.isValid(), True)
        QgsProject.instance().addMapLayer(l1)
        l2 = QgsVectorLayer(os.path.join(self.testDataDir, "points_relations.shp"), "points_relations", "ogr", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l2.isValid(), True)
        QgsProject.instance().addMapLayer(l2)
        ref_sum = sum(f.attributes()[1] for f in l2.getFeatures())

        # use a temporary file
        query = toPercent("select id,Pilots,vtab1.geometry from vtab1,vtab2 where intersects(vtab1.geometry,vtab2.geometry)")
        l3 = QgsVectorLayer("?layer_ref=%s&layer_ref=%s&uid=id&query=%s&geometry=geometry:1:4326" % (l1.id(), l2.id(), query), "vtab", "virtual", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l3.isValid(), True)
        self.assertEqual(l3.dataProvider().wkbType(), 1)
        self.assertEqual(l3.dataProvider().fields().count(), 2)
        ref_sum2 = sum(f.id() for f in l3.getFeatures())
        self.assertEqual(ref_sum, ref_sum2)

        QgsProject.instance().removeMapLayer(l1)
        QgsProject.instance().removeMapLayer(l2)
示例#16
0
    def test_sql2(self):
        l2 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"),
                            "france_parts", "ogr",
                            QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l2.isValid(), True)
        QgsProject.instance().addMapLayer(l2)

        query = toPercent("SELECT * FROM france_parts")
        l4 = QgsVectorLayer("?query=%s&uid=ObjectId" % query, "tt", "virtual")
        self.assertEqual(l4.isValid(), True)

        self.assertEqual(l4.dataProvider().wkbType(), 6)
        self.assertEqual(l4.dataProvider().crs().postgisSrid(), 4326)

        n = 0
        r = QgsFeatureRequest(QgsRectangle(-1.677, 49.624, -0.816, 49.086))
        for f in l4.getFeatures(r):
            self.assertEqual(f.geometry() is not None, True)
            self.assertEqual(f.attributes()[0], 2661)
            n += 1
        self.assertEqual(n, 1)

        # use uid
        query = toPercent("SELECT * FROM france_parts")
        l5 = QgsVectorLayer(
            "?query=%s&geometry=geometry:polygon:4326&uid=ObjectId" % query,
            "tt", "virtual")
        self.assertEqual(l5.isValid(), True)

        idSum = sum(f.id() for f in l5.getFeatures())
        self.assertEqual(idSum, 10659)

        r = QgsFeatureRequest(2661)
        idSum2 = sum(f.id() for f in l5.getFeatures(r))
        self.assertEqual(idSum2, 2661)

        r = QgsFeatureRequest()
        r.setFilterFids([2661, 2664])
        self.assertEqual(sum(f.id() for f in l5.getFeatures(r)), 2661 + 2664)

        # test attribute subset
        r = QgsFeatureRequest()
        r.setFlags(QgsFeatureRequest.SubsetOfAttributes)
        r.setSubsetOfAttributes([1])
        s = [(f.id(), f.attributes()[1]) for f in l5.getFeatures(r)]
        self.assertEqual(sum([x[0] for x in s]), 10659)
        self.assertEqual(sum([x[1] for x in s]), 3064.0)

        # test NoGeometry
        # by request flag
        r = QgsFeatureRequest()
        r.setFlags(QgsFeatureRequest.NoGeometry)
        self.assertEqual(all([not f.hasGeometry() for f in l5.getFeatures(r)]),
                         True)

        # test subset
        self.assertEqual(l5.dataProvider().featureCount(), 4)
        l5.setSubsetString("ObjectId = 2661")
        idSum2 = sum(f.id() for f in l5.getFeatures(r))
        self.assertEqual(idSum2, 2661)
        self.assertEqual(l5.dataProvider().featureCount(), 1)
示例#17
0
    def test_filter_rect(self):
        source = toPercent(os.path.join(self.testDataDir, "france_parts.shp"))

        query = toPercent("select * from vtab where _search_frame_=BuildMbr(-2.10,49.38,-1.3,49.99,4326)")
        l2 = QgsVectorLayer("?layer=ogr:%s:vtab&query=%s&uid=objectid" % (source, query), "vtab2", "virtual", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l2.isValid(), True)
        self.assertEqual(l2.dataProvider().featureCount(), 1)
        a = [fit.attributes()[4] for fit in l2.getFeatures()]
        self.assertEqual(a, ["Basse-Normandie"])
    def test(self):
        l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "françéà", "ogr", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l1.isValid(), True)
        QgsProject.instance().addMapLayer(l1)

        df = QgsVirtualLayerDefinition()
        df.setQuery('select * from "françéà"')
        task = QgsVirtualLayerTask(df)

        ids = [f.id() for f in task.layer().getFeatures()]
        self.assertEqual(len(ids), 0)

        task.taskCompleted.connect(self.onSuccess)
        task.taskTerminated.connect(self.onFail)

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

        self.assertTrue(self.success)
        self.assertFalse(self.fail)

        ids = [f.id() for f in task.layer().getFeatures()]
        self.assertEqual(len(ids), 4)
示例#19
0
    def layer_to_QgsVectorLayer(
            source_layer,  # pylint: disable=too-many-locals,too-many-branches,too-many-statements
            input_file,
            context: Context,
            fallback_crs=QgsCoordinateReferenceSystem(),
            defer_layer_uri_set: bool = False):
        """
        Converts a vector layer
        """
        if source_layer.__class__.__name__ == 'CadFeatureLayer':
            layer = source_layer.layer
        else:
            layer = source_layer

        crs = CrsConverter.convert_crs(
            layer.layer_extent.crs,
            context) if layer.layer_extent else QgsCoordinateReferenceSystem()
        if not crs.isValid():
            crs = fallback_crs

        subset_string = ''
        if layer.selection_set:
            subset_string = 'fid in ({})'.format(','.join(
                [str(s) for s in layer.selection_set]))
        elif layer.definition_query:
            subset_string = ExpressionConverter.convert_esri_sql(
                layer.definition_query)

        base, _ = os.path.split(input_file)

        uri, wkb_type, provider, encoding, file_name = VectorLayerConverter.get_uri(
            source_layer=source_layer,
            obj=layer,
            base=base,
            crs=crs,
            subset=subset_string,
            context=context)

        if wkb_type is None or wkb_type == QgsWkbTypes.Unknown:
            wkb_type = VectorLayerConverter.layer_to_wkb_type(layer)
        context.layer_type_hint = wkb_type

        if Qgis.QGIS_VERSION_INT >= 31600:
            # try to get the layer name so that we can remove it from field references.
            # e.g. if layer name is polys then qgis won't support to arcgis style "polys.field" format
            parts = QgsProviderRegistry.instance().decodeUri(provider, uri)
            context.main_layer_name = parts.get('layerName')
            if not context.main_layer_name and provider == 'ogr':
                context.main_layer_name = Path(parts['path']).stem

            if context.main_layer_name:
                subset_string = subset_string.replace(
                    context.main_layer_name + '.', '')
        else:
            context.main_layer_name = None

        if provider == 'ogr' and (not file_name
                                  or not os.path.exists(file_name)
                                  ) and context.invalid_layer_resolver:
            res = context.invalid_layer_resolver(layer.name, uri, wkb_type)
            uri = res.uri
            provider = res.providerKey

        if Qgis.QGIS_VERSION_INT >= 31000:
            opts = QgsVectorLayer.LayerOptions()
            if wkb_type is not None:
                opts.fallbackWkbType = wkb_type

            if provider == 'ogr' and subset_string:
                uri += '|subset={}'.format(subset_string)

            original_uri = uri
            if defer_layer_uri_set:
                uri = 'xxxxxxxxx' + uri

            vl = QgsVectorLayer(uri, layer.name, provider, opts)
            if defer_layer_uri_set:
                vl.setCustomProperty('original_uri', original_uri)
        else:
            vl = QgsMemoryProviderUtils.createMemoryLayer(
                layer.name, QgsFields(), wkb_type, crs)

        # context.style_folder, _ = os.path.split(output_file)
        if layer.renderer:
            renderer = VectorRendererConverter.convert_renderer(
                layer.renderer, context)
            try:
                if not renderer.usingSymbolLevels():
                    renderer.setUsingSymbolLevels(
                        layer.use_advanced_symbol_levels)
            except AttributeError:
                pass

            if layer.use_page_definition_query:
                filter_expression = '"{}" {} @atlas_pagename'.format(
                    layer.page_name_field, layer.page_name_match_operator)
                root_rule = QgsRuleBasedRenderer.Rule(None)

                # special case -- convert a simple renderer
                if isinstance(renderer, QgsSingleSymbolRenderer):
                    filter_rule = QgsRuleBasedRenderer.Rule(
                        renderer.symbol().clone())
                    filter_rule.setFilterExpression(filter_expression)
                    filter_rule.setLabel(layer.name)
                    filter_rule.setDescription(layer.name)
                    root_rule.appendChild(filter_rule)
                else:
                    source_rule_renderer = QgsRuleBasedRenderer.convertFromRenderer(
                        renderer)
                    filter_rule = QgsRuleBasedRenderer.Rule(None)
                    filter_rule.setFilterExpression(filter_expression)
                    filter_rule.setLabel('Current Atlas Page')
                    filter_rule.setDescription('Current Atlas Page')
                    root_rule.appendChild(filter_rule)
                    for child in source_rule_renderer.rootRule().children():
                        filter_rule.appendChild(child.clone())

                renderer = QgsRuleBasedRenderer(root_rule)

            if renderer:
                vl.setRenderer(renderer)
                vl.triggerRepaint()
        else:
            vl.setRenderer(QgsNullSymbolRenderer())
            vl.triggerRepaint()

        metadata = vl.metadata()
        metadata.setAbstract(layer.description)
        vl.setMetadata(metadata)  #

        # layer.zoom_max = "don't show when zoomed out beyond"
        zoom_max = layer.zoom_max
        # layer.zoom_min = "don't show when zoomed in beyond"
        zoom_min = layer.zoom_min

        enabled_scale_range = bool(zoom_max or zoom_min)
        if zoom_max and zoom_min and zoom_min > zoom_max:
            # inconsistent scale range -- zoom_max should be bigger number than zoom_min
            zoom_min, zoom_max = zoom_max, zoom_min

        # qgis minimum scale = don't show when zoomed out beyond, i.e. ArcGIS zoom_max
        vl.setMinimumScale(
            zoom_max if enabled_scale_range else layer.stored_zoom_max)
        # qgis maximum scale = don't show when zoomed in beyond, i.e. ArcGIS zoom_min
        vl.setMaximumScale(
            zoom_min if enabled_scale_range else layer.stored_zoom_min)
        vl.setScaleBasedVisibility(enabled_scale_range)

        vl.setOpacity(1.0 - (layer.transparency or 0) / 100)

        if layer.display_expression_properties and layer.display_expression_properties.expression and layer.display_expression_properties.expression_parser is not None:
            vl.setDisplayExpression(
                ExpressionConverter.convert(
                    layer.display_expression_properties.expression,
                    layer.display_expression_properties.expression_parser,
                    layer.display_expression_properties.advanced, context))

        if Qgis.QGIS_VERSION_INT < 31000:
            vl.setDataSource(uri, layer.name, provider)

        if encoding:
            vl.dataProvider().setEncoding(encoding)

        if subset_string:
            vl.setSubsetString(subset_string)

        vl.setCrs(crs)

        for e in layer.extensions:
            if e.__class__.__name__ == 'ServerLayerExtension':
                if 'CopyrightText' in e.properties.properties:
                    layer_credits = e.properties.properties['CopyrightText']
                    metadata = vl.metadata()
                    rights = metadata.rights()
                    rights.append(layer_credits)
                    metadata.setRights(rights)
                    vl.setMetadata(metadata)

        LabelConverter.convert_annotation_collection(
            layer.annotation_collection, dest_layer=vl, context=context)
        vl.setLabelsEnabled(layer.labels_enabled)

        DiagramConverter.convert_diagrams(layer.renderer,
                                          dest_layer=vl,
                                          context=context)

        # setup joins
        join_layer = VectorLayerConverter.add_joined_layer(
            source_layer=layer,
            input_file=input_file,
            base_layer=vl,
            context=context)

        context.dataset_name = ''

        vl.setLegend(QgsMapLayerLegend.defaultVectorLegend(vl))

        if layer.hyperlinks:
            VectorLayerConverter.convert_hyperlinks(layer.hyperlinks, vl)

        vl.setDisplayExpression(
            QgsExpression.quotedColumnRef(layer.display_field))

        res = [vl]
        if join_layer:
            res.append(join_layer)

        context.main_layer_name = None
        return res