Suite

Comment charger le QGIS openlayers_plugin dans un script python autonome (pas la console python intégrée à QGIS)


si j'essaie de charger le plug-in openlayers dans une application autonome, il échoue toujours avec False, bien que les chemins soient définis et que le plug-in soit disponible.

(testé sur Ubuntu 14.04, QGIS 2.4, python-2.7)

#!/usr/bin/python # -*- codage : utf-8 -*- import sys, os import qgis import qgis.gui, qgis.utils from qgis.core import * from PyQt4 import QtGui # open an app app = QtGui.QApplication(sys.argv) # fournir le chemin d'accès à l'endroit où votre qgis est installé QgsApplication.setPrefixPath(u'/usr', True) # charger les fournisseurs QgsApplication.initQgis() # configurer les plugins qgis.utils.plugin_paths =  [ '/usr/share/qgis/python/plugins', os.path.expanduser('~/.qgis2/python/plugins'),] qgis.utils.updateAvailablePlugins() print qgis.utils.available_plugins print "… charge : ", qgis.utils.loadPlugin(u'openlayers_plugin') print "… start:", qgis.utils.startPlugin(u'openlayers_plugin') print "active:
",qgis.utils.active_plugins canvas = qgis.gui. QgsMapCanvas() canvas.show()

Quel est le problème ici ? post Comment récupérer les couches openlayers de pyqgis? fait référence à la console python intégrée, où le plugin était magiquement disponible auparavant.

Merci!


Ce n'est jamais, enfin peut-être avec quelques hacks, qui va bien fonctionner. Les plugins utilisent normalement leQgisInterfaceobjet qui donne accès à l'interface et aux méthodes de QGIS. Vous n'avez pas cet objet dans votre script autonome. La plupart des plugins, sinon tous, ne sont pas conçus pour s'exécuter en dehors de QGIS comme celui-ci.


Étant très passionné par le paradigme TDD, j'ai passé du temps à mettre en place une interface factice (basée sur des fragments de code que j'ai trouvés sur Internet) qui permet d'appeler QGIS et QGIS-plugins autonomes.

L'interface que j'ai créée se présente comme suit et je l'ai utilisée pour tous mes tests unitaires depuis :

# coding=utf-8 """Implémentation du plugin QGIS… remarque : : ce programme est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier selon les termes de la licence publique générale GNU telle que publiée par la Free Software Foundation ; l'une ou l'autre version 2 de la Licence, ou (à votre choix) toute version ultérieure… note :: La base de ce code source a été copiée à partir de l'application 'postgis viewer' avec les auteurs originaux : Copyright (c) 2010 par Ivan Mincik, [email protected] gista.sk Copyright (c) 2011 German Carrillo, [email protected] Copyright (c) 2014 Tim Sutton, [email protected] """ de qgis._core import QgsVectorLayer de PyQt4.QtCore import QObject, pyqtSlot, pyqtSignal, QCoreApplication , QSize de PyQt4.QtGui import QWidget de qgis.core import QgsMapLayerRegistry, QgsApplication, QgsVectorLayer de qgis.gui import QgsMapCanvasLayer, QgsMapCanvas import logging import sys de mole import config LOGGER = logging.get_Logger () :QGIS "" Configure une pseudo-application QGIS w qui permet d'appeler des méthodes comme si vous les appeliez depuis la console QGIS. :return qgis_app: Pseudo QGIS-instance :rtype: QgsApplication :return canvas: Le canevas de la carte :rtype: QgsMapCanvas :return iface: Une interface factice, donnant accès aux appels de méthode nécessaires :rtype: QgisInterface """ gui_flag = True # All le test exécutera qgis en mode gui qgis_app = QgsApplication(sys.argv, gui_flag) prefix_path = config.qgis_prefix_path() qgis_app.setPrefixPath(prefix_path, True) qgis_app.initQgis() QCoreApplication.setOrganizationName('QGIS') QCore'Application.setApplicationName QGIS2') # parent = QWidget() # canvas = QgsMapCanvas(parent) # canvas.resize(QSize(400, 400)) canvas = MyMapCanvas() iface = QgisInterface(canvas) return qgis_app, canvas, iface #noinspection PyMethodMayBeStatic,PyPep8Naming class QgisInterface(QObject): """Classe pour exposer les objets et fonctions QGIS aux plugins. Cette classe est là pour nous permettre d'exécuter des tests unitaires uniquement, donc la plupart des méthodes sont simplement des stubs. """ currentLayerChanged = pyqtSignal(QgsMapCanvasLayer) def __init__(self, canvas): """Constructor :param canvas: """ QObject.__init__(self) self.canvas = canvas self.legend_interface = MyLegendInterface() self.active_layer = Aucun # Configurer des slots afin que nous puissions imiter le comportement de QGIS lorsque des couches # sont ajoutées. LOGGER.debug('Initialisation du canevas… ') # noinspection PyArgumentList QgsMapLayerRegistry.instance().layersAdded.connect(self.addLayer) # noinspection PyArgumentList QgsMapLayerRegistry .instance().layerWasAdded.connect(self.addLayer) # noinspection PyArgumentList QgsMapLayerRegistry.instance().removeAll.connect(self.removeAllLayers) # Pour le module de traitement self.destCrs = None @pyqtSlot('QgsMapLayer') def addLayer(self , layer): """ Gérez un calque ajouté au registre afin qu'il apparaisse dans le canevas. :param couche: liste liste des couches de carte qui ont été ajoutées… note : l'API QgsInterface n'inclut pas cette méthode, elle est ajoutée ici en tant qu'aide pour faciliter les tests… note : la méthode addLayer a été dépréciée dans QGIS 1.8, vous ne devriez donc pas avoir beaucoup besoin de cette méthode. """ # définit le calque récemment ajouté comme actif # LOGGER.debug('Layer Count Before : %s' % len(self.canvas.layers())) current_layers = self.canvas.layers() final_layers = [] + current_layers final_layers.append(QgsMapCanvasLayer(layer)) self.canvas.setLayerSet(final_layers) self.active_layer = layer @pyqtSlot() def removeAllLayers(self): """Supprimer les calques du canevas avant qu'ils ne soient supprimés.""" self .canvas.setLayerSet([]) def newProject(self): """Créer un nouveau projet.""" # noinspection PyArgumentList QgsMapLayerRegistry.instance().removeAllMapLayers() def legendInterface(self): """Obtenir la légende." "" return self.legend_interface def activeLayer(self): """Obtenir le pointeur vers le calque actif (calque sélectionné dans la légende).""" return self.active_layer def setActiveLayer(self, layer): """Définir le donné couche comme active. :param layer : couche qui doit être activée :type layer : QgsMapLayer """ self.active_layer = couche classe actionAddFeature(object): def __init__(self): passe def trigger(self): passe la classe actionZoomToLayer(object): def __init__(self): pass def trigger(self): pass # ---------------- L'API Mock pour QgsInterface suit --------------- ---- def zoomFull(self): """Zoomer sur toute l'étendue de la carte.""" pass def zoomToPrevious(self): """Zoomer sur l'étendue de la vue précédente.""" pass def zoomToNext(self): " ""Zoomer sur l'étendue de la vue suivante.""" pass def zoomToActiveLayer(self): """Zoomer sur l'étendue de la couche active.""" pass def addVectorLayer(self, path, base_name, provider_key): """Ajouter un vecteur couche. :param path : chemin vers le calque. :type path: str :param base_name : nom de base du calque. :type base_name: str :param provider_key: Clé du fournisseur, par ex. 'ogr' :type provider_key: str """ pass def addRasterLayer(self, path, base_name): """Ajoute une couche raster à partir d'un nom de fichier de couche raster :param path: Chemin vers la couche. :type path: str :param base_name : nom de base du calque. :type base_name: str """ pass def addToolBarIcon(self, action): """Ajoute une icône à la barre d'outils des plugins. :param action : Action à ajouter à la barre d'outils. :type action: QAction """ pass def removeToolBarIcon(self, action): """Supprime une action (icône) de la barre d'outils du plugin. :param action : Action à ajouter à la barre d'outils. :type action: QAction """ pass def addToolBar(self, name): """Ajouter une barre d'outils avec le nom spécifié. :param name : Nom de la barre d'outils. :type name: str """ pass def mapCanvas(self): """Renvoyer un pointeur vers le canevas de la carte.""" return self.canvas def mainWindow(self): """Renvoyer un pointeur vers la fenêtre principale. Dans le cas de QGIS, il renvoie une instance de QgisApp. """ pass def addDockWidget(self, area, dock_widget): """Ajoute un widget dock à la fenêtre principale. :param area: Où dans l'interface utilisateur le dock doit être placé. :type area: :param dock_widget : Un widget dock à ajouter à l'interface utilisateur. :type dock_widget: QDockWidget """ pass class MyLegendInterface(object): def __init__(self): self.layer_visibility = {} def setLayerVisible(self, layer, yes_no): self.layer_visibility[layer.name()] = yes_no def isLayerVisible(self, layer): try: return self.layer_visibility[layer.name()] sauf KeyError: print('Layer {} n'a pas encore été défini (in)visible.'.format(layer.name())) return False class MyMapCanvas(object): def __init__(self): self.layer_set = [] def layer(self): return self.layer_set def layer(self, index): layer = self.layer_set[index].layer() return layer def setLayerSet(self, layer_set): self.layer_set = layer_set def layerCount(self): return len(self.layer_set)

Si vous souhaitez tester/utiliser QGIS plus l'interaction avec un plugin installé maintenant, procédez comme suit (dans votre configuration unittest, par exemple) :

qgis_app, canvas, iface = set_up_interface() plugin_name = 'openlayers_plugin' utils.plugin_paths = [os.path.expanduser('~/.qgis2/python/plugins')] utils.updateAvailablePlugins() utils.loadPlugin(plugin_name) utils. iface = self.iface utils.startPlugin(plugin_name)

Pour d'autres exemples d'utilisation et des exemples concrets sur les applications QGIS de test unitaire, vous pouvez consulter notre page github (https://github.com/UdK-VPT/Open_eQuarter/tree/master/mole). Le dossier essais contient tous les tests unitaires (qui testent principalement les modules dans le package qgisinteraction, qui contient un module, qui interagit avec le plugin point_sampling_tool).


Voir la vidéo: 02. Python in QGIS3. Read, Add, Delete, Update Features. Vector Layer (Octobre 2021).