{"id":172,"date":"2008-11-17T18:34:20","date_gmt":"2008-11-18T02:34:20","guid":{"rendered":"http:\/\/www.antunkarlovac.com\/blog\/?p=172"},"modified":"2008-11-17T18:34:20","modified_gmt":"2008-11-18T02:34:20","slug":"google-maps-in-openlaszlo","status":"publish","type":"post","link":"https:\/\/www.antunkarlovac.com\/blog\/2008\/11\/17\/google-maps-in-openlaszlo\/","title":{"rendered":"Google Maps in OpenLaszlo"},"content":{"rendered":"<p>Recently, I wrote about <a href=\"\/blog\/2008\/11\/04\/rmenuz-openlaszlo-and-google-maps\/\">Rmenuz<\/a>, a site that embedded Google&#8217;s Flash maps in OpenLaszlo. The <a href=\"http:\/\/code.google.com\/apis\/maps\/documentation\/flash\/\" target=\"_blank\">Google Flash Maps<\/a> are written in ActionScript 3 (AS3), which requires Flash Player 9 or above. That means you wouldn&#8217;t be able to use them in OpenLaszlo 4.1 or below. I figured that with OpenLaszlo 4.2b3, which supports compiling to SWF9, it should be possible to embed an AS3 component. With some much-appreciated help from <a href=\"http:\/\/www.beartronics.com\/\" target=\"_blank\">Henry<\/a>, I got the following application working:<\/p>\n\n<object classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"\n\t\t\tid=\"fm_openlaszlo_google_maps_908613956\"\n\t\t\tclass=\"flashmovie\"\n\t\t\twidth=\"468\"\n\t\t\theight=\"530\">\n\t<param name=\"movie\" value=\"\/blog\/wp-content\/uploads\/2008\/11\/openlaszlo_google_maps.swf\" \/>\n\t<!--[if !IE]>-->\n\t<object\ttype=\"application\/x-shockwave-flash\"\n\t\t\tdata=\"\/blog\/wp-content\/uploads\/2008\/11\/openlaszlo_google_maps.swf\"\n\t\t\tname=\"fm_openlaszlo_google_maps_908613956\"\n\t\t\twidth=\"468\"\n\t\t\theight=\"530\">\n\t<!--<![endif]-->\n\t\t\n\t<!--[if !IE]>-->\n\t<\/object>\n\t<!--<![endif]-->\n<\/object>\n<p>I wanted an example that:<\/p>\n<ul>\n<li>Embedded Google maps in a clean, developer-friendly way.<\/li>\n<li>Was full-featured (allowed a user to search for an address, and add a marker there).<\/li>\n<li>Passed information (such as where to add a marker) from the OpenLaszlo application to the map component.<\/li>\n<li>Passed information (such as the address of the marker that a user clicked) from the map to an object in the OpenLaszlo namespace.<\/li>\n<\/ul>\n<p>Note that the Google Maps geocoding service is Flash-specific. Even though it passes XML back to the client, you need to use Google's Flash-based APIs to call it. I didn't want to do this; I wanted my example to perform the search in OpenLaszlo, and pass instructions to the map component. So I used Yahoo Maps' excellent <a href=\"http:\/\/developer.yahoo.com\/maps\/rest\/V1\/geocode.html\" target=\"_blank\">geocoding service<\/a>.<\/p>\n<p>Here are the instructions on how to do this:<\/p>\n<ol>\n<li><a href=\"http:\/\/www.openlaszlo.org\/download\/\" target=\"_blank\">Download OpenLaszlo<\/a> 4.2b3 or later, and install.<\/li>\n<li>Get a <a href=\"http:\/\/code.google.com\/apis\/maps\/signup.html\" target=\"_blank\">Google Maps API key<\/a> (free).<\/li>\n<li>Download the <a href=\"http:\/\/code.google.com\/apis\/maps\/documentation\/flash\/\" target=\"_blank\">Google Maps API for Flash SDK<\/a>, from Google's web site. I used version 1.7.<\/li>\n<li>Find the WEB-INF directory in your OpenLaszlo install, and create a directory called flexlib inside that. i.e. WEB-INF\/flexlib\/<\/li>\n<li>Unzip the Google Maps SDK, and locate the two SWC files in the lib directory. Take the Flash one (mine was called map_1_7a.swc) and copy it into WEB-INF\/flexlib\/.<\/li>\n<li>In your OpenLaszlo my-apps folder, create your lzx file (e.g. main.lzx), and write your application.<\/li>\n<li>When you compile the app via the browser, make sure that you remember to compile to SWF9. When you request the LZX file, append ?lzr=swf9 to the request. (e.g. main.lzx?lzr=swf9).<\/li>\n<\/ol>\n<p>Here's my complete source:<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;canvas proxied=&quot;false&quot; width=&quot;468&quot; height=&quot;530&quot;&gt;\r\n\r\n    &lt;!-- antunkarlovac.com key --&gt;\r\n    &lt;attribute name=&quot;gmapsKey&quot;\r\n               value=&quot;ABQIAAAAN0JyO4tW04-1OKNW7bg9gxSPySWqAfkZkuZG2U8jr6yyIuV3XBSrEn410_O9d9QPJh3dbWV85Qad8w&quot; type=&quot;string&quot; \/&gt;\r\n\r\n    &lt;alert name=&quot;errorDialog&quot; width=&quot;400&quot; \/&gt;\r\n\r\n    &lt;method name=&quot;handleMarkerClick&quot; args=&quot;address&quot;&gt;\r\n        addressWin.writeAddress(address);\r\n    &lt;\/method&gt;\r\n\r\n    &lt;script when=&quot;immediate&quot;&gt;&lt;!&amp;#91;CDATA&amp;#91;\r\n        class FlashMapOL {\r\n            #passthrough (toplevel: true) {\r\n                import com.google.maps.*;\r\n                import com.google.maps.controls.*;\r\n                import com.google.maps.overlays.*;\r\n\r\n\r\n                import flash.geom.*;\r\n            }#\r\n\r\n            var map:Map;\r\n\r\n            function createMap() {\r\n                map = new Map();\r\n                map.addEventListener(MapEvent.MAP_READY, onMapReady);\r\n                map.key = canvas.gmapsKey;\r\n                map.setSize(new Point(450, 300));\r\n                return map;\r\n            }\r\n\r\n            function onMapReady(event:MapEvent):void {\r\n                map.addControl(new ZoomControl());\r\n                map.addControl(new PositionControl());\r\n                map.addControl(new MapTypeControl());\r\n            }\r\n\r\n            function addMarker(lat:Number, lon:Number, address:String):void {\r\n                map.clearOverlays();\r\n                var latLon:LatLng = new LatLng(lat, lon);\r\n                var marker:Marker = new Marker(latLon);\r\n                marker.addEventListener(MapMouseEvent.CLICK, function(e:MapMouseEvent):void {\r\n                    canvas.handleMarkerClick(address);\r\n                    map.openInfoWindow(latLon, new InfoWindowOptions({titleHTML: &quot;&lt;b&gt;Search Result&lt;\/b&gt;&quot;, contentHTML: address}));\r\n                });\r\n                map.addOverlay(marker);\r\n            }\r\n\r\n            function centerAndZoom(lat:Number, lon:Number):void {\r\n                var latLon:LatLng = new LatLng(lat, lon);\r\n                this.map.setCenter(latLon, 14, MapType.NORMAL_MAP_TYPE);\r\n            }\r\n\r\n        }\r\n\r\n        lz.mapFactory = new FlashMapOL();\r\n        \r\n        lz.map = lz.mapFactory.createMap();\r\n    &amp;#93;&amp;#93;&gt;\r\n    &lt;\/script&gt;\r\n\r\n    &lt;dataset name=&quot;geoCode_ds&quot;\r\n             src=&quot;http:\/\/local.yahooapis.com\/MapsService\/V1\/geocode?&quot; type=&quot;http&quot; request=&quot;false&quot;\/&gt;\r\n\r\n    &lt;datapointer name=&quot;result_dp&quot; \r\n                 xpath=&quot;geoCode_ds:\/ResultSet\/Result&amp;#91;1&amp;#93;&quot; \/&gt;\r\n\r\n    &lt;handler name=&quot;ondata&quot; reference=&quot;geoCode_ds&quot;&gt;&lt;!&amp;#91;CDATA&amp;#91;\r\n        var lat;\r\n        var lon;\r\n        var root_dp = geoCode_ds.getPointer();\r\n        root_dp.selectChild();\r\n        if (root_dp.getNodeName() != &quot;Error&quot;) {\r\n            lat = result_dp.xpathQuery(&quot;Latitude\/text()&quot;) * 1;\r\n            lon = result_dp.xpathQuery(&quot;Longitude\/text()&quot;) * 1;\r\n            var warn = result_dp.getNodeAttribute(&quot;warning&quot;);\r\n            if (warn != undefined) {\r\n                \/\/ Pass along any warnings (e.g. couldn&#039;t find address,\r\n                \/\/ centering on city.\r\n                errorDialog.setAttribute(&quot;text&quot;, warn);\r\n                errorDialog.open();\r\n            }\r\n            \/\/ Get full address as a string\r\n            var address = result_dp.xpathQuery(&quot;Address\/text()&quot;)\r\n                        + &quot;,&lt;br \/&gt;&quot; + result_dp.xpathQuery(&quot;City\/text()&quot;)\r\n                        + &quot;, &quot; + result_dp.xpathQuery(&quot;State\/text()&quot;)\r\n                        + &quot; &quot; + result_dp.xpathQuery(&quot;Zip\/text()&quot;)\r\n                        + &quot;&lt;br \/&gt;&quot; + result_dp.xpathQuery(&quot;Country\/text()&quot;);\r\n            lz.mapFactory.centerAndZoom(lat,lon);\r\n            lz.mapFactory.addMarker(lat, lon, address);\r\n        } else {\r\n            \/\/ Failed to find address\r\n            var msg = root_dp.xpathQuery(&quot;Message\/text()&quot;);\r\n            errorDialog.setAttribute(&quot;text&quot;, msg);\r\n            errorDialog.open();\r\n        }\r\n    &amp;#93;&amp;#93;&gt;\r\n    &lt;\/handler&gt;\r\n\r\n    &lt;window name=&quot;mapWin&quot; title=&quot;Map&quot; width=&quot;468&quot; height=&quot;369&quot; \r\n            allowdrag=&quot;false&quot;&gt;\r\n        &lt;passthrough&gt;\r\n            import flash.display.*;\r\n        &lt;\/passthrough&gt;\r\n        &lt;handler name=&quot;oninit&quot;&gt;\r\n            var sprite:Sprite = this.content.sprite;\r\n            sprite.addChildAt(lz.map, sprite.numChildren);\r\n        &lt;\/handler&gt;\r\n\r\n        &lt;view name=&quot;buttons&quot; bgcolor=&quot;0xeaeaea&quot; width=&quot;100%&quot;\r\n              valign=&quot;bottom&quot;&gt;\r\n            &lt;simplelayout axis=&quot;x&quot; spacing=&quot;10&quot; \/&gt;\r\n            &lt;text valign=&quot;middle&quot;&gt;Address Search:&lt;\/text&gt;\r\n            &lt;edittext name=&quot;addressInput&quot; width=&quot;260&quot; \r\n                      text=&quot;1221 Mariposa Street, San Francisco, CA&quot; \/&gt;\r\n            &lt;button&gt;Search\r\n                &lt;handler name=&quot;onclick&quot;&gt;&lt;!&amp;#91;CDATA&amp;#91;\r\n                    var qs = &quot;appid=YD-9G7bey8_JXxQP6rxl.fBFGgCdNjoDMACQA--&quot; \r\n                           + &quot;&amp;amp;amp;location=&quot; + parent.addressInput.text \r\n                    geoCode_ds.setQueryString(qs);\r\n                    geoCode_ds.doRequest();\r\n                &amp;#93;&amp;#93;&gt;\r\n                &lt;\/handler&gt;\r\n            &lt;\/button&gt;\r\n        &lt;\/view&gt;\r\n        \r\n    &lt;\/window&gt;\r\n\r\n    &lt;window name=&quot;addressWin&quot; title=&quot;Address&quot; width=&quot;468&quot; height=&quot;150&quot; \r\n            y=&quot;379&quot; allowdrag=&quot;false&quot;&gt;\r\n        &lt;method name=&quot;writeAddress&quot; args=&quot;address&quot;&gt;\r\n            this.txt.setAttribute(&quot;text&quot;, address);\r\n        &lt;\/method&gt;\r\n\r\n        &lt;simplelayout axis=&quot;y&quot; spacing=&quot;10&quot; \/&gt;\r\n\r\n        &lt;text width=&quot;100%&quot; multiline=&quot;true&quot; fontstyle=&quot;italic&quot;&gt;\r\n            Click the search button to search for an address. When you click\r\n            one of the markers, the full address will be displayed in the\r\n            OpenLaszlo text field below:\r\n        &lt;\/text&gt;\r\n\r\n        &lt;!-- Address display area --&gt;\r\n        &lt;text name=&quot;txt&quot; width=&quot;100%&quot; multiline=&quot;true&quot; fontsize=&quot;14&quot;&gt;\r\n        &lt;\/text&gt;\r\n    &lt;\/window&gt;\r\n\r\n&lt;\/canvas&gt;\r\n<\/pre>\n<p>Note a few important points in the code:<\/p>\n<ul>\n<li>There's AS3 code directly inside the script block in the canvas. You need to use the when=\"immediate\" option in the script tag for this.<\/li>\n<li>There's an OpenLaszlo compiler instruction that allows you to include libraries from the WEB-INF\/flexlib\/ directory:<br \/>\n#passthrough (toplevel: true) {<br \/>\n...<br \/>\n}#<\/li>\n<li>There's another OpenLaszlo compiler instruction in the view where you want to instantiate the map (there's a new passthrough tag, and the map must be added procedurally - sprite.addChildAt().<\/li>\n<\/ul>\n<p>Here's the <a href=\"\/blog\/wp-content\/uploads\/2008\/11\/openlaszlo_google_mapslzx.zip\">complete source<\/a> to my app, as a zip.<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Recently, I wrote about Rmenuz, a site that embedded Google&#8217;s Flash maps in OpenLaszlo. The Google Flash Maps are written in ActionScript 3 (AS3), which requires Flash Player 9 or above. That means you wouldn&#8217;t be able to use them in OpenLaszlo 4.1 or below. I figured that with OpenLaszlo 4.2b3, which supports compiling to &hellip; <a href=\"https:\/\/www.antunkarlovac.com\/blog\/2008\/11\/17\/google-maps-in-openlaszlo\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Google Maps in OpenLaszlo<\/span><\/a><!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[8,3,5],"tags":[],"_links":{"self":[{"href":"https:\/\/www.antunkarlovac.com\/blog\/wp-json\/wp\/v2\/posts\/172"}],"collection":[{"href":"https:\/\/www.antunkarlovac.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.antunkarlovac.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.antunkarlovac.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.antunkarlovac.com\/blog\/wp-json\/wp\/v2\/comments?post=172"}],"version-history":[{"count":7,"href":"https:\/\/www.antunkarlovac.com\/blog\/wp-json\/wp\/v2\/posts\/172\/revisions"}],"predecessor-version":[{"id":253,"href":"https:\/\/www.antunkarlovac.com\/blog\/wp-json\/wp\/v2\/posts\/172\/revisions\/253"}],"wp:attachment":[{"href":"https:\/\/www.antunkarlovac.com\/blog\/wp-json\/wp\/v2\/media?parent=172"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.antunkarlovac.com\/blog\/wp-json\/wp\/v2\/categories?post=172"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.antunkarlovac.com\/blog\/wp-json\/wp\/v2\/tags?post=172"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}