Intro to Google Maps API for Flex: Part 2
It is hard to deny that the Google Maps API has a lot of built in functionality to it. I enjoyed writing the last article and I felt it was time to get into it a little more. In my last last article on the API, I focused primarily on how to add a marker to the map and also how to create a custom infoWindow. This article’s main topic will be on how to plot PolyLines on a map, how to get the distance between them, and using Markers to had a little bit more usability to your application.
Start out by making sure that you have your environment setup to use Google Maps. Just read the first part of last tutorial here.
……
Alright welcome back. Lets discuss our end result for our application that way its not a mystery what we are building.

So we have our map. Whenever we click on the map, we want to add a line from a starting point(S) to an ending point(E). When we draw a line, we are going to add a row to our grid that will tell us how far we have gone from our initial starting point. We can change our unit of distance if we want, and we can also undo our lines. Lastly, we can highlight our Polylines with markers by clicking on the row it is associated with in the grid.
First lets just make sure we’ve got our map on the screen.
public function onMapReady(event:MapEvent):void { formatter.precision = 2; map.setCenter(new LatLng(40.665226,-73.984659), 14, MapType.NORMAL_MAP_TYPE); map.addEventListener(MapMouseEvent.CLICK,mapClicked); }
That will go into your actionscript and this will be in your mxml
<maps:Map xmlns:maps="com.google.maps.*" id="map" mapevent_mapready="onMapReady(event)" width="100%" height="100%" key="{GoogleConstants.KEY}"/>
As you probably noticed, within our onMapReady event, we have an eventListener for mouse clicks. This is what we are going to use this to start drawing our lines out. Now our initial click will not show anything (its the starting point) but after that, anywhere we click will draw a line from the last point you clicked to the point you just clicked.
public function mapClicked(event:MapMouseEvent):void{ latlngs.addItem(event.latLng); drawMap(); calculateDistance(); }
latlngs is just an ArrayCollection that we keep in order to draw out the lines. The drawMap() function is used to draw out our lines and the calculateDistance() is used to build out the rows within our grid. Dropping the PolyLines on the map is amazingly easy.
private function drawMap():void{ map.clearOverlays(); var polyShape:Polyline = new Polyline(latlngs.toArray()); map.addOverlay(polyShape); }
We want to clear off whatever is in our map (so we arent drawing over anything). Then we take our latlngs array collection, convert it to an array and pass that as a parameter to our PolyLine object. After that, we just add it as an overlay to our map. Next we will calculate the distances of our lines.
[Bindable]public var dist:Number=0; private function calculateDistance():void{ var o:Object; dist=0; dataProvider = new ArrayCollection(); for (var x:int =0;x<latlngs.length-1;x++){ var sl:LatLng = getLat(x); var el:LatLng = getLat(x+1); setDistanceForUnits(sl,el); o = {distance: formatter.format(dist).toString() +" " + unitOfDistance , start:sl, end:el}; dataProvider.addItem(o); } total.text = "Total Distance : " +formatter.format(dist) + unitOfDistance; }
Obviously this function has a little bit more meat but nothing we can’t handle. dist will be used to keep track of our total distance. Each time we calculate our distance, we reset our dist variable. Next we iterate through our LatLngs, grabbing two at a time and set the distance based on the unit of measurement.
public function setDistanceForUnits(startLatLng:LatLng, endLatLng:LatLng):void{ if (startLatLng && endLatLng){ if (km.selected) dist += (startLatLng).distanceFrom(endLatLng)/1000; if (mi.selected) dist += MapUtils.convertToMiles(((startLatLng).distanceFrom(endLatLng)/1000)); } }
After our sanity check, if km(kilometers) is selected, use that. If not, use miles. The LatLng.distanceFrom from function returns its units in kilometers. For us bleeding yanks, we want might want to think of things in terms of miles, so we have to convert it. The MapUtils is just a small utility class I have (which you might recall from the “>previous tutorial).
public static const MILES:Number = 0.621; public static function convertToMiles(km:Number):Number{ return km * MILES; }
Pretty self explanatory. Going back to our calculate distance, Object o that is used for the datagrid. The formatter just sets the numbers precision. unitOfDistance is what we have selected (Kilometers or Miles) and start/end is used to mark the starting LatLng and the ending LatLng. This will be used for dropping markers on the map when a row in the grid is clicked. After that, we set our text which is above the buttons and we are done. Now we have a map that draws our PolyLines, a grid that will give us our total distance and the ability to convert our units.
Next lets add the ability to mark our polyLines to the grid. We are going to want to add a itemClick to our grid like this:
<mx:DataGrid id="grid" dataProvider="{dataProvider}" itemClick="showPolyLine(event)" width="100%" height="100%">
This is what the handler looks like
public function showPolyLine(event:ListEvent):void{ var rowIndex:int = event.rowIndex; var o:Object = dataProvider.getItemAt(rowIndex); var startingMarker:Marker = new Marker(o["start"] as LatLng, new MarkerOptions({label:"S"})); var endingMarker:Marker = new Marker(o["end"] as LatLng, new MarkerOptions({label:"E"})); drawMap(); map.addOverlay(startingMarker); map.addOverlay(endingMarker); }
When a row is clicked, it calls the event handler and it gets the object associated that row. Earlier in the calculatedistance() function, we set the start and end LatLng objects. Now we create markers based on those. Next we want to redraw the map. This is to wipe away any preexisting markers. After that, we just add the two new markers are overlays to our map and we are done.
As I said previously, the Google Maps API does offer pretty wide variety of things you can do with it. I would really like to do a part 3 tutorial for this since there are just too many cool features (in my opinion) that the API has to offer.
Here is the source. If you want to check out the applications running, click here.
Hello,
Please add your site at http://www.sweebs.com. Sweebs.com is a place where other people can find you among the best sites on the internet!
Its just started and we are collecting the best found on the net! We will be delighted to have you in the sweebs listings.
Regards
Kris
Hey great tutorials on flex google maps!!!
Two really cool features to have would be:
1.) Save a map and its points to a database
2.) The ability to show the elevation profile (with data from http://gisdata.usgs.gov/XMLWebServices/TNM_Elevation_Service.php)
Really nice tutorials, thanks
Great tutorial! Its awsome!
Nice work, helped me get a map into my flex app in under an hour. Adding GM to flex is so much simpler than it was a couple years ago with html/javascript.
rick
how to get intermediate latlongs? Is there any API for this?
this is great, just what I was looking for
I really like this feature of Google Map! Thanks so much!