1
Univerzita Komenského v Bratislave, Prírodovedecká fakulta
LLiibboorr BBuurriiaann
HHaannaa SSttaannkkoovváá
PPyytthhoonn
GGeeoovveeddnnéé aapplliikkáácciiee
2
Univerzita Komenského v Bratislave, Prírodovedecká fakulta
Katedra fyzickej geografie a geoekológie
Katedra kartografie, geoinformatiky a DPZ
Python pre
Geovedné aplikácie
autori: Mgr. Libor Burian
Mgr. Hana Stanková, PhD.
recenzenti: Mgr. Michal Gallay, PhD.
Ing. Karel Jedlička, PhD.
jazyková úprava: Bc. Martina Lešková
© Univerzita Komenského v Bratislave
ISBN: 978-80-223-3947-6
Bratislava, 2015
3
Obsah
Úvod ................................................................................................................................ 4
1. Jazyk Python ............................................................................................................... 5
2. Prostredia jazyka Python............................................................................................. 5
2.1 IDLE (Python GUI) ............................................................................................... 6
2.2 Spyder .................................................................................................................... 8
2.3 PSPad .................................................................................................................... 8
2.4 ArcGIS 10.x ........................................................................................................ 10
3. Základy jazyka Python .............................................................................................. 11
3.1 Základné príkazy jazyka Python ......................................................................... 11
3.2 Premenné ............................................................................................................. 12
3.2.1 Priraďovanie hodnôt premenným ................................................................. 13
3.2.2 Typy premenných ......................................................................................... 14
3.2.3 Zmena typu premenných .............................................................................. 14
3.3 Práca s textovými reťazcami ............................................................................... 15
3.4 Práca so súbormi ................................................................................................. 17
3.4.1 Čítanie zo súboru .......................................................................................... 17
3.4.2 Zapisovanie do súboru .................................................................................. 18
3.5 Podmienky ........................................................................................................... 19
3.6 Cykly ................................................................................................................... 24
3.6.1 Cykly s definovaným počtom opakovaní ..................................................... 24
3.6.2 Cykly s nedefinovaným počtom opakovaní ................................................. 28
3.7 Zoznamy .............................................................................................................. 29
3.8 Funkcie ................................................................................................................ 31
3.9 Modulárna štruktúra jazyka Python .................................................................... 32
4. Priestorová analýza prostredníctvom knižnice ArcPy .............................................. 33
4.1 Práca s vektorovými vrstvami ............................................................................. 37
4.2 Práca s rastrovými vrstvami ................................................................................ 39
4.3 Tvorba nástroja v ArcToolbox ............................................................................ 45
5. Priestorová analýza prostredníctvom knižnice NumPy ............................................ 52
6. Vykresľovanie grafov prostredníctvom knižnice Matplotlib ................................... 59
7. Zoznam použitej literatúry ........................................................................................ 66
8. Zoznam odporúčanej literatúry ................................................................................. 66
4
Úvod
V predkladanej publikácii predstavujeme jazyk Python ako jeden z nástrojov na priestorovú
analýzu pre potreby fyzickej geografie. Text je určený najmä študentom a pracovníkom s
geovedným vzdelaním, ktorí vo svojej bežnej praxi využívajú geografické informačné
systémy na úrovni používateľov (tvorba máp, základné priestorové analýzy, tvorba
jednoduchých modelov...) a majú snahu postúpiť o krok ďalej. Naopak, text rozhodne nie je
odporúčaný začiatočníkom na poli priestorovej analýzy. Pre túto skupinu čitateľov
odporúčame najprv siahnuť po iných publikáciách, zameraných na osvojenie si základných
znalostí na poli priestorovej analýzy a až následne sa vrátiť k tomuto textu. Text ani v
najmenšom nenahrádza plnohodnotné učebnice jazyka Python, určené najmä pre technické
smery štúdia. Naopak, ponúka veľmi jednoduché ozrejmenie pojmového aparátu, najmä za
pomoci príkladov a poskytuje prehľad o základných nástrojoch, využívaných pre potreby
priestorovej analýzy. Text je zostavený na základe filozofie "tak jednoducho, ako sa len dá",
preto nám snáď skúsený programátor alebo pokročilý používateľ informačných systémov
odpustí nedostatočnú exaktnosť a miestami hrubé zjednodušovanie. V prípade, že čitateľ
nadobudne po tomto základnom exkurze dojem, že bol preň jednoduchý, ba priam banálny,
odporúčame mu, aby čo najskôr siahol po učebných textoch určených pre mierne pokročilých
používateľov, ktoré sú používané najmä na vysokých školách s technickým zameraním.
autorský kolektív
5
1. Jazyk Python
Python je open sourceový jazyk, ktorý vznikol v roku 1991 a za jeho tvorcu je považovaný
Guido van Rossum. Jeho názov je odvodený od satirickej skupiny Monty Python, nie od hada
pytóna, ako je vo všeobecnosti známe. Považuje sa za skriptovací jazyk, teda na rozdiel od
programovacích jazykov, akým je napríklad C, nie je možné z neho vytvoriť priamo
spustiteľný *.exe súbor. Medzi základnú výhodu tohto jazyka považujeme schopnosť
spolupráce na širokom spektre platforiem a implementovanie do bežne používaných
geografických informačných systémov, akými sú ArcGIS, GRASS, QGIS a podobne.
Funkcionalitu jazyka je možné rozširovať prostredníctvom modulov (akýchsi balíčkov
funkcií), vďaka čomu dokáže, napríklad, pracovať s priestorovými informáciami, pohodlne
tvoriť grafy, počítať pohyby hviezd a planét na oblohe, kresliť geometrické tvary,
komunikovať priamo s operačným systémom alebo komunikovať s externými programami.
Práve táto univerzalita z neho urobila veľmi populárny jazyk hlavne v komunite používateľov
informačných technológií, ktorí nemajú hlboké znalosti v oblasti programovania, teda stoja na
pomedzí medzi vývojárom a používateľom.
Jazyk Python je možné nainštalovať do osobného počítača ako:
1. Samostatný jazyk a samostatné prostredie (rozhranie).
2. Ako komplexný balík, ktorý v sebe najčastejšie obsahuje jazyk, prostredie a niekoľko
bežne používaných modulov (napr. Anaconda).
3. Ako súčasť niektorých iných prostredí, kde sa jadro a základné prostredie nainštalujú
spolu s iným programom alebo skupinou programov (napr. ArcGIS 10.x).
Pre potreby tohto textu budeme využívať verziu Python 2.7. Táto verzia je bežne
distribuovaná s prostredím ArcGIS 10.2.
2. Prostredia jazyka Python
Za prostredie (vývojové prostredie) považujeme obslužnú aplikáciu, ktorá komunikuje so
samotným jazykom Python (jadrom jazyka Python). Ide teda o komunikačné rozhranie medzi
používateľom a jazykom Python. Ak jazyk Python (jadro Python) považujeme za úradníka,
tak prostredie (rozhranie) považujeme za kanceláriu prvého kontaktu, kde zadáme svoju
žiadosť vo správnej forme a tá ju následne postúpi úradníkovi, ktorý o nej rozhodne a
opätovne prostredníctvom kancelárie prvého kontaktu nám odpovie (Obrázok 1.).
6
Obrázok 1. Schéma komunikácie prostredia a jadra Python.
Na jednom operačnom systéme môže byť nainštalovaných niekoľko verzií jazyka Python a
každá verzia môže mať niekoľko prostredí (Obrázok 2.).
Obrázok. 2. Ukážka vzťahov medzi prostrediami a jadrami jazyka Python. Na jednom
počítači môže byť nainštalovaných niekoľko verzií jadra a každá z nich môže komunikovať s
niekoľkými prostrediami.
Medzi bežne najpoužívanejšie prostredia patrí Python IDLE, Spyder alebo PSPad. V tomto
texte sa zoznámime len s elementárnym ovládaním každého z prostredí. Podrobnejšie štúdium
necháme na samotného používateľa. Začínajúcemu používateľovi odporúčame vyskúšať
niekoľko prostredí a vybrať si to, s ktorým sa mu pracuje najkomfortnejšie.
2.1 IDLE (Python GUI)
Ide o jedno z najintuitívnejších open sourceových prostredí pre Python. Prostredie sa inštaluje
spolu s jadrom Python. Stiahnuť ho je najjednoduchšie zo stránky https://www.python.org. V
prípade, že má používateľ nainštalovaný ArcGIS 10.0, inštaluje sa toto prostredie spolu s
jadrom automaticky vo verzii 2.6. V prípade, že je nainštalovaný ArcGIS 10.2, inštaluje sa
verzia jadra 2.7. Ukážku základného okna tohto prostredia (Python Shell) vidíme na Obrázku
3. Prvých desať riadkov nás informuje o základných atribútoch jadra Python. Riadok
začínajúci >>> a blikajúci kurzor nás informuje o pripravenosti prostredia. IDLE je
interaktívne prostredie, kde je interaktivita zabezpečená možnosťou spustiť nami napísaný
riadok skriptu priamo stlačením tlačidla ENTER. Tento druh prostredia je vhodný najmä pre
prvotné pokusy s jazykom, pretože je možné spustit vždy len jeden príkaz (prostredie funguje
ako interpreter). Nie je možné vytvoriť zdrojový kód dlhý niekoľko riadkov a spustiť ho
naraz. Ak chceme využiť práve túto funkciu, je nutné vytvoriť nový Python súbor
prostredníctvom ponuky File/New window alebo prostredníctvom klávesovej skratky ctrl + n.
Následne sa otvorí nové obdobné okno IDLE, ktoré však nie je interaktívne. Tu možno písať
priamo zdrojový kód, ktorý spustíme prostredníctvom Run/Run module alebo klávesou F5.
Celé prostredie IDLE sa reštartuje, aby sa vynulovali hodnoty premenných a spustí sa
program v hlavnom okne prostredia. Celý postup je ilustrovaný na Obrázku 4., kde sme
vytvorili program, ktorý vypíše na obrazovku "Ahoj". Samotné prostredie IDLE sa v dnešnej
dobe používa len výnimočne, avšak pre začínajúceho programátora je vhodné.
7
Obrázok 3. Ukážka hlavného okna prostredia IDLE
Obrázok 4. Ukážka výpisu Ahoj prostredníctvom interaktívneho módu (vľavo) a
neinteraktívneho módu (vpravo) v prostredí IDLE.
8
2.2 Spyder
Ide o sofistikovanejšie open sourceové prostredie, ktoré je podobné mnohým bežne
používaným prostrediam skriptovacích jazykov, ako napríklad R studio alebo Matlab.
Prostredie je súčasťou balíčka Anaconda (32 / 64 bit verzia), ktorý ponúka komplexné
prostredie Python spolu so 195 najbežnejšie používanými modulmi Python a konzolou
IPython, ktorá je alternatívou k vyššie spomínanému IDLE prostrediu. Ukážka základného
okna prostredia Spyder sa nachádza na Obrázku 5.
Obrázok 5. Ukážka hlavného okna prostredia Spyder.
Hlavné okno sa skladá z troch častí. V ľavej časti je umiestnené pole na písanie zdrojového
kódu. V pravej hornej časti nachádzame Object inspector (správca objektov), Variable
explorer (správca premenných) a File explorer (správca súborov). Prostredníctvom týchto
troch nástrojov dokážeme kontrolovať vstupy a výstupy zo skriptu. V pravej dolnej časti
nachádzame konzolu IPython, ktorá spúšťa skripty napísané v ľavej časti hlavného okna.
Skript po napísaní spustíme tlačidlom F5. Jednou z výhod tohto prostredia je schopnosť
odhaľovať chyby v zdrojovom kóde už počas jeho písania. Teda v prípade, že zadáme
nekorektný príkaz, prostredie nás na to upozorní s krátkym časovým oneskorením (žltá
výstražná ikona). Každý novovytvorený skript je nutné ešte pred spustením uložiť ako
samostatný súbor prostredníctvom File/Save, treťou ikonou zľava na hornej lište prostredia
alebo klávesovou skratkou ctrl + s. Spyder je sofistikované prostredie určené aj pre
pokročilých programátorov, ktoré môže byť pre začínajúceho používateľa trocha mätúce.
2.3 PSPad
PSPad nepredstavuje prostredie v klasickom ponímaní. Ide o open sourceový textový editor,
ktorý je v mnohých aspektoch podobný poznámkovému bloku (Notepadu) v prostredí MS
Windows. Disponuje však pokročilejšími funkciami na editáciu textu (zdrojového kódu) a
pohodlnejšiu prácu s ním. Okrem iného je možné ho prepojiť s jadrom Python, ktoré v
operačnom systéme stojí samostatne. Ukážku hlavného okna tohto programu nachádzame na
Obrázku 6.
9
Obrázok 6. Ukážka hlavného okna prostredia PSPad.
V ľavej časti prostredia nachádzame Správcu projektov, Správcu súborov, Správcu FTP
spojení, Správcu obľúbených lokalít a Správcu otvorených súborov.
V prípade, že chceme PSPad využívať pre potreby komunikácie s jadrom Python, je nutné
spojiť ho s jadrom Python:
1. Otvoríme si menu Nastavenie/Nastavenie zvýrazňovačov.
2. V ľavej časti menu zrušíme označenia všetkých možností okrem možnosti Python.
3. V záložke Externé programy definujeme cestu k jadru Python. Prostredníctvom
tlačidla "..." v položke Program definujeme umiestnenie jadra Python. V našom
prípade to je C:\Python27\ArcGIS10.2\python.exe
4. Po stlačení tlačidla Otvoriť sa v položke Program automaticky zobrazí nasledovná
cesta "C:\Python27\ArcGIS10.2\python.exe" "%File%".
5. Cestu spomínanú v bode 4 upravíme na "C:\Python27\ArcGIS10.2\python.exe" -i
"%File%", teda za cestu k jadru jazyka Python pridáme "-i". To zabezpečí, aby sa
spúšťané okno s prebiehajúcim programom ihneď nezavrelo, ale ostalo otvorené, aby
sme boli schopní prečítať výsledok (Obrázok 7.).
6. Potvrdíme tlačidlom Pridaj a okno zavrieme tlačidlom OK.
7. PSPad reštartujeme.
Pre korektné spustenie projektu v novom okne, musí byť nový projekt nastavený ako
Python dokument s príponou *.py. Nový Python dokument vytvoríme prostredníctvom
Súbor/Nový, čo predstavuje siedmu ikonu zľava na hornej lište a následne výberieme
Python z ponuky. Súbor nemusí byť pred spustením programu uložený. Program
spúšťame prostredníctvom tlačidla F9. Medzi hlavné výhody prostredia PSPad patrí
jednoduchosť, kde mimo základného nastavenia sa prostredie správa ako bežný textový
editor so všetkými ponukami editácie textu, ktoré používatelia poznajú z iných textových
editorov.
10
Obrázok 7. Ukážka korektne nastaveného spojenia medzi PSPad a jadrom Python.
2.4 ArcGIS 10.x
Ako bolo spomínané už vyššie, jazyk Python sa využíva aj v externých komerčných a open
sourceových prostrediach ako alternatíva interaktívnej komunikácie (príkazy sa neklikajú
myšou, ale spúšťajú sa prostredníctvom skriptov). Python implementovaný v prostredí
ArcGIS 10.x týmto umožňuje ovládať a vyvíjať toto prostredie prostredníctvom
programového kódu. Jedným z takýchto prostredí je ArcGIS verzia 10.0 a vyššia, v ktorom sa
nachádza špeciálne prostredie určené na prácu s jazykom Python, tzv. Python Window (od
verzie ArcGIS 10 nahradilo dovtedajšie Command Line Window). Python Window spustíme
ikonou, ktorá je umiestnená na hornej lište hlavného okna ArcGIS. Ukážku okna Python
nachádzame na Obrázku 8.
Obrázok 8. Ukážka Python Window v prostredí ArcGIS 10.x.
Okno je rozdelné na dve časti. V ľavej časti je príkazový riadok, v ktorom zadávame príkazy
za znak >>>, podobne ako v prostredí Python IDLE. V tomto prípade ide opätovne o
interaktívne prostredie, teda príkaz v každom riadku spúšťame prostredníctvom tlačidla
ENTER. Taktiež je možné spúšťať aj viacriadkové príkazy, pričom na nový riadok sa príkaz
zadáva prostredníctvom CTRL + ENTER alebo SHIFT + ENTER. Viacriadkové príkazy sa
spúšťajú dvojnásobným stlačením ENTER. Zdrojové kódy je možné kopírovať (ctrl + c) a
prilepiť (ctrl + v) do konzoly a následne spustiť tlačidlom ENTER, alebo načítať zo súboru
11
prostredníctvom funkcie Load... v kontextovom menu (pravé tlačidlo myši). V pravej časti
okna sa zobrazuje pomoc k príkazom, vrátane syntaxe nástrojov ArcToolbox. V Python
Window môžeme používať všetky príkazy jazyka Python, tak ako v ktoromkoľvek
interpretačnom rozhraní. Medzi základné výhody tohto prostredia patrí priama komunikácia s
prostredím ArcGIS a jednoduchosť. Avšak, v prípade viacriadkových zdrojových kódov je
pre prácu s ArcGIS nástrojmi v Python ideálne využívať externé programy pre prácu s textom
(napr. Notepad alebo PSPad), ktoré pracujú v neinteraktívnom režime. Nasledujúca kapitola
3. je zameraná na osvojenie si základov jazyka Python. Využívaniu funkcionality prostredia
ArcGIS 10.x prostredníctvom jazyka Python sa venujeme až následne v kapitole 4.
3. Základy jazyka Python
3.1 Základné príkazy jazyka Python
V tejto časti sa zameriame na základné príkazy využívané v jazyku Python. Medzi tie
elementárne, ktoré využíva začínajúci operátor, patrí príkaz print, ktorý slúži na výpis
informácií na obrazovku. Je to jeden zo skupiny príkazov, skladajúcich sa z pevnej a
premenlivej časti. Pevná časť je samotný príkaz print a premenlivá časť je všetko, čo sa za
týmto príkazom nachádza, teda čo sa vypíše na obrazovku po stlačení tlačidla ENTER.
print 10
10
# po stlaceni ENTER sa vypiše 10 na obrazovku
print "Ahoj"
Ahoj
# po stlaceni ENTER sa vypiše Ahoj na obrazovku
print 2+5
7
# po stlaceni ENTER sa vypise 7 na obrazovku
print 2*5
10
# po stlaceni ENTER sa vypise 10 na obrazovku
Uviedli sme pár príkladov použitia príkazu print. V prípade, že chceme vypísať čísla,
zadávame ich priamo za príkaz print. V prípade, že chceme vypísať text, tak premenlivú časť
príkazu print ohraničíme úvodzovkami. V prípade príkazu print, ako aj ostatných príkazov, je
možné v premenlivej časti využívať aritmetické operátory. Zoznam bežne používaných
aritmetických operátorov spolu s príkladmi ich využitia v jazyku Python nachádzame v
tabuľke 1. Ako vidíme na ukážke, znak # na začiatku riadku sa využíva pre zápis komentárov.
Tabuľka 1. Ukážka základných aritmetických operátorov v jazyku Python
operand popis príklad + sčítanie 2 + 4 = 6 - odčítanie 2 - 4 = -2 * násobenie 2 * 4 = 8 / delenie 2 / 4 = 0.5 % zvyšok z delenia 7 % 2 = 1 ** mocnina 4 ** 2 = 16
12
Z vyššie uvedeného vyplýva, že interaktívne vývojové prostredie jazyka Python môžeme
používať aj ako jednoduchú kalkulačku. V tomto špecifickom prípade nepotrebujeme zadať
príkaz print, ale rovno zadáme matematický výraz, stlačíme ENTER a vypíše sa výsledok.
>>>2*5
10
>>>2+5
7
>>>7/2
3
>>>7/2.0
3.5
Ak delíme celé čísla, aj výsledok bude zaokrúhlený na celé čísla. Ak potrebujeme dostať
výsledok vo forme desatinného čísla, musíme zadať delenec alebo deliteľ ako desatinné číslo.
Viac o premenných a práci s nimi sa čitateľ dozvie v nasledujúcej podkapitole 3.2.
Okrem aritmetických operátorov využívame aj logické operátory, ktoré sa využívajú najmä na
spájanie výrazov. Výsledkom operácie je v tomto prípade hodnota True (platí, je pravda)
alebo False (neplatí, nie je pravda). Ich význam plne pochopíme neskôr, avšak pre úplnosť
informácie ponúkame ich zoznam v Tabuľke 2, spolu s príkladom ich využitia.
Tabuľka 2. Ukážka základných logických operátorov využívaných v jazyku Python.
operand popis príklad
== rovná sa 2 == 2 True
!= nerovná sa 3!= 2 True
< ľavá časť je menšia ako pravá 2 > 4 False
> pravá časť je menšia ako ľavá 1 < 2 True
<= ľavá časť je menšia alebo rovná ako pravá 1 >= 1 True
>= pravá časť je menšia alebo rovná ako ľavá 5 <= 1 False
10 > 5
True
# po stlaceni ENTER sa vypise True na obrazovku
10 == 5
False
# po stlaceni ENTER sa vypise False na obrazovku
10 >= 11
False
# po stlaceni ENTER sa vypise False na obrazovku
3.2 Premenné
Z uhla pohľadu bežného človeka je použitie premennej nadbytočnou operáciou, pretože
človek len málokedy uvažuje v hodnotách x, y... V našej mysli teda počítame 2 + 2 = 4, nie x
13
= 2, y = 2, z = x + y = 4. Avšak, pri opakovanom použití hodnôt (napr. v cykloch)
v počítačovom prostredí sa oplatí tieto hodnoty uložiť do pripravených pamäťových miest
a ďalej s nimi pracovať práve takouto formou. Premennú môžeme definovať ako pripravené
pamäťové miesto, ktoré môže, alebo nemusí mať definovanú veľkosť a je zaplnené
najčastejšie číselnou alebo znakovou (textovou) hodnotou.
3.2.1 Priraďovanie hodnôt premenným
Priradenie hodnoty premennej je proces uloženia hodnoty do premennej. V niektorých
programovacích jazykoch je potrebné premennú najprv vytvoriť (tzv.deklarovať). Výhodou
jazyka Python je, že premennú nemusíme dopredu vytvárať (nie je nevyhnutné program
informovať o tom, že plánujem využiť premennú), vytvorí sa automaticky pri priradení.
Priradenie premennej sa skladá z troch častí (Obrázok 9):
1. názov premennej – Ide o jednoznačný identifikátor premennej, ktorý musí byť
jedinečný (neopakovať sa), výstižný (aby ju vedel operátor prečítať) a korektný
(nesmie obsahovať diakritiku a iné špeciálne znaky a musí byť odlišný od príkazov
jazyka Python, teda premennú nemôžeme, napr. nazvať print). Názov premennej
obyčajne tvorí jedno písmeno alebo slovo. V prípade viacslovných premenných
nepoužívame medzery, ale oddeľujeme ďalšie slová prvým veľkým písmenom
(myVariable) alebo podčiarkovníkom (my_variable).
2. znak priradenia – Premennú takzvane priraďujeme, teda názvu premennej priraďujeme
hodnotu. Znakom priraďovania v jazyku Python je "=".
3. hodnota premennej – Hodnota premennej nemusí byť na rozdiel od názvu premennej
unikátna a môže nadobúdať niekoľko typov hodnôt (viď. kapitola 3.2.2.).
Obrázok 9. Proces priradenia premennej
Nasleduje niekoľko ukážok priradenia premenných.
x = 10
# premennej x priradi hodnotu 10 (cele cislo)
y = 12.2
# premennej y priradi hodnotu 12.2 (realne cislo)
z = "Ahoj"
# premennej z priradi hodnotu "Ahoj" (znakovy retazec)
m = 15*2
# premennej m priradi hodnotu 30 (cele cislo)
m = "Teraz som zmazal hodnotu premennej m a nahradil som ju
týmto textom" (znakovy retazec)
# povodna hodnota premennej bola zmazaná a nahradená textovym
retazcom
14
Z = "Cau"
print z
"Ahoj"
# v tomto pripade sme nechali vypisat na obrazovku premennu z,
nie Z.
Opätovne, v prípade priradenia znakových reťazcov využívame úvodzovky a pri procese
priradenia hodnoty premennej môžeme využívať aritmetické operátory. Taktiež si môžeme
všimnúť, že Python rozlišuje veľké a malé písmená, teda premenná z nie je rovná premennej
Z.
3.2.2 Typy premenných
V praxi sa stretávame so širokým spektrom premenných, my však budeme pracovať najmä s
tromi typmi premenných, ktoré môžeme považovať za základné, nielen v jazyku Python. Sú
to:
integer – Premenná typu integer môže obsahovať celočíselné hodnoty v ľubovoľnom
rozsahu. Rozsah hodnôt je limitovaný len pamäťovým miestom. (napr. 4, 5, 6, -7, -8
...)
float – Premenná typu float môže obsahovať reálne čísla v ľubovoľnom rozsahu.
Rozsah hodnôt je limitovaný len pamäťovým miestom. (napr. 4, 5, 2.1, 3.5, -4.587, -
4568741258.457 ...) V prípade dlhých čísel sa využíva zápis čísla prostredníctvom
exponentu (tzv. vedecká anotácia známa napríklad z MS Excel).
string – Premenná typu string môže obsahovať ľubovoľné znaky z tabuľky ASCII
(znakový reťazec). Rozsah hodnôt je limitovaný len pamäťovým miestom. Za znak
považujeme aj číslo, ktoré sa však v prípade tejto premennej považuje za text, nie číslo
ako také. S týmto typom premennej nie je možné uskutočňovať aritmetické
operácie.
Ako bolo spomínané už vyššie, typ premennej nie je potrebné deklarovať. V praxi to
znamená, že na začiatku zdrojového kódu nie je nutné informovať program, že budeme
používať premenné x a y, ktoré budú nadobúdať hodnotu reálnych čísel a premennú z, ktorá
bude textová. Len priamo v programe priradíme premennej x hodnotu 10.2, premennej y
hodnotu 11.2 a premennej z hodnotu Ahoj. Ide o snahu autorov prostredia zjednodušiť
programátorovi prácu.
3.2.3 Zmena typu premenných
Zmenou typu premennej (tzv. pretypovanie) nazývame proces predefinovania typu
premennej. Ak je v premennej uložená nejaká hodnota, prevedie sa na hodnotu príslušného
typu. Napríklad, premennú typu integer, v ktorej je uložená hodnota 10, prevedieme na
premennú s takým istým názvom typu string a hodnota v nej uložená sa zmení na textový
reťazec „10“. Niektoré druhy prevodov nie sú možné, napr. prevod premenných typu string,
obsahujúcich písmená na premenné typu integer a float (v takomto prípade program vypíše
chybu). Zoznam základných funkcií, ktoré sa využívajú na zmenu typu premenných
nachádzame v Tabuľke 3.
15
Tabuľka 3. Ukážka funkcií využívaných na zmenu typu premenných.
funkcia popis príklad
int() prevod na premennú typu integer int(12.7) = 12
float() prevod na premennú typu float float(12) = 12.0
str() prevod na premennú typu string str(12) = 12
Funkcia int() sa využíva na prevod textových reťazcov vo vhodnom tvare na celé číslo, alebo
na prevod z reálneho čísla na celé tým, že sa oddelí desatinná časť (nie zaokrúhli). Funkcia
float() sa využíva na prevod textových reťazcov vo vhodnom tvare na reálne číslo, alebo na
prevod z celého čísla na reálne tým, že sa pridá jedno desatinné miesto s hodnotou 0. Funkcia
str() sa využíva na prevod celého alebo desatinného čísla na textový reťazec, teda číslo ostane
nezmenené, len je uložené ako text a nie je možné s ním operovať ako s číslom.
Začínajúcemu používateľovi sa takéto prevody môžu zdať nelogické, ba až nadbytočné, avšak
v ďalších kapitolách textu zistíme, že majú význam.
a = 12.45
a = int(a)
print a
12
# prevod realneho cisla na cislo cele
b = 12.45
b = str (b)
print b
12.45
# prevod realneho cisla na textovy retazec, pricom jeho
hodnota ostane nezmenena
3.3 Práca s textovými reťazcami
Práca s textovými reťazacmi (textom) sa bude začínajúcemu programátorovi javiť
komplikovaná, pretože je pre používateľa zväčša jednoduchšie pracovať s číslami ako s
textom. Textový reťazec je v jazyku Python reprezentovaný premennou typu string. Medzi
základné operácie s touto premennou patrí jej formátovanie. V rámci tohto kurzu sa
zameráme len na najzákladnejšie formátovanie textu, zvyšok ponecháme na samoštúdium.
Ako bolo ukázané už vyššie, textové reťazce zapisujeme medzi úvodzovky.
x = "Ahoj"
print x
Ahoj
y = " Ahoj ako sa mas?"
print y
Ahoj ako sa mas?
# Do retazca sa pocitaju aj prazdne znaky (medzery) a to aj
pred slovami aj za slovami
V prípade, že chceme využiť v rámci textového reťazca nový riadok alebo text oddeliť
tabulátorom, je nevyhnutné využiť regulárne výrazy. Regulárne výrazy sú reťazce, ktoré
zastupujú špecifický znak. Medzi najbežnejšie používané regulárne výrazy patria:
16
\n – nový riadok textu
\t – tabulátor
\s – medzera
print "Ahoj ja som Jozef \n A ty si kto?"
Ahoj ja som Jozef
A ty si kto?
# v tomto pripade znak \n zastupuje novy riadok a stlacenie
klavesy ENTER
print "\t Ako sa máš"
Ako sa máš
# v tomto pripade znak \t zastupuje tabulator a teda text je
odsadeny
Ďalšou častou operáciou je spájanie dvoch reťazcov alebo ich násobenie (multiplikácia).
x = "Ahoj"
y = " ako sa mas?"
print x + y
Ahoj ako sa mas?
# dva retazce boli spojene znakom "+"
x = "Si "
y = "velmi "
z = "super "
print x + 3 * y + z
Si velmi velmi velmi super
# v tomto pripade sme spojili tri retazce do jedného retazca a
retazec y sme multiplikovali tri krat
Omnoho komplikovanejšie je spájanie znakových reťazcov s číslom. Jazyk Python nám
neumožňuje jednoducho spájať znakový reťazec s číslom.
x = "Ahoj"
y = 3
print x + y
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
print x + y
TypeError: cannot concatenate 'str' and 'int' objects
Existujú dve možnosti riešenia tohto problému:
1. V prvom prípade prevedieme všetky premenné na jeden formát, najčastejšie na
znakový reťazec, ktorý sa dá bez problémov spájať. K tomuto využívame zmenu typu
premenných (pretypovanie).
x = "Ahoj"
y = 3
y = str(y)
print x + y
ahoj3
# v tomto pripade sme najprv ciselnu premennú previedli na
znakovy retazec a nasledne sme spojili dva znakove retazce.
17
2. Druhou možnosťou je využiť formátovanie reťazcov a špecifický zápis, ktorý umožní
spájať niekoľko premenných rozličných typov.
meno = "Jozef"
vek = 25
print "Ahoj, volam sa %s a mam %i rokov." %(meno,vek)
Ahoj volam sa Jozef a mam 25 rokov.
V tomto prípade sme vypísali znakový reťazec, ktorý obsahuje dve premenné (jednu
znakovú a jednu číselnú). Znak % v textovom reťazci označuje začiatok formátovania
a nasledujúce znaky za ním hovoria, na aký formát sa má premenná previesť (znak
s označuje prevod na textový reťazec, znak i prevod na celé číslo). Za ďalším znakom
% za textovým reťazcom sa nachádza zoznam premenných, ktoré musia byť uvedené
v rovnakom poradí ako v predchádzajúcej časti.
3.4 Práca so súbormi
V doterajších príkladoch sme vstupy zadávali len prostredníctvom klávesnice a výstupy sa
zobrazovali priamo na obrazovke. Ide o najjednoduchší a zároveň najmenej efektívny spôsob
výstupu. V prípade zložitejších operácií ide o značne nepohodlný spôsob. Predstavte si, že
výsledkom skriptu je 10 000 hodnôt, ktoré je potrebné ručne prepisovať. Druhou často
používanou možnosťou vstupu a výstupu je čítanie a zapisovanie do súboru, kde sa vstupné
dáta čítajú a zapisujú z a do súboru. Najčastejšie sa pre základnú prácu so súbormi využíva
textový formát *.txt.
3.4.1 Čítanie zo súboru
Máme vytvorený súbor mena.txt, ktorý má nasledovný tvar.
Magda
Veronika
Michaela
Margita
Zelmira
Kvetoslava
Miroslava
Tatiana
Chceme vytvoriť program, ktorý prečíta mená zo súboru a priradí ich do znakových
premenných s názvami meno_1, meno_2, meno_3... Postup práce je nasledovný:
1. Otvoríme súbor mena.txt, ktorý sa nachádza v rovnakom priečinku ako nami
vytvorený skript.
2. Prečítame prvý riadok v súbore a priradíme ho premennej meno_1.
3. Krok 2 opakujeme ešte sedemkrát.
4. Súbor mena.txt zavrieme.
f = open('mena.txt', 'r')
# otvorenie suboru mena.txt len na citanie
meno_1 = f.readline()
meno_2 = f.readline()
meno_3 = f.readline()
meno_4 = f.readline()
meno_5 = f.readline()
18
meno_6 = f.readline()
meno_7 = f.readline()
meno_8 = f.readline()
# precitanie vzdy jedneho riadka a jeho priradenie premennej
s prislusnym nazvom
f.close()
# uzatvorenie suboru mena.txt
Vo vyššie uvedenom kóde sme sa zoznámili s tromi novými funkciami. Funkcia open()
priradí do premennej (v našom prípade f) otvorený súbor, ktorého meno je deklarované v
zátvorke. Inak povedané, otvoríme súbor mena.txt. Tento súbor sa musí nachádzať v
rovnakom priečinku ako zdrojový kód. V prípade, že chceme zmeniť umiestnenie vstupného
súboru mena.txt, je nevyhnutné zadať celú cestu k súboru nasledovným spôsobom
"C:/mena.txt". V druhej časti tejto funkcie deklarujeme, čo máme v úmysle s týmto súborom
robiť. V našom prípade budeme súbor čítať, teda pridáme symbol 'r' (read). V prípade, že by
sme do súboru zapisovali, pridáme symbol 'w' (write), čím sa vymaže celý predošlý obsah
súboru. V prípade, že chceme do súboru len informácie pridávať, pridáme symbol 'a'
(append), kde sa každý ďalší riadok súboru len pridá na existujúci koniec súboru. Funkcia
.readline() zabezpečí prečítanie prvého riadku súboru, teda všetky informácie až po prvý
ENTER. Pred funkciu je nevyhnutné zadať aj názov premennej, ku ktorej je súbor priradený.
Hlavnou nevýhodou tohto postupu je, že nie sme schopní priamo prečítať, napríklad, piaty
riadok bez toho, aby sme neprečítali predošlé štyri riadky. Príkaz .close(), otvorený súbor
uzatvorí, a taktiež uloží akékoľvek uskutočnené zmeny v ňom (platí len v prípade zápisu
alebo pridávania do súboru). Pred funkciu je nevyhnutné zadať aj názov premennej, ku ktorej
je súbor priradený.
3.4.2 Zapisovanie do súboru
Metóda zápisu do súboru sa využíva najmä v prípade veľkého množstva textových výstupov.
Napríklad, v prípade, že skript vygeneruje 200 znakových premenných, je vhodnejšie ich
zapísať do súboru, ako ich len vypísať na monitor. V nasledujúcom príklade vytvoríme
jednoduchú kalkulačku, ktorej z dvoch vstupných čísel vypočíta súčet, rozdiel, súčin, podiel a
výsledok zapíše do nového súboru s názvom vysledok.txt. Postup práce je nasledovný:
1. Otvoríme si nový súbor s názvom vysledok.txt v móde na zapisovanie.
2. Zadáme hodnoty premennej x a premennej y.
3. Do prvého riadku súboru zapíšeme výsledok súčtu premennej x a premennej y.
4. Krok 3 zopakujeme aj pre rozdiel, súčin a podiel.
5. Súbor vysledok.txt zatvoríme.
f = open('vysledok.txt', 'w')
# otvori novy subor vysledok.txt v mode zapisovania
x = 10.0
y = 3.0
# definuje hodnoty premennych x a y
f.write("Sucet %i a %i je %i\n" %(x,y,x+y))
f.write("Rozdiel %i a %i je %i\n" %(x,y,x-y))
f.write("Sucin %i a %i je %i\n" %(x,y,x*y))
f.write("Podiel %i a %i je %f\n" %(x,y,x/y))
19
# vypocita sucet, rozdiel, sucin a podiel premenych x a y a
vysledok priamo zapise do noveho riadku.
f.close()
# uzatvorenie suboru vysledok.txt
Výsledný súbor vysledok.txt bude vyzerať nasledovne.
Sucet 10 a 3 je 13
Rozdiel 10 a 3 je 7
Sucin 10 a 3 je 30
Podiel 10 a 3 je 3.333333
Funkcia open() je nám známa už z predošlého príkladu. V tomto prípade sme však využili už
spomínaný mód zapisovania (editácie) 'w', ktorý najprv zmaže predošlý obsah súboru a
následne začne zapisovať od prvého riadku. Súbor sa uloží do rovnakého adresára ako je
umiestnený zdrojový kód. Funkcia .write()zapíše znaky uvedené v zátvorke do nového
súboru. Pred funkciu je nevyhnutné zadať aj názov premennej, do ktorej je súbor priradený.
Príkaz .close() otvorený súbor uzatvorí, a taktiež uloží v ňom uskutočnené zmeny.
3.5 Podmienky
Podmienky (vetvenie, conditions) sú jednou z bežne používaných operácií v rámci
pokročilých kódov. Podmienka je chápaná ako operácia rozhodovania, kde v prípade splnenia
podmienky nastane jedna eventualita, a naopak, v prípade nesplnenia podmienky nastane
eventualita druhá (Obrázok 10).
Obrázok 10. Ukážka významu podmienok v programovaní.
Podmienky v jazyku Python sú zastúpené príkazom if s ustálenou štruktúrou.
if podmienka:
eventualita_1
else:
eventualita_2
Prvý riadok sa skladá z pevnej časti if, za ktorou nasleduje samotná podmienka, ktorá je
ukončená dvojbodkou. V prípade, že sa tu dvojbodka nenachádza, príkaz je považovaný
za chybný. Druhý riadok popisuje eventualitu 1, ktorá bude vykonaná v prípade, že je
podmienka splnená. V treťom riadku nachádzame pevnú časť else opätovne ukončenú
dvojbodkou. Štvrtý riadok popisuje eventualitu 2, ktorá bude vykonaná v prípade, že
podmienka nebude splnená. Eventualita_1 a eventualita_2 sa skladá z jedného alebo
viacerých príkazov, ktoré sa vykonajú v prípade splnenia, resp. nesplnenia podmienky.
20
Môžeme si všimnúť, že tieto príkazy nie sú oddelené od posledného kódu zátvorkami.
Jediným oddeľovačom je v tomto prípade umiestnenie na nový riadok a odsadenie
(indentation), ktoré je v jazyku Python veľmi dôležité. Nie je predpísané, koľko medzier
alebo tabulátorov sa má použiť na odsadenie, ale podstatné je, aby bolo toto odsadenie
v celom kóde jednotné, inak sa kód nemusí správne interpretovať alebo program vypíše chybu
(tzv. indetation error). Na toto si treba dávať pozor, najmä pri kopírovaní z textových
editorov, ako napr. PSPad do prostredia, v ktorom sa vykonávajú príkazy jazyka Python. Na
odsadenie sa obyčajne používajú 4 medzery (prípadne jeden tabulátor).
Použitie podmienok si ukážeme na príklade skriptu, ktorý rozhodne, či nami zadané číslo je
väčšie alebo menšie ako 100. Postup práce je nasledovný:
1. Premennej x priradíme hodnotu, ktorú budeme skúmať.
2. Vhodne zostavíme podmienku, ktorá bude testovať, či x je väčšie alebo rovné ako 100
a zistenie vypíše na obrazovku.
x = 20
# premennej x priradime hodnotu 20
if x >= 100:
print "Cislo je vacsie ako 100."
else:
print "Cislo je mensie ako 100."
# definujeme, co sa stane v pripade ze cislo je vacsie alebo
mensie ako 100
Nami zostavený skript sa dá využiť len pre jedno testované číslo, teda len pre číslo 20. V
prípade, že chceme testovať iné číslo, musíme jeho hodnotu zmeniť v zdrojovom kóde. V
nasledovnom príklade zmeníme pevné priradenie premennej na dynamické priradenie.
Program sa nás teda opýta, aké číslo chceme testovať. Následne toto číslo zadáme a program
nám vyhodnotí, či je toto číslo menšie alebo väčšie ako 100.
x = input("Zadaj cislo ktore chces testovat \n")
# definujeme, aby sa skript vzdy dopytoval pouzivatela na
hodnotu premennej x
if x >= 100:
print "Cislo je vacsie ako 100."
else:
print "Cislo je mensie ako 100."
# definujeme, co sa stane v pripade ze cislo je vacsie alebo
mensie ako 100
Jediná zmena oproti poslednému skriptu nastala v prvom riadku, kde sme pevné priradenie
premennej x = 20 zamenili za variabilné priradenie prostredníctvom funkcie input(). Funkcia
sa skladá z pevnej časti input a premenlivej časti ohraničenej zátvorkami. Premenlivá časť
reprezentuje hlásenie, ktoré sa zobrazí pred zadaním hodnoty. V prípade, že ju necháme
prázdnu, zobrazí sa len blikajúci kurzor a skript bude čakať na zadanie hodnoty.
Úlohou ďalšieho skriptu bude spýtať sa nás na našu výšku v metroch a váhu v kilogramoch, z
čoho následne vypočíta náš Body Mass Index (BMI). Na základe našej hodnoty BMI nám
program vypíše, či máme nadváhu, normálnu váhu alebo podváhu. BMI sa počíta ako podiel
hmotnosti v kilogramoch a druhej mocniny výšky v metroch. BMI nad 25 sa považuje za
21
nadváhu a pod 19 za podváhu. Všetky hodnoty medzi tým reprezentujú normálnu hmotnosť.
Postup práce je nasledovný:
1. Premenným hmotnost a vyska dynamicky priradíme hodnoty.
2. Vypočítame hodnotu BMI.
3. Zostavíme podmienku, ktorá bude vhodným spôsobom informovať, či má subjekt
nadváhu, normálnu váhu alebo podváhu.
vyska = input("Zadaj vysku v metroch \n")
vaha = input("Zadaj vahu v kilogramoch \n")
# dynamicke priradenie vahy a vysky
vyska = float(vyska)
vaha = float(vaha)
# prevod vysky a vahy na typ float, aby bol vysledok BMI v
desatinnych cislach
bmi = vaha/(vyska**2)
# vypocet BMI
print "Tvoj BMI = %f" %(bmi)
# vypis bmi
if bmi < 19:
print "Mas podvahu"
if 19 <= bmi < 25:
print "Mas normalnu vahu"
if bmi >= 25:
print "Mas nadvahu"
# zistujeme ci ma subjekt nadvahu, normalnu vahu alebo podvahu
a vysledok vypiseme na obrazovku
V tomto prípade sme využili zápis podmienky, kde definujeme každú eventualitu zvlášť. Ide o
najjednoduchší a zároveň menej korektný zápis.
Vyššie uvedená podmienka sa dá zapísať aj nasledovným spôsobom.
if bmi < 19:
print "Mas podvahu"
else:
if 19 <= bmi < 25:
print "Mas normalnu vahu"
else:
if bmi >= 25:
print "Mas nadvahu"
# definujeme ci ma subjekt nadvahu, normalnu vahu alebo
podvahu
V tomto prípade sme využili vnorenú podmienku, kde každá nesplnená podmienka vstupuje
do ďalšieho testovania. Vnorené podmienky využívame najmä pri hierarchickom
rozhodovaní, keď delíme celok na časti a tie ešte na ďalšie časti. Situácia prvej, aj druhej
možnosti je zobrazená na Obrázku 11.
22
Obrázok 11. Ukážka dvoch možností riešenia viacnásobných podmienok (vetvenia). a,–
Každá eventualita je definovaná zvlášť b,– Takzvaná vnorená podmienka, keď sa v prípade
nesplnenia prvej podmienky následne testuje druhá a v prípade nesplnenia druhej podmienky
sa testuje tretia.
V ďalšom príklade budeme simulovať trh s cennými papiermi. Skript nám najprv vypíše
ponuku akcií od piatich firiem aj s ich cenou, ktorá bude náhodná. Následne si používateľ
môže nakúpiť ľubovoľný počet akcií jednej firmy. Skript bude simulovať zmenu hodnoty
akcie prostredníctvom generovania novej náhodnej hodnoty akcie. Nakoniec skript vypíše,
koľko sme na operácii zarobili alebo prerobili.
1. Importujeme modul na prácu s generátormi náhodných čísel.
2. Vytvoríme výpis cien pre päť spoločností.
3. Zistíme, koľko akcií, od ktorej spoločnosti si chce používateľ nakúpiť.
4. Simulujeme zmenu akcií prostredníctvom náhodného generovania novej ceny akcie.
5. Vypočítame celkový zisk alebo stratu a zostavíme podmienku, ktorá nás bude o tejto
skutočnosti vhodne informovať.
import random
# import modulu random
a1 = random.randrange(5,28)
a2 = random.randrange(5,28)
a3 = random.randrange(5,28)
a4 = random.randrange(5,28)
23
a5 = random.randrange(5,28)
# nahodne generovanie cien akcii piatich firiem
print "1,\t cena akcie spolocnosti Prva Udenarska a.s. je %i
eur" %(a1)
print "2,\t cena akcie spolocnosti Cokoladovne a.s. je %i eur"
%(a2)
print "3,\t cena akcie spolocnosti Plynarne Myjava a.s. je %i
eur" %(a3)
print "4,\t cena akcie spolocnosti Vinohrady Kolarovo a.s. je
%i eur" %(a4)
print "5,\t cena akcie spolocnosti Zemiakaren Nitra a.s. je %i
eur" %(a5)
# vypis cien akcii jednotlivych spolocnosti
firma = input("Zadaj id spolocnosti od ktorej chces nakupovat
\n")
pocet_akcii = input("Zadaj pocet akcii ktory chces nakupit
\n")
# dynamicke priradenie id firmy a poctu akcii.
if firma == 1:
nakupna_cena = a1
if firma == 2:
nakupna_cena = a2
if firma == 3:
nakupna_cena = a3
if firma == 4:
nakupna_cena = a4
if firma == 5:
nakupna_cena = a5
# priradenie ceny nakupu akcii
print "Celkova cena nakupu je %i eur" %(nakupna_cena *
pocet_akcii)
# vypis celkovej ceny nakupu
predajna_cena = random.randrange(5,28)
print "Cena predaja akcie je %i eur" %(predajna_cena)
print "Vsetky akcie predas za %i eur" %(predajna_cena *
pocet_akcii)
# generovanie predajnej ceny akcie a nasledne jej vypis a
vypis celkovej ceny predaja
if predajna_cena >= nakupna_cena:
print "Na obchode si zarobil %i eur" %((predajna_cena -
nakupna_cena)*pocet_akcii)
if predajna_cena < nakupna_cena:
print "Na obchode si prerobil %i eur" %((nakupna_cena -
predajna_cena)*pocet_akcii)
# definujeme ci sme na obchode zarobili alebo prerobili
24
V tomto prípade sme sa zoznámili s modulom random, ktorý pod sebou združuje niekoľko
funkcií na generovanie náhodných čísel. Modul importujeme prostredníctvom príkazu import
v prvom riadku. Viac o moduloch a ich importovaní a práci s nimi nachádzame v kapitole 3.8.
Z modulu random sme využili funkciu randrange(), ktorá náhodne generuje celé čísla v nami
definovanom intervale. Interval definujeme v premenlivej časti kódu tak, že najprv zapíšeme
spodnú hranicu intervalu a za čiarku vrchnú hranicu intervalu.
3.6 Cykly
Za cyklus (iteráciu) v ponímaní programovania považujeme proces, ktorý sa opakuje s
pravidelným prírastkom minimálne jednej premennej vopred definovaným počtom krát, alebo
pokiaľ nie je splnená vopred definovaná podmienka. Už z vyššie uvedenej definície je
evidentné, že poznáme cyklus s vopred definovaným počtom opakovaní (funkcia for) a cyklus
s nedefinovaným počtom opakovaní (funkcia while) (Obrázok 12.).
Obrázok 12. Ukážka dvoch druhov cyklov. a, – Cyklus s vopred definovaným počtom
opakovaní. b, – Cyklus s vopred definovanou podmienkou, ktorý sa opakuje pokiaľ je
podmienka platná.
V cykle vždy existuje unikátna premenná, ktorá v každom behu cyklu mení svoju hodnotu a
nazývame ju iterátor. Iterátorom býva ordinálna (poradová) premenná, a to buď v podobe
celého čísla, alebo v podobe zoznamu hodnôt.
3.6.1 Cykly s definovaným počtom opakovaní
Cyklus s vopred definovaným počtom opakovaní sa v jazyku Python zapisuje
prostredníctvom funkcie for.
for i in rozsah hodnôt:
ukon
Prvý riadok funkcie sa skladá z pevnej časti for a časti premenlivej, ktorá je ukončená
dvojbodkou. V prípade, že sa tu dvojbodka nenachádza, príkaz je považovaný za chybný. V
premenlivej časti definujeme rozsah hodnôt (od – do), v ktorých sa iterátor bude pohybovať.
Druhý riadok v sebe obsahuje úkon, alebo úkony, ktoré sa v každom opakovaní cyklu
vykonajú. Tento riadok musí nevyhnutne byť odsadený podľa podmienok uvedených v
kapitole 3.5 Podmienky.
V prvom príklade vyskúšame prostredníctvom cyklu s vopred definovaným počtom
opakovaní vypísať na obrazovku 20-krát "Ahoj, ako sa mas?". Postup práce je nasledovný:
25
1. Vytvoríme telo cyklu, ktorý sa bude 20-krát opakovať.
2. Definujeme zápis, ktorý bude vždy do nového riadku vypisovať "Ahoj, ako sa mas?".
for i in range(20):
# telo funkcie for
print "Ahoj, ako sa mas?"
# vypis vety 20–krát
V tomto prípade sme v prvom riadku využili príkaz range(), ktorý generuje sekvenciu čísel
v zadanom rozsahu. Ak zadáme iba jeden parameter, chápe sa ako konečná hodnota (prvá,
ktorá už nebude patriť do zoznamu). V takom prípade sa vygeneruje sekvencia, začínajúca
číslom 0 a končiaca číslom 19. Premenná i v cykle nadobúda postupne tieto hodnoty, ale
v tele cyklu ju nepoužívame, slúži iba na iteráciu (opakovanie). Daný príkaz print sa teda
v cykle zopakuje 20-krát.
V druhom príklade vyskúšame prostredníctvom cyklu s vopred definovaným počtom
opakovaní vypísať na obrazovku prvých 20 čísel, pričom začneme číslom jeden. Postup práce
je nasledovný:
1. Vytvoríme telo cyklu, ktorý sa bude opakovať 20-krát.
2. Definujeme zápis, ktorý bude postupne do nového riadku zapisovať čísla od 1 do 20.
for i in range(1,21):
# telo funkcie for
print i
# vypis
V tomto prípade sme len pozmenili predošlý skript. V prvom rade sme definovali aj spodnú,
aj hornú hranicu intervalu a v druhom rade sme zmenili vopred definovaný výpis za iterátor
(premennú). V tomto prípade sa teda iterátor používa priamo vo výpise.
V ďalšom príklade vyskúšame prostredníctvom cyklu s vopred definovaným počtom
opakovaní vypísať na obrazovku jednostranný trojuholník zložený zo znaku "*", kde na
začiatku skriptu budeme môcť definovať výšku tohto trojuholníka. Výsledok bude vyzerať
nasledovne.
*
**
***
****
...
Postup práce je nasledovný:
1. Prostredníctvom dynamického dopytu zistíme od používateľa výšku trojuholníka.
2. Vytvoríme telo cyklu, ktorý sa bude opakovať toľko krát, aká bude výška trojuholníka.
3. Definujeme zápis, ktorý bude postupne do prvého riadka vypisovať jednu hviezdičku,
do druhého dve hviezdičky, do tretieho tri hviezdičky, atď.
vyska = input("Zadaj pocet riadkov \n")
# dynamicke priradenie vysky trojuholnika premennej "vyska"
for i in range (1,vyska):
26
# telo funkcie for, kde horna hranica intervalu je definovana
premennou vyska
print i*"*"
# vypis
Do predošlého skriptu sme pridali len dynamické priradenie premennej vyska, ktorá bude
udávať počet riadkov, a tým aj výšku trojuholníka. Horná hranica intervalu v cykle je
definovaná touto premennou. Taktiež sme vhodne upravili výpis.
V ďalšom príklade vypíšeme prostredníctvom cyklu s definovaným počtom opakovaní maticu
4x4, ktorá bude obsahovať dvojice čísel, označujúce riadok (prvé číslo) a stĺpec (druhé číslo).
Výstup nezobrazíme na monitor, ale vypíšeme do súboru matica.txt. Výsledok by mal vyzerať
nasledovne.
1,1 1,2 1,3 1,4
2,1 2,2 2,3 2,4
3,1 3,2 3,3 3,4
4,1 4,2 4,3 4,4
Postup práce je nasledovný:
1. Otvoríme súbor matica.txt v móde na zápis, ktorý sa bude nachádzať priamo na disku
C:.
2. Vytvoríme telo cyklu, ktorý bude zabezpečovať výpis riadkov.
3. Vytvoríme telo cyklu, ktorý bude zabezpečovať výpis stĺpcov.
4. Definujeme zápis, ktorý bude za seba zapisovať číslo riadka, čiarku a číslo stĺpca.
5. Definujeme zápis, ktorý zabezpečí ukončenie riadka.
6. Uzatvoríme súbor matica.txt.
f = open('C:/matica.txt', 'w')
# otvorenie suboru matica.txt len na citanie
for i in range(1,5):
for j in range(1,5):
f.write("%i,%i " %(i,j))
f.write("\n")
# definovanie zapisu ktory do suboru vypise najprv cislo
riadka, potom cislo stlpca, ktore su oddelene ciarkou a na
konci riadka sa presunie a novy riadok.
f.close()
# uzatvorenie suboru mena.txt
V tomto prípade sme nevyužili žiadny nový príkaz. Počet riadkov a stĺpcov definujeme
prostredníctvom hornej hranice intervalu funkcie range(). Využili sme takzvaný vnorený
cyklus (Obrázok 13), kde v rámci cyklu existuje cyklus nižšej hierarchickej úrovne (podobne
ako vnorená podmienka).
27
Obrázok 13. Ukážka štruktúry vnoreného cyklu.
Najprv sa teda vypísali stĺpce v prvom riadku prostredníctvom cyklu s iterátorom j a následne
sa riadok posunul prostredníctvom cyklu s iterátorom i. Ďalší riadok sa vypísal opätovne
prostredníctvom cyklu s iterátorom j. Všimnime si, že samotný zápis do súboru využíva oba
iterátory, i aj j. Vnorené cykly budeme v geoinformatickej praxi využívať najmä na testovanie
rozličných nastavení algoritmov, kde môžeme relatívne pohodlne zostaviť, napríklad, skript
na testovanie nastavení interpolačnej funkcie spline, kde budeme meniť parameter tenzie a
parameter minimálneho počtu bodov vstupujúcich do výpočtu.
V ďalšom príklade zostavíme prostredníctvom vnoreného cyklu binárnu maticu, ktorá bude
nadobúdať hodnoty 0 a len na svojej diagonále bude nadobúdať hodnoty 1. Výsledok
zapíšeme do súboru bin_matica.txt. Výsledok by mal vyzerať nasledovne.
1 0 0 0 0 0 0
0 1 0 0 0 0 0
0 0 1 0 0 0 0
0 0 0 1 0 0 0
0 0 0 0 1 0 0
0 0 0 0 0 1 0
0 0 0 0 0 0 1
Postup práce bude nasledovný:
1. Otvoríme súbor bin_matica.txt v móde na zápis.
2. Vytvoríme telo cyklu, ktorý bude zabezpečovať výpis riadkov.
3. Vytvoríme telo cyklu, ktorý bude zabezpečovať výpis stĺpcov.
4. Definujeme zápis, ktorý bude v prípade, že je hodnota riadka a hodnota stĺpca totožná,
zapisovať hodnotu 1, v opačnom prípade hodnotu 0.
5. Uzatvoríme súbor bin_matica.txt.
f = open('bin_matica.txt', 'w')
# otvorenie suboru matica.txt len na citanie
for i in range(1,8):
for j in range(1,8):
if i ==j:
f.write("1 ")
# v pripade, ze cislo riadka je totozne s cislom stlpca
zapiseme 1
28
else:
f.write("0 ")
# v pripade, ze cislo riadka nie je totozne s cislom
stlpca zapiseme 0
f.write("\n")
f.close()
# uzatvorenie suboru mena.txt
V tomto príklade sme v podstate len zmenili skript z predošlého príkladu a pridali k nemu
podmienku, ktorá testuje, či je číslo riadka totožné s číslom stĺpca. V prípade že áno, zapíše sa
1, v opačnom prípade sa zapíše 0.
3.6.2 Cykly s nedefinovaným počtom opakovaní
Doteraz sme využívali len cykly s vopred definovaným počtom opakovaní. Ako bolo
spomínané na začiatku, okrem tohto druhu cyklu existuje aj cyklus s nedefinovaným počtom
opakovaní, kde je počet opakovaní obmedzený podmienkou, ktorá ak nie je splnená, cyklus
skončí. V jazyku Python pre tento zámer slúži príkaz while.
while podmienka:
ukon
Prvý riadok funkcie sa skladá z pevnej časti while a časti premenlivej, ktorá je ukončená
dvojbodkou. V prípade, že sa tu dvojbodka nenachádza, príkaz je považovaný za chybný. V
premenlivej časti definujeme podmienku, ktorá musí byť platná. Druhý riadok obsahuje úkon,
alebo úkony, ktoré sa v každom opakovaní cyklu vykonajú. Tento riadok musí byť
nevyhnutne odsadený podľa podmienok uvedených v kapitole 3.5 Podmienky. V prípade, že
podmienka bude vždy platná, cyklus bude pokračovať donekonečna, preto je potrebné byť pri
zadávaní podmienok opatrný.
V ďalšom príklade budeme simulovať ročný nárast platu zamestnanca vo firme Čokoládovne
a.s., ktorý k svojmu základnému nástupnému mesačnému platu 650€, bude získavať ročné
zvýšenie platu vždy podľa vzorca:
zvýšenia_platu [€] = odpracované_roky * 27
Zamestnanec tvrdí, že keď bude jeho mesačný plat 1020 €, odíde z firmy a založí si živnosť.
Budeme simulovať, kedy sa to stane, a aký bude jeho každoročný mesačný plat. Postup práce
bude nasledovný:
1. Vytvoríme premennú roky, ktorej priradíme hodnotu 0 a premennú plat, ktorej
priradíme hodnotu 560.
2. Vytvoríme telo cyklu, ktorý bude prebiehať až dovtedy, kým mesačný plat
zamestnanca nebude aspoň 1020 €.
3. Definujeme premennú, ktorá bude počítať odpracované roky.
4. Definujeme zápis, ktorý bude vypisovať každoročný plat zamestnanca.
5. Po ukončení cyklu vypíšeme na obrazovku, o koľko rokov bude mať zamestnanec plat
aspoň 1020 €.
roky = 0
# premennej roky priradenime hodnotu 0
plat = 560
29
# premennej plat priradime hodnotu 560, ktora reprezentuje
nastupny plat
while plat <1020:
# telo cyklu while s podmienkou
roky = roky + 1
# pocitadlo odpracovanych rokov
plat = plat +(roky*27)
# vypocet mesacneho platu
print "Mesacny plat po %i roku je %i eur" %(roky, plat)
# vypis poctu rokov vo firme a mesacneho platu zamestnanca
print "Zamestnanec odide o %i rokov" %(roky)
# vypis poctu rokov,kedy zamestnanec odide
V tomto prípade sme zabezpečili, že podmienka nebude vždy platná, preto nedôjde k vzniku
nekonečného cyklu.
3.7 Zoznamy
Zoznam môžeme definovať ako n-ticu prvkov (premenných alebo konštánt). Príkladom
zoznamu môže byť n-tica čísel, napr. [12, 13, 14, 18, 4, 5, 6]. Jednotlivé prvky v zozname je
možné meniť. Pre bežného používateľa, ktorý nemá znalosti z oblasti programovania, nemá
zoznam hodnôt prílišný význam, avšak, pre vývojárov ide o prvok jazyka, ktorý je bežne a
početne využívaný. Dobrým príkladom použitia je súbor, ktorý obsahuje v riadkoch mená
osôb a počet týchto mien (počet riadkov) je neznámy. Nevieme teda, koľko premenných si
máme pripraviť pred čítaním tohto súboru. Môžeme si však pripraviť zoznam, do ktorého
budeme tieto mená postupne pridávať. Najjednoduchším spôsobom vytvorenia zoznamu je
jeho enumerácia (vymenovanie), kde premennej priradíme hodnoty.
zoznam1 = []
# vytvorenie prazdneho zoznamu
zoznam1 = [1,15,12,14,75,8,4]
# vytvorenie zoznamu s hodnotami
V tomto prípade sme vytvorili zoznam s názvom zoznam1, ktorý bol prázdny. Následne sme
mu priradili hodnoty 1, 15, 12... Ide o zoznam typu integer, pretože všetky hodnoty v ňom sú
typu celého čísla. Ak dáme zoznam vypísať prostredníctvom príkazu print, zobrazí sa nám
celý jeho výpis.
zoznam1 = [1,2,3,4,5,6,7]
print zoznam1
[1,2,3,4,5,6,7]
# zoznam celých čísel
zoznam2 = ["janko", "misko", "ferko"]
print zoznam2
['janko', 'misko', 'ferko']
# zoznam znakovych premennych
30
Zoznam ako premenná sa javí ako jeden celok. Čo však v prípade, že chceme zobraziť (alebo
použiť) len vybraný prvok zo zoznamu? Využívame takzvané indexovanie, čo znamená, že
každá pozícia v zozname má svoj poradový identifikátor, ktorý je unikátny (Obrázok 14).
Obrázok 14. Ukážka indexovania zoznamu, kde je evidentné, že indexovanie začína zľava
doprava od hodnoty 0.
Indexovanie zoznamu začína vždy zľava a začína pozíciou 0, pokračuje pozíciou 1, atď. V
prípade, že chceme využiť len jednu hodnotu zo zoznamu, využívame nasledujúci príkaz.
zoznam1 = [1,2,3,4,5,6,7]
print zoznam1 [1]
2
print zoznam1 [3]
4
Pre potreby sofistikovanejšej práce so zoznamom využívame funkcie integrované v jazyku
Python. Ukážeme si to na príklade funkcie len(), ktorá vracia dĺžku parametra zadaného
medzi okrúhle zátvorky (v tomto prípade zadáme názov zoznamu).
zoznam1 = [1,52,34,4,5,46,17]
print len(zoznam1)
7
V tomto prípade sa výsledok funkcie vypíše na obrazovku, ale je možné priradiť ho aj do
premennej a naďalej používať. V súčasnosti existuje skutočne široké spektrum funkcií na
prácu so zoznamom, avšak, v tomto texte sa im nebudeme venovať.
Mnohé funkcie implementované v jazyku Python pracujú so zoznamom poloautomaticky a
dokážu sa v ňom samé pohybovať. Dobrým príkladom je cyklus for. V prípade, že chceme
aby iterátor nadobúdal hodnoty, ktoré nie sú v logickej postupnosti, využijeme práve zoznam.
zoznam = [1,52,34]
for i in zoznam:
print i
1
52
34
V tomto prípade sme cyklu for zadali len názov premennej (zoznamu) a cyklus sám pochopil,
že v každom kroku má využiť vždy pozíciu s vyšším indexom. V prvom kroku za iterátor teda
zvolil pozíciu 0 v zozname, ktorá nadobúda hodnotu 1, v druhom kroku za iterátor zvolil
pozíciu 1 v zozname, ktorá nadobúda hodnotu 52 a v kroku treťom za iterátor zvolil pozíciu 2,
ktorá nadobúda hodnotu 34. Následne sa cyklus automaticky ukončil.
31
3.8 Funkcie
Funkcie v programovacom jazyku sú časti kódu, ktoré možno opakovane spúšťať
prostredníctvom ich zavolania. Vo všeobecnosti je funkcia časť zdrojového kódu, ktorá
vykonáva nejakú konečnú činnosť (počíta faktoriál, kreslí štvorec) a vracia výsledok
(faktoriál, nakreslený štvorec). Zdrojový kód funkcie sa skladá z dvoch častí:
1. Definovanie funkcie – časť zdrojového kódu, kde zapíšeme funkciu má nasledovnú
štruktúru.
def nazov (parametre):
zdrojovy_kod
return vystupna_premenna
Pri tvorbe vlastnej funkcie v jazyku Python začíname kľúčovým slovom def, za
ktorým nasleduje medzera a názov funkcie. Pre názvy funkcií platia rovnaké pravidlá
ako pre názvy premenných, teda nesmú obsahovať medzery, diakritiku a musia byť
odlišné od príkazov v jazyku Python. Za názvom funkcie nasledujú okrúhle zátvorky,
v ktorých sú uvedené parametre (argumenty, vstupné premenné) funkcie a dvojbodka,
ktorá je povinným znakom. Časť za dvojbodkou sa označuje ako telo funkcie a
nachádzajú sa tam príkazy, ktoré sa vykonávajú po zavolaní funkcie. Tieto musia byť
odsadené rovnako, ako v prípade podmienok a cyklov. Kľúčové slovo return na
poslednom riadku deklaruje, akú hodnotu má funkcia vrátiť (výstupnú premennú z
funkcie). Ukážku definovania jednoduchej funkcie vidíme na nasledovnom príklade.
def stvorec(n):
n2 = n*n
return n2
# funkcia s nazvom stvorec vypocita druhu mocninu zadanej
hodnoty
V tomto prípade funkcia s názvom stvorec vráti hodnotu vypočítanej druhej mocniny
parametra.
2. Volanie funkcie – časť zdrojového kódu, ktorou voláme funkciu, ktorá je v kóde už
definovaná. Volanie funkcie má nasledovnú štruktúru.
nazov(vstupne_premenne)
Vyššie definovanú funkciu stvorec voláme prostredníctvom nasledovného zápisu.
print stvorec(4)
16
# po zavolani funkcie s parametrom 4 sa vrati ako vysledok
hodnota 16
Funkcia nemusí mať žiadne parametre, aj v tomto prípade sa však povinne uvádzajú prázdne
okrúhle zátvorky, ktoré vyjadrujú, že sa jedná o funkciu.
def prezident():
return 'Kiska'
# funkcia na zistenie mena sucasneho prezidenta
print prezident()
Kiska
Funkcia dokonca nemusí vracať žiadnu hodnotu, môže len vykonávať určitú činnosť:
def pozdrav(meno):
32
print ('Ahoj ' + meno + ', ako sa máš?')
pozdrav('Mirka')
Ahoj Mirka, ako sa mas? V rámci funkcie môžeme volať akékoľvek funkcie jazyka Python, ako aj vlastné funkcie:
def pozdravPrezidenta():
print ('Ahoj ' + prezident() + ', ako sa máš?')
# v tele funkcie sa zavolá funkcia prezident(), ktora vracia
meno sucasneho prezidenta
pozdravPrezidenta()
Ahoj Kiska, ako sa máš? Funkcie sú veľmi častým prvkom najmä komplikovanejších skriptov, ktoré zrýchľujú, a
najmä zjednodušujú proces tvorby skriptu. Avšak, pre začínajúceho programátora môžu (ale
nemusia) pôsobiť priveľmi komplikovane. V ďalšom texte preto nebudeme využívať vlastné
funkcie, iba funkcie jazyka Python a jeho knižníc (modulov).
3.9 Modulárna štruktúra jazyka Python
Ako bolo spomínané už vyššie, jazyk Python je modulárny, teda je možné ho rozširovať
prostredníctvom modulov (balíčkov, knižníc, packages, libraries...). Za balíček považujeme
skupinu funkcií, ktorá rozširuje základnú funkcionalitu jadra jazyka Python (Obrázok 15.).
Obrázok 15. Ukážka vzťahu medzi jadrom jazyka Python a modulmi. Inštalované moduly sa
nachádzajú v operačnom systéme, avšak sú neaktívne až do času použitia.
Všetky používané moduly musia byť inštalované v rámci používaného operačného systému, v
rámci ktorého je vytvorený ich zoznam. V prípade, že chceme využiť akýkoľvek nástroj z
33
jedného z týchto modulov, je nutné najprv modul importovať (aktivovať, vzbudiť). Toto
uskutočníme prostredníctvom príkazu import.
import numpy
# import knižnice numpy
import matplotlib
# import knižnice matplotlib
import os
# import knižnice os
Odporúča sa importovať len tie moduly, ktoré sú v skripte aj reálne využívané, pretože import
každej knižnice zaberá nejaký čas, čo spomaľuje beh samotného skriptu. Časovo náročný je,
napríklad, import modulu arcpy, ktorý slúži na prácu s priestorovými údajmi. V súčasnosti
existuje niekoľko stoviek bežne používaných modulov, pričom každý z nich sa skladá z
niekoľkých desiatok nástrojov. V prípade, že chceme knižnicu využívať, je nevyhnutné si
overiť, či je korektne nainštalovaná.
4. Priestorová analýza prostredníctvom knižnice ArcPy
Prvou knižnicou, s ktorou sa v rámci tohto textu bližšie zoznámime, bude knižnica ArcPy. Je
súčasťou prostredia ESRI ArcGIS 10.X. Samotná knižnica umožňuje prostredníctvom jazyka
Python ovládať základnú funkcionalitu prostredia ArcGIS 10.X, najmä ArcToolbox. Môžeme
si ju predstaviť najmä ako komunikačný nástroj. Takmer každý nástroj v ArcToolbox-e je
možné ovládať práve prostredníctvom tejto knižnice. Ponúka však aj ďalšie funkcie na
zrýchlenie a zjednodušenie práce (napr., funkcie na tvorbu zoznamov vrstiev, polí v
atribútovej tabuľke, atď.). Hlavnou výhodou ovládania nástrojov ArcToolbox-u
prostredníctvom knižnice ArcPy je možnosť reťazenia a opakovaného použitia nástrojov, teda
automatizácia spracovania. Nie je problémom, napríklad, vytvorenie reťazca nástrojov, ktorý
vyčlení povodia na základe zvoleného digitálneho výškového modelu alebo cyklu, ktorý bude
tvoriť digitálne výškové modely s rôznymi nastaveniami parametrov interpolácie.
Pred použitím knižnice ArcPy je nevyhnutné ju importovať (vždy, keď nanovo spustíme
ArcMap a okno Python Window). Proces importu zabezpečuje príkaz na import modulov:
import arcpy
# import knižnice ArcPy
Modul v jazyku Python je súbor, ktorý obsahuje funkcie a triedy. Knižnica ArcPy obsahuje
viacero modulov, medzi najdôležitejšie patrí modul Mapping (arcpy.mapping) na tvorbu
mapových výstupov, modul Spatial Analyst (arcpy.sa) na prácu s rastrami a modul
Geostatistical Analyst (arcpy.ga) na geoštatistické analýzy. Niektoré moduly nepodliehajú
základnej licencii ArcGIS Desktop, preto je v prípade problémov s importom potrebné overiť
dostupnosť licencie na ich používanie. Takisto je potrebné mať zapnuté príslušné rozšírenie.
Moduly môžeme importovať viacerými spôsobmi. Výhodné je použiť príkaz from-import-*,
ktorý umožňuje použitie funkcií a podmodulov príslušného modulu bez nutnosti písania
predpony s názvom modulu a najmä bez nutnosti importu celého modulu ArcPy, ale len jeho
časti:
from arcpy import sa
# import modulu Spatial Analysis – prvý spôsob
# musíme písať predponu
outRaster = (sa.Raster(inRaster1) + sa.Raster(inRaster2))
34
from arcpy.sa import *
# import modulu Spatial Analysis – druhý spôsob
# nemusíme písať predponu
outRaster = (Raster(inRaster1) + Raster(inRaster2))
Knižnica ArcPy obsahuje jednak geoprocesné nástroje dostupné aj v ArcToolbox-e a jednak
vlastné funkcie. Z hľadiska používateľa, rozdiel medzi nimi spočíva v tom, že sú odlišne
dokumentované a majú odlišnú syntax. Dokumentáciu ku geoprocesným nástrojom nájdeme v
ArcGIS Desktop Help systéme (dostupný aj online), kde má každý nástroj svoju referenčnú
stránku (Obrázok 16.). Referenčná stránka obsahuje základný popis nástroja, podrobné
informácie o použití nástroja, popis vstupných a výstupných parametrov nástroja, ako aj
ukážku syntaxe a príklad použitia kódu. Dokumentácia k ostatným nástrojom je súčasťou
dokumentácie knižnice ArcPy, ktorá je takisto súčasťou ArcGIS Desktop Help systému.
Ďalším rozdielom medzi geoprocesnými a vlastnými funkciami ArcPy je v tom, že
geoprocesné nástroje sú licencované úrovňou produktu (ArcGIS Desktop Basic, Standard,
Advanced) a rozšíreniami, podobne ako v ArcToolbox-e, kým funkcie sú nainštalované spolu
s ArcPy sú vždy prístupné bez obmedzenia.
Obrázok 16. Ukážka základných častí Pomocníka pre ľubovoľný nástroj z ArcGIS Toolbox.
Počas práce s nástrojmi ArcPy netreba zabúdať na nasledujúce fakty:
1. Knižnica ArcPy umožňuje len komunikáciu s prostredím ArcGIS (najmä
ArcToolbox), teda takmer všetky limitácie nástrojov ArcToolbox sa budú prejavovať
aj v tomto prípade.
2. Pozor na prepisovanie už raz zapísaných dát, teda v prípade opakovaného spustenia
toho istého skriptu dôjde k prepísaniu už existujúcich dát. Platí len v prípade, že
máme povolenú možnosť prepisu dát (v menu Geoprocessing/Geoprocessing
options/Overwrite the outputs of geoprocessing operations–Enable).
3. Niektoré skupiny nástrojov (napr. Spatial Analyst) sú samostatne licencované, teda
treba si overiť, či má používateľ túto licenciu zakúpenú a aktivovanú (v menu
Customize/Extensions...).
35
V prípade, že chceme v rámci modulu ArcPy využiť nástroj, s ktorým sme ešte nepracovali,
odporúčame nasledujúci postup:
1. Zistenie názvu nástroja. Tento krok býva v rámci riešenia problému
najkomplikovanejší, vzhľadom na široké spektrum nástrojov v prostredí ArcGIS. V
tomto prípade je vhodné využiť vyhľadávanie prostredníctvom internetu alebo
využitie okna Search v prostredí ArcGIS (Obrázok 17.). To nám po zadaní kľúčových
slov ponúkne nástroj alebo niekoľko nástrojov, ktoré sú k týmto slovám asociované.
Obrázok 17. Ukážka okna Search v prostredí ArcGIS 10.X.
2. Oboznámenie sa s podrobným popisom nástroja v okne Pomocníka alebo
prostredníctvom online Pomocníka.
3. Oboznámenie sa so vstupmi do nástroja. Vo všeobecnosti rozoznávame povinné a
voliteľné vstupy. Ako ich názvy napovedajú, povinné vstupy sú nevyhnutné na beh
modulu a voliteľné vstupy ponúkajú len viac možností nastavenia, ktoré ak používateľ
nenastaví, automaticky sa nastavia prednastavené (default) hodnoty. Povinné
parametre sú bez zátvoriek, voliteľné sú uvedené v hranatých zátvorkách. Samotná
tabuľka, popisujúca vstupy ponúka aj exaktné definovanie typu vstupu (Data type),
vďaka ktorému vieme, aký druh vstupu je možné v nastavení využiť. Počas
zostavovania skriptu je nevyhnutné sa vždy uistiť, že používame správny druh vstupu.
4. Preštudovanie výstupov z modelu. V mnohých prípadoch je výstupom z modelu len
záverečná správa (Log) alebo tabuľka (Table), ktorým treba venovať zvláštnu
pozornosť.
5. Preštudovanie samotného zdrojového kódu uvedeného v časti s príkladmi (Code
samples). V prípade začínajúcich používateľov, odporúčame tento kód kopírovať do
vlastného skriptu a tu ho vhodne upraviť.
V prípade, že sme sa oboznámili s vlastnosťami nástroja, ktorý chceme využívať, zameráme
sa na samotné zostavenie skriptu. Je potrebné si uvedomiť, že knižnica ArcPy (ako akákoľvek
iná knižnica v jazyku Python) má špecifickú syntax a vlastnosti, ktoré nie sú vždy totožné s
vlastnosťami samotného jadra jazyka Python. Geoprocesné nástroje sa spúšťajú cez
všeobecnú syntax arcpy.toolname_toolboxalias(), pričom do zátvorky sa zadávajú vstupné a
výstupné parametre nástroja. Parametre musíme zadávať v predpísanom poradí, tak ako je
36
definované v Help súbore. Ak nepovinné parametre nechceme zadať, nemôžeme ich
vynechať, ale musíme namiesto toho uviesť prázdny reťazec (""). Dôležité je uvedomiť si,
akého typu je príslušný parameter. V prípade, že vstupným parametrom je číslo, zadávame ho
bez ohraničenia úvodzovkami. V prípade, že vstupným parametrom je znakový reťazec, tento
ohraničujeme jednoduchými alebo dvojitými úvodzovkami. Ak je vstupným alebo výstupným
parametrom vrstva, zadávame celú cestu k nej spolu s jej názvom a príponou, celé ohraničené
úvodzovkami. Pri zadávaní vstupov môžeme využiť aj pomôcku v okne Python Window,
ktoré ponúka ako vstupy vrstvy v práve otvorenom projekte (Obrázok 18.).
Obrázok 18. Ukážka okna Python spolu s pomôckou s práve otvorenými vrstvami.
Ukážeme si príklad skriptu na spustenie geoprocesného nástroja Buffer_analysis, ktorý
vytvára vzdialenostné zóny okolo prvkov vektorovej vrstvy. Nástroj Buffer_analysis má tri
povinné parametre – vstupnú triedu prvkov, výstupnú triedu prvkov a vzdialenosť. Ak sa
pozrieme do dokumentácie k tomuto nástroju, môžeme vidieť, že okrem troch povinných
parametrov, môžeme zadať aj voliteľné parametre:
Buffer_analysis (in_features, out_feature_class, buffer_distance_or_field, {line_side},
{line_end_type}, {dissolve_option}, {dissolve_field})
Voliteľné parametre, uvedené v hranatých zátvorkách, umožňujú zvoliť, na ktorej strane línie
chceme vytvoriť vzdialenostnú zónu (line_side), ako má byť tvarovaná zóna na konci línie
(line_end_type), či sa majú zóny okolo jednotlivých prvkov zlúčiť (dissolve_option),
prípadne, na základe ktorého poľa v atribútovej tabuľke majú byť zlúčené (dissolve field).
Možnosti a predvolené hodnoty jednotlivých parametrov takisto nájdeme v dokumentácii. V
nasledovnom príklade si ukážeme tvorbu vzdialenostných zón po oboch stranách ciest do
vzdialenosti 100 metrov.
import arcpy
arcpy.Buffer_analysis("C:/py/cesty.shp", "C:/py/buffer1.shp",
"100 Meters")
Prvý riadok kódu zabezpečuje import modulu arcpy a druhý riadok priamo spúšťa modul
Buffer_analysis. Ďalší príklad ukazuje tvorbu vzdialenostných zón po oboch stranách ciest do
vzdialenosti 100 metrov so zlúčením zón do jedného prvku.
import arcpy
arcpy.Buffer_analysis("C:/py/cesty.shp", "C:/py/buffer2.shp",
"100 Meters","FULL","","ALL","")
37
Na vyššie uvedenom príklade sme si ukázali spôsob spúšťania nástrojov ArcToolbox-u
pomocou knižnice ArcPy. Ak je výsledkom nástroja priestorová vrstva, ako je tomu,
napríklad, pri nástrojoch balíka Spatial Analyst, použijeme nasledovný spôsob.
import arcpy
from arcpy.sa import *
objekt = NaturalNeighbor("c:/vyska.shp ", "Z", 2)
# skript, ktoreho vysledkom je rastrova vrstva reprezentovana
ako objekt
objekt.save("C:/dtm.tif")
# ulozenie objektu vo formate "tiff"
V tomto prípade v parametroch nástroja NaturalNeighbor nezadávame cestu k výstupnej
vrstve, ale namiesto toho tento nástroj výstupnú vrstvu vracia ako objekt. Tento objekt najprv
uložíme do premennej a v ďalšom riadku kódu použijeme funkciu save() na uloženie objektu
vo formáte tiff na určené miesto na disku. V prípade, že žiadnu príponu nezadáme, súbor sa
uloží vo formáte ESRI Grid.
4.1 Práca s vektorovými vrstvami
Skriptovanie pomocou jazyka Python významne uľahčuje prácu s vektorovými vrstvami v
prostredí ArcGIS, najmä ak sa jedná o dávkové (hromadné) spracovanie údajov, alebo
zložitejšie operácie, vyžadujúce podmienkovú logiku.
Spracovanie vektorových údajov si ukážeme na príklade odhadu negatívneho vplyvu
hlučnosti a znečistenia ovzdušia v okolí ciest na škôlky, školy a nemocnice v okrese Banská
Bystrica. Budeme mať k dispozícii vstupné vrstvy ciest, budov a hranice okresu Banská
Bystrica. Postup bude pozostávať z týchto hlavných krokov:
1. Tvorba vzdialenostných zón okolo ciest prostredníctvom nástroja Buffer.
2. Výber škôl, škôlok a nemocníc z vrstvy budov prostredníctvom nástroja Select.
3. Orezanie výsledných vrstiev podľa hraníc okresu Banská Bystrica prostredníctvom
nástroja Clip.
4. Priestorový prekryt vybraných budov so vzdialenostnými zónami prostredníctvom
nástroja Intersect.
Prvým krokom bude vytvorenie vzdialenostných zón okolo ciest. V príklade uvedenom vyššie
sme si ukázali použitie nástroja Buffer_analysis(). Tento istý nástroj použijeme v cykle na
vytvorenie zón v rôznych vzdialenostiach od ciest.
import arcpy
distList = [50,100,250]
# vytvorenie zoznamu vzdialenosti
for dist in distList:
distString = "%s Meters" % dist
outPath = "C:/py/data/buffer%s.shp" % dist
arcpy.Buffer_analysis("C:/py/cesty.shp", outPath,
distString,"FULL","","ALL","")
V prvom kroku si vytvoríme zoznam vzdialeností, ktorým budeme prechádzať v cykle for.
V samotnom tele cyklu si najprv musíme pripraviť dve premenné, ktoré budú vstupovať do
38
nástroja Buffer_analysis(). Keďže parameter vzdialenosti sa zadáva ako textový reťazec aj s
uvedením jednotiek, tento parameter si predpripravíme pomocou formátovania reťazcov a
uložíme ho do premennej distString. Pri spúšťaní geoprocesných nástrojov v cykle je dôležité
zabezpečiť, aby sa pri jednotlivých spusteniach neprepisovali výsledné vrstvy. Pre tento
zámer si vytvoríme premennú outPath, predstavujúcu cestu k výstupnej vektorovej vrstve, v
ktorej sa bude meniť hodnota vzdialenosti. Výsledkom skriptu budú tri vektorové vrstvy s
názvami buffer50.shp, buffer100.shp a buffer250.shp.
V druhom kroku je potrebné z vektorovej vrstvy budov vybrať všetky školy, škôlky
a nemocnice a uložiť ich do samostatnej vrstvy. Použijeme na to nástroj Select_analysis(),
ktorý slúži na atribútové výbery (dopyty).
arcpy.Select_analysis("C:/py/budovy.shp",
"C:/py/data/budovyVyber.shp",""" "typ" IN ('skola', 'skolka',
'nemocnica') """)
Povinnými vstupnými parametrami nástroja Select_analysis() je názov vstupnej vrstvy, názov
výstupnej vrstvy a SQL výraz s podmienkou výberu. Pri zadávaní podmienky sú názvy polí
(stĺpcov) atribútovej tabuľky ohraničené dvojitými úvodzovkami a textové reťazce sú
ohraničené jednoduchými úvodzovkami. Samotná podmienka je ako celok ohraničená tromi
dvojitými úvodzovkami. Pri výbere sme použili operátor IN, ktorý umožňuje porovnanie
s viacerými hodnotami (oproti tomu operátor = dovoľuje porovnávanie iba s jednou
hodnotou). V tomto prípade porovnávame hodnoty v stĺpci typ v atribútovej tabuľke s tromi
textovými reťazcami (stĺpec typ vo vrstve budovy.shp obsahuje informácie o druhu budovy).
Ak budova patrí do jedného z troch typov, uloží sa do výslednej vrstvy.
V treťom kroku orežeme vytvorené vektorové vrstvy budov a vzdialenostných zón podľa
hraníc okresu Banská Bystrica. Na tomto príklade si ukážeme použitie listovacej funkcie
knižnice ArcPy. Listovacia funkcia ListFeatureClasses() vracia zoznam všetkých vrstiev v
pracovnom adresári. Vytvoreným zoznamom budeme následne prechádzať v cykle for pri
orezávaní vrstiev.
arcpy.env.workspace = "C:/py/data"
# nastavenie pracovneho adresara
fcList = arcpy.ListFeatureClasses()
# vytvorenie zoznamu vrstiev v pracovnom adresari a ulozenie
do premennej
print fcList
[u'budovyVyber.shp', u'buffer50.shp', u'buffer100.shp',
u'buffer250.shp]
for inFC in fcList:
outFC = inFC.strip('.shp') + "BB.shp"
arcpy.Clip_analysis(inFC, "C:/py/okresBB.shp", outFC)
# prechadzanie zoznamom a orezanie vrstiev v cykle
V tomto prípade sa stretávame s pracovným adresárom, čo je priestor na disku, z ktorého
program predvolene číta a zapisuje dáta. V prípade, že používame pracovný adresár, nie je
nutné definovať celé cesty k vrstvám. Pracovný adresár nastavíme pomocou premennej
arcpy.env.workspace. Funkcia ListFeatureClasses() potom vráti zoznam všetkých vrstiev v
adresári, ktorý je v našom prípade priradený do premennej fcList. Ako môžeme vidieť,
zoznam obsahuje názvy jednotlivých vrstiev v podobe textových reťazcov (pred každým
39
reťazcom je písmeno u, ktoré znamená, že sa jedná o reťazec typu Unicode). Takto vytvorený
zoznam môžeme použiť pri akomkoľvek dávkovom spracovaní vektorových vrstiev pomocou
geoprocesných nástrojov. V našom príklade vrstvy orezávame podľa hraníc okresu Banská
Bystrica. Orezanie vrstiev v knižnici ArcPy zabezpečuje nástroj Clip_analysis(), ktorý má tri
povinné parametre v poradí vstupná vrstva, vrstva, podľa ktorej orezávame a výstupná vrstva.
Názov výstupnej vrstvy vytvoríme pridaním písmen BB za názov vstupnej vrstvy. Keďže
súčasťou názvu je aj prípona .shp, musíme najprv túto príponu odstrániť funkciou strip()
a následne pripojiť textový reťazec „BB.shp“. Výsledkom tretieho kroku teda budú štyri
orezané vrstvy s názvami budovyVyberBB.shp, buffer50BB.shp, buffer100BB.shp
a buffer250BB.shp
V poslednom, štvrtom kroku, urobíme priestorový prekryt vybraných budov so
vzdialenostnými zónami. V prostredí GIS je štandardným nástrojom na prekrytie dvoch
vrstiev nástroj Intersect. V knižnici ArcPy ho nájdeme pod názvom Intersect_analysis() a má
dva povinné parametre, zoznam vstupných vektorových vrstiev a názov výstupnej vektorovej
vrstvy. Zoznam sa rovnako ako v jadre jazyka Python ohraničuje hranatými zátvorkami.
Priestorový prekryt urobíme pre všetky tri vzdialenostné zóny, takže opäť využijeme cyklus:
for dist in distlist:
inFC = ["budovyVyberBB.shp", "buffer%sBB.shp" % dist]
outFC = "budovy%s.shp" % dist arcpy.Intersect_analysis(inFC,outFC)
V cykle postupne vybrané budovy prekryjeme s každou vdialenostnou zónou. Výsledkom
budú tri vrstvy budovy50.shp, budovy100.shp a budovy250.shp, obsahujúce školy, škôlky a
nemocnice do 50, do 100 a do 250 m od ciest v okrese Banská Bystrica. Tieto budovy môžu
byť potenciálne ovplyvnené znečistením ovzdušia a hlučnosťou a deťom, študentom
a pacientom v nich môže hroziť potenciálne zdravotné riziko.
Na vyššie uvedených príkladoch sme si ukázali základné analytické nástroje na prácu
s vektorovými vrstvami Select, Buffer, Clip a Intersect a vysvetlili sme princípy dávkového
spracovania vektorových údajov v cykloch.
4.2 Práca s rastrovými vrstvami
V predchádzajúcej kapitole sme sa oboznámili s využitím jazyka Python a knižnice ArcPy pre
potreby práce s vektorovými priestorovými dátami. V tejto kapitole sa zameráme na prácu s
rastrovými dátami. Kapitola sa sústreďuje na využitie skupiny nástrojov Spatial Analyst, ktorá
je zameraná na priestorovú analýzu s vrstvami dát v rastrovom formáte.
V nasledujúcom príklade zostavíme skript, ktorý spustí interpoláciu digitálneho výškového
modelu prostredníctvom algoritmu idw.
import arcpy
from arcpy.sa import *
# import kniznice arcpy a modulu Spatial Analyst
outIDW = Idw("C:/vector/body.shp", "Z", 2, 2,
RadiusVariable(10, 150))
# spustenie interpolacie a vytvorenie rastrovej vrstvy vo
forme objektu
outIDW.save("C:/raster/dtm.tif")
40
# ulozenie vyslednej rastrovej vrstvy vo formate TIF
Vstupná vektorová vrstva sa v tomto prípade volá body.shp a nachádza sa v priečinku vector,
umiestnenom priamo na disku C. Názov stĺpca v tabuľke atribútov s hodnotou nadmorskej
výšky je Z a rozlíšenie výstupnej rastrovej vrstvy (výstupného digitálneho výškového modelu)
sú 2 metre. Exponent vzdialenosti je nastavený na hodnotu 2. Využitou metódou
vyhľadávania okolitých bodov je RadiusVariable s minimálnym počtom bodov 10 a
maximálnym vyhľadávacím okolím 150 jednotiek vzdialenosti. Výslednou rastrovou vrstvou
bude dtm.tif. V tomto prípade sme spustili len jeden modul z knižnice ArcPy. Tento postup je
adekvátny tomu, ak by sme spustili jeden modul prostredníctvom grafického rozhrania.
V nasledujúcom príklade vytvoríme skript, ktorý vytvorí 8 rastrov (8 digitálnych výškových
modelov), ktoré budú všetky vytvorené prostredníctvom interpolačnej funkcie IDW, pričom
exponent vzdialenosti bude nadobúdať hodnoty (0.1, 0.3, 0.4, 0.6, 0.7 , 1, 1.3, 1.5 ). Postup
práce bude nasledovný:
1. Vytvorenie zoznamu reprezentujúceho hodnoty exponentu vzdialenosti, ktoré budeme
využívať pre interpoláciu.
2. Vytvorenie cyklu, ktorý bude meniť exponent vzdialenosti.
3. Interpolácia prostredníctvom algoritmu IDW.
4. Zápis výslednej rastrovej vrstvy s názvom dtm_10.
5. Opakovanie bodov 3 a 4 ďalších 7-krát.
import arcpy
from arcpy.sa import *
# import kniznice arcpy a modulu Spatial Analyst
p = [0.1, 0.3, 0.4, 0.6, 0.7 , 1, 1.3, 1.5 ]
# vytvorenie zoznamu p, ktore obsahuje hodnoty exponentov
vzdialenosti
for pow in p:
# vytvorenie cyklu zabezpecujuceho pohyb po zozname "p"
objekt = Idw("C:/arcpy/body.shp", "ELEVATION", 2000, pow,
RadiusVariable(10,200))
# vytvorenie vrstvy a ulozenie do podoby objektu
objekt.save("C:/arcpy/raster/dtm_%i.tif" %(pow*10))
# ulozenie objektu do podoby rastrovej vrstvy
V tomto prípade využívame fakt, že cyklus for sa dokáže automaticky posúvať po zozname.
V prípade, že iterátor (v našom prípade pow) využívame v zápise funkcie ArcPy, je
nevyhnutné pamätať na formát tohto iterátora, pretože niektoré parametre si vyžadujú len
textové vstupy, a niektoré len číselné vstupy. Iterátorom je v tomto prípade desatinné číslo.
Pri ukladaní novej rastrovej vrstvy je nevyhnutné pamätať na zmenu názvu vrstvy počas
každej iterácie, aby nedochádzalo k prepisovaniu vždy tej istej výstupnej vrstvy. V prípade, že
by sme nechali zapísať priamo iterátor do názvu, došlo by k ukončeniu skriptu, pretože názov
rastrovej vrstvy nesmie obsahovať znak bodky. Preto iterátor násobíme číslom 10 a až
následne používame v názve výstupnej vrstvy. Vo vyššie uvedenom prípade sme spustili len
jeden nástroj ArcToolbox s ôsmimi odlišnými nastaveniami.
V ďalšom príklade zostavíme algoritmus na vytvorenie 20 rastrových vrstiev prostredníctvom
algoritmu Spline, pričom vrstvy budú nadobúdať 4 rozlíšenia rastra (1 m, 2 m, 3 m, 4 m) a 5
41
nastavení váhy (0.1, 0.2, 0.3, 0.4, 0.5). Je teda nutné zostaviť skript, ktorý bude generovať
všetky možnosti nastavenia týchto dvoch parametrov. Postup práce je nasledovný:
1. Vytvorenie zoznamu reprezentujúceho rozlíšenie rastra.
2. Vytvorenie zoznamu reprezentujúceho hodnoty váh.
3. Vytvorenie cyklu, ktorý bude meniť rozlíšenie rastra.
4. Vytvorenie cyklu, ktorý bude meniť hodnoty váh.
5. Interpolácia prostredníctvom algoritmu Spline.
6. Zápis výslednej rastrovej vrstvy s názvom dtm_1_10.
7. Opakovanie krokov 5 a 6 ďalších 19-krát.
import arcpy
from arcpy.sa import *
# import kniznice arcpy a modulu Spatial Analyst
rozlisenie = [1, 2, 3, 4]
# vytvorenie zoznamu "rozlisenie", ktore obsahuje hodnoty
rozliseni rastra
vaha = [0.1, 0.2, 0.3, 0.4, 0.5]
# vytvorenie zoznamu "vaha", ktory obsahuje hodnoty vah
for res in rozlisenie:
# vytvorenie cyklu zabezpecujuceho pohyb po zozname
"rozlisenie"
for wei in vaha:
# vytvorenie cyklu zabezpecujuceho pohyb po poli "vaha"
objekt = Spline("C:/arcpy/body.shp", "ELEVATION", res,
"REGULARIZED", wei)
# vytvorenie vrstvy a ulozenie do podoby objektu
objekt.save("C:/arcpy/raster/dtm_%i_%i.tif" %(res,
wei*10))
# ulozenie objektu do podoby rastrovej vrstvy
Vo svojej podstate ide len o vnorený cyklus, s ktorým sme sa už zoznámili v predošlých
kapitolách a využívali sme ho na zapisovanie matíc. V tomto prípade jeden cyklus
zabezpečuje pohyb po zozname rozlisenie a druhý cyklus pohyb po zozname vaha. Je nutné
zabezpečiť, aby výsledná rastrová vrstva mala v každom cykle vždy originálny názov.
V nasledujúcom príklade sa zameráme na vývoj algoritmu, ktorý zo vstupnej vektorovej
bodovej vrstvy nadmorskej výšky vygeneruje digitálny výškový model a odvodené polia
sklonu georeliéfu, orientácie georeliéfu voči svetovým stranám a normálovej krivosti v smere
dotyčnice k spádnici (profile curvature). Postup práce je nasledovný:
1. Interpolácia rastrovej vrstvy z vrstvy bodovej prostredníctvom nástroja Spline.
2. Vytvorenie rastrovej vrstvy sklonu prostredníctvom nástroja Slope.
3. Vytvorenie rastrovej vrstvy orientácie reliéfu voči svetovým stranám prostredníctvom
nástroja Aspect.
4. Vytvorenie krivosti georeliéfu v smere dotyčnice k spádnici prostredníctvom nástroja
Curvature.
42
import arcpy
from arcpy.sa import *
# import kniznice arcpy a modulu Spatial Analyst
outSpline = Spline("C:/arcpy/body.shp", "ELEVATION", 2,
"REGULARIZED", 0.1)
outSpline.save("C:/arcpy/raster/dtm")
# interpolacia dtm prostrednictvom algoritmu spline
outSlope = Slope("C:/arcpy/raster/dtm", "DEGREE")
outSlope.save("C:/arcpy/raster/slope")
# vypocet rastrovej vrstvy sklonu georeliefu
outAspect = Aspect("C:/arcpy/raster/dtm")
outAspect.save("C:/arcpy/raster/aspect")
# vypocet rastrovej vrstvy orientacie georeliefu voci svetovym
stranam
outCurve = Curvature("C:/arcpy/raster/dtm", 1,
"C:/arcpy/raster/prof_curv" )
# vypocet rastrovej vrstvy normalovej krivosti voci svetovym
stranam
Vyššie uvedený algoritmus je lineárny, teda nedochádza k vetveniu alebo opakovaniu
niektorých nástrojov s rozličným nastavením vstupných parametrov. Skript využíva najmä
nástroje knižnice Spatial Analyst, ktoré len vhodne radí za seba. V prvom kroku vygeneruje
digitálny výškový model na základe vstupnej bodovej vrstvy s názvom body.shp. Z
digitálneho výškového modelu sa následne generujú polia sklonu, orientácie voči svetovým
stranám a pole normálovej krivosti v smere dotyčnice k spádnici.
V ďalšom príklade zostavíme algoritmus, ktorý na základe vstupnej bodovej vrstvy vytvorí
vektorové vrstvy subpovodí. Následne tento algoritmus upravíme pre niekoľko nastavení
váhy interpolačnej funkcie Spline. Postup práce je nasledovný:
1. Interpolácia rastrovej vrstvy z vrstvy bodovej prostredníctvom nástroja Spline.
2. Hydrologická korekcia digitálneho výškového modelu prostredníctvom nástroja Fill.
3. Výpočet smerov odtoku prostredníctvom nástroja Flow direction.
4. Výpočet príspevkových plôch prostredníctvom nástroja Flow accumulation.
5. Reklasifikácia rastrovej vrstvy príspevkových plôch prostredníctvom nástroja
Reclassify, na základe čoho je možné zostaviť potenciálnu sieť vodných tokov.
Hranicou pre vznik potenciálneho vodného toku bude hodnota príspevkovej plochy
nad 1000 buniek.
6. Unikátne pomenovanie segmentov tokov prostredníctvom nástroja Stream Link.
7. Výpočet rastra povodí prostredníctvom nástroja Watershed.
8. Transformácia rastrovej vrstvy povodí na vektorovú vrstvu prostredníctvom nástroja
Raster to Polygon.
import arcpy
from arcpy.sa import *
# import kniznice arcpy a modulu Spatial Analyst
43
outSpline = Spline("C:/arcpy/body.shp", "ELEVATION", 5,
"REGULARIZED", 0.1)
outSpline.save("C:/arcpy/raster/dtm")
# interpolacia dtm prostrednictvom algoritmu spline
outFill = Fill("C:/arcpy/raster/dtm")
outFill.save("C:/arcpy/raster/dtm_fill")
# hydrologicka korekcia vstupneho digitalneho vyskoveho modelu
outFlowDirection = FlowDirection("C:/arcpy/raster/dtm_fill",
"NORMAL")
outFlowDirection.save("C:/arcpy/raster/flow_dir")
# vypocet smerov odtoku
outFlowAccumulation =
FlowAccumulation("C:/arcpy/raster/flow_dir")
outFlowAccumulation.save("C:/arcpy/raster/flow_acc")
# vypocet rastrovej vrstvy prispevkovych ploch
outReclass2 = Reclassify("C:/arcpy/raster/flow_acc", "Value",
RemapRange([[0,1000,"NODATA"],[1000,22000,1]]))
outReclass2.save("C:/arcpy/raster/fl_acc_rec")
# reklasifikacia rastrovej vrstvy prispevkovych ploch
outStreamLink = StreamLink("C:/arcpy/raster/fl_acc_rec",
"C:/arcpy/raster/flow_dir")
outStreamLink.save("C:/arcpy/raster/str_lnk")
# unikatne pomenovavanie segmentov vodnych tokov
outWatershed = Watershed("C:/arcpy/raster/flow_dir",
"C:/arcpy/raster/str_lnk")
outWatershed.save("C:/arcpy/raster/basins")
# vytvaranie povodi na zaklade rastra smeru odtoku a unikatne
pomenovanych segmentov potencialnych vodnych tokov
arcpy.RasterToPolygon_conversion("C:/arcpy/raster/basins",
"C:/arcpy/basins.shp", "NO_SIMPLIFY", "VALUE")
# konverzia rastrovej vrstvy povodi na vektorovu vrstvu povodi
Samotný postup práce skriptu je popísaný v niekoľkých publikáciách (e.g. Silhavy, 2010),
preto sa mu nebudeme podrobne venovať a zameráme sa najmä na postup tvorby skriptu.
Vyššie uvedený algoritmus je lineárny, teda nedochádza k vetveniu alebo opakovaniu
niektorých modulov s iným nastavením vstupných parametrov. Skript využíva najmä nástroje
modulu Spatial Analyst, ktoré len vhodne radí za seba. V prvom kroku sa generuje digitálny
výškový model prostredníctvom algoritmu Spline. Vstupom je vrstva body.shp, ktorá v sebe
obsahuje informácie o nadmorskej výške vo vybraných bodoch. V druhom kroku sa tento
digitálny výškový model hydrologicky koriguje, teda sa vyplnia bezodtokové depresie, ktoré
by mohli podmieniť vznik umelých subpovodí. Následne sa vypočíta rastrová vrstva smeru
odtoku, ktorú budeme využívať ako vstup do ďalších nástrojov. V nasledujúcom kroku
vypočítame rastrovú vrstvu príspevkových plôch, ktorú následne reklasifikujeme na novú
binárnu rastrovú vrstvu. Pre potreby reklasifikácie sme zvolili hranicu 1000 buniek, teda
všetky bunky, ktorých príspevková plocha nadobúda hodnotu pod 1000, budú reklasifikované
44
na hodnotu "NO DATA" a všetky ostatné bunky budú reklasifikované na hodnotu 1. Pre
potreby reklasifikácie využívame nástroj Reclassify s nastavením RemapRange, ktorý
reklasifikuje intervaly. Výsledkom je rastrová vrstva potenciálnej siete vodných tokov. Každý
samostatný segment vodného toku následne unikátne pomenujeme prostredníctvom modulu
Stream Link. Samotné povodia vytvoríme prostredníctvom nástroja Watershed, do ktorého
vstupuje rastrová vrstva unikátne pomenovaných segmentov toku a rastrová vrstva smeru
odtoku. Výsledkom je rastrová vrstva povodí, kde každé povodie nadobúda inú hodnotu. V
poslednom kroku prevedieme rastrovú vrstvu povodí na vrstvu vektorovú prostredníctvom
nástroja RasterToPolygon.
Výsledný algoritmus následne upravíme tak, aby generoval subpovodia pre niekoľko váh
interpolačnej interpolácie (konkrétne pre váhy 0.5, 1.1, 1.9), teda lineárny algoritmus
zmeníme na cyklický algoritmus.
import arcpy
from arcpy.sa import *
# import kniznice arcpy a modulu Spatial Analyst
vaha =[0.5, 1.1, 1.9]
# vytvorenie zoznamu vah interpolacnej funkcie
for i in vaha:
# cyklus pre zmenu vah interpolacie
outSpline = Spline("C:/arcpy/body.shp", "ELEVATION", 5,
"REGULARIZED", i)
outSpline.save("C:/arcpy/raster/dtm")
# interpolacia dtm prostrednictvom algoritmu spline
outFill = Fill("C:/arcpy/raster/dtm")
outFill.save("C:/arcpy/raster/dtm_fill")
# hydrologicka korekcia vstupneho digitalneho vyskoveho modelu
outFlowDirection = FlowDirection("C:/arcpy/raster/dtm_fill",
"NORMAL")
outFlowDirection.save("C:/arcpy/raster/flow_dir")
# vypocet smerov oddtoku
outFlowAccumulation =
FlowAccumulation("C:/arcpy/raster/flow_dir")
outFlowAccumulation.save("C:/arcpy/raster/flow_acc")
# vypocet rastrovej vrstvy prispevkovych ploch plochy
outReclass2 = Reclassify("C:/arcpy/raster/flow_acc",
"Value",RemapRange([[0,1000,"NODATA"],[1000,22000,1]]))
outReclass2.save("C:/arcpy/raster/fl_acc_rec")
# reklasifikacia rastrovej vrstvy prispevkovych ploch
outStreamLink = StreamLink("C:/arcpy/raster/fl_acc_rec",
"C:/arcpy/raster/flow_dir")
45
outStreamLink.save("C:/arcpy/raster/str_lnk")
# unikatne pomenovavanie segmentov vodnych tokov
outWatershed = Watershed("C:/arcpy/raster/flow_dir",
"C:/arcpy/raster/str_lnk")
outWatershed.save("C:/arcpy/raster/basins")
# vytvaranie povodi na zaklade rastra smeru odtoku a unikatne
pomenovanych segmentov potencialnych vodnych tokov
arcpy.RasterToPolygon_conversion("C:/arcpy/raster/basins",
"C:/arcpy/basins_%i.shp" %(i*10), "NO_SIMPLIFY", "VALUE")
# konverzia rastrovej vrstvy povodi na vektorovu vrstvu povodi
V tomto prípade bude dochádzať k prepisovaniu medzivýsledkov a jedine výsledná vektorová
vrstva bude niesť vždy unikátny názov.
4.3 Tvorba nástroja v ArcToolbox
Doteraz sme sa v tomto texte zameriavali na vytvorenie skriptov vhodných na jednorazové
použitie. Všetky vstupné parametre sú teda v týchto skriptoch pevne definované a v prípade,
že by sme ich chceli zmeniť, musíme zmeniť zdrojový kód skriptu. Tento fakt si ukážeme na
príklade skriptu na výpočet základných morfometrických charakteristík digitálneho
výškového modelu.
import arcpy
from arcpy.sa import *
# import kniznice arcpy a modulu Spatial Analyst
outSpline = Spline("C:/arcpy/body.shp", "ELEVATION", 2,
"REGULARIZED", 0.1)
outSpline.save("C:/arcpy/raster/dtm")
# interpolacia dtm prostrednictvom algoritmu spline
outSlope = Slope("C:/arcpy/raster/dtm", "DEGREE")
outSlope.save("C:/arcpy/raster/slope")
# vypocet rastrovej vrstvy sklonu georeliefu
outAspect = Aspect("C:/arcpy/raster/dtm")
outAspect.save("C:/arcpy/raster/aspect")
# vypocet rastrovej vrstvy orientacie georeliefu voci svetovym
stranam
outCurve = Curvature("C:/arcpy/raster/dtm", 1,
"C:/arcpy/raster/prof_curv" )
# vypocet rastrovej vrstvy normalovej krivosti voci svetovym
stranam
Ak chceme meniť názov vstupnej vrstvy, musíme vstúpiť priamo do zdrojového kódu a v
štvrtom riadku textu zmeniť hodnotu "C:/arcpy/body.shp" z body.shp na iný názov vstupnej
vrstvy. S najväčšou pravdepodobnosťou bude nevyhnutné upraviť aj názov stĺpca, ktorý bude
obsahovať informáciu o nadmorskej výške, z "ELEVATION" na iný názov. Celá práca so
zostaveným skriptom sa vďaka týmto obmedzeniam stáva ťažkopádna a komplikovaná pre
používateľa, ktorý nedisponuje aspoň základnými znalosťami z oblasti tvorby skriptov.
46
Riešením tohto problému je vytvorenie skriptu na výpočet základných morfometrických
charakteristík, ktorý bude disponovať graficky prívetivým a interaktívnym používateľským
prostredím, vďaka ktorému bude možné meniť názvy vstupných a výstupných vrstiev.
Vytvorenie takéhoto prostredia je v bežnej praxi časovo náročné a vyžaduje si pokročilé
znalosti z oblasti programovania. Tento problém je v prostredí ArcGIS vyriešený
prostredníctvom skupiny nástrojov na tvorbu grafického rozhrania pre vlastné nástroje,
naprogramované v jazyku Python. Vlastné nástroje s grafickým rozhraním sú potom dostupné
v prostredí ArcToolbox spolu s ostatnými nástrojmi ArcGIS. Štruktúra prepojenia medzi
grafickým rozhraním a nástrojom je znázornená na Obrázku 19.
Obrázok 19. Ukážka štruktúry novovytvoreného nástroja prostredníctvom Python skriptu a
grafického rozhrania, ktoré je poskytované ArcToolbox-om.
Ako vidíme na Obrázku 19, funkčný nástroj ArcToolbox-u, ktorý je vytvorený na základe
Python skriptu, sa skladá z dvoch častí. Prvou z nich je samotný skript v jazyku Python.
Premenné, ktoré bude možné pri každom spustení nástroja meniť (parametre), sú samostatne
označené v zdrojovom kóde (viď nižšie). Druhou časťou je pripravené grafické rozhranie,
ktoré je súčasťou ArcToolbox-u. Vo svojej podstate ide o rozhranie, ktoré je známe každému
používateľovi ArcGIS. V rámci tohto rozhrania je možné nastaviť hodnoty parametrov, ktoré
budú používané pri spúšťaní skriptu. Aj napriek faktu, že ide o zjednodušenie vytvorenia
nového komunikačného prostredia, aj toto riešenie má svoje úskalia, na ktoré je potrebné si
zvyknúť. Pri zostavovaní nového nástroja do prostredia ArcToolbox je potrebné si uvedomiť
najmä fakt, že nástroj bude určený širokému spektru používateľov, ktorí nebudú mať znalosť
o jeho funkčnosti. Preto je nevyhnutné zostaviť ho jednoznačne a jednoducho.
Funkcionalitu vyššie uvedeného riešenia si ukážeme na jednoduchom príklade skriptu, ktorý
na základe vstupného bodového výškového poľa vo formáte ESRI shape vytvorí tri rastrové
vrstvy nadmorskej výšky. Vrstvy budú vytvorené prostredníctvom algoritmu IDW s
hodnotami exponentu 0.2, 1.2, 1.8. Postup práce bude nasledovný:
1. Vytvorenie skriptu, ktorý bude vykonávať vyššie uvedenú úlohu.
47
2. Vytvorenie nového Toolbox-u.
3. Vytvorenie nového nástroja (Tool) vo vyššie vytvorenom Toolbox-e a priradenie
skriptu k nemu.
4. Deklarovanie parametrov v skripte.
import arcpy
from arcpy.sa import *
# import kniznice arcpy a modulu Spatial Analyst
power =[0.2, 1.2, 1.8]
# vytvorenie zoznamu s hodnotami vah interpolacnej funkcie
for i in power:
# cyklus pre zmenu vah interpolacie
outIDW = Idw("C:/arcpy/body.shp", "ELEVATION", 5, i,
RadiusVariable(10, 150000))
outIDW.save("C:/arcpy/raster/dtm_%i" %(i*10))
# interpolacia
Tento skript si následne uložíme do vhodného adresára a pomenujeme ho, napríklad,
interpol.py.
Následne si otvoríme ArcCatalog a vytvoríme nový prázdny Toolbox. Prvou možnosťou je
kliknúť pravým tlačidlom myši do priečinka, kde chceme vytvoriť nový Toolbox a vyberieme
voľbu New/Toolbox (Obrázok 20).
Obrázok 20. Príklad vytvorenia nového Toolbox-u v prostredí ArcCatalog.
48
Druhou možnosťou je vytvorenie nového Toolbox-u prostredníctvom horného kontextového
menu File/New/Toolbox. Názov nového Toolbox-u je preddefinovaný na Toolbox.tbx, ale je
možné ho jednoducho zmeniť. Toolbox je v podstate len špecifický súbor, ktorý sa v prostredí
ArcCatalog správa ako priečinok, do ktorého je možné ukladať Toolset-y (podpriečinky),
modely vytvorené v prostredí Model Builder a skripty vytvorené v jazyku Python.
V ďalšom kroku vytvoríme grafické rozhranie, ktoré prepojíme so skriptom interpol.py.
Otvoríme si novovytvorený Toolbox a postupujeme podobne ako pri tvorbe Toolboxu.
Klikneme pravým tlačidlom na voľnú plochu ArcCatalogu a vyberieme možnosť
Add/Script.... (Obrázok 21) Následne sa nám otvorí nové okno tvorby grafického rozhrania
(Obrázok 22).
Obrázok 21. Ukážka vytvorenia nového grafického rozhrania pre skript v jazyku Python.
Obrázok 22. Ukážka okna tvorby nového grafického rozhrania pre skripty písané v jazyku
Python.
49
V tomto okne je nevyhnutné nastaviť nasledovné parametre:
Name: – Názov nového modulu.
Label: – Menovka nového modulu.
Description: – Základný popis funkcionality modulu, ktorý sa zobrazí pri spustení
grafického rozhrania.
Stylesheet: – Cesta k vopred vytvorenému vzoru grafického rozhrania.
Store relative path names: – V prípade, že je táto voľba aktívna, skript pracuje len s
relatívnou adresáciou súborov, čím je výsledný modul možné premiestňovať po disku
a na iné počítače ako celok bez toho, aby sa znefunkčnil. V tomto prípade je ideálne
všetky vstupné vrstvy, výstupné vrstvy, skript a grafické rozhranie umiestniť do
samostatného priečinka.
Always run on foreground: – V prípade, že je táto voľba aktívna, skript pracuje vždy v
popredí ako práve prebiehajúci proces.
V našom prípade zadáme nasledovné hodnoty:
Name: – interpolacny-skript
Label: – interpolacny-skript
Description: – Interpolácie prostredníctvom algoritmu IDW s tromi nastaveniami
exponentu interpolácie.
Store relative path names: – aktívne
Always run on foreground: – aktívne
Pokračujeme prostredníctvom tlačidla Ďalej >. V nasledujúcom okne definujeme cestu k
samotnému skriptu, ktorý bude spúšťaný prostredníctvom grafického rozhrania. V našom
prípade to bude "C:/arcpy/interpol.py". Pokračujeme tlačidlom Ďalej >. Ďalšie okno slúži na
definovanie vstupných parametrov. Týmto oknom sa budeme zaoberať neskôr a momentálne
ho preskočíme tlačidlom Finish. Takto sme vytvorili nový nástroj, ktorý je možné spúšťať v
prostredí ArcCatalog alebo ArcMap, podobne ako všetky ostatné bežné nástroje. Nástroj
spustíme dvojklikom na jeho ikonu. Zobrazí sa nám okno zobrazené na Obrázku 23.
Obrázok 23. Ukážka grafického rozhrania skriptu bez nastavených vstupných parametrov.
Nástroj spustíme tlačidlom OK. Po spustení prebehne interpolácia s prednastavenými
parametrami.
Vytvorili sme teda nástroj, ktorý nedisponuje žiadnymi vstupnými parametrami, preto v
prípade akejkoľvek zmeny, musíme vstupovať do zdrojového kódu. V poslednom kroku
50
upravíme nami vytvorený nástroj tak, aby bolo možné meniť názov vstupnej vrstvy a názov
stĺpca s hodnotou nadmorskej výšky.
V tomto kroku je vhodné zoznámiť sa s funkciou GetParameterAsText(), ktorú možno
prirovnať k funkcii input(). Funkcia zabezpečuje dynamické priradenie premennej medzi
skriptom v jazyku Python a grafickým rozhraním v prostredí ArcToolbox. Je teda na strane
skriptu nevyhnutné upraviť zdrojový kód a na strane grafického rozhrania je nevyhnutné
deklarovať dva vstupné parametre. Zdrojový kód upravíme nasledovne.
import arcpy
from arcpy.sa import *
# import kniznice arcpy a modulu Spatial Analyst
power =[0.2, 1.2, 1.8]
# vytvorenie zoznamu s hodnotami vah interpolacnej funkcie
vrstva = arcpy.GetParameterAsText(0)
stlpec = arcpy.GetParameterAsText(1)
# vytvorenie dvoch parametrov, ktorych hodnoty budu definovane
prostrednictvom grafickeho rozhrania
for i in power:
# cyklus pre zmenu vah interpolacie
outIDW = Idw(vrstva, stlpec, 5, i, RadiusVariable(10,
150000))
outIDW.save("C:/arcpy/raster/dtm_%i" %(i*10))
# interpolacia
V zdrojovom kóde sme zamenili názov vstupnej vrstvy a názov stĺpca používaného na
interpolovanie za premenné, ktorým dynamicky priraďujeme hodnoty prostredníctvom
funkcie GetParameterAsText(). Všimnime si, že argumentom funkcie je poradové číslo
(index) preberaného parametra. Prvý parameter, prebraný od používateľa v grafickom
rozhraní, bude mať index 0, druhý index 1, atď. Z toho vyplýva, že je nevyhnutné dodržať
presné poradie parametrov aj v grafickom rozhraní. Na strane grafického rozhrania
uskutočňujeme zmeny v okne na definovanie vstupných parametrov, ktoré sme vynechávali
pri zostavovaní nástroja. Toto okno opätovne vyvoláme prostredníctvom voľby Properties... v
kontextovom menu novovytvoreného nástroja (Obrázok 24).
51
Obrázok 24. Vyvolanie kontextového menu nástroja v prostredí ArcCatalog.
V tomto menu nachádzame karty General, Source, Parameters, Validation, Help. V našom
prípade nás zaujíma karta Parameters, kde je možné deklarovať parametre nástroja. Ukážku
tejto karty nachádzame na Obrázku 25.
Obrázok 25. Ukážka okna na zmenu vstupných parametrov grafického rozhrania.
52
Okno sa skladá z dvoch častí. V hornej časti deklarujeme názov a dátový typ premennej a v
spodnej časti nastavujeme ďalšie charakteristiky premennej. Prostredie ArcToolbox ponúka
široké spektrum dátových typov, medzi najpoužívanejšie patria:
Raster layer – rastrová vrstva
Feature class – vektorová vrstva uložená vo formáte shapefile alebo v geodatabáze
Shapefile – vektorová vrstva vo formáte shapefile
String – textový reťazec
Text file – textový súbor
File – súbor
Directory – adresár
Table – tabuľka
Field – pole tabuľky
Každý parameter môže byť povinný (Required), voliteľný (Optional) alebo odvodený
(Derived). Ak je parameter povinný, používateľ nástroja ho musí zadať, a ak ho nezadá,
program vypíše chybu. Povinné parametre sú v grafickom rozhraní označené zelenou
guličkou. Ďalej môžeme nastaviť, či je parameter vstupný (Input) alebo výstupný (Output).
Tieto funkcie oceníte najmä v prípade, že chcete skript zabezpečiť proti nesprávnym vstupom.
Takto ošetrený skript sa však dá spúšťať iba v prostredí ArcGIS.
V našom prípade deklarujeme dva vstupné parametre:
1. Parameter s názvom vrstva, ktorý bude dátového typu Feature class.
2. Parameter s názvom stĺpec, ktorý bude dátového typu Field.
Oba parametre budú vstupné a povinné. Pri parametri stĺpec môžeme využiť nastavenie
Obtained from Input, ktoré ponúkne používateľovi nástroja na výber zoznam polí vstupnej
vrstvy. Je to výhodné v prípade, ak používateľ nemá informácie o štruktúre atribútovej
tabuľky a presných názvoch polí.
Zmeny uložíme tlačidlom OK a otestujeme funkčnosť nástroja. V prípade potreby môžeme
používateľovi ponúknuť aj ďalšie možnosti na výber, napr. môžeme pridať parameter
exponentov interpolačnej funkcie alebo parameter adresára, v ktorom majú byť uložené
výstupné vrstvy.
5. Priestorová analýza prostredníctvom knižnice NumPy
V predošlých kapitolách sme pre potreby priestorovej analýzy využívali funkcie prostredia
ArcGIS prostredníctvom knižnice ArcPy. Knižnica teda slúžila pre volanie funkcií ArcGIS.
V tejto kapitole si ukážeme možnosti práce s priestorovými údajmi prostredníctvom inej
knižnice, knižnice NumPy. Táto knižnica bola vytvorená pre potreby matematickej analýzy v
jazyku Python. Ponúka, napríklad, prácu s n-rozmerným poľom (nielen jednorozmerným
zoznamom ako v prípade samotného jazyka Python) alebo vylepšené generátory náhodných
čísel. Knižnica je súčasťou distribúcie Python, ktorá sa dodáva spolu s prostredím ArcGIS
10.x, ale aj balíčka Anaconda. V prípade priestorovej analýzy je využívaná najmä práca s n-
rozmerným poľom, kde je možné prostredníctvom nástroja v knižnici ArcPy konvertovať
bežne používané rastrové dáta do podoby dvojrozmerného poľa (Obrázok 26.).
53
Obrázok 26. Ukážka prevodu rastra do podoby dvojrozmerného poľa (matice).
Na prevod rastrovej vrstvy do podoby dvojrozmerného poľa (ďalej využívame len názov
pole) využívame vlastnú funkciu RasterToNumPyArray(), ktorá je integrovaná v knižnici
ArcPy. Zápis funkcie sa skladá z pevnej a premenlivej časti, ktorá je ohraničená zátvorkami.
V premenlivej časti definujeme názov vstupnej vrstvy a hodnotu, ktorá bude považovaná za
prázdnu bunku. Výsledkom je dvojrozmerné pole, s ktorým sa dá naďalej pracovať.
import arcpy
import numpy
# import kniznic arcpy a numpy
arr =
arcpy.RasterToNumPyArray("C:/arcpy/raster/dtm",nodata_to_value
=0)
# konverzia rastrovej vrstvy na dvojrozmerne pole
Počas tejto konverzie netreba zabúdať na fakt, že strácame informáciu o priestorovom
referenčnom systéme vrstvy, teda v prípade, že ľavý horný roh vrstvy mal súradnice x =
1456845 a y = 5466871, tak konvertované pole bude mať v tomto bode súradnice i = 0 a j = 0.
V ďalšej časti si ukážeme základné príkazy pre prácu a správu poľa prostredníctvom knižnice
NumPy.
import arcpy
import numpy
# import kniznic arcpy a numpy
arr =
arcpy.RasterToNumPyArray("C:/arcpy/raster/dtm",nodata_to_value
=0)
# konverzia rastrovej vrstvy na trojrozmerne pole
print arr.shape
(3024, 4954)
# vypis rozmerov pola, teda vypis poctu riadkov a stlpcov
print arr.ndim
2
# vypis poctu dimenzii pola
Počas práce s touto knižnicou sa dostaneme do situácie, kde bude nevyhnutné nielen sa po
dvojrozmernom poli pohybovať, ale aj zapisovať hodnoty do nového dvojrozmerného poľa.
Na to, aby sme do poľa mohli zapisovať nové hodnoty, musíme najprv nové pole vytvoriť. Na
54
vytvorenie nového poľa, vyplneného hodnotou 0, využívame funkciu zeros(), kde v druhej
časti funkcie zadávame rozmery nového nulového poľa.
nuly = zeros((5,3))
Výpis poľa na obrazovku je v tomto prípade komplikovanejší, pretože do konzoly nie je
možné vypísať polia s rozmermi 100 x 100 a podobne. Práve z tohto dôvodu častejšie
využívame výpis jednotlivých prvkov poľa.
print arr[10,20]
1364.07
# vypis hodnoty pola v 11 riadku a 21 stlpci
Rovnako ako v prípade bežných 1D polí (viď. Zoznamy), aj v tomto prípade využívame
indexovanie pozície polí, ako to je zobrazené na obrázku XY. Nezabúdajte na fakt, že
indexovanie začína na pozícii 0 a nie na pozícii 1.
from numpy import *
arr = zeros( (3,4) )
# vytvorit pole naplnene hodnotami 0, ktore bude mat tri
riadky a styri stlpce
print arr
[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
# vypis pola
V nasledujúcom príklade zostavíme skript pre výpočet vertikálnej disekcie reliéfu pre
vyhľadávacie okolie jednej bunky. Postup práce je nasledovný:
1. Import rastrovej vrstvy dtm do dvojrozmerného poľa numpy s názvom array.
2. Vytvorenie nového poľa s názvom vysledok vyplneného hodnotami 0 s totožnými
rozmermi ako vstupné pole.
3. Vytvorenie cyklu pre posun po riadkoch a stĺpcoch.
4. Výpočet maximálnej, minimálnej hodnoty a rozdielu hodnôt pre okolie pozície 1,1
vstupného poľa array.
5. Zápis rozdielu hodnôt do poľa s nulovými hodnotami.
6. Opakovanie bodov 4 a 5 pre ostatné pozície vstupneho pola array.
7. Export poľa vysledok do rastrovej vrstvy.
import arcpy
from numpy import *
# import kniznice arcpy a numpy
array =
arcpy.RasterToNumPyArray("C:/arcpy/raster/dtm",nodata_to_value
=0)
# prevod rastrovej vrstvy na dvojrozmerne pole numpy
vysledok = zeros(array.shape)
# vytvorenie dvojrozmerneho pola rovnakej velkosti ako vstupne
pole
rozmer = array.shape
55
riadky = rozmer[0]
stlpce = rozmer[1]
# priradenie poctu riadkov premennej riadky a poctu stlpcov
premennej stlpce
for i in range(1, riadky-1):
for j in range(1, stlpce-1):
# vytvorenie cyklov pre posun po riadkoch a stlpcoch pola
maximum = 0
minimum = 0
rozdiel = 0
if array[i+1,j+1] > maximum:
maximum = array[i+1,j+1]
if array[i,j+1] > maximum:
maximum = array[i,j+1]
if array[i-1,j+1] > maximum:
maximum = array[i-1,j+1]
if array[i+1,j] > maximum:
maximum = array[i+1,j]
if array[i,j] > maximum:
maximum = array[i,j]
if array[i-1,j] > maximum:
maximum = array[i-1,j]
if array[i+1,j-1] > maximum:
maximum = array[i+1,j-1]
if array[i,j-1] > maximum:
maximum = array[i,j-1]
if array[i-1,j-1] > maximum:
maximum = array[i-1,j-1]
# najdi maximum v okoli
if array[i+1,j+1] < minimum:
minimum = array[i+1,j+1]
if array[i,j+1] < minimum:
minimum = array[i,j+1]
if array[i-1,j+1] < minimum:
minimum = array[i-1,j+1]
if array[i+1,j] < minimum:
minimum = array[i+1,j]
if array[i,j] < minimum:
minimum = array[i,j]
if array[i-1,j] < minimum:
minimum = array[i-1,j]
if array[i+1,j-1] < minimum:
minimum = array[i+1,j-1]
if array[i,j-1] < minimum:
minimum = array[i,j-1]
if array[i-1,j-1] < minimum:
minimum = array[i-1,j-1]
# najdi minimum v okoli
56
rozdiel = maximum - minimum
vysledok[i,j] = rozdiel
# zapis najdeny rozdiel do pola vysledok
raster = arcpy.NumPyArrayToRaster(vysledok)
raster.save("C:/arcpy/raster/vysledok")
# export pola s nazvom "vysledok" do rastrovej formy
Skript postupne prehľadáva bezprostredné okolie pozície v druhom riadku a druhom stĺpci v
poli. V tomto okolí nájde maximálnu a minimálnu hodnotu, ktorú si priradí do premenných
maximum a minimum. Rozdielom týchto premenných určí vertikálnu disekciu reliéfu, ktorú
zapíše do premennej s názvom rozdiel a následne do pripraveného nového poľa s názvom
vysledok na pozíciu, ktorá zodpovedá strednej bunke prehľadávaného okolia (v prvom prípade
to je druhý riadok a druhý stĺpec). Algoritmus sa posunie na ďalšiu pozíciu a premenné
maximum, minimum a rozdiel sa vynulujú. Tento postup sa opakuje, pokiaľ nie je takto
spracované celé vstupné pole. Výsledné pole sa exportuje do podoby rastrovej vrstvy.
Hlavným problémom postupu transformácie rastrovej vrstvy do poľa, a potom spätne do
rastrovej vrstvy, je nezachovávanie priestorového referenčného systému tejto vrstvy.
Výsledná vrstva sa teda nenachádza v rovnakej pozícii ako vstupná vrstva, ale je priradená na
začiatok priestorového referenčného systému do bodu 0, 0. V prípade, že chceme túto vrstvu
priradiť do pôvodnej pozície, je nutné ju georeferencovať, alebo využiť podrobnejšie
nastavenia funkcie NumPyArrayToRaster(), ktoré je možné nájsť v ArcGIS pomocníkovi. Pre
čo najväčšie zjednodušenie celého postupu tento krok vynecháme.
V ďalšom cvičení sa zameráme na vytvorenie skriptu, ktorý bude na základe vstupného
digitálneho výškového modelu a pozície i (riadky) a j (stĺpce) generovať línie dohľadnosti do
štyroch hlavných svetových strán. Postup práce je nasledovný:
1. Import rastrovej vrstvy dtm vo formáte ESRI Grid do dvojrozmerného poľa s názvom
dtm.
2. Vytvorenie nového poľa s názvom "vysledok" vyplneného hodnotami 0 s totožnými
rozmermi ako vstupné pole.
3. Priradenie pozície pozorovateľa k premenným riadky_poz a stlpce_poz.
4. Zostavenie štyroch cyklov s definovanou podmienkou, ktoré zabezpečia zostavenie
štyroch línií dohľadnosti. Podmienkou bude, že každá nasledujúca bunka musí mať
nižšiu alebo rovnakú nadmorskú výšku, ako je nadmorská výška definovaná
súradnicami X a Y. V prípade, že je podmienka splnená, do poľa vysledok sa do
prislúchajúcej pozície zapíše hodnota 1. V prípade, že podmienka nie je splnená,
cyklus sa ukončí.
5. Export poľa vysledok do rastrovej vrstvy.
import arcpy
from numpy import *
# import kniznice arcpy a numpy
array =
arcpy.RasterToNumPyArray("C:/arcpy/raster/dtm",nodata_to_value
=0)
# prevod rastrovej vrstvy na dvojrozmerne pole
vysledok = zeros(array.shape)
57
# vytvorenie dvojrozmerneho pola rovnakej velkosti ako vstupne
pole
rozmery = array.shape
max_riadky = rozmery[0]
max_stlpce = rozmery[1]
print max_riadky
print max_stlpce
# zistenie maximalnych rozmerov pola
riadky_poz = 20
stlpce_poz = 20
# priradenie pozicie pozorovatela
originalna_vyska = array[riadky_poz,sltpce_poz]
# zistenie nadmorskej vysky pozorovatela
test = 0
# vytvorenie premennej test
i = riadky_poz
j = stlpce_poz
# premennym i a j priradenie pozicie skumaneho miesta
while test == 0:
# cyklus pre posun po poli v smere na juh
if 1 < i < max_riadky:
# testovanie, ci pozicia definovana i a j je v ramci indexov
pola
if array[i,j] <= originalna_vyska:
vysledok[i,j] = 1
i = i + 1
# testovanie ci ide o bod, ktoreho nadmorska vyska je nizsia
alebo rovna ako nadmorska vyska povodneho miesta
else:
test = 1
else:
test = 1
test = 0
# vynulovanie premennej test
i = riadky_poz
j = stlpce_poz
# premennym i a j priradenie pozicie skumaneho miesta
while test == 0:
# cyklus pre posun po poli v smere na sever
58
if 1 < i < max_riadky:
# testovanie, ci pozicia definovana i a j je v ramci indexov
pola
if array[i,j] <= originalna_vyska:
vysledok[i,j] = 1
i = i - 1
# testovanie ci ide o bod, ktoreho nadmorska vyska je nizsia
alebo rovna ako nadmorska vyska povodneho miesta
else:
test = 1
else:
test = 1
test = 0
# vynulovanie premennej test
i = riadky_poz
j = stlpce_poz
# premennym i a j priradenie pozicie skumaneho miesta
while test == 0:
# cyklus pre posun po poli v smere na zapad
if 1 < j < max_stlpce:
# testovanie ci pozicia definovana i a j je v ramci indexov
pola
if array[i,j] <= originalna_vyska:
vysledok[i,j] = 1
j = j - 1
# testovanie ci ide o bod, ktoreho nadmorska vyska je nizsia
alebo rovna ako nadmorska vyska povodneho miesta
else:
test = 1
else:
test = 1
test = 0
# vynulovanie premennej test
i = riadky_poz
j = stlpce_poz
# premennym i a j priradenie pozicie skumaneho miesta
while test == 0:
# cyklus pre posun po poli v smere na vychod
59
if 1 < j < max_stlpce:
# testovanie ci pozicia definovana i a j je v ramci indexov
pola
if array[i,j] <= originalna_vyska:
vysledok[i,j] = 1
j = j + 1
# testovanie ci ide o bod, ktoreho nadmorska vyska je nizsia
alebo rovna ako nadmorska vyska povodneho miesta
else:
test = 1
else:
test = 1
raster = arcpy.NumPyArrayToRaster(vysledok)
raster.save("C:/arcpy/raster/vysledok")
# export pola "vysledok" do rastrovej formy
V tomto prípade skript postupuje najprv v smere juh od zadanej pozície pozorovateľa, kde
zisťuje, či je nadmorská výška skúmanej pozície poľa nižšia ako nadmorská výška
počiatočnej pozície. V prípade, že je táto podmienka splnená, skript zapíše do výstupného
poľa s názvom vysledok hodnotu 1. Následne sa tento test posunie smerom na juh. Testovanie
končí v prípade, že nájdeme pozíciu, na ktorej bude nadmorská výška vyššia ako nadmorská
výška v zadanej pozícii pozorovateľa, alebo sa dosiahne koniec poľa. Následne sa vynulujú
premenné i, j a test a obdobný postup sa opakuje v smere na sever, západ a východ. Výsledné
pole exportujeme do podoby rastrovej vrstvy. Hlavným problémom postupu transformácie
rastrovej vrstvy do formy poľa a následného export do rastrovej vrstvy je nezachovávanie
priestorového referenčného systému tejto vrstvy. Výsledná vrstva sa teda nenachádza v
rovnakej pozícii ako vstupná vrstva, ale je priradená na začiatok priestorového referenčného
systému do bodu 0, 0. V prípade, že chceme túto vrstvu priradiť do pôvodnej pozície, je nutné
ju georeferencovať, alebo využiť podrobnejšie nastavenia funkcie NumPyArrayToRaster(),
ktoré je možné nájsť v ArcGIS pomocníkovi. Pre čo najväčšie zjednodušenie celého postupu
tento krok vynecháme.
6. Vykresľovanie grafov prostredníctvom knižnice
Matplotlib
Knižnica Matplotlib zabezpečuje produkciu grafov v jazyku Python. Je súčasťou šiestich
bežných distribúcií jazyka Python, okrem iného aj distribúcie Anaconda. Prostredníctvom
tejto knižnice dokážeme tvoriť histrogramy, líniové grafy, koláčové diagramy, XY grafy,
bublinové grafy a 3D verzie týchto grafov. Knižnica taktiež umožňuje generovanie videí a
máp.
Jej funkčnosť si ukážeme na jednoduchom príklade. Prostredníctvom knižnice Matplotlib
zostavíme XY graf z hodnôt:
X Y
10 12
8 5
7 4
12 6
Postup práce je nasledovný:
60
1. Načítanie hodnôt premenných X a Y do dvoch samostatných polí s totožným názvom.
2. Vykreslenie grafu XY.
3. Dodatočná úprava tohto grafu.
4. Export grafu do PNG súboru s názvom graf.png.
import matplotlib.pyplot as plt
# import kniznice matplotlib
x = [10,8,7,12]
y = [12,5,4,6]
# priradenie hodnot do zoznamov x a y
plt.scatter(x, y)
# vytvorenie grafu XY
plt.savefig("c:/graf.png")
# ulozenie grafu XY do suboru graf.png
Výsledný graf je zobrazený na Obrázku 27.
Obrázok 27. Ukážka výsledného XY grafu zostaveného prostredníctvom knižnice Matplotlib.
V tomto prípade sme nedefinovali farbu zobrazených bodov, ale výber farby sme nechali na
knižnici. V prípade, že chceme definovať farbu bodov, musíme časť skriptu, ktorá produkuje
samotný graf, upraviť.
plt.scatter(x, y, c="red")
V tomto prípade sme využili definovanie farby prostredníctvom jej názvu, táto sa však dá
definovať aj prostredníctvom RBG kódu, a to nasledovne:
plt.scatter(x, y, c=[0.9,0.2,0.5])
61
RBG kód farby je definovaný prostredníctvom zoznamu troch prvkov, v ktorom každý z nich
nadobúda hodnoty v rozmedzí 0 – 1. Šírku línie, ktorá ohraničuje každý bod na grafe,
definujeme nasledovne:
plt.scatter(x, y, c=[0.9,0.2,0.5], linewidth=0.1)
V prípade, že chceme zmeniť zobrazovaný znak, urobíme to nasledovnou zmenou skriptu:
plt.scatter(x, y, c=[0.9,0.2,0.5], linewidth=0.1, marker='x')
Vo vyššie uvedenom prípade bude vykreslený graf zložený zo symbolov "x".
Ak sme menili len pôvodný zdrojový kód, tak sme si mohli všimnúť fakt, že dochádza k
nadkladaniu symbolov nad seba. Je to spôsobené tým, že graf generovaný prostredníctvom
knižnice matplotlib sa každou zmenou len aktualizuje, teda k pôvodnému grafu sa pridávajú
nové prvky. Ak chceme docieliť, aby sa graf vymazal (vyčistil), na konci skriptu je nutné
využiť príkaz .clf(), ktorý vymaže generovaný graf. Výsledný skript teda bude mať
nasledovný tvar.
import matplotlib.pyplot as plt
# import kniznice matplotlib
x = [10,8,7,12]
y = [12,5,4,6]
# priradenie hodnot do poli X a Y
plt.scatter(x, y, c=[0.9,0.2,0.5], linewidth=0.1, marker='x')
# vytvorenie grafu XY
plt.savefig("c:/graf.png")
# ulozenie grafu XY do suboru graf.png
plt.clf()
Na koniec skriptu sme pridali už spomínanú funkciu, pred ktorou sme definovali, ktorý objekt
sa má vymazať.
V nasledujúcom príklade zostavíme skript, pomocou ktorého budeme prostredníctvom
modelu simulovať let siedmich vtákov smerom z Afriky do Európy. Vieme, že každý vták
môže za deň vykonať let v smere na západ o 150 km, v smere na východ o 150 km, v smere
na sever o 150 km alebo o 210 km. Budeme predpokladať, že každý vták sa o smere letu
každý deň rozhoduje náhodne, teda každý deň si náhodne vyberie, či poletí na východ, na
západ alebo na sever o 150 km alebo 210 km. V prípade, že vták nepreletí za 32 dní
vzdialenosť 3000 km v smere na sever, tak uhynie. Výsledkom algoritmu bude graf pozícií
každého vtáka a výpis, ktorí vtáci prežili, a ktorí uhynuli. Postup práce je nasledovný:
1. Pridelenie súradníc 7 pozorovaným jedincom. Vzdialenosť medzi jedincami zvolíme
na 1000 km.
2. Zostavenie tela cyklu, ktorý bude simulovať 32 dní letu.
3. Implementácia generátora náhodných čísel, ktorý bude simulovať každodennú
náhodnú voľbu jedinca.
4. Vytvorenie podmienok, ktoré budú zabezpečovať pohyb jedinca v závislosti od jeho
voľby.
5. Pridanie súčasnej polohy jedinca do XY grafu.
6. Opakovanie krokov 3, 4 a 5 ďalších 31-krát.
62
import random
import matplotlib.pyplot as plt
# import kniznice random a kniznice matplotlib
x1 = 1000
y1 = 0
x2 = 2000
y2 = 0
x3 = 3000
y3 = 0
x4 = 4000
y4 = 0
x5 = 5000
y5 = 0
x6 = 6000
y6 = 0
x7 = 7000
y7 = 0
# umiestnenie 7 jedincov na jednu startovaciu liniu
for i in range (1,32):
# cyklus simulujuci 32 dni
rand = random.randint(1,4)
# generovanie nahodneho rozhodnutia prveho jedinca
if rand == 1:
x1 = x1 - 150
y1 = y1
if rand == 2:
x1 = x1
y1 = y1 + 150
if rand == 3:
x1 = x1 + 150
y1 = y1
if rand == 4:
x1 = x1
y1 = y1 + 210
# podmienky zapezpecujuce pohyb jedinca v zavislosti od jeho
rozhodnutia
rand = random.randint(1,4)
# generovanie nahodneho rozhodnutia druheho jedinca
if rand == 1:
x2 = x2 - 150
y2 = y2
if rand == 2:
x2 = x2
y2 = y2 + 150
if rand == 3:
x2 = x2 + 150
63
y2 = y2
if rand == 4:
x2 = x2
y2 = y2 + 210
# podmienky zapezpecujuce pohyb jedinca v zavislosti od jeho
rozhodnutia
rand = random.randint(1,4)
# generovanie nahodneho rozhodnutia tretieho jedinca
if rand == 1:
x3 = x3 - 150
y3 = y3
if rand == 2:
x3 = x3
y3 = y3 + 150
if rand == 3:
x3 = x3 + 150
y3 = y3
if rand == 4:
x3 = x3
y3 = y3 + 210
# podmienky zapezpecujuce pohyb jedinca v zavislosti od jeho
rozhodnutia
rand = random.randint(1,4)
# generovanie nahodneho rozhodnutia stvrteho jedinca
if rand == 1:
x4 = x4 - 150
y4 = y4
if rand == 2:
x4 = x4
y4 = y4 + 150
if rand == 3:
x4 = x4 + 150
y4 = y4
if rand == 4:
x4 = x4
y4 = y4 + 210
# podmienky zapezpecujuce pohyb jedinca v zavislosti od jeho
rozhodnutia
rand = random.randint(1,4)
# generovanie nahodneho rozhodnutia piateho jedinca
if rand == 1:
x5 = x5 - 150
y5 = y5
if rand == 2:
x5 = x5
64
y5 = y5 + 150
if rand == 3:
x5 = x5 + 150
y5 = y5
if rand == 4:
x5 = x5
y5 = y5 + 210
# podmienky zapezpecujuce pohyb jedinca v zavislosti od jeho
rozhodnutia
rand = random.randint(1,4)
# generovanie nahodneho rozhodnutia siesteho jedinca
if rand == 1:
x6 = x6 - 150
y6 = y6
if rand == 2:
x6 = x6
y6 = y6 + 150
if rand == 3:
x6 = x6 + 150
y6 = y6
if rand == 4:
x6 = x6
y6 = y6 + 210
# podmienky zapezpecujuce pohyb jedinca v zavislosti od jeho
rozhodnutia
rand = random.randint(1,4)
# generovanie nahodneho rozhodnutia siedmeho jedinca
if rand == 1:
x7 = x7 - 150
y7 = y7
if rand == 2:
x7 = x7
y7 = y7 + 150
if rand == 3:
x7 = x7 + 150
y7 = y7
if rand == 4:
x7 = x7
y7 = y7 + 210
# podmienky zapezpecujuce pohyb jedinca v zavislosti od jeho
rozhodnutia
plt.scatter(x1, y1, alpha=0.5, marker='o')
plt.scatter(x2, y2, alpha=0.5, marker='v')
plt.scatter(x3, y3, alpha=0.5, marker='.')
plt.scatter(x4, y4, alpha=0.5, marker=',')
plt.scatter(x5, y5, alpha=0.5, marker='x')
65
plt.scatter(x6, y6, alpha=0.5, marker='D')
plt.scatter(x7, y7, alpha=0.5, marker='1')
# pridanie pozicie jedincov do grafu
plt.savefig('trasy.tif', dpi=200)
if y1 > 3000:
print "Jedinec 1 prezil"
else:
print "Jedinec 1 uhynul"
if y2 > 3000:
print "Jedinec 2 prezil"
else:
print "Jedinec 2 uhynul"
if y3 > 3000:
print "Jedinec 3 prezil"
else:
print "Jedinec 3 uhynul"
if y4 > 3000:
print "Jedinec 4 prezil"
else:
print "Jedinec 4 uhynul"
if y5 > 3000:
print "Jedinec 5 prezil"
else:
print "Jedinec 5 uhynul"
if y6 > 3000:
print "Jedinec 6 prezil"
else:
print "Jedinec 6 uhynul"
if y7 > 3000:
print "Jedinec 7 prezil"
else:
print "Jedinec 7 uhynul"
print "koniec"
plt.clf()
# vypis konecneho stavu jedincov
V prípade zostavenia grafu pohybu jedincov využívame fakt, že graf je objektom, do ktorého
je možné jednotlivé prvky pridávať až do doby, kým príkazom .clf() tento objekt nezmažeme.
Vždy teda pridáme len súčasnú polohu jedinca a cesta jedinca sa zaznamená ako trasa jeho
pozícií. Je potrebné pamätať na to, že jedince musíme v grafe farebne alebo znakovo rozlíšiť.
Celý predkladaný skript nezabezpečí, že jedinec sa nevráti na miesto, na ktorom sa nachádzal
predošlý beh cyklu (predošlý deň). V tomto prípade išlo o jednoduchý model, pracujúci na
predpoklade rovnakej pravdepodobnosti výberu trasy. V našom prípade sme využili ten
najjednoduchší spôsob zápisu, ktorý je však najdlhší. Zdrojový kód sa dá, napríklad, skrátiť
prostredníctvom zostavena funkcie, ktorá zabezpečí pohyb jedinca (Funkcie 3.8.). Taktiež je
možné využiť funkciu Option, ktorá umožňuje výber z niekoľkých variánt podmienok, nie len
jednej varianty, ako funkcia If.
66
7. Zoznam použitej literatúry
ŠILHAVÝ, J. Hydrologické analýzy v distribuovaném prostředí. Diplomova práca,
Západočeská univerzita v Plzni, 2010
8. Zoznam odporúčanej literatúry
PIMPLER, E. Programming ArcGIS 10.1 with Python Cookbook, PACKT Publishing, 304 p.,
2013,
ZANDBERGER, P., A. Python Scripting for ArcGIS, 368 p., 2012
HETLAND M., I. Beginning Python: From Novice to Professional, Apress, 607 p., 2008
67
Táto práca bola podporovaná Agentúrou na podporu výskumu a vývoja na základe zmluvy č.
APVV-0625-11 a Grantom Univerzity Komenského č. UK/503/2015.
Mgr. Libor Burian
Mgr. Hana Stanková, PhD.
Python
Geovedné aplikácie
Vydala Univerzita Komenského v Bratislave, Prírodovedecká fakulta
jazyková úprava: Bc. Martina Lešková
Rozsah 4.56 AH, 3.28 AH textu a 1.28 AH obrázkov (27 obrázkov), 1. vydanie