HaxeMaps / Layer

Bázová třída implementuje nezbytné funkce pro práci s mapovou vrstvou. Instance třídy Layer se nepoužívá přímo, ale je určena k dalšímu rozšíření o renderovací funkcionalitu. Tvorbě vektorových a rastrových vrstev se věnuje sekce Rozšíření funkcionality.

1. Metody

map.Layer (extends Sprite)

  • Layer(map_service:MapService = null, scalable:Bool = false)

    Vytvoří instanci třídy Layer, která se stará o vykreslování mapového podkladu. Parametr map_service určuje mapovou službu, která bude použita pro transformaci souřadnic, parametr scalable definuje, zda-li se bude jednat o vrstvu, u které bude možné měnit měřitkou pouze pomocí vlastnosti scaleX respektive scaleY (výhodné pro vektorové vrstvy, které nevyžadují update obsahu při změně měřítka).

    Není-li specifikována mapová služba map_service, použije se při inicializaci vrstvy služba z první vrsty registrované ve správci vrstev, která má službu specifikovánu (při použití jedné mapové služby je postačující uvést parametr map_service pouze u jedné vrstvy). Mapová služba se používá 1) pro vykreslování rastrových dat a 2) pro přepočet souřadnic z geodetických na rovinné.

  • initialize(update:Bool=true) : Int

    Inicializace vrstvy, která je volána správcem vrstev (objektem Canvas) v okamžiku, kdy jsou nastaveny všechny nezbytné parametry jako je a) úroveň přiblížení, b) souřadnice středu, c) clipbox a d)zdroj dat. Parametr update určuje, zda-li se má zahájit načítání / generování dat nebo nikoliv a používá se při vytváření uživatelských vrstev.

    Metoda vrací hodnotu 0 v případě úspěšné inicializace a nastavuje proměnnou initialized na True. V případě chyby obsahuje návratová hodnota číslo chybového kódu.

    V případě, že je metoda volána na již zinicializovanou vrstvu, provede se volání finalize() a teprve poté následuje vlastní inicializace.

  • finalize()

    Metoda je volána při požadavku na uvolnění alokovaných dat a nastavuje proměnnou initialized na False.

  • clear()

    Uvolní alokované objekty. Tato metoda je volána před odstraněním vrstvy či změnou obsahu.

  • getOriginXY():Point

    Vrací souřadnici počátku (středu) vrstvy v pixelech umístěného na pozici (0,0). Ve spojení getPointXY se používá k určení pozice v rámci vykreslovacího plátna vrstvy při kreslení.

    Ukázka vykreslení kružnice na souřadnice (16.0, 49.0) a (16.1, 49.1)

    override function updateContent(forceUpdate:Bool=false)
    {
       if (!forceUpdate) return;
     
       graphics.clear();
       graphics.lineStyle(4,0xF00040);
       var a:Point = getOriginXY();
     
       var b:Point = getPointXY(new LngLat(16.0, 49.0));
       b = b.subtract(a);
       graphics.drawCircle(b.x, b.y, 5);
     
       b = getPointXY(new LngLat(16.1, 49.1));
       b = b.subtract(a);
       graphics.drawCircle(b.x, b.y, 5);
    }

    Poznámka: Pro rychlejší přepočet je možné využít přímo metod služby map_service. Rozdělení na getOriginXY a getPointXY bylo zvoleno z důvodu redukce množství přepočtů. Při vykreslování postačí zjistit pouze jednou souřadnice počatku a ty poté odečítat od souřadnic vykreslovaných bodů.

  • getCenterXY():Point

    Vrací souřadnici v pixelech bodu, který se právě nachází uprostřed výřezu (clipboxu).

  • getPointXY(point:LngLat):Point

    Vrací souřadnici v pixelech bodu point.

  • getCenter():LngLat

    Vrací souřadnice bodu, který se právě nachází uprostřed výřezu.

  • getLngLat(local:Point):LngLat

    Vrací souřadnice bodu, který se nachází na souřadnicích local vztažených k aktuálnímu výřezu (vrstvě).

    Tuto metodu lze použít pro zjištění souřadnice bodu nacházejícího se pod kurzorem myši

    function onLayerMouseMove(e:MouseEvent)
    {
      var pt = layer.globalToLocal(new Point(e.stageX, e.stageY));
      statusbar.setText(layer.getLngLat(pt));
    }
  • setCenter(point:LngLat)

    Nastaví vrstvu tak, aby uprostřed výřezu byl bod s požadovanými souřadnicemi.

  • moveRelative(dx:Float, dy:Float)

    Posune vrstvu o hodnotu dx v ose X a dy v ose Y. Kladné hodnoty odpovídají posuvu směrem doprava/ nahoru, záporné hodnoty naopak. Tuto metodu není zapotřebí volat přímo.

  • moveTo(x:Float, y:Float)

    Posune vrstvu tak, aby její souřadnice uvnitř plátna odpovídaly hodnotám x,y. Tuto metodu není zapotřebí volat přímo.

  • validZoom(zoom:Int) : Bool

    Vrací True, je-li hodnota relativního přiblížení v přípustném rozsahu.

  • zoomIn()

    Plynule o jeden krok zvýší rozlišení mapy. Pokud mapový zdroj neposkytuje detailnější data případně již probíhá změna rozlišení, či vrstva nebyla inicializována, pokus o přiblížení je ignorován.

  • zoomOut()

    Plynule o jeden krok sníží rozlišení mapy. Pokud mapový zdroj neposkytuje detailnější data případně již probíhá změna rozlišení, či vrstva nebyla inicializována, pokus o přiblížení je ignorován.

  • setZoom(zoom:Int)

    Nastavení konkrétní hodnoty relativního přiblížení bez animace. Rozsah a význam hodnot je možné nalézt v popisu stejnojmenné funkce třídy Canvas. Pokus o nastavení přiblížení, které nedovoluje použitý mapový zdroj je ignorován.

Privátní metody

  • updateContent(forceUpdate:Bool=false)

    Tato metoda je volána pokaždé, když se změní obsah výřezu, tzn. tehdy, dojde-li k posunu mapy nebo změně měřítka. Parametr forceUpdate má hodnotu True tehdy, pokud se jedná o inicializaci nebo změnu měřítka. Pokud se jedná o vektorovou vrstvu, která využívá scalable (viz popis konstruktoru), pak je dostačující přegenerovat obsah vrstvy pouze při prvním volání této funkce, neboť změna měřítka i posun je řešen v rámci metod třídy Layer.

    Třída Layer tuto metodu neimplementuje.

2. Rozšíření funkcionality

Odvozené třídy musí obsahovat a implementovat minimálně metodu updateContent(), která se stará o vykreslení aktuálního obsahu. Protože třída Layer je potomkem třídy Sprite, je možné obsah vytvářet několika způsoby.

  1. Obsah lze kreslit přímo do objektu prostřednictvím atributu graphics

    override function updateContent(forceUpdate:Bool=false)
    {
        if (!forceUpdate) return;
     
        graphics.clear();
        graphics.lineStyle(1,0xFF0000);
        graphics.moveTo(...,...);
        graphics.moveTo(...,...);
     
    }

    Pokud se jedná o čistě vektorovou vrstvu, kterou je možné vykreslit celou a u které změna měřítka odpovídá přímo zvětšení nebo změnšení, pak stačí obsah vykreslit pouze při prvním volání metody updateContent. Pokud je možné vrstvu vykreslit celou avšak při změně měřítka je nutné provést update, stačí obsah vykreslit při každém volání metody updateContent, kdy parametr forceUpdate má hodnotu True. Pokud vykreslujeme pouze část vrstvy dle aktuálního výřezu, je nutné překreslit obsah při každém volání metody updateContent.

    Tento přístup je použit např. v ukázce Tvorba vlastní vektorové vrstvy (a mapy) (škálovatelná vektorová vrstva) a dále ukázce Interaktivní vrstva (vrstva měnící se se změnou úrovně přiblížení).

  2. Obsah lze realizovat vkládáním grafických elementů pomocí metody addChild

    override function updateContent(forceUpdate:Bool=false)
    {
        if (!forceUpdate) return;
     
        //remove all objects
        while (numChildren > 0) removeChildAt(0);
     
        //add objects
        var s:Shape = new Shape();
        s.x = ...;
        s.y = ...;
        ...
        addChild(s);
     
    }

    Tento přístup používá ukázka Propojení s WMS službami, kde jsou podobným mechanismem vkládány načtená data z WMS služby.

  3. Obsah lze vytvořit kombinací předchozích přístupů. Např. značky lze realizovat pomocí objektu Shape, cesty lze kreslit.

3. Použití

Příklad realizace vektorové vrstvy, která vykresluje dva body na předem dané souřadnice. Vektorová vrstva je vždy překreslena při změně měřítka. Kružnice mají tedy stále poloměr 5 bodů.

class TestLayer extends Layer
{
 
 override function updateContent(forceUpdate:Bool=false)
 {
     if (!forceUpdate) return;
 
     graphics.clear();
     graphics.lineStyle(1,0xF00040);
 
     var a:Point = getOriginXY();
 
     var b:Point = getPointXY(new LngLat(16.0,49.0)).subtract(a);
     graphics.drawCircle(b.x, b.y, 5);
 
     b = getPointXY(new LngLat(16.1,49.1)).subtract(a);
     graphics.drawCircle(b.x, b.y, 5);
 
 }
 
}

Nová vrstva se použije např. následovně

function init()
{
 canvas = new Canvas();
 canvas.setSize(100,100);
 canvas.addLayer(new TileLayer(new OpenStreetMapService(), 8));
 canvas.addLayer(new TestLayer());
 canvas.initialize();
}

Specifikovat službu v konstruktoru vrstvy TestLayer není zapotřebí, neboť se využije služba z OpenStreetMapService z předchozí vrsty. Služba tedy slouží nejen jako zdroj dlaždic ale také k přepočtu souřadnic

Zobrazeno: 832x Naposledy: 19.4.2024 12:20:56