-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #60 from GispoCoding/add_GE01
Add GE01 (QGIS-lisäosien kehitys)
- Loading branch information
Showing
44 changed files
with
6,257 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
# Harjoitus 1: Python-konsoli | ||
|
||
**Harjoituksen sisältö:** QGISin Python-konsoli ja skriptieditori. | ||
|
||
**Harjoituksen tavoite:** Tutustua Python-komentojen ajamiseen konsolissa ja | ||
skriptien ajamiseen skriptieditorissa. | ||
|
||
::: note-box | ||
Seuraavissa harjoituksissa oletetaan, että tunnet Python-kielen perusteet. | ||
Tarvittaessa voit kerrata Pythonia [täällä](00_harjoitus_0.html). | ||
::: | ||
|
||
Yksinkertaisin tapa käyttää Python-rajapintaa QGISissä on Python-konsolin kautta. | ||
Konsolin avulla voidaan syöttää ja ajaa yksittäisiä komentoja tai pidempiä skriptejä. | ||
Windowsilla QGIS-asennukseen sisältyy erillinen Python-tulkki, jonka versio on 3.12. | ||
Lisäksi asennukseen sisältyy joitain Python-paketteja standardikirjaston lisäksi. | ||
Asennukseen kuuluu myös QGIS- ja gdal/ogr-kirjastot, jotka mahdollistavat eri | ||
komponenttien hyödyntämisen konsolissa ja lisäosissa. Näiden lisäksi asennukseen | ||
kuuluu myös PyQt-kirjasto, eli Qt-käyttöliittymäkirjaston Python-sidonta (binding), | ||
joka mahdollistaa graafisen käyttöliittymän luomisen lisäosille. | ||
|
||
::: hint-box | ||
Python toimii käyttöjärjestelmien välillä hieman eri tavalla. Windows- ja | ||
MacOS-käyttöjärjestelmissä QGIS-asennukseen kuuluu oma Python-tulkki, kun | ||
taas Linux-pohjaisilla käyttöjärjestelmillä QGIS käyttää järjestelmän Python-tulkkia. | ||
::: | ||
|
||
Python-konsoliin pääsee usealla tavalla (kts. alla oleva kuva): | ||
|
||
- Sen voi avata QGISin ylävalikosta Lisäosat > Python-konsoli (Plugins > Python Console), | ||
- Pikanäppäinyhdistelmällä Ctrl + Alt + P, | ||
- Klikkaamalla työkalupalkista Python-logon kohdalta | ||
|
||
![](img/harjoitus_1/image1.png) | ||
|
||
Tarkastellaan konsoli-ikkunan eri osia: vihreästä kolmiosta klikkaamalla komennot | ||
suoritetaan (enter-näppäin ajaa saman asian). Muista ikoneista: | ||
|
||
- ![](https://raw.githubusercontent.com/qgis/QGIS/master/images/themes/default/console/iconTabEditorConsole.svg) | ||
Avaa skriptieditorin. Editori helpottaa pidempien skriptien tekoa ja ajamista | ||
|
||
- ![](https://raw.githubusercontent.com/qgis/QGIS/master/images/themes/default/console/iconClearConsole.svg) | ||
Tyhjentää konsoli-ikkunan edellisistä komennoista | ||
|
||
- ![](https://raw.githubusercontent.com/qgis/QGIS/master/images/themes/default/console/iconHelpConsole.svg) | ||
Täältä löydät kätevästi linkit PyQGIs API -dokumentaatioon, PyQGIS Cookbookiin | ||
sekä konsolin ohjeisiin. | ||
|
||
Avaa konsolista skriptieditori ja tutki samoin sen ominaisuuksia. | ||
|
||
## Harjoitusten rakenne | ||
|
||
## Esimerkit | ||
|
||
Eri harjoitusosioissa on annettu esimerkkejä Python-koodista. Suosittelemme, | ||
että esimerkkejä läpikäydessä kopioit esimerkin QGIS-konsolin skriptieditorin | ||
puolelle ja ajat koodin. Esimerkkien yhteydessä voi myös muokata koodia | ||
kokeillakseen eri toimintoja ja lopputuloksia. Esimerkit on annettu | ||
koodilaatikossa, josta sen sisällön voi kopioida viemällä hiiren osoittimen | ||
laatikon päälle ja klikkaamalla laatikon oikeaan yläreunaan ilmestyvää | ||
painiketta. | ||
|
||
::: code-box | ||
```python | ||
# Esimerkkikoodia | ||
|
||
print("Run me as an example!") | ||
``` | ||
::: | ||
|
||
## Harjoitukset | ||
|
||
Suosittelemme, että työstät myös harjoitusten vastaukset skriptieditorissa. | ||
Harjoitusten yhteydessä on joskus annettu oikeaan suuntaan ohjaava vinkki, | ||
sekä aina malliratkaisu. Saat nämä näkyville painamalla **Näytä ratkaisu** ja | ||
**Näytä vinkki** -painikkeita. Suosittelemme kuitenkin, ettet katso malliratkaisua | ||
liian aikaisin vaan yrität ensin keksiä ratkaisun itse. | ||
Saman asian voi myös tehdä usealla tavalla, ja malliratkaisu on vain yksi | ||
tapa ratkaista ongelma! | ||
|
||
## Harjoitus 1.1 | ||
|
||
Aseta muuttujan a arvoksi 5 Python- konsolissa ja tulosta muuttujan arvo. | ||
|
||
<button onclick="toggleAnswer(this)" class="btn answer_btn">vinkki</button> | ||
|
||
::: hidden-box | ||
::: code-box | ||
```python | ||
# Aseta ensin arvo | ||
a = 5 | ||
|
||
# Millä funktiolla voit tulostaa muuttujan arvon? | ||
``` | ||
::: | ||
::: | ||
|
||
<button onclick="toggleAnswer(this)" class="btn answer_btn">ratkaisu</button> | ||
|
||
::: hidden-box | ||
::: code-box | ||
```python | ||
a = 5 | ||
|
||
print(5) | ||
``` | ||
::: | ||
::: | ||
|
||
\ | ||
\ | ||
|
||
::: hint-box | ||
Lisävinkkejä konsolin käyttöön: | ||
|
||
- Konsoli sopii hyvin myös esimerkiksi PyQGIS-olioiden ominaisuuksien tutkimiseen sekä | ||
testailuun, ja se tukee esimerkiksi PyQGIS-kirjastojen koodintäydennystä (code completion). | ||
|
||
- Konsolissa voi myös suorittaa useammalle riville jatkuvia komentoja, kuten for-loopin. | ||
Konsoliin ilmestyy tällöin rivinvaihdon jälkeen kolme pistettä sen merkiksi, että se | ||
odottaa lisäkomentoja. Huomaa kuitenkin, että pisteet eivät vastaa Python-koodin | ||
sisennystä, vaan käyttäjän on huolehdittava tästä. | ||
|
||
- Nuolinäppäimillä ylös- ja alaspäin pääsee siirtymään konsoliin syötettyjen komentojen | ||
historiassa. | ||
|
||
- Konsolipaneeli aukeaa todennäköisesti karttaikkunan alapuolelle, mutta sen pystyy | ||
raahaamaan ja telakoimaan haluttaessa muuallekin QGISin käyttöliittymässä tai irrottamaan | ||
omaksi ikkunakseen. | ||
::: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,227 @@ | ||
# Harjoitus 2: PyQGIS-perusteet | ||
|
||
**Harjoituksen sisältö:** QGISin Python-paketin käytön perusteet | ||
|
||
**Harjoituksen tavoite:** Harjoituksen jälkeen opiskelija hallitsee PyQGISin perusteet. | ||
|
||
QGISin Python-konsolissa on käytössä valmiiksi alustettu `iface`-muuttuja, | ||
joka on QgisInterface-luokan olio. Tämä olio mahdollistaa mm. vuorovaikutuksen | ||
tällä hetkellä käynnissä olevan QGIS-ohjelman eri komponenttien kanssa. | ||
Sen kautta voidaan manipuloida esimerkiksi projektiin ladattuja | ||
tasoja tai vaikka pääkarttanäkymää (QgsMapCanvas). | ||
|
||
## Tasojen käsittely | ||
|
||
Avaa QGISiin kurssihakemistosta `NaturalEarth_10m_admin_0_countries.gpkg`-tiedosto. | ||
Klikkaa se aktiiviseksi tasopaneelissa. | ||
|
||
Valitaan aktiivinen taso: | ||
|
||
::: code-box | ||
```python | ||
layer = iface.activeLayer() | ||
print(layer) | ||
``` | ||
::: | ||
|
||
Haetaan vektoritason kohteiden määrä: | ||
|
||
::: code-box | ||
```python | ||
layer = iface.activeLayer() | ||
feature_count = layer.featureCount() | ||
|
||
print(feature_count) | ||
``` | ||
::: | ||
|
||
Iteroidaan vektoritasojen kohteita ja tulostetaan | ||
ominaisuustieto: | ||
|
||
::: code-box | ||
```python | ||
layer = iface.activeLayer() | ||
|
||
for feature in layer.getFeatures(): | ||
attribute = feature.attribute('NAME_EN') | ||
|
||
print(attribute) | ||
``` | ||
::: | ||
|
||
Lisää QGISiin selainpaneelista **XYZ Tiles**-valikon alta | ||
**OpenStreetMap**-taso. | ||
|
||
Haetaan listaus kaikista projektin tasoista: | ||
|
||
::: code-box | ||
```python | ||
layers = QgsProject.instance().mapLayers() | ||
|
||
# Tarkistetaan layers-muuttujan tyyppi | ||
print(type(layers)) | ||
``` | ||
::: | ||
|
||
Tässä `mapLayers()`-metodi palauttaa `dictionary`- | ||
datatyypin, jossa avaimena on tasolle oma uniikki tunniste | ||
merkkijonona ja arvona on varsinainen taso-olio. | ||
|
||
::: hint-box | ||
Tässä esimerkissä meillä on projektissa vektori- ja rasteritaso. | ||
Näiden olioiden luokat on QgsVectorLayer ja QgsRasterLayer. | ||
Huomaa, että nämä luokat perivät | ||
[QgsMapLayer](https://qgis.org/pyqgis/master/core/QgsMapLayer.html)-luokan, | ||
jolloin niillä on myös yhteisiä metodeja. | ||
::: | ||
|
||
Iteroidaan tasoja: | ||
|
||
::: code-box | ||
```python | ||
# Voidaan käyttää listakoostetta | ||
# (kts. tarvittaessa Python-lisätehtävistä | ||
# aihe 1). | ||
|
||
# Tason ID:tä ei välttämättä tarvita, | ||
# joten voidaan hakea suoraan vain | ||
# tasot | ||
layers = [layer for layer in QgsProject.instance().mapLayers().values()] | ||
|
||
for layer in layers: | ||
print(f"name: {layer.name()}") | ||
``` | ||
::: | ||
|
||
Valitaan taso nimen perusteella: | ||
|
||
::: code-box | ||
```python | ||
layers = QgsProject.instance().mapLayersByName('OpenStreetMap') | ||
|
||
# mapLayersByName() palauttaa listan | ||
# tasoista, koska QGISissä on sallittua | ||
# olla useampi taso samalla nimellä | ||
|
||
layer = layers[0] | ||
|
||
print(layer.name()) | ||
``` | ||
::: | ||
|
||
|
||
::: hint-box | ||
**QgsProject**-luokka noudattaa ns. singleton- | ||
suunnittelumallia (ainokainen), joka tarkoittaa sitä että luokasta | ||
voi olla kerrallaan olemassa ainoastaan yksi olio. Tämä | ||
olio voidaan hakea käyttämällä QgsProject-luokan | ||
staattista metodia `instance()`, joka palauttaa aina saman olion. | ||
Koska metodi on staattinen, projektiolioon on globaali pääsy. | ||
::: | ||
|
||
## Harjoitus 2.1 | ||
|
||
Selvitä Pythonilla **OpenStreetMap**-tason datan lähde. | ||
Tutki tarvittaessa [PyQGIS-dokumentaatiota](https://qgis.org/pyqgis/latest/). | ||
|
||
<button onclick="toggleAnswer(this)" class="btn answer_btn">ratkaisu</button> | ||
|
||
::: hidden-box | ||
::: code-box | ||
```python | ||
layers = QgsProject.instance().mapLayersByName('OpenStreetMap') | ||
layer = layers[0] | ||
|
||
data_source = layer.source() | ||
print(data_source) | ||
``` | ||
::: | ||
|
||
Tulos: | ||
|
||
``` | ||
type=xyz&url=https://tile.openstreetmap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png&zmax=19&zmin=0 | ||
``` | ||
::: | ||
|
||
## Harjoitus 2.2 | ||
|
||
Kirjoita skripti, joka käy läpi kaikki projektiin lisätyt tasot | ||
ja tulostaa **vain** vektoritasojen kenttien nimet. | ||
|
||
<button onclick="toggleAnswer(this)" class="btn answer_btn">vinkki</button> | ||
|
||
::: hidden-box | ||
::: code-box | ||
```python | ||
layers = [layer for layer in QgsProject.instance().mapLayer().values() <ehtolause>] # miten tarkistat onko kyseessä vektoritaso? | ||
|
||
for layer in layers: | ||
fields = <funktio> # miten saat QgsFields-olion tasosta? | ||
|
||
for field in fields: | ||
<tulosta nimi> | ||
``` | ||
::: | ||
::: | ||
|
||
|
||
<button onclick="toggleAnswer(this)" class="btn answer_btn">ratkaisu</button> | ||
|
||
::: hidden-box | ||
::: code-box | ||
```python | ||
layers = [layer for layer in QgsProject.instance().mapLayers().values() if layer.type() == QgsMapLayer.VectorLayer] | ||
|
||
for layer in layers: | ||
fields = layer.fields() | ||
|
||
print(f"layer '{layer.name()}' fields:") | ||
|
||
for field in fields: | ||
print(field.name()) | ||
``` | ||
::: | ||
::: | ||
|
||
## Harjoitus 2.3 | ||
|
||
Kirjoita skripti, joka tulostaa kaikkien Etelä-Amerikan | ||
alueiden nimet **NaturalEarth**-tasolta. Valitse maanosa | ||
`CONTINENT`-sarakkeen perusteella. Tason oletusnimi | ||
QGISiin lisätessä on "NaturalEarth_10m_admin_0_countries — admin_0_countries". | ||
|
||
<button onclick="toggleAnswer(this)" class="btn answer_btn">vinkki</button> | ||
|
||
::: hidden-box | ||
::: code-box | ||
```python | ||
# Hae taso esim. nimen perusteella | ||
layers = <funktio> | ||
|
||
layer = layers[0] | ||
|
||
for feature in layer.getFeatures(): | ||
# Millä metodilla haet kohteen ominaisuustiedon? | ||
# Vertaa merkkijonoon | ||
if <funktio> == "South America": | ||
print(<kohteen nimi>) | ||
``` | ||
::: | ||
::: | ||
|
||
<button onclick="toggleAnswer(this)" class="btn answer_btn">ratkaisu</button> | ||
|
||
::: hidden-box | ||
::: code-box | ||
```python | ||
layers = QgsProject.instance().mapLayersByName('NaturalEarth_10m_admin_0_countries — admin_0_countries') | ||
|
||
layer = layers[0] | ||
|
||
for feature in layer.getFeatures(): | ||
if feature.attribute("CONTINENT") == "South America": | ||
print(feature.attribute("SOVEREIGNT")) | ||
``` | ||
::: | ||
::: |
Oops, something went wrong.