<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Flex Consultant Thoughts</title>
	<atom:link href="http://nordicnets.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://nordicnets.com</link>
	<description>Wojciech Ptak</description>
	<lastBuildDate>Sat, 06 Mar 2010 22:54:21 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Flex, AIR 2.0, multitouch and Google Maps</title>
		<link>http://nordicnets.com/2009/11/air-2-0-multitouch-and-google-maps/</link>
		<comments>http://nordicnets.com/2009/11/air-2-0-multitouch-and-google-maps/#comments</comments>
		<pubDate>Thu, 26 Nov 2009 12:26:57 +0000</pubDate>
		<dc:creator>wjptak</dc:creator>
				<category><![CDATA[Coding Ideas]]></category>
		<category><![CDATA[air]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[googlemaps]]></category>
		<category><![CDATA[maps]]></category>
		<category><![CDATA[multitouch]]></category>

		<guid isPermaLink="false">http://wjptak.me/nordicnets/?p=4</guid>
		<description><![CDATA[When I first heard about possibilities of AIR 2.0 after MAX Conference I got enthusiast, specially about features that were so awaited. Among them, one of the most promising for the future way of creating applications with rich interfaces is &#8211; multitouch support. Thanks to the updated AIR 2.0 we have access to gestures on [...]]]></description>
			<content:encoded><![CDATA[<p>When I first heard about possibilities of AIR 2.0 after MAX Conference I got enthusiast, specially about features that were so awaited. Among them, one of the most promising for the future way of creating applications with rich interfaces is &#8211; multitouch support. Thanks to the updated AIR 2.0 we have access to gestures on when using touch pads and multitouch screen displays. I was looking forward to create very simple demo using multitouch and I thought about mapping using Google Maps.</p>
<p>Here is the simple recipe how to create the simplest application using three gestures: <strong>Pan</strong> (with two fingers), <strong>Zoom</strong> (also with two fingers) and <strong>Swipe</strong> (using three fingers). I built it and tested on MB Pro with multitouch running under Snow Leopard with AIR 2.0 beta 1.</p>
<p>Ok, let&#8217;s get started. First &#8211; we need to set up a map. I almost pasted the code from the Google site to make it simpler for you. I listen to to the event mapevent_mappreinitialize, where I set up map types, zoom etc.:</p>

<div class="wp_syntax"><div class="code"><pre class="as3" style="font-family:monospace;">private function onMapInitialize( event : MapEvent ) : void
{
mapTypes = MapType.DEFAULT_MAP_TYPES;
&nbsp;
var mapOptions : MapOptions = new MapOptions();
&nbsp;
mapOptions.zoom = 14;
mapOptions.mapType = mapTypes[ currentMapType ];
&nbsp;
map.setInitOptions( mapOptions );
}</pre></div></div>

<p>Ok, than we set up the map itself on mapevent_mapready.  We will look for The Ministry of Ideas in Cracow and put a marker there:</p>

<div class="wp_syntax"><div class="code"><pre class="as3" style="font-family:monospace;">private function onMapReady( event : MapEvent ) : void
{
doGeocode();
}
&nbsp;
private function doGeocode() : void
{
var geocoder : ClientGeocoder = new ClientGeocoder();
geocoder.addEventListener( GeocodingEvent.GEOCODING_SUCCESS, function ( event : GeocodingEvent ) : void
{
var placemarks : Array = event.response.placemarks;
if ( placemarks.length &gt; 0 )
{
map.setCenter( placemarks[ 0 ].point );
var marker : Marker = new Marker( placemarks[ 0 ].point );
marker.addEventListener( MapMouseEvent.CLICK, function ( event : MapMouseEvent ) : void
{
marker.openInfoWindow( new InfoWindowOptions( { content: placemarks[ 0 ].address } ) );
} );
map.addOverlay( marker );
&nbsp;
var latlng : LatLng = marker.getLatLng();
&nbsp;
map.panTo( latlng );
}
} );
geocoder.addEventListener( GeocodingEvent.GEOCODING_FAILURE, function ( event : GeocodingEvent ) : void
{
Alert.show( &quot;Geocoding failed: &quot; + event.toString() );
} );
geocoder.geocode( &quot;Mostowa 2, Krakow, Poland&quot; );
}</pre></div></div>

<p>Now, when the map is set up it&#8217;s time to do the magic. On creationComplete for Application we add:</p>

<div class="wp_syntax"><div class="code"><pre class="as3" style="font-family:monospace;">public function onCreationComplete() : void
{
Multitouch.inputMode = MultitouchInputMode.GESTURE;
&nbsp;
this.addEventListener( TransformGestureEvent.GESTURE_ZOOM, onZoom );    // zoom map in/out
this.addEventListener( TransformGestureEvent.GESTURE_SWIPE, onSwipe );    // change map type
this.addEventListener( TransformGestureEvent.GESTURE_PAN, onPan );        // pan map around
}</pre></div></div>

<p>We also use a constant to set up threshold for reading the gestures and a variable to hold the last update time. We need them so the application feedback is comfortable to the client:</p>

<div class="wp_syntax"><div class="code"><pre class="as3" style="font-family:monospace;">private static const IDLE_THRESHOLD : int = 300;
private var lastUpdate : Number = 0;</pre></div></div>

<p>Zooming is simple. If the zoom variables from the gesture event are below 1 &#8211; we zoom out, if greater than 1 we zoom in. Simple as that. We have all we need in the event variables.</p>

<div class="wp_syntax"><div class="code"><pre class="as3" style="font-family:monospace;">private function onZoom( event : TransformGestureEvent ) : void
{
if( getTimer() - lastUpdate &gt; IDLE_THRESHOLD )
{
if( event.scaleX &gt; 1 &amp;&amp; event.scaleY &gt; 1 )
map.setZoom( map.getZoom() + 1 );
if( event.scaleX &lt; 1 &amp;&amp; event.scaleY &lt; 1 )
map.setZoom( map.getZoom() - 1 );
&nbsp;
lastUpdate = getTimer();
}
}</pre></div></div>

<p>Than we go to panning. Panning is also easy. What I decided to do is to read a movement from the event and create a new &#8220;vector&#8221; based on it. I use it to set up a new center of the map:</p>

<div class="wp_syntax"><div class="code"><pre class="as3" style="font-family:monospace;">private function onPan( event : TransformGestureEvent ) : void
{
var point : Point = map.fromLatLngToPoint( map.getCenter() );
var newPoint : Point = new Point( point.x + ( event.offsetX * 10 ), point.y + ( event.offsetY * 10 ) );
var newLatLon : LatLng = map.fromPointToLatLng( newPoint );
&nbsp;
map.setCenter( newLatLon );
}</pre></div></div>

<p>I thought that we could use swiping for changing the map type, which is quite useful as Google Maps API has four map types. when you swipe right or left the map type will change. As you can see I use helper variable to hold the current map type.</p>

<div class="wp_syntax"><div class="code"><pre class="as3" style="font-family:monospace;">private function onSwipe( event : TransformGestureEvent ) : void
{
if( getTimer() - lastUpdate &gt; IDLE_THRESHOLD )
{
if( event.offsetX &gt; 0 )
currentMapType++;
if( event.offsetX &lt; 0 )
currentMapType--;
&nbsp;
if( currentMapType &lt; 0 )
currentMapType = mapTypes.length - 1;
&nbsp;
currentMapType = currentMapType % mapTypes.length;
&nbsp;
map.setMapType( mapTypes[ currentMapType ] );
&nbsp;
lastUpdate = getTimer();
}
}</pre></div></div>

<p>You will find the full <a title="Source Code" href="http://nordicnets.com/wp-content/uploads/2010/03/AIR2TestGoogleMaps.fxp_.zip">source code here</a>. Comments and critique are welcomed, as always.</p>
<p>You can try it by quickly installing the following AIR file. Have in mind that to test it you will need a computer with a multitouch screen or pad and a PC with Windows 7 or a Mac with Snow Leopard.</p>
<div id="flashcontent" style="width:215px; height:180px;"><strong>Please upgrade your Flash Player</strong></div>
<p><script type="text/javascript">
//<![CDATA[
var so = new SWFObject("http://nordicnets.com/wp-content/uploads/AIR2Test/AIRInstallBadge.swf", "Badge", "215", "180", "9.0.115", "#FFFFFF");
so.useExpressInstall('http://nordicnets.com/wp-content/uploads/AIR2Test/expressinstall.swf');
so.addVariable("airversion", "2.0beta");
so.addVariable("appname", "AIR2 Test Google Maps");
so.addVariable("appurl", "http://nordicnets.com/wp-content/uploads/AIR2Test/AIR2TestGoogleMaps.air");
so.addVariable("appid", "com.wjptak.AIR2TestGoogleMaps");
so.addVariable("pubid", "");
so.addVariable("appversion", "1.0.2");
so.addVariable("image", "http://nordicnets.com/wp-content/uploads/AIR2Test/AIR2Test.jpg");
so.addVariable("appinstallarg", "installed from web");
so.addVariable("applauncharg", "launched from web");
so.addVariable("helpurl", "help.html");
so.addVariable("hidehelp", "false");
so.addVariable("skiptransition", "false");
so.addVariable("titlecolor", "#e5e5e5");
so.addVariable("buttonlabelcolor", "#e5e5e5");
so.addVariable("appnamecolor", "#e5e5e5");
so.addVariable("str_err_airswf", "<u>Running locally?</u><br/><br/>The AIR proxy swf won't load properly when this demo is run from the local file system.");
so.write("flashcontent");
//]]&gt;
</script></p>
<p>Have a great day,<br />
W.</p>
]]></content:encoded>
			<wfw:commentRss>http://nordicnets.com/2009/11/air-2-0-multitouch-and-google-maps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
