HaxeMaps / Interaktivní vrstva

Cílem této ukázky je nastínit, jakým způsobem vytvořit interaktivní vrstvu, jejíž obsah lze modifikovat za pomoci myši. V této ukázce vytvoříme jednoduchou vrstvu značek vytyčujících určitou trasu. S některými značkami bude možné pohybovat pomocí myši, některé značky budou pevné. Kliknutím do mapy přidáme další značku.

1. Zdrojový kód

V první části zdrojového kódu vložíme do mapy novou vrstvu, zinicializujeme mapu a vytvoříme jednoduchou nástrojovou lištu obsahující několik tlačítek a zobrazující aktuální souřadnice pod kurzorem myši. Jedná se o obdobu příkladu Ovládání mapy. Dále využijeme událost MAP_CLICKED, kterou vyvolá třída Canvas při jednoduchém kliknutí do mapy, a vložíme do naší vrstvy nový bod pomocí metody addMark. Odlišnost od standardní dálosti myši je popsána v dokumentaci třídy Canvas.

example06.hx

  1. import flash.display.Sprite;
  2. import flash.events.Event;
  3. import map.Canvas;
  4. import map.LngLat;
  5. import map.TileLayer;
  6. import map.MapService;
  7. import com.Button;
  8. import com.ToolBar;
  9. import com.StatusBar;
  10.  
  11. class Example06 extends Sprite {
  12.  
  13.     var canvas:Canvas;
  14.     var toolbar:ToolBar;
  15.     var layer:InteractiveLayer;
  16.  
  17.     static public function main()
  18.     {
  19.        flash.Lib.current.stage.scaleMode = flash.display.StageScaleMode.NO_SCALE;
  20.        var t:Example06 = new Example06();
  21.        flash.Lib.current.stage.addEventListener(Event.RESIZE, t.stageResized);
  22.        flash.Lib.current.stage.addChildAt(t,0);
  23.     }
  24.  
  25.  
  26.     function new()
  27.     {
  28.         super();
  29.    
  30.         toolbar = new ToolBar();
  31.         canvas = new Canvas();
  32.         layer = new InteractiveLayer();
  33.  
  34.         toolbar.move(0, 0);
  35.         canvas.move(0, 0);
  36.         canvas.setCenter(new LngLat(16.685218,49.482312));
  37.         canvas.addLayer(new TileLayer(new OpenStreetMapService(14), 8));
  38.         canvas.addLayer(layer);
  39.  
  40.         stageResized(null);
  41.         initToolbar();
  42.  
  43.         addChild(canvas);
  44.         addChild(toolbar);
  45.  
  46.         canvas.initialize();
  47.  
  48.         var me = this;
  49.         canvas.addEventListener(MapEvent.MAP_CLICKED, function(e:MapEvent) { me.layer.addMark(e.point); });
  50.         canvas.addEventListener(MapEvent.MAP_MOUSEMOVE, mouseMove);
  51.  
  52.  
  53.     }
  54.  
  55.     public function stageResized(e:Event)
  56.     {
  57.         toolbar.setSize(flash.Lib.current.stage.stageWidth, 30);
  58.         canvas.setSize(flash.Lib.current.stage.stageWidth, flash.Lib.current.stage.stageHeight);
  59.     }
  60.  
  61.     function mouseMove(e:map.MapEvent)
  62.     {
  63.        toolbar.setText("longitude:" + LngLat.fmtCoordinate(e.point.lng) +
  64.                        " latitude:" + LngLat.fmtCoordinate(e.point.lat));
  65.     }
  66.  
  67.     function initToolbar()
  68.     {
  69.         var me = this;
  70.         toolbar.addButton(new ZoomOutButton(), "Zoom Out", function(b:CustomButton) { me.canvas.zoomOut(); });
  71.         toolbar.addButton(new ZoomInButton(), "Zoom In",  function(b:CustomButton) { me.canvas.zoomIn(); });
  72.     }
  73.  
  74. }
  75.  

Druhá část kódu obsahuje implementaci třídy InteractiveLayer. Abychom mohli reagovat na události myši, používáme standardní událost MouseEvent.MOUSE_DOWN (vyvolá se při stisknutí tlačítka myši) a MouseEvent.MOUSE_MOVE (vyvolá se při pohybu myši nad vrstvou), která slouží ke změně kurzoru z šipky na ručičku v případě najetí na bod, se kterým lze hýbat (detekováno pomocí funkce hitTest). Dále třída obsahuje metodu updateContent, která vykreslí registrované značky do mapy. V kódu je ukázáno, jak lze vykreslovat v závislosti na aktuálním zvětšení (od hrubšího měřítka se již nevykreslují body).

example06.hx

  1. import map.Layer;
  2. import flash.geom.Point;
  3. import flash.events.MouseEvent;
  4.  
  5. class InteractiveLayer extends Layer
  6. {
  7.     var marks_lat:Array<Float>;
  8.     var marks_lng:Array<Float>;
  9.     var marks_xy:Array<Point>;
  10.     var marks_fixed:Array<Bool>;
  11.     var marks_count:Int;
  12.     var mark_id:Int;
  13.  
  14.     public function new()
  15.     {
  16.         super();
  17.  
  18.         marks_lat = new Array<Float>();
  19.         marks_lng = new Array<Float>();
  20.         marks_fixed = new Array<Bool>();
  21.         marks_xy = new Array<Point>();
  22.         marks_count = 0;
  23.  
  24.         mouseEnabled = true;
  25.         buttonMode = false;
  26.  
  27.         addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
  28.         addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove2);
  29.  
  30.         //test points
  31.         addMark(new LngLat(16.660036,49.487759), true, false);
  32.         addMark(new LngLat(16.663343,49.486342), false, false);
  33.         addMark(new LngLat(16.668463,49.484107), true, false);
  34.         addMark(new LngLat(16.672148,49.483342), false, false);
  35.         addMark(new LngLat(16.678405,49.482557), false, false);
  36.         addMark(new LngLat(16.685218,49.482312), false, false);
  37.         addMark(new LngLat(16.694393,49.477777), true, false);
  38.         addMark(new LngLat(16.710615,49.471790), false, false);
  39.  
  40.    }
  41.  
  42.    public function addMark(point:LngLat, fixed:Bool = false,  update:Bool = true)
  43.    {
  44.         marks_lng.push(point.lng);
  45.         marks_lat.push(point.lat);
  46.         marks_fixed.push(fixed);
  47.         marks_count = marks_lng.length;
  48.  
  49.         if (update)
  50.            updateContent(true);
  51.    }
  52.  
  53.    /* mouse handling methods */
  54.    function hitTest(e:MouseEvent) : Int
  55.    {
  56.         var a:Point = getXY(globalToLocal(new Point(e.stageX, e.stageY)));
  57.         for (i in 0...marks_xy.length)
  58.             if ((Point.distance(marks_xy[i], a) < 8)  && (!marks_fixed[i]))
  59.               return i;
  60.         return -1;
  61.    }
  62.  
  63.    function onMouseDown(e:MouseEvent)
  64.    {
  65.         mark_id = hitTest(e);
  66.         if (mark_id != -1)
  67.         {
  68.            e.stopPropagation();
  69.  
  70.            removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove2);
  71.            removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
  72.            flash.Lib.current.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
  73.            flash.Lib.current.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
  74.         }
  75.              
  76.    }
  77.  
  78.    function onMouseUp(e:MouseEvent)
  79.    {
  80.         flash.Lib.current.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
  81.         flash.Lib.current.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
  82.         addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
  83.         addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove2);
  84.    }
  85.  
  86.    function onMouseMove2(e:MouseEvent)
  87.    {
  88.         buttonMode = false;
  89.         if (hitTest(e) != -1)
  90.            buttonMode = true;
  91.    }
  92.  
  93.    function onMouseMove(e:MouseEvent)
  94.    {
  95.         if (mark_id > -1)
  96.         {
  97.            var p:LngLat = getLngLat(globalToLocal(new Point(e.stageX, e.stageY)));
  98.            marks_lng[mark_id] = p.lng;
  99.            marks_lat[mark_id] = p.lat;
  100.            
  101.            updateContent(true);
  102.         }
  103.    }
  104.  
  105.    /* drawing methods */
  106.    function drawMark(p:Point, color:Int)
  107.    {
  108.         var s = new flash.display.Shape();
  109.         s.graphics.lineStyle(3,0xFFFFFF);
  110.         s.graphics.beginFill(color);
  111.         s.graphics.drawCircle(20, 20, 7);
  112.         s.graphics.endFill();
  113.  
  114.         s.filters = [new flash.filters.DropShadowFilter(3,145,0x000000, 0.5)];
  115.         var bd  = new flash.display.BitmapData(Std.int(s.width + 20),
  116.                                                Std.int(s.height + 20),
  117.                                                true, 0x00FFFFFF); //w,h
  118.         bd.draw(s);
  119.  
  120.         graphics.lineStyle(Math.NaN);
  121.         var matrix = new flash.geom.Matrix();
  122.         matrix.translate(p.x- bd.height / 2, p.y - bd.width / 2);
  123.         graphics.beginBitmapFill(bd, matrix, false);
  124.         graphics.drawRect(p.x - bd.height / 2, p.y - bd.width / 2, bd.height, bd.width);
  125.         graphics.endFill();
  126.    }
  127.  
  128.    override function updateContent(forceUpdate:Bool=false)
  129.    {
  130.         if (!forceUpdate) return;
  131.  
  132.         graphics.clear();
  133.         marks_xy = new Array<Point>();
  134.  
  135.         var a:Point = getOriginXY();
  136.         var b:Point = null;
  137.         var zz =  this.mapservice.zoom_def + zoom;
  138.         var ll = this.mapservice.lonlat2XY;
  139.  
  140.         //draw path
  141.         graphics.lineStyle(6,0x004080, 0.9);
  142.         for (i in 0...marks_count)
  143.         {
  144.             if (b != null)
  145.             {
  146.                b = ll(marks_lng[i], marks_lat[i], zz);
  147.                b = b.subtract(a);
  148.                graphics.lineTo(b.x, b.y);
  149.             }
  150.             else
  151.             {
  152.                b = ll(marks_lng[i], marks_lat[i], zz);
  153.                b = b.subtract(a);
  154.                graphics.moveTo(b.x, b.y);
  155.             }
  156.         }
  157.  
  158.         if (zoom < -2) return;
  159.  
  160.         //draw marks
  161.         for (i in 0...marks_count)
  162.         {
  163.             b = ll(marks_lng[i], marks_lat[i], zz);
  164.             marks_xy.push(b);
  165.             b = b.subtract(a);
  166.             drawMark(b, (marks_fixed[i]) ? 0xFF0000 : 0x004080);
  167.         }
  168.    }
  169.  
  170. }
  171.  

2. Výsledek

Aplikace obsahující interaktivní vrstvu. Modrými značkami lze pomocí myši pohybovat, červené značky jsou pevně definované. Kliknutím do mapy se vloží nová značka.

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: 755x Naposledy: 3.4.2024 12:25:02