HaxeMaps / Navigace pomocí služby Nominatim (Geocoding)

V této ukázce přidáme k interaktivní mapě propojení se službou OpenStreetMap Nominatim, které umožní hledat určitou adresu (překlad z adresy na geografické souřadnice). Podobné služby poskytuji i služba Google Geocoding, ovšem její použití je možné pouze pro soukromé účely.

1. Nominatim

Abychom vyhledali souřadnice určité adresy, je nutné metodou GET zažádat o stránku,

http://nominatim.openstreetmap.org/search?q=Brno,CZ&format=xml

kde parametr q obsahuje dotazovaný řetězec a format definuje požadovaný výstupní formát. Odpověď vypadá následovně.

<searchresults
      timestamp="Tue, 20 Feb 10 18:29:52 +0000"
      attribution="Data Copyright OpenStreetMap Contributors, Some Rights Reserved. CC-BY-SA 2.0."
      querystring="Brno,CZ" polygon="false"
      exclude_place_ids="16290"
>
  <place
      place_id="16290" osm_type="node" osm_id="21308975"
      boundingbox="49.0349487,49.3549487,16.4493039,16.7693039"
      lat="49.1949487" lon="16.6093039"
      display_name="Brno, Jihomoravský kraj, Česká Republika, Europe"
      class="place" type="city"
      icon="http://nominatim.openstreetmap.org/images/mapicons/poi_place_city.p.20.png"
  />
</searchresults>

2. Zdrojový kód

Zdrojový kód se skládá 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 obsahující textové pole, do kterého bude možné zadat hledanou adresu a dále tlačítko pomocí kterého se odešle požadavek. Při úspěšné odpovědi služby Geocoding se nastaví mapa na souřadnice obdržené v odpovědi a v pravém horním rohu se vypíše výsledek dotazu.

example03.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 Example03 extends Sprite {
  12.  
  13.     var canvas:Canvas;
  14.     var toolbar:ToolBar;
  15.     var gc:OSMGeoCoding;
  16.  
  17.     static public function main()
  18.     {
  19.        flash.Lib.current.stage.scaleMode = flash.display.StageScaleMode.NO_SCALE;
  20.        var t:Example03 = new Example03();
  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.  
  33.         toolbar.move(0, 0);
  34.         canvas.move(0, 0);
  35.         canvas.setCenter(new LngLat(16.720,49.570));
  36.         canvas.addLayer(new TileLayer(new OpenStreetMapService(14), 8));
  37.  
  38.         stageResized(null);
  39.         initToolbar();
  40.  
  41.         addChild(canvas);
  42.         addChild(toolbar);
  43.  
  44.         canvas.initialize();
  45.  
  46.         gc = new OSMGeoCoding();
  47.         gc.addEventListener(OSMGeoCoding.QUERY_FINISHED, queryFinished);
  48.     }
  49.  
  50.     function queryFinished(e:Event)
  51.     {
  52.         toolbar.setText("Address:" + gc.address);
  53.         canvas.setCenter(gc.point);
  54.     }
  55.  
  56.     function initToolbar()
  57.     {
  58.         var me = this;
  59.         var tf = toolbar.addTextField(200,"Božetěchova, Brno, CZ","Address:", -10);
  60.         toolbar.addButton(new SearchButton(), "Find", function(b:CustomButton) { me.gc.query(tf.text); });
  61.  
  62.         tf.addEventListener(flash.events.KeyboardEvent.KEY_DOWN,
  63.                               function(e:flash.events.KeyboardEvent) {  
  64.                                         if (e.keyCode == flash.ui.Keyboard.ENTER) me.gc.query(tf.text);
  65.                               }
  66.                            );
  67.     }
  68.  
  69.     public function stageResized(e:Event)
  70.     {
  71.         toolbar.setSize(flash.Lib.current.stage.stageWidth, 30);
  72.         canvas.setSize(flash.Lib.current.stage.stageWidth, flash.Lib.current.stage.stageHeight-20);
  73.     }
  74.  
  75. }

V druhé části je implementován jednoduchý Geocoding client, který umí odeslat požadavek na server a dekódovat odpověď. Jedná se o zjednodušenou implementaci, neboť a) vracíme první bod v odpovědi ačkoliv může obsahovat více výsledků, b) ignorujeme informaci o nejvhodnější úrovni přiblížení.

example03.hx

  1. import flash.net.URLLoader;
  2. import flash.net.URLRequest;
  3. import flash.net.URLVariables;
  4.  
  5. class OSMGeoCoding extends URLLoader {
  6.  
  7.     //Info:
  8.     //-----------------------------------------------------------------------------
  9.     //  http://wiki.openstreetmap.org/wiki/Nominatim
  10.  
  11.     public static var QUERY_FINISHED:String = "queryfinished";
  12.     public var point:LngLat;
  13.     public var address:String;
  14.  
  15.     public function new()
  16.     {
  17.         super();
  18.         this.point = null;
  19.         this.address = "";
  20.     }
  21.  
  22.     public function query(text:String)
  23.     {
  24.         var request:URLRequest = new URLRequest("http://nominatim.openstreetmap.org/search");
  25.         request.data = new URLVariables();
  26.         request.data.format = "xml";
  27.         request.data.q = text;
  28.         request.method = flash.net.URLRequestMethod.GET;
  29.         try {
  30.             dataFormat = flash.net.URLLoaderDataFormat.TEXT;
  31.             load(request);
  32.             addEventListener(Event.COMPLETE, getResponse);
  33.         } catch (unknown : Dynamic)  {
  34.             trace("Error:"+unknown);
  35.         };
  36.     }
  37.  
  38.     function getResponse(e:Event)
  39.     {
  40.         removeEventListener(Event.COMPLETE, getResponse);
  41.  
  42.         try {
  43.  
  44.            var resp:Xml = Xml.parse(data);
  45.            //trace("Response:" + resp);
  46.  
  47.            var el:Xml = resp.firstElement();
  48.            if ((el != null) && (el.nodeName == "searchresults")) {
  49.               for (ep in el.elementsNamed("place"))
  50.                   if (ep.exists("lat") && ep.exists("lon") && ep.exists("display_name"))
  51.                   {
  52.                      this.point = new LngLat(Std.parseFloat(ep.get("lon")), Std.parseFloat(ep.get("lat")));
  53.                      this.address = ep.get("display_name");
  54.                      dispatchEvent(new Event(QUERY_FINISHED));
  55.                      return;      
  56.                   }
  57.            }
  58.  
  59.         } catch (unknown : Dynamic)  {
  60.            trace("Error:"+unknown);
  61.         };
  62.     }
  63. }
  64.  

3. Překlad a Html kód

Pro překlad platí informace uvedené v Ukázka použití s tím rozdílem, že nyní použijeme výchozí třídu Example03, kterou jsme implementovali v souboru example03.hx. Pro vložení do Html stránky lze využít kód uvedený v předchozím příkladu.

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

4. Výsledek

Kliknutím na tlačítko případně stisknutím klávesy Enter dojde k odeslání požadavku a v případě přijetí odpovědi dojde k nastavení středu mapy na pozici hledaného objektu.

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: 994x Naposledy: 29.3.2024 22:07:37