Mapový server snadno a rychle (4)

1. 12. 2005
Doba čtení: 5 minut

Sdílet

V minulém díle jsme si mapfile rozšířili o několik (celkem tři) vrstev a z Pendolína (rychlíku) jsme se seznámili s mapovými projekcemi. V tomto dílu budeme jednotlivé vrstvy klasifikovat podle jejich databázových atributů. Nakonec si povíme něco o textových štítcích v mapě – jak na ně.

Třídy podle atributu

Třídy můžeme vytvářet na základě jejich atributů. V našem souboru obsahujícím státy states_ugl.shp, resp. v připojené databázové tabulce states_ugl.shp můžeme vidět sloupečky atributů:

$ ogrinfo -al -so states_ugl.shp
[...]
AREA: Real (12.3)
PERIMETER: Real (12.3)
STATESP020: Integer (11.0)
STATE: String (20.0)
STATE_FIPS: String (2.0)
CLASS: String (5.0) 

Rozhodli jsme se klasifikovat mapu na základě sloupečku class. Ten obsahuje buď slovo land nebo water. Specifikace sloupečku se děje atributem CLASSITEM, hledané výrazy jsou specifikovány atributem EXPRESSION, přičemž lze využívat i regurální výrazy:

  LAYER # začátek vrstvy ploch států
    NAME        staty_plochy
    DATA        states_ugl
    TYPE        POLYGON
    STATUS      OFF
    CLASSITEM   'class'
    PROJECTION
         "init=epsg:4326"
    END

    CLASS # třída pevniny
        NAME 'Plochy států'
        EXPRESSION 'land'
        STYLE # jak bude třída vypadat
            COLOR 225 225 185
        END # konec stylu
    END # konec pevniny

    CLASS # třída jezer
        NAME 'Plochy jezer'
        EXPRESSION 'water'
        STYLE
            COLOR      198 198 255
          END
    END # konec jezer
  END # konec vrstvy 

Po reloadu stránky by se měla jezera objevit. Všechny textové řetězce se vyplatí uzavřít do uvozovek. Všimněte si, že na pořadí vrstev záleží. Vrstvy se vykreslují tak, jak jsou v mapfilu psány – odshora dolů. Kdybychom vrstvy otočili,

LAYER
    NAME        staty_hranice
    ...
END
LAYER
    NAME        stat_plochy
    ...
END 

nebudou hranice států vůbec vykresleny, ačkoliv budou zapnuty a vše bude korektně nastaveno.

Textové štítky v mapě

Důležitou funkcí jsou textové popisky v mapách. Musí být vyvedeny v určitém měřítku, nesmí se překrývat. Sloupeček v tabulce, ze kterého se mají štítky brát, se nastavuje atributem LABELITEM. Vlastní vzhled popisku je popsán v objektu LABEL , ukončeném END. Písmo může být buď bitmapové a nebo TrueType fonty. Používáme-li TrueType, musíme nastavit na začátku mapfilu cestu k seznamu aliasů k těmto fontům, tzv. fontlistu. Každý řádek v souboru má dvě klíčová slova: Alias, pomocí kterého se budeme na font odkazovat, a cesta/k/fontu.ttf. Cesta je buď relativní (vzhledem k fontlistu), nebo absolutní. Máte-li nějaký adresář s TrueType fonty, máte práci o to jednodušší. Pokud ne nebo chcete spíše využít nějaké jiné, můžete je vybrat na příklad z archivu Itasca-demo. Vytvořme tedy soubor font.list v adresáři  /var/mapservdata:

cd /var/mapservdata
$EDITOR font.list

mono-bold-oblique       /usr/share/fonts/truetype/freefont/FreeMonoBoldOblique.ttf
mono-bold               /usr/share/fonts/truetype/freefont/FreeMonoBold.ttf
mono-oblique            /usr/share/fonts/truetype/freefont/FreeMonoOblique.ttf
mono                    /usr/share/fonts/truetype/freefont/FreeMono.ttf
sans-bold-oblique       /usr/share/fonts/truetype/freefont/FreeSansBoldOblique.ttf
sans-bold               /usr/share/fonts/truetype/freefont/FreeSansBold.ttf
sans-oblique            /usr/share/fonts/truetype/freefont/FreeSansOblique.ttf
sans                    /usr/share/fonts/truetype/freefont/FreeSans.ttf
serif-bold-italic       /usr/share/fonts/truetype/freefont/FreeSerifBoldItalic.ttf
serif-bold              /usr/share/fonts/truetype/freefont/FreeSerifBold.ttf
serif-italic            /usr/share/fonts/truetype/freefont/FreeSerifItalic.ttf
serif                   /usr/share/fonts/truetype/freefont/FreeSerif.ttf 

Takto to mám já nastaveno na svém Debianu. Doplníme řádek s atributem FONTSET do objektu  MAP:

MAP
  NAME ITASCA   # každý objekt by měl být pojmenován
  SIZE 400 300  # výchozí velikost mapy v pixelech
  EXTENT 208398.01 -372335.44 1285308.08 632638.93 # hraniční souřadnice v projekci US Nat. Atl.
  UNITS METERS
  SHAPEPATH "/var/mapservdata/data/" # Cesta k datům
  IMAGECOLOR 255 255 255 # Barva pozadí
  IMAGETYPE PNG
  FONTSET '/var/mapservdata/font.list'
  [...] 

A nyní již můžeme doplnit do objektu CLASS objekt LABEL. Ukažme si ucelenější blok:

CLASS # třída pevniny
    [...]
    CLASSITEM   'class' # podle čeho dělit třídy
    LABELITEM   'state' # z jakého sloupečku brát popisky
    LABEL
        COLOR 132 31 31
        SHADOWCOLOR 218 218 218
        SHADOWSIZE 2 2
        TYPE TRUETYPE
        FONT arial-bold
        SIZE 12
        ANTIALIAS TRUE
        MINDISTANCE 300
        BUFFER 4
    END # end of label 

Atributy jsou vesměs samovysvětlující. Ty méně jasné si přiblížíme:

SIZE
Velikost písma se zadává buď v pixelech (v případě TrueType fontů), nebo klíčovými slovy (tiny,small,me­dium,large,gi­ant).
MINDISTANCE
Udává minimální vzálenost mezi opakovanými štítky (v pixelech).
BUFFER
V pixelech zadaný obvod okolo každého štítku tak, aby se tyto navzájem nekryly.

Štítky jsou vždy vykreslovány na novém místě tak, aby byly pokud možno uprostřed mapového objektu a aby se zároveň s okolními štítky nepřekrývaly.

Přidávání rastrových vrstev

Doposud jsme se zabývali pouze vektorovými soubory, shodou okolností uloženými ve formátu ESRI Shape. Snad každý ze čtenářů ROOTa chápe rozdíl mezi rastrovým a vektorovým formátem. Rastrová vrstva je jako každá jiná:

  LAYER # začátek družicového snímku
    NAME         modis
    DATA         'mod09a12003161_ugl_ll_idxa.tif'
    STATUS       OFF
    TYPE         RASTER
    OFFSITE      71 74 65
    PROJECTION
          "init=epsg:4326"
    END
  END # konec družicového snímku. 

Protože již víme, že mapfile je zpracováván odshora dolů a že tedy vrstvy definované později překryjí vrstvy definované dříve, umístili jsme rastrovou vrstvu před obě vrstvy vektorové. Upravíme-li url našeho obrázku na http://localhos­t/cgi-bin/mapserv?map=/var/m­apservdata/je­zera.map &layer=staty_hra­nice&layer=sta­ty_plochy &layer=modis&mo­de=map (Mezery přidány kvůli řádkovému zlomu. – poznámka editora), zjistíme, že vykreslování trvá o něco déle a také, že vrstva států překryla vrstvu rastrovou.

Řešení jsou v podstatě dvě: Buď nastavíme barvu států na zcela průhlednou:

CLASS # třída pevniny
        NAME 'Plochy států'
        STYLE
            COLOR -1 -1 -1
        END
        ...
END 

a nebo použijeme parametr TRANSPARENCY objektu LAYER:

bitcoin_skoleni

LAYER # začátek vrstvy ploch států
    NAME        staty_plochy
    TRANSPARENCY 50
    ...
END 

Vyzkoušejte si obě možnosti. Pro úplnost celý dosavadní mapfile se všemi úpravami:

# Můj první mapfile mapserveří aplikace
#

# počátek mapfilu
MAP
  NAME Jezera   # každý objekt by měl být pojmenován
  SIZE 400 300  # výchozí velikost mapy v pixelech
  EXTENT 208398.01 -372335.44 1285308.08 632638.93 # hraniční souřadnice v projekci US Nat. Atl.
  UNITS METERS
  SHAPEPATH "/var/mapservdata/data/" # Cesta k datům
  IMAGECOLOR 255 255 255 # Barva pozadí
  IMAGETYPE PNG
  FONTSET '/var/mapservdata/font.list'
  PROJECTION
          "init=epsg:2163"
  END

###########################################################
# začátek všech vrstev
###########################################################
 LAYER # začátek družicového snímku
    NAME         modis
    DATA         'mod09a12003161_ugl_ll_idxa.tif'
    STATUS       OFF
    TYPE         RASTER
    OFFSITE      71 74 65
    PROJECTION
          "init=epsg:4326"
    END
  END # MODIS raster layer ends here

  LAYER # začátek vrstvy ploch států
    NAME        staty_plochy
    DATA        states_ugl
    TYPE        POLYGON
    STATUS      OFF
    CLASSITEM   'class'
    LABELITEM   'state'
    PROJECTION
          "init=epsg:4326"
    END

    CLASS # třída pevniny
        NAME 'Plochy států'
        EXPRESSION 'land'
        STYLE # jak bude třída vypadat
            COLOR -1 -1 -1
        END # konec stylu
        LABEL
            COLOR 132 31 31
            SHADOWCOLOR 218 218 218
            SHADOWSIZE 2 2
            TYPE TRUETYPE
            FONT sans-bold
            SIZE 12
            ANTIALIAS TRUE
            POSITION CL
            PARTIALS FALSE
            MINDISTANCE 300
            BUFFER 4
       END # end of label
    END # konec pevniny

    CLASS # třída jezer
        NAME 'Plochy jezer'
        EXPRESSION 'water'
        STYLE
            COLOR      198 198 255
        END
    END # konec jezer
  END # konec vrstvy

  LAYER # začátek vrstvy
    NAME        staty_hranice # jak se jmenuje
    DATA        states_ugl # v jakém souboru (souborech) se nachází
    TYPE        LINE # typ dat
    STATUS      OFF
    PROJECTION
          "init=epsg:4326"
    END
    CLASS # začátek třídy
        NAME 'Hranice států'
        STYLE # jak bude třída vypadat
            COLOR 128 128 128
        END # konec stylu
    END # konec tříd
  END # konec vrstvy

###########################################################
# konec všech vrstev
###########################################################
END 

Závěr

Doposud jsme využívali UMN MapServer jen omezeně – prostě nám vygeneroval obrázek – toť vše. Příště si připravíme šablonu celé HTML stránky – konečně něco, co bude vypadat jako webová aplikace.

Autor článku