Archive for the ‘Programming’ Category

Smooth Route Animation in Google Maps: panTo vs. setCenter

November 26, 2007

In my first attempt to animate a route on Google Maps, I used the GMap2.setCenter method. This provided for a spotty animation:


As the marker moved along the route, the background map (as you can see) would often not render. Changing to use GMap2.panTo instead of the GMap2.setCenter method fixed this problem and the flickering of the route problem that I was seeing on Safari.

Now the route animation of the Sheldon Road Trail looks a lot better. So does other routes, e.g. the Pebble Beach route, Kenndey/Shannon/Hicks Roads route, or the Stevens Creek Reservoir route.

How to animate a Flex Slider & update Google maps

November 24, 2007

Flex Slider AnimationFlex offers a number of different animation techniques. For my Route Player application, I wanted to offer an animation speed option so that when the user clicks on the Start button, Flex Slider Animation Control the animation starts: the Flex horizontal slider moves to the right, the time-line on the elevation chart moves accordingly, and the Google map gets updated. To see what I mean, click on the thumbnail, and when the Flex application starts, click on the Start button. To make this all work, first you need to define a Flex Sequence control, and include an AnimateProperty that specifies the duration of the animation.


<mx:Sequence id="myMove" target="{slider}">
    <mx:AnimateProperty property="value"
      fromValue="{timeMin}"
      toValue="{timeMax}"
      duration="{selectedItem.data}" />
</mx:Sequence>

Next, you’ll need to extend the HSlider control and override the set value method. See the control Note19HSlider. This extension of HSlider, includes a callback function that is set to the method sliderMove, which gets called each time the value of the slider has been updated, this in turn updated the chart and the Google Map. The code for all of this is here.

(more…)

How to embed Google Maps in Flex

November 22, 2007

Embed Google Map in FlexCreate your Flex application as you would normally do, design the UI and set aside a rectangle in which you wish to display Google Maps. In the HTML wrapper for the Flex application, add a DIV for the Google map, and add JavaScript functions to show or hide this DIV. These functions will be called from Flex when you need to show or hide the map. In this example, I’ve added the Google map to a Flex Accordion control. The map is shown when you click on the tab “Google Map” and is hidden when you click on the other tabs. The trick to get this to work is to use the Flash wmode="transparent" option when the Flash object is embedded in the HTML page. The code for this example is here.

Click here to see this Flex/HTML integration in action. See also this blog entry. 

Here is the reverse idea: embedding Flash on top of Google Maps. This is a useful way of enhancing Google maps

How to use GPX bounds to center the map

November 21, 2007

A GPX file has a bounds element that defines the coordinates of the bounding box of all the GPS points in the file. Here is an example:


<gpx version="1.0" ...>
<time>2007-10-24T02:45:26Z</time>
<bounds minlat="37.221354973"
   minlon="-121.987776104"
   maxlat="37.330222065"
   maxlon="-121.892523821"/>
...
</gpx>

Here is how you can use the Google MAP API to center the routes based on the bounds element in the GPX file:


var b = xmlDoc.documentElement.getElementsByTagName("bounds");
var sw = new GLatLng(b[0].getAttribute("minlat"), b[0].getAttribute("minlon"));
var ne = new GLatLng(b[0].getAttribute("maxlat"), b[0].getAttribute("maxlon"));
var bounds = new GLatLngBounds(sw, ne);
map.setCenter(bounds.getCenter(), 12);

Here is the above code in action: Los Gatos, Stevens Creek Reservoir bike trail

Processing GPX data with Flex

November 19, 2007

GPX files that you capture from your GPS device using GPSBabel are in XML and start with the following tags:


<gpx    
  version="1.0"    
  creator="GPSBabel - http://www.gpsbabel.org"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://www.topografix.com/GPX/1/0"
  xsi:schemaLocation="http://www.topografix.com/GPX/1/0http://www.topografix.com/GPX/1/0/gpx.xsd"
  >
  ...

You wont be able to read these GPX files from Flex (2.01) without modifying the namespace definition. Here is the problem that you will run into: when you try to get all of the trkpt elements, using a construct such as gpx..trkpt (or any other method of traversing the XML, e.g., gpx.descendants("trkpt")) the ActionScript program will silently fail. The only to way to get around this is to remove the XML name space declaration

xmlns="http://www.topografix.com/GPX/1/0"

from the start of your XML file. This must be a bug in ActionScript. The same GPX file works fine when you read it from DHTML using Google AJAX mapping API.

Calling Flex from JavaScript

November 18, 2007

To call Flex from JavaScript, you need to register a Flex method using the ExternalInterface class to make this method callable from JavaScript. Here I wanted to get hold of a JavaScript variable that is defined in the HTML wrapper (in my case, this variable defined the URL of a GPX file that I wanted to process in Flex).


<mx:Application
  xmlns:mx="http://www.adobe.com/2006/mxml"
  layout="absolute"
  creationComplete="initApp();">
  <mx:Script>
	private var gpxUrl : String;
	public function setGpxDataSource(value:String):void {
 	    gpxUrl = value;
 	    loadData();
	}

        // Make the method setGpxDataSource callable from JavaScript.
	public function initApp() : void {
	    ExternalInterface.addCallback("setDataSource", setGpxDataSource);
	    var u:URLRequest = new URLRequest("javascript:getGpxUrl()");
	    navigateToURL(u,"_self");
	}
  </mx:Script>

This means that in the JavaScript portion of your application you wont be able to call the Flex method until the Flex component has been completely rendered. To get around this, after the Flex component has been completed, call a JavaScript method (using the navigateToURL method) that in turn will call Flex.

In the HTML wrapper, you need to define the JavaScript function that will call Flex. The object that you can use to invoke Flex is the object that is created via the embed/object tag. The name/id of this object is what you use to call the Flex method.


<html>
...
   <object
      classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
      id="flexRuutr" ...
     <embed name="flexRuutr" .../>
   />
...
<script>
    var gpxUrl = "http://javey.net/bike/gpx/18-nov-2007.gpx";
    function getGpxUrl() {
	flexRuutr.setDataSource(gpxUrl);
    }

</script>

How to get the set of open files/ports for a process

October 26, 2007

Every once in a while I need to know the set of files/ports that a process on OS X has opened. I have been using the Activity Monitor for a while but was unaware that this tool also provided this kind of information. In Activity Monitor, just select the process of interest and then click on the Inspect button, and then on the Open Files and Ports button. Here is a screen-cast to show you how.

Eclipse and Perforce plug-in

October 23, 2007

This morning, eclipse refused to start again on my Mac laptop. The following lines were in the .metadata/.log file:


!SUBENTRY 1 org.eclipse.ui.workbench 2 0 2007-10-23 14:50:10.999
!MESSAGE Conflict for 'com.perforce.team.ui.actions.unlock':
HandlerActivation(commandId=com.perforce.team.ui.actions.unlock,
handler=ActionDelegateHandlerProxy(null,com.perforce.team.ui.actions.UnlockAction),
expression=WorkbenchWindowExpression(org.eclipse.ui.internal.WorkbenchWindow@b0f929),sourcePriority=16384)
HandlerActivation(commandId=com.perforce.team.ui.actions.unlock,
handler=ActionDelegateHandlerProxy(null,com.perforce.team.ui.actions.UnlockAction),
expression=WorkbenchWindowExpression(org.eclipse.ui.internal.WorkbenchWindow@b0f929),sourcePriority=16384)

Deleting the .metadata/.lock file fixed the problem. I’m not sure what caused this problem, but deleting the .lock file did fix it.

Rails config/environment.rb

October 23, 2007

Today the company I host my sharepdf.com site updated their Rails platform from 1.2.3 to 1.2.5 and all of sudden my Ruby on Rails application that gives users an HTML (suitable for an iPhone) view of the Adobe Share library stopped working. The following error message kept appearing in the error log:


Cannot find gem for Rails ~>1.2.3.0: Install the missing gem with 'gem install -v=1.2.3 rails', or change environment.rb to define RAILS_GEM_VERSION with your desired version.

I had to edit the config/environment.rb file and update the Rails version from 1.2.3 to 1.2.5.


# Specifies gem version of Rails to use when vendor/rails is not present
RAILS_GEM_VERSION = '1.2.5' unless defined? RAILS_GEM_VERSION

This change fixed the problem.

UUID Generator

October 7, 2007

Every once in while I need a UUID. So here is a hosted version (based on this).


Follow

Get every new post delivered to your Inbox.