Přístup k vektorovým datům

K vektorovým datům lze přistupovat ve dvou režimech:

  • bez topologie (ala jednoduché geoprvky, viz OGC standard Simple Features), tento přístup zajišťuje třída Vector
  • včetně topologie, viz třída VectorTopo

Další informace v dokumentaci PyGRASS.

Průchod vektorovými prvky bez topologie

Skript níže vypisuje souřadnice definičních bodů z mapy obce_bod mapsetu ruian spolu s jejich názvy.

  1. Nejprve na řádku 5 vytvoříme instaci třídy Vector odkazující na zvolenou vektorovou mapu, kterou na následujícím řádku otevřeme v režimu čtení.
  2. Jednotlivé prvky procházíme sekvenčně v cyklu for na řádku 8.
  3. Na konci skriptu nezapomeneme vektorovou mapu korektně uzavřít 11.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/usr/bin/env python

from grass.pygrass.vector import Vector

obce = Vector('obce_bod', mapset='ruian')
obce.open('r')

for prvek in obce:
    print (u"{:<25}: {:.0f} {:.0f}".format(prvek.attrs['nazev'], prvek.x, prvek.y))
    
obce.close()

Skript ke stažení zde.

Důležité

Tímto způsobem (bez topologie) lze procházet v mapě pouze základní geometrická primitiva jako jsou body, linie, hraniční linie a centroidy, viz kapitola Topologický model ze školení pro začátečníky. Přístup ke složeným typům jako jsou plochy již vyžaduje topologii.

Výpis skriptu může vypadat následovně:

...
Božejov                  : -700917 -1129944
Cejle                    : -677975 -1132017
Drahonice                : -781273 -1137206
...

Poznámka

Pokud skript v GUI končí chybou

Traceback (most recent call last):
  File "/home/martin/skripty/obce_body.py", line 11, in <module>
    print (u"{:<25}: {:.0f}{:.0f}".format(prvek.attrs['nazev'], prvek.x, prvek.y))
  UnicodeEncodeError: 'ascii' codec can't encode characters in
   position 3-4: ordinal not in range(128)

tak přidejte na začátek skriptu

import sys
import codecs
sys.stdout = codecs.getwriter('utf8')(sys.stdout)

Přístup k topologii

Přístup k topologii vektorových prvků zajišťuje třída VectorTopo. Více informací o topologickém modelu systému GRASS najdete ve školení pro začátečníky.

V následující ukázce vypíšeme pro každý okres počet jeho sousedních okresů.

  1. Na řádku 5 vytvoříme instaci třídy VectorTopo odkazující na zvolenou vektorovou mapu, kterou na následujícím řádku otevřeme v režimu topologického čtení.
  2. Jednotlivé prvky (tj. okresy) procházíme sekvenčně v cyklu for na řádku 8. Pro průchod složených topologických primitiv, jako jsou v tomto případě plochy, musíme použít funknci viter().
  3. Pro každou plochu okresu projdeme její hraniční linie 10 a zjistíme jaká plocha je od této linie nalevo a napravo 11 (-1 představuje žádný prvek).
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#!/usr/bin/env python

from grass.pygrass.vector import VectorTopo

okresy = VectorTopo('okresy_polygon', mapset='ruian')
okresy.open('r')

for o in okresy.viter('areas'):
    sousede = set()
    for b in o.boundaries():
        for n in b.get_left_right():
            if n != -1 and n != o.id:
                sousede.add(n)
    
    print (u'{:20}: {}'.format(o.attrs['nazev'], len(sousede)))

okresy.close()

Varování

Mezi verzemi GRASS 7.1 a GRASS 7.0 se API PyGRASS částečně změnilo. Místo funkce get_left_right() (11) použijte v GRASS 7.1 read_area_ids().

Skript ke stažení zde.

Výpis skriptu může vypadat následovně:

...
Blansko             : 5
Brno-město          : 1
Vyškov              : 6
...

Varování

Tento skript je funkční pouze ve verzi GRASS 7.0.1 a vyšší.

Nalezení nejbližších prvků, zápis nových prvků

K nalezení nejbližších prvků je vyžadován přístup k topologii. V následujícím příkladu budeme hledat nejbližší ulici k dané záchrance. Dále zkontrolujeme, zda je záchrance přiřazen korektní kód ulice (dle RÚIAN).

Záchranky jsou společně s nejbližšími ulicemi zapsány do nové vektorové mapy zachranka_ulice (řádky 10, 15,24,26). Atributová tabulka pro výstupní vektorovou mapu je definována na řádcích 11-14.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/usr/bin/env python

from grass.pygrass.vector import VectorTopo

zachranka = VectorTopo('adresnimista_zachranka', mapset='ruian_praha')
zachranka.open('r')
ulice = VectorTopo('ulice', mapset='ruian_praha')
ulice.open('r')

zu = VectorTopo('zachranka_ulice')
cols = [('cat',       'INTEGER PRIMARY KEY'),
        ('kod',       'INTEGER'),
        ('ulice',     'TEXT'),
        ('nespravny', 'INTEGER')]
zu.open('w', tab_cols=cols)

seznam = []
for z in zachranka:
    u = ulice.find['by_point'].geo(z, maxdist=1000.)
    if u is None:
        continue
    nespravny = z.attrs['ulicekod'] != u.attrs['kod']
    print (u'{:10} {:1} {}'.format(z.attrs['kod'], nespravny, u.attrs['nazev']))
    zu.write(z, (z.attrs['kod'], u.attrs['nazev'], nespravny))
    if u.cat not in seznam:
        zu.write(u, (None, u.attrs['nazev'], None))
        seznam.append(u.cat)

zu.table.conn.commit() # nutne pro zapis atributu !!!

zu.close()
zachranka.close()
ulice.close()

Skript ke stažení zde.

Varování

Velmi důležitý řádek je 29, kde dochází k zápisu atributů do atributové tabulky. Pokud nezavoláte funkci commit(), tak do výstupní vektorové mapy nezapíší žádné atributy!

Skript současně vypisuje na výstup kód záchranky, 0 nebo 1 podle toho, zda se nalezená nejbližší ulice shoduje s údajem z RÚIANu a nakonec adresu této ulice. Výpis může vypadat následovně:

40432211 0 Chrpová
40432408 1 Strašnická
40433048 0 Práčská
../_images/zachranka_ulice.png

Obrázek 1: Zvýraznění úseků ulic nejbližších dané záchrance.