Recently, I wrote about Rmenuz, a site that embedded Google’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’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 Henry, I got the following application working:
I wanted an example that:
- Embedded Google maps in a clean, developer-friendly way.
- Was full-featured (allowed a user to search for an address, and add a marker there).
- Passed information (such as where to add a marker) from the OpenLaszlo application to the map component.
- Passed information (such as the address of the marker that a user clicked) from the map to an object in the OpenLaszlo namespace.
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 geocoding service.
Here are the instructions on how to do this:
- Download OpenLaszlo 4.2b3 or later, and install.
- Get a Google Maps API key (free).
- Download the Google Maps API for Flash SDK, from Google’s web site. I used version 1.7.
- Find the WEB-INF directory in your OpenLaszlo install, and create a directory called flexlib inside that. i.e. WEB-INF/flexlib/
- 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/.
- In your OpenLaszlo my-apps folder, create your lzx file (e.g. main.lzx), and write your application.
- 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).
Here’s my complete source:
<canvas proxied="false" width="468" height="530">
<!-- antunkarlovac.com key -->
<attribute name="gmapsKey"
value="ABQIAAAAN0JyO4tW04-1OKNW7bg9gxSPySWqAfkZkuZG2U8jr6yyIuV3XBSrEn410_O9d9QPJh3dbWV85Qad8w" type="string" />
<alert name="errorDialog" width="400" />
<method name="handleMarkerClick" args="address">
addressWin.writeAddress(address);
</method>
<script when="immediate"><![CDATA[
class FlashMapOL {
#passthrough (toplevel: true) {
import com.google.maps.*;
import com.google.maps.controls.*;
import com.google.maps.overlays.*;
import flash.geom.*;
}#
var map:Map;
function createMap() {
map = new Map();
map.addEventListener(MapEvent.MAP_READY, onMapReady);
map.key = canvas.gmapsKey;
map.setSize(new Point(450, 300));
return map;
}
function onMapReady(event:MapEvent):void {
map.addControl(new ZoomControl());
map.addControl(new PositionControl());
map.addControl(new MapTypeControl());
}
function addMarker(lat:Number, lon:Number, address:String):void {
map.clearOverlays();
var latLon:LatLng = new LatLng(lat, lon);
var marker:Marker = new Marker(latLon);
marker.addEventListener(MapMouseEvent.CLICK, function(e:MapMouseEvent):void {
canvas.handleMarkerClick(address);
map.openInfoWindow(latLon, new InfoWindowOptions({titleHTML: "<b>Search Result</b>", contentHTML: address}));
});
map.addOverlay(marker);
}
function centerAndZoom(lat:Number, lon:Number):void {
var latLon:LatLng = new LatLng(lat, lon);
this.map.setCenter(latLon, 14, MapType.NORMAL_MAP_TYPE);
}
}
lz.mapFactory = new FlashMapOL();
lz.map = lz.mapFactory.createMap();
]]>
</script>
<dataset name="geoCode_ds"
src="http://local.yahooapis.com/MapsService/V1/geocode?" type="http" request="false"/>
<datapointer name="result_dp"
xpath="geoCode_ds:/ResultSet/Result[1]" />
<handler name="ondata" reference="geoCode_ds"><![CDATA[
var lat;
var lon;
var root_dp = geoCode_ds.getPointer();
root_dp.selectChild();
if (root_dp.getNodeName() != "Error") {
lat = result_dp.xpathQuery("Latitude/text()") * 1;
lon = result_dp.xpathQuery("Longitude/text()") * 1;
var warn = result_dp.getNodeAttribute("warning");
if (warn != undefined) {
// Pass along any warnings (e.g. couldn't find address,
// centering on city.
errorDialog.setAttribute("text", warn);
errorDialog.open();
}
// Get full address as a string
var address = result_dp.xpathQuery("Address/text()")
+ ",<br />" + result_dp.xpathQuery("City/text()")
+ ", " + result_dp.xpathQuery("State/text()")
+ " " + result_dp.xpathQuery("Zip/text()")
+ "<br />" + result_dp.xpathQuery("Country/text()");
lz.mapFactory.centerAndZoom(lat,lon);
lz.mapFactory.addMarker(lat, lon, address);
} else {
// Failed to find address
var msg = root_dp.xpathQuery("Message/text()");
errorDialog.setAttribute("text", msg);
errorDialog.open();
}
]]>
</handler>
<window name="mapWin" title="Map" width="468" height="369"
allowdrag="false">
<passthrough>
import flash.display.*;
</passthrough>
<handler name="oninit">
var sprite:Sprite = this.content.sprite;
sprite.addChildAt(lz.map, sprite.numChildren);
</handler>
<view name="buttons" bgcolor="0xeaeaea" width="100%"
valign="bottom">
<simplelayout axis="x" spacing="10" />
<text valign="middle">Address Search:</text>
<edittext name="addressInput" width="260"
text="1221 Mariposa Street, San Francisco, CA" />
<button>Search
<handler name="onclick"><![CDATA[
var qs = "appid=YD-9G7bey8_JXxQP6rxl.fBFGgCdNjoDMACQA--"
+ "&amp;location=" + parent.addressInput.text
geoCode_ds.setQueryString(qs);
geoCode_ds.doRequest();
]]>
</handler>
</button>
</view>
</window>
<window name="addressWin" title="Address" width="468" height="150"
y="379" allowdrag="false">
<method name="writeAddress" args="address">
this.txt.setAttribute("text", address);
</method>
<simplelayout axis="y" spacing="10" />
<text width="100%" multiline="true" fontstyle="italic">
Click the search button to search for an address. When you click
one of the markers, the full address will be displayed in the
OpenLaszlo text field below:
</text>
<!-- Address display area -->
<text name="txt" width="100%" multiline="true" fontsize="14">
</text>
</window>
</canvas>
Note a few important points in the code:
- 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.
- There’s an OpenLaszlo compiler instruction that allows you to include libraries from the WEB-INF/flexlib/ directory:
#passthrough (toplevel: true) {
…
}# - 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().
Here’s the complete source to my app, as a zip.
31 responses so far ↓
1 Raju Bitter | OpenLaszlo, SWF9, ActionScript3 and Flex Libraries // Nov 18, 2008 at 1:26 pm
[...] Antun Karlovac of Laszlo has an interesting blog post with an OpenLaszlo showing how it’s possible to use Flex/AS3 SWC libraries for the OpenLaszlo SWF9 runtime.That’s a valuable example as many people have been asking to support SWC import into OpenLaszlo apps in the past. This will probably take away 2 hours of my sleep tonight, as I just have to play around with that feature. Thanks Antun & Henry! [...]
2 Google Maps in OpenLaszlo | OpenLaszlo Project Blog // Nov 18, 2008 at 4:09 pm
[...] Google Maps in OpenLaszlo: [...]
3 vivanno » Blog Archive » Google Maps in OpenLaszlo, Another “développeur PHP” web site. :) // Nov 18, 2008 at 10:01 pm
[...] Google Maps in OpenLaszlo: [...]
4 Norman Klein // Nov 19, 2008 at 9:43 am
I’m just curious why the “immediate” qualifier needs to be used by the script tag. I know it ensures the script tag is executed earlier, but why does the script code need to execute earlier? It already executes very early within the execution cycle. What does it need to precede?
5 Simon // Nov 20, 2008 at 9:37 pm
Fantastic stuff. This gets around the drawbacks of using the html laszlo tag (iFrame solution). Of course it does indeed tie it very much down to a flash runtime, but for us that’s of little consequence.
Is there any way to get Webtop to use versions of Laszlo other than what it ships with? It’d be great to be able to use this solution in a Webtop app, but that doesn’t use a new enough version of OL.
6 antun // Nov 21, 2008 at 6:58 am
Hey Simon,
Unfortunately there isn’t a way to use a different version of OpenLaszlo other than the one that comes bundled with Webtop. The Webtop client code is all precompiled into .lzo files; it ships with the Webtop distribution.
There are code changes that would need to be made to the Webtop client code (by Laszlo) to move it from where it is today – 4.0.x – to 4.2. I wrote about moving an OpenLaszlo application from 4.0.x to 4.1 a while back (http://www.antunkarlovac.com/blog/2008/07/02/migrating-lzx-code-to-openlaszlo-41/ ). There’s also a script that comes with the 4.1.1 distribution that does the migration for you. As a result, it’ll be a little while before Webtop is running on OpenLaszlo 4.2, but given the attractive performance gains of SWF9, I hope the project will get prioritized.
-Antun
7 Carsten // Nov 23, 2008 at 12:18 pm
running http://localhost:8080/lps-4.2b3/my-apps/main.lzx?lzr=swf9 shows up a map, but searching for any address is waiting for local.yahooapis.com … any idea ?
8 antun // Nov 23, 2008 at 11:09 pm
Hi Carsten,
There may be a problem with the geocoding service. It’s working for me if I use the app on this page. Can you see what is being returned? To do so:
1. Enable the Debugger (add debug=”true” to the canvas), and recompile the application.
2. Search for an address.
3. Enter geoCode_ds.serialize() in the Debugger, and hit the “Eval” button.
Thanks,
Antun
9 Oscar Nava Trujillo // Nov 29, 2008 at 2:41 pm
Hi Antun.
I’ve been working lately in a project (in fact my site upgrade) and choose Laszlo and Google maps for this, although the dhtml way. I’ve managed to develop a fairly functional component, but I’m stuck in some basic mouse functionality (Chrome & Safari become unresponsive to dragging, and some clicking; Firefox, IE and SeaMonkey work well) and I could use some help
that is, if you are interested (BTW, when ready, I’ll release it as Open Source).
If you wan’t to see it in action, I have it working at http://asuka.depatadeperro.com/ Just be aware that this is my test site, so it might now behave ok every time.
Oscar
10 Ajit // Jan 7, 2009 at 10:43 pm
The following is the problem that we are facing in our application Order Entry Application:
This is developed using OpenLaszlo. In our application we need to include google maps.
We found that the site below is havingsteps to include Google maps in openlaszlo:
http://www.antunkarlovac.com/blog/2008/11/17/google-maps-in-openlaszlo/
This uses Google Maps API for Flash SDK version 1.7 but the available download version is 1.8(http://maps.googleapis.com/maps/flash/release/sdk.zip). With this version 1.8 the sample code is not displaying the maps. It’s not throwing any error also. Please let us know which part of the coding we have to change related to Google Maps API for Flash SDK version 1.8 in the above sample code.
Running http://localhost:8080/lps-4.2.0/my-apps/main.lzx?lzr=swf9 doesn’t show up a map.
If we Enter geoCode_ds.serialize() in the Debugger, and hit the “Eval” button. It’s returning the value . Please let us know how to get google maps working.
11 antun // Jan 9, 2009 at 10:16 am
Hi Ajit,
I just downloaded the Google Maps API for Flash SDK 1.8 and tried the steps listed in my blog post above. I used OpenLaszlo 4.2.0. The application ran successfully. I was able to see the maps, and then search for a location.
Are you sure that you are following the exact steps listed in my post (i.e. steps 1-7)?
-Antun
12 Open Future » Archive » Fullscreen HD video with OpenLaszlo 4.2 and the SWF9 runtime // Jan 9, 2009 at 7:13 pm
[...] for a detailed description on how to do that take a look at Antun Karlovac’s example of AS3 based GoogleMaps integration into [...]
13 pedalpete // Jan 11, 2009 at 12:09 pm
Hi Antun,
Like Ajit, I too am unable to retrieve a map.
I’m using 4.2.0 with 1.8 sdk.
I’ve copied your code and replaced the API key with my local API key.
In testing, I decided to check if maybe the API key was wrong, so I removed half of the API key in an attempt to get an error of the wrong API key, and I don’t get any such response.
So my guess is that the API key s not being retrieved for some reason.
I have very little experience with OpenLaszlo having only written one simple page with it before, so I’m not really sure how to get an API Key response error.
14 antun // Jan 11, 2009 at 6:33 pm
If you’re having trouble with the maps, there are a few approaches to debugging:
– Make sure that the OpenLaszlo debugger is enabled. (i.e. debug=”true” in the canvas tag). See if there are any errors there.
– Download and install the Flash debug player. It’ll automatically throw a dialog box with any ActionScript 3 exceptions it catches.
– Examine the HTTP traffic (using a tool like Firebug, Fiddler, Charles, etc.), to see what’s being returned.
Feel free to post any output here.
By the way, are you running this from localhost, or from a remote server that you’re accessing by domain name/IP address?
15 pedalpete // Jan 12, 2009 at 12:57 pm
Thanks Antun,
I am trying to run this from localhost (actually the OpenLaszlo default 127.0.0.1:8080/…).
I followed your advice (I had already been running the debug=true). The http traffic returns without errors, but the Flash Debugger returns the following
Error: No class registered for interface ‘mx.styles::IStyleManager2′.
at mx.core::Singleton$/getInstance()[/Users/hqm/openlaszlo/adobe/trunk/frameworks/projects/framework/src/mx/core/Singleton.as:111]
at mx.styles::StyleManager$/get impl()[/Users/hqm/openlaszlo/adobe/trunk/frameworks/projects/framework/src/mx/styles/StyleManager.as:78]
at mx.styles::StyleManager$/get http://www.adobe.com/2006/flex/mx/internal::stylesRoot()[/Users/hqm/openlaszlo/adobe/trunk/frameworks/projects/framework/src/mx/styles/StyleManager.as:100]
at mx.core::UIComponent/http://www.adobe.com/2006/flex/mx/internal::initProtoChain()[/Users/hqm/openlaszlo/adobe/trunk/frameworks/projects/framework/src/mx/core/UIComponent.as:7480]
at mx.core::UIComponent/regenerateStyleCache()[/Users/hqm/openlaszlo/adobe/trunk/frameworks/projects/framework/src/mx/core/UIComponent.as:7690]
at mx.core::UIComponent/http://www.adobe.com/2006/flex/mx/internal::addingChild()[/Users/hqm/openlaszlo/adobe/trunk/frameworks/projects/framework/src/mx/core/UIComponent.as:5199]
at mx.core::UIComponent/addChild()[/Users/hqm/openlaszlo/adobe/trunk/frameworks/projects/framework/src/mx/core/UIComponent.as:4916]
at com.google.maps.wrappers::SpriteFactory/addChild()
at com.google.maps.wrappers::ISpriteFactoryWrapper/addChild()
at com.google.maps.core::Bootstrap$/createChildComponent()
I’ve been searching for a solution to the mx.styles issue (as I’m somewhat assuming that will resolve everything else) and came across a few posts between you and Henry, but nothing with a resolution.
I have both of the flex and flash file in the flexlib folder (though I tried removing the flex file to see if that would help, it didn’t).
Thanks for your help,
Pete
16 Ajit // Jan 14, 2009 at 11:29 pm
Hi Antun,
Thanks for response. I followed the every steps mentioned. As far as the Google Map API key, I tried with your key and also generate a key. Result is same. I can’t see the map. I generate the key by giving arbitrary site name. Do you think it is the problem?
For testing purpose I deleted the flexlib folder inside the WEB-INF, that I created and compile the application again, but there is no compilation errors or warnings but no map aslo.
Do I need any particular version of flash or any supporting files?
-Ajit
17 Kevin Armstrong // Feb 10, 2009 at 1:19 pm
I have a laszlo-google app that uses a laszlo InfoWindow…all works okay except for the scroll bars and select list controls.
Any ideas? Thanks…
The site is http://www.rmenuz.net/UW_PROJECT_A
Search on Trees -> Tree number -> 1
Next, open the google InfoWindow and select “Proximity Search” tab.. Draw a 200 foot proximity and select “Trees” again…notice no scroll bars and only check boxes.
18 zerozonex // Feb 24, 2009 at 9:48 am
Hi autun,
I tried to make my app step by step as your instruction. but there’s nothing in my map place.. hix.. I used my Google key..
Then, I download your file, use my Google key, but there’s the same, nothing in the window, it’s blank.. could you tell me how to run it successfully?
19 care // Mar 25, 2009 at 9:45 pm
I use laszlo quite a bit to create complex input forms (as everyone knnows building any form in HTML is an adventure), but why would one need to create a laszlo based google map and introduce all that overhead when making ajax-enabled maps is quite easy? Just a thought. Great solution though!
20 Richard Hendricks // May 22, 2009 at 6:37 am
I’m using OpenLaszlo v 4.3.0 and I’m compiling to Flash 9 or 10. I have map_1_9a.swc in the ..\Server\lps-4.3.0\WEB-INF\flexlib folder.
The map displays, the search works and the 3 controls are displayed (Zoom, Position and MapType). The buttons (arrows, +, -, etc) on the controls do not work. I can double click on the map itself to zoom in. The little bar on the zoom control can be grabbed used to zoom in an out.
It appears that the click events are not being handled.
You can see the App at http://www.himweb.org/openlaszlo
This my experiment page for OL Apps. The debugger does not display any error messages or warnings.
Thank you,
Richard
21 Henry Minsky // Jun 2, 2009 at 7:22 am
Richard,
Did you try the example that ships in the incubator
(lps/components/incubator/googlemap.lzx) , run in swf9 runtime (lzr=swf9)
The various control buttons do respond to mouse clicks. Is it possible your window is intercepting mouse clicks with some other onclick handler?
22 Frank // Jul 8, 2009 at 11:37 pm
did anyone see the same problem as richard and fix it? i have 4.2 with 1.9 and see exactly the same.
thanks,
frank
23 Frank // Jul 9, 2009 at 12:59 am
some more info on the zoom/position/type controls not reacting: i was using map_1.9a.swc. using map_1.9.swc it does work fine!
24 Charlie // Jul 22, 2009 at 7:22 am
Henry and Antun:
Why this ?lzr=swf9 is making the doRequest() method not returning the resultset?
It is calling backend api but no resultset with swf9 and it is working fine with swf8!
Any ideas or solutions? is this bug in lzx4.2 and lzx 4.4?
Thanks,
Charlie
25 antun // Jul 22, 2009 at 8:23 am
Hi Charlie,
Can you add the following somewhere in the canvas tag to see what is being returned by the web service in both SWF8 and SWF9:
<handler name="ondata" reference="geoCode_ds">Debug.write(geoCode_ds.serialize());
</handler>
26 Charlie // Jul 22, 2009 at 9:43 am
Hi Antun,
It is not just for the map, all other DataSet that I am using has same problem that returns null when I use ?lzr=swf9 but all things are find with ?lzr=swf8.
Anyway, I followed your instructions and it is not coming to ondata but onerror.
so onerror I did serialize it and it is showing me just called DataSet name without and contents.
To prove, ?lzr=swf8 is working, I did serialize it and shows all data what supposed to be.
In my opinion, there is something that I am do not know about usage of ?lzr=swf9 or problem with swf9 or that is related with flex configuration that I found this message from logs about how flex is used when I do ?lzr=swf9.
here is the message that hopefully you can get hints,
Executing compiler: (cd /Applications/apache-tomcat-5.5.26_parent/temp/lzswf9/lzgen60827; /Applications/apache-tomcat-5.5.26_parent/webapps/splash/WEB-INF/bin/mxmlc -load-config=/Applications/apache-tomcat-5.5.26_parent/webapps/splash/WEB-INF/frameworks/flex-config.xml -compiler.show-actionscript-warnings=false -compiler.source-path+=/Applications/apache-tomcat-5.5.26_parent/temp/lzswf9/lzgen60827 -debug=true -compiler.headless-server=true -compiler.fonts.advanced-anti-aliasing=true -output /Applications/apache-tomcat-5.5.26_parent/temp/lzswf9/lzgen60827/app.swf -default-size 500 400 -compiler.library-path+=/Applications/apache-tomcat-5.5.26_parent/webapps/splash/lps/includes/lfc/LFC9-debug.swc -compiler.library-path+=/Applications/apache-tomcat-5.5.26_parent/webapps/splash/WEB-INF/flexlib -frame two LzSpriteApplication -file-specs=/Applications/apache-tomcat-5.5.26_parent/temp/lzswf9/lzgen60827/LzPreloader.as)
compiler output is Loading configuration file /Applications/apache-tomcat-5.5.26_parent/webapps/splash/WEB-INF/frameworks/flex-config.xml
/Applications/apache-tomcat-5.5.26_parent/temp/lzswf9/lzgen60827/app.swf (307798 bytes)
compiler output:
Loading configuration file /Applications/apache-tomcat-5.5.26_parent/webapps/splash/WEB-INF/frameworks/flex-config.xml
/Applications/apache-tomcat-5.5.26_parent/temp/lzswf9/lzgen60827/app.swf (307798 bytes)
Cheers,
Charlie
27 Charlie // Jul 23, 2009 at 7:37 am
I found the problem and solved it that was matter of welformed XML issue that ?lzr=swf8 is not checking it but ?lzr=swf9 is sensitive for this so that it looks like No Resultset is back to caller.
Hopefully this information save somebody’s time as I spent 2 days to find this.
Thanks,
28 antun // Jul 23, 2009 at 9:27 am
Thanks for posting that Charlie! I guess that the underlying Flash APIs must do better XML validation in SWF9 than they did in SWF8.
Was there any error at all – in the Debugger? If not how did you discover the problem? The reason I ask is that if there was no Debugger error, it may be possible to add one.
-Antun
29 leo // Nov 17, 2009 at 10:58 pm
Hi, How to compile my laszlo as swf9?Just exchange ‘lzr=swf8′ to ‘lzr=swf9′ ?and that’s OK? If I want to compile my laszlo into swf with solo in laszlo server, What could i do?
Thanks a lot.
30 antun // Nov 18, 2009 at 9:19 am
Leo,
You should simply be able to compile your app to SWF9 by adding ?lzr=swf9 to the querystring, if you’re using Tomcat. If you’re using the command line compiler, you’d need to add a –runtime=swf9 argument.
-Antun
31 Packovic // Jul 1, 2010 at 8:56 am
People who run the Antum code and see the boxs but don´t see the maps and can´t make a searching, check if you have added only the “map_1_7a.swc” file into “WEB-INF/flexlib” folder or if you have added the file “map_flex_1_7a.swc” too. If you have added this two files clear “map_flex_1_7a.swc” from “WEB-INF/flexlib/”folder and it works perfectly.
Excuse me for my english and thanks Antun for the tutorial!
Leave a Comment