Taken voor QGIS uitvoeren en in schema zetten

U kunt veel van de taken in QGIS automatiseren met behulp van Python scripten (PyQGIS) en het framework Processing. Meestentijds zult u deze scripts handmatig uitvoeren terwijl QGIS is geopend. Hoewel dat nuttig is, heeft u ook vaak een manier nodig om deze taken via de opdrachtregel uit te kunnen voeren en zonder QGIS te moeten openen. Gelukkig kunt u zelfstandige scripts voor Python schrijven die bibliotheken van QGIS gebruiken en via de opdrachtregel kunnen worden uitgevoerd. In deze handleiding zullen we leren hoe een taak te schrijven en in en schema te zetten en die het framework van QGIS Processing gebruikt.

Overzicht van de taak

Laten we zeggen dat we werken aan enkele analyses met behulp van shapefiles van een regio. De shapefiles worden bijgewerkt op dagelijkse basis en we hebben altijd het laatste bestand nodig. Maar voordat we deze bestanden kunnen gebruiken, moeten we de gegevens opschonen. We kunnen een taak voor QGIS instellen die dit proces automatiseert en dagelijks wordt uitgevoerd zodat u de laatste opgeschoonde shapefiles voor uw werk heeft. We zullen een zelfstandig script voor Python schrijven dat een shapefile downloadt en topologische bewerkingen voor opschonen uitvoert op een dagelijkse basis.

Andere vaardigheden die u zult leren

  • Bestanden downloaden en unzippen met behulp van Python.

  • Een algoritme van Processing uitvoeren via PyQGIS.

  • Topologische fouten in een vectorlaag repareren.

De gegevens ophalen

Geofabrik verschaft dagelijks bijgewerkte shapefiles van gegevenssets van OpenStreetMap .

We zulleen de shapefiles voor Fiji gebruiken voor deze oefening. Download de fiji-latest.shp.zip en pak dat uit in een map op uw schijf.

Gegevensbron [GEOFABRIK]

Procedure

  1. We zullen eerst door het proces van het handmatig opschonen gaan om de opdrachten te noteren die we zullen gebruiken in het script voor Python. Start QGIS en ga naar Kaartlagen ‣ Laag toevoegen ‣ Vector laag toevoegen.

../_images/1207.png
  1. Blader naar de map die de uitgepakte shapefiles bevat en selecteer het bestand roads.shp en klik op Open.

../_images/2174.png
  1. Eerst moeten we de laag roads opnieuw projecteren naar een Geprojecteerd CRS. Dat stelt ons in staat om meters als eenheden te gebruiken bij het uitvoeren van anlyses, in plaats van graden. Open Processing ‣ Toolbox.

../_images/3121.png
  1. Zoek naar het gereedschap Reproject layer. Dubbelklik er op om het dialoogvenster te starten.

../_images/473.png
  1. Selecteer, in het dialoogvenster Reproject layer, de laag roads als Input layer. We zullen CRS EPSG:3460 Fiji 1986 / Fiji Map Grid gebruiken als het Target CRS. Klik op Run.

../_images/567.png
  1. Als het proces eenmaal is voltooid, zult u de opnieuw geprojecteerde laag zien geladen in QGIS. Ga naar Processing ‣ Historie...

../_images/664.png
  1. Vergroot, in het dialoogvenster Historie, de map ALGORITHM en selecteer het laatste item. U zult de volledige opdracht voor Processing in het onderste paneel zien staan. Noteer deze opdracht om in ons script te gebruiken.

../_images/763.png
  1. Klik, terug in het hoofdvenster van QGIS, op de knop CRS in de rechter benedenhoek.

../_images/861.png
  1. In het dialoogvenster Projecteigenschappen | CRS, selecteer Gelijjktijdige CRS-transformatie gebruiken en selecteer EPSG:3460 Fiji 1986 / Fiji Map Grid als het CRS. Dit zal er voor zorgen dat onze originele en opnieuw geprojecteerde lagen juist uit zullen lijn.

../_images/960.png
  1. Nu zullen we de bewerking voor het opschonen uitvoeren. GRASS heeft een zeer krachtige verzameling topologische gereedschappen voor opschonen. Deze zijn in QGIS beschikbaar via het algoritme v.clean. Zoek naar dit algoritme in de Processing Toolbox en dubbelklik er op om het dialoogvenster te starten.

../_images/1068.png
  1. U kunt meer te weten komen over de verschillende gereedschappen en opties op de tab Help. Voor deze handleiding zullen we het gereedschap snap gebruiken om duplicaat-punten te verwijderen die binnen 1 meter van elkaar liggen. Selecteer de`` laag Opnieuw geprojecteerd`` als de Layer to clean. Kies snap als de Cleaning tool. Voer 1.00 als de Threshold. Laat de andere velden leeg en klik op Run.

../_images/11107.png
  1. Als de verwerking eenmaal is voltooid zult u 2 nieuwe lagen zien toegevoegd aan QGIS. De laag Cleaned vector is de laag met gecorrigeerde topologische fouten. U zult ook een laag Errors hebben waarin de objecten zijn geaccentueerd die zijn gerepareerd. U kunt de laag met fouten als richtlijn nemen en inzoomen op de punten die werden verwijderd.

../_images/1269.png
  1. Ga naar het dialoogvenster Processing ‣ Geschiedenis en noteeer de volledige opdracht voor Processing voor later gebruik.

../_images/1366.png
  1. We zijn nu klaar om te beginnen met coderen. Bekijk het gedeelte Een tekstbewerker of een Python IDE in de handleiding Een plug-in in Python bouwen voor instructies om uw tekstbewerker of IDE in te stellen. Voor het uitvoeren van zelfstandige scripts in Python die QGIS gebruiken, moeten we verschillende opties voor configuratie instellen. Een goede manier om zelfstandige scripts uit te voeren is om ze te starten via een .bat-bestand. Dat bestand zal eerst de juiste opties voor configuratie instellen en dan het script van Python aanroepen. Maak een nieuw bestand genaamd launch.bat en voer de volgende tekst in. Wijzig de waarden overeenkomstig uw configuratie voor QGIS. Vergeet niet de gebruikersnaam te vervangen door uw eigen gebruikersnaam in het pad naar het script van Python. De paden in dit bestand zullen hetzelfde zijn op uw systeem indien u QGIS installeerde via de OSGeo4W Installer. Sla het bestand op op uw bureaublad.

Notitie

Linux- en Mac-gebruikers dienen een shell-script te maken om de variabelen voor paden en omgeving in te stellen.

REM Change OSGEO4W_ROOT to point to the base install folder
SET OSGEO4W_ROOT=C:\OSGeo4W64
SET QGISNAME=qgis
SET QGIS=%OSGEO4W_ROOT%\apps\%QGISNAME%
set QGIS_PREFIX_PATH=%QGIS%
REM Gdal Setup
set GDAL_DATA=%OSGEO4W_ROOT%\share\gdal\
REM Python Setup
set PATH=%OSGEO4W_ROOT%\bin;%QGIS%\bin;%PATH%
SET PYTHONHOME=%OSGEO4W_ROOT%\apps\Python27
set PYTHONPATH=%QGIS%\python;%PYTHONPATH%

REM Launch python job
python c:\Users\Ujaval\Desktop\download_and_clean.py
pause
../_images/1463.png
  1. maak een nieuw Python-bestand en voer de volgende code in. Noem het bestand download_and_clean.py en sla het op op uw bureaublad.

from qgis.core import *
print 'Hello QGIS!'
../_images/1558.png
  1. Schakel over naar uw bureaublad en zoek naar het pictogram van het bestand launch.bat. Dubbelklik er op om een nieuw scherm voor de opdrachtregel te starten en voer het script uit. Als u in het scherm van de opdrachtregel ziet afgedrukt Hello QGIS!, zijn uw configuratie en instellingen juist ingesteld. Als u fouten ziet of de tekst niet ziet, controleer dan uw bestand launch.bat en zorg er voor dat alle paden overeenkomen met de locaties op uw systeem.

../_images/1655.png
  1. Terug in uw tekstbewerker, pas het script download_and_clean.py aan door de volgende code toe te voegen. Dit is de bootstrap-code om QGIS te initialiseren. Deze zijn overbodig als u het script binnen QGIS uitvoert. Maar omdat we het buiten QGIS uitvoeren, moeten we deze aan het begin toevoegen. Zorg er voor dat u de gebruikersnaam vervangt door uw eigen gebruikersnaam. Sla, na het maken van deze wijzigingen, het ebstand op en voer launch.bat opnieuw uit. Als u Hello QGIS! ziet afgedrukt, is alles ingesteld om de logica voor Processing toe te voegen aan het script.

import sys
from qgis.core import *

# Initialize QGIS Application
QgsApplication.setPrefixPath("C:\\OSGeo4W64\\apps\\qgis", True)
app = QgsApplication([], True)
QgsApplication.initQgis()

# Add the path to Processing framework
sys.path.append('c:\\Users\\Ujaval\\.qgis2\\python\\plugins')

# Import and initialize Processing framework
from processing.core.Processing import Processing
Processing.initialize()
import processing

print 'Hello QGIS!'
../_images/1752.png
  1. herinnert u zich nog de eerste opdracht voor Processing die we hebben opgeslagen vanuit het log? Dat was de opdracht om de laag opnieuw te projecteren. Plak de opdracht in uw script en voeg de omringende code als volgt toe. Onthoud dat de opdrachten voor Processing het pad naar de uitvoerlaag teruggeven als een woordenboek. We zullen dat opslaan als de waarde ret en het pad naar de opnieuw geprojecteerde laag afdrukken.

roads_shp_path = "C:\\Users\\Ujaval\\Downloads\\fiji-latest.shp\\roads.shp"
ret = processing.runalg('qgis:reprojectlayer', roads_shp_path, 'EPSG:3460',
None)
output = ret['OUTPUT']
print output
../_images/1849.png
  1. Voer het script uit via launch.bat en u zult het pad zien naar de nieuw gemaakte laag Opnieuw geprojecteerd.

../_images/1940.png
  1. Voeg nu de code toe voor het opschonen van de topologie. Omdat dit onze uiteindelijke uitvoer is, zullen we de paden voor de uitvoerbestanden als de laatste 2 argumenten vermelden voor het algoritme grass.v.clean. Als u deze leeg laat zal de uitvoer worden gemaakt in een tijdelijke map.

processing.runalg("grass:v.clean",
                  output,
                  1,
                  1,
                  None,
                  -1,
                  0.0001,
                  'C:\\Users\\Ujaval\\Desktop\\clean.shp',
                  'C:\Users\\Ujaval\\Desktop\\errors.shp')
../_images/2035.png
  1. Voer het script uit en u zult 2 nieuwe shapefiles zien gemaakt op uw Bureaublad. Dit voltooid het gedeelte ven Processing van het script. Laten we de code toevoegen voor het downloaden van de gegevens van de originele website en die automatisch laten unzippen. We zullen ook het pad naar het uitgepakte bestand opslaan als een variabele die we later kunnen doorgeven aan het algoritme van Processing. We zullen enkele aanvullende modules moeten importeren om dit te kunnen doen. (Bekijk het einde van de handleiding voor het volledige script met alle wijzigingen)

import os
import urllib
import zipfile
import tempfile

temp_dir = tempfile.mkdtemp()
download_url = 'http://download.geofabrik.de/australia-oceania/fiji-latest.shp.zip'
print 'Downloading file'
zip, headers = urllib.urlretrieve(download_url)
with zipfile.ZipFile(zip) as zf:
    files = zf.namelist()
    for filename in files:
        if 'roads' in filename:
            file_path = os.path.join(temp_dir, filename)
            f = open(file_path, 'wb')
            f.write(zf.read(filename))
            f.close()
            if filename == 'roads.shp':
                roads_shp_path = file_path
../_images/2175.png
  1. Voer het complete script uit. Elke keer als u het script uitvoert wordt een verse kopie van de gegevens gedownload en verwerkt.

../_images/2234.png
  1. We kunnen de Taakplanner in Windows gebruiken om het uitvoeren van dit script op een dagelijkse basis te automatiseren. Start de Taakplanner en klik op Basistaak maken.

Notitie

Linux- en Mac-gebruikers kunnen cron jobs gebruiken om taken te plannen.

../_images/2331.png
  1. Noem de taak Dagelijkse download en opschonen en klik op Volgende.

../_images/2430.png
  1. Selecteer Dagelijks als de Taaktrigger en klik op Volgende

../_images/2527.png
  1. Selecteer een tijdstip naar keuze en klik op Volgende.

../_images/2625.png
  1. Kies Een programma starten als de Actie en klik op Volgende.

../_images/2724.png
  1. Klik op Bladeren en zoek naar het script launch.bat. Klik op Volgende.

../_images/2823.png
  1. Klik op Voltooien in het laatste scherm om de taak te plannen. Nu zal het script automatisch starten op de gespecificeerde tijd om u elke dag een verse kopie van opgeschoonde gegevens te geven.

../_images/2920.png

Hieronder staat het volledige script download_and_clean.py ter verwijzing.

import sys
from qgis.core import *

import os
import urllib
import zipfile
import tempfile

# Initialize QGIS Application
QgsApplication.setPrefixPath("C:\\OSGeo4W64\\apps\\qgis", True)
app = QgsApplication([], True)
QgsApplication.initQgis()

# Add the path to Processing framework  
sys.path.append('c:\\Users\\Ujaval\\.qgis2\\python\\plugins')

# Import and initialize Processing framework
from processing.core.Processing import Processing
Processing.initialize()
import processing

# Download and unzip the latest shapefile
temp_dir = tempfile.mkdtemp()
download_url = 'http://download.geofabrik.de/australia-oceania/fiji-latest.shp.zip'
print 'Downloading file'
zip, headers = urllib.urlretrieve(download_url)
with zipfile.ZipFile(zip) as zf:
    files = zf.namelist()
    for filename in files:
        if 'roads' in filename:
            file_path = os.path.join(temp_dir, filename)
            f = open(file_path, 'wb')
            f.write(zf.read(filename))
            f.close()
            if filename == 'roads.shp':
                roads_shp_path = file_path

print 'Downloaded file to %s' % roads_shp_path

# Reproject the Roads layer
print 'Reprojecting the roads layer'

ret = processing.runalg('qgis:reprojectlayer', roads_shp_path, 'EPSG:3460', None)
output = ret['OUTPUT']

# Clean the Roads layer
print 'Cleaning the roads layer'

processing.runalg("grass:v.clean",
                  output,
                  1,
                  1,
                  None,
                  -1,
                  0.0001,
                  'C:\\Users\\Ujaval\\Desktop\\clean.shp',
                  'C:\Users\\Ujaval\\Desktop\\errors.shp')
print 'Success'

If you want to give feedback or share your experience with this tutorial, please comment below. (requires GitHub account)