google earth, google maps and your photos: a tutorial earth and... · this article is available in...

70
Google Earth, Google Maps and Your Photos: a Tutorial Rob Reed

Upload: buituong

Post on 30-Jan-2018

222 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

Google Earth, Google Maps and Your

Photos: a Tutorial

Rob Reed

Page 2: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

About Packt

Our books and publications share the experiences of your fellow IT professionals in

adapting and customizing today's systems, applications, and frameworks.

Packt is a modern, unique publishing company with a focus on producing cutting-edge

books for communities of developers, administrators, and newbies alike.

For more information, visit: www.PacktPub.com.

About The Author

Rob Reed has over 10 years experience in the IT industry. He has held positions as the

Director of Technology, IT Director, and Research and Development Technical Lead for

various firms. Currently, he is an independent consultant and is pursuing a graduate

degree in Computer Science at Tufts University (Medford, MA). His thesis work looks at

issues of semantic information management. He is also interested in the topics of

computing platforms, network and systems security, programming languages, and

development. He maintains a weblog at http://robreed.net/weblog. He can be reached at

[email protected].

Page 3: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

Google Earth, Google Maps and Your Photos: a Tutorial

Introduction

A scholar who never travels but stays at home is not worthy to be accounted a

scholar. From my youth on I had the ambition to travel, but could not afford to

wander over the three hundred counties of Korea, much less the whole world.

So, carrying out an ancient practise, I drew a geographical atlas. And while

gazing at it for long stretches at a time I feel as though I was carrying out my

ambition . . . Morning and evening while bending over my small study table, I

meditate on it and play with it and there in one vast panorama are the districts,

the prefectures and the four seas, and endless stretches of thousands of miles.

WON HAK-SAENG

Korean Student

Preface to his untitled manuscript atlas of China during the Ming Dynasty,

dated 1721.1

To say that maps are important is an understatement almost as big as the world itself.

Maps quite literally connect us to the world in which we all live, and by extension, they

link us to one another. The oldest preserved maps date back nearly 4500 years. In

addition to connecting us to our past, they chart much of human progress and expose the

relationships among people through time.

Unfortunately, as a work of humankind, maps share many of the same shortcomings of

all human endeavors. They are to some degree inaccurate and they reflect the bias of the

map maker. Advancements in technology help to address the former issue, and offer us

the opportunity to resist the latter. To the extent that it's possible for all of us to

participate in the map making, the bias of a select few becomes less meaningful.

Google Earth2 and Google Maps

3 are two applications that allow each of us to assert our

own place in the world and contribute our own unique perspective. I can think of no

better way to accomplish this than by combining maps and photography.

1 Source: Library of Congress Geography and Maps: An Illustrated Guide

2 Google Earth: http://earth.google.com/

3 Google Maps: http://maps.google.com/

Page 4: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

Photos reveal much about who we are, the places we have been, the people with whom

we have shared those experiences, and the significant events in our lives. Pinning our

photos to a map allows us to see them in their proper geographic context, a valuable way

to explore and share them with friends and family. Photos can reveal the true character of

a place, and afford others the opportunity to experience these destinations, perhaps

faraway and unreachable for some of us, from the perspective of someone who has

actually been there.

In this tutorial I'll show you how to 'pin' your photos using Google Earth and Google

Maps. Both applications are free and available for Windows, Mac OS X, and Linux. In

the case of Google Earth there are requirements associated with installing and running

what is a local application. Google Maps has its own requirements: primary among them

a compatible web browser (the highly regarded FireFox is recommended).

In Google Earth, your photos show up on the map within the application complete with

titles, descriptions, and other relevant information. You can choose to share your photos

with everyone, only people you know, or even reserve them strictly for yourself.

Google Maps offers the flexibility to present maps outside of a traditional application.

For example you can embed a map on a webpage pinpointing the location of one

particular photo, or mapping a collection of photos to present along with a photo gallery,

or even collecting all of your digital photos together on one dynamic map.

Over the course of a short couple of articles we'll cover everything you need to take

advantage of both applications. I've put together two scripts to help us accomplish that

goal. The first is a Perl script that works through your photos and generates a file in the

proper format with all of the data necessary to include those photos in Google Earth. The

second is a short bit of Javascript that works with the first file and builds a dynamic

Google Map of those same photos. Both scripts are available for you to download, after

which you are free to use them as is, or modify them to suit your own projects. I've

purposefully kept the code as simple as possible to make them accessible to the widest

audience, even those of you reading this who may be new to programming or unfamiliar

with Perl, Javascript or both. I've taken care to comment the code generously so that

everything is plainly obvious. I'm hopeful that you will be surprised at just how simple it

is.

There a couple of preliminary topics to examine briefly before we go any further.

In the preceding paragraph I mentioned that the result of the first of our two scripts is a

'file in the proper format...'. This file, or more to the point the file format, is a very

important part of the project. KML (Keyhole Markup Language) is a fairly simple XML-

based format that can be considered the native "language" of Google Earth. That

description begs the question, 'What is XML?'

To oversimplify, because even a cursory discussion of XML is outside of the scope of

this article, XML (Extensible Markup Language) is an open data format (in contrast to

Page 5: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

proprietary formats) which allows us to present information in such way that we

communicate not only the data itself, but also descriptive information about the data and

the relationships among elements of the data. One of the technical terms that applies is

'metalanguage', which approximately translates to mean a language that makes it possible

to describe other languages. If you're unfamiliar with the concept, it may be difficult to

grasp at first or it may not seem impressive. However, metalanguages, and specifically

XML, are an important innovation (I don't mean to suggest that it's a new concept. In fact

XML has roots that are quite old, relative to the brief history of computing). These

metalanguages make it possible for us to imbue data with meaning such that software can

make use of that data. Let's look at an example taken from the Wikipedia entry for KML4.

<?xml version="1.0" encoding="UTF-8"?>

<kml xmlns="http://earth.google.com/kml/2.0">

<Placemark>

<description>New York City</description>

<name>New York City</name>

<Point>

<coordinates>-74.006393,40.714172,0</coordinates>

</Point>

</Placemark>

</kml>

Ignore all of the pro forma stuff before and after the <Placemark> tags and you might be

able to guess what this bit of data represents. More importantly, a computer can be made

to understand what it represents in some sense. Without the tags and structure, "New

York City" is just a string, i.e. a sequence of characters. Considering the tags we can see

that we're dealing with a place, (a Placemark), and that "New York City" is the name of

this place (and in this example also its description). With all of this formal structure,

programs can be made to roughly understand the concept of a Placemark, which is a

useful thing for a mapping application.

Let's think about this for a moment. There are a very large number of recognizable places

on the planet, and a provably infinite number of strings. Given a block of text, how could

a computer be made to identify a place from, for example the scientific name of a

particular flower, or a person's name? It would be extremely difficult.

We could try to create a database of every recognizable place and have the program

check the database every time it encounters a string. That assumes it's possible to agree

on a 'complete list of every place', which is almost certainly untrue. Keep in mind that we

could be talking about informal places that are significant only to a small number of

people or even a single person, e.g. 'the park where, as a child, I first learned to fly a kite'.

It would be a very long list if we were going to include these sorts of places, and

incredibly time-consuming to search.

4 Wikipedia entry for KML: http://en.wikipedia.org/wiki/KML

Page 6: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

Relying on the structure of the fragment above, we can easily write a program that can

identify 'New York City' as the name of a place, or for that matter 'The park where I first

learned to fly a kite'. In fact, I could write a program that pulls all of the place names

from a file like this, along with a description, and a pair of coordinate points for each, and

includes them on a map. That's exactly what we're going to do. KML makes it possible.

If I haven't made it clear, the structural bits of the file must be standardized. KML

supports a limited set of elements (e.g. 'Placemark' is a supported element, as are 'Point'

and 'coordinates'), and all of the elements used in a file must adhere to the standard for it

to be considered valid.

The second point we need to address before we begin is, appropriately enough... where to

begin? Lewis Carroll famously tells us to "Begin at the beginning and go on till you come

to the end: then stop."5 Of course, Mr. Carroll

6 was writing a book at the time. If "Alice's

Adventures in Wonderland" were an article, he might have had different advice. From the

beginning to the end there is a lot of ground to cover. We're going to start somewhere

further along, and make up the difference with the following assumptions. For the

purposes of this discussion, I am going to assume that you have:

1. Perl7;

2. Access to Phil Harvey's excellent ExifTool8, a Perl library and command-

line application for reading, writing, and editing metadata in images (among

other file types). We will be using this library in our first script

3. A publicly accessible web server. Google requires the use of an API key9 by

which it can monitor the use of its map services. Google must be able to

validate your key, and so your site must be publicly available. Note that this

a requirement for Google Maps only

4. Photos, preferably in a photo management application. Essentially, all you

need is an app capable of generating both thumbnails and reduced size

copies of your original photos. An app that can export a nice gallery for use

on the web is even better

5. Coordinate data as part of the EXIF metadata10

embedded in your photos. If

that sounds unfamiliar to you, then most likely you will have to take some

5 Alice's Adventures in Wonderland

6 Lewis Carroll is a pen name of Charles Lutwidge Dodgson an English who lived during

the mid to late nineteenth century. 7 Perl: http://www.perl.org/

8 ExifTool: http://www.sno.phy.queensu.ca/~phil/exiftool/

9 Google Maps API Sign Up page: http://www.google.com/apis/maps/signup.html

10 EXIF metadata information at the ExifTool site:

http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html See also:

Page 7: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

additional steps before you can make use of this tutorial. I'm not aware of

any digital cameras that automatically include this information at the time

the photo is created. There are devices that can be used in combination with

digital cameras, and there are a number of ways that you can 'tag' your

photos with geographic data much the same way you would add keywords

and other annotations.

Let's begin!

GPS tags: http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/GPS.html Wikipedia entry: http://en.wikipedia.org/wiki/Exif specifications at exif.org: http://www.exif.org/specifications.html

Page 8: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

Part 1: Google Earth

Section 1: Introduction to Part 1 Time to begin the project in earnest. As I've already mentioned we'll spend the first half

of this tutorial looking at Google Earth and putting together a Perl script that, given a

collection of geotagged photos, will build a set of KML files so we can browse our

photos in Google Earth. These same files will serve as the data source for our Google

Maps application later on.

Section 2: Some Advice Before We Begin Take your time to make sure you understand each topic before you move on to the next.

Think of this as the first step in debugging your completed code. If you go slowly enough

to be able to identify aspects of the project that you don't quite understand, then you'll

have some idea where to start looking for problems should things not go as expected.

Furthermore, going slowly will give you the opportunity to identify those parts that you

may want to modify to better fit the script to your own needs.

If this is new to you, follow along as faithfully as possible with what I do here the first

time through. Feel free to make notes for yourself as you go, but making changes on the

first pass may make it difficult for you to catch back on to the narrative and piece

together a functional script. After you have a working solution, it will be a simple matter

to implement changes one at a time until you have something that works for you.

Following this approach it will be easy to identify the silly mistakes that tend to creep in

once you start making changes.

There is also the issue of trust. This is probably the first time we're meeting each other, in

which case you should have some doubt that my code works properly to begin with. If

you minimize the number of changes you make, you can confirm that this works for you

before blaming yourself or your changes for my mistakes. I will tell you up front that I'm

building this project myself as we go. You can be certain at least that it functions as

described for me as of the date attached to the article. I realize that this is quite different

from being certain that the project will work for you, but at least it's something.

The entirety of my project is available for you to download. You are free to use all of it

for any legal purpose whatsoever, including my photos in addition to all of the code,

icons, etc. This is so you have some samples to use before you involve your own content.

I don't promise that they are the most beautiful images you have ever seen, but they are

Page 9: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

all decent photos and properly annotated with the necessary metadata, including

geographic tags.

Section 3: Photos, Metadata and ExifTool To begin, we must have a clear understanding of what the Perl script will require from us.

Essentially, we need to provide it with a selection of annotated image files, and

information about how to reference those files.

A simple folder of files is sufficient, and will be convenient for us, both as the

programmer and end user. The script will be capable of negotiating nested folders, and if

a directory contains both images and other file types, non-image types will be ignored.

Typically, after a day of taking photos I'll have 100 to 200 that I want to keep. I delete the

rest immediately after offloading them from the camera. For the files that are left, I

preserve the original grouping, keeping all of the files together in a single folder. I place

this folder of images in an appropriate location according to a scheme that serves to keep

my complete collection of photos neatly organized. These are my digital 'negatives'. I

handle all subsequent organization, editing, enhancements, and annotations within my

photo management application. I use Apple Inc.'s Aperture11

but there are many others

that do the job equally well.

Annotating your photos is well worth the investment of time and effort, but it's important

that you have some strategy in mind so that you don't create meaningless tags that are

difficult to use to your advantage. For the purposes of this project the tags we'll need are

quite limited, which means that going forward we will be able to continue adding photos

to our maps with a reasonable amount of work.

The annotations we need are:

Caption

Latitude

Longitude

Image Date *

Location/Sub-Location

City

Province/State

Country Name

Event

People

ImageWidth *

ImageHeight *

* Values for these Exif tags are generated by your camera.

11

Aperture: http://www.apple.com/aperture/

Page 10: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

Note that these are labels used in Aperture, and are not necessarily consistent from one

application to the next. Some of them are more likely than others to be used reliably.

'City' for example should be dependable, while the labels 'People', 'Events', and

'Location', among others, are more likely to differ. One explanation for these variations is

that the meaning of these fields are more open to interpretation. Location, for example, is

likely to be used to narrow down the area where the photo was taken within a particular

city, but it is left to the person who is annotating the photo to decide that the field should

name a specific street address, an informal place (e.g. 'home' or 'school'), or a larger area,

for example a district or neighborhood. Fortunately things aren't so arbitrary as they

seem.

Each of these fields corresponds to a specific tag name that adheres to one of the common

metadata formats (Exif12

, IPTC13

, XMP14

, and there are others). These tag names are

consistent as required by the standards. The trick is in determining the labels used in your

application that correspond to the well-defined tag names. Our script relies on these

metadata tags, so it is important that you know which fields to use in your application.

This gives us an excuse to get acquainted with ExifTool15

. From the project's website, we

have this description of the application:

ExifTool is a platform-independent Perl library plus a command-line application for

reading, writing, and editing meta information in image, audio and video files...

ExifTool can seem a little intimidating at first. Just keep in mind that we will need to

understand just a small part of it for this project, and then be happy that such a useful and

flexible tool is freely available for you to use.

The brief description above states in part that ExifTool is a Perl library and command line

application that we can use to extract metadata from image files.

With a single short command, we can have the app print all of the metadata contained in

one of our image files. First, make sure ExifTool is installed. You can test for this by

typing the name of the application at the command line.

$ exiftool

12

Exif: (E)(x)changeable (i)mage (f)ile format. EXIF.org, http://exif.org/ is an unofficial site that at least links to the specifications. See the appendix for more information about the Exif standard. 13

(I)nternational (P)ress (T)elecommunications (C)ouncil. See the IPTC entry at Wikipedia for more information: http://en.wikipedia.org/wiki/IPTC 14

XMP home at adobe.com: http://www.adobe.com/products/xmp/index.html 15

The ExifTool homepage at http://www.sno.phy.queensu.ca/~phil/exiftool/ is the best reference for the project. Other than a tutorial like this one, you shouldn't need another resource.

Page 11: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

If it is installed, then running it with no options should prompt the tool to print its

documentation. If this works, there will be more than one screen of text. You can page

through it by pressing the spacebar. Press the 'q' key at any time to stop.

If the tool is not installed, you will need to add it before continuing. See the appendix at

the end of this tutorial for more information.

Having confirmed that ExifTool is installed, typing the following command will result in

a listing of the metadata for the named image:

$ exiftool -f -s -g2 /path/image.jpg

Where 'path' is an absolute path to image.jpg or a relative path from the current directory,

and 'image.jpg' is the name of one of your tagged image files.

We'll have more to say about ExifTool later, but because I believe that no tutorial should

ask the reader to blindly enter commands as if they were magic incantations, I'll briefly

describe each of the options used in the command above:

-f, forces printing of tags even if their values are not found. This gives us a better idea

about all of the available tag names, whether or not there are currently defined values for

those tags.

-s, prints tag names instead of descriptions. This is important for our purposes. We need

to know the tag names so that we can request them in our Perl code. Descriptions, which

are expanded, more human-readable forms of the same names obscure details we need.

For example, compare the tag name 'GPSLatitude' to the description 'GPS Latitude'. We

can use the tag name, but not the description to extract the latitude value from our files.

-g2, organizes output by category. All location specific information is grouped together,

as is all information related to the camera, date and time tags, etc. You may feel, as I do,

that this grouping makes it easier to examine the output. Also, this organization is more

likely to reflect the grouping of field names used by your photo management application.

If you prefer to save the output to a file, you can add ExifTool's -w option with a file

extension.

$ exiftool -f -s -g2 -w txt path/image.jpg

This command will produce the same result but write the output to the file 'image.txt' in

the current directory; again, where 'image.jpg' is the name of the image file. The -w

option appends the named extension to the image file's basename, creates a new file with

that name, and sets the new file as the destination for output.

The tag names that correspond to the list of Aperture fields presented above are:

metadata tag name Aperture field label

Caption-Abstract Caption

Page 12: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

metadata tag name Aperture field label

GPSLatitude Latitude

GPSLongitude Longitude

DateTimeOriginal Image Date

Sub-location Location/Sub-Location

City City

Province-State Province/State

Country-PrimaryLocationName Country Name

FixtureIdentifier Event

Contact People

ImageWidth Pixel Width

ImageHeight Pixel Height

Section 4: Making Photos Available to Google Earth We will use some of the metadata tags from our image files to locate our photos on the

map (e.g. GPSLatitude, GPSLongitude), and others to describe the photos. For example,

we will include the value of the People tag in the information window that accompanies

each marker to identify friends and family who appear in the associated photo.

Because we want to display and link to photos on the map, not just indicate their position,

we need to include references to the location of our image files on a publicly accessible

web server. You have some choice about how to do this, but for the implementation

described here we will (1) Display a thumbnail in the info window of each map marker

and (2) include a link to the details page for the image in a gallery created in our photo

management app.

When a visitor clicks on a map marker they will see a thumbnail photo along with other

brief descriptive information. Clicking a link included as part of the description will open

the viewer's web browser to a page displaying a large size image and additional details.

Furthermore, because the page is part of a gallery, viewers can jump to an index page and

step forward and back through the complete collection. This is a complementary way to

Page 13: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

browse our photos. Taking this one step further, we could add a comments section to the

gallery pages or replace the gallery altogether, instead choosing to display each photo as

a weblog post for example.

The structure of the gallery created from my photo app is as follows...

/ (the root of the gallery directory)

index.html

large-1.html

large-2.html

large-3.html

...

large-n.html

assets/

css/

img/

catalog/

pictures/

picture-1.jpg

picture-2.jpg

picture-3.jpg

...

picture-n.jpg

thumbnails/

thumb-1.jpg

thumb-2.jpg

thumb-3.jpg

...

thumb-n.jpg

The application creates a root directory containing the complete gallery. Assuming we do

not want to make any manual changes to the finished site, publishing is as easy as

copying the entire directory to a location within the web server's document root.

assets/: Is a subfolder containing files related to the theme itself. We don't need to

concern ourselves with this sub-directory.

catalog/: Contains a single catalog.plist file which is specific to Aperture and not relevant

to this discussion.

pictures/: Contains the large size images included on the detail gallery pages.

thumbnails/: This subfolder contains the thumbnail images corresponding to the large

size images in pictures/.

Page 14: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

Finally, there are a number of files at the root of the gallery. These include index pages

and files named 'large-n.html', where n is a number starting at 1 and increasing

sequentially e.g. large-1.html, large-2.html, large-3.html, ... .

The index files are the index pages of our gallery. The number of index pages generated

will be dictated by the number of image files in the gallery, as well as the gallery's layout

and design. index.html is always the first gallery page.

The large-n.html files are the details pages of our gallery. Each page features an

individual photo with links to the previous and next photos in sequence and a link back to

the index. You can see the gallery I have created for this tutorial here:

http://robreed.net/photos/tutorial_gallery/

If you take the time to look through the gallery, maybe you can appreciate the value of

viewing these photos on a map. Web-based photo galleries like this one are nice enough,

but the photos are more interesting when viewed in some meaningful context.

There are a couple of things to notice about this gallery.

Firstly, picture-1.jpg, thumb-1.jpg, and large-1.html all refer to the same image. So if we

pick one of the three files we can easily predict the names of the other two. This

relationship will be useful when it comes to writing our script.

There is another important issue I need to call to your attention because it will not be

apparent from looking only at the gallery structure. Aperture has renamed all of my

photos in the process of exporting them.

The name of the original file from which picture-1.jpg was generated (as well as large-

1.html and thumb-1.jpg) is 'IMG_0277.JPG', which is the filename produced by my

camera. Because I want to link to these gallery files, not my original photos which will

stay safely tucked away on a local drive, I must run the script against the photos in the

gallery. I cannot run it against the original image files because the filenames referenced

in the output are unrelated to the files in the gallery.

If my photo management app provided me the option of preserving the original filenames

for the corresponding photos in the gallery, then I could run the script against the original

image files or the gallery photos because all of the filenames would be consistent, but this

is not the case. I don't have a problem as long as I run the script on the exported photos.

However, if I'm running the script against the photos in the web gallery, either the

pictures or thumbnail images must contain the same metadata as the original image files.

Aperture preserves the metadata in both. Your application may not.

A simple, dependable way to confirm that the metadata is present in the gallery files is to

run ExifTool first against the original file and then the same photo in the pictures/ and

thumbnails/ directories in the gallery. If ExifTool reports identical metadata, then you

will have no trouble using one of pictures/ or thumbnails/ as your source directory. If the

Page 15: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

metadata is not present or not complete in the gallery files, you may need to use the script

on your original image files. As has already been explained, this isn't a problem unless

the gallery produces filenames that are inconsistent with the original filenames, as

Aperture does. In this case you have a problem. You won't be able to run the script on the

original image files because of the naming issue or on the gallery photos because they

don't contain metadata.

Make sure that you understand this point.

If you find yourself in this situation, then your best bet is to generate files to use with

your maps from your original photos in some other way, bypassing your photo

management app's web gallery features altogether in favor of a solution that preserves the

filenames, the metadata, or both. There is another option which involves setting up a

relationship between the names of the original files and the gallery filenames. This

tutorial does not include details about how to set up this association.

Finally, keep in mind that though we've looked at the structure of a gallery generated by

Aperture, virtually all photo management apps produce galleries with a similar structure.

Regardless of the application used, you should find:

A group of html files including index and details pages

A folder of large size image files

A folder of thumbnails

Once you have identified the structure used by your application, as we have done here, it

will be a simple task to translate these instructions.

Section 5: Referencing Files Over the Internet Now we can talk about how to reference these files and gallery pages so that we can

create a script to generate a KML file that includes these references.

When we identify a file over the internet, it is not enough to use the filename, e.g.

'thumb-1.jpg', or even the absolute and relative path to the file on the local computer. In

fact these paths are most likely not valid as far as your web server is concerned. Instead

we need to know how to reference our files such that they can be accessed over the global

internet, and the web more specifically. In other words, we need to be able to generate a

URL (Uniform Resource Locator) which unambiguously describes the location of our

files. The formal details of exactly what comprises a URL16

are more complicated than

may be obvious at first, but most of us are familiar with the typical URL, like this one:

http://www.ietf.org/rfc/rfc1630.txt

16

RFC 1630: http://www.ietf.org/rfc/rfc1630.txt

Page 16: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

which describes the location of a document titled "Universal Resource Identifiers in

WWW" that just so happens to define the formal details of what comprises a URL.

http://www.ietf.org

This portion of the address is enough to describe the location of a particular web server

over the public internet. In fact it does a little more than just specify the location of a

machine. The http:// portion is called the scheme and it identifies a particular protocol

(i.e. a set of rules governing communication) and a related application, namely the web.

What I just said isn't quite correct; at one time, HTTP was used exclusively by the web,

but that's no longer true. Many internet-based applications use the protocol because the

popularity of the web ensures that data sent via HTTP isn't blocked or otherwise

disrupted. You may not be accustomed to thinking of it as such, but the web itself is a

highly-distributed, network-based application.

/rfc/

This portion of the address specifies a directory on the server. It is equivalent to an

absolute path on your local computer. The leading forward slash is the root of the web

server's public document directory. Assuming no trickiness on the part of the server, all

content lives under the document root.

This tells us that rfc/ is a sub-directory contained within the document root. Though this

directory happens to be located immediately under the root, this certainly need not be the

case. In fact these paths can get quite long.

We have now discussed all of the URL except for:

rfc1630.txt

which is the name of a specific file. The filename is no different than the filenames on

your local computer. Let's manually construct a path to one of the large-n.html pages of

the gallery we have created.

The address of my server is robreed.net, so I know that the beginning of my URL will be:

http://robreed.net

I keep all of my galleries together within a photos/ directory, which is contained in the

document root.

http://robreed.net/photos/

Within photos/, each gallery is given its own folder. The name of the folder I have

created for this tutorial is 'tutorial_gallery'. Putting this all together, the following URL

brings me to the root of my photo gallery:

http://robreed.net/photos/tutorial_gallery/

We've already gone over the directory structure of the gallery, so it should make sense

you to that when referring to the 'large-1.html' detail page, the complete URL will be:

Page 17: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

http://robreed.net/photos/tutorial_gallery/large-1.html

the URL of the image that corresponds to that detail page is:

http://robreed.net/photos/tutorial_gallery/pictures/picture-1.jpg

and the thumbnail can be found at:

http://robreed.net/photos/tutorial_gallery/thumbnails/thumb-1.jpg

Notice that the address of the gallery is shared among all of these resources. Also, notice

that resources of each type (e.g. the large images, thumbnails, and html pages) share a

more specific address with files of that same type.

If we use the term 'base address' to refer to the shared portions of these URLs, then we

can talk about several significant base addresses:

The gallery base address: http://robreed.net/photos/tutorial_gallery/

The html pages base address: http://robreed.net/photos/tutorial_gallery/

The images base address: http://robreed.net/photos/tutorial_gallery/pictures/

The thumbnails base address: http://robreed.net/photos/tutorial_gallery/thumbnails/

Note that given the structure of this particular gallery, the html pages base address and

the gallery base address are identical. This need not be the case, and may not be for the

gallery produced by your application.

We can hard-code the base addresses into our script. For each photo, we need only

append the associated filename to construct valid URLs to any of these resources. As the

script runs, it will have access to the name of the file that it is currently evaluating, and so

it will be a simple matter to generate the references we need as we go.

At this point we have discussed almost everything we need to put together our script. We

have:

created a gallery at our server, which includes our photos with metadata in

tow

identified all of the metadata tags we need to extract from our photos with

the script and the corresponding field names in our photo management

application

determined all of the base addresses we need to generate references to our

image files

Section 6: KML The last thing we need to understand is the format of the KML files we want to produce.

Page 18: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

We've already looked at a fragment of KML. The full details can be found on Google's

KML documentation pages17

, which include samples, tutorials and a complete reference

for the format.

A quick look at the reference is enough to see that the language includes many elements

and attributes, the majority of which we will not be including in our files. That statement

correctly implies it is not necessary for every KML file to include all elements and

attributes. The converse however is not true, which is to say that every element and

attribute contained in any KML file must be a part of the standard.

A small subset of KML will get us most, if not all, of what you will typically see in

Google Earth from other applications.

Many of the features we will not be using deal with aspects of the language that are

either:

1. Not relevant to this project, e.g. ground overlays (GroundOverlay) which

"draw an image overlay draped onto the terrain"

2. Minute details for which the default values are sensible

There is no need to feel shortchanged because we are covering only a subset of the

language. With the basic structure in place and a solid understanding of how to script the

generation of KML, you will be able to extend the project to include any of the other

components of the language as you see fit.

The structure of our KML file is as follows:

1. <?xml version="1.0" encoding="UTF-8"?>

2. <kml xmlns="http://earth.google.com/kml/2.1">

3. <Document>

4. <Folder>

5. <name>$folder_name</name>

6. <description>$folder_description</description>

7. <Placemark>

8. <name>$placemark_name</name>

9. <Snippet maxLines="1">

10. $placemark_snippet

11. </Snippet>

12. <description><![CDATA[

13. $placemark_description

14. ]]></description>

15. <Point>

17

KML documentation at google.com: http://code.google.com/apis/kml/documentation/

Page 19: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

16. <coordinates>$longitude,$latitude</coordinates>

17. </Point>

18. </Placemark>

19. </Folder>

20. </Document>

21. </kml>

Line 1: XML header

Every valid KML file must start with this line and nothing else is allowed to appear

before it. As I've already mentioned, KML is an XML-based language and XML requires

this header.

Line 2: Namespace declaration

More specifically this is the KML namespace declaration, and it is another formality. The

value of the xmlns attribute must be a URI referencing a resource that identifies elements

and attributes which are valid under the language. Remember that KML is one of many

XML based languages, each with its own vocabulary. Making namespaces unique to each

language avoids the obvious problems that would occur if all languages were required to

pull from a common pool of identifiers. In such a scheme all identifiers would need to be

unique among all XML based languages—a situation which would quickly prove

unworkable.

The first two lines are strictly boilerplate. They are required and will be identical in every

KML file you produce. They change only when the language itself is modified.

Line 3: <Document> is a container element representing the KML file itself. If we do

not explicitly name the document by including a name element then Google Earth will

use the name of the KML file as the Document element <name>.

The Document container will appear on the Google Earth 'Sidebar' within the 'Places'

panel. Optionally we can control whether the container is closed or open by default. (This

setting can be toggled in Google Earth using a typical disclosure triangle.) There are

many other elements and attributes that can be applied to the Document element. Refer to

the KML Reference for the full details.

Line 4: <Folder> is another container element. The files we produce will include a

single <Folder> containing all of our Placemarks, where each Placemark represents a

single image. We could create multiple Folder elements to group our Placemarks

according to some significant criteria. Think of the Folder element as being similar to

your operating system's concept of a folder.

At this point, note the structure of the fragment. The majority of it is contained within the

Folder element. Folder, in turn, is an element of Document which is itself within the

Page 20: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

<kml> container. It should make sense that everything in the file that is considered part

of the language must be contained within the kml element.

From the KML reference

A Folder is used to arrange other Features hierarchically (Folders, Placemarks,

NetworkLinks, or Overlays). A Feature is visible only if it and all its ancestors are

visible.

Line 5: The name element identifies an object, in this case the Folder object. The text

that appears between the name tags can be any plain text that will serve as an appropriate

label.

Line 6: <description> is any text that seems to adequately describe the object.

From the KML reference:

User-supplied text that appears in the description balloon when the user clicks

on either the feature name in the Places panel or the Placemark icon in the 3D

viewer. This text also appears beneath the feature name in the Places panel if no

<Snippet> tag is specified for the feature.

The description element supports both plain text and a subset of HTML. We'll

consider issues related to using HTML in <description> at the discussion of

Placemark, lines 12 - 14.

Lines 7 - 17 define a <Placemark> element.

Note that Placemark contains a number of elements that also appear in Folder, including

<name> (line 8), and <description> (lines 12 - 14). These elements serve the same

purpose for Placemark as they do for the Folder element, but of course they refer to a

different object.

I've said that <description> can include a subset of HTML in addition to plain text. Under

XML, some characters have special meaning. You may need to use these characters as

part of the HTML included in your descriptions. Angle brackets (<, >) for example

surround tag names in HTML, but serve a similar purpose in XML. When they are used

strictly as part of the content, we want the XML parser to ignore these characters.

We can accomplish this a few different ways:

We can use entity references, either numeric character references or character entity

references, to indicate that the symbol appears as part of the data and should not be

treated as part of the syntax of the language. The character '<', which is required to

include an image as part of the description (something we will be doing), (e.g. <img

src=... />) can safely be included as the character entity reference '&lt;' or the numeric

character reference '&#60'.

Page 21: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

The character entity references may be easier to remember and recognize on sight but are

limited to the small subset of characters for which they have been defined. The numeric

references on the other hand can specify any ASCII character. Of the two types, numeric

character references should be preferred. There are also Unicode entity references which

can specify any character at all.

In the simple case of embedding short bits of HTML in KML descriptions, we can avoid

the complication of these references altogether by enclosing the entire description in a

CDATA18

element, which instructs the XML parser to ignore any special characters that

appear until the end of the block set off by the CDATA tags.

Notice the string '<![CDATA[' immediately after the opening <description> tag within

<Placemark>, and the string ]]> immediately before the closing </description> tag. If we

simply place all of our HTML and plain text between those two strings, it will all be

ignored by the parser and we are not required to deal with special characters individually.

This is how we'll handle the issue.

Lines 9 - 11: <Snippet>

The KML reference does a good job of clearly describing this element.

From the KML reference:

In Google Earth, this description is displayed in the Places panel under the

name of the feature. If a Snippet is not supplied, the first two lines of the

<description> are used. In Google Earth, if a Placemark contains both a

description and a Snippet, the <Snippet> appears beneath the Placemark in the

Places panel, and the <description> appears in the Placemark's description

balloon. This tag does not support HTML markup. <Snippet> has a maxLines

attribute, an integer that specifies the maximum number of lines to display.

Default for maxLines is 2.

Notice that in the block above at line 9, I have included a 'maxLines' attribute with a

value of 1. Of course, you are free to substitute your own value for maxLines, or you can

omit the attribute entirely to use the default value.

The only element we have yet to review is <Point>, and again we need only look to the

official reference for a nice description.

From the KML reference:

A geographic location defined by longitude, latitude, and (optional) altitude.

When a Point is contained by a Placemark, the point itself determines the

position of the Placemark's name and icon.

18

The name CDATA is formed from the phrase 'Character DATA'

Page 22: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

<Point> in turn contains the element <coordinates> which is required.

From the KML reference:

A single tuple consisting of floating point values for longitude, latitude, and

altitude (in that order).

The reference also informs us that altitude is optional, and in fact we will not be

generating altitude values.

Finally the reference warns:

Do not include spaces between the three values that describe a coordinate.

This seems like an easy mistake to make. We'll need to be careful to avoid it.

There will be a number of <Placemark> elements, one for each of our images.

The question is how to handle these elements. The answer is that we'll treat KML as a 'fill

in the blanks' style template. All of the structural and syntactic bits will be hard-coded,

e.g. the XML header, namespace declaration, all of the element and attribute labels, and

even the whitespace, which is not strictly required but will make it much easier for us to

inspect the resulting files in a text editor. These components will form our template.

The blanks are all of the text and html values of the various elements and attributes. We

will use variables as place-holders everywhere we need dynamic data, i.e. values that

change from one file to the next or one execution of the script to the next.

Take a look at the strings I've used in the block above. $folder_name,

$folder_description, $placemark_name, etc. For those of you unfamiliar with Perl, these

are all valid variable names chosen to indicate where the variables slot into the structure.

These are the same names used in the source file distributed with the tutorial.

Section 7: Introduction to the Code At this point, having discussed every aspect of the project, we can succinctly describe

how to write the code. We'll do this in 3 stages of increasing granularity.

Firstly, we'll finish this tutorial with a natural language walk-through of the execution of

the script.

Secondly, if you look at the source file included with the project, you will notice

immediately that comments dominate the code. Because instruction is as important an

objective as the actual operation of the script, I use comments in the source to provide a

running narration. For those of you who find this superabundant level of commenting a

distraction, I'm distributing a second copy of the source file with much of the comments

removed.

Page 23: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

Finally, there is the code itself. After all, source code is nothing more than a rigorously

formal set of instructions that describe how to complete a task. Most programs, including

this one, are a matter of transforming input in one form to output in another. In this very

general sense, programming is similar to cooking, farming, manufacturing, or any

number of other pursuits. To take this idea a little further, you could think of gardening as

a sort of abstract form of organic object oriented programming.

After reading through the following high level description you'll want to move on to the

source file.

Section 8: Natural language walk-through 1. We need to prime the script by hard-coding some variable assignments.

These 'configurable variables' serve the same purpose as the preferences,

menus and dialog boxes typical of GUI applications.

Among other values we'll specify:

The names of the KML output files

The directory where the script should look for our photos

and our Google Maps API key

Important: If you haven't yet, now is a perfect time to sign up for a key19

.

Before running the script, open the source file and look for the 'configurable

variables' section of the code. Read through the comments describing each

required value, make whatever necessary changes, and save the file.

2. We need to create our KML output files.

If there is a problem which prevents the script from writing these files, we

can determine that at the beginning of execution before doing any other

work.

3. The script starts reading from the 'fill in the blanks' template included in the

data section of the source file, which is read via the __DATA__ pseudo-

filehandle. (See the comments in the source for more information.)

The template looks like this:

__DATA__

<?xml version="1.0" encoding="UTF-8"?>

<kml xmlns="http://earth.google.com/kml/2.1">

<Document>

<Style id="tutorial_custom_icon">

<IconStyle>

19

Google Maps API Sign Up: http://www.google.com/apis/maps/signup.html

Page 24: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

<scale>1.0</scale>

<Icon>

<href>http://!custom_icon_url_goes_here!</href>

</Icon>

</IconStyle>

</Style>

<Folder>

<name>!folder_name_goes_here!</name>

<description>

!folder_description_goes_here!

</description>

!placemarks_go_here!

</Folder>

</Document>

</kml>

All of the literal text in the template is written directly to the output files.

The term 'literal text' applies to those parts of our template written directly

into the source code, or in other words that are not part of the metadata

extracted from the image files or computed values.

Notice that there are a number of placeholder strings in the template:

!custom_icon_url_goes_here!

!folder_name_goes_here!

!folder_description_goes_here!

!placemarks_go_here!

Because these placeholders are all unique strings in the template we can

attempt to match against of them as we read each line and, wherever a

match succeeds, substitute the current value of the appropriate variable for

the placeholder. Note that some of these are from the configurable variables

section of the file while others are values set dynamically during execution.

We could simply include the values from the configurable variables section

in the template rather than assigning these values to variables, and then

substituting the values for placeholders as described.

Handling it the way it has been presented here allows us to group all of the

values we must set manually together in one small section at the top. This is

considered to be preferable to scattering these values throughout the source

because it makes it easier to configure the script and maintain the code. For

example, it minimizes the chance that we'll break something by making an

inadvertent change when we only intended to update one of these values.

There are a number of other benefits as well, including these commonly

noted advantages:

Page 25: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

These values are essentially options or directives we use to modify

the behavior of the script. Grouping them together makes it more

efficient to use our little command line executable, just as well

organized menus make it easier to work with a GUI-based app.

Grouping these values together makes it easier to examine them.

Because the values are defined once and stored in variables, we can

repeatedly use the same values at more than one point in the code

without retyping them. Reusing values whenever possible, rather

than recreating them, significantly decreases the likelihood of a typo

or some other careless mistake breaking the execution of the

program or ruining our output.

Defining values only once avoids a common problem where two or

more independent values that are intended to be identical get out of

sync when the value is not updated everywhere it is used.

4. When we encounter the Placemarks section of the KML template (i.e. the

string !placemarks_go_here!) we need to append one Placemark element for

each of our image files.

The Perl module File::Find, which is part of the standard distribution,

defines a number of functions for traversing a filesystem hierarchy starting

at a specified root. One of these functions, find(), does a depth-first search

of the directory tree, running a routine we provide it against every item

found, where an item is any of the possible filesystem entry types (these

vary among platforms but always include files and directories among

others).

For example, Unix-like operating systems typically allow for seven (7)

unique entry types including:

plain files

directories

symbolic links

named pipes

block special files

character special files

sockets

These different types of entries and the differences among platforms aren't

particularly important to us. For our purposes, there are only 2 categories of

entries: plain files and everything else. If the item is not a file, we can

ignore it regardless of type.

Page 26: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

We need to define a routine that can be run against each item found. We

provide find() a reference to the routine and a starting location and it

arranges for the routine to run repeatedly, once for each item in the directory

tree starting at the root.

From the documentation for File::Find

find(\&wanted, @directories_to_search);

sub wanted { ... }

"find()" does a depth-first search over the given @directories in the order

they are given.

For each file or directory found, it calls the &wanted subroutine.

Additionally, for each directory found, it will "chdir()" into that directory

and continue the search, invoking the &wanted function on each file or

subdirectory in the directory.

The wanted function takes no arguments but rather does its work through a

collection of variables.

$File::Find::dir is the current directory name, $_ is the current filename

within that directory and $File::Find::name is the complete pathname to the

file.

Don't modify these variables.

The documentation confirms that we need to supply find() a reference to a

function, &wanted, and a list of directories to search,

@directories_to_search.

@directories_to_search is easy enough, we want to search the folder

containing our geotagged image files. This is the value of one of our

configurable variables ($photos_dir).

Let's describe the routine that find() will run against each item in

$photos_dir. Make sure you understand that the routine should be designed

to run against only one item. If there are many items, find() will call the

routine many times, but that is irrelevant as far as the design of the routine is

concerned.

For a single item:

5. First, the routine runs a series of tests to determine if it is:

a file

the appropriate type of file

and readable

Page 27: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

The second test will make a determination based on the filename extension.

As written, the script considers any file that ends in .jpg or .jpeg (case

insensitive) a valid file type. You can expand this list to include extensions

for other types of image files or alternative extensions for jpeg files.

If the item fails any of these tests then we immediately return from our

routine, essentially skipping it.

6. If the item passes all of the tests, we use ExifTool to extract from the

image's metadata only those tag values we're interested in (detailed above).

7. Next check for the 'GPSLatitude' and 'GPSLongitude' tags among the list

returned from ExifTool. If there are not defined values for these tags then

the tag names will not be included among the list returned. Though the item

may be a valid image file, without coordinate data we can't know where to

position a marker representing this photo on a map, so there's nothing we

can do with it in our mapping application. We have no choice but to skip it.

Note that any photo for which there is no coordinate data will be missing

from our output files.

8. Assuming we have at least the two tags 'GPSLatitude' and 'GPSLongitude',

we use the tag values to build a Placemark element for the image and write

the element to output.

We assemble a <description> element for the Placemark by combining

several of the tag values.

We can account for optional tags, which may or may not have been

populated in the metadata for the image (the tag People for example) by

determining if ExifTool was able to find values for the associated tag

names. If no value was found, because the tag was not used, the

corresponding variable will be undefined.

The Placemark description for each of our image files can be illustrated by

the following block, which is another template:

<ul>

<li>People: $People</li>

<li>Event: $Event</li>

<li>Location: $Location</li>

<li>City: $City</li>

<li>State: $State</li>

<li>Country: $Country</li>

<li>Date: $DateTimeOriginal</li>

</ul>

<p>$thumbnail_img</p>

<p>$image_link</p>

Page 28: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

Variables are replaced by tag values extracted from the current image file. If

one or more of the variables is undefined, we simply do not include the

entire line.

$thumbnail_img is a complete URL to a thumbnail which will be included

in the description via the <img> tag's src attribute, e.g.

<img src="$thumbnail_img" />

$image_link is a complete URL to the gallery detail page featuring the

photo. We include a link to the page in the description, e.g.

<a href="$image_link">Gallery details page for this image</a>

At this point we've done everything required to represent the photo in our

output file, but we're not quite ready to return from the routine.

As we have just seen, among the metadata tags we want to extract are the

regional tags 'City', 'State/Province' and 'Country'. Assuming values for

these tags are defined, we will include the information as part of the

description in our <Placemark>, which means we will see it displayed in the

information window when we click the marker representing this image on

the map.

We also use these tags to assist us with clustering in our Google Maps

application and as a first step to implementing a feature called 'Regions' in

Google Earth (more on the topic of Regions later).

Throughout the tutorial I've said that we will be generating more than one

output file, but we haven't identified what these files are until now.

By default, the names of the output files generated in the script

accompanying the tutorial are:

photos.kml

cities.kml

states.kml

countries.kml

photos.kml is the only file of interest as far as this part of the tutorial is

concerned. It is the output file we've been discussing to this point. This is

the file that includes one <Placemark> for each of our geotagged image

files.

What are the others?

In the source we declare the three hashes:

%known_cities

Page 29: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

%known_ states

%known_countries

These hashes will contain one key for each unique region represented

among the geotagged images (i.e. one key in the appropriately named hash

for each city, state, and country represented).

The purpose of these hashes is to enable clustering of markers on our maps

around large, well-defined geographical areas at lower zoom levels.

What is clustering?

Until we are above some threshold level, we will not be able to distinguish

between markers for photos first within the same country, then

state/province, and finally city, assuming we have more than one photo for

the region. In these cases we create a single marker at the center of the

region to indicate that there are photos available which cannot be displayed

at the current zoom level.

9. Before we return from the routine, we check the hashes to see if the keys

corresponding to the tag values from the current image file already exist. If

they don't, we add them.

For example, if the current image file is a photo of Boston, Massachusetts

(USA), the following is a partial list of tag values from ExifTool:

City: "Boston"

State: "MA"

Country: "USA"

Let's say that the script has already come across a photo of someplace in the

United States. If that's the case, then the key "USA" will already exist in the

%known_countries hash. We don't have to add it again.

If we've also seen at least one photo taken somewhere in Massachusetts,

then the key "MA, USA" will exist in

%known_states; but let's say this is the first photo of Boston, Massachusetts.

Then the key "Boston, MA" will not exist in %known_cities, so it will be

added to the hash.

If this is all a little unclear, it may help to look at the source file.

After all items have been evaluated, find() returns. At this point in

execution, we've generated a Placemark element for each image, and

finished populating the regional hashes.

10. For each key in the regional hashes, the script creates a Placemark element

in one of cities.kml, states.kml or countries.kml (these are the default output

Page 30: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

filenames). For example, for every key in the %known_countries hash, a

Placemark is created in the countries.kml file.

There are a couple of important differences between photos.kml and these

regional files.

A. There will be only one Placemark element for each unique regional

location. So if we have 100 image files and all of them are photos of

Boston, MA, then we will have a single Placemark element in each

of cities.kml, states.kml, and countries.kml - not 100 identical

Placemark elements in each.

B. Because these Placemarks represent regions, not photos, there is no

metadata for us to work with. How do we get a coordinate pair for

each city, state, and country?

We have two options.

The Google Maps API includes a geocoder we can use. From the

documentation we have this definition of geocoding:

Geocoding is the process of converting addresses (like "1600 Amphitheatre

Parkway, Mountain View, CA") into geographic coordinates (like latitude

37.423021 and longitude -122.083739), which you can use to place markers

or position the map based on street addresses in your database or addresses

supplied by users.

We can pass the geocoder any one of our hash keys and it will return the

geographic coordinates representing the center of the named region.

The problem is that it returns coordinates for what I'll call the 'computed

center' of the region, which is not always what we want. For example, the

following is a link to maps.google.com identifying the computed center of

Massachusetts (my home state).

http://maps.google.com/maps?f=q&hl=en&geocode=&q=Massachusetts&ie=UTF8&ll=42.008489,-71.71875&spn=3.98356,7.03125&z=7&om=1

The arrow identifies the computed center of the state as reported by

Google's geocoder, which seems to indicate that the center is along the

southern border. This makes sense when you consider that Massachusetts

includes Cape Cod and Nantucket, which are much further southeast than

the rest of the state.

If you aren't bothered by these odd-looking but technically accurate

computed coordinates, then Google's geocoder may be all you need. Also, if

your regions are regularly shaped then this issues won't be apparent to you.

Page 31: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

Alternatively, you could build a set of associations between region names

and the geographic coordinates you want to represent these places.

As written, the script allows you to do both. In addition to using the

geocoder, you can manually associate regional locations with specific

coordinates in the configurable variables section of the code. Instructions

are included in the source file itself. If you have manually placed a

particular region, then it will use your coordinates, otherwise it will use

Google's geocoder.

Note: Use of the geocoder here is the reason that you must include a Google

Maps API key in the script.

These regional places are useful for clustering with Google Maps and

Google Earth. Clustering in Google Earth requires the use of Regions which

are not implemented in this tutorial. The topic of clustering will come up

again in the Google Maps portion of the project.

11. After generating all of our Placemark elements, there are a couple of lines

from the KML template at DATA that must still to be appended to the

output before we're finished. These are nothing more than closing tags for

the <Folder>, <Document> and <kml> elements and can be written directly

from our template to the the output files.

12. At the end of execution we print a few statistics that have been collected

throughout execution to help users identify problems, or confirm that the

script ran as expected. These are simple counters or based on simple

counters, but are useful nonetheless.

At the end of execution we have generated our KML files:

photos.kml, cities.kml, states.kml, countries.kml

Of primary interest is photos.kml.

Because we're not dealing with Regions for clustering in Google Earth, the regional kml

files aren't useful for this part of the tutorial, but don't delete them because we will be

using clustering in Google Maps. Should we decide to use Regions in the future,

implementing the feature will be a much simpler proposition than it would be otherwise

because we've already done some of the work involved.

Page 32: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

Section 9: Finishing up You can, and probably should, validate your KML files to ensure that they adhere to the

standard. This doesn't take a long time and it's easy to do. If you've uploaded your files to

a publicly accessible web server, visit the Feed Validator20

Once at the site, type the complete URL of your KML file(s), one at a time, into the text

entry field and click the validate button.

A note about the results:

The validator makes a distinction between warnings and errors.

If your file conforms to the standard, but the validator has some suggestions for

improving it you'll see the message:

Warning

This feed is valid, but may cause problems for some users. We recommend fixing these problems.

If you scroll down the page you will see a message confirming that the feed has

validated.

If there are actually errors in the file it will not validate, and you will see the message:

Sorry

This feed does not validate.

In either case, the validator will identify the lines in the file that produced the messages

as well as an attempted explanation of the issue.

Once your feed validates, all that's left to do is enjoy browsing and sharing your photos.

Section 10: Sharing KML Files 1. You can open the KML files locally.

Doubling-clicking photos.kml should open Google Earth. Alternatively,

launch Google Earth, choose 'Open...' from the 'Edit' menu and use the

standard dialog box to navigate the filesystem to your photos.kml file.

2. You can share the file via email.

Because the files contain only text, you can depend on file sizes being

relatively small. Remember that images are referenced in the file via URL

not included directly.

20

Feed Validator: http://feedvalidator.org/

Page 33: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

3. If you upload the file to a public web server, something you'll want to do in

preparation for the Google Maps portion of the project, then others can

access your images from within Google Earth by adding a Network Link.

However you choose to share the KML file, you can select the folder containing all of

your photo markers in Google Earth's Places panel and 'tour' your photos. A tour moves

from one marker to the next on the map, pausing for a short amount of time at each and

(optionally) displaying the marker's information window.

Finally, and as a preview of what we'll be doing next, you can display your KML file in

Google Maps in either of two ways:

You can visit the Google Maps site at maps.google.com and type the full URL to your

photos.kml file into the search field on the page.

Equivalently, you can pass the URL for the photos.kml file as the value to that

application's 'q' parameter.

For example, the KML file I've created for this project is located at:

http://robreed.net/maps_tutorial/photos.kml

I can display the data from the file in Google Maps at:

http://maps.google.com?q=http://robreed.net/maps_tutorial/photos.kml

We can't change anything about the Google designed page, which works well for only

small numbers of images. If you had hundreds of image files on the other hand, the

'Contents' list in the sidebar on the page would be very long and unwieldy. Also, we

cannot incorporate clustering or other features available to us through the API.

Take a look at my kml file and you'll see the problem that clustering solves on display

around the area of Boston, MA, where the majority of the 113 photos in the collection

were taken. As you zoom in, the space between the markers on the map increases. At

some point, you will be able to clearly distinguish between all of them, but at the default

zoom level there are a jumble of indistinguishable, overlapping icons.

Limitations notwithstanding, using Google Maps and KML in this way is useful in its

own right and a good demonstration of what's possible.

Section 11: Next Steps What could be done to improve on this script?

The next topic you should familiarize yourself with related to Google Earth is 'Regions',

which make it possible to efficiently work with very large datasets in Google Earth, even

when publishing data over a network.

Regions define areas in Google Earth in terms of a 'bounding box' and 'levels of detail'.

Page 34: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

The bounding box defines the northern, southern, eastern, and western boundaries of the

user's current view of the Google Earth map (and also possibly min and max altitude

values if appropriate, for example when working with 3D objects).

Level of detail describes the number of pixels the Region currently occupies on screen.

Keep in mind that even a large area (large in terms of coordinate boundaries) may occupy

only a small portion of the map at low zoom levels. Of course the reverse is also true, i.e.

very small geographic areas may fill a large portion of the display at the highest zoom

levels. Or we can say that at high zoom levels the resolution of the view is much greater

than it is at the lowest levels. As a result of this higher resolution, more markers can be

distinguished on the map but the field of view is decreased. At lower resolutions, adding

a lot of detail to the map, i.e. many Placemarks, only results in overlapping,

indistinguishable markers. Google Earth and your computer must work harder to display

these Placemarks. In the case of Network Links, all of this data must be transmitted over

relatively slow connections, significantly reducing the performance of the application and

detracting from the appeal of using Google Earth as a solution for sharing your photos.

This discussion may sound confusing the first time you read it. Suffice it to say that it

makes little sense to produce markers for photos on your map that are not visible to your

audience because they exist outside the current view or because they are obscured by

other markers. Regions solve these issues by ignoring data that is either outside of the

current bounds of the map, or indistinguishable because of the current resolution. While

we are dealing with only hundreds or thousands of images, this isn't necessarily a

significant concern. At the point when we are sharing tens of thousands of photos, or

perhaps hundreds of megabytes worth of data, Regions are critically important.

Because the use of Regions is not necessary given the scope of this project (hundreds of

photos) I'll not pursue this topic further. I can say that you will be able to incorporate

Regions into the rest of this project if you choose to do so. Nothing that we do here

precludes the use of Regions or complicates their use.

Note that we will be implementing a similar feature in Google Maps, because the issue of

inefficiency is a problem with far fewer markers. Google provides a 'marker manager'

that is similar in functionality to the Regions feature in Google Earth. Allowing the

application to ignore photos outside the current view and 'cluster' (i.e. reduce the number

of markers generated) in response to the resolution of the map at various zoom levels.

The discussion of the marker manager should help you with the concept of Regions.

Section 12: Conclusion We've finally come to the end of the Google Earth project, which is actually the first half

of a 2-part tutorial.

If you haven't looked at the source code yet, now is the time.

Page 35: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

If you followed along with the tutorial, the code will seem very familiar to you. Also, if

you have some questions after reading through the tutorial, the extensive comments in the

source should help. If you've successfully generated your KML files, congratulations! If

you're still working on it, and especially if you're having some trouble, I would encourage

you to keep at it. Maybe take a break and come back. It's always been surprising to me

just how much clearer a problem becomes after spending some time away from it doing

anything else.

In the second project, we look at building a Google Map from the KML files that we've

generated. In the process we'll cover the Google Maps API, Javascript, object models, the

DOM, and we'll talk a little bit about XHTML.

Page 36: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

Part 2: Google Maps

Section 1: Introduction to Part 2 When approaching any sufficiently high-level computing topic, it is often true that we

need to be familiar with a broad range of underlying and related concepts to establish the

foundation necessary to learn the new material. Virtually every technology not only

borrows from, but also builds on others. Furthermore, it is often the case with

programming projects that the bulk of the work comes at the beginning and involves

carefully thinking through the problem, devising a solution, and building those parts of

the project that we need to write before we can get to the code we want to write.

In the first part of the tutorial we wrote a Perl script which allows us to generate valid

KML files from collections of geotagged photos. Using our new tool, we generated a

number of files containing all of the data (about our photos) that we'll use to populate our

Google Maps. We also looked at the structure of KML, and covered a number of other

important topics, which are key to understanding the material presented here. If you have

not read part 1, do take the time at least to glance through it to confirm for yourself that

you won't have trouble following along with this discussion.

Now we turn our attention to Google Maps.

After this short introduction we'll handle the tutorial in 3 parts.

Part 1: This section discusses the document-object-model (DOM), which is a formal

methodology for negotiating XML files, like the KML files we created in part 1.

Part 2: Next we'll look at XHTML and the XHTML file we'll use to display our Google

Map. As you'll see, the file included with the project is no more than a shell, but it does

suffice to allow us to present our map. Furthermore, it affords us an opportunity to talk

about integrating XHTML, Javacript, and the Google Maps API. There are a few

important things we'll need to understand.

Working with a simple page will help us avoid complicating the issues unnecessarily and

will make it easy for you to relocate the map to a page of your own (maybe as part of a

weblog for example) with a minimum amount of fuss.

Part 3: Finally, we'll look at Javascript and the Google Maps API.

Before we get to all of that, there are a couple of preliminary topics to talk about:

Page 37: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

XML We've already looked at XML, describing it as an open, extensible markup language.

We've said that XML is a metalanguage which allows us to define other languages with

specific syntactic structures and vocabularies tailored to discrete problem domains.

Furthermore we've said that KML is one such XML-based language, engineered to

address the problem of describing geographical data and the positioning of geographical

placemarks and other features to display on a map, among other applications.

XHTML We haven't yet talked about XHTML which is a reimplementation of HTML as a

standard, XML-based format. HTML21

(Hypertext Markup Language) has served as the

preeminent language for authoring documents on the World Wide Web since the web's

inception in the late 1980s and early 1990s.

HTML is the markup language22

which makes hypertext23

linking between documents on

the web possible and defines the set of tags, i.e. elements and attributes, that indicate the

structure of a document using plain-text codes included alongside the content itself. Just

as the web was not the first hypertext system24

, HTML was not the first markup language,

though both have become extremely important.

Without delving too deeply into the primordial history of markup, HTML is a descendant

of SGML (Standard Generalized Markup Language) which is itself an offspring of GML

(Generalized Markup Language).

The Wikipedia entry for GML offers this description of the language:

GML frees document creators from specific document formatting concerns such as font

specification, line spacing, and page layout required by Script.

SCRIPT was an early text formatting language developed by IBM, and a precursor to

modern page description languages like Postscript and LaTeX, that describe the structure

21

HTML entry at Wikipedia: http://en.wikipedia.org/wiki/HTML 22

A markup language is any language that uses text codes or symbols alongside the content itself to specify the style and layout of the document. 23

A simple definition of hypertext from the The W3Cs what is Hypertext glossary of Hypertext terms: http://www.w3.org/WhatIs.html. The full list of terms is available at: http://www.w3.org/Terms.html. Note that this document is not a complete list of terms, nor does it necessarily reflect current usage. (Last updated 1995.). See the appendix for additional resources. 24

The History of Hypertext: http://ei.cs.vt.edu/~wwwbtb/book/chap1/htx_hist.html

Page 38: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

and appearance of documents. Not surprisingly the goal of GML is echoed in the intent of

HTML, though the two are far removed from each other.

Berners-Lee25

considered HTML to be an application of SGML from the very beginning,

but with a clear emphasis on simplicity and winnowing down much of the overhead that

had always characterized formal markup languages. In the early days, the web had to

struggle for acceptance. The birth of the web is a story of humble beginnings26

. The

significance of the web was by no means a forgone conclusion and early adoption

required that the markup syntax of the web be as accessible as possible. After all, more

stodgy languages already existed.

The simplicity of HTML certainly contributed to the success of the web (among many

other factors), but it also meant that the standard was lacking in key areas. As the web

gained wider appeal there was a tendency to take advantage of the early permissiveness

of the standard. Developers of mainstream web browsers exacerbated the problem

significantly by tolerating noncompliant documents and encouraging the use of

proprietary tags in defiance of efforts on the part of standards organizations to reign in

the syntax of the language.

In the short term, this was a confusing situation for everyone and led to incompatibilities

and erratic behavior among an ever increasing multitude of documents on the web and

the various web browsers available, which differed in their support for, and interpretation

of, what were in essence emerging 'dialects' of HTML. These web browsers not only

differed from one another, but also frequently from one version to the next of the same

application.

There was a real need to establish stability in the language. Lack of dependable syntax

meant that the job of building a parser capable of adequately adhering to the standards,

and at the same time accommodating various abuses of the standard, had become an

exercise in futility. Unlike HTML, XHTML must strictly adhere to the XML standard,

which means that any compliant XML parser can negotiate properly formatted

documents with relative ease. This reliability paves the way for a more efficient and

sophisticated web, resulting in not only more consistent rendering of content, but the

development of software that is able to differentiate and act on content based on context,

and relationships among data. This is one of the primary advantages of XML, as has

already been discussed, and this is a key advantage of XHTML as well.

Berners-Lee, who currently serves as the director of the World Wide Web Consortium

(W3C)27

and a senior researcher at MIT's Computer Science and Artificial Intelligence

25

Sir. Tim Berners Lee who is considered the father of the web and currently serves as the director of the World Wide Web Consortium (W3C) 26

The World Wide Web: A very short personal history: http://www.w3.org/People/Berners-Lee/ShortHistory 27

World Wide Web Consortium: http://www.w3.org/

Page 39: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

Laboratory (CSAIL)28

, continues to actively pursue the vision of a Semantic Web29

. That

is, a web that can be mined as a rich repository of data by intelligent software agents,

which not only present information, perform basic pattern matching, and the like, but are

capable of analysing information (in a truer sense - keep this or get rid of it?).

From the W3C's Semantic Web Roadmap we have this brief introduction to the concept:

The Web was designed as an information space, with the goal that it should be useful not

only for human-human communication, but also that machines would be able to

participate and help. One of the major obstacles to this has been the fact that most

information on the Web is designed for human consumption, and even if it was derived

from a database with well defined meanings (in at least some terms) for its columns, that

the structure of the data is not evident to a robot browsing the web. Leaving aside the

artificial intelligence problem of training machines to behave like people, the Semantic

Web approach instead develops languages for expressing information in a machine

processable form.

Whether this vision accurately predicts the future of the web remains to be seen. At the

moment the Semantic Web is a veritable stew of protocols, frameworks, concepts,

extensions, namespaces, vocabularies, schema, ontologies, and other components. It is

the subject of much debate, virtually all of it far beyond the scope of this tutorial. But this

'brave new web' is not purely academic.

The increased emphasis on standards-compliant markup has resulted in developers of

web browsers and content creation tools steering their apps toward the standards. This in

turn motivates authors to produce compliant documents. In fact the Strict variations of

XHTML do not allow for deviation from the standards. Two immediate benefits of this

work, whether or not it ultimately leads to some future web, are (1) more consistent

document rendering across platforms among mainstream web browsers, (2) and the

emergence of the Document Object Model (DOM). We'll look at the DOM shortly.

Section 2: Object Models and the DOM An object model is a collection of objects and the typically hierarchical, often complex,

relationships among them, where the most generic definition of an object is simply a

'thing'. Object models are all around us and are not limited to programming or the broader

topic of computing for that matter. If, for example, you were to describe a car in terms of

its object model:

28

MIT Computer Science and Artificial Intelligence Laboratory: http://www.csail.mit.edu/index.php 29

W3C Semantic Web Activity: http://www.w3.org/2001/sw/

Page 40: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

You might start by talking about the chassis, or base frame, and then go on to describe

the body of the car, its wheels, axles, exhaust system, the drivetrain, etc.; everything that

is directly attached to the frame.

For each of these you could describe various attributes and elements of that object; for

e.g. the body material is an attribute of the body object. The elements may in fact be other

objects that collectively comprise those objects within which they are contained.

The body of the car contains the engine compartment, passenger compartment, and trunk

elements. The engine compartment includes the engine which is itself a collection of

smaller objects. The passenger compartment can be described as the collection of front

and rear compartment objects, where the front compartment object includes at least a

driver side compartment with a steering wheel, instrument panel, etc. These objects have

their own attributes and elements perhaps consisting of other objects each of which is an

object itself, with a more specific function than the objects in which they are contained.

If you've ever put together a toy model of a car you may remember seeing an exploded

schematic diagram of the completed model which clearly shows all of the objects from

the largest container elements to the smallest ties, screws and other fasteners that hold all

of the pieces together. This is a nice way to visualize the object model of the toy car.

Of course the object model I have described is only an informal example. It may be fair

to dispute the model I've sketched here. As long as you have a better general

understanding of what an object model is then this example has served its purpose.

Object models are very common within the realms of computer technology, information

technology, programming languages, and formal notation.

The Document Object Model The Document Object Model (DOM)

30 is a standard object model for describing,

accessing and manipulating HTML documents and XML-based formats. The often

quoted description of the DOM from the W3C's site dedicated to the specification is:

The Document Object Model is a platform- and language-neutral interface that will allow

programs and scripts to dynamically access and update the content, structure and style of

documents. The document can be further processed and the results of that processing can

be incorporated back into the presented page.

Remember that XHTML is a special case of XML (i.e. it is an XML based format) and

essentially no more than a formalization of HTML. Because it is an XML based format

the XML DOM applies. Furthermore, because XHTML describes a single format with a

number of required structural elements and only a limited collection of allowable

30

W3C Document Object Model: http://www.w3.org/DOM/

Page 41: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

elements and attributes, the HTML DOM has a number of unique objects and methods

for acting on those objects that are not available in the more generic XML DOM. Having

said that, I want to emphasize the the two are more alike than the are different.

Technically we will look at the XML DOM here but nearly everything discussed is

applicable to the HTML DOM as well. Though there are differences, some of which we'll

encounter later in this tutorial, as an introduction it is appropriate to limit ourselves to

fundamental concepts, which the two share in common. We need both. We'll rely on the

XML DOM to parse the KML files we generated in part one of the tutorial to populate

our Google Map, and the HTML DOM to add the map to our webpage. By the time we've

completed this part of the tutorial hopefully you will appreciate just how integral the

DOM is for modern web design and development, though we'll only have skimmed the

surface of it.

The concept of the DOM is actually quite easily understood. It will seem intuitive to

anyone who has ever dealt with tree structures (from filesystem hierarchies to family

trees). Even if you haven't had any experience with this sort of data structure, you should

anticipate being able to pick it up quickly.

Under the Document Object Model individual components of the structure are referred to

as nodes. Elements, attributes and the text contained within elements are all nodes.

The DOM represents an XML document as an inverted tree with a root node at the top.

As far as the structure of an actual XML document is concerned, the root is the element

that contains all others. In every structure all other nodes are contained within a

document node. In the KML files we've generated the Document element is the root

element.

Every other node is a descendent of Document. We can express the reciprocal

relationship by stating that Document is an ancestor of every element other than itself.

Relationships among nodes of the document are described in familial terms. Direct

descendants are called child nodes or simply children of the their immediate ancestor,

referred to as a parent.

In our KML files, <Folder> is the only child of <Document>. (It would be just as correct

to say that <Document> is the parent node of <Folder>.) Note that there could be more

than one Folder node. We could use additional folders to group Placemarks (a) by year,

with one folder per year, (b) by event, with each folder dedicated to a single event, or (3)

by image gallery so that each folder corresponds to a discrete image gallery, or maybe

some combination of these and other criteria. Furthermore, we can have more than one

type of child node under a single parent. For example Placemark is the parent node of

<name>, <Snippet>, <description> and <Point> in our files. These nodes can all be

described as siblings, because they all have the same parent. Also, notice that

<coordinates> is a child of <Point>, and a grandchild (not a child) of Placemark.

Page 42: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

We can make a couple of other useful observations about this structure:

1. Every node other than the root has exactly one parent.

2. Parents may have any number of children including zero, though a node

without any children won't be referred to as a parent. (A node with no

children is called a leaf.)

Implicitly there are other familial relationships among nodes. For example, elements with

parents that are siblings could be thought of as 'cousins' I suppose, but it is unusual to see

these relationships named or otherwise acknowledged.

There is one important subtlety. Text is always stored in a text node and never directly in

some other element node. For example, the description elements in our KML files

contain either plain text or html descriptions of associated Placemarks. This text is not

contained directly in the description node. Instead the description node contains unseen

text node which contains the descriptive text. So the text is a grandchild of the description

node, and a child of a text node, which is the direct descendent of description. Make sure

that you understand this before continuing.

Because of the inherent structure of XML, we can unambiguously navigate a document

without knowing anything else about it, except that it validates. We can move around the

tree without being able to name the nodes before we begin. Starting at the root document

node, we can traverse that node's children, move laterally among siblings, travel more

deeply from parent to child, and then work our way back up the tree negotiating parent

relationships. We haven't yet described how we move among siblings.

The DOM allows us to treat siblings as a list of nodes, and take advantage of the

relationships that exist among elements in any list. Specifically, we can refer to the first

(firstChild) and last (lastChild) nodes to position ourselves in the list. Once we are at

some location in the list, we can refer to the previous (previousSibling) and next

(nextSibling) nodes to navigate among siblings. Programmatically we can use the DOM

to treat siblings in a XML data structure as we would any other list. For example, we can

loop through sibling nodes working on each node in turn.

Keep in mind that we are using generic terminology, not referring to specific node names

and we are relying only on the structure of XML which we know must be dependable if

the document adheres to the standard. This will work well for our KML files, and it is

certainly not limited to KML.

There are primarily two techniques we can use to find and manipulate elements in our

XML structure using the DOM.

1. Node Properties

Firstly, we can take advantage of relationships among element nodes as we

have been discussing.

Page 43: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

A number of node properties, some of which have already been mentioned,

allow us to move between nodes in the structure. These include:

firstChild,

lastChild,

previousSibling,

nextSibling,

parentNode

If we look at a fragment of KML, similar to the KML files generated in part

1 of the tutorial, starting at the Placemark element...

<Placemark>

<name>value</name>

<Snippet maxLines="1">

value

</Snippet>

<description><![CDATA[value]]></description>

<Point>

<coordinates>value</coordinates>

</Point>

</Placemark>

...we see a number of these properties:

a. <name> is the firstChild of <Placemark>

b. <Point> is the lastChild of <Placemark>

c. The nextSibling of <name> is <Snippet>

d. The previousSibling of <Point> is <description>

e. <Placemark> is the parentNode of <name>, <Snippet>, <description>, and

<Point>

2. getElementsByTagName()

Secondly, we can use the method getElementsByTagName() to find any

element regardless of the document structure.

For example, using the syntax...

getElementsByTagName("name")

...we can retrieve all <name> elements as a nodeList from the document

which are descendants of the element we are using when we call the

method.

The following Javascript statement returns a list of all <name> elements in

the document and stores that list at the variable list_of_nodes.

var list_of_nodes = getElementsByTagName("name");

Page 44: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

What is a node list?

A node list (NodeList) is an object representing an ordered list of nodes, where each node

represents an element in the XML document. The order of the NodeList is the same as

the order of the elements in the document. Elements at the top of the document appear

first in the list, and the first element returned, i.e. the first position in the list, is numbered

0.

Keep in mind that the list includes all <name> elements. If you look at the KML files

we've generated you may notice that both <Folder> and <Placemark> elements contain

<name>. We need to be aware that getElementsByTagName("name") will return all of

these if we are starting at the document root. We can differentiate between these <name>

elements in a number of different ways. For example we can insist that the node is a child

of a Placemark node to exclude <name> elements that are the children of <Folder>

elements.

We need to be able to refer to various properties of these nodes if we are going to act on

them in any reasonable way. The XML DOM exposes several useful node properties incl:

nodeName, nodeValue, and nodeType.

nodeName: is (quite obviously) the name of the node. What might be less obvious is

precisely how the DOM defines nodeName.

The tag name is always the name of an element, e.g. 'Placemark' is the name

of the <Placemark> elements.

The attribute name is the nodeName of an attribute, e.g. the name of the

maxLines attribute of <Snippet> is 'maxLines'.

The name of any text node is always the string '#text'. e.g., the plain text or

html that we're using as our Placemark descriptions are each contained in a

text node, as has already been discussed, and the name of this text node is

'#text', and not the name of the element which surrounds the value in the

XML document.

The nodeName of the root document node is always the literal string

'#document'.

nodeValue: is what you might expect.

The value of text nodes is text itself. So the text node of one of our

Placemark <description> elements is all of the plain-text or html within the

description tags. Again, as far as the DOM is concerned the text is actually

contained within a text node which is a child of a description node.

The value of an attribute node is simply the attribute value. e.g.

maxLines="1" has a nodeValue of 1.

nodeValue is not defined for the document node and all element nodes.

Page 45: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

nodeType: is certainly not something you could guess.

A specific value is assigned to each of the available types (categories) of nodes. The

following is an incomplete list of common node types.

Element, type 1

Attribute, type 2

Text, type 3

Comment, type 8

Document, type 9

As I have already said, we will take advantage of the DOM to parse our KML files and

populate our Google Maps. Many of the ideas we've seen here will seem much more

concrete when we put them to use. Still, this has been a very brief look at an interesting

topic that is especially important to web developers and designers. I would recommend

that you pick up a book that does a good job of describing the document object model if

you are planning on doing any significant amount of that kind of work. This need not be

an intimidating topic, though I have found that the majority of books and articles do an

inadequate job with it. If you are only interested in following along with this tutorial then

this brief treatment of the DOM, the comments in the included source files, and the

javascript code itself should be sufficient for you to complete the project.

Section 3: XHTML The next topic we need to look at before moving on to the Javascript that will complete

the project is the XHTML page on which we will present our map. A very simple page

has been provided. It will be obvious from looking at the file that it is no more than a

shell; the basic framework necessary to present our map in a web page. I doubt that any

effort I put into building an elaborate XHTML page would accomplish more than

confusing the issues and detracting from the overall value of the tutorial. Absolutely no

one should be intimidated by the page nor should it take more than a moment to

understand it.

There are some noteworthy parts of the page you will want to pay attention to:

1. The page is compliant with the XHTML 1.0 Strict standard as written. It

could just as easily be XHTML 1.1, HTML 4.0.1 Transitional, or any other

specification. In the case of XHTML 1.1, all that would need to change is

the doctype declaration and MIME type:

Compare the two doctype declarations

XHTML 1.0 Strict

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"

"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

Page 46: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

XHTML 1.1

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"

"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

and the MIME types

XHTML 1.0 Strict

text/html

XHTML 1.1

application/xhtml+xml

I chose XHTML 1.0 Strict because it is an XML based format and closer to

HTML 4.01 than XHTML 1.1. Furthermore, you may need to reconfigure

your web server or change the extensions on your XHTML 1.1 files before

your server will deliver the proper MIME types. Again, this point is fairly

trivial considering how simple the page is. However, it does present an

opportunity to mention validation.

We've already discussed validating the KML files generated in the first part

of this tutorial. In that case we used the Feed Validator at

http://feedvalidator.org/ to confirm that our KML files were up to spec so

that we wouldn't run into trouble opening the files in Google Earth, or when

it came time to incorporate them into our Google Maps script.

Here we'll use the W3C's Markup Validation Service

(http://validator.w3.org/) to check our XHTML file. The procedure is

similar to what we did with KML validation though we're using a different

validation service against a different type of file.

(1) Simply visit the validator's page in your web browser, (2) type or paste

the complete URI to your map page at the text entry box labeled "Address:',

and (3) click the 'Check' button.

A valid page will result in the following message:

"This Page Is Valid XHTML 1.0 Strict!"

while an invalid page will produce the error message:

"This page is not Valid XHTML 1.0 Strict!"

Like the Feed Validator, the W3C validation service makes a distinction

between errors, which are failures of the page to comply with the standard

and must be corrected, and warnings, which are detected deviations from

what may be considered ideal. You should take these warnings under

advisement and correct as many as you are able to, unless you're

intentionally ignoring them for some good reason.

Page 47: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

Besides validating a page publicly available on the web by URI, you have

the option of uploading a local file, or even copying and pasting a full

document into a text entry box for validation, what the validator calls

'Validate by Direct Input'. There are some options you can use to affect the

behavior of the service. The default behavior should be fine, but using

options you can do things like:

temporarily override the automatically detected Document Type

group reported error messages by type

display the source of the page being validated with the results

fix problems with your page using the HTML Tidy library, which is

code that can correct common editing mistakes (for example it can

add closing tags, fix simple tag nesting issues, etc.) and apply a

consistent structural style to messily written pages

The validator is a valuable tool for all of us and I encourage you to make a

habit of using it, especially when designing your own pages, including

weblog templates or themes. Keep in mind that there is no such thing as a

personal publicly accessible web page. If your site is accessible on the web

then you have a responsibility to produce clean markup for your visitors and

the rest of the global community. If you're unmotivated by the argument that

you should validate because it's 'the right thing to do', then keep in mind that

invalid markup may effectively reduce the size of your audience and impact

your site's ranking with search engines. Furthermore, nonstandard markup is

ultimately more time-consuming and difficult to maintain, and is likely to

break in unpredictable ways.

This brings up a dirty little not-so-secret truth about some of the more

popular web services, which are becoming increasingly important these

days. Many very useful, slick-looking web services generate broken

markup. What can you do about it? Well, from a practical standpoint, don't

be too upset by this. The services wouldn't be popular if they weren't

functional. So, if you want to use one of them and it works for you and your

audience then I say go for it.

Of course, this is no excuse to produce invalid markup yourself. In fact, this

is yet another very practical reason to do everything you can to keep your

own code as compliant as possible. The problems you introduce that work

on their own may react badly and unpredictably with the problems you

inherit from others, which may also function correctly until they conflict

with your broken markup. These are likely to be very difficult issues to

diagnose and resolve, which is good reason to avoid them to begin with.

There is a well known quote from internet pioneer Jon Postel

(http://en.wikipedia.org/wiki/Jon_Postel) that applies here,

Page 48: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

"be conservative in what you do, be liberal in what you accept from others".

Of course, feel free to complain to whichever organization is responsible for

the web services you use that are fouling up your otherwise standards-

compliant site. Something along the lines of...

Thank you for the service you provide but please invest whatever resources

are necessary to clean up the code you're asking others to embed in their

sites

...is probably the right approach.

2. Notice the <script> tags in the header that we use to include our own

Javascript functions and the code necessary to interact with the Google

Maps API.

From the Google Maps API documentation:

The URL (http://maps.google.com/maps?file=api&v=2) is the location of

a JavaScript file that includes all of the symbols you need for placing

Google Maps on your pages. Your page must contain a script tag

pointing to that URL, using the key you got when you signed up for the

API. If your Maps API key were "abcdefg", then your script tag might

look like this:

<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=abcdefg"

type="text/javascript"></script>

It's not necessary that you understand these lines to use them, but they are

simple enough. The script tag references the location of Javascript code

hosted at maps.google.com (a specific server or more likely group of servers

in the google.com domain) that defines the various functions we'll use on

our page, and in our own Javascript code to produce and manipulate the

Google Map.

We provide some information to Google with our request. We need only

refer to the official documentation to learn about these and possibly other

available parameters.

From the documentation:

The v parameter within the http://maps.google.com/maps?file=api&v=2

URL refers to the version number of the Google Maps API to use. Most

users of the API will want to use the stable "Version 2" API by passing

the v=2 parameter within that URL. You may instead obtain the latest

release (including the latest features) by passing v=2.x instead. However,

Page 49: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

be aware that the latest release may not be as stable as the v=2 release.

We update the Google Maps API about every two weeks, at which point

features within the v=2.x release are migrated into the stable v=2 release

unless problems are discovered.

We have already identified the 'key' parameter which is required to

authorize the page against a valid Google Maps API key. Remember that

these keys are tied to a specific directory on your server. You must keep

your pages that contain code that references the API in the directory you

specified when you requested the key. It will not work with pages in

subdirectories.

You can request additional keys to serve pages from multiple directories or

in the case that you lose track of the key(s) you have already generated. You

do not need to request that unused or misplaced keys be revoked. In fact

there is no established procedure for doing this even if you wanted to.

There are of course terms of service governing the Google Maps API. In

most cases these terms won't interfere with what you want to do, but I'm

sure there are many legitimate uses of the API that do not meet the terms of

service for one reason or another. You will find all of the legal information

you need to know about the API on the 'Google Maps API - Sign Up' page

(http://www.google.com/apis/maps/signup.html), including the complete

Terms of Use and a link to a form for contacting Google if you are unsure

that your usage will meet their terms.

Concerning our own Javascript code, you will see the following script tag in

the XHTML file

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

which references an external file where we will create our Javascript code.

Notice that this is a relative link. The tag will work for you as written if you

keep the filename 'maps_tutorial.js', and if you place the file in the same

directory as your XHTML page. Of course you are free to use any filename

you like at any location by simply changing the value of the src attribute.

Any relative path will work, as will absolute paths from your web server's

document root and fully qualified URLs, e.g.

http://sample.net/maps_tutorial/maps_tutorial.js.

There are a few ways for us to include javascript on our XHTML pages.

Javascript can be included:

in the head section of the page,

Page 50: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

the body of the page,

in an external file referenced by the script tag's src attribute.

a. Javascript code written into the head section of a page is available

from anywhere on the page, but only on the page. Defined functions

are executed on request, either because they are explicitly called, or

triggered in response to an event.

b. Javascript written into the body of the page is executed as soon as the

page is loaded. You might include code this way to generate the

content of the page dynamically.

c. Javascript in an external file is available to possibly many

documents. For example, Google's Maps API is available globally to

anyone who requests an API key. This is a significant advantage of

creating external Javascript files but it is not the only one.

I've repeatedly said just how simple and blatantly obvious the included

XHTML file is. It's all of 30 lines long including all of the header info and

basic structural bits. On the other hand, the relatively simple Javascript file

accompanying the tutorial is hundreds of lines long (including comments).

The XHTML file would seem to be radically more complex, and

unnecessarily so, if we simply dumped all of the Javascript into the file.

This separation of structure (XHTML) from behavior (Javascript) is an

important tenet of modern web development. Unless you are doing

something highly unusual the Javascript code should exist in its own file(s)

referenced from your pages as we have done here.

Except where appropriate the other two techniques mentioned amount to no

more than bad habit which you should work to break or be careful to avoid

in the first place. Even with a page as simple as this, separating the structure

of the XHTML page from the behavior of the code makes it easier to

discuss each as discrete aspects of the project.

3. You will notice if you look at the body tag that two HTML events have

been specified along with behaviors (Javascript functions) triggered by the

events.

<body onload="setup_map()" onunload="GUnload()">

onload is a trigger that causes the associated script to execute when the page

is loaded. setup_map() is the name of one of the functions in our external

Javascript file. It is responsible for (a) working with the Google Maps API

to create a new map on our page (b) defining the custom icons we'll use to

represent markers on our map, (c) initiating the process of adding markers

Page 51: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

to the map by calling the other functions we'll define. As the name implies,

setup_map() is the function that gets the whole process of generating our

custom map started.

As you might guess, the behavior associated with the event onunload is

triggered when the visitor leaves the page. GUnload() is a function from the

Google Maps API that takes care of cleaning up the data structures created

by the API.

From the documentation:

function GUnload - You can call this function to cause the map API to

cleanup internal data structures to release memory. This helps you to

work around various browser bugs that cause memory leaks in web

applications. You should call this function in the unload event handler of

your page. After this function was called, the map objects that you've

created in this page will be dysfunctional.

As you can see from this description, we're doing the right thing by

associating GUnload with the onunload event.

We'll be dealing with the Google Maps API and taking a closer look at

setup_maps() later in the tutorial.

4. I'm including a basic stylesheet which does no more than center the map on

the page horizontally, and style the font used on the page. For the purposes

of this tutorial, you can either keep the CSS file as it is, make any

modifications you like, or even choose not to use it altogether.

If you do choose to forgo the stylesheet, just delete the included tutorial.css

file and remove the link tag from the head section of the XHTML file.

If you keep the file, notice that I've used a relative link. The style info will

be available to your XHTML page without making any changes as long as

you keep the filename 'tutorial.css' and place the file in the same directory

as your XHTML page. You are free to use any filename you like at any

location by simply changing the value of the src attribute. Any relative path

will work, as will absolute paths from your web server's document root, and

fully qualified URLs, e.g. http://sample.net/maps_tutorial/tutorial.css.

There is one bit of style information that I am purposefully keeping out of the

external stylesheet and instead including in the XHTML file as an inline style;

that is the height and width of the div which will contain our map.

From the Google Maps API Documentation:

Page 52: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

When you create a new map instance, you specify a named element in the page

(usually a div element) to contain the map. Unless you specify a size explicitly

for the map, the map uses the size of the container to determine its size.

I've left the size of the map div outside of the stylesheet to de-emphasize the the topic of

CSS as much as possible. This is not meant to imply that CSS is an unimportant topic. In

fact CSS is well worth your time and effort to learn. But, there are already quite a few

topics that we must cover to do a responsible job of introducing Google Maps as a

tutorial like this. CSS is not necessarily one of them, so I'm pushing it to the side in favor

of emphasizing other required topics. Of course, I am still using a style sheet for much

the same reasons I opted to use an external Javascript file. Separating presentation from

structure is as important as separating structure and behavior.. Unfortunately, a discussion

of CSS is beyond the scope of the article. Fortunately there are many good books and

other resources available on the topic.

Other than what has already been discussed, the XHTML file consists of a number of div

elements each named by an id attribute. For example:

<div id="map"></div>

Is the container for our map, as we have discussed.

The other divs specify locations on the page where we'll output status messages related to

the operation of our script.

For example:

After we request the photos.kml file from our server, so that we can include markers for

each of our photos on our map. The response code returned from our web server will be

written to

<div id="photos_kml_response"></div>

The other divs are target locations for response codes resulting from requests for the other

KML files we need to download, and some basic statistics, e.g. the number of markers

generated, etc.

The purpose of each of these divs should be obvious to you after looking through the

source for our Javascript code, which is responsible for writing these messages, and the

XHTML file itself. In fact you may be able to predict the purpose of each from the name

chosen for the id attributes. Alternatively, we could have included a single 'status' div for

all of these messages, but considering the simplicity of the XHTML file, I decided that

handling each in a separate div would be a more explicit way of structuring the file.

Typically, you would not expose this sort of 'debugging' message to your visitors. They

are useful only during development and then the code responsible for producing them

should be disabled in the Javascript and the divs removed from your XHTML pages.

Page 53: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

Section 4: A Note about Web Programming Why include these messages at all? Because it can be difficult to debug Javascript code.

This is true of all web based application development and network programming more

generally. There are a number of reasons that this is the case.

Firstly, the success or failure of our code is dependent on many factors that are out of our

control.

If you are connecting to a remote machine and that computer is

malfunctioning, then your code may fail to execute as expected.

Transient networking issues may cause significant problems even if the

machines and all of the code involved are behaving properly.

Network applications tend to get complicated quickly because the

requirement of network communication means that the applications depend

on many underlying network services (e.g. name resolution) and network

devices (routers, switches, other gateway devices, etc.). What's more,

because of increasing concerns about security, many of these devices are

intentionally designed to interfere with network communications. Of course

the idea is that this interference affects only unwanted or harmful apps but

practically speaking this is virtually impossible.

Compromises inherent in the design of the security mechanisms,

configuration errors, other mistakes introduced during development or

implementation, and the intentional actions of those agents who endeavor to

abuse the network all contribute to the sorts of problems you may encounter

when developing network applications.

Fortunately for us, our network application is particularly simple. Traffic

over HTTP between web client and server is almost universally allowed,

because the web is viewed as such a fundamentally important application.

Furthermore, our communications with Google are almost entirely mediated

by functions provided to us as part of the Maps API. Assuming we trust that

Google knows what they are doing, then we can hope to avoid many of the

problems that might otherwise affect client/server interactions. Of course,

Google can't guarantee the stability of the network and those network

services that are out of its control any better than we can. For example,

transient network issues may still disrupt our application. What's more, we

are responsible for understanding the API so that we can be sure that we are

using it correctly. We need to supply the various functions Google provides

with appropriate data in the correct formats, and we must be prepared for the

values returned. A well-designed API simplifies these interactions, but we

must do our part as well.

Page 54: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

Secondly, and this is more specifically an issue with Javascript and other web

programming, a web browser is extremely limited as a debugging environment. We must

do a lot of the heavy lifting to expose even the most basic information that will be useful

to us when it comes to identifying problems with our code. This is a particularly

annoying situation considering that the sorts of errors we may encounter are so varied and

difficult to predict, as has already been discussed.

Unfortunately the topic of debugging Javascript is well beyond the scope of this tutorial.

In fact, it deserves a substantial article of its own. So what can we do?

The single best piece of advice I can give is to use Firefox when you are working on the

Javascript portion of this project. Firefox includes an Error Console that will show you

warnings and errors encountered during the execution of this script. This basic

information will be incredibly useful to you if you find yourself staring at an empty

webpage where your map should be. You will find the 'Error Console' under the 'Tools'

menu.

While we're on the topic of debugging Javascript code, I want to point out that this is

another reason to use a very basic shell of an XHTML file before dumping your maps

into an existing page, e.g. an existing weblog theme. It very often is the case that your

existing webpages have a number of problems that will generate warnings or errors in the

Error Console. There is quite a bit of code involved when a Weblog engine generates a

page dynamically, especially considering all of the various extensions to the base script

that you have the opportunity to add. It would be a mistake to assume that all of this code

runs without throwing off a number of errors, even if the finished page displays perfectly

in your browser. These errors have nothing to do with your map of course, but will

nonetheless complicate the task of identifying and resolving problems you encounter

when building it.

A page as simple as the XHTML file included with this tutorial will not contribute any

errors or warnings to the messages you see in the Error Console. Once you have your

map working, it's a trivial task to move it to another page simply by copying and pasting

the script tags to your new page, and adding a 'map' div where you want the map to be

displayed.

If you want something more than the Error Console, take a look at the Venkman

Javascript Debugger (http://www.mozilla.org/projects/venkman/) which is available as an

add-on for Firefox and other Mozilla-based browsers.

From the Introduction on the Venkman project page:

Venkman is the code name for Mozilla's JavaScript Debugger. Venkman aims

to provide a powerful JavaScript debugging environment for Mozilla based

browsers namely Firefox 2.x, the Netscape 7.x series of browsers, Netscape 9.x

series, Mozilla Seamonkey 1.x and Mozilla Seamonkey 2.x.

Page 55: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

Having discussed all of the preliminary topics, we can succinctly describe how to write

the Javascript code that will generate our map. Following the pattern established in the

first part of the tutorial we'll do this in 3 passes.

Section 5: An Introduction to the Code We'll begin with a high level, natural language discussion that faithfully describes the

code.

The second and third passes can be found in the source file itself, accompanying this

tutorial. What I'm referring to as a second pass are the detailed comments you will find

throughout the source. Pass 3 is the code itself.

After reading through the discussion here I recommend that you read through the source

file. Not only will this help familiarize you with the code but it will give you the

opportunity to make any changes necessary so that the code meets your needs. You'll find

the complete source code for the javascript portion of this tutorial in the file

'maps_tutorial.js'.

This discussion will frequently refer to the official Google Maps documentation pages

and version two of the API Reference. The documentation is well written and fairly easy

to understand. After you have finished with this tutorial you will want to remember to

spend some time reviewing the API reference. You will no doubt find answers to many of

your questions and discover new ways of doing things. Where the descriptions presented

in the reference are clearly written (and relevant of course) I will quote them here rather

than complicating the issue with my own clumsy explanations.

I'll take this opportunity to say that this is not intended to be an introduction to the

Javascript language. I will be careful to describe the execution of the script, i.e. how it

operates even when it may seem obvious to those of you who have some programming

experience. This is done intentionally to make the code as accessible as possible. Those

of you who find this discussion too chatty are welcome to move on directly to the source

code. I will not be spending any significant amount of time on the syntax of Javascript.

There are any number of good introductory Javascript books and other resources

available. It shouldn't take you much time at all to pick up enough of the syntax to follow

along with the rest of the tutorial, especially given that a completely functional script is

available for you to download, use and modify. I'm hopeful that even those of you who

have had little to no exposure to Javascript before now will be able to copy, paste and

reason your way through the script well enough to get your Google Map up and running.

Page 56: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

Section 6: Natural language walk-through The first function definition we see is setup_map(). You may remember from the the

discussion about the XHTML page above that setup_map() is attached to the onload

event on our page. Accordingly, this function is called when the page is loaded.

First, we check that the browser is compatible with the Google Maps API using the

function GBrowserIsCompatible().

From the API Reference:

This function decides whether the maps API can be used in the current browser.

If the browser is compatible then we continue, or else we return having done nothing.

You may want to handle the case that the browser is incompatible with the API by

writing a helpful message to the page. Alternatively, you could do something more

complicated, but certainly you won't be generating a map so the best way to handle this

may be a simple message that is informative without wasting your visitors' time or

causing some unexpected behavior.

Assuming the browser is compatible we generate a map by creating an instance of the

class GMap2. The class defines a Google Map, and we can request an instance of that

class with a single statement:

map = new GMap2(document.getElementById("map_container"));

From the API Reference:

class GMap2 - Instantiate class GMap2 in order to create a map. This is the

central class in the API. Everything else is auxiliary.

Creates a new map inside of the given HTML container, which is typically a DIV

element. If no set of map types is given in the optional argument opts.mapTypes, the

default set G_DEFAULT_MAP_TYPES is used. If no size is given in the optional

argument opts.size, then the size of the container is used. If opts.size is given, then the

container element of the map is resized accordingly. See class GMapOptions.

You can safely ignore the discussion of optional arguments. In the absence of these

options sensible defaults will be used.

From the statement above:

map, which is the target of the assignment, is a variable which going forward will be a

reference to the map object created with this statement. We will manipulate this object

throughout the execution of the script to modify the map that appears on the page.

Page 57: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

There is also "map_container", which is the structural element of the page that will

contain our map. We saw this div when we looked at our XHTML file.

Note the use of the HTML DOM in the statement. Though our use of the XML DOM

with the KML files containing our Placemark data will be a little more extensive, what

we do with the HTML DOM will not be much more complicated than what we see here.

We have already discussed the method getElementsByTagName() when we looked at the

XML DOM. getElementById() is similar. We simply pass the method the unique name of

one of the id attributes included on the page to target the named container. Because all id

names are unique we can ignore the nested structure of the document and relationship

among elements when using getElementById. Technically the method returns a reference

to the first object with the named id, but there should be only one.

In the HTML DOM, the document object represents the entire page. So,

document.getElementById("map")

returns a reference to the first container with the id "map" anywhere on the page.

Adding standard controls to our map is just as easy thanks to the API.

map.addControl(new GLargeMapControl());

This statement adds the built-in large pan and zoom control. This the standard control

which typically appears along the left side of a Google Map and allows the user to select

the zoom level of the map either by incrementally increasing or decreasing the level or

jumping directly to the desired resolution utilizing a slider. The control also allows

visitors to pan the map in any direction.

The statement instructs the API to create a new GLargeMapControl() object and then add

the control to our map object.

Alternatively we could have opted for the equally common smaller control with the

statement,

map.addControl(new GSmallMapControl());

which offers much the same functionality but lacks the slider. The advantage is that the

control takes up significantly less space. This may be especially important for smaller

maps. The choice is yours.

Next we'll add a type control which allows visitors to switch between the three primary

map views, 'Map', 'Satellite', and 'Hybrid':

map.addControl(new GMapTypeControl());

This is functionality that most users appreciate and it does seem appropriate for our map

of photos. Map view is often the least cluttered of the three, and so the least distracting,

and the easiest to navigate. Satellite view on the other hand may help users better

understand the context of our photos. Hybrid view combines the two so that we can have

Page 58: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

the satellite imagery but still find our way around the map with street names and other

important indicators.

It is possible to implement your own controls by taking advantage of several classes

Google makes available via the API for enabling and disabling standard overlay

information and toggling between map types. You may have a good reason for doing this,

and if so I don't want to discourage you. I do want to say however, that unless you have

cause to do something else, keeping the standard controls is recommended. Chances are

good that your visitors will be familiar with the standard controls and replacing them just

for the sake of being different is unnecessarily disorienting for users. Interface

consistency should be one of the primary goals of any developer. Keep in mind that your

map is essentially an instance of the Google Maps application. The more consistent we

all are, the more comfortable our visitors will be with our collective maps.

We've created a map (an instance of the GMap2 class), specified where to place the map

on the page, and we've added some controls. Before we can expect the Google API to be

able to generate a map, we need to tell it what to display, i.e. what location to show us.

We do this by setting the center point of the map and defining an initial zoom level.

Taken together, a center point, zoom level, and the size of the map (determined by the

height and width attributes of the 'map' div on our XHTML page), completely defines the

map that we see. A better way to think about an interactive Google Map might be to

imagine it as a dynamic window offering a view of a potentially much larger map of the

world. We can change the resolution of that view by adjusting the zoom level, or adjust

our vantage point by panning our view of the map.

The API provides the function setCenter() to set the position of the map.

From the reference:

setCenter

Sets the map view to the given center. Optionally, also sets zoom level and map

type. The map type must be known to the map. See the constructor, and the

method addMapType(). This method must be called first after construction to

set the initial state of the map. It is an error to call other operations on the map

after construction.

Do not overlook this line from that description:

This method must be called first after construction to set the initial state of the map.

map.setCenter(initial_center, initial_zoom);

This statement, from setup_map() sets the center of our map object.

setCenter must be provided a point and a zoom level. Technically the zoom level is

optional, but it's one of those optional arguments that you will specify most of the time.

Page 59: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

Generally a point is a coordinate pair, i.e. standard latitude and longitude values. When

working with the Google Maps API, a coordinate pair is represented by a GLatLng

object.

From the API reference:

class GLatLng

GLatLng is a point in geographical coordinates longitude and latitude.

Notice that although usual map projections associate longitude with the x-coordinate of

the map, and latitude with the y-coordinate, the latitude cooridnate is always written first,

followed by the longitude, as it is custom in cartography.

Notice also that you cannot modify the coordinates of a GLatLng. If you want to compute

another point, you have to create a new one.

When working with GLatLng objects be very careful about the order of the values in the

pair. The reference tells us that the latitude must always be written first. Also notice that

the latitude and longitude must be specified in decimal degrees, as opposed to degrees,

minutes, and seconds. We have already taken care of converting the coordinate metadata

from our photos to the proper format in the first part of the project.

The second argument in the call to setCenter above is the zoom level. Google Maps

allows for a range of zoom levels. The higher the integer value the greater the amount of

detail (the higher the resolution) of the map. Of course higher resolution comes at the

expense of field of view. In other words, as we make the map larger, we get a more

detailed image of a smaller area. This correctly implies that smaller zoom level values

(lower integer values) present a wider field of view (more of the Earth is visible on the

map) but less detail (any specific area is smaller in terms of the number of pixels it

occupies).

The smallest zoom level available is 0, which displays a map of the entire world.

At a zoom level of 4 we can fit all of (Western) Europe on a map roughly 800px wide by

500px tall:

http://maps.google.com/?ie=UTF8&ll=47.279229,21.884766&spn=30.453577,72.246094&z=4&om=1

Increasing the zoom level to 6, adjusts the resolution such that France occupies nearly the

entire map:

http://maps.google.com/?ie=UTF8&om=1&ll=46.800059,4.130859&spn=7.671813,18.061523&z=6

and at 12 we have a map just larger than the city of Paris in France:

http://maps.google.com/?ie=UTF8&om=1&ll=48.856358,2.350731&spn=0.115203,0.282211&z=12

Page 60: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

There is one issue about zoom level that we want to be careful to remember. Though 0

consistently represents the low end of the scale, always producing a very wide world

map, the high end is less reliable. In an urban area, for example the city of Paris, high

zoom levels are likely to be useful because at this level we can clearly distinguish

between individual streets, and even buildings and landmarks, like this satellite map of

the Eiffel Tower in Paris at zoom level 17.

http://maps.google.com/maps?f=q&hl=en&geocode=&q=&ie=UTF8&ll=48.858278,2.294705&spn=0.0036,0.008819&t=k&z=17&om=1

On the other hand, there are many areas of the planet where high zoom levels will result

in a map displaying nothing of any interest. This issue is especially problematic with

Satellite maps. The satellite imagery available via Google Maps is fairly inconsistent and

somewhat unpredictable at high zoom levels. The problem is that Google simply does not

have high resolution satellite imagery covering the entire planet. Where no images exist

instead of a map you will see the message 'We are sorry, but we don't have imagery at

this zoom level for this region'.

Your only choice is to move to a different region, or reduce the zoom level until you

reach a point where a lower resolution image is available. We need to be aware of these

issues when working with Google Maps or our visitors may find themselves staring at a

broken looking page.

In some cases, adding a feature to our map is as simple as invoking a function from the

API with a single statement, as is the case with the next line from our setup_map

function.

map.enableDoubleClickZoom();

This does what you might guess from the name. With this statement included among our

Javascript code double clicking on the map will increase the zoom by one integer level,

while centering the map on the position clicked. Holding the Control key while double-

clicking will decrease the zoom level. Without this statement, double-clicking the map

centers the map without affecting the zoom level. This feature is disabled for all maps by

default in the API, so if you would rather disable the 'double click zoom' feature, simply

comment out this line in the source file or remove it entirely.

At this point we've defined our initial map. It is complete except that there are no

markers. There are no icons indicating the location of the markers, no info windows with

descriptive text, thumbnails, and links to our photo gallery attached to the non-existent

markers. In fact there is nothing linking our photos to the map whatsoever. This is no

small omission. We had better get started on customizing our rather generic map.

Still in the setup_map function, we define all of the custom icons we'll use in our project.

Icons (GIcon) are very visible components on the map.

Icons are the symbols that represent markers at a particular point on the map but you

should think of the marker (GMarker) as the primary object. It is this object which will

Page 61: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

represent each of our photos. The marker includes an icon (GIcon) described above, a

point (GPoint) which describes where to place the marker, and optionally an info window

(GInfoWindow) which is an area of content containing descriptive information about the

marker displayed when it is clicked. It is not uncommon for people to confuse points and

markers either because they do not understand the distinction or because of simple

carelessness, but the two are not interchangeable. We'll discuss markers later. Here we're

defining the icons we'll use so that later we can refer to them by name.

Icons are a required component of markers but it is not necessary to create custom icons.

If we don't supply a custom icon then Google Maps will use a default.

Why then go through the bother of creating custom icons at all? There is no single answer

to that question. In fact it's perfectly acceptable to decide to use the defaults. Someone at

Google has taken the time to design icons that work quite well, and it would be a mistake

to waste your time and effort creating icons that aren't as nice. But there are a number of

common reasons why you might want to consider creating your own, and why I have

decided to include custom icons with this project.

Branding and identification of markers as belonging to a specific application

or set.

It's possible for a Google map to include not only your markers but also

markers from Google (e.g. search results), and even third party applications.

The term 'Mashup' has been coined to describe an application that combines

data from multiple sources to create what is in some sense a completely new

application. Mashups can be much more than the sum of their collected data

sources. Custom icons allow users to distinguish markers related to your data

from all of the others.

Custom markers can communicate more information than the default icon.

Using a default icon tells a visitor where a marker is located but not much

else. With custom icons you can vary the size, color, and even create a

number of entirely different icon styles to indicate that the icons represent

different categories of data or to communicate information about the status of

a marker. For example a weather application may use several different icons

to represent possible weather conditions, e.g. the weather for a particular

location may be sunny, raining, overcast, warm, cold, or even a combination

of these conditions, maybe sunny but cold. The developer may choose to

vary the size of the icons to indicate the severity or intensity of the weather

pattern. For example, an icon depicting a rain cloud might be enlarged to

indicate a storm and reduced in size to indicate a light rain. The same

weather map may use red colored icons to immediately warn users of

dangerous conditions.

Page 62: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

Size of icons influences visibility of markers on the map.

While large icons may be more noticeable, and small icons more likely to

blend into the background detail if there is not a lot of contrast between the

map and the icon, it is possible to fit more small icons than large in a given

area and resolution without overlap.

Icons which indicate general regions vs icons which mark a specific point on

the map.

Frequently icons may be used to indicate either a region of the map or a

specific place. Icons that represent a precise location should clearly indicate

that by attaching to the map at a specific point. It's less useful, maybe even

inappropriate, for an icon designating a region to appear to indicate a specific

location. We can make regional icons to resemble 'badges' which appear to

float over the map, while point specific icons can be made with lines, tails or

arrows that appear to extend down to the point of attachment, in much the

same way as Google's default icons.

Aesthetic sensibility.

Of all of these common reasons for using custom icons, this is the hardest to

justify. You may choose to use custom icons because you consider Google's

default icons ugly. That's fair enough, certainly taste is subjective. The

problem with this argument is that it is difficult to completely banish

Google's icons from your maps, even if you do choose to use custom icons

for your markers.

I've chosen to use several different custom icons for all of the reasons just discussed,

except for aesthetic sensibility. I like Google's default icon and wouldn't create a custom

icon, something that requires a nontrivial amount of time and effort, just to be different.

Let's briefly discuss the rationale for the icons we'll be using before we get to the

business of the code for creating the icons.

First, let's quickly review the concept of clustering. We've described what clustering is

and its advantages. Because the topic has already been discussed I'll just remind you that

clustering is a way of replacing multiple markers with one representing the group when

the resolution of the map (i.e. the zoom level) and the proximity of the markers would

result in overlap such that it would not be possible to distinguish any one from the others.

Let's say that at every possible zoom level we want to guide visitors toward our photos.

At the lowest zoom levels a visitor will be looking at large geographical areas condensed

within a small amount of space in terms of display size. Entire countries are reduced to

Page 63: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

the size of a small number of pixels. At these levels even just two markers representing

photos taken literally thousands of miles away from each other may overlap. A typical

collection of photos may include hundreds of photos or more with large groupings of

them appearing in the same relatively small geographical areas. For example, the

majority of the photos included in the gallery accompanying this tutorial were taken in

and around Boston, Massachusetts, USA. It would be ineffective to display markers for

these photos at many of the lowest zoom levels. Instead we'll create an icon to indicate

areas on the map where photos are available at higher zoom levels. By displaying

markers attached to regions appropriate for the current zoom level of the map, we avoid

the issue of overlapping markers and the performance issues that would result from trying

to display a world's worth of photos in a single view. The details of how to do this are

discussed in the comments included with the source code.

The first type of icon we want to create is a regional icon. Depending on the zoom level

we will draw a marker with this icon centered on a country, state/province, or city, where

we have at least one photo in our collection. You may remember that we created a KML

file matching each of these regions. We will rely on these KML files to create our

regional markers. For example for the lowest few zoom levels, let's say levels 0 - 2, we

can distinguish between countries but not smaller regions. At these zoom levels our

regional icons will indicate countries where we have at least one photo. At higher zoom

levels the same icons will be used with markers to indicate states and then, as the level

increases, eventually cities where we have photos to display on the map.

At intermediate zoom levels the resolution is such that there is a reasonable amount of

separation between small geographical areas so that we can add markers for individual

photos and expect that many of the icons will be visible without overlap and, for any one

view, we will not have so many markers that we overwhelm the map. It may be true that

we have thousands of photos but many of the corresponding markers will fall outside the

bounds of the view. However, at these levels it may be that we have a number of images

appearing in the same small area of the map. In this case we include only a single marker

for one of the images, and use an icon to not only indicate the location of a specific

photo, but also to let visitors know that there are additional icons which are currently

obstructed by this one.

Where we can clearly distinguish between the icons for all of our markers, we will use a

third custom icon that simply indicates the location of a particular photo. At the highest

zoom levels this is the icon we will use for all of our markers.

Though we have described only three distinct styles we need to define one more type. So

that we can include markers for as many photos as possible at intermediate zoom levels,

we will need two differently sized icons—one for the highest zoom levels and a smaller

one for intermediate levels.

Now we can discuss how we will create these icon styles. This is only intended to be an

overview, for the full details please refer to the Javascript file accompanying this tutorial.

Page 64: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

From the API reference:

class GIcon

An icon specifies the images used to display a GMarker on the map. For

browser compatibility reasons, specifying an icon is actually quite complex.

Note that you can use the default Maps icon G_DEFAULT_ICON if you don't

want to specify your own.

There are quite a few properties to consider when it comes to creating a new icon. All of

these properties are not required and in fact we do not use all of them in the tutorial.

Refer to the API Reference for the full details. We will limit ourselves to the following

list of properties: image, shadow, iconSize, iconAnchor, and infoWindowAnchor.

To create a custom icon we create a new instance of the GIcon class

icon = new GIcon();

The image property specifies a URL referencing a file used as the foreground image.

photo_icon_large_image = "http://robreed.net/maps_tutorial/images/photo_icon_large.png";

The shadow property specifies a URL referencing a file used as a shadow image for this

icon. The shadow image should be based on the foreground image of course. I'll have

more to say about the shadow at the end of the list of properties.

photo_icon_large_shadow = "http://robreed.net/maps_tutorial/images/photo_shadow_large.png";

iconSize is the size in pixels of the foreground image, listed as (width, height)

photo_large.iconSize = new GSize(32, 34);

shadowSize is the size in pixels of the shadow image, also listed as (width, height)

photo_large.shadowSize = new GSize(56, 32);

iconAnchor is:

The pixel coordinate relative to the top left corner of the image at which this icon is

anchored to the map. (This description is taken from the API reference)

icon.iconAnchor = new GPoint(6, 20);

infoWindowAnchor is:

The pixel coordinate relative to the top left corner of the image at which the info window

is anchored to the icon. (This description is taken from the API reference)

icon.infoWindowAnchor = new GPoint(5, 1);

We create a new instance of the GIcon class and define all of these properties for each of

the following custom icon styles.

Page 65: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

regional_icon = new GIcon();

photo_large = new GIcon();

photo_small = new GIcon();

photo_bunch = new GIcon();

Before we move on, a couple of notes about the icon foreground and shadow images.

The foreground image should be of reasonable size. Google's own default image is

approx 32px high by 20 pixels wide. We've already discussed the tradeoffs involved in

creating larger versus smaller icons.

The shadow image is derived from the foreground image. Using an image editing

application of your choice (I used Adobe's Photoshop), the steps are as follows:

a. Copy the foreground image to a new file.

b. Fill the shape of the object so that it's black. The icons included in the

project started out as Adobe Illustrator files, which I opened in Photoshop.

Once in Photoshop I could select the object and set the fill and outline

colors to black. If you have another type of image you may need to use a

selection tool to grab the shape and set the fill that way.

c. Shear the shape at a 45 degree angle. (Note that shearing is not the same as

rotating. Shearing the image essentially stretches it at the specified angle

rather than turning it around a fixed point. It's the shearing effect that gives

it the look of a shadow.)

d. Scale the image to half its original height without adjusting the width.

(Don't do a proportional scale.)

e. Blur the image. In Photoshop this means applying a blur filter. Whatever is

identified in your application as a standard blur should work fine.

f. Finally, adjust the opacity of the image to lighten it a bit.

g. Save the image as a transparent png.

After defining all of the icons, we're essentially finished setting up the map itself. The last

statement of the setup_map() function calls setup_markers() which controls the rest of the

execution of the script. In setup_markers() we do the following:

1. Download from the server the KML files generated in the first part of the

tutorial which contain all of the data about our photos. To do this we take

advantage of the function GDownloadUrl() from the Google Maps API.

This is an important function for us and its use is described at length in the

comments of the sourcecode.

2. After parsing the KML structure from the data files using a parse method,

again from the API, we create a number of NodeLists, which are objects

that mimic lists of nodes from the DOM. I want to emphasize that these

Page 66: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

aren't lists in the traditional sense. A NodeList is a particular type of object

which represents an ordered collection of nodes (not an array of nodes).

This distinction may seem subtle, but it's not. For example, virtually all of

the array object methods that you may be used to using aren't available for

NodeList objects. Still, we can loop through these NodeLists and create

markers for each of the <Placemark> elements from the original KML files

where each Placemark corresponds to one of our photos.

3. We push all of these markers onto one or more arrays where they're

collected until we're done processing all of the nodes from the KML

structure.

4. Finally, we pass these arrays to a number of marker managers

(GMarkerManager), which are objects the API makes available to us to

control display of collections of markers based on the bounds and zoom

level of the map.

Marker Managers The marker managers automatically remove markers that fall outside of the bounds of the

view. Without the marker manager, all of the markers, including those that can't be seen,

are added to the map. This adds to the amount of work the application must do but isn't

useful. Alternatively, we could accomplish the same thing by determining the bounds of

the map and checking that each marker falls within the view before adding it. We'd need

to repeat this every time the map was moved or the zoom level increased or decreased.

The marker managers handle this for us.

Another advantage is that we can define a number of marker managers and assign

different collections of markers to each. For each marker manager we set a zoom range

over which it is active; that is to say, levels at which it adds and removes all of the

markers it's responsible for from the map, subject to the bounds of the view as just

described. We can set these marker managers up to accomplish clustering. As we move

from low to higher zoom levels we can enable different managers to display increasingly

more of our markers so that we're never overloading the map, but always representing as

many of our photos as can be accommodated at the current zoom level.

Though we've described the setup_map function here, I'll refer you to the source code for

detailed discussion of the rest of the project. It simply makes more sense to structure the

discussion as the source code is written. The easiest way to handle that is in the source

file itself. Certainly don't be intimidated by the source. It is all explained very explicitly.

In fact, because the file is so heavily commented, I'm including a duplicate

maps_tutorial.js that omits the commenting so that those of you who feel that the

narration is distracting can focus on the code itself.

Page 67: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

This article is available in its entirety with downloadable code files online at

http://www.packtpub.com/article/Google-Earth-Google-Maps-and-Your-Photos-a-Tutorial-Part-I.

This means we've come to the end of the tutorial, except that you must read through the

source file to come to the end of the story of the javascript portion of the project. If your

Google Map works, congratulations. If not, keep at it. When it comes to programming,

persistence is a virtue. Review those portions of the tutorial that you may not have

understood completely, or double-check your source file looking for any small mistake.

As has already been mentioned, Firefox's Error Console should help point you in the right

direction.

Once you get the project working, it will only take a few minutes to create a map of your

geotagged photos going forward. It really is something that is valuable on its own and

potentially the beginning of any number of other more sophisticated projects.

Google Maps has been a fantastically successful application for Google and in

recognition of this, the amount of time and effort they continue to invest is only

increasing. Recently the API has gotten radically better. They've added their geocoder,

which we've used in this project, and expanded it to reach literally billions of new people.

Moreover, they're improving their own applications based on the API. For example,

they've recently launched My Maps, which is a simple web-based interface for

customizing a Google Map with information including photos, markers, routes, etc. And

they're doing everything they can to encourage independent developers like us.

Literally, from the time I started writing this tutorial to the time it was completed, it's

become possible to do more with Google Maps. One of the best places to find out about

improvements to Google Maps and the Maps API is the Official Google Maps API Blog

at http://googlemapsapi.blogspot.com/

Whether this project we've put together is everything you want to do with Google maps

or just the beginning of something bigger, I hope this tutorial helps you to enjoy your

photos.

Page 68: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

Books from Packt

Packt will be publishing the following books over the next two months:

PHP Web 2.0 Mashup Projects: August, 2007

Create practical mashups in PHP grabbing and mixing data from Google Maps, Flickr, Amazon, YouTube, MSN Search, Yahoo!, Last.fm, and 411Sync.com www.PacktPub.com/php-web-20-mashups/book

Learning PHP Data Objects: August, 2007

A Beginner's Guide to PHP Data Objects, Database Connection Abstraction Library for PHP 5 www.PacktPub.com/Learning-PHP-Data-Objects-Open-Source/book

Professional Plone Development: August, 2007 Building robust content-centric web applications with open-source Plone 3 CMS www.PacktPub.com/Professional-Plone-web-applications-CMS/book

Programming Microsoft Dynamics NAV: September, 2007

Create, modify, and maintain applications in NAV 5.0, the latest version of the ERP application formerly known as Navision

www.PacktPub.com/Microsoft-.NET-Dynamics-NAV-5.0-ERP-Navision/book

SOA and WS-BPEL: August, 2007 Composing Service-Oriented Architecture Solutions with PHP and Open-Source ActiveBPEL www.PacktPub.com/SOA-WS-BPEL-PHP-Open-Source-ActiveBPEL/book

Java EE 5 Development using GlassFish Application Server: September, 2007 The complete guide to installing and configuring the GlassFish Application Server and developing Java EE 5 applications to be deployed to

this server www.PacktPub.com/Java-EE-5-GlassFish-Application-Servers/book

Mastering OpenLDAP: August, 2007 Install, Configure, Build, and Integrate Secure Directory Services with OpenLDAP server in a networked environment www.PacktPub.com/OpenLDAP-Developers-Server-Open-Source-Linux/book

Page 69: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

For more information, visit: www.PacktPub.com.

OSWorkflow: A guide for Java developers and architects to integrating open-source Business Process Management: August, 2007 Get your workflow up and running with this step-by-step guide authored by an active developer of the OSWorkflow project with real-world examples www.PacktPub.com/OSWorkflow-Java-open-source-Business-Process-Management/book

Page 70: Google Earth, Google Maps and Your Photos: a Tutorial Earth and... · This article is available in its entirety with downloadable code files online at  …

How to get a free book

We are happy to supply copies of our books for review purposes. To qualify, you need to

be:

A blogger with your own blog site who would like to read the book and then

review it/recommend it on their blog

A reviewer for a magazine or popular and relevant website with a reasonable

prospect of a review being published

An academic or trainer considering the title for adoption on a course you are

teaching. You will need to write to us from a valid academic e-mail address

and include a postal address to an academic institution. You will need to

provide information about the course, including title and the number of

students. Out of courtesy, we may ask applicants to write book reviews for

us.

Email review copy requests to: [email protected]

If you don't qualify for a free copy based on these criteria, then we are willing to consider

exchanging a free book for an original article written by you that we can publish on

Packtpub.com. Articles should be about 1500 words long, and be a technical how-to or

case study that would be of interest to other Packt readers.

All submitted articles must be original, not having been published before,

and not under consideration for publication elsewhere

All articles will be edited as necessary for content, style, clarity, grammar,

and spelling

Articles once submitted become the property of Packt Publishing

Email your ideas to us at the address above.