Skip to content

Commit d3b7b60

Browse files
authored
PyQGIS cookbook updates during the Coruna Dev meeting
* cookbook data structure * pyqgis cookbook project + data * add 2 raster dataset to the gpkg * pyqgis raster chapter tested and ready to use * load vector layer improvements * show how to load a gpkg layer * be more specific about code imports * add specific imports at the beggining * finish loading vector layers * better raster layer loading * finished loadlayer pycook * verify composer rst completed * finish verifying communication with the user pyqgis chapter * show how to load raster from gpkg * [settings.rst] Doublecheck code, add imports and comments, fix typos (qgis#3514) * [settings.rst] Doublecheck code, add imports and comments, fix typos * [settings.rst] Move all import to top * [settings.rst] fix whitespace issue * fix mapcanvas imports * some small fixes + reorder for consistency * fix rubberband + vertex markers * [geometry.rst] tested and updated geometry.rst of the pyqgis cookbook (qgis#3522) * Changed code snippets to be self-contained examples, minor edits to tutorial text * Update geometry.rst minor text formatting * Update source/docs/pyqgis_developer_cookbook/geometry.rst Co-Authored-By: arongergely <[email protected]> * Update source/docs/pyqgis_developer_cookbook/geometry.rst Co-Authored-By: arongergely <[email protected]> * Update source/docs/pyqgis_developer_cookbook/geometry.rst Co-Authored-By: arongergely <[email protected]> * Split line in code snippet for legibility * Added a snippet with all the imports * Minor snippet and non-code text edits * .rst markup fix * Removed prompt strings ('>>>') from snippets, small corrections to code examples * Improve characthers max number * Update source/docs/pyqgis_developer_cookbook/loadlayer.rst Co-Authored-By: SrNetoChan <[email protected]> * Update source/docs/pyqgis_developer_cookbook/communicating.rst Co-Authored-By: SrNetoChan <[email protected]> * Update source/docs/pyqgis_developer_cookbook/communicating.rst Co-Authored-By: SrNetoChan <[email protected]> * Update source/docs/pyqgis_developer_cookbook/geometry.rst Co-Authored-By: SrNetoChan <[email protected]> * Update source/docs/pyqgis_developer_cookbook/geometry.rst Co-Authored-By: SrNetoChan <[email protected]> * Update source/docs/pyqgis_developer_cookbook/geometry.rst Co-Authored-By: SrNetoChan <[email protected]> * Update source/docs/pyqgis_developer_cookbook/geometry.rst Co-Authored-By: SrNetoChan <[email protected]> * Update source/docs/pyqgis_developer_cookbook/loadlayer.rst Co-Authored-By: SrNetoChan <[email protected]>
1 parent adfc523 commit d3b7b60

File tree

10 files changed

+9674
-295
lines changed

10 files changed

+9674
-295
lines changed

qgis-projects/python_cookbook/01_project.qgs

+9,244
Large diffs are not rendered by default.
7.68 MB
Binary file not shown.
2.17 MB
Binary file not shown.

source/docs/pyqgis_developer_cookbook/canvas.rst

+91-91
Original file line numberDiff line numberDiff line change
@@ -90,22 +90,101 @@ layers for canvas
9090

9191
.. code-block:: python
9292
93-
layer = QgsVectorLayer(path, name, provider)
94-
if not layer.isValid():
95-
raise IOError, "Failed to open the layer"
93+
path_to_ports_layer = os.path.join(QgsProject.instance().homePath(), "data", "ports", "ports.shp")
9694
97-
# add layer to the registry
98-
QgsProject.instance().addMapLayer(layer)
95+
vlayer = QgsVectorLayer(path_to_ports_layer, "Ports layer", "ogr")
96+
if not vlayer.isValid():
97+
print("Layer failed to load!")
9998
100-
# set extent to the extent of our layer
101-
canvas.setExtent(layer.extent())
99+
# add layer to the registry
100+
QgsProject.instance().addMapLayer(vlayer)
102101
103-
# set the map canvas layer set
104-
canvas.setLayers([layer])
102+
# set extent to the extent of our layer
103+
canvas.setExtent(vlayer.extent())
104+
105+
# set the map canvas layer set
106+
canvas.setLayers([vlayer])
105107
106108
After executing these commands, the canvas should show the layer you have
107109
loaded.
108110

111+
.. index:: Map canvas; Rubber bands, Map canvas; Vertex markers
112+
113+
Rubber Bands and Vertex Markers
114+
===============================
115+
116+
To show some additional data on top of the map in canvas, use map canvas items.
117+
It is possible to create custom canvas item classes (covered below), however
118+
there are two useful canvas item classes for convenience:
119+
:class:`QgsRubberBand <qgis.gui.QgsRubberBand>` for drawing polylines or polygons, and
120+
:class:`QgsVertexMarker <qgis.gui.QgsVertexMarker>` for drawing points. They both work with map
121+
coordinates, so the shape is moved/scaled automatically when the canvas is
122+
being panned or zoomed.
123+
124+
To show a polyline
125+
126+
.. code-block:: python
127+
128+
r = QgsRubberBand(canvas, False) # False = not a polygon
129+
points = [QgsPoint(-100, 45), QgsPoint(10, 60), QgsPoint(120, 45)]
130+
r.setToGeometry(QgsGeometry.fromPolyline(points), None)
131+
132+
To show a polygon
133+
134+
.. code-block:: python
135+
136+
r = QgsRubberBand(canvas, True) # True = a polygon
137+
points = [[QgsPointXY(-100, 35), QgsPointXY(10, 50), QgsPointXY(120, 35)]]
138+
r.setToGeometry(QgsGeometry.fromPolygonXY(points), None)
139+
140+
Note that points for polygon is not a plain list: in fact, it is a list of
141+
rings containing linear rings of the polygon: first ring is the outer border,
142+
further (optional) rings correspond to holes in the polygon.
143+
144+
Rubber bands allow some customization, namely to change their color and line
145+
width
146+
147+
.. code-block:: python
148+
149+
r.setColor(QColor(0, 0, 255))
150+
r.setWidth(3)
151+
152+
The canvas items are bound to the canvas scene. To temporarily hide them (and
153+
show them again), use the :func:`hide` and :func:`show` combo. To completely remove
154+
the item, you have to remove it from the scene of the canvas
155+
156+
.. code-block:: python
157+
158+
canvas.scene().removeItem(r)
159+
160+
(in C++ it's possible to just delete the item, however in Python ``del r``
161+
would just delete the reference and the object will still exist as it is owned
162+
by the canvas)
163+
164+
Rubber band can be also used for drawing points, but the
165+
:class:`QgsVertexMarker <qgis.gui.QgsVertexMarker>` class is better suited for this
166+
(:class:`QgsRubberBand <qgis.gui.QgsRubberBand>` would only draw a rectangle around the desired point).
167+
168+
You can use the vertex marker like this:
169+
170+
.. code-block:: python
171+
172+
m = QgsVertexMarker(canvas)
173+
m.setCenter(QgsPointXY(10,40))
174+
175+
This will draw a red cross on position **[10,45]**. It is possible to customize the
176+
icon type, size, color and pen width
177+
178+
.. code-block:: python
179+
180+
m.setColor(QColor(0, 255, 0))
181+
m.setIconSize(5)
182+
m.setIconType(QgsVertexMarker.ICON_BOX) # or ICON_CROSS, ICON_X
183+
m.setPenWidth(3)
184+
185+
For temporary hiding of vertex markers and removing them from canvas, use the same methods
186+
as for rubber bands.
187+
109188
.. index:: Map canvas; Map tools
110189

111190
Using Map Tools with Canvas
@@ -123,9 +202,8 @@ are activated using :meth:`setMapTool() <qgis.gui.QgsMapCanvas.setMapTool>` meth
123202
.. code-block:: python
124203
125204
from qgis.gui import *
126-
from qgis.PyQt.QtGui import QAction
205+
from PyQt5.QtWidgets import QAction, QMainWindow
127206
from qgis.PyQt.QtCore import Qt
128-
from qgis.PyQt.QtWidgets import QMainWindow
129207
130208
class MyWnd(QMainWindow):
131209
def __init__(self, layer):
@@ -182,86 +260,8 @@ selected layer on the newly created canvas
182260

183261
.. code-block:: python
184262
185-
import mywnd
186-
w = mywnd.MyWnd(iface.activeLayer())
187-
w.show()
188-
189-
.. index:: Map canvas; Rubber bands, Map canvas; Vertex markers
190-
191-
Rubber Bands and Vertex Markers
192-
===============================
193-
194-
To show some additional data on top of the map in canvas, use map canvas items.
195-
It is possible to create custom canvas item classes (covered below), however
196-
there are two useful canvas item classes for convenience:
197-
:class:`QgsRubberBand <qgis.gui.QgsRubberBand>` for drawing polylines or polygons, and
198-
:class:`QgsVertexMarker <qgis.gui.QgsVertexMarker>` for drawing points. They both work with map
199-
coordinates, so the shape is moved/scaled automatically when the canvas is
200-
being panned or zoomed.
201-
202-
To show a polyline
203-
204-
.. code-block:: python
205-
206-
r = QgsRubberBand(canvas, False) # False = not a polygon
207-
points = [QgsPoint(-1, -1), QgsPoint(0, 1), QgsPoint(1, -1)]
208-
r.setToGeometry(QgsGeometry.fromPolyline(points), None)
209-
210-
To show a polygon
211-
212-
.. code-block:: python
213-
214-
r = QgsRubberBand(canvas, True) # True = a polygon
215-
points = [[QgsPoint(-1, -1), QgsPoint(0, 1), QgsPoint(1, -1)]]
216-
r.setToGeometry(QgsGeometry.fromPolygon(points), None)
217-
218-
Note that points for polygon is not a plain list: in fact, it is a list of
219-
rings containing linear rings of the polygon: first ring is the outer border,
220-
further (optional) rings correspond to holes in the polygon.
221-
222-
Rubber bands allow some customization, namely to change their color and line
223-
width
224-
225-
.. code-block:: python
226-
227-
r.setColor(QColor(0, 0, 255))
228-
r.setWidth(3)
229-
230-
The canvas items are bound to the canvas scene. To temporarily hide them (and
231-
show them again), use the :func:`hide` and :func:`show` combo. To completely remove
232-
the item, you have to remove it from the scene of the canvas
233-
234-
.. code-block:: python
235-
236-
canvas.scene().removeItem(r)
237-
238-
(in C++ it's possible to just delete the item, however in Python ``del r``
239-
would just delete the reference and the object will still exist as it is owned
240-
by the canvas)
241-
242-
Rubber band can be also used for drawing points, but the
243-
:class:`QgsVertexMarker <qgis.gui.QgsVertexMarker>` class is better suited for this
244-
(:class:`QgsRubberBand <qgis.gui.QgsRubberBand>` would only draw a rectangle around the desired point).
245-
246-
You can use the vertex marker like this:
247-
248-
.. code-block:: python
249-
250-
m = QgsVertexMarker(canvas)
251-
m.setCenter(QgsPointXY(0, 0))
252-
253-
This will draw a red cross on position [0,0]. It is possible to customize the
254-
icon type, size, color and pen width
255-
256-
.. code-block:: python
257-
258-
m.setColor(QColor(0, 255, 0))
259-
m.setIconSize(5)
260-
m.setIconType(QgsVertexMarker.ICON_BOX) # or ICON_CROSS, ICON_X
261-
m.setPenWidth(3)
262-
263-
For temporary hiding of vertex markers and removing them from canvas, use the same methods
264-
as for rubber bands.
263+
w = MyWnd(iface.activeLayer())
264+
w.show()
265265
266266
.. index:: Map canvas; Custom map tools
267267

source/docs/pyqgis_developer_cookbook/communicating.rst

+24-8
Original file line numberDiff line numberDiff line change
@@ -140,17 +140,25 @@ it accepts widgets. Here is an example that you can try in the console.
140140
iface.messageBar().clearWidgets()
141141
142142
Also, you can use the built-in status bar to report progress, as in the next
143-
example
143+
example:
144144

145145
.. code-block:: python
146146
147-
count = layer.featureCount()
148-
for i, feature in enumerate(features):
149-
#do something time-consuming here
150-
...
151-
percent = i / float(count) * 100
152-
iface.mainWindow().statusBar().showMessage("Processed {} %".format(int(percent)))
153-
iface.mainWindow().statusBar().clearMessage()
147+
vlayer = QgsProject.instance().mapLayersByName("countries")[0]
148+
149+
count = vlayer.featureCount()
150+
features = vlayer.getFeatures()
151+
152+
for i, feature in enumerate(features):
153+
# do something time-consuming here
154+
print('') # printing should give enough time to present the progress
155+
156+
percent = i / float(count) * 100
157+
# iface.mainWindow().statusBar().showMessage("Processed {} %".format(int(percent)))
158+
iface.statusBarIface().showMessage("Processed {} %".format(int(percent)))
159+
160+
iface.statusBarIface().clearMessage()
161+
154162
155163
Logging
156164
=======
@@ -173,11 +181,19 @@ save about the execution of your code.
173181
cases you should always use thread safe classes (:class:`QgsLogger <qgis.core.QgsLogger>`
174182
or :class:`QgsMessageLog <qgis.core.QgsMessageLog>`) instead.
175183

184+
176185
.. note::
177186

178187
You can see the output of the :class:`QgsMessageLog <qgis.core.QgsMessageLog>`
179188
in the :ref:`log_message_panel`
180189

190+
.. note::
191+
192+
* :class:`QgsLogger <qgis.core.QgsLogger>` is for messages for debugging /
193+
developers (i.e. you suspect they are triggered by some broken code)
194+
* :class:`QgsMessageLog <qgis.core.QgsMessageLog>` is for messages to
195+
investigate issues by sysadmins (e.g. to help a sysadmin to fix configurations)
196+
181197

182198
.. Substitutions definitions - AVOID EDITING PAST THIS LINE
183199
This will be automatically updated by the find_set_subst.py script.

source/docs/pyqgis_developer_cookbook/composer.rst

+30-23
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
.. only:: html
2-
3-
|updatedisclaimer|
4-
51
.. index:: Map rendering, Map printing
62

73
.. _layout:
@@ -10,7 +6,11 @@
106
Map Rendering and Printing
117
**************************
128

13-
.. warning:: |outofdate|
9+
The code snippets on this page needs the following imports:
10+
11+
.. code-block:: python
12+
13+
import os
1414
1515
.. contents::
1616
:local:
@@ -28,27 +28,31 @@ The rendering is done creating a :class:`QgsMapSettings <qgis.core.QgsMapSetting
2828
and then constructing a :class:`QgsMapRendererJob <qgis.core.QgsMapRendererJob>` with those options. The latter is then
2929
used to create the resulting image.
3030

31-
Here's an example
31+
Here's an example:
3232

3333
.. code-block:: python
3434
35-
layer=iface.activeLayer()
36-
options = QgsMapSettings()
37-
options.setLayers([layer])
38-
options.setBackgroundColor(QColor(255, 255, 255))
39-
options.setOutputSize(QSize(800, 600))
40-
options.setExtent(layer.extent())
35+
image_location = os.path.join(QgsProject.instance().homePath(), "render.png")
36+
37+
# e.g. vlayer = iface.activeLayer()
38+
vlayer = QgsProject.instance().mapLayersByName("countries")[0]
39+
options = QgsMapSettings()
40+
options.setLayers([vlayer])
41+
options.setBackgroundColor(QColor(255, 255, 255))
42+
options.setOutputSize(QSize(800, 600))
43+
options.setExtent(vlayer.extent())
4144
42-
render = QgsMapRendererParallelJob(options)
45+
render = QgsMapRendererParallelJob(options)
4346
44-
def finished():
45-
img = render.renderedImage()
46-
img.save("/Users/myuser/render.png","png")
47-
print("saved")
47+
def finished():
48+
img = render.renderedImage()
49+
# save the image; e.g. img.save("/Users/myuser/render.png","png")
50+
img.save(image_location, "png")
51+
print("saved")
4852
49-
render.finished.connect(finished)
53+
render.finished.connect(finished)
5054
51-
render.start()
55+
render.start()
5256
5357
5458
Rendering layers with different CRS
@@ -100,7 +104,7 @@ Here's a description of some of the main layout items that can be added to a lay
100104
.. code-block:: python
101105
102106
map = QgsLayoutItemMap(layout)
103-
layout.addItem(mapp)
107+
layout.addItem(map)
104108
105109
* label --- allows displaying labels. It is possible to modify its font, color,
106110
alignment and margin
@@ -170,7 +174,8 @@ A frame is drawn around each item by default. You can remove it as follows:
170174

171175
.. code-block:: python
172176
173-
composerLabel.setFrameEnabled(False)
177+
# for a composer label
178+
label.setFrameEnabled(False)
174179
175180
Besides creating the layout items by hand, QGIS has support for layout
176181
templates which are essentially compositions with all their items saved to a
@@ -188,8 +193,10 @@ To export a layout, the :class:`QgsLayoutExporter <qgis.core.QgsLayoutExporter>`
188193

189194
.. code-block:: python
190195
191-
exporter = QgsLayoutExporter(layout)
192-
exporter.exportToPdf("path/to/output/pdf", QgsLayoutExporter.PdfExportSettings())
196+
pdf_path = os.path.join(QgsProject.instance().homePath(), "output.pdf")
197+
198+
exporter = QgsLayoutExporter(layout)
199+
exporter.exportToPdf(pdf_path, QgsLayoutExporter.PdfExportSettings())
193200
194201
Use the :meth:`exportToImage() <qgis.core.QgsLayoutExporter.exportToImage>` in case you want to export to an image instead of a PDF file.
195202

0 commit comments

Comments
 (0)