From 28a092b03c57f3a5a0559db2deda20f652593ec1 Mon Sep 17 00:00:00 2001 From: Harrissou Sant-anna Date: Sat, 30 Nov 2024 07:22:33 +0000 Subject: [PATCH 1/5] Update to the active docker container --- doctest.dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doctest.dockerfile b/doctest.dockerfile index f90117a9ad3..d390319c684 100644 --- a/doctest.dockerfile +++ b/doctest.dockerfile @@ -1,4 +1,4 @@ -FROM qgis/qgis:release-3_34 +FROM qgis/qgis:3.34 # Install requirement first to use caching COPY REQUIREMENTS.txt /documentation/REQUIREMENTS.txt From 5e2f2037b1087ded309cdb37576b862be2177db8 Mon Sep 17 00:00:00 2001 From: Tim Sutton Date: Thu, 27 Jun 2024 13:37:44 +0100 Subject: [PATCH 2/5] Fixing doctests in gh workflow (cherry picked from commit 74600fe1d9e8b4ccee1cbf6f8b8d948b6116bfda) --- .gitignore | 6 ++++++ Makefile | 7 +++++++ doctest.dockerfile | 7 +++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 0d8c5a2101e..f2f86d1e3cb 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,9 @@ venv .venv user.mk .vscode +shell.nix +vscode.sh +clean.sh +.envrc +.vscode-extensions +core diff --git a/Makefile b/Makefile index dc3bfeab2bb..d5d9566f607 100644 --- a/Makefile +++ b/Makefile @@ -126,6 +126,13 @@ tx_force_pull_translations: $(eval comma += ,) tx pull -f --parallel --mode onlytranslated -l $(subst $(space),$(comma),$(subst en$(space),,$(subst zh_,zh-,$(LANGUAGES)))) ; +doctest-gh: + # --system-site-packages needed to keep QGIS libs in python path + export PYTHONPATH=$(PYTHONPATH):/usr/lib/python3/dist-packages && \ + . /docsenv/bin/activate --system-site-packages && LD_PRELOAD=/lib/x86_64-linux-gnu/libSegFault.so $(SPHINXBUILD) -b doctest . $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + doctest: LD_PRELOAD=/lib/x86_64-linux-gnu/libSegFault.so $(SPHINXBUILD) -b doctest . $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ diff --git a/doctest.dockerfile b/doctest.dockerfile index d390319c684..b32c890b88a 100644 --- a/doctest.dockerfile +++ b/doctest.dockerfile @@ -2,8 +2,11 @@ FROM qgis/qgis:3.34 # Install requirement first to use caching COPY REQUIREMENTS.txt /documentation/REQUIREMENTS.txt -RUN pip3 install -r /documentation/REQUIREMENTS.txt + +# make the venv in /docsenv +WORKDIR / +RUN python3 -m venv docsenv && . docsenv/bin/activate && pip3 install -r /documentation/REQUIREMENTS.txt WORKDIR /documentation -CMD make doctest +CMD make doctest-gh From d2986338ffda8a48c817910f9b0a5ba2936f990d Mon Sep 17 00:00:00 2001 From: Harrissou Sant-anna Date: Fri, 19 Jul 2024 06:46:29 +0200 Subject: [PATCH 3/5] Fixing doctests in gh workflow (#9152) (cherry picked from commit 5b1857e3ba38ff1c9556bc1470bb4de76fb6428b) --- docs/pyqgis_developer_cookbook/canvas.rst | 4 +++ docs/pyqgis_developer_cookbook/crs.rst | 2 +- .../pyqgis_developer_cookbook/expressions.rst | 14 ++++---- docs/pyqgis_developer_cookbook/geometry.rst | 18 +++++----- docs/pyqgis_developer_cookbook/loadlayer.rst | 9 +++++ docs/pyqgis_developer_cookbook/raster.rst | 2 +- docs/pyqgis_developer_cookbook/vector.rst | 34 ++++++++++--------- 7 files changed, 49 insertions(+), 34 deletions(-) diff --git a/docs/pyqgis_developer_cookbook/canvas.rst b/docs/pyqgis_developer_cookbook/canvas.rst index 9883fc91b94..f4479fcbcf1 100644 --- a/docs/pyqgis_developer_cookbook/canvas.rst +++ b/docs/pyqgis_developer_cookbook/canvas.rst @@ -136,6 +136,10 @@ layers for the canvas. # set the map canvas layer set canvas.setLayers([vlayer]) +.. testoutput:: canvas + :hide: + + (2): Using non-preferred coordinate operation between EPSG:2964 and EPSG:4326. Using +proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=aea +lat_0=50 +lon_0=-154 +lat_1=55 +lat_2=65 +x_0=0 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-5 +y=135 +z=172 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad +xy_out=deg, preferred +proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=aea +lat_0=50 +lon_0=-154 +lat_1=55 +lat_2=65 +x_0=0 +y_0=0 +ellps=clrk66 +step +proj=hgridshift +grids=us_noaa_alaska.tif +step +proj=unitconvert +xy_in=rad +xy_out=deg. After executing these commands, the canvas should show the layer you have loaded. diff --git a/docs/pyqgis_developer_cookbook/crs.rst b/docs/pyqgis_developer_cookbook/crs.rst index da0f32e62be..f0354821975 100644 --- a/docs/pyqgis_developer_cookbook/crs.rst +++ b/docs/pyqgis_developer_cookbook/crs.rst @@ -126,7 +126,7 @@ Output: Ellipsoid Acronym: EPSG:7030 Proj String: +proj=longlat +datum=WGS84 +no_defs Is geographic: True - Map units: DistanceUnit.Degrees + Map units: 6 .. index:: Projections diff --git a/docs/pyqgis_developer_cookbook/expressions.rst b/docs/pyqgis_developer_cookbook/expressions.rst index 8b4ae7097bc..7868af54eee 100644 --- a/docs/pyqgis_developer_cookbook/expressions.rst +++ b/docs/pyqgis_developer_cookbook/expressions.rst @@ -166,17 +166,17 @@ order to compute new field values: .. testcode:: expr - from qgis.PyQt.QtCore import QVariant + from qgis.PyQt.QtCore import QMetaType # create a vector layer vl = QgsVectorLayer("Point", "Companies", "memory") pr = vl.dataProvider() - pr.addAttributes([QgsField("Name", QVariant.String), - QgsField("Employees", QVariant.Int), - QgsField("Revenue", QVariant.Double), - QgsField("Rev. per employee", QVariant.Double), - QgsField("Sum", QVariant.Double), - QgsField("Fun", QVariant.Double)]) + pr.addAttributes([QgsField("Name", QMetaType.Type.QString), + QgsField("Employees", QMetaType.Type.Int), + QgsField("Revenue", QMetaType.Type.Double), + QgsField("Rev. per employee", QMetaType.Type.Double), + QgsField("Sum", QMetaType.Type.Double), + QgsField("Fun", QMetaType.Type.Double)]) vl.updateFields() # add data to the first three fields diff --git a/docs/pyqgis_developer_cookbook/geometry.rst b/docs/pyqgis_developer_cookbook/geometry.rst index 2339ea05f4f..c57b3c0f4e0 100644 --- a/docs/pyqgis_developer_cookbook/geometry.rst +++ b/docs/pyqgis_developer_cookbook/geometry.rst @@ -148,18 +148,18 @@ enumeration. .. testcode:: geometry print(gPnt.wkbType()) - # output: 'WkbType.Point' + # output: 1 print(gLine.wkbType()) - # output: 'WkbType.LineString' + # output: 2 print(gPolygon.wkbType()) - # output: 'WkbType.Polygon' + # output: 3 .. testoutput:: geometry :hide: - WkbType.Point - WkbType.LineString - WkbType.Polygon + 1 + 2 + 3 As an alternative, one can use the :meth:`type() ` method which returns a value from the :meth:`QgsWkbTypes.GeometryType ` @@ -168,12 +168,12 @@ enumeration. .. testcode:: geometry print(gLine.type()) - # output: 'GeometryType.Line' + # output: 1 .. testoutput:: geometry :hide: - GeometryType.Line + 1 You can use the :meth:`displayString() ` function to get a human readable geometry type. @@ -279,7 +279,7 @@ It's also possible to modify each part of the geometry using .. testoutput:: geometry - MultiPoint ((-10334728.12541878595948219 -5360106.25905461423099041),(-10462135.16126426123082638 -5217485.4735023295506835),(-10589399.84444035589694977 -5072021.45942386891692877)) + MultiPoint ((-10334726.79314758814871311 -5360105.10101194866001606),(-10462133.82917747274041176 -5217484.34365733992308378),(-10589398.51346861757338047 -5072020.35880533326417208)) .. index:: Geometry; Predicates and operations diff --git a/docs/pyqgis_developer_cookbook/loadlayer.rst b/docs/pyqgis_developer_cookbook/loadlayer.rst index 536da7b8cda..5ac9389d1b7 100644 --- a/docs/pyqgis_developer_cookbook/loadlayer.rst +++ b/docs/pyqgis_developer_cookbook/loadlayer.rst @@ -65,6 +65,11 @@ identifier, name for the layer and provider's name: else: QgsProject.instance().addMapLayer(vlayer) +.. .. testoutput:: loadlayer + :hide: + + (2): Using non-preferred coordinate operation between EPSG:2964 and EPSG:4326. Using +proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=aea +lat_0=50 +lon_0=-154 +lat_1=55 +lat_2=65 +x_0=0 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-5 +y=135 +z=172 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad +xy_out=deg, preferred +proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=aea +lat_0=50 +lon_0=-154 +lat_1=55 +lat_2=65 +x_0=0 +y_0=0 +ellps=clrk66 +step +proj=hgridshift +grids=us_noaa_alaska.tif +step +proj=unitconvert +xy_in=rad +xy_out=deg. + The data source identifier is a string and it is specific to each vector data provider. Layer's name is used in the layer list widget. It is important to check whether the layer has been loaded successfully. If it was not, an invalid @@ -225,6 +230,10 @@ providers: uri = "https://demo.mapserver.org/cgi-bin/wfs?service=WFS&version=2.0.0&request=GetFeature&typename=ms:cities" vlayer = QgsVectorLayer(uri, "my wfs layer", "WFS") + .. .. testoutput:: loadlayer + :hide: + + (2): Using non-preferred coordinate operation between EPSG:2964 and EPSG:4326. Using +proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=aea +lat_0=50 +lon_0=-154 +lat_1=55 +lat_2=65 +x_0=0 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-5 +y=135 +z=172 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad +xy_out=deg, preferred +proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=aea +lat_0=50 +lon_0=-154 +lat_1=55 +lat_2=65 +x_0=0 +y_0=0 +ellps=clrk66 +step +proj=hgridshift +grids=us_noaa_alaska.tif +step +proj=unitconvert +xy_in=rad +xy_out=deg. The uri can be created using the standard ``urllib`` library: diff --git a/docs/pyqgis_developer_cookbook/raster.rst b/docs/pyqgis_developer_cookbook/raster.rst index 0309d9fae76..bcf91d1e915 100644 --- a/docs/pyqgis_developer_cookbook/raster.rst +++ b/docs/pyqgis_developer_cookbook/raster.rst @@ -114,7 +114,7 @@ The following code assumes ``rlayer`` is a .. testoutput:: raster - RasterLayerType.GrayOrUndefined + 0 .. testcode:: raster diff --git a/docs/pyqgis_developer_cookbook/vector.rst b/docs/pyqgis_developer_cookbook/vector.rst index 6b53fdc20f0..3eec9ac5f5e 100644 --- a/docs/pyqgis_developer_cookbook/vector.rst +++ b/docs/pyqgis_developer_cookbook/vector.rst @@ -502,7 +502,7 @@ Here you have some examples that demonstrate how to use these editing methods. .. testcode:: vectors - from qgis.PyQt.QtCore import QVariant + from qgis.PyQt.QtCore import QMetaType feat1 = feat2 = QgsFeature(layer.fields()) fid = 99 @@ -522,7 +522,7 @@ Here you have some examples that demonstrate how to use these editing methods. layer.changeAttributeValue(fid, fieldIndex, value) # add new field - layer.addAttribute(QgsField("mytext", QVariant.String)) + layer.addAttribute(QgsField("mytext", QMetaType.Type.QString)) # remove a field layer.deleteAttribute(fieldIndex) @@ -579,12 +579,12 @@ For deletion of fields just provide a list of field indexes. .. testcode:: vectors - from qgis.PyQt.QtCore import QVariant + from qgis.PyQt.QtCore import QMetaType if caps & QgsVectorDataProvider.AddAttributes: res = layer.dataProvider().addAttributes( - [QgsField("mytext", QVariant.String), - QgsField("myint", QVariant.Int)]) + [QgsField("mytext", QMetaType.Type.QString), + QgsField("myint", QMetaType.Type.Int)]) if caps & QgsVectorDataProvider.DeleteAttributes: res = layer.dataProvider().deleteAttributes([0]) @@ -593,7 +593,9 @@ For deletion of fields just provide a list of field indexes. # Alternate methods for removing fields # first create temporary fields to be removed (f1-3) - layer.dataProvider().addAttributes([QgsField("f1",QVariant.Int),QgsField("f2",QVariant.Int),QgsField("f3",QVariant.Int)]) + layer.dataProvider().addAttributes([QgsField("f1", QMetaType.Type.Int), + QgsField("f2", QMetaType.Type.Int), + QgsField("f3", QMetaType.Type.Int)]) layer.updateFields() count=layer.fields().count() # count of layer fields ind_list=list((count-3, count-2)) # create list @@ -839,7 +841,7 @@ you can do the following: def fieldDefinition(self, field): idx = self.layer.fields().indexFromName(field.name()) if idx == self.list_field_idx: - return QgsField(LIST_FIELD_NAME, QVariant.String) + return QgsField(LIST_FIELD_NAME, QMetaType.Type.QString) else: return self.layer.fields()[idx] @@ -867,12 +869,12 @@ Directly from features .. testcode:: vectors - from qgis.PyQt.QtCore import QVariant + from qgis.PyQt.QtCore import QMetaType # define fields for feature attributes. A QgsFields object is needed fields = QgsFields() - fields.append(QgsField("first", QVariant.Int)) - fields.append(QgsField("second", QVariant.String)) + fields.append(QgsField("first", QMetaType.Type.Int)) + fields.append(QgsField("second", QMetaType.Type.QString)) """ create an instance of vector file writer, which will create the vector file. Arguments: @@ -966,22 +968,22 @@ The following example code illustrates creating and populating a memory provider .. testcode:: vectors - from qgis.PyQt.QtCore import QVariant + from qgis.PyQt.QtCore import QMetaType # create layer vl = QgsVectorLayer("Point", "temporary_points", "memory") pr = vl.dataProvider() # add fields - pr.addAttributes([QgsField("name", QVariant.String), - QgsField("age", QVariant.Int), - QgsField("size", QVariant.Double)]) + pr.addAttributes([QgsField("name", QMetaType.Type.QString), + QgsField("age", QMetaType.Type.Int), + QgsField("size", QMetaType.Type.Double)]) vl.updateFields() # tell the vector layer to fetch changes from the provider # add a feature fet = QgsFeature() fet.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(10,10))) - fet.setAttributes(["Johny", 2, 0.3]) + fet.setAttributes(["Johnny", 2, 0.3]) pr.addFeatures([fet]) # update layer's extent when new features have been added @@ -1008,7 +1010,7 @@ Finally, let's check whether everything went well fields: 3 features: 1 extent: 10.0 10.0 10.0 10.0 - F: 1 ['Johny', 2, 0.3] + F: 1 ['Johnny', 2, 0.3] .. index:: Vector layers; Symbology From e0039cb2d97cfdf3315f3af6d55af8b4b2c98e92 Mon Sep 17 00:00:00 2001 From: Harrissou Sant-anna Date: Sat, 30 Nov 2024 00:08:34 +0100 Subject: [PATCH 4/5] Attempt to fix doctests by using airports layer in epsg4326 instead of epsg2964 (#9256) (cherry picked from commit 11f4976c2e6077e6ac6253ed84151c8e37a5fd58) --- docs/pyqgis_developer_cookbook/canvas.rst | 7 +- .../pyqgis_developer_cookbook/cheat_sheet.rst | 2 +- docs/pyqgis_developer_cookbook/loadlayer.rst | 78 ++++++++----------- docs/pyqgis_developer_cookbook/vector.rst | 33 ++++---- 4 files changed, 54 insertions(+), 66 deletions(-) diff --git a/docs/pyqgis_developer_cookbook/canvas.rst b/docs/pyqgis_developer_cookbook/canvas.rst index f4479fcbcf1..94165768898 100644 --- a/docs/pyqgis_developer_cookbook/canvas.rst +++ b/docs/pyqgis_developer_cookbook/canvas.rst @@ -123,7 +123,7 @@ layers for the canvas. .. testcode:: canvas - vlayer = QgsVectorLayer('testdata/airports.shp', "Airports layer", "ogr") + vlayer = QgsVectorLayer("testdata/data/data.gpkg|layername=airports", "Airports layer", "ogr") if not vlayer.isValid(): print("Layer failed to load!") @@ -136,11 +136,6 @@ layers for the canvas. # set the map canvas layer set canvas.setLayers([vlayer]) -.. testoutput:: canvas - :hide: - - (2): Using non-preferred coordinate operation between EPSG:2964 and EPSG:4326. Using +proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=aea +lat_0=50 +lon_0=-154 +lat_1=55 +lat_2=65 +x_0=0 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-5 +y=135 +z=172 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad +xy_out=deg, preferred +proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=aea +lat_0=50 +lon_0=-154 +lat_1=55 +lat_2=65 +x_0=0 +y_0=0 +ellps=clrk66 +step +proj=hgridshift +grids=us_noaa_alaska.tif +step +proj=unitconvert +xy_in=rad +xy_out=deg. - After executing these commands, the canvas should show the layer you have loaded. diff --git a/docs/pyqgis_developer_cookbook/cheat_sheet.rst b/docs/pyqgis_developer_cookbook/cheat_sheet.rst index fa03c69367f..e032cd9dd93 100644 --- a/docs/pyqgis_developer_cookbook/cheat_sheet.rst +++ b/docs/pyqgis_developer_cookbook/cheat_sheet.rst @@ -168,7 +168,7 @@ Layers .. testcode:: cheat_sheet - layer = iface.addVectorLayer("testdata/airports.shp", "layer name you like", "ogr") + layer = iface.addVectorLayer("testdata/data/data.gpkg|layername=airports", "Airports layer", "ogr") if not layer or not layer.isValid(): print("Layer failed to load!") diff --git a/docs/pyqgis_developer_cookbook/loadlayer.rst b/docs/pyqgis_developer_cookbook/loadlayer.rst index 5ac9389d1b7..092b5ca97d3 100644 --- a/docs/pyqgis_developer_cookbook/loadlayer.rst +++ b/docs/pyqgis_developer_cookbook/loadlayer.rst @@ -48,43 +48,21 @@ them here. Vector Layers ============= -To create and add a vector layer instance to the project, specify the layer's data source -identifier, name for the layer and provider's name: - -.. testcode:: loadlayer - - # get the path to the shapefile e.g. /home/project/data/ports.shp - path_to_airports_layer = "testdata/airports.shp" - - # The format is: - # vlayer = QgsVectorLayer(data_source, layer_name, provider_name) - - vlayer = QgsVectorLayer(path_to_airports_layer, "Airports layer", "ogr") - if not vlayer.isValid(): - print("Layer failed to load!") - else: - QgsProject.instance().addMapLayer(vlayer) - -.. .. testoutput:: loadlayer - :hide: - - (2): Using non-preferred coordinate operation between EPSG:2964 and EPSG:4326. Using +proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=aea +lat_0=50 +lon_0=-154 +lat_1=55 +lat_2=65 +x_0=0 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-5 +y=135 +z=172 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad +xy_out=deg, preferred +proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=aea +lat_0=50 +lon_0=-154 +lat_1=55 +lat_2=65 +x_0=0 +y_0=0 +ellps=clrk66 +step +proj=hgridshift +grids=us_noaa_alaska.tif +step +proj=unitconvert +xy_in=rad +xy_out=deg. - -The data source identifier is a string and it is specific to each vector data -provider. Layer's name is used in the layer list widget. It is important to -check whether the layer has been loaded successfully. If it was not, an invalid -layer instance is returned. +To create and add a vector layer instance to the project, specify the layer's data source identifier. +The data source identifier is a string and it is specific to each vector data provider. +An optional layer name is used for identifying the layer in the :guilabel:`Layers` panel. +It is important to check whether the layer has been loaded successfully. +If it was not, an invalid layer instance is returned. For a geopackage vector layer: .. testcode:: loadlayer - # get the path to a geopackage e.g. /usr/share/qgis/resources/data/world_map.gpkg - path_to_gpkg = os.path.join(QgsApplication.pkgDataPath(), "resources", "data", "world_map.gpkg") + # get the path to a geopackage + path_to_gpkg = "testdata/data/data.gpkg" # append the layername part - gpkg_countries_layer = path_to_gpkg + "|layername=countries" - # e.g. gpkg_places_layer = "/usr/share/qgis/resources/data/world_map.gpkg|layername=countries" - vlayer = QgsVectorLayer(gpkg_countries_layer, "Countries layer", "ogr") + gpkg_airports_layer = path_to_gpkg + "|layername=airports" + vlayer = QgsVectorLayer(gpkg_airports_layer, "Airports layer", "ogr") if not vlayer.isValid(): print("Layer failed to load!") else: @@ -92,11 +70,11 @@ For a geopackage vector layer: The quickest way to open and display a vector layer in QGIS is the :meth:`addVectorLayer() ` -method of the :class:`QgisInterface `: +method of the :class:`QgisInterface ` class: .. testcode:: loadlayer - vlayer = iface.addVectorLayer(path_to_airports_layer, "Airports layer", "ogr") + vlayer = iface.addVectorLayer(gpkg_airports_layer, "Airports layer", "ogr") if not vlayer: print("Layer failed to load!") @@ -110,23 +88,36 @@ providers: .. index:: pair: Loading; GDAL layers -* GDAL library (Shapefile and many other file formats) --- data source is the - path to the file: +* The ogr provider from the GDAL library supports a `wide variety of formats + `_, + also called drivers in GDAL speak. + Examples are ESRI Shapefile, Geopackage, Flatgeobuf, Geojson, ... + For single-file formats the filepath usually suffices as uri. + For geopackages or dxf, a pipe separated suffix allows to specify the layer to load. + + * for ESRI Shapefile: + + .. code:: + + uri = "testdata/airports.shp" + vlayer = QgsVectorLayer(uri, "layer_name_you_like", "ogr") + QgsProject.instance().addMapLayer(vlayer) - * for Shapefile: + * for Geopackage (note the internal options in data source uri): .. testcode:: loadlayer - vlayer = QgsVectorLayer("testdata/airports.shp", "layer_name_you_like", "ogr") - QgsProject.instance().addMapLayer(vlayer) + uri = "testdata/data/data.gpkg|layername=airports" + vlayer = QgsVectorLayer(uri, "layer_name_you_like", "ogr") + QgsProject.instance().addMapLayer(vlayer) * for dxf (note the internal options in data source uri): .. testcode:: loadlayer - uri = "testdata/sample.dxf|layername=entities|geometrytype=Polygon" - vlayer = QgsVectorLayer(uri, "layer_name_you_like", "ogr") - QgsProject.instance().addMapLayer(vlayer) + uri = "testdata/sample.dxf|layername=entities|geometrytype=Polygon" + vlayer = QgsVectorLayer(uri, "layer_name_you_like", "ogr") + QgsProject.instance().addMapLayer(vlayer) .. index:: pair: Loading; PostGIS layers @@ -230,11 +221,6 @@ providers: uri = "https://demo.mapserver.org/cgi-bin/wfs?service=WFS&version=2.0.0&request=GetFeature&typename=ms:cities" vlayer = QgsVectorLayer(uri, "my wfs layer", "WFS") - .. .. testoutput:: loadlayer - :hide: - - (2): Using non-preferred coordinate operation between EPSG:2964 and EPSG:4326. Using +proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=aea +lat_0=50 +lon_0=-154 +lat_1=55 +lat_2=65 +x_0=0 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-5 +y=135 +z=172 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad +xy_out=deg, preferred +proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=aea +lat_0=50 +lon_0=-154 +lat_1=55 +lat_2=65 +x_0=0 +y_0=0 +ellps=clrk66 +step +proj=hgridshift +grids=us_noaa_alaska.tif +step +proj=unitconvert +xy_in=rad +xy_out=deg. - The uri can be created using the standard ``urllib`` library: .. testcode:: loadlayer diff --git a/docs/pyqgis_developer_cookbook/vector.rst b/docs/pyqgis_developer_cookbook/vector.rst index 3eec9ac5f5e..8933cfb7d7b 100644 --- a/docs/pyqgis_developer_cookbook/vector.rst +++ b/docs/pyqgis_developer_cookbook/vector.rst @@ -73,18 +73,25 @@ by calling :meth:`fields() ` on a .. testcode:: vectors - vlayer = QgsVectorLayer("testdata/airports.shp", "airports", "ogr") + vlayer = QgsVectorLayer("testdata/data/data.gpkg|layername=airports", "Airports layer", "ogr") for field in vlayer.fields(): print(field.name(), field.typeName()) .. testoutput:: vectors - ID Integer64 - fk_region Integer64 - ELEV Real - NAME String - USE String + fid Integer64 + id Integer64 + scalerank Integer64 + featurecla String + type String + name String + abbrev String + location String + gps_code String + iata_code String + wikipedia String + natlscale Real The :meth:`displayField() ` and :meth:`mapTipTemplate() ` methods provide @@ -96,13 +103,13 @@ methods you can easily get both: .. testcode:: vectors - vlayer = QgsVectorLayer("testdata/airports.shp", "airports", "ogr") + vlayer = QgsVectorLayer("testdata/data/data.gpkg|layername=airports", "Airports layer", "ogr") print(vlayer.displayField()) .. testoutput:: vectors - NAME + name .. note:: If you change the ``Display Name`` from a field to an expression, you have to use :meth:`displayExpression() ` @@ -703,7 +710,7 @@ field: .. testcode:: vectors - vlayer = QgsVectorLayer("testdata/airports.shp", "airports", "ogr") + vlayer = QgsVectorLayer("testdata/data/data.gpkg|layername=airports", "Airports layer", "ogr") feat = QgsVectorLayerUtils.createFeature(vlayer) @@ -712,7 +719,7 @@ you to quickly get the values of a field or expression: .. testcode:: vectors - vlayer = QgsVectorLayer("testdata/airports.shp", "airports", "ogr") + vlayer = QgsVectorLayer("testdata/data/data.gpkg|layername=airports", "Airports layer", "ogr") # select only the first feature to make the output shorter vlayer.selectByIds([1]) val = QgsVectorLayerUtils.getValues(vlayer, "NAME", selectedOnly=True) @@ -720,7 +727,7 @@ you to quickly get the values of a field or expression: .. testoutput:: vectors - (['AMBLER'], True) + (['Sahnewal'], True) .. index:: Vector layers; Creating @@ -1230,8 +1237,8 @@ arrangement) from qgis.PyQt import QtGui - myVectorLayer = QgsVectorLayer("testdata/airports.shp", "airports", "ogr") - myTargetField = 'ELEV' + myVectorLayer = QgsVectorLayer("testdata/data/data.gpkg|layername=airports", "Airports layer", "ogr") + myTargetField = 'scalerank' myRangeList = [] myOpacity = 1 # Make our first symbol and range... From 18ff5a02c0dec076c7ff86849afb378e52273cc9 Mon Sep 17 00:00:00 2001 From: Harrissou Sant-anna Date: Sun, 1 Dec 2024 20:15:15 +0100 Subject: [PATCH 5/5] No QMetatype in 3.34 --- .../pyqgis_developer_cookbook/expressions.rst | 14 ++++---- docs/pyqgis_developer_cookbook/vector.rst | 32 +++++++++---------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/docs/pyqgis_developer_cookbook/expressions.rst b/docs/pyqgis_developer_cookbook/expressions.rst index 7868af54eee..8b4ae7097bc 100644 --- a/docs/pyqgis_developer_cookbook/expressions.rst +++ b/docs/pyqgis_developer_cookbook/expressions.rst @@ -166,17 +166,17 @@ order to compute new field values: .. testcode:: expr - from qgis.PyQt.QtCore import QMetaType + from qgis.PyQt.QtCore import QVariant # create a vector layer vl = QgsVectorLayer("Point", "Companies", "memory") pr = vl.dataProvider() - pr.addAttributes([QgsField("Name", QMetaType.Type.QString), - QgsField("Employees", QMetaType.Type.Int), - QgsField("Revenue", QMetaType.Type.Double), - QgsField("Rev. per employee", QMetaType.Type.Double), - QgsField("Sum", QMetaType.Type.Double), - QgsField("Fun", QMetaType.Type.Double)]) + pr.addAttributes([QgsField("Name", QVariant.String), + QgsField("Employees", QVariant.Int), + QgsField("Revenue", QVariant.Double), + QgsField("Rev. per employee", QVariant.Double), + QgsField("Sum", QVariant.Double), + QgsField("Fun", QVariant.Double)]) vl.updateFields() # add data to the first three fields diff --git a/docs/pyqgis_developer_cookbook/vector.rst b/docs/pyqgis_developer_cookbook/vector.rst index 8933cfb7d7b..2f57b5164f6 100644 --- a/docs/pyqgis_developer_cookbook/vector.rst +++ b/docs/pyqgis_developer_cookbook/vector.rst @@ -509,7 +509,7 @@ Here you have some examples that demonstrate how to use these editing methods. .. testcode:: vectors - from qgis.PyQt.QtCore import QMetaType + from qgis.PyQt.QtCore import QVariant feat1 = feat2 = QgsFeature(layer.fields()) fid = 99 @@ -529,7 +529,7 @@ Here you have some examples that demonstrate how to use these editing methods. layer.changeAttributeValue(fid, fieldIndex, value) # add new field - layer.addAttribute(QgsField("mytext", QMetaType.Type.QString)) + layer.addAttribute(QgsField("mytext", QVariant.String)) # remove a field layer.deleteAttribute(fieldIndex) @@ -586,12 +586,12 @@ For deletion of fields just provide a list of field indexes. .. testcode:: vectors - from qgis.PyQt.QtCore import QMetaType + from qgis.PyQt.QtCore import QVariant if caps & QgsVectorDataProvider.AddAttributes: res = layer.dataProvider().addAttributes( - [QgsField("mytext", QMetaType.Type.QString), - QgsField("myint", QMetaType.Type.Int)]) + [QgsField("mytext", QVariant.String), + QgsField("myint", QVariant.Int)]) if caps & QgsVectorDataProvider.DeleteAttributes: res = layer.dataProvider().deleteAttributes([0]) @@ -600,9 +600,9 @@ For deletion of fields just provide a list of field indexes. # Alternate methods for removing fields # first create temporary fields to be removed (f1-3) - layer.dataProvider().addAttributes([QgsField("f1", QMetaType.Type.Int), - QgsField("f2", QMetaType.Type.Int), - QgsField("f3", QMetaType.Type.Int)]) + layer.dataProvider().addAttributes([QgsField("f1", QVariant.Int), + QgsField("f2", QVariant.Int), + QgsField("f3", QVariant.Int)]) layer.updateFields() count=layer.fields().count() # count of layer fields ind_list=list((count-3, count-2)) # create list @@ -848,7 +848,7 @@ you can do the following: def fieldDefinition(self, field): idx = self.layer.fields().indexFromName(field.name()) if idx == self.list_field_idx: - return QgsField(LIST_FIELD_NAME, QMetaType.Type.QString) + return QgsField(LIST_FIELD_NAME, QVariant.String) else: return self.layer.fields()[idx] @@ -876,12 +876,12 @@ Directly from features .. testcode:: vectors - from qgis.PyQt.QtCore import QMetaType + from qgis.PyQt.QtCore import QVariant # define fields for feature attributes. A QgsFields object is needed fields = QgsFields() - fields.append(QgsField("first", QMetaType.Type.Int)) - fields.append(QgsField("second", QMetaType.Type.QString)) + fields.append(QgsField("first", QVariant.Int)) + fields.append(QgsField("second", QVariant.String)) """ create an instance of vector file writer, which will create the vector file. Arguments: @@ -975,16 +975,16 @@ The following example code illustrates creating and populating a memory provider .. testcode:: vectors - from qgis.PyQt.QtCore import QMetaType + from qgis.PyQt.QtCore import QVariant # create layer vl = QgsVectorLayer("Point", "temporary_points", "memory") pr = vl.dataProvider() # add fields - pr.addAttributes([QgsField("name", QMetaType.Type.QString), - QgsField("age", QMetaType.Type.Int), - QgsField("size", QMetaType.Type.Double)]) + pr.addAttributes([QgsField("name", QVariant.String), + QgsField("age", QVariant.Int), + QgsField("size", QVariant.Double)]) vl.updateFields() # tell the vector layer to fetch changes from the provider # add a feature