LabeledMarker v1.0: Do More with Your Markers!

Friday, April 27, 2007 at 1:24:00 PM

I'll admit it -- I sometimes get tired of staring at a map full of reddish-pink markers, and find myself too lazy to click on the markers to find out what information they represent. I'm inclined to believe I'm not the only lazy user out there. That's why I think it's important for map mashup designers to put some effort into creating their map's markers to convey more than just simply "there is a data point here," when possible.

There are several techniques for conveying additional information: colored markers, markers with symbols (like a bike or eating utensils), or markers of varying sizes. There's also the possibility of overlaying letters or numbers on top of your marker to associate it with a rank or code. In the past, users have typically had to create those kinds of markers individually (in Photoshop, for example), increasing the map development time as well as the download time for the maps user.

Mike Purvis, a Maps API developer and co-author of "Beginning Google Maps Applications with PHP and Ajax", realized there was a need for an easy way to overlay text on markers a few months ago, and introduced his LabeledMarker extension that does just that. Since then, he's added it to the Google Maps API Utility Library open source project, and together we've put together documentation and examples to show it off. With just one line of code, you can create a LabeledMarker with a custom icon and any text overlaid on top:

  var marker = new LabeledMarker(myPoint, {icon: myIcon, labelText: "A"});

Since LabeledMarker is an extension of GMarker, you can use many of the GMarker options and methods with it, like adding a click listener or changing the icon image dynamically. Below is a map based on an example from the documentation, where I've used LabeledMarker to show a map of the top 20 airports in the world and used their airport codes as the marker label.

If you think that LabeledMarker will be useful for your next maps project, check out the examples and browse the reference. Please report any issues you find in the Maps API Google Group, and consider joining the open-source project if you'd like to work on extending LabeledMarker further.

Google Developer Day on May 31

Tuesday, April 24, 2007 at 4:29:00 PM

As a reminder, we'd love to see lots of Maps API developers at the Google Developer Day on May 31, so be sure to sign up soon. This is a great opportunity to mingle with other developers, meet the Google Maps engineers, request features, throw food at us, etc. Last year's event was a lot of fun.

This year's Developer Day will be a global event with sessions in:

We look forward to meeting you on May 31. The event is free of charge.

http://www.google.com/events/developerday/index.html

Introducing 3 Maps API/KML Tutorials in Google Code's Knowledge Base

Friday, April 20, 2007 at 3:25:00 PM

We've just rolled out an exciting new addition to the Google Code Knowledge Base: Articles & Tutorials. Here's a summary of 3 Maps-related articles. Give these articles a read, and learn something new this weekend!

Creating a Simple Digitizer Using the Google Maps API

Have you seen Google's "My Maps" feature, which has the fun feature of letting you click to create lines and shapes? You may be surprised to find out how easy it is to create a similar tool using the Google Maps API. This article describes how to build a simple digitizer that allows users to point and click, or "draw", around a particular region and store the geographical coordinates in KML.

Click here to read!


Using PHP/MySQL with Google Maps

Are you a developer accustomed to developing mySQL-driven websites with PHP? Do you want to learn how to use Google Maps with your database using "AJAX" techniques? This article goes through the steps of creating a mySQL table, populating the table with data, using PHP to generate XML from that mySQL table, and finally, writing the HTML/Javascript webpage to dynamically load in the PHP-generated XML and display a map with multiple markers and custom icons. After going through this tutorial, you should be ready to extend what you've learned to your own databases.

Click here to read!


Adding Metadata to Your KML Files

Update: This article was removed as Metadata was deprecated in KML 2.2.Read our Developer Guide for information about using ExtendedData.

Keyhole Markup Language, or KML, is a simple but powerful file format for displaying geographic data in an earth browser, such as Google Earth or Google Maps. Increasingly, people are starting to use it in their own applications to represent geographic data. Exchanging data between applications, however, can sometimes be a challenge. This article describes how with KML 2.1 the new element <Metadata> allows you to include structured data in your KML

Click here to read!

v2.78: Go ahead, Scroll your mouse wheels & encode your polygons!

Tuesday, April 17, 2007 at 7:25:00 PM



The latest version of the API exposes two features that have often been requested (or reverse engineered) by API developers: the ability to enable the mouse wheel zoom used on maps.google.com, and the ability to create GPolygons from encoded points.

To get started using the new features, read through the examples and explanations below.


1) Scroll wheel zoom:

The API gives you these 2 new GMap2 methods: enableScrollWheelZoom, disableScrollWheelZoom. These functions let you turn scroll wheel zoom on or off.

If you'd just like to modify your current map mashups to enable this user-friendly zoom, add the following line of code anywhere after you've created your map.

map.enableScrollWheelZoom();

You should see results like the example below. For the complete code to this map, view the source on this link.

Note: You'll notice the webpage scrolls along with the map. This is expected behavior, as the scroll wheel zoom is optimized for the screen-filling map on maps.google.com. Many maps site use a similar design, but if you do have a long webpage with an embedded map, you can write some extra javascript to get better behavior (here's one developer's suggestion).

If you'd like to let your users choose whether to enable the mouse wheel zoom, or you'd like to see how to disable it at certain times, check out the toggling example below, and view source on this link to see how it's done.



2) Encoded GPolygons

In 2.63, we introduced GPolyline.fromEncoded(), a factory method that lets you create a polyline based on encoded points and levels. This technique is useful for developers using long and complicated lines, as the encoding algorithm both saves storage space and lets you specify which points are displayed at each zoom level.

When GPolygon was announced in version 2.69, developers immediately asked if a GPolygon.fromEncoded method was also available so they could use the same effficient technique. Well, the engineers heard their call and have exposed GPolygon.fromEncoded() in the API.

This new factory method lets you create a polygon based on a set of encoded polylines, and specify the fill/stroke for the resultant polygon(s). The example below shows Texas and a (fictional) island near it, created using the GPolygon.fromEncoded method with 2 encoded polylines.

The Texas polyline encoding comes from this example from Mark McClure, a Mathematics professor/API hobbyist who's done extensive work with the polyline encoding scheme. Check out his useful page that has more information and examples of polyline encoding, including a utility to automatically encode a set of latitude/longitude points using an extended Douglas-Peucker algorithm.

You can also reference the API documentation's encoded polylines example, and related polyline encoding utility for more help.

Note: Remember that you'll need to specify v=2.x in your script tag to use the new functions for the next few weeks, since they're new features. More information on API script versioning is here.



API v2 Latest (v=2.x): 2.78
API v2 Default (v=2): 2.77

A Marker-Managed Easter Egg Hunt

Sunday, April 08, 2007 at 3:00:00 AM

A few weeks ago, we announced the open source version of MarkerManager, the class used to manage visibility of hundreds of markers on a map, based on the map's current viewport and zoom level. The open-source version has additional functions to delete or clear markers, making it possible to use MarkerManager for a wider variety of applications. In case some of you were wondering how that extra functionality can be useful, I've created a marker-managed easter egg hunt game to show it off.

Try it out below - just press "Start New Game," then click eggs to add them to your basket until you run out of time. Most of the eggs are good (mmm... chocolate filled), but there are some evil (rotten!) eggs in there. As you zoom in, the eggs will be bigger and easier to find, and it will become more obvious which of the eggs are evil and should be avoided.

How does it work?

  • First I create a MarkerManager with a maxZoom of 19, as I want to make sure that it tracks markers up to my map's highest zoom level (19).
  • When the user starts their first game, I generate 45 random points. For each point, I create 3 markers, each with an increasingly larger GIcon. I add the 3 markers to 3 arrays, representing the 3 zoom levels that display eggs in the hunt. When I'm done creating the marker arrays, I add each array to the MarkerManager using the addMarkers function, each with an increasingly higher zoom level (17-19) for the maxZoom and minZoom options.
  • When the user clicks on a marker, I use the MarkerManager's removeMarker function to delete the marker at all 3 zoom levels. Back when I created the marker, I extended it to remember it's array index, and because of the way I populated the 3 arrays, the "sister" eggs have the same index in each array. That means it's a simple for loop to delete them at each zoom level.
  • If the user wants to play again, I call the MarkerManager's clearMarkers function and also clear the 3 arrays I was using to keep references to the markers. Then the egg hiding cycle begins again!

There are also a few extra bits in the code to differentiate between good and bad eggs, timing, and score output. Click here if you'd like to check out the source yourself.

If you're a developer and you're interested in extending MarkerManager or otherwise contributing to our open source library, read the project's FAQ for information on how to join.

GMarker.show: American for 'clock'

Thursday, April 05, 2007 at 1:07:00 PM



When we released the setImage method for GMarker a few weeks ago, we showed you how it could be used to overlay an animated clock on top of a map. Well, honestly, I've never been that good at reading the time from an analog clock, so I decided to take advantage of the new GMarker show/hide methods to create this digital clock:

Just to remind you that it's easy to mash up the Google Maps API with Google Gadgets, I made a smaller gadget version that you can add to your personalized homepage or website, and then customize the map's latitude/longitude and zoom. I chose to position my clock over Victoria Falls, Africa (in the hope it'll increase my chances of visiting there one day!), but you may have your own background preference.

How does the clock work? Each clock digit is made up of the seven segments typical of LED clocks, and each of these segments is actually a marker that I toggle with show/hide. If you really want to dive into the code (and perhaps customize it to display messages or countdowns), view source on the clock and read the code breakdown below.

Storing the clock data:
  • The markers associative array is used to keep track of the markers. For example, "hour_10" refers to the array for all the markers representing the tens place of the hour. The arrays begin empty and are populated later.
  • clock diagram The numberLayouts associative array is used to indicate which segments should be on/off in order to represent a particular digit. In the array, true indicates a segment should be on and false indicates the opposite, and the array index for each segment is dictated by the diagram shown here. Because of the way it's setup, it'd be simple to extend this alarm clock to non-number output as well.
  • The numberWidth, numberHeight, and colonWidth variables are used in positioning the marker segments with the correct spacing.
Setting up the clock:
  • First the map is initialized and 3 custom icons are declared (for the colon, horizontal segment, and vertical segment). Then addSegmentMarkers is called 6 times (hours*2,minutes*2,seconds*2) and addColonMarker is called twice, each time with an appropriate offset so that digits aren't overlapping.
  • In the addSegmentMarkers function, a pixel location is calculated for each 7 segments based on a startPixel, and the global sizing variables. The API-provided fromPixelToLatLng is used to calculate a GLatLng based on the resultant pixel location, and a marker is created at that point and added to the relevant array in markers. The segments are added so that their array indices correspond with the numberLayouts array.
  • The addColonMarker function is similar to addSegmentMarkers, but only calculates one marker position.
Animating the clock:
  • After setup, it calls javascript's setInterval on clockTick with 1000 as the speed, so that the clock will update each second.
  • The clockTick function calculates the time (local to the user) with javascript's Date function. It then calls toggleSegments for each of the digits.
  • The toggleSegments function iterates through the markers in the array for that digit place, and compares the return value of isHidden() to the boolean in the numberLayouts array. If it's hidden and needs to be shown, it calls show() on the marker. If it's shown and needs to be hidden, it calls hide() on the marker.

Search for KML in Google Maps

at 10:39:00 AM

I am happy to announce that you can now search through all of the world's Keyhole Markup Language (KML) files on Google Maps. This enables you to find all the great user-created map content on the web, as well as new maps created with My Maps, which launched today.

You will continue to see local search results with the red pushpins, but now there is a link called "See user-created content" that will enable you to see relevant user-generated results, represented by blue pushpins. Go to maps.google.com and give it a try with these search queries:

v2.77: GMarker show, hide, and isHidden = Quick & Easy Marker Toggling!

Wednesday, April 04, 2007 at 7:31:00 AM



The day has come - the API now has officially documented methods for showing and hiding markers, and querying their ("hidden-ness") state. Using a combination of GMarker.show(), GMarker.hide(), and GMarker.isHidden(), you can painlessly toggle the visibility of markers. Here's what the code looks like to toggle one marker:

if (marker.isHidden()) {
  marker.show();
 } else {
  marker.hide();
}

It's pretty easy to extend that code to create a map that has groups of markers that are toggled by checking boxes in a sidebar. Shown below is a map that loads in an XML file of my favorite restaurants and bars in Seattle, and creates 2 different "toggle-able" marker groups:

How's it done? There are a couple ways you could keep track of marker groups, but I chose to use an associative array that keys each marker type with an array of markers. The array declaration looks like:

var markerGroups = { "restaurant": [], "bar": []};

Then when parsing the XML, I use an attribute value of each marker node that's either "restaurant" or "bar" to push the marker into the appropriate array, like so:

var type = markers[i].getAttribute("type");
//...
markerGroups[type].push(marker);

The onclick event for the checkboxes trigger either toggleGroup('restaurant') or toggleGroup('bar'). In toggleGroup, I just iterate through the markers in that group's array, using the same code shown at the beginning of the post, like so:

    function toggleGroup(type) {
      for (var i = 0; i < markerGroups[type].length; i++) {
        var marker = markerGroups[type][i];
        if (marker.isHidden()) {
          marker.show();
        } else {
          marker.hide();
        }
      } 
    }

Now go forth and toggle! Remember that you'll need to specify v=2.x in your script tag to use the new functions for the next few weeks, since they're new features.

API v2 Latest (v=2.x): 2.77
API v2 Default (v=2): 2.76