HaxeMaps / Tvorba vlastní vektorové vrstvy (a mapy)

V tomto příkladu si ukážeme, jakým způsobem se vytváří vektorová vrstva a jak je možné ji zkombinovat s rastrovou mapou. Cílem bude vytvořit nejprve vektorovou krajů ČR a doplnit ji o rastrovou mapu, používanou v předchozích ukázkách.

1. Zdrojový kód

Zdrojový kód se skládá opět ze dvou částí. V první části používáme obdobu kódu uvedeného v příkladu Ovládání mapy, kde zinicializujeme mapu a vytvoříme jednoduchou nástrojovou lištu pomocí které bude možné mapu ovládat. Oproti předchozímu případu však použijeme vlastní vektorovou vrstvu nazvanou VectorLayer. Protože kombinace s rastrovou mapou je snadná, použijeme stejný kód pro obě aplikace s tím, že použijeme přepínač TILE_LAYER.

Vložení vektorové vrstvy provedeme příkazem

canvas.addLayer(new VectorLayer(new OpenStreetMapService(12)));

Hodnota 12 definuje výchozí přiblížení mapy, pro které budeme renderovat vektorovou mapu - budeme využívat možnosti automatické změny měřítka (viz popis parametru scale třídy Layer). Dodejme, že následuje parametr canvas.setZoom(-4);, který nastaví 4x hrubší měřítko, tedy hodnotu 8. Pokud bychom renderovali vrstvu přímo pro přiblížení 8, může dojít v závislosti na datech ke ztrátě detailů (v našem případě by došlo ke ztrátě přesnosti na hranicích krajů, neboť body na jsou v přiblížení 8 blíže než jeden pixel).

example04.hx

  1. import flash.display.Sprite;
  2. import flash.events.Event;
  3. import map.Canvas;
  4. import map.LngLat;
  5. import map.MapService;
  6. import com.Button;
  7. import com.ToolBar;
  8.  
  9. class Example04 extends Sprite {
  10.  
  11.     var canvas:Canvas;
  12.     var toolbar:ToolBar;
  13.  
  14.     static public function main()
  15.     {
  16.        flash.Lib.current.stage.scaleMode = flash.display.StageScaleMode.NO_SCALE;
  17.        var t:Example04 = new Example04();
  18.        flash.Lib.current.stage.addEventListener(Event.RESIZE, t.stageResized);
  19.        flash.Lib.current.stage.addChildAt(t,0);
  20.     }
  21.  
  22.  
  23.     function new()
  24.     {
  25.         super();
  26.    
  27.         toolbar = new ToolBar();
  28.         canvas = new Canvas();
  29.  
  30.         toolbar.move(0, 0);
  31.         canvas.move(0, 0);
  32.         canvas.setCenter(new LngLat(15.5,49.5));
  33.         #if TILE_LAYER
  34.         canvas.addLayer(new map.TileLayer(new OpenStreetMapService(12), 8));
  35.         #end
  36.         canvas.addLayer(new VectorLayer(new OpenStreetMapService(12)));
  37.         canvas.setZoom(-4);
  38.         stageResized(null);
  39.  
  40.         initToolbar();
  41.  
  42.         addChild(canvas);
  43.         addChild(toolbar);
  44.  
  45.         canvas.initialize();
  46.         canvas.addEventListener(MapEvent.MAP_MOUSEMOVE, mouseMove);
  47.  
  48.     }
  49.  
  50.     public function stageResized(e:Event)
  51.     {
  52.         toolbar.setSize(flash.Lib.current.stage.stageWidth, 30);
  53.         canvas.setSize(flash.Lib.current.stage.stageWidth, flash.Lib.current.stage.stageHeight);
  54.     }
  55.  
  56.     function initToolbar()
  57.     {
  58.         var me = this;
  59.         toolbar.addButton(new ZoomOutButton(), "Zoom Out", function(b:CustomButton) { me.canvas.zoomOut(); });
  60.         toolbar.addButton(new ZoomInButton(), "Zoom In",  function(b:CustomButton) { me.canvas.zoomIn(); });
  61.         toolbar.addSeparator(30);
  62.         //pan buttons
  63.         toolbar.addButton(new UpButton(), "Move up",  function(b:CustomButton) { me.pan(1); });
  64.         toolbar.addButton(new DownButton(), "Move down",  function(b:CustomButton) { me.pan(2); });
  65.         toolbar.addButton(new LeftButton(), "Move left",  function(b:CustomButton) { me.pan(4); });
  66.         toolbar.addButton(new RightButton(), "Move right",  function(b:CustomButton) { me.pan(8); });
  67.     }
  68.  
  69.     function pan(direction:Int)
  70.     {
  71.        var lt:LngLat = canvas.getLeftTopCorner();
  72.        var br:LngLat = canvas.getRightBottomCorner();
  73.        var p:LngLat  = canvas.getCenter();
  74.  
  75.        if (direction & 0x3 == 1) p.lat = lt.lat; //up
  76.        if (direction & 0x3 == 2) p.lat = br.lat; //down
  77.        if (direction & 0xC == 4) p.lng = lt.lng; //left
  78.        if (direction & 0xC == 8) p.lng = br.lng; //right
  79.  
  80.        canvas.panTo(p);
  81.     }
  82.  
  83.     function mouseMove(e:map.MapEvent)
  84.     {
  85.        toolbar.setText("longitude:" + LngLat.fmtCoordinate(e.point.lng) +
  86.                        " latitude:" + LngLat.fmtCoordinate(e.point.lat) +
  87.                        " zoom:" + canvas.getZoom());
  88.     }
  89.  
  90. }

Druhá část obsahuje třídu VectorLayer, která načte data ze 14-ti souborů obsahujících definiční body obrysů jednotlivých krajů a tyto data vyrenderuje.

example04.hx

  1. import flash.net.URLLoader;
  2. import flash.net.URLRequest;
  3. import flash.utils.ByteArray;
  4. import flash.geom.Point;
  5. import map.Layer;
  6.  
  7. class VectorLayer extends Layer
  8. {
  9.     static var URL:String = "http://www.fit.vutbr.cz/~vasicek/map_proxy.php?service=k&id=";
  10.  
  11.     var plon:Array<Float>;
  12.     var plat:Array<Float>;
  13.     var colors:Array<Int>;
  14.  
  15.     public function new(map_service:MapService = null)
  16.     {
  17.         super(map_service, true);
  18.  
  19.         plon = new Array<Float>();
  20.         plat = new Array<Float>();
  21.         colors = [0xB2182B, 0xD6604D, 0xF4A582, 0xFDDBC7, 0xE0E0E0,
  22.                   0xBABABA, 0x878787, 0x4D4D4D, 0xD9EF8B, 0xA6D96A,
  23.                   0x66BD63, 0x1A9850, 0x92C5DE, 0x4393C3];
  24.  
  25.         for (i in 0...14)
  26.         {
  27.             var urlLoader:URLLoader = new URLLoader();
  28.             urlLoader.dataFormat = flash.net.URLLoaderDataFormat.BINARY;
  29.             urlLoader.addEventListener(Event.COMPLETE, processData);
  30.             urlLoader.addEventListener(flash.events.IOErrorEvent.IO_ERROR,
  31.                                        function(e) { trace("Can't load data");}
  32.                                       );
  33.  
  34.             try {
  35.                 var urlRequest:URLRequest = new URLRequest(URL+(14-i));
  36.                 urlLoader.load(urlRequest);
  37.             } catch (unknown : Dynamic)  {
  38.                 trace("Error - Unable to load data");
  39.             }
  40.         }
  41.  
  42.     }
  43.  
  44.     function processData(e:Event)
  45.     {
  46.         var loader:URLLoader = e.target;
  47.         loader.removeEventListener(Event.COMPLETE, processData);
  48.  
  49.         var b:ByteArray = loader.data;
  50.         try
  51.         {
  52.            b.uncompress();
  53.  
  54.            var s:String = b.readUTF();
  55.            //trace(s);
  56.  
  57.            if (plat.length > 0)  
  58.            {
  59.              plat.push(0); //sentinel
  60.              plon.push(0); //sentinel
  61.            }
  62.  
  63.            var len:Int =  b.readUnsignedShort();
  64.            for (i in 0...len)
  65.            {
  66.                plat.push(b.readDouble());
  67.                plon.push(b.readDouble());
  68.            }
  69.  
  70.            updateContent(true);
  71.  
  72.         }
  73.         catch (unknown : Dynamic)  
  74.         {
  75.             trace("Error - Unable to read data");
  76.         }
  77.     }
  78.  
  79.     override function updateContent(forceUpdate:Bool=false)
  80.     {
  81.         if (!forceUpdate) return;
  82.  
  83.         var z:Int = this.mapservice.zoom_def;
  84.         var l2pt = this.mapservice.lonlat2XY;
  85.         var cpt:Point = l2pt(center.lng, center.lat, z);
  86.         var pt:Point;
  87.         var calpha = #if TILE_LAYER 0.5 #else 0.9 #end;
  88.  
  89.         graphics.clear();
  90.         graphics.lineStyle(1,0xF00040);
  91.         graphics.beginFill(0xF00000, calpha);
  92.  
  93.         var first:Bool = true;
  94.         var id:Int = 0;
  95.  
  96.         for (i in 0...plon.length)
  97.         {
  98.             if ((plon[i] == 0) && (plat[i] == 0))
  99.             {
  100.                graphics.endFill();
  101.                first = true;
  102.                graphics.beginFill(colors[id], calpha);
  103.                id++;
  104.                continue;
  105.             }
  106.  
  107.             pt = l2pt(plon[i],plat[i], z);
  108.             if (!first)
  109.             {
  110.                graphics.lineTo((pt.x - cpt.x), (pt.y - cpt.y));
  111.             }
  112.             else
  113.             {
  114.                graphics.moveTo((pt.x - cpt.x), (pt.y - cpt.y));
  115.                first = false;
  116.             }
  117.         }
  118.  
  119.         graphics.endFill();
  120.     }
  121. }
  122.  

2. Překlad a Html kód

Pro překlad platí informace uvedené v Ukázka použití, avšak nyní použijeme výchozí třídu Example04, kterou jsme implementovali v souboru example04.hx. Pro vložení do Html stránky lze využít kód uvedený v předchozím příkladu.

Pro vytvoření čistě vektorové mapy (viz první ukázka) použijeme

> haxe -swf output.swf -swf-version 9 -main Example04 -swf-header 800:600:25:ffffff -cp haxemaps

Pro vytvoření mapy kombinující vektorovou a rastrovou vrstvu (viz druhá ukázka) použijeme

> haxe -swf output.swf -swf-version 9 -main Example04 -swf-header 800:600:25:ffffff -cp map -D TILE_LAYER

3. Výsledek

Pro správnou funkci je vyžadován Flash player
   


Deprecated: Function ereg() is deprecated in /home2/web/homes/vasicek/private/notes/web/data/map/examples.php on line 12

Zobrazeno: 1917x Naposledy: 25.4.2024 12:29:00