Get rad!

Recently we've been using some of our own tools in other projects and found some room for improvement on the KML Loader we developed. In particular we wanted a simple class that could handle all the processing from the loader, adding the resulting overlays to the google map. Also we needed it to load in some of the styles, such as colours and line types.

Example Kml Loader ScreenShot

So we've expanded our KmlLoader class and provided a few additional utility classes.

Before we get into it, to get the latest version, just checkout from our public repo:

https://github.com/marchbold/as3-gmaps-utils

The most useful is the SimpleKmlLoader class. This simplifies the loading and display of a kml file to a single line of code.

  1. new SimpleKmlLoader( _map, true ).load( _file );

Generally you'll probably want to do something more with the kml than just display it, but this is handy for those quick display situations. You'll probably more want to do something like this, adding an event listener for when the file is loaded:

  1. var _loader:SimpleKmlLoader = new SimpleKmlLoader( _map, true );
  2. _loader.addEventListener( Event.COMPLETE, loader_completeHandler );
  3. _loader.load( _file );

The second parameter provided to the constructor is an option to automatically add the objects to the map when the load is complete, so you no longer have to worry about adding the features to the map.

Once the loader has completed you'll have access to all the objects loaded from within the file. Each of the Kml Objects is represented by the KmlDisplayObject class, which has automatically created the appropriate type of map feature to add when required.

The important properties are SimpleKmlLoader.objects which is an array of KmlDisplayObject and then KmlDisplayObject.children contains all the children of that object (again an array of KmlDisplayObject).

  1. import com.distriqt.gmaps.kml.utils.*;
  2. /**
  3.  * Iterates over the objects and traces out the name of
  4.  * each and recurses into the children of each object
  5.  * @param _objects An array of KmlDisplayObjects
  6.  * @param _prefix A string to prefix to the output trace
  7.  */
  8. function traceObjects(
  9. _objects:Array /* of KmlDisplayObject */,
  10. _prefix:String = "" ):void
  11. {
  12. for each (var _object:KmlDisplayObject in _objects)
  13. {
  14. trace( _prefix+" "+_object.name );
  15. traceObjects( _object.children, _prefix + "\t" );
  16. }
  17. }
  18.  
  19. function loader_completeHandler( _event:Event ):void
  20. {
  21. traceObjects( _loader.objects );
  22. }
  23.  

The trace output from the function above would look something like the below:

 districts for BSI
	 kangaroo ground
	 kinglake west
	 kinglake
	 ...

There is an example usage of the class in the svn, gmaps/examples/kmlloader/. It will load the kml file shown in the image above.

We've also added some Kml editing and saving tools into the svn which we'll leave those for the subject of another post but feel free to check out the code.


48 Responses to “Simple KML Loader Revisited”

  1. Very cool indeed.. I am not sure why but having a little problem accessing the com.distriqt.gmap.kml.utils

    I am getting an error of

    1172: Definition com.distriqt.gmaps.kml.utils could not be found.

    Reply

  2. Took me a moment to figure out the svn but I almost have this thing working. I am not sure where I am going wrong here. I just want to pull a KML from a weather website onto a simple map.

    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.geom.Point;
    import flash.display.*;
    import flash.events.*;
    import flash.text.*;
    import com.google.maps.LatLng;
    import com.google.maps.Map;
    import com.google.maps.MapEvent;
    import com.google.maps.MapType;
    import com.distriqt.gmaps.kml.utils.*;
    //var kmlLoader:KmlLoader = new KmlLoader();
    //kmlLoader.addEventListener( Event.COMPLETE, kmlLoader_completeHandler );
    //kmlLoader.load( “http://www.hpc.ncep.noaa.gov/kml/qpf/QPF24hr_Day1_main.kml” );

    var map:Map = new Map();
    map.key = “your_api_key”;
    //define the size of the map extent….
    map.setSize(new Point(stage.stageWidth, stage.stageHeight));
    map.addEventListener(MapEvent.MAP_READY, onMapReady);
    this.addChild(map);

    //Lat Long define center, number after defines scale in unit????
    function onMapReady(event:Event):void {
    map.setCenter(new LatLng(39,-98), 3, MapType.NORMAL_MAP_TYPE);
    }

    var kmlLoader:KmlLoader = new KmlLoader();
    kmlLoader.addEventListener( Event.COMPLETE, kmlLoader_completeHandler );
    kmlLoader.load(“http://www.hpc.ncep.noaa.gov/kml/qpf/QPF24hr_Day1_main.kml”);

    function kmlLoader_completeHandler( _event:Event ):void
    {
    for each (var _object:KmlDisplayObject in KmlLoader(_event.currentTarget).objects)
    addObject( _object );
    }
    function addObject( _object:KmlDisplayObject ):void
    {
    // It may just be a container with child elements
    // so check if there is an overlay
    if (_object.overlay != null)
    {
    // Here you can add the kml object to your map
    map.addOverlay( _object.overlay );
    }
    // Add the children
    for each (var _child:KmlDisplayObject in _object.children)
    addObject( _child );
    }

    Reply

    • Josh,

      Your code looks fine! I had a look through the kml you’re trying to load and just note that the loader doesn’t yet load linked kml files. So you’ll have to load the kml directly, in your case thats:

      http://www.hpc.ncep.noaa.gov/kml/qpf/QPF24hr_Day1_latest_netlink.kml

      Also while checking that file I discovered a bug in the google maps extras library that parses the points from the kml. I’ve submitted this to our svn, but it’s not in the google code version yet (Issue 24). But if you’re using our version of the google extras lib you should be able to do an update (svn up in your working directory) and load the kml in successfully.

      Let me know if you’re still having problems.

      Reply

  3. Hey Michael,

    Thanks for getting back to me. I’ve svn’d up and am up on your fixes to the google extras. I am still getting a couple errors in relation to “ColourUril.as, Line 27,35 and 44″. The error is a 1047:Parameter initializer unknown or is not a compile-time constant.

    I am now loading the kml locally. I’d be happy to send you an email if you prefer. Here’s where I am at with this code

    import com.google.maps.LatLng;
    import com.google.maps.Map;
    import com.google.maps.MapEvent;
    import com.google.maps.MapType;
    import com.distriqt.gmaps.kml.utils.*;
    var kmlLoader:KmlLoader = new KmlLoader();
    kmlLoader.addEventListener( Event.COMPLETE, kmlLoader_completeHandler );
    kmlLoader.load( “QPF24hr_Day1_latest_netlink.kml” );

    var map:Map = new Map();
    map.key = “your_api_key”;
    //define the size of the map extent….
    map.setSize(new Point(stage.stageWidth, stage.stageHeight));
    map.addEventListener(MapEvent.MAP_READY, onMapReady);
    this.addChild(map);

    //Lat Long define center, number after defines scale in unit????
    function onMapReady(event:Event):void {
    map.setCenter(new LatLng(39,-98), 3.6, MapType.NORMAL_MAP_TYPE);
    }

    function kmlLoader_completeHandler( _event:Event ):void
    {
    for each (var _object:KmlDisplayObject in KmlLoader(_event.currentTarget).objects)
    addObject( _object );
    }

    function addObject( _object:KmlDisplayObject ):void
    {
    // It may just be a container with child elements
    // so check if there is an overlay
    if (_object.overlay != null)
    {
    // Here you can add the kml object to your map
    map.addOverlay( _object.overlay );
    }
    // Add the children
    for each (var _child:KmlDisplayObject in _object.children)
    addObject( _child );
    }

    Reply

    • This is a weird one, I’ve seen it pop up sometimes, it’s caused by the static initialisers in the static helper functions of the ColourUtil class. Sometimes they don’t seem to be able to reference the static constants in the Endian class.

      I’ve locally defined them in that class now so see how you go with this update.

      Reply

  4. Thanks Michael. I am now getting an “Access of undefined property StringUtil” (ParsingTools.as, Line 52 and 34). Should I have imported StringUtil from somewhere else?

    Reply

    • Hey Josh,
      Yeah that class is part of the mx package so if you’re using the Flash IDE you’ll have to make sure you include the swc packaged with the google extras library, namely GoogleMapsAPIUtilityLibrary.swc. Include that file in “publish settings / actionscript settings / library path”.

      Reply

  5. Michael,

    I’ve been giving your library a try and it seems to be working. Do you have an example that allows you to identfy features on the map? It would be very helpful to have info windows when clicking on features. And have you addressed parsing KMZ?

    Thank you!

    Reply

  6. Nate,

    You can create interactions with the objects contained in the loader. Every KmlDisplayObject has an overlay property which is simply the IOverlay added to the Map. So you can attach mouse listeners and do interactions with this component as you normally do with Overlay’s.

    What in particular are you trying to identify about the features?

    We haven’t looked into KMZ at this stage. The library is still in it’s infancy at supporting the KML features so we’ll attempt to complete that before moving to KMZ.

    Michael

    Reply

  7. Thanks Michael.

    We just want to display info windows for each point/polygon as they would appear in the Javascript API.

    The lack of a robust library in the Flash API that supports GeoRSS, KML, and KMZ, similar to what GeoXML provides seems to be a deal breaker for us. It’s a little disappointing there isn’t a more mature library for the Flash API yet.

    Reply

  8. This is very cool indeed. I am new to flash but I want to learn mapping on platforms other than javascript and finally being able to import .kml files will be wonderful.

    I have run into a problem however, I’ve tried emulating the code above, with a local .kml file. It will compile but nothing from the .kml file will display on the map. I get this error. Any help? I am a newbie remember. I am sure it’s nothing major.

    Thanks!

    TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at com.distriqt.gmaps.kml.utils::KmlDisplayObject()
    at com.distriqt.gmaps.kml.utils::KmlLoader/loader_completeHandler()
    at com.distriqt.gmaps.kml.utils::SimpleKmlLoader/loader_completeHandler()
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at flash.net::URLLoader/onComplete()

    Reply

  9. […] if you haven't read the Simple KML Loader post then head over there first. It explains how to get that KML file loaded and displayed on your […]

    Reply

  10. Hi, I’m using your kml loader and works really well, thank you so much.
    I have a quick question, how would you access (say display in the info window) the kml content? Like you do with the ?
    I tried something like (see my ‘trace’ statement):

    function object_clickHandler( _event:MapMouseEvent ):void{
    var _object:KmlDisplayObject = KmlDisplayObject(_event.currentTarget);
    map.openInfoWindow( _object.latLng,
    new InfoWindowOptions({title: “KML Click Event”, content: “You clicked a KML called: “+ _object.name}));
    trace(“var :”+_object.description);

    It does not like _object.description for some reason.
    What about other accessing other KML properties, like the vertices coordinates for example?

    cheers,

    Andino

    Reply

    • I’m still putting together all the documentation for the classes, so I apologise for there not being any help on the features at the moment.

      However, you can access all of the properties of the kml object using the feature property of the KmlDisplayObject. This property is the Kml Feature object from the kml parser library.

      So you should be able to access:

      _object.feature.description

      Additionally you can access all of the points of the object via the points array. This array contains all of the LatLng points used in the geometry of the object. Of course how these points are used depends on the object. Eg:

      LatLng(_object.points[0]).lat

      Hope that helps in the meantime.

      Reply

  11. I’ve downloaded directly the GoogleMapsAPIUtilityLibrary.swc directly from your site on my windows machine. I’ve also checked it out on my linux box. However, I can’t seem to find any classes starting with com.distriqt.gmaps.

    Am I doing sometihng wrong? Thanks!

    Reply

    • Hi Brian,

      The SimpleKmlLoader class is not in the swc you’ve downloaded. It is a separate class provided as Actionscript code. In order to use it you must check out the library from our svn and put the “com” directory in your project class path.

      So in your project folder you should have the following structure

      com/distriqt/gmaps/kml/utils/SimpleKmlLoader.as
      com/distriqt/gmaps/kml/utils/KmlLoader.as
      com/distriqt/gmaps/kml/utils/KmlDisplayObject.as

      Note: There are other files in our svn but the above 3 are the important ones!

      You’ll also need the google maps utility library. It’s in our svn as well at the moment,

      com/google/…

      Let me know if you’re having problems with svn and I’ll put together a zip package for you.

      Reply

  12. Hi Michael,

    Thanks you, those instructions were perfect!

    Brian

    Reply

  13. Hi,

    I’m trying to run the ExampleKmlLoader.as and getting ‘type not found…’ errors for Feature, Document, Container, Placemark, Style in KmlDisplayObject.as.

    Any ideas why, or can you confirm a couple of basics of the setup necessary to run your sample code? Now working with
    – ExampleKmlLoader.as and example.kml files
    – your utilities from svn
    – flash cs3 IDE
    – gmaps 1.2 swc

    thanks!

    Reply

  14. Regarding my last comment, I’m making progress, finding all the missing classes. wanted to let you know. still the big picture questions remain, if you have a moment.

    also, can you clarify something about your SVN, are the google utilities files all updates to those found on the google code site?

    Reply

  15. OK, totally stuck now at the point where Josh was when you replied 8 Sep 10 at 11:01. I can’t get past the StringUtil problem. I’ve put the swc from your svn into the same google component directory as that of the Google Maps 1.2 library. It doesn’t make an appearance in the Library of the authoring environment however and no improvement to this error msg.

    So in an effort to find an alternative I’ve added the MapUtils.as, but really not sure what that’s getting me. Pamela at google had responded to someone on a related subject, suggesting they find and include all the .as files related to the GoogleMapsAPIUtilityLibrary instead of trying to use that swc file (which was made for flex?). I guess I’m trying random crap at this point.

    Just curious why you chose the flash API to begin with. I’ve done one major project with it and avoided the KML problem by using json for my coordinate data.

    Thanks

    Reply

  16. Hi,
    I’m trying to work out a quick proof of concept for a new project. Can you help me understand what/how this is feasible? I’m using your example kml and got it working with the example.kml file showing southern Australia.

    I’ve swapped that kml file out for my own, which involves a GroundOverlay. I’m not sure what feature types your component supports, or whether this kml is oddly structured, but here’s the file below. I’m getting an error Error #2044: Unhandled error:. text=KML Parse Error: Could not find any features

    checkHideChildren

    40.7283438628567
    40.7203336582895
    -73.9958462529911
    -74.0071665622886

    128
    -1

    onRequest
    http://maps.nypl.org/warper/maps/7149.kml?DBOX=-74.0071665622886,40.7203336582895,-73.9958462529911,40.7283438628567,1

    Reply

  17. Does your parser/entity creator support auto creation of ground overlays? That’s just about all that’s in my kml, such as…
    -GroundOverlay
    –name
    –Icon
    —href
    —viewBoundScale
    –LatLonBox
    —north
    —south
    —east
    —west
    —rotation

    I can get it working in Earth but still “no entities found” when I try it in your example file.

    Reply

    • Phillip,

      Sounds like you got the classes running? Pamela is right in that you should include the class files for use in Flash IDE. The StringUtil problem can be a little confusing but simple to fix once you grab that swc with the class packaged into it for you.

      Unfortunately the loader doesn’t support ground overlays as yet. It’s on my todo list, along with linked files. The error event you are getting is part of the documented class functionality. The ErrorEvent.ERROR type gets dispatched when the loader does not find any features in the file that it can process, so you can listen for this event to check if you’re file is useable.

      The choice for us to use flash is a simple one. It’s the best environment for the type of projects we’re involved in, cross platform with large multimedia components. Other environments just don’t provide the same experience you can get out of flash.

      If you have any suggestions for the loader please let me know. I’ll endeavour to get through my todo list asap.

      Michael

      Reply

  18. Thanks, I’ll check back again about the GO support. That would be excellent! Meanwhile, it looks like I finally got it running.

    Reply

  19. Can anyone help me with this? I am trying to set all of the files so that my flash can reada kml file. Tried different ways and still having issues. If I go to the SVN, how am I suppose to organize the files?

    Thank you.

    Reply

    • Hi Jean,

      You need to checkout or export a version of the source from the svn repository and place the com directory in a directory included in your flash files source paths. To do this you’ll need an svn client, what operating system are you using? eg under linux you can use the command line svn client. First change to your flash source directory and type:

      svn co http://svn.distriqt.com/public/trunk/gmaps/src/

      Reply

  20. Tried to emulate Josh’s code with Flash Builder also but having this error: Error #2044: Unhandled error:. text=KML Parse Error: Could not find any features

    Any quick thought Michael?

    Thanks for sharing this cool stuff with us.

    Reply

    • Hi,

      This error is actually the loader telling you that it couldn’t find/process any features in your kml file. This is generally due to the subset of features that I’ve implemented as yet. I’m currently working through a list of features so will have an update soon, but if you’ve got some in particular you need in your kml let me know and i’ll focus on them initially.

      Glad to hear it’s been of use! Let me know any feedback etc!

      Reply

  21. Hi Michael,

    thanks again for your work and responses.
    I’m having problems getting my markers to display different styles. No matter what I try I always get the red marker icon. DO you have any ideas on how to customize the icons for point features (markers)?

    Reply

  22. To all of you getting “Error #2044: Unhandled error:. text=KML Parse Error: Could not find any features”, make sure that your KML header has this in the second line:

    -cheers

    Reply

  23. To all of you getting “Error #2044: Unhandled error:. text=KML Parse Error: Could not find any features”, make sure that the second line of your KML header begins like this: kml xmlns=”http://earth.google.com/kml/2.2

    -cheers

    Reply

    • The namespace change you had to do is an issue with the kml parser in the google maps utility library, I’m also working with them to get this updated as well.

      Reply

  24. Hi Mike,

    How would you add a progressbar to it when it’s loading the KML file?

    Thanks.

    Harry

    Reply

    • Harry,

      The loader will dispatch ProgressEvent.PROGRESS as the kml file is downloaded, so you can listen for this event and use the bytesLoaded and bytesTotal properties to update a progress bar of your choice. Let me know if you need more information or an example.

      Reply

  25. Hi Michael,

    I was able to figure out the “Do you have any ideas on how to customize the icons for point features (markers)?” issue. I made a few tweeks to the KmlDisplayObject.as file to set some marker styles in there…kinda crude, but works.
    Any tipos on the KML events? Infowindows and tooltip type things act a bit buggy over here.

    anyway, thanks for your work.
    cheers

    Reply

    • Hi

      Glad to hear you sorted the marker styles out, the current loader doesn’t apply any style info to the markers unfortunately but hope it was easy enough to modify to your own needs.

      I’m currently working on a major update to this loader, got a series of additional features going in and the marker styles is one of the major ones, so stay tuned. Should have this out in the coming weeks, but I’ll post about the changes here when it’s up.

      Reply

  26. I am attempting to impliment this loader. I am working in the Flash IDE. when i go to publish out I recieve an error “Error #2044: Unhandled error:. text=KML Parse Error: Could not find any features”

    My kml file is local , when i replace the kml file in the example it works great. any help is appreciated.

    Reply

    • This error is thrown when the KML Parser can’t find any supported features in your KML file.

      What particular features have you used in the KML file? I’m always trying to improve this loader so please let me know, or send over your KML file if you can.

      Cheers

      Reply

  27. Thanks for the update, I cant send over this XML file but I ended up changing the header in the XML file and that resolved my issue.However now i am running into another issue.

    I have a flex project and i am attempting to unload the KML file using loader.removeFromMap();. unfortunately it is not working and not throwing an error , any sugestions. thanks in advance.

    Reply

  28. Hey Michael,

    I have been attempting to use this kml loader (which is great!), after running into a few simple snags with code I got the error that Louie posted on 30 Sep 10 at 16:28. My error looks like this:

    TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at com.google.maps.overlays::Marker()
    at com.distriqt.gmaps.kml.utils::KmlDisplayObject/createGeometryWithStyle()
    at com.distriqt.gmaps.kml.utils::KmlDisplayObject/addPlacemark()
    at com.distriqt.gmaps.kml.utils::KmlDisplayObject/processObject()
    at com.distriqt.gmaps.kml.utils::KmlDisplayObject()
    at com.distriqt.gmaps.kml.utils::KmlDisplayObject/processChildren()
    at com.distriqt.gmaps.kml.utils::KmlDisplayObject/processObject()
    at com.distriqt.gmaps.kml.utils::KmlDisplayObject()
    at com.distriqt.gmaps.kml.utils::KmlDisplayObject/processChildren()
    at com.distriqt.gmaps.kml.utils::KmlDisplayObject/processObject()
    at com.distriqt.gmaps.kml.utils::KmlDisplayObject()
    at com.distriqt.gmaps.kml.utils::KmlLoader/loader_completeHandler()
    at com.distriqt.gmaps.kml.utils::SimpleKmlLoader/loader_completeHandler()
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at flash.net::URLLoader/onComplete()

    I have been unsuccessful in fixing this error. Any help would be appreciated! Thanks

    Reply

    • Hi Otto,

      I’ve got an update here to fix some of the treatments of unknown entities which I’ll put up this weekend. This sort of error was produced when the kml had some elements in it the loader didn’t understand. I’ll shoot you an email when I’ve put it up.

      Michael

      Reply

  29. Sounds great thanks Michael, look forward to seeing the email!

    Reply

  30. Hey Michael,

    I was just wondering if the update was posted yet? I have updated the svn and still get the same results.

    Thanks again!

    Reply

  31. Hi Michael,

    I’m trying to include a google My Map in a website. I have been able to include a sample map in the site. Then I found your kml instructions, navigated to your .as classes, downloaded them, put them in the projects folder, copied and pasted actionscript I found above, but only getting compiler error messages:

    Definition com.distriqt.gmaps.kml.utils cannot be found

    as well as some other concerning types and undefined methods of kmlloader.

    I suspect I may not have put the .as files in the right place? The current path is:
    Flash CS5/Common/Configuration/Actionscript3.0/projects/com/distriqt/gmaps/kml/utils/*.as

    The swc is in Configuration/Components and working well.

    Can you help me out?
    I have another issue as well: once I navigate to the map on the site, it won’t go away when I go to the other pages. It’s not the case with the other pages on the site.

    http://www.industrialmuffins.com
    the map is under: enter > pick-up

    Thanks very much,

    KoffeeKat

    Reply

    • @KoffeeKat

      Sorry about the late reply.

      The error you’re getting with the KmlLoader sounds like you’ve got the classes in the wrong location. The easiest way to include them is to put the “com” directory in the same location as either your fla (for an IDE based project) or at the same location as your main application actionscript file (for a flash builder/mxmlc project).

      With the map not removing, might need a bit more information on your project. Are you using Flash IDE ie. an fla/xfl file? If you want to shoot it over to me, I’d be happy to have a quick look for you?

      Basically the actionscript should be something like this:
      var map:Map = new Map();
      map.key = "ETC";
      // other setup options
      addChild( map );

      Then when you want to remove it:

      if (contains(map)) removeChild( map );

      Reply

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>