Commit 93428a38 authored by Roelandt nicolas's avatar Roelandt nicolas
Browse files

Merge branch 'cours_pyqgis' into 'master'

Corrections typos

See merge request !9
parents 4230809b 74d812dc
Pipeline #388191 passed with stages
in 45 seconds
......@@ -346,7 +346,7 @@ Your QGIS plugin directory is located at:
<li>scripts : dossier contenant les scripts du plugin</li>
<li>test : tests unitaires</li>
</ul>
<p>Le fichier <code>resources.py</code> est créé par <code>pyrcc5</code> à partir des resources.
<p>Le fichier <code>resources.py</code> est créé par <code>pyrcc5</code> à partir des ressources.
<code>pyrcc5</code> est un outil en ligne de commande.</p>
<p>Sous <em>Windows</em>, <code>pyrcc5</code> est fourni avec le shell OSGeo4W.
Néanmoins le recours à un fichier <code>.bat</code> peut être utile pour charger
......@@ -408,7 +408,7 @@ Modifions l’interface pour préparer la suite.</p>
<div id="modification-de-linterface" class="section level3">
<h3><span class="header-section-number">3.2.2</span> Modification de l’interface</h3>
<p>Pour notre besoin (afficher des coordonnées), la fenêtre du plugin est trop grande.
de plus, il nous faut y ajouter des éléments en modifiant le fichier d’interface
De plus, il nous faut y ajouter des éléments en modifiant le fichier d’interface
(<em>.ui</em>) et le fichier d’implémentation (<em>ousuisje.py</em>).</p>
<p>Commençons par l’interface.
Nous allons utiliser pour cela l’outil <em>Qt Designer</em> qui est installé avec QGIS.</p>
......@@ -451,10 +451,7 @@ Relachez, la boite de dialogue de configuration des connexions doit apparaitre.<
<p>Dans le panneau gauche, cliquez sur <code>pressed()</code>.
Dans le panneau droit, cliquez sur <code>reject()</code>.
Cliquez sur <code>Ok</code> pour valider la connexion.</p>
<!-- TODO Apporter des informations sur pressed(), clicked(), etc...
Lien vers la page https://pythonpyqt.com/pyqt-bitton/
-->
<p>Côté code, un bouton suivant son type pourra avoir plusieurs attibuts (coché/non coché, accessible ou non, etc.), il transmet aussi un signal (pressé, relaché, cliqué) qui sera exploité par le code Python.</p>
<p>Côté code, un bouton suivant son type pourra avoir plusieurs attributs (coché/non coché, accessible ou non, etc.), il transmet aussi un signal (pressé, relaché, cliqué) qui sera exploité par le code Python.</p>
<p>Il faut que le signal défini dans l’interface et celui attendu dans le code Python coïncide.</p>
<p>Plus d’informations sur les boutons dans la <a href="https://pythonpyqt.com/pyqt-button/">documentation de PyQt</a>.</p>
<div class="figure">
......@@ -472,7 +469,7 @@ Commençons par celui-ci, ouvrez-le avec une éditeur de texte.</p>
<div id="ousuisje.py" class="section level4">
<h4><span class="header-section-number">3.2.3.1</span> ousuisje.py</h4>
<p>Jetons un oeil à ce fichier.</p>
<p>il importe un certain nombre de module et défini la classe <code>ousuisje</code> qui contient la méthode <code>__init__()</code>.</p>
<p>Il importe un certain nombre de module et défini la classe <code>ousuisje</code> qui contient la méthode <code>__init__()</code>.</p>
<div class="sourceCode" id="cb32"><pre class="sourceCode python"><code class="sourceCode python"><a class="sourceLine" id="cb32-1" data-line-number="1"><span class="im">from</span> qgis.PyQt.QtCore <span class="im">import</span> QSettings, QTranslator, QCoreApplication</a>
<a class="sourceLine" id="cb32-2" data-line-number="2"><span class="im">from</span> qgis.PyQt.QtGui <span class="im">import</span> QIcon</a>
<a class="sourceLine" id="cb32-3" data-line-number="3"><span class="im">from</span> qgis.PyQt.QtWidgets <span class="im">import</span> QAction</a>
......@@ -503,7 +500,7 @@ Commençons par celui-ci, ouvrez-le avec une éditeur de texte.</p>
<a class="sourceLine" id="cb32-28" data-line-number="28">[...]</a></code></pre></div>
<p>Nous devons ajouter les lignes de code définissant notre plugin comme un <em>map tool</em>.
Ainsi l’outil <em>Où suis-je ?</em>, quand cliqué, deviendra l’outil de carte actif et
manipulera les clicks sur la carte.
manipulera les clics sur la carte.
Il restera actif tant qu’un autre outil de carte (zoom, pan, etc) n’est pas sélectionné.</p>
<p>Ajouter l’import suivant: <code>from qgis.gui import QgsMapToolEmitPoint</code>
Cette classe implémente un outil de carte qui émet un point contenant des coordonnées.</p>
......@@ -589,7 +586,7 @@ Ajouter la méthode <em>display_point</em> à la fin de la classe.</p>
<a class="sourceLine" id="cb37-7" data-line-number="7"> </a>
<a class="sourceLine" id="cb37-8" data-line-number="8"> <span class="va">self</span>.dlg.show() <span class="co"># affiche de nouveau la boite de dialogue</span></a></code></pre></div>
<p>Vous remarquez qu’il est fait référence à <em>dlg</em>.
il s’agit de la boite de dialogue.
Il s’agit de la boite de dialogue.
Pour récupérer sa référence, ajouter cette ligne après les lignes de traduction.</p>
<div class="sourceCode" id="cb38"><pre class="sourceCode python"><code class="sourceCode python"><a class="sourceLine" id="cb38-1" data-line-number="1"> <span class="co"># Création de la boite de dialogue (après les traductions)</span></a>
<a class="sourceLine" id="cb38-2" data-line-number="2"> <span class="va">self</span>.dlg <span class="op">=</span> OuSuisJeDialog()</a></code></pre></div>
......@@ -615,15 +612,17 @@ Puis cliquez n’importe où sur la carte.</p>
</div>
<div id="plugin-proximité" class="section level3">
<h3><span class="header-section-number">3.3.2</span> Plugin <code>Proximité</code></h3>
<p>Transformer <code>proximite.py</code> en plugin, fonctionnalités attendues:
- icone personnalisée
- charger une couche de point d’intérêt
- charger une couche de superposition
- saisir une distance <code>X</code>
- trouver les éléments de la couche de superposition à distance <code>X</code> des points d’intérêts de l’autre couche
- la couche de résultat doit être chargée dans le projet à l’issue du calcul
- sélectionner un chemin vers un fichier de sauvegarde (si vide, la couche sera conservée en mémoire)
- gérer les erreurs de saisie de la distance (conversion <code>,</code> -&gt; ‘.’, génération d’un message si caractère non valide)</p>
<p>Transformer <code>proximite.py</code> en plugin, fonctionnalités attendues:</p>
<ul>
<li>icone personnalisée</li>
<li>charger une couche de point d’intérêt</li>
<li>charger une couche de superposition</li>
<li>saisir une distance <code>X</code></li>
<li>trouver les éléments de la couche de superposition à distance <code>X</code> des points d’intérêts de l’autre couche</li>
<li>la couche de résultat doit être chargée dans le projet à l’issue du calcul</li>
<li>sélectionner un chemin vers un fichier de sauvegarde (si vide, la couche sera conservée en mémoire)</li>
<li>gérer les erreurs de saisie de la distance (conversion <code>,</code> -&gt; ‘.’, génération d’un message si caractère non valide)</li>
</ul>
<div class="figure">
<img src="images/42_proximite_interface.png" alt="Exemple d’interface pour le plugin Proximité" />
<p class="caption">Exemple d’interface pour le plugin <code>Proximité</code></p>
......
......@@ -261,15 +261,17 @@ accessible depuis la console python:</p>
<p>Créeons un script simple qui va trouver les stations de métro à moins de 1000 mètres de la gare de Lyon Part-Dieu.</p>
<div id="importation-des-bibliothèques" class="section level3">
<h3><span class="header-section-number">2.2.1</span> Importation des bibliothèques</h3>
<p>Pour réaliser notre tache, nous allons avoir besoin d’accèder aux algorithmes de
géotraitements et de certaines méthodes du projet QGIS.</p>
<p>Pour réaliser notre tâche, nous allons avoir besoin d’accèder aux
algorithmes de géotraitements et de certaines méthodes du projet QGIS.</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode python"><code class="sourceCode python"><a class="sourceLine" id="cb11-1" data-line-number="1"><span class="im">import</span> processing</a>
<a class="sourceLine" id="cb11-2" data-line-number="2"><span class="im">from</span> qgis.core <span class="im">import</span> QgsProject</a></code></pre></div>
</div>
<div id="chargement-des-données" class="section level3">
<h3><span class="header-section-number">2.2.2</span> Chargement des données</h3>
<p>Nous allons avoir besoin des couches des gares SNCF et des stations de métro TCL.
Chargeons aussi les arrondissments de la ville de Lyon pour avoir un peu de contexte.</p>
<p>Nous allons avoir besoin des couches des gares SNCF et des
stations de métro TCL.
Chargeons aussi les arrondissements de la ville de Lyon pour avoir
un peu de contexte.</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode python"><code class="sourceCode python"><a class="sourceLine" id="cb12-1" data-line-number="1"><span class="co">## arrondissements</span></a>
<a class="sourceLine" id="cb12-2" data-line-number="2">uri <span class="op">=</span> <span class="st">&quot;/home/niko/Téléchargements/lyon/arrondissements.shp&quot;</span></a>
<a class="sourceLine" id="cb12-3" data-line-number="3">arrondissements <span class="op">=</span> iface.addVectorLayer(uri,<span class="st">&quot;arrondissements&quot;</span>, <span class="st">&quot;ogr&quot;</span>)</a>
......@@ -310,8 +312,11 @@ par <code>EPSG:2154</code> ou <code>IGNF:LAMB93</code>.</p>
<h3><span class="header-section-number">2.2.4</span> Extraction de la gare de la Part-Dieu</h3>
<div class="sourceCode" id="cb16"><pre class="sourceCode python"><code class="sourceCode python"><a class="sourceLine" id="cb16-1" data-line-number="1"><span class="co"># Extraction de la gare de Part-Dieu</span></a>
<a class="sourceLine" id="cb16-2" data-line-number="2">expression <span class="op">=</span> <span class="st">&quot;nom = &#39;Gare de Lyon Part-Dieu&#39;&quot;</span></a>
<a class="sourceLine" id="cb16-3" data-line-number="3">partdieu <span class="op">=</span> processing.runAndLoadResults(<span class="st">&quot;native:extractbyexpression&quot;</span>,</a>
<a class="sourceLine" id="cb16-4" data-line-number="4">{<span class="st">&#39;INPUT&#39;</span>:gares_reproject, <span class="st">&#39;EXPRESSION&#39;</span>: expression,<span class="st">&#39;OUTPUT&#39;</span>:<span class="st">&#39;memory&#39;</span>})[<span class="st">&#39;OUTPUT&#39;</span>]</a></code></pre></div>
<a class="sourceLine" id="cb16-3" data-line-number="3">partdieu <span class="op">=</span> processing.runAndLoadResults(</a>
<a class="sourceLine" id="cb16-4" data-line-number="4"> <span class="st">&quot;native:extractbyexpression&quot;</span>,</a>
<a class="sourceLine" id="cb16-5" data-line-number="5"> {<span class="st">&#39;INPUT&#39;</span>:gares_reproject, </a>
<a class="sourceLine" id="cb16-6" data-line-number="6"> <span class="st">&#39;EXPRESSION&#39;</span>: expression,</a>
<a class="sourceLine" id="cb16-7" data-line-number="7"> <span class="st">&#39;OUTPUT&#39;</span>:<span class="st">&#39;memory&#39;</span>})[<span class="st">&#39;OUTPUT&#39;</span>]</a></code></pre></div>
<p>Une fois notre gare extraite, nous pouvons créer notre zone tampon de 1000 mètres.</p>
</div>
<div id="création-de-la-zone-tampon" class="section level3">
......@@ -319,13 +324,24 @@ par <code>EPSG:2154</code> ou <code>IGNF:LAMB93</code>.</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode python"><code class="sourceCode python"><a class="sourceLine" id="cb17-1" data-line-number="1"><span class="co"># Création d&#39;un tampon de 500m</span></a>
<a class="sourceLine" id="cb17-2" data-line-number="2">buffer_partdieu <span class="op">=</span> processing.runAndLoadResults(</a>
<a class="sourceLine" id="cb17-3" data-line-number="3"> <span class="st">&quot;native:buffer&quot;</span>, </a>
<a class="sourceLine" id="cb17-4" data-line-number="4"> {<span class="st">&#39;INPUT&#39;</span>:partdieu,<span class="st">&#39;DISTANCE&#39;</span>:<span class="dv">1000</span>,<span class="st">&#39;SEGMENTS&#39;</span>:<span class="dv">5</span>,<span class="st">&#39;END_CAP_STYLE&#39;</span>:<span class="dv">0</span>,<span class="st">&#39;JOIN_STYLE&#39;</span>:<span class="dv">0</span>,<span class="st">&#39;MITER_LIMIT&#39;</span>:<span class="dv">2</span>,<span class="st">&#39;DISSOLVE&#39;</span>:<span class="va">False</span>,<span class="st">&#39;OUTPUT&#39;</span>:<span class="st">&#39;memory:&#39;</span>})[<span class="st">&#39;OUTPUT&#39;</span>]</a></code></pre></div>
<a class="sourceLine" id="cb17-4" data-line-number="4"> {<span class="st">&#39;INPUT&#39;</span>:partdieu,</a>
<a class="sourceLine" id="cb17-5" data-line-number="5"> <span class="st">&#39;DISTANCE&#39;</span>:<span class="dv">1000</span>,</a>
<a class="sourceLine" id="cb17-6" data-line-number="6"> <span class="st">&#39;SEGMENTS&#39;</span>:<span class="dv">5</span>,</a>
<a class="sourceLine" id="cb17-7" data-line-number="7"> <span class="st">&#39;END_CAP_STYLE&#39;</span>:<span class="dv">0</span>,</a>
<a class="sourceLine" id="cb17-8" data-line-number="8"> <span class="st">&#39;JOIN_STYLE&#39;</span>:<span class="dv">0</span>,</a>
<a class="sourceLine" id="cb17-9" data-line-number="9"> <span class="st">&#39;MITER_LIMIT&#39;</span>:<span class="dv">2</span>,</a>
<a class="sourceLine" id="cb17-10" data-line-number="10"> <span class="st">&#39;DISSOLVE&#39;</span>:<span class="va">False</span>,</a>
<a class="sourceLine" id="cb17-11" data-line-number="11"> <span class="st">&#39;OUTPUT&#39;</span>:<span class="st">&#39;memory:&#39;</span>})[<span class="st">&#39;OUTPUT&#39;</span>]</a></code></pre></div>
<p>Comme cette couche produit de nouvelles données, il peut être intéressant de la visualiser.</p>
<p>Nous pouvons maintenant intersecter cette zone tampon avec la couche contenant les entrées et sorties de métro.</p>
<div class="sourceCode" id="cb18"><pre class="sourceCode python"><code class="sourceCode python"><a class="sourceLine" id="cb18-1" data-line-number="1"><span class="co"># Intersection des stations de métros</span></a>
<a class="sourceLine" id="cb18-2" data-line-number="2">metro_1000m <span class="op">=</span> processing.runAndLoadResults(</a>
<a class="sourceLine" id="cb18-3" data-line-number="3"> <span class="st">&quot;native:intersection&quot;</span>, </a>
<a class="sourceLine" id="cb18-4" data-line-number="4"> {<span class="st">&#39;INPUT&#39;</span>:metro,<span class="st">&#39;OVERLAY&#39;</span>:buffer_partdieu,<span class="st">&#39;INPUT_FIELDS&#39;</span>:[],<span class="st">&#39;OVERLAY_FIELDS&#39;</span>:[],<span class="st">&#39;OUTPUT&#39;</span>:<span class="st">&#39;memory:&#39;</span>})[<span class="st">&#39;OUTPUT&#39;</span>]</a></code></pre></div>
<a class="sourceLine" id="cb18-4" data-line-number="4"> {<span class="st">&#39;INPUT&#39;</span>:metro,</a>
<a class="sourceLine" id="cb18-5" data-line-number="5"> <span class="st">&#39;OVERLAY&#39;</span>:buffer_partdieu,</a>
<a class="sourceLine" id="cb18-6" data-line-number="6"> <span class="st">&#39;INPUT_FIELDS&#39;</span>:[],</a>
<a class="sourceLine" id="cb18-7" data-line-number="7"> <span class="st">&#39;OVERLAY_FIELDS&#39;</span>:[],</a>
<a class="sourceLine" id="cb18-8" data-line-number="8"> <span class="st">&#39;OUTPUT&#39;</span>:<span class="st">&#39;memory:&#39;</span>})[<span class="st">&#39;OUTPUT&#39;</span>]</a></code></pre></div>
</div>
<div id="renommer-la-couche-finale" class="section level3">
<h3><span class="header-section-number">2.2.6</span> Renommer la couche finale</h3>
......@@ -347,7 +363,7 @@ de la liste.</p>
<div id="sauvegarde-de-la-couche" class="section level3">
<h3><span class="header-section-number">2.2.7</span> Sauvegarde de la couche</h3>
<p>Pour sauvegarder la couche, nous allons utiliser la méthode <code>QgsVectorLayerExporter.exportLayer</code>.</p>
<p>Elle prend 4 arguments:</p>
<p>Cette méthode attend 4 arguments:</p>
<ul>
<li>la couche vectorielle</li>
<li>une chemin vers un fichier (appelé <em>uri</em>)</li>
......@@ -775,10 +791,10 @@ de la Part-Dieu et reprojection en 2154).</p>
</div>
<div id="ajout-du-script-dans-la-boite-à-outils" class="section level3">
<h3><span class="header-section-number">2.4.3</span> Ajout du script dans la boite à outils</h3>
<p>Maintenant que nous avons un script fonctionnel, nous pouvons l’ajouter à la boite
à outil pour le réutiliser quand nous en aurons besoin.</p>
<p>Pour cela, depuis la boite à outils, dépliez le menu déroulant situé sous l’icone
Python.
<p>Maintenant que nous avons un script fonctionnel, nous pouvons l’ajouter
à la boite à outil pour le réutiliser quand nous en aurons besoin.</p>
<p>Pour cela, depuis la boite à outils, dépliez le menu déroulant situé
sous l’icone Python.
Cliquez sur <code>Ajouter un script à la boite à outils</code></p>
<div class="figure">
<img src="images/19_ajout_script_toolbox.png" alt="Ajouter un script à la boite à outils" />
......@@ -815,6 +831,10 @@ n’a été réactivé qu’à partir de QGIS 3.6.</p>
<p class="caption"><a href="https://gis.stackexchange.com/questions/277878/exporting-processing-modeler-as-python-script-in-qgis-3/313547#313547">Source: Anita Graser</a></p>
</div>
<p>QGIS 3.4 étant encore très répandue, cette fonctionnalité ne sera pas abordée.</p>
<!--
TODO: Écrire de nouveaux algorithmes sous la forme de scripts Python
https://docs.qgis.org/3.16/fr/docs/user_manual/processing/scripts.html
-->
</div>
</div>
......
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment