Facebook launches iPhone camera app

Internet-Technology

Facebook’s rocky initial public offering hasn’t stopped life at the world’s biggest online social network. On Thursday, the company unveiled a camera app for the iPhone.

The app can be downloaded from Apple’s App Store and works like most other camera applications for smart phones. To take a photo, you tap a camera icon in the upper left corner of your screen, aim and shoot. You can then add filters, crop or tilt your photo, and share it on Facebook.

The new app is similar to Instagram, the photo-sharing app Facebook is in the process of buying for $1 billion. The acquisition, however, has not yet been completed.

Facebook didn’t give details on when it might release a version of the app for phones that run on Google’s Android operating system.

Resources

Google Maps API Tutorial

The Book

Beginning Google Maps Applications with PHP and Ajax

If you want to take your Google Maps further. If you want to take them a lot further, then get the book.

Beginning Google Maps Applications with PHP and Ajax by Michael Purvis, Jeffrey Sambells and Cameron Turner goes a long way beyond what I’ve been able to include in this tutorial.

Don’t be confused by the word “beginning” in the title of the book. This is not a book for beginners. If you don’t have solid grounding in HTML, Javascript and PHP then this book is going to leave you standing. Familiarity with CSS, mySQL, Ajax and XML will also help. I confess that some of the sections were beyond me.

The book isn’t perfect. There are a few typos that you’ll spot immediately you try to write pages that use their code [like “map.addControl(GMap2TypeControl());”]. I, personally, think that it’s a mistake to assume that all your users will have Javascript enabled, rather than using <noscript> to explain to users without Javascript why they’re looking at a blank page. I also think that the section of using the Yahoo Geocoder should have mentioned that it is a violation of the Yahoo Terms to use the Yahoo Geocoder with Google Maps.

One problem with books related to the Internet is that they get out of date really fast. An awful lot has changed since 2006 when the book was published. When the book was written, the API had no GDirections, GGeoXml, GAdsManager, StreetView, GScreenOverlay, GGroundOverlay, Encoded polylines, G_PHYSICAL_MAP, G_SATELLITE_3D_MAP, GMarkerManager or GTRafficOverlay. The Open Source library did not exist, so there was no MarkerManager, LabeledMArker, ExtMapTypeControl, ExtInfoWindow or MapIconMaker. Polygons and polylines were rendered with either VML or via the image server, not SVG or canvas. There were no My Maps, and no Google Spreadsheets. No Google Charts, no Google static maps and no embedded maps. In wider Internet, there was no Firebug, no Safari for Windows, and no Google Chrome.

When it came out, I reckoned that the book should be an indispensable part of the toolkit of any professional web designers who want to include advanced Google Map techniques in their web sites. Things have changed so much in the last two years that make the book rather less useful these days.

The book is divided into three parts.

Part 1: Your First Google Maps covers things like allowing users to add markers and related information to your map and store it in a mySQL database and fetch it back so that other users can see it.

Part 2: Beyond the basics covers things like handling huge numbers of points using several techniques, including creating a custom tile layer generating the tile graphics dynamically in the server, and caching the images to improve response times.
There’s an example at http://googlemapsbook.com/chapter7/ServerCustomTiles with a map that displays over 115,000 data points.

Part 3: Advanced Map Features and Methods covers some advanced topics, like the ability to write your own geocoding service, like this one: http://googlemapsbook.com/chapter11/UKRest/index.php?code=AB10.

There’s also lots of ongoing support from the web site associated with the book,http://googlemapsbook.com including copies of all the source code printed in the book and updated information about things like available geocoders and data sets.

Resources

Google Maps API Tutorial

Some Recommended Tools

Venkman Javascript Debugger

Venkman is the original Javascript Debugger for Firefox and Mozilla. Venkman forms part of the standard Mozilla package and is available as a Firefox extension. You can get the Firefox version here. It’s got a pretty steep learning curve.

I now recommend Firebug (see below) rather than Venkman.

Tidy HTML Validator

There are several HTML validation routines around. I happen to like this one because it’s not overly pedantic about tiny details, and it gives a neat concise explanation of the reasons why it thinks your HTML is incorrect.

It comes as a Firefox extension, and puts a little green tick on the status bar when it considers your code to be valid, so you don’t have to keep remembering to send your page to an external validator whenever you change something, you just watch to see if the green tick turns into a yellow triangle or a red cross.

The Windows version is here. There are Linux, MacOSX and FreeBSD versions here.

Web Developer

An indispensable Firefox Extension for general web development.

For Google maps API work, its “Information:View Javascript” facility is very useful for instantly collecting together all the Javascript contained in the webpage and in all the files that it loads. And the “Disable:Disable Styles:Disable Individual Stylesheet” comes in handy for spotting if any of the strange behaviours of your map are due to CSS settings.

Download the Firefox version here.

Javascript: The Definitive Guide

By David Flanagan. This is the book to read if you want to learn more about Javascript.

It’s part of the O’Reilly series of Definitive Guides, which are all excellent resources for their respective topics.

w3schools

w3schools  is an excellent resource for finding details of almost any web-related technology. Of particular interest to API programmers are their Javscript Tutorial and their Javascript Reference, but their information on other topics can be very useful. If you just want to know about how to use one or two features of a technology like XSLT or CSS, you’ll find comprehensive information and clear examples.

The technologies covered are: HTML, XHTML, CSS, TCP/IP, XML, XSL, XSLT, XSL-FO, XPath, XQuery, XLink, XPointer, DTD, Schema, XML DOM, XForms, SOAP, WSDL, RDF, RSS, WAP, Web Services, JavaScript, HTML DOM, DHTML, VBScript, E4X, WMLScript, SQL, ASP, ADO, PHP, .NET, .NET Microsoft, .NET ASP, .NET Mobile, Media, SMIL, SVG and Flash.

And it’s all free.

MS Visual Web Developer Express

msdn.microsoft.com/vstudio/express/vwd/

Some people have recommended this Microsoft tool. I can’t comment since my computer falls short of the system requirements in almost every category, so I’ve not tried it.

Debugbar

Provides a facility within MSIE that mimics Firebug.

It contains a DOM inspector, HTTP inspector, Javascript Inspector, Javascript console, HTML validator.

It’s still in beta, and performs very erratically on my machine, and interferes with the behaviour of Google Maps, but it’s an awful lot better than nothing.

http://www.debugbar.com/

Companion.js

Javascript debugger for MSIE.

http://www.my-debugbar.com/wiki/CompanionJS/HomePage

Requires Microsoft Script Debugger.

I’ve not tried this out yet.

ieTab

https://addons.mozilla.org/firefox/1419/

Embeds a copy of Internet Explorer inside a Mozilla/Firefox tab.

I think there are only versions for Windows.

This is a great tool for web developers, since you can develop your code in Firefox. Then, with a single click of the ieTab icon, you can see what sort of mess MSIE makes of it, and still be in a Firefox environment.

Firebug

http://www.getfirebug.com

Firebug is an extension that integrates with Firefox to put a wealth of development tools at your fingertips while you browse. You can edit, debug, and monitor CSS, HTML, and JavaScript live in any web page.

Unlike Web Developer, Firebug works on the dynamic version of the page, so, for example, you can look at the way the html elements that contain the map change as you make calls to the API.

To get the best out of Firebug, you need to install the Firefox DOM Inspector. The DOM Inspector isn’t an extension, it’s an optional component of Firefox. To install the DOM Inspector you need to re-install Firefox and choose the “Custom Setup” option instead of “Standard”.

There seem to occasionally be severe conflicts between Venkman and Firebug, when Venkman tries to handle errors that are thrown by the Firebug code. I’ve ended up uninstalling Firebug for now, because I’ve already invested a lot of time learning Venkman. If you’re starting out from scratch, I’d suggest learning Firebug rather than Venkman plus Web Developer.

Chrome Inspector

View your page in Google Chrome, right-click on an element and select “Inspect Element”.

This gives you:

  • A detailed view of the dynamic HTML and styles, including the details of what’s going on inside the map structure.
  • A Javascript command console.
  • Information about the timing and size of resources such as image files and Javascript modules.

Pagetest

Useful for addressing performance issues. Provides standard performance tests for your web page.

Paste the URL of your page into pagetest.patrickmeenan.com:8080/

I recommend this rather than using the resources information from Firebug or Google Chrome because they give results that are distorted by the fact that connectivity to your own server may well be perceived as being much faster than other people will see it. The tests are performed with MSIE, which has performance issues which may need to be addressed which Firefox and Chrome don’t exhibit. You get the option to perform the tests over three different line speeds.

Javascript Concepts

Google Maps API Tutorial

Javascript Concepts: Scope

In common with most modern computer languages, Javascript variables and functions have “scope”. What this means is that the variable or function can only be accessed from within the function that “var”ed it.

In languages without scope, such as early versions of BASIC and COBOL, people working on different parts of the same program had to be careful not to use the same variable for different purposes. If Fred wrote a useful BASIC subroutine that used the variable “A”, and Dave incorporated that subroutine into one of his programs that also happened to use a variable called “A”, then calling the subroutine would change the value of “A” which might cause Dave’s program to behave incorrectly in a completely different part of the code that expected the original value.

In a scoped language, Fred can write a function that uses separate “local” variables which only exist inside that function, and there’s no danger of them clashing with “global” variables of the same name that exist in the calling program.

If you really really want to, you can explicitly access the global variable, by referring to it like “window.A”. Global variables are properties of the “window” object.

Undeclared variables

If you assign a value to a variable without first “var”ing it, then a global variable of that name is created for you.

In MSIE, there’s a conflict with the fact that it already creates a global variable that matches the “id” of each element that has an “id”. Attempting to assign a new value to a variable that MSIE created that way, without using “var”, will throw an error.

Not block structured

If you’re familiar with block-structured languages, such as C, Pascal and Java, then you might possibly be caught out by the fact that Javascript is not block-structured. Variables that are created inside blocks (such as for loops and if statements) persist until the end of the function. For example, if you’re used to a block-structured language, you might expect variable in this example to display the value “123”.

   function foo() {
     var i=123;
     for (var i=0; i<3; i++) {
       ...
     }
     alert(i);
   }

In Javascript, the value displayed is “3”. That’s because “i” is local to the function, not local to the “block”, so the “i” used inside the for is the same as the one declared outside the for loop.

Note that Javascript doesn’t complain if you “var” the same variable more than once within the same scope.

Calling Javascript from HTML

Whenever you make calls from HTML to Javascript, e.g. from the “onclick” of a button, the called Javascript executes in global context. This means that any functions or variables referenced in the “onclick” string must be global.

Local functions

In the same way that variables can be local to a function, functions can be local to another function.

It’s all to easy to do this by mistake if you change your code from something that runs inline to something that’s called from <body onload=”loadMap()”>. You can’t just wrap “function loadMap() {” … “}” around the whole of your code and expect it to work because functions that were previously global will have become local functions of loadMap().

Compatibility

Google Maps API Tutorial

APIv2 supports the old v1 documented commands (except openInfoWindowXslt) as well as the new v2 syntax.

If you already have a working v1 map that doesn’t use any undocumented features, then you can just change the version number when you load the API code and it may well work the same.

One significant source of incompatibility is that you must perform a map.setCenter() before adding any overlays.

Third Party Extensions

Google Maps API Tutorial

Using the EBubble extension

The EBubble extension provides an alternative to custom info windows.

You can use EBubbles in a similar manner to info windows, but the technology is completely different, and causes significant differences in the behaviour.

  1. The background of an EBubble is fixed-size image file. That allows you to make the graphic as fancy as you like, but it’s obviously only suitable in situations where your contents conform to a standard size.
  2. The EBubble is not attached to the map, it’s attached directly to the <body>. This has the advantage that the EBubble can lie partly outside the map, but has the disadvantage that it doesn’t move when the map moves.
  3. In order not to look silly when the map moved from under it, the EBubble closes when the map moves.
  4. In order to minimise strange click-through behaviour, by default the EBubble closes when clicked.

Here’s an example

The background image for that EBubble was created in PaintShopPro using a simple speech bubble object. I applied the Inner Bevel effect to make it look a little 3D, added a central drop shadow, and gave the whole image partial transparency.

The basic procedure for using an EBubble is:

  1. Download ebubble.js and place it on your web site.
  2. Load the Javascript code like this <script type=”text/javascript” src=”ebubble.js”></script>
  3. Create one or more EBubble instances.
  4. Open the EBubble with bubble.openOnMarker(marker,html) or bubble.openOnMap(point, html, offset)

EBubble Constructor

The parameters for new EBubble() are:

map The map on which the EBubble is to appear.
image URL of the background image
imageSize GSize() specifying the size of that image
contentSize GSize() specifying the size of the inner area when the contents can be written.
contentOffset GPoint() specifying the offset of top left corner of the inner area from the top left corner of the background image
anchor GPoint() specifying the anchor point of the image
noCloseOnClick Optional: set to true to not close the EBubble when it is clicked

The content is not actually constrained by the contentSize parameter. If you put more content into it, then the contens will overflow.

Specifying noCloseOnClick may sometimes cause strange click-through behaviour, but it might improve things if you’re experiencing problems with clickable elements inside your EBubble contents.

Opening an EBubble

There are two methods provided for opening an EBubble

bubble.openOnMap

This opens the EBubble on the map that you specified in the EBubble constructor.

point A GLatLng() or GPoint() specifying the geographical location
html A string containing the HTML to be displayed.
offset (optional) A GPoint() specifying a pixel offset.

bubble.openOnMarker

This opens the EBubble on the map that you specified in the EBubble constructor, with a location derived from the specified marker.

This call uses the infoWindowAnchor parameter of the icon that is being used by the marker.

marker The marker on which the EBubble is to be opened.
html A string containing the HTML to be displayed.

Multiple EBubbles

You can have as many EBubbles as you like on the same map.

You can use different background images for different EBubbles.

Closing an EBubble

Use bubble.hide()

The EBubble wil also close automatically if the map moves or if the user clicks on the EBubble.

I provide a bubble.show() method, but I don’t recommend using it, because it doesn’t track map movements. If you want to re-open the bubble, use .openOnMap() or .openOnMarker() again.

Events

When an EBubble is clicked, it throws a “click” event.

More About The Parameters

Consider this bubble image:

While creating the image, I recorded the following information:

The total size of the image is (297,243), which makes the 3rd parameter new GSize(297,243)

The contents go in the rectangular area marked by the black box. The size of the box is (224,126), which makes the 4th parameter new GSize(224,126)

The green dot indicates the position of the black box. It is located at (36,28), which makes the 5th parameter new GPoint(36,28)

The red dot at the tip of the stem is the point which will be anchored to the map location. It is located at (175,238), which makes the 6th parameter new GPoint(175,238)

Here’s an example which uses that image.

Credits

Inspired by the Radio Shack Store Locator: www.radioshack.com/storeLocator3 (but not using any of their code) (I couldn’t understand it).

Third Party Extensions

Google Maps API Tutorial

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: http://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&#8221; 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/&#8221;.

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


Third Party Extensions

Google Maps API Tutorial

Using EInsert.groundOverlay

EInsert.groundOverlay() is a static method which creates an EInsert() object using parameters similar to those of GGroundOverlay(). I.e. it uses a GLatLngBounds to specify the corners of the region, instead of using a centre point and size.

Here’s an example

In order to use EInsert.groundoverlay() you need to:

  1. Create a suitable image. Transparent PNG format is particularly suitable. Animated GIF format is not suitable.
  2. Include a copy of the “einsert.js” file. Please take your own local copy, don’t hot link to my copy of the file.
  3. Create some EInsert objects using EInsert.groundoverlay().
  4. Use map.addOverlay() to add them to the map.

Create some EInsert objects using EInsert.groundoverlay()

E.g.

      var insert = EInsert.groundOverlay("foo.png",new GLatLngBounds(sw,ne));

The parameters are:

  1. A string containing the URL of the image.
  2. A GLatLngBounds() specifying the bounds of the region.
  3. (Optional) zindex and pane control value.
    Use -1 if you want this EInsert to be placed below any polylines and GTileLayerOverlay()s.
    use 0 if you want this EInsert to be placed above any polylines and below any GTileLayerOverlay()s.
    Use 1 if you want this EInsert to be placed above any polylines and GTileLayerOverlay()s.
    Use other values to place one EInsert above or below another.
  4. (Optional) GProjection to be used for non-mercator map
  5. (Optional) Zoom level to be used for calculations if the GProjection doesn’t have a zoom level 17.

For normal maps that use the Mercator projection, omit the last two parameters.
The number of zoom levels in a GProjection is not exposed, so if you are using a custom GProjection with fewer zoom levels, you need to tell me the highest zoom level that I can use for the calculations.

Note Don’t write “new EInsert.groundOverlay(…)”. EInsert.groundOverlay() is a static method, not a constructor.

The EInsert() created by EInsert.groundOverlay() supports all the usual EInsert() methods. See Using the EInsert extension

Third Party Extensions

Google Maps API Tutorial

Using the EInsert extension

The EInsert extension is implemented as a Custom Overlay.

The EInsert extension allows you to attach a scalable image to the map. The extension scales the image as the zoom level changes.

Here’s an example

You could use EInserts to:

  • add updates to the Google maps (as in that example)
  • draw small complex boundary lines or tracks in a way that runs faster than polylines, and is easier to implement than a custom maptype.
  • add detailed plans of individual facilities.
  • draw circles, like this.

In order to use EInsert you need to:

  1. Create a suitable image. Transparent PNG format is particularly suitable. Animated GIF format is not suitable.
  2. Include a copy of the “einsert.js” file. Please take your own local copy, don’t hot link to my copy of the file.
  3. Create some EInsert objects.
  4. Use map.addOverlay() to add them to the map.

1. Creating a suitable image

I used an image processing package that supports layers, and drew the “Hawking Way” graphic on one layer with a copy of the satellite imagery on another layer.

EInsert assumes that the image can be used with the AlphaImageLoader in IE, so avoid file formats that AlphaImageLoader can’t handle, such as animated GIF.

Make a note of the dimensions of the image and the zoom level it was created to match.

2. Include a copy of the “einsert.js” file

Download it from here einsert.js

Include it like

    <script src="einsert.js" type="text/javascript"></script>

3. Create some EInsert objects

E.g.

      var insert = new EInsert(new GLatLng(53.8,-3.0),
                   "hawkingway.png", new GSize(159,435), 16);

The parameters are:

  1. A GLatLng() specifying the location of the centre of the image.
  2. A string containing the URL of the image.
  3. A GSize() specifying the size of the image.
  4. A number specifying the zoom level on which the image is to be displayed at full size.
  5. (Optional) zindex and pane control value.
    Use -1 if you want this EInsert to be placed below any polylines and GTileLayerOverlay()s.
    use 0 if you want this EInsert to be placed above any polylines and below any GTileLayerOverlay()s.
    Use 1 if you want this EInsert to be placed above any polylines and GTileLayerOverlay()s.
    Use other values to place one EInsert above or below another.

4. Use map.addOverlay() to add them to the map.

And use map.removeOverlay() if you want to remove them.

map.clearOverlays() will also remove all the EInserts as well as any markers and polylines.

Hide and Show

The insert.hide() method makes the EInsert invisible.

The insert.show() method makes the EInsert visible.

The insert.isHidden() method returns true if the EInsert is hidden.

The insert.supportsHide() method returns true, indicating to the API that EInserts support hide(), show() and isHidden().

More Methods

The insert.getPoint() method returns the position of the EInsert.

The insert.setPoint(latlng) method moves the EInsert to a new position.

The insert.setSize(gsize) method changes the size of the EInsert.

The insert.setImage(url) method changes the image of the EInsert.

The insert.setZindex(a) method changes the zIndex of the EInsert relative to other EInserts.

Notes

EInserts are placed below the markers and info windows.

You can click, double-click and drag parts of the map that are underneath EInserts.

You don’t need to keep a reference to your EInserts unless you want to removeOverlay() them, hide() them or change their properties.

Positioning Hint

An easy way to place your EInserts in the correct place is to make them draggable.
See Draggable EInserts

Using EInserts with MarkerManager

EInserts work under the Open Source MarkerManager.

The Open Source MarkerManager can be obtained here http://code.google.com/p/gmaps-utility-library-dev/wiki/Libraries.

MarkerManager can manage EInserts in the same way that it can manage GMarkers.

Here’s an example that uses 1576 EInserts

Third Party Extensions

Google Maps API Tutorial

Animated Markers

From API v2.59, the API supports animated GIFs as markers in all browsersThe techniques described on the rest of this page are no longer necessary

You may have noticed that the API accepts GIF images as markers, but that animated GIF icons don’t work in IE. This is because the API loads the marker image with the “DXImageTransform.Microsoft.AlphaImageLoader” filter under IE, so that transparent PNG files are displayed correctly, and that filter doesn’t handle animated GIFs.

This example  shows three strategies for animating a marker.

The main v1 methods are no longer possible, so the only possibility is to use a third party extension.

The example shows three implementations of clickable animated markers using third party extensions. From left to right:

  1. Pure TLabel
    The contents of the TLabel are an animated GIF.
    addDomListener() is used on the TLabel div to catch mouse clicks and open an info window.
  2. TLabel plus GMarker
    The contents of the TLabel are an animated GIF.
    An invisible GMarker is plotted at the same location. The GMarker mouse target goes above the TLabel to catch the clicks and the GMarker shadow goes underneath.
  3. ELabel plus GMarker
    The contents of the ELabel are an animated GIF.
    An invisible GMarker is plotted at the same location. The GMarker mouse target goes above the ELabel to catch the clicks and the GMarker shadow goes underneath.ELabels overlap intelligently when the “overlap” property is set.

Third Party Extensions

Google Maps API Tutorial

Using the ELabel extension

The ELabel extension is implemented as a Custom Overlay.

ELabel allows you to place text labels or images or any other HTML elements on the map and have them move with the map, like marker and polyline overlays

Here’s an example

In order to use ELabels you need to:

  1. Create CSS class styles for your labels. It is possible to run ELabels without them, but it’s generally easier to use them.
  2. Include a copy of the “elabel.js” file. Please take your own local copy, don’t hot link to my copy of the file.
  3. Create some ELabel objects.
  4. Use map.addOverlay() to add them to the map.

1. CSS Class Styles

Create CSS class styles for your ELabels to use. E.g.

    <style type="text/css">
    .style1 {background-color:#ffffff;font-weight:bold;border:2px #006699 solid;}
    </style>

You’ll probably find it a lot easier to use pre-defined styles.
You’ll usually want to include a background-color style setting, because the default is to have an invisible background.

2. Include a copy of the “elabel.js” file

Download it from here elabel.js

Include it like

    <script src="elabel.js" type="text/javascript"></script>

3. Create some ELabel objects

E.g.

      var label = new ELabel(new GLatLng(44.3,-78.8), "Utopia", "style1");

The parameters are:

  1. a GLatLng() specifying the location.
  2. a html string to be used as the contents of the ELabel.
  3. (optional) a string containing a class name, corresponding to the class style you created in step 1.
  4. (optional) a GSize() specifying a pixel offset from the GLatLng(). Without this parameter, the bottom left corner of the ELabel will touch the location specified by the GLatLng
  5. (optional) an opacity percentage. If omitted, the ELabel will be 100% opaque.
  6. (optional) set this to true to cause ELabels to overlap intelligently. If omitted, the latest one to be addOverlay()ed will be on top.

4. Use map.addOverlay() to add them to the map.

And use map.removeOverlay() if you want to remove them.

map.clearOverlays() will also remove all the ELabels as well as any markers and polylines.

Notes

ELabels are placed above the markers and below the info window.

You can click markers that are underneath ELabels, even if the marker is 100% opaque.

You can click, double-click and drag parts of the map that are underneath ELabels.

You can use different style classes for different ELabels on the same map.

You don’t need to keep a reference to your ELabels unless you want to removeOverlay() them or change their properties.

The content of an ELabel can be as complex as you want. Here’s an example of slightly more complex content.

Manipulating ELabels

When an ELabel is not addOverlay()ed, you can change its properties directly. e.g.

    map.removeOverlay(label)
    label.pixelOffset=new GSize(20,10);
    map.addOverlay(label)

While a label is addOverlay()ed, the following methods can be used to modify its properties dynamically.

  • label.hide() : Makes the label invisible
  • label.show() : Makes the label visible if it was hidden
  • label.setContents(html) : changes the contents of the label.
  • label.setPoint(glatlng) : changes the location of the label.
  • label.setOpacity(number) : changes the opacity of the label.

Using ELabel with MarkerManager

ELabels work under the Open Source MarkerManager.

The Open Source MarkerManager can be obtained here http://code.google.com/p/gmaps-utility-library-dev/wiki/Libraries.

Now that the Open Source MarkerManager is available, I’m not going to be updating ELabels to work under new releases of the obfuscated GMarkerManager. The problem is that I need to know the internal name by which GMarkerManager requests the location of the overlays that it manages. MarkerManager uses overlay.getPoint(), but the obfuscated GMarkerManager changes the internal function name whenever the code is re-obfuscated.

MarkerManager can manage ELabels in the same way that it can manage GMarkers.

Here’s an example that uses 1576 ELabels.

Markered Labels

If you try to place an ELabel alongside every marker, then you can get the the markers to overlap the markers sensibly and the labels to overlap the labels sensibly, but the labels and markers don’t overlap each other sensibly.

What you can do is place an <img> of the marker inside the ELabel contents, so now the marker image and text acts as a single ELabel, and the intelligent overlapping works.

If you care about how the image looks in MSIE6, then you need to to add code to switch to using the AlphaImageLoader if the browser is MSIE. Or you could use a GIF image instead of a PNG.

If you want the markers to be clickable, then place an invisible GMarker at the same location. ELabels are not clickable, so the click drops through to the GMarker below it.

Here’s an example.

Just for fun, I bump up the opacity of the label when the info window is open on the GMarker associated with it. You could do the same thing with mouseover and mouseout events on the GMarker.

Bugs

IE sometimes seems to return false information about the height of the ELabel contents. This causes the vertical positioning of the ELabel to be incorrect.

Updates

v0.2: 5 April 2006: ELabel.copy() fixed. The labels now get copied correctly into .showMapBlowup()’s.
(Thanks to “Jacob” for pointing out the problem)

v1.0: 7 April 2006: Lots of new methods added

v1.1: 31 Dec 2006: Works with GMarkerManager under API v2.67 to v2.71

v1.2: 25 Feb 2007: Works with GMarkerManager under API v2.67 to v2.75

Third Party Extensions

Google Maps API Tutorial

Third Party Extensions

This is a list of all the third party extensions that I know about.

Clusterer Handles large numbers of markers.
OverlayMessage Place a semitransparent message over a map.
ELabels Place any html element on a map (good for text labels)
GxMagnifier Adds a moveable magnified window
GxMarker Provides markers with built in tooltip support and hover events
EInsert Attach an image to the map that scales when the map zooms
EWindows Multiple custom info windows
PDMarker Change marker images, show tooltips on hover, customised info windows, manage lists of markers, store marker data, etc.
Custom Tile Generator Generates tiles from an XML description
GRoutes Provides functionality for displaying multiple routes
BpBrowser Exposes browser and Operating System info
BpDownloadUrl Like GDownloadUrl but with more options
BpLabel Place any html element on a map (good for text labels)
BpMarker Extended Marker class with tooltip and mousover icon swapping
BpMarkerLight Extended Marker class with tooltip and mousover icon swapping
BpMarkerList Automatic sidebars.
BpWindow Display info in a box that can extend outside the map.
BpControl Simple interface to GControl.
MapTypeMenuControl A compact map type control
MarkerManager An improved Open Source version of GMarkerManager
LabeledMarker Puts text onto markers
EGeoXml Renders My Maps KML files and other similar KML files.
HtmlControl HtmlControl provides an easy way to add and position custom GControls over your Google Map.
EPoly Adds a few methods to polygons and polylines.
ASP.NET Control Write Google Maps with ASP.NET code instead of Javascript
EBubble An alternative to info windows
GeoXml Renders KML, GML, GPZ and GeoRSS files.
Blocks Simplified markers. Faster than GMarkers.
Graticules Display lat/lng grid or UK National Grid.
Arrows Displays small arrows using SVG or VML.
Offsetable Marker A draggable marker that leaves a line pointing back to where it came from.
Scaled Circle Displays a scaled circle using SVG or VML.
Clickable Polylines and Polygons Displays clickable polylines and polygons using SVG or VML.
Distance to Poly Calculates the distance of a point from a polyline or the boundary of a polygon.
Calculate US OS references Calculates UK Ordnance Survey map references.
ExtInfoWindow Customised Info Window
GMouseWheelControl Extra mouse functionality
ClusterMarker Detects and substitutes markers that would overlap
Bearings and Directions Functions for distances, bearings, rhumb lines, etc.
GeoKit A Rails plugin
USNaviguide_Google_Tiles A Perl module that calculates tile details
jMaps jQuery plugin for Google Maps
Parallel Lines Creates a pair of parallel polylines
MStatusControl Displays map centre, SW and NW corners, zoom level and mouse position (tile numbers, (x,y) position and lat/lon)
MapIconMaker Easily create dynamically sized and coloured icons.
MarkerTracker Display directional indicators for markers as they move out of a maps view.
GReverseGeocoder Reverse Geocoder
ourarea allows you to easily create an embeddable Google Map showing the area around your business that you deliver to or support.
EShapes provides a number of additional static methods for GPolyline and GPolygon for creating certain shapes
Frame Animation Frame animation overlay
MControl Suite A bunch of custom controls.
cSnapToRoute Snap a marker to the closest point in a polyline
ProgressbarControl Progress bar control
NASA Maps NASA Extensions to the Google Maps API
Geometry Controls Edit content just like My Maps
CSGeoXml Renders KML files as a single overlay.
Intellisense Helper Intellisense helper for VS2008.
ClusterManager Substitutes markers that would overlap with clusters.
Popup Title A little popup for GMarkers
Dragzoom Zoom by dragging a rectangle on the map
ExtLargeMapControl Custom Large Map COntrol that uses the new graphics
ExtMapTypeControl Adds overlay controls that look like map type controls
SnapToRoute Snap a marker to closest point on a line.
MultiIconMarker Change marker icon when an event occurs
MyMapExplorer Embed MyMaps in your web page
Custom Marker Maker Creates suitable files for a custom marker.

Clusterer

Allows you to use large numbers of markers by collecting them into “clusters” to avoid having too many markers drawn on the screen at any time.
Author: Jef Poskanzer

Example page: http://www.acme.com/jef/hotsprings/ and my example

Information: http://www.acme.com/javascript/#Clusterer and my tutorial

OverlayMessage

OverlayMessage allows you to place a semi-transparent message over the top of any HTML element. It’s not a true Google API Map extension, because it works equally well on things other than maps.
Author: Jef Poskanzer

Example page: my example

Information: http://www.acme.com/javascript/#OverlayMessage

Elabels

ELabels allow you to place any HTML element on a map as a Custom Overlay. You can use it in a similar manner to TLabel.
Author: Mike Williams

Information: my tutorial

Example Page:my example

GxMagnifier

GxMagnifier is a free add-in control for Google Maps that creates a moveable, magnified window on top of your map.
Author: Richard Kagerer

APIv2 compatibility: Andre Howe

Example page: boxme.net/wdch/test.html

Download: boxme.net/wdch/GxMagnifier2.js

Information (v1 version): http://www.googlemappers.com/libraries/gxmagnifier/docs/default.htm

GxMarker

Provides markers with built in tooltip support and hover events.
Author: J. Shirley

APIv2 compatibility: Robert Aspinall

Information: code.toeat.com/package/gxmarker

EInsert

The EInsert extension allows you to attach a scaleable image to the map. The extension scales the image as the zoom level changes.
Author: Mike Williams

Information: my tutorial

Example Page:my example

EWindows

The EWindows extension provides some of the functionality of Custom Info Windows.
You can design your own info window styles, and have more than one EWindow open on the same map.

Author: Mike Williams

Information: my tutorial

Example Page: my example

PdMarker

PdMarker is a Javascript extension to Google Maps markers. You can change marker images, show tooltips on hover, customised info windows, manage lists of markers, store marker data, etc.
Author: Peter Jones

Information: http://www.pixeldevelopment.com/pdmarker.asp

Example Pages:www.pixeldevelopment.com/virtualgoogleearth.asp
http://www.pixeldevelopment.com/showmap.asp?gallery=stanleypark2004&caller=index.asp

Custom Tile Generator

This Windows desktop application accepts XML files that describes shapes (beziers, closed curves, curves, ellipses, images, polygons, polylines, rectangles, text and filled shapes) and generates a set of tiles suitable for using in a custom GTileLayer.
Author: Jacob Reimer

Information: http://www.reimers.dk/blogs/jjrdk/archive/2006/04/14/216.aspx and http://www.reimers.dk/blogs/jjrdk/archive/2006/05/09/252.aspx

Example Page: http://www.reimers.dk/demos/wmsdemo.aspx

GRoutes

GRoutes is a JavaScript package that provides functionality for displaying multiple routes (including an associated set of markers) on a map along with a control to switch between maps. Informational texts on the markers to be displayed in the info window (bubble) are also supported.
Author: Holger Pollmann

Information: http://www.stud.uni-giessen.de/~st8632/misc/internet/googlemaps.html

Example Page: http://www.stud.uni-giessen.de/~st8632/misc/internet/groutesdemo.html

BpBrowser

Encapsulates browser, os, and version information. Free for commercial and non-commercial use.
Author: Bitperfect Internet Solutions

Information and examples: http://www.gmaptools.com

BpDownloadUrl

A more fully-featured version of GDownloadUrl, allowing you to execute POST and synchronous AJAX requests. Free for commercial and non-commercial use.
Author: Bitperfect Internet Solutions

Information and examples: http://www.gmaptools.com

BpLabel

A robust GOverlay subclass. Lets you put HTML on the map as an overlay. Free for non-commercial use.
Author: Bitperfect Internet Solutions

Information and examples: http://www.gmaptools.com

BpMarker

A GMarker subclass with a few extra options. Free for non-commercial use.
Author: Bitperfect Internet Solutions

Information and examples: http://www.gmaptools.com

BpMarkerLight

A light-weight GOverlay subclass with image and icon swapping, tooltip support, etc. The fact that it’s light-weight allows you to add hundreds of markers to a map quickly. Free for non-commercial use.
Author: Bitperfect Internet Solutions

Information and examples: http://www.gmaptools.com

BpMarkerList

Encapsulates a map sidebar which holds divs which represent markers. Allows for sorting, managing div content and events through the use of HTML templates, and more. Free for non-commercial use..
Author: Bitperfect Internet Solutions

Information and examples: http://www.gmaptools.com

BpWindow

An infoWindow-type tool which can open outside the map. As a result, the map will never automatically pan to show its contents. It also can open outside of its iframe, and open up, right, left, or down, depending on what direction will allow it to open within existing page borders. Free for non-commercial use.
Author: Bitperfect Internet Solutions

Information and examples: http://www.gmaptools.com

BpControl

A simple interface to GControl()
Author: Bitperfect Internet Solutions

Information and examples: http://www.gmaptools.com

MapTypeMenuControl

A compact drop-down map type control.
Author: Dawn Endico

Information and examples: maps.tafoni.net/MapTypeMenuControl/

MarkerManager

Improved version of GMarkerManager.
As well as doing everything that GMarkerManager does, the Open Source version allows markers to be removed, has some bug fixes, and can be used to manage custom overlays, such as ELabels and EInserts, as well as GMarkers.

Author: Doug Ricket, others

Information and examples: code.google.com/p/gmaps-utility-library-dev/wiki/Libraries/

LabeledMarker

Supports markers with textual labels.
Author: Mike Purvis

Code and example: gmaps-utility-library.googlecode.com/svn/trunk/labeledmarker/

Hint: LabeledMarker works well alongside MapIconMaker, like this

EGeoXml

The EGeoXml extension renders My Map KML files and other KML files of similar structure. The internal structures are exposed, allowing you to have much more control than when using GGeoXml.
Author: Mike Williams

Information: my tutorial

Example Page: my example

HtmlControl

HtmlControl provides an easy way to add and position custom GControls over your Google Map.
An HtmlControl can contain any valid HTML markup and can be styled with any valid CSS style-rules.
HtmlControl makes it easy to create; buttons, hideable menus and forms, map loading messages and much more!
Author: Martin Pearman

Information: googlemapsapi.martinpearman.co.uk/htmlcontrol

Example Page:googlemapsapi.martinpearman.co.uk/htmlcontrol/demo_map.php

EPoly

Author: Mike Williams
Adds methods to GPolygon and GPolyline for determining the area, bounds, path length and whether a GLatLng is contained within the poly.

Information: my tutorial

Example Page: my example

ASP.NET Control

Author: Subgurim
Code and information: en.googlemaps.subgurim.net

EBubble

The EBubble extension provides an alternative to info windows.
Author: Mike Williams

Information: my tutorial

Example Page: my example

GeoXml

The GeoXml extension enables client-side parsing and viewing of a number of flavors of GeoXml, including GML from WFS servers, GPX from GPS devices or log as well as KML and multiple flavors of GeoRSS,In addition to the XML it supports saving out and re-loading of KJSON.
Author: Lance Dyas

Information and example: http://www.dyasdesigns.com/geoxml

Blocks

These are a very simple coloured block marker with a tooltip. The point of these is that for the same load time, you should be able to use more of these on a map than you can GMarkers.
Author: “Bill Chadwick ”

Information: http://www.bdcc.co.uk/Gmaps/BdccGmapBits.htm

Graticules

Display lat/lng grid or UK National Grid.
Author: “Bill Chadwick ”

Information: http://www.bdcc.co.uk/Gmaps/BdccGmapBits.htm

Arrows

Displays small arrows using SVG or VML.
Because this extension relies on SVG or VML, it will not work in browsers which do not support these features.

Author: “Bill Chadwick ”

Information: http://www.bdcc.co.uk/Gmaps/BdccGmapBits.htm

Offsetable Marker

This uses sub-classing on GMarker to provide a marker that can be dragged from its spot but leaves a line indicating its actual reference point.
Author: “Bill Chadwick ”

Information: http://www.bdcc.co.uk/Gmaps/BdccGmapBits.htm

Scaled Circle

Displays a scaled circle using SVG or VML.
Because this extension relies on SVG or VML, it will not work in browsers which do not support these features.

Author: “Bill Chadwick ”

Information: http://www.bdcc.co.uk/Gmaps/BdccGmapBits.htm

Clickable Polylines and Polygons

Displays clickable polylines and polygons using SVG or VML.
Because this extension relies on SVG or VML, it will not work in browsers which do not support these features.

Author: “Bill Chadwick ”

Information: http://www.bdcc.co.uk/Gmaps/BdccGmapBits.htm

Distance To Poly

Calculates the distance of a point from a polyline or the boundary of a polygon.
Author: “Bill Chadwick ”

Information: http://www.bdcc.co.uk/Gmaps/BdccGmapBits.htm

Calculate US OS references

Converts Lat/Lng pairs to UK Ordnance Survey references, like “SU 66277 62491”.
Author: “Bill Chadwick ”

Code: http://www.bdcc.co.uk/Gmaps/LatLngToOSGB.js

ExtInfoWindow

Customised Info Window.
Author: Joe Monahan

Information and examples: gmaps-utility-library.googlecode.com/svn/trunk/extinfowindow/.

GMouseWheelControl

A custom control built by using Google Map API to enhance the usage of a mouse on Google Map. It can be used in any Google map mashups. It takes advantage of scroll wheel mouse.
Author: Pman (Parvez Akkas)

Information and Example: http://www.pmanslab.com/projects/gmwControl/.

ClusterMarker

ClusterMarker detects any group(s) of two or more markers whose icons visually intersect when displayed. Each group of intersecting markers is then replaced with a single cluster marker. The cluster marker, when clicked, simply centres and zooms the map in on the markers whose icons previously intersected.
Author: Martin Pearman

Information and Example: googlemapsapi.110mb.com/clustermarker/.

Bearings and Directions

Not actually an extension, but a collection of useful functions
Distance between two points (using Haversine formula).
Distance between two points (using Vincenty formula).
Bearing of one point from another.
Midpoint between two points.
Destination point given distance and bearing from start point.
Rhumb lines
Convert between degrees-minutes-seconds and decimal degrees
Convert between UK Ordnance Survey grid reference and lat/long.

Author: Chris Veness

Information and code: http://www.movable-type.co.uk/scripts/latlong.html.
and http://www.movable-type.co.uk/scripts/latlong-vincenty.html.
and http://www.movable-type.co.uk/scripts/latlong-gridref.html.
GeoKit

Geokit is a Rails plugin for building location-based apps. It provides geocoding, location finders, and distance calculation in one cohesive package. If you have any tables with latitude/longitude columns in your database, or if you every wanted to easily query for “all the stores within a 50 mile radius,” then GeoKit is for you.
Authors: Bill Eisenhauer and Andre Lewis

Information and Examples: geokit.rubyforge.org.

USNaviguide_Google_Tiles

A Perl module that calculates just about everything you’d want to know about tiles including:
Tile name for a coordinate (lat,lng)
Tile name for a pixel location (x,y)
Tiles for a bounding box of coordinates and zoom
Bounding box for a tile in coordinates
Bounding box for a tile in pixel locations
Coordinates to pixel
Pixel to coordinates
Author: John D. Coryat
Information and Code: http://www.usnaviguide.com/google-tiles.htm.

jMaps

jQuery plugin that provides several useful functions that make working with Google maps easier.
Author: Tane Piper

Code: hg.digitalspaghetti.me.uk/jmaps/.

Documentation: hg.digitalspaghetti.me.uk/jmaps/raw-file/271365e77c35/docs/index.html.

Parallel Lines

Creates parallel polylines.
Author: Bill Chadwick

Code: wheresthepath.googlepages.com/BDCCParallelLines.js.

Example: wheresthepath.googlepages.com/ParallelLines.htm.

MStatusControl

displays map centre, SW and NW corners, zoom level and mouse position (tile numbers, (x,y) position and lat/lon)
Author: Marcelo Montagna

Source and Example: maps.forum.nu/gm_MStatusControl.html.

MapIconMaker

Easily create dynamically sized and coloured icons.
The icon images are generated dynamically using a secret feature of the Google Chart API.

There’s a Wizard to help you choose the settings, and a Blog article with details and examples.

(The URL of the Wizard changes from time to time. If the wizard link fails, use the blog link and go from there.)

As well as generating the image, IconFactory also produces correct shadows, click targets, and printImages.

Author: Pamela Fox

Source and Examples: gmaps-utility-library.googlecode.com/svn/trunk/mapiconmaker/

Hint: LabeledMarker works well alongside MapIconMaker, like this (now probably obsolete, because MapIconMaker v1.1 includes createLabeledMarkerIcon)

MarkerTracker

Display directional indicators for markers as they move out of a maps view.
There’s a Blog article with details and examples.

Author: Dan Rummel

Source and Examples: gmaps-utility-library.googlecode.com/svn/trunk/markertracker/

GReverseGeocoder

Given latitude and longitude coordinates, the reverse geocoder obtains the nearest address
Author: Nico Goeminne

Information: nicogoeminne.googlepages.com/documentation.html

ourarea

Allows you to easily create an embeddable Google Map showing the area around your business that you deliver to or support.
Author: Nirmal Patel

Website: http://www.nirmalpatel.com/ourarea/

EShapes

The EShapes extension provides a number of additional static methods for GPolyline and GPolygon for creating certain shapes. It also provides two functions that can help in the placement of such shapes.
Author: Mike Williams

Information: my tutorial

Example Page: my example

Frame Animation Overlay

Author: “bratliff”
Useful for animated overlays, like moving weather radar images.

Please make your own copy because the one on this page may change.

Code: http://www.polyarc.us/frameanimation.js

Example Page: http://www.polyarc.us/ridge

MControl Suite

A bunch of custom controls.
MMapTypeControl
MOpacityControl – With a separate slider foreach tile layer
MZoomControl – Allows for predefined zoom levels
MStatusControl – Displays map status and mouse position info
MTileNumberControl – Displays tile numbers over the map
Author: Marcelo Montagna
Information and example: maps.forum.nu/gm_custom_controls.html

cSnapToRoute

Snap a marker to the closest point in a polyline
Author: Bill Chadwick

Information and example: wheresthepath.googlepages.com/cSnapToRouteDemo.html

ProgressbarControl

Progress Bar Control
Author: Björn Brala

Information and example: gmaps-utility-library.googlecode.com/svn/trunk/progressbarcontrol/

NASA Maps

Extra map types for the Moon and Mars, including polar maps.
Author: NASA

Info: ti.arc.nasa.gov/projects/planetary/maps.php

As supplied, the polar map projections don’t support polylines or polygons.

If you want to draw polylines, then you can use this version of the code: nasamaps2.js which uses a nasty hack to work round the bug in the API. If you’re not using polylines, then use the NASA version of the code, because i’t likely to be faster and to be kept up to date with new imagery.

Here’s an example of a NASA Polar map with polylines.

Geometry Controls

Edit content just like with My Maps.
Author: Chris Marx and Pamela Fox and others

Example: gmaps-utility-library-dev.googlecode.com/svn/trunk/geometrycontrols/examples/test.html

Info: gmaps-utility-library-dev.googlecode.com/svn/trunk/geometrycontrols/docs/reference.html

Code: gmaps-utility-library-dev.googlecode.com/svn/trunk/geometrycontrols/

CSGeoXml

A modified version of EGeoXml that acts like a single overlay.
Author: Matt Bernier

Information: devblog.cloudsync.com/projects/csgeoxml/

Intellisense Helper

Intellisense helper for VS2008.
Author: Nicolas Boonaert & Roger Chapman

Information: http://www.codeplex.com/GMapJS

ClusterManager

ClusterManager detects any groups of two or more markers whose icons visually intersect when displayed. Each group of intersecting markers is then replaced with a single cluster marker. The cluster marker, when clicked, provides an info window that gives access to the original markers.
Author: Peter van der Zee

Information and Example: cm.qfox.nl.

Popup Title

Displays a popup mini bubble for marker mouseover titles.
Author: Masashi Katsumata

Information and Example: googlemaps.googlermania.com/gmapkit/example/GMarkerPopupTitle.html.

Dragzoom

Dragzoom is a custom Google Maps control which allows you to zoom by dragging a rectangle on the map.
Author: Andre Lewis

Information and examples: gmaps-utility-library.googlecode.com/svn/trunk/dragzoom/

ExtLargeMapControl

A custom Large Map COntrol that uses the new graphics, as seen on maps.google.com.
Author: Bjorn Brala

Information and examples: gmaps-utility-library.googlecode.com/svn/trunk/extlargemapcontrol/.

ExtMapTypeControl

ExtMapTypeControl lets you add a control to the map which looks like the typical GMapTypeControl from the obfuscated API. By specifying additional options however, you can also add a Traffic button to the control and a drop-down legend for that button. Author: Pamela Fox and others
Information and examples: gmaps-utility-library.googlecode.com/svn/trunk/extmaptypecontrol/.

SnapToRoute

SnapToRoute will snap a marker to closest point on a polyline.
Author: Bjorn Brala

Information and examples: gmaps-utility-library.googlecode.com/svn/trunk/snaptoroute/.

MultiIconMarker

An alternative for GMarker that allows the associated GIcon to be changed (not just the icon image) when an event occurs.
Hint: by using your own custom events you can achieve the equivalent of a .setIcon() method.

Author: Masashi Katsumata

Information and examples: gmaps-utility-library-dev.googlecode.com/svn/trunk/multiiconmarker/.

MyMapExplorer

Allows you to embed a map created using Gooogle Maps’ My Maps feature into any web page with more information and flexibility than Google’s iFrame embed code.
Author: John Beales

Information and examples: code.google.com/p/mymapexplorer.

Custom Marker Maker

Upload an image (png, gif, jpg) and this page creates the 6 separate image files (image, shadow, printImage, mozPrintImage, printShadow and transparent) that make up a custom marker icon and suggests an array of x,y pixel coordinates that define the image map area used for capturing image clicks in non IE browsers. Transparency of the original image is preserved. Users see their image as a marker on a map and are presented with a zipped package for download that contain the generated images and some sample code.
Author: Graham

URL: http://www.powerhut.co.uk/googlemaps/custom_markers.php.

Custom Maps

Google Maps API Tutorial

Browser Connection Limits

Inspiration

This page was inspired by the fact that Google seem to have imposed timeouts on the tile fetches. That’s fine for Google tiles that are provided by fast servers, but if you have a slow server, it looks like the API doesn’t always wait long enough before giving up and deciding that the fetch has failed.

I noticed that fetching an individual tile from a page that exhibits the problem wasn’t much any longer than fetching an individual Google tile. The significant difference was that the Google map types were fetching more tiles at once, so the total time taken to fetch all the tiles was significantly shorter. Google achieve this effect by using aliases to break the browser connection limits.

What are Browser Connection Limits?

Although browsers are capable of fetching many files simultaneously, only two files will be fetched simultaneously from the same domain. This limit made some sense back in the days when the majority of Internet users had slow dial-up connections, but it makes no sense with today’s high speed connections. For most pages, the continuing existence of these limits doesn’t slow the page loading down to make it worthwhile for the limits to be redesigned, but they do have a significant effect on map tile fetches.

So what can we do?

What Google do is have four different subdomains mt0.google.com, mt1.google.com, mt2.google.com, mt3.google.com, and share the tile fetching between them. The browser doesn’t know that these are all aliases for the same machine, and allows two simultaneous fetches to each subdomain. So eight tiles get fetched at the same time, instead of two.

Here’s an example where I spread the load across four subdomains of econym.org.uk.

The code looks like this

      CustomGetTileUrl=function(a,b){
        var subdomain=(a.x+a.y)%4;
        return "http://sub" +subdomain+ ".econym.org.uk/gmap/tiles/"+a.x+"_"+a.y+"_"+(17-b)+".jpg"
      }

The rest of the code is the same as that used in custommap1.htm.

I created “sub0.econym.org.uk” etc., as subdomanins that have the same destination (or “Document root”) as “econym.org.uk”, so there actually is only one set of tiles on the webserver, but the browser has no way of knowing that.

How much faster is it?

In those examples, you may not notice much speed difference visually, but when the pages are analysed with PageTest, the old one typically loads in 4.5 seconds and the new one in 3.4 seconds.

Even then, that doesn’t seem like a huge improvement, but if you compare the timings from the start of the first tile request to the completion of the last tile request, those times have gone down from 2.9 seconds to 1.4 seconds. If you have a slow server, the differences would be expected to be more significant.

The timings

I don’t know how long PageTest keeps the timing results, but for now you can see one set of results for the custommap1 at pagetest.patrickmeenan.com:8080/result/RC8/1/details/ and for custommap1p atpagetest.patrickmeenan.com:8080/result/RC7/1/details/

Custom Maps

Google Maps API Tutorial

Alternative Map Type Controls

New formats for the map type controls were introduced in v2.93 and v2.94. These new formats can be useful in situations where you have a large number of custom map types, causing the normal GMapTypeControl to become cumbersome.

The GMenuMapTypeControl() displays all the map types in a drop-down menu.
If the optional first parameter is true, then shortnames are used.
If the optional second parameter is true, then a border is drawn round the control.

The GHeirarchicalMapTypeControl() lists “child” map types below their “parent” map type if that parent is active.
If the optional parameter is true, then shortnames are used.

GHeirarchicalMapTypeControl() has three Methods for managing parent and child map type relationships:

GHierarchicalMapTypeControl.addRelationship(parent, child, name, isDefault) adds a parent/child map type relationship. The parameters are

        1.  parent GMapType
        2.  child GMapType
        3.  (optional) Name for child
        4.  (optional) isDefault boolean

GHierarchicalMapTypeControl.removeRelationship(child) removes a parent/child map type relationship. The parameter is the child GMapType.

GHierarchicalMapTypeControl.clearRelationships() removes all relationships.

Here’s an example of a map with seven map types showing all possible map type controls. Click the buttons to display the different controls.

Here’s an example that sets the map type controls to look exactly like the v2.94 maps.google.com controls. The Terrain map type is added. Hybrid is underneath Satellite and is selected by default when the Sattelite button is clicked.

Custom Maps

Google Maps API Tutorial

Using Google Maps API for Flat Maps and Diagrams

You might think that we can use the techniques in the previous examples to get the Google Map API to manage views of things that are not spherical maps, such as flat maps, diagrams and circuit boards. That would be fine as long as we don’t want to draw markers or polylines on it.

Once we start drawing lines, we encounter the fact that all the maps we’ve looked at so far use the Mercator projection, which distorts the mapping geometry in order to represent a spherical Earth on a flat map.

The line on the “Mercator” map type in this example is a “straight” line that gets distorted into a curve due to the Mercator projection. You can imagine that such a distortion wouldn’t be much use for dealing with things like circuit diagrams.

The “Euclidean” map type in the same example Note I don’t move or redraw the markers or the polyline. When the map type changes, the API redraws all the overlays using the new projection.

Copyright strings

The GTileLayer.getCopyright() method must return an Object that has the following properties

prefix String to be placed at the front of the copyright text, like “Map Data:” or “Satellite Imagery:”
copyrightTexts Array of strings: Copyright texts that apply to various parts of the area.

The constructor and methods of the object class are not exposed, so it’s not possible to construct the return value properly, but it is possible to return an anonymous object literal.

E.g., in the example, I’ve used

     tilelayers[0].getCopyright = function(a,b) {
        return {prefix:"Fractal: ©", copyrightTexts:["Mike Williams"]};
     }

Potential Pitfalls

  1. The GScaleControl() and point.distanceFrom() features assume spherical geometry, so they’re not going to be useful for non-Mercator maps.
  2. The API calculates the polyline geometry at zoom level 17. This means that any GProjection used in a map that has polylines must be created with at least 18 zoom levels, even if the map itself has far fewer zoom levels.

Custom Maps

Google Maps API Tutorial

Custom Map Types

To create a custom map, you first need to create a set of 256*256 tiles, or obtain a set for which you have the relevant permissions. Or, alternatively, write your own tileserver code that runs on your server and can create the tile images on the fly.

A Simple Custom Map

To use these tiles as a simple Custom Map Type, you need to do following:

  • Create a GCopyright object
  • Create a GCopyrightCollection
  • Add the GCopyright to the GCopyrightCollection
  • Create a GTileLayer object
  • Create a GMapType object
  • Add the GMapType to the map

These steps are well described in The Mapki so I’ll not repeat that information here.

Here’s an example.

The only significant difference between this example and the Makpki information is that my tiles are stored as images in my web folder, rather than being generated by a tileserver script.

Aligning your map

There’s a very nice facility at open.atlas.free.fr/GMapsTransparenciesImgOver.php which can be used to align a map image in the correct place on top of a Google map.

It specifies the preprocessing (scaling and padding) that should be performed on your image before using something like the Automatic Tile Cutter mapki.com/wiki/Automatic_Tile_Cutter to cut your image into tiles.

Bounds checks

One problem with the previous example is that it causes the API to perform standard error tile handling when the user drags the map out of the custom region. This is a bit ugly and slow.

So what we can do is to add a check in the CustomGetTileUrl() code to see if the tile is in the custom region, and if not return a special “blank.jpg” tile.

Here’s an example.

It would have been nice to have been able to store the information about the custom region tiles in a series of GBounds() objects (one for each supported zoom level) and test to see if the GPoint() representing the tile number is inside the GBounds(), but there is no GBounds.contains(point) method.

Bounds Checks 2

Instead of returning a blank tile for tiles that are outside the custom region, you could return the URL of a tile from G_NORMAL_MAP or G_SATELLITE_MAP.

The problem with this is that you should then display the Google copyright string whenever a Google tile is visible. This turns out to be extremely tricky to get right.

In this example, I display the custom copyright string whenever a custom tile is visible and the Google copyright string whenever no custom tiles are visible.

If you know a better way of handling the copyright, please let me know atlas@econym.demon.co.uk

Common CustomGetTileUrl formats

This code returns URLs in the format created by the Photoshop tile splitter: “http://mydomain.com/tiles/5295_5922_3.jpg&#8221;

      CustomGetTileUrl=function(a,b){
          return "http://mydomain.com/tiles/"+a.x+"_"+a.y+"_"+(17-b)+".jpg";
      }

This code returns URLs in the format created by the Paint Shop Pro tile splitter: “http://mydomain.com/tiles/14_5922x5295.jpg&#8221;

      CustomGetTileUrl=function(a,b){
          return "http://mydomain.com/tiles/"+b+"_"+a.y+x+a.x+".jpg";
      }

This code returns URLs in the format used by the Google Normal Map tileserver: “http://mydomain.com/tileserver.php?x=5295&y=5922&zoom=3&#8221;

      function CustomGetTileUrl(a,b) {
        var z = 17 - b;
        var f = "http://mydomain.com/tileserver.php?x="+a.x+"&y="+a.y+"&zoom="+z;
        return f;
      }

Potential Pitfalls

  1. Some API features, such as polylines and ground overlays, perform their calculations at zoom level 17, rather than at the max zoom level of the map type. These features will fail if the GProjection() of the map type ahs less than 18 zoom levels.

More advanced stuff

Google Maps API Tutorial

UK Posctcodes

The Problem

Since I wrote this page, The Problem seems to have gone away making this page unnecessary

Unlike other countries, the geographical information associated with UK postcodes is strictly controlled. The copyright is owned by the Royal Mail, who make a lot of money selling licences to use it.

For example, I just bought a new TV. The guy at the shop didn’t ask for my address, but just asked for my postcode and house number, and used that to find my full street address. The shop presumably finds it worthwhile fo pay the annual £85 licence per workstation, or the annual £75,000 corporate licence for all the workstations operated by that chain of stores, or one of the intermediate licences. Since large numbers of UK high street shops do the same thing, that adds up to an awful lot of money that the Royal Mail receive from licensing that data. Therefore they’re not keen to allow Google to give the information away for free via the API geocoder.

The Royal Mail have allowed Google to buy a licence to use the data on its own websites, but not to redistribute the data to other people.

This results in it being possible to find the exact location of “FY2 0HH, UK” at maps.google.com, but if you try the same search with the API geocoder you get a point that’s nearly a mile away.

What actually happens

The API geocoding database contains the locations of places like “FY2 0” and “FY2 9”. I.e. the “outcode” part of the postcode plus the numeric part of the “incode”.

When you reverse geocode a point, it gives the correct one of those locations as the Locality.PostalCode.PostalCodeNumber

When you forward geocode a UK postcode, the geocoder is only allowed to look at the “outcode” part. It then returns an arbitrary one of the “FY2 ?” locations, not necessarily the correct one. Which one of those locations actually gets returned is influenced ny things like country bias. There is a suggestion that it might even be biassed by the location of the user who is calling your page.

Workrounds

Use the full address

You could always ask your user to input their full address. That generally works.

The terms of the licence require the geocoder to discard the “incode” part of the postcode, and effectively performs a search for [street address] near [outcode]. In some extreme cases, even that won’t work. An example near where I live is “10 Bispham Road FY6 7PE, UK”. There are three “Bispham Road”s that are near FY6. One at “FY3 7HJ”. One at “FY5 1DG” and the one that I asked for at “FY6 7PE”. The API geocoder returns all three, but the one I asked for is the second placemark.

Use a non-google geocoding service

I don’t know of any commercial on-line services, but I’m sure there are some.

Buy the data from the Royal Mail

Put it on your server and perform your own lookups. I reckon that you need to pay the annuall £3,850 fee for a System Licence to do that.

Use the Google Local Search API

I’ve no idea how the licensing of this works, but calls to the Google Local Search API do correctly geocode full UK postcodes.

A Google spokesman did once say that this might not always be the case, so if you do use this strategy don’t be surprised if it suddenly stops working.

It’s not a good idea to use Google Local Search as a general purpose geocoder. It’s slower than the API geocoder and can sometimes get confused between placenames and business names. So if there’s a possibility that your search string might not be a UK postcode, it’s a good idea to test it first, see below.

Use GDirections

I’ve no idea how the licensing of this works, but calls to GDirections do correctly geocode full UK postcodes. The locations are slightly different from the maps.google.com locations, since they will have been snapped to the nearest street.

The strategy is to request a route from the postcode to itself, like “from: FY2 0HH to: FY2 0HH”, wait for the reply, then use .getPolyline().getVertex(0) to obtain the location.

If you do use this strategy don’t be surprised if it suddenly stops working.

It’s not a good idea to use GDirections as a general purpose geocoder. It’s slower than the API geocoder, has a lower daily quota, and can only handle one request at a time. So if there’s a possibility that your search string might not be a UK postcode, it’s a good idea to test it first, see below.

There’s also considerable doubt about whether this strategy is legal. Read section 10.12 of the Terms for yourself before implementing this strategy.

Testing if a string is a UK postcode

To test if a string looks like a UK post code you can use this regexp
^[A-Z]{1,2}[0-9R][0-9A-Z]? [0-9][ABD-HJLNP-UW-Z]{2}$.

That expession assumes that the string is in upper case, has exactly one space between outcode and incode, has no leading or trailing whitespace and no punctuation. That’s a bit more severe than we need, since GDirections and Google Local Search will accept any case and any punctuation and whitespace, so you might want to tidy it up first before performing the test.

That expression should be sufficient to distinguish a full UK postcode from anything else, but if you want to be more exact, there’s a long form in the Wikipedia. Don’t use the very long expression from the Wikipedia article that includes BFPO postcodes, because BFPO postcodes don’t represent fixed geographical locations, but groups of British Overseas Forces which may well be mobile.

Example

Here’s an example that tests whether a search string is a UK postcode, and if so uses the GDirections trick rather than the GClientGeocoder to find the location.

More advanced stuff

Google Maps API Tutorial

Altitude

Google themselves don’t serve altitude information, so if you want to obtain the altitude, you’ll need to get it from somewhere else.

Here’s a simple example

One place where you can get altitude information is the US Geological Survey Elevation Query. Information about their service can be found here:
gisdata.usgs.gov/XMLWebServices/TNM_Elevation_Service.php

A request looks like this:
http://gisdata.usgs.gov/xmlwebservices2/elevation_service.asmx/getElevation?X_Value=-118.4&Y_Value=36.7&Elevation_Units=METERS&Source_Layer=-1&Elevation_Only=true.

The parameters are:

X_Value Longitude
Y_Value Latitude
Elevation_Units METERS or FEET.
Source_layer You can use this to request data from a specific survey, or use -1 to request the best available data at the location.
Elevation_Only true or false. If you set it false you get information about the data source as well as the elevation data.

The service provides a SOAP interface that returns XML, so you can’t access it directly from Javascript for security reasons. What you have to do is to write a little server script that runs in your own domain. Your Javascript can send a request to your own server, which then sends the request to USGS and returns the reply back to your Javascript client.

I’m not a PHP expert, but I managed to throw together something that works for this purpose. A general purpose relay script would need to be more complicated than this, to avoid the possibility of cross-domain attacks, but I think I can trust the USGS. My PHP code looks like this and returns the data like this:altitude.php?lat=53&lng=-2.

There are two asynchronous steps in this chain, so don’t expect to be able to write a function that returns the altitude of a point. Send the request with GDownloadUrl() and then process the reply in the callback funtion. If you’re sending several requests (e.g. to obtain the profile of a cycle route) you can wrap your call in a function and use it to hold Function Closure so that you can match the replies back to the requests.

The service will return up to 10 decimal places of information, but I suspect that the surveys aren’t accurate to 0.1 nanometres. In my code I just use the integer value.

The service returns the value 0 for open sea. You could therefore use it to distinguish land from sea, but there are a few other points on land where the elevation is also zero, e.g. Elburg in the Netherlands.

The documentation states that the service can return the value -1.79769313486231E+308 if there is no valid data for the requested location, so you might want to filter out such values if you’re drawing an elevation diagram.

In this example I use GDirections to find a route, use the EPoly extension to obtain points at equal distances along that route, use USGS to find the altitude at those points, and use the Google Chart API to plot a chart of those altitudes.

More advanced stuff

Google Maps API Tutorial

GLayers

API v2.130 introduces GLayers, which can be used for displaying the Wikipedia and Panoramio layers to your map.

Google themselves don’t (yet) supply a control for allowing users to switch layers on and off, so I wrote this example

IDs and LMCs

The documented way to specify a particular layer is by using its ID. The official list of IDs is atspreadsheets.google.com/pub?key=p9pdwsai2hDN-cAocTLhnag

In addition to the official list, there are also “com.panoramio.popular”, which omits the Panoramio elements that have the small icons, and there’s “com.youtube.all” which displays the YouTube layer, and there are a few other Wikipedia languages. I don’t intend to test all possible Wikipedia languages: If your favourite language is supported by Wikipedia but isn’t in the official GLayers list, try it anyway.

There’s also an undocumented way to specify a particular layer, by using its LMC. E.g.map.addOverlay(new GLayer(“lmc:panoramio/0”)) is the same as map.addOverlay(new GLayer(“com.panoramio.popular”)).

You can only use IDs that the particular release of the main API code knows about, because the main API code needs to know how to translate the ID into an LMC. In v2.130, the known IDs are “com.panoramio.all”, “com.panoramio.popular” and “org.wikipedia.*”.

When you use an LMC, the main API code doesn’t need to translate it for you, so you can use any LMC for which there is a service.

At the moment, the only LMC that I know about that has service but no ID is “lmc:panoramio/1”, which displays the unpopular Panoramio entries and omits the popular ones.

Viewing the source of maps.google.com reveals the existence of “lmc:youtube”, but the API has no service for it at the moment.

hide() and show()

GLayers support .hide(), .show() and .isHidden().

GLayers don’t support .supportsHide().