Samodzielne aplikacje korzystające z QGIS i zmiennych środowiskowych

12

Próbowałem przejść przez IRC, aby zobaczyć, czy ludzie mogą mi w tym pomóc, ale medium wydaje się trochę niezdarne z powodu wyjaśniania jakichkolwiek odpowiedzi, więc spróbuję tego.

Chciałbym zaprogramować samodzielną aplikację za pomocą PyQGIS w sposób, w jaki mogę już programować samodzielne aplikacje za pomocą ArcPy.

Sam PyQGIS jest prosty. Nie miałem trudności z uruchomieniem skryptów Python w edytorze konsoli QGIS. Jednak aby użyć powiązań Python w samodzielnym skrypcie, radzę, że muszę zmienić ustawienia środowiska za pomocą skryptu wsadowego (używam Windows Vista w domu, więc mówimy o skryptach wsadowych dla systemu Windows). Spowodowało to bałagan po mojej stronie, ponieważ tak naprawdę nie rozumiem skryptów wsadowych i nie podoba mi się pomysł, że resetuję środowisko, które musi być pewnym sposobem dla innych aplikacji, które uruchamiam.

Mam trudności ze zrozumieniem, dlaczego instrukcje tworzenia tych ustawień są tak niepotrzebnie skomplikowane i dlaczego nie stanowią jednego wiersza kodu mówiącego: „przejdź do miejsca, w którym znajdują się powiązania, udostępnij biblioteki, których chcę, aby ten program mógł używać Z pewnością ArcPy nie wymaga od ludzi, aby bawili się ustawieniami środowiska komputera, więc mam trudności ze zrozumieniem, dlaczego PyQGIS to robi. Wydaje mi się, że ludzie po prostu się poddadzą niż nauczą się języka skryptowego Windows Batch.

Teraz zauważam, że kiedy uruchamiam skrypt w edytorze konsoli QGIS, działa. To prawda, że ​​sprawia, że ​​reszta QGIS nie nadaje się do użytku po uruchomieniu skryptu, więc muszę później ponownie uruchomić QGIS, ale skrypt działa dokładnie tak, jak go zaprogramowałem. Ale kiedy robię to poza aplikacją QGIS, nie robi tego. Problemem nie wydaje się być to, że nie udało mi się zaimportować niektórych pakietów Pythona automatycznie zaimportowanych przez aplikację QGIS (qgis.core i qgis.utils) - Mam te instrukcje importu w moim samodzielnym skrypcie wraz z wszystkimi innymi pakietami skrypt wymaga. To prowadzi mnie do przekonania, że ​​różnica polega na tym, że aplikacja QGIS poprawnie ustawia zewnętrzne zmienne środowiskowe, ale te zmienne nie są ustawione poprawnie, gdy uruchamiam je jako samodzielny skrypt.

Dodatkowo, kiedy uruchamiam skrypt jako samodzielny skrypt, przechodzi przez cały kod bez zgłaszania błędu; po prostu nie robi tego, co nakazuje kod. Kiedy uruchamiam skrypt w edytorze konsoli, robi to wszystko poprawnie. Kiedy uruchamiam go jako samodzielny, tworzy okno, a następnie natychmiast je niszczy, nie zgłaszając żadnych błędów. Tak więc interpreter rozumie wszystko, o co proszę skrypt - po prostu tego nie zrobi.

Oto skrypt:

from PyQt4 import *
from PyQt4 import *
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from qgis.gui import *
from qgis.utils import *
import Tkinter
from Tkinter import *
import sys
import os

qgishome = "c:/OSGeo4W/apps/qgis/"
app = QgsApplication([], True)
QgsApplication.setPrefixPath(qgishome, True)
QgsApplication.initQgis()

canvas = QgsMapCanvas()
canvas.setCanvasColor(Qt.yellow)
canvas.enableAntiAliasing(True)
canvas.show()

layer = QgsVectorLayer(r"c:/GIS Data/fed308/cpc.shp", "Ridings", "ogr")
reg = QgsMapLayerRegistry.instance()
reg.addMapLayer(layer)
canvas.setExtent(layer.extent())
canvas.setLayerSet([QgsMapCanvasLayer(layer)])
QgsApplication.exitQgis()

Proszę ... czy mogę w jakiś sposób uruchomić ten skrypt poza QGIS i sprawić, aby działał tak, jak działa w QGIS (najlepiej bez wyłączania rzeczy na samym końcu)?

QGIS to wspaniały program, a PyQGIS wydaje się tak intuicyjny jak ArcPy i byłby prawdziwą zaletą dla oprogramowania typu open source - ale jeśli ludzie będą musieli przejść przez wszystkie obręcze, przez które już przeszedłem i nadal nie mają samodzielnej aplikacji dostęp do bibliotek PyQGIS w taki sam sposób, w jaki mają dostęp do ArcPy, wydaje mi się, że PyQGIS nie przyda się ludziom. Mam nadzieję, że się mylę i jest to łatwiejsze niż dotychczas. Czy ktoś ma rozwiązanie?

Zak Klaas
źródło

Odpowiedzi:

6

Musisz uruchomić pętlę zdarzeń Qt, używając:

app.exec_()

Chciałbym usunąć QgsApplication.exitQgis (). Idealnie powinno być obsługiwane w gnieździe podłączonym do sygnału lastWindowClosed () aplikacji.

gsherman
źródło
Dobrze wiedzieć. Skieruję moją energię na czytanie na PyQt4, więc wiem więcej, co muszę zrobić, aby stworzyć GUI, których spróbuję w przyszłości. Jeśli G. Sherman ze sławy wtyczki Script Runner ... Zauważyłem, kiedy próbowałem uruchomić ten kod bez żadnych odniesień do QgsApplication, a przy pomocy nagłówka def run_script Script Runner potrzebuje, mój skrypt zrobił dokładnie to, co robił, gdy Próbowałem skryptu, jak pokazano powyżej, jako samodzielnego skryptu ... tworząc okno, a następnie natychmiast go zamykając. To po części dlatego założyłem, że nadal mam problemy ze zmiennymi środowiskowymi.
Zak Klaas
7

Po zapoznaniu się z dokumentacją PyQGis dowiesz się, że istnieją cztery główne sposoby wykorzystania interfejsu API PyQGis:

  1. za pomocą poleceń w konsoli Python
  2. za pomocą skryptów Python w przetwarzaniu lub za pomocą wtyczki ScritRunner Gary'ego Shermana
  3. poprzez opracowanie niestandardowych wtyczek do aplikacji QGis
  4. poza QGIS (w powłoce Pythona lub tworząc aplikacje z PyQt4, a nie z Tkinter (po co importować Tkinter dwa razy?)

i jesteś zainteresowany tym ostatnim punktem:

  • możesz używać PyQGIS jak każdego innego modułu Pythona. Ale Python nie wie, gdzie znaleźć PyQGIS. W tym celu musisz dodać folder PyQGIS do PYTHONPATH (w systemie Windows, zobacz Jak dodać do ścieżki python w Windows 7? ).

Z pewnością ArcPy nie wymaga od ludzi, aby bawili się ustawieniami środowiska komputera, więc mam trudności ze zrozumieniem, dlaczego PyQGIS

Ponieważ korzystasz z ArcGIS w wersji Pythona, w innych przypadkach to samo jest prawdą, spójrz na Arcpy poza arcmap lub Skonfiguruj PyScripter do użycia z QGIS (i nadal używaj Arcpy) w systemie Windows , na przykład.

Nie potrzebujesz tutaj PyQt4, Tkinter ani qgis.gui:

from qgis.core import *
QgsApplication.setPrefixPath("yourpath", True)
QgsApplication.initQgis()
# or your solution
# read a shapefile 
layer = QgsVectorLayer('your.shp', 'your', 'ogr')
layer.isValid()
True
# loop through layer 
for elem in layer.getFeatures():
    geom= elem.geometry()
    attr =elem.attributes()
    (processing)

 # interaction with other Python module: Shapely, for example
 from shapely.geometry import shape
 from json import loads
 for elem in layer.getFeatures():
       shapely_geometry = shape(loads(elem.geometry().exportToGeoJSON()))
  • możesz stworzyć aplikację. Potrzebujesz tutaj PyQt4 (a nie Tkinter) i qgis.gui.

Chciałbym zaprogramować samodzielną aplikację za pomocą PyQGIS w sposób, w jaki mogę już programować samodzielne aplikacje za pomocą ArcPy.

W tym celu musisz nauczyć się PyQt4, tak jak na przykład Tkinter (lub wxPython). To kolejny problem: rozwiązanie podane przez gsherman dotyczy problemu PyQt4, a nie PyQGIS (patrz na przykład samouczek PyQt4 )

gen
źródło
Dzięki. Nie słyszałem jeszcze, żeby ktoś opisywał PyQt4 jako coś, co stanowiło swoistą wyłączną alternatywę dla Tkintera, którą znam całkiem dobrze (nie jestem pewien, dlaczego zadeklarowałem to dwukrotnie w powyższym kodzie ... to był tylko błąd). Twój link do samouczka PyQt4 wydaje się być bardzo pomocny. Po dzisiejszych eksperymentach zdecydowałem się rozwiązać problem za pomocą edytora konsoli i zminimalizować okno skryptu GUI QGIS, więc okno mojego skryptu wydaje się być samodzielne, z QGIS działającym w tle - więc chyba jest to numer 1 na liście 4 możliwości.
Zak Klaas