Google Maps API Tutorial

© 2007, 2008, 2009 Mike Williams

 
Translate this page:

 

EGeoXml

The primary objective of the EGeoXml extension is to be able to take a "My Maps" KML file, change the file extension to .XML and render the markers, polylines and polygons under the API in a manner that exposes those objects, allowing them to be manipulated by the calling program.

A secondary objective is to support a reasonable range of types of KML files that were not created with MyMaps.

The extension is far from complete, but it does render markers, polylines, polygons, info windows and sidebar.

A more complete extension is available from Lance Dyas: www.dyasdesigns.com/geoxml/

How to use it

  1. take a copy of egeoxml.js, and place it in the same folder as your code.
     
  2. Call the extension code into your page after loading the API code, like this
         <script src="egeoxml.js" type="text/javascript"></script>
  3. Create an EGeoXml() instance, like this
         var exml;
         exml = new EGeoXml("exml", map, "test001.xml");
    
  4. Call the .parse() Method, like this
         exml.parse();

Obtaining the KML file with the Placemarks

If you click the "View in Google Earth" link of the My Maps page, then you get a KML file that contains a NetworkLink instead of a list of Placemarks. EGeoXml can't do anything with that.

To obtain the real KML file from My Maps, you now have to right click on the "View in Google Earth" link, copy the link location ("copy shortcut" in MSIE) and then edit the resulting URL.
Find the bit that says "&output=nl" and change it to "&output=kml".

Constructor

The EGeoXml constructor takes 4 parameters.
  1. A text string containing the name of a global variable into which you will be storing the returned reference.

    That's a bit of a weird one, but I can't see any way round it. I need a global variable so that I can create the HTML for a sidebar entry that can reference the EGeoXml properties (calls from HTML execute in global context) but I don't think I can safely create global variables from inside a method, particularly if I want to allow you to use more than one EGeoXml instance in the same page.

    It might sound complicated, but you just have to make sure that when you write
    foo = new EGeoXml("foo",... the two "foo"s are the same.
     

  2. The map on which the objects are to be rendered
     
  3. Either A text string containing the URL of the XML file. It must be on the same server.
    Or An array of strings containing the URLs of such XML files.
     
  4. An optional set of {options}.

The currently available set of options are:
 

  • {icontype:"style"} Tries to use the icons specified in the "Style" tags of the XML file.
  • {icontype:"default"} Always uses the G_DEFAULT_ICON for the markers. If absent {icontype:"style} is used.
  • {sidebarid: ... } A string containing the ID of a div to be used for the sidebar. If absent, no sidebar is generated.
  • {dropboxid: ... } A string containing the ID of a div to be used for the drop down selection box. If absent, no dropbox is generated.
  • {sidebarfn:...} A reference to your own fundtion for creating sidebar entries. See below
  • {dropboxfn:...} A reference to your own fundtion for creating drop down selection entries. See below
  • {noshadow:true} Plots markers with no shadows. Doesn't work with {icontype:"default"}.
  • {iwwidth: ... } An integer specifying the width of the info window detail div. If absent, it will be set to 250.
  • {titlestyle: ... } A string controlling the style of the info window title field, see below.
  • {descstyle: ... } A string controlling the style of the info window description field, see below.
  • {directionstyle: ... } A string controlling the style of the info window title field, see below.
  • {baseicon: ... } A GIcon() to be used as a basis for the marker icons, see below.
  • {iwoptions:{ ...}} A set of GInfoWindowOptions to be applied to the info windows. E.g. {iwoptions:{maxHeight:300,autoScroll:true}}
  • {markeroptions:{ ... } A set of GMarkerOptions to be applied to the markers. E.g. {markeroptions:{draggable:true}}
    If you set the "icon" option, then the information from the XML file will be countermanded by your setting.
  • {createmarker: ... } A reference to your own createMarker() function.
    Use this if you want to handle your own marker and sidebar creation.
    The function will be called with parameters containing the GLatLng() of the location, then strings containing the "name", the "description" and the "styleUrl" fields from the XML file.
    NOTE: if you write your own createMarker function, then it's up to you whether you implement any of the previous options.
  • {createpolyline: ... } A reference to your own createPolyline() function.
    Use this if you want to handle your own polyline creation.
    The function will be called with the same parameters as new GPolyline(), i.e. points, colour, width, opacity.
  • {createpolygon: ... } A reference to your own createPolygon() function.
    Use this if you want to handle your own polygon creation.
    The function will be called with the parameters: points, colour, width, opacity, fillcolour, fillopacity, bounds, name, description.
  • {addmarker. ... } A reference to your (G)MarkerManager.addMarker() helper function. Use this if you want to manage your markers. See below.
  • {nozoom:true} If this option is absent, then the view will be zoomed to fit the data.
  • {sortbyname:true} The sidebar will be sorted by name.
  • {directions:true} Activate direction finding and local search in the info window
  • {printgif:true} Use gifs when printing icons.
  • {printgifpath:...} A string containing the location of the print gifs.
  • {elabelclass:...} A string containing the name of the CSS class to be used for ELabels, see below.
  • {elabelopacity:...} A number from 0 to 100 specifying the percent opacity of the ELabels.
  • {elabeloffset:...} A GSize specifying the offset of the ELabels.
  • {preloadimages:true} Attempts to preload images mentioned in the description, see below.
  • {polylineoptions:{ ... } A set of GPolylineOptions to be applied to the polylines. E.g. {polylineoptions:{clickable:false}}
  • {polygonoptions:{ ... } A set of GPolygonOptions to be applied to the polygons. E.g. {polygonoptions:{clickable:false}}

Properties

The internal structure of the EGeoXml instance is exposed via these properties:
  • .myvar - stores the first passed parameter from the Constructor.
  • .map - stores the second passed parameter from the Constructor.
  • .url - stores the third passed parameter from the Constructor.
  • .urls - stores an array of URLs to be processed.
  • .opts - stores the fourth passed parameter from the Constructor.
  • .iwwidth - a copy of the opts.iwwidth parameter, or 250 of that parametr is absent.
  • .bounds - a GLatLngBounds object which will be used for the zoom-to-bounds option.
  • .gmarkers - array of markers.
  • .gpolygons - array of polygons.
  • .gpolylines - array of polylines.
  • .groundoverlays - array of ground overlays.
  • .side_bar_html - the HTML string that is used to create the sidebar.
  • .side_bar_list - array used for sorting the sidebar.
  • .styles - an associative array containing information from the Style tags of the XML file.
  • .progress - the number of GDownloadURL requests currently in progress.
  • .lastmarker - a reference to the last marker that was clicked

Methods

EGeoXml.hide() Performs .hide() on all the markers, polylines, polygons and ground overlays, and hides the sidebar or dropbox.

EGeoXml.show() Performs .show() on all the markers, polylines, polygons and ground overlays, and unhides the sidebar or dropbox.

EGeoXml.parseString(txt) accepts a string of text containing the KML data an parses it.

It also accepts an array of strings, each string being a complete KML document.

You can use this instead of EGeoXml.parse().

When using .parseString the "url" parameter of new EGeoXml is ignored, so the whole thing looks like this:

     var exml;
     exml = new EGeoXml("exml", map, null, {sidebarid:"the_side_bar"});
     exml.parseString('<?xml version="1.0" encoding="UTF-8"?> ... </kml>');
or
     var exml;
     exml = new EGeoXml("exml", map, null, {sidebarid:"the_side_bar"});
     var doc1 = '<?xml version="1.0" encoding="UTF-8"?> ... </kml>';
     var doc2 = '<?xml version="1.0" encoding="UTF-8"?> ... </kml>';
     var doc3 = '<?xml version="1.0" encoding="UTF-8"?> ... </kml>';
     exml.parseString([doc1, doc2, doc3]);

"parsed" Event

EGeoXml throws a "parsed" event when the parsing is complete.

The EgeoXml.parse() operation is asynchronous because it uses GDownloadUrl(), so if you have code that should only operate after the markers etc. have all been created, then you'll need to listen for that event.

Using (G)MarkerManager

EGeoXml isn't really suitable for handling large numbers of markers, but using (G)MarkerManager can help speed things up a little.

To use (G)MarkerManager with EGeoXml, create the manager in the normal way, and write a helper function that assigns minZoom and maxZoom settings for each marker. Then use {addmarker: } to tell EGeoXml which function to use.

Whenever EGeoXml has a marker ready to be added to the map, instead of performing map.addOverlay(), it will pass the marker and some extra information to your helper function. Your function should examine the extra information to choose the minZoom and maxZoom settings for the marker and either call manager.addMarker() with that information immediately, or store the marker reference in an array to be used with manager.addMarkers() later when the "parsed" event is triggered.

The passed information is: (marker, title, description, number, iconImage). Your code can examine any of that information for clues about which manager settings to use.

It sounds complicated, but the code is quite simple, see the examples below.

Several pages of My Maps

If your My Map runs to several pages, then each of the XML files will contain data for an individual page.

Pass the URLs of those files in an array, and any overall processing (such as zooming to fit the map view to the data) will be performed on the contents of all the files taken together.

var exml = new EGeoXml("exml", map, ["file1.xml","file2.xml","file3.xml"]); If you use a separate EGeoXml() instance for each file, then the map view will be zoomed to fit the contents of each of those files taken separately. The map ends up being zoomed to fit whichever file request completes last.

Using info window styles

The "titlestyle", "descstyle" and "directionstyle" options allow you to control the CSS styles of the three parts of the info window contents.

There are two basic ways to use these options. You can either use inline styles, like

   {titlestyle:'style = "color:#FF0000;text-align:center;"'} 
or you can set the class attribute so that the info window uses a style from an embedded or external style sheet, like
   {directionstyle:'class = "dstyle"'} 

If you set the class for the directions section, you can additionally declare styles for ".dstyle a" or ".dstyle form" to give the links and form within the directions section their own separate style settings.

Using any of these style settings wipes out the default styles that I apply to the corresponding section of the info window. My default style settings do not cascade.

You can, of course, apply your styles individually by editing the KML file. This facility just allows you to apply styles to the contents of all the info windows at once. Style information from the KML file does cascade.

Clever Stuff: I don't actually limit you to only setting the "class" and "style" atrtributes. If you want to, you can add other attribute settings to the option strings and I'll just plonk them in.

   {titlestyle:'class= "tstyle" onclick="titleclick()" id="Title"'} 

Non-MyMap Icons

EGeoXml uses GIcon properties that use the same size of icon and shadow as the My Maps icons, (32,32) and (59,32). It also guesses the URL of the shadow image using the conventions used by My Maps. That's fine if your XML file really is a My Maps file, but not if you're using a XML file from another source that uses very different icons.

KML files don't specify any information about the icon other than the URLs of the images, so EGeoXml can't obtain the information from there.

So what you can do is create a GIcon() that contains all the properties for your icons, except the .image, and specify it in the {baseicon} option. EGeoXml will use the settings from the base icon plus the image specified in the XML file.

You should specify at least these properties for your base icon: shadow, iconSize, shadowSize, iconAnchor, infoWondowAnchor.

Printing

Google do not provide printable gif equivalents of the My Map icons.

By default, EGeoXml uses a stretched version of the default marker gif when printing. That's pretty ugly.

A slightly better alternative is provided via the {printgif:true,printgifpath:"images/"} options.

When these options are set, EGeoXml will extract the filename of the icon, replace ".png" with ".gif" and use the specified path. E.g. if the icon image is "http://maps.google.com/mapfiles/ms/icons/sailing.png" and the printgifpath is "images/", then EGeoXml will use "images/sailing.gif" for the print icon.

Both options must be specified. The printgifpath can be relative, like "images/" or absolute, like "http://mydomain.com/images/".

A set of gif images matching the My Map png files can be obtained from here: printgifs.zip. To use them, unzip the file and place the gifs in your printgifpath folder.

Custom sidebars and selection boxes

You can now write your own functions for adding entries to the sidebar or drop down selection box.

Your function will be passed:

  1. the name of the global variable that points to the EGeoXml instance
  2. the placemark name
  3. the placemark type ("marker", "polyline" or "polygon")
  4. the index into the correspongding gmarker[], gpolyline[] or gpolygon[] array
  5. HTML that's the same as I use for the polyline or polygon graphic in my sidebars
The drop down selection box currently only supports placemarks of type "marker".

For example, here's a function that creates a sidebar entry that's the same as the EGeoXml default sidebar for markers, but returns an empty string for polylines and polygons:

    function side(myvar,name,type,i,graphic) {
      if (type == "marker") {
        return '<a href="javascript:GEvent.trigger('
          + myvar+ '.gmarkers['+i+'],\'click\')">' + name + '</a><br>';
      }
      return "";
    }
It would be invoked by using {sidebarfn:side}

ELabels

To have ELabels displayed alongside your markers, you need to:
  • Include the elabel.js extension.
  • Create a CSS style class for the label display.
  • Set the {elabelclass} option to specify that sytle class.
  • Optionally specify the {elabeloffset} to control the position of the label relative to the marker.
  • Optionally specify the {elabelopacity}. If omitted, the label will be 100% opaque.
The ELabel parameters are the same as ELabel parameters 3, 4 and 5 described in the Elabel documentation.

Preloading images

If you have images in the <description> field which don't have a height attribute, then the API guesses that they have zero size and doesn't make the info window graphics large enough.

The best way to fix that is to add a height attribute to all your images.

An alternative way to fix it is to use {preloadimages:true}. This will cause EGeoXml to attempt to identify all the image files that you use in your <description> fields, and preload them. If you have lots of large images, this will cause EGeoXml to execute rather slowly.

This only fixes the height of the info window. The width of the info window is controlled by the {iwwidth} parameter. If you have images wider than 250 pixels, then you will need to set {iwwidth} to at least the width of your widest image.

Remote Files

A security feature prevents EGeoXml directly reading files that are on other domains, but if your webhost supports server side scripting you can write a proxy server that reads a remote resource and echoes the data to its output stream.

Examples

Normal use with a sidebar

Using your own createMarker function

Using the default marker icon

Polylines

Polygons

Sorted sidebar, directions and non-MyMap icons

Using info window styles

Using GMarkerManager, method 1

Using GMarkerManager, method 2

Printable gifs and a drop down select box

Using ELabels

Using ClusterMarker

Accessing remote resources uses this server to obtain current data from maps.google.com

Back to Mike's Homepage
Up to the start of this tutorial