Google Maps

Web Mapping Programmers Bundle

Posted on July 15, 2011. Filed under: ArcGIS Server, GeoSpatial Training Services, Google Maps, Open Source GIS, OpenLayers |

Today we are pleased to announce that our Web Mapping Programmers Bundle is now available for purchase.

This is a set of four self-paced, web based courses focused on developing web mapping applications with three of the leading JavaScript APIs.

Courses include:

This bundle of courses will be made available on Monday, July 18th.  Links to each of the courses will be sent out on that date.

Through July 22nd you can pre-purchase this bundle for $299.00.   After July 22nd the bundle will sell for $399.00.

Read Full Post | Make a Comment ( None so far )

Using the Google Maps Elevation Service

Posted on May 31, 2011. Filed under: GeoSpatial Training Services, Google Maps |

The Google Elevation Service provides elevation data for points on the surface of the Earth as well as sampled elevation data along paths.  The ElevationService object is used to communicate with the service.

The process of obtaining elevation data about a location or path is similar to that of the geocoding process.  A request object which can be either a LocationElevationRequest or PathElevationRequest object is created and passed to the ElevationService object.

Results are returned in the form of an ElevationResult object.  The Elevation Service is asynchronous so you must provide a callback function to process the results that are returned.  There is also an ElevationStatus object that you can query to determine the results of the request before further processing.

In this exercise you will learn how to use the Google Elevation Service to display the elevation profile of a polyline drawn across a map.  In addition to the Google Maps API this exercise also uses the Google Visualization service to handle plotting the elevation profile in a chart.  In addition to charting the elevation profile you’ll also write code to place Markers for each map click and also draw a polyline connecting the Markers.

Step 1: Open the Exercise File

  • The exercise file can be downloaded here.  Save the file to your computer.
  • Open the file in your favorite HTML or text editor.
  • So that you can focus on the sections of code related to the Elevation Service we have already written some of the code for this exercise.  You can view the final result of this exercise here.  Left click each point in the path and then right click to enter the final point.

Step 2: Create a new Instance of the Elevation Service

  • Inside the initialize( ) function I want you to create a new instance of the ElevationService class using the line of code that you see below.

Step 3: Add Event Listeners
For this exercise you’ll need to create two event listeners; one for a map click (Map.click) and the other for a right mouse click (Map.rightclick) on the map.  The intent of the Map.click event is to create a Marker object each time the user clicks the map and to add the LatLng objects of each click to an array which will later be used as input to the Elevation Service.  The Map.rightclick event will signal that the user has finished placing points.  In addition to creating the final Marker for the polyline this event handler will create a Polyline from the array of LatLng objects that were created and it will make a call to the ElevationService object to get the elevation along a path.

  • Add the code that you see below to create the event handlers.

The first event listener (Map.click) calls the JavaScript function ‘plotPoints()’ while the second (Map.rightclick) calls the ‘plottingComplete()’ function.  We haven’t created either of these functions yet so you won’t see them in your exercise file.

Step 4: Create plotPoints() JavaScript Function
In this step you will write the ‘plotPoints()’ JavaScript function that adds a Marker to the map each time it is clicked.  This function also adds the LatLng of the map click to an array which will be used as input to the ElevationService.

First, create the ‘path’ variable which is the array that will be populated by LatLng objects.

  • Create the plotPoints() function as seen below.

Here we use the ‘push’ method which is a JavaScript array method.  This places each LatLng into the ‘path’ array.  Next, we create a new Marker at the LatLng position.

Step 5: Creating the plottingComplete() Function
The ‘plottingComplete()’ function is triggered when the user right clicks the map display.  Just as with the ‘plotPoints()’ function this function will also create a Marker where the map was clicked and push the LatLng object into the ‘path’ array.  In addition, this function also create a Polyline connecting the Markers, creates the elevation service request, and calls the ElevationService.getElevationAlongPath() method.

  • Create the function, push the LatLng coordinate into the array, and create the Marker.
  • Create the Polyline.  A Polyline object in Google Maps accepts a PolylineOptions object in its constructor.  This PolylineOptions object is used to define the path of the Polyline, the line color, transparency, and the map with which it is associated.  Notice that the ‘path’ parameter is set to our ‘path’ variable.
  • Create the request that will be submitted to the ElevationService.  The request has two parameters: path and samples.  The ‘path’ parameter defines the path for which the elevation profile should be generated and the ‘samples’ parameter indicates the number of sample points that should be taken.
  • Finally, call the ElevationService.getElevationAlongPath() method as seen below.  The request object (pathRequest) and a callback function (plotElevation) are passed as parameters to the method.

    Step 6: Examine the ElevationService Return
    The second parameter passed into the ElevationService.getElevationAlongPath() method (plotElevation) is the callback function that will process the results returned by the Elevation Service.  The results are contained within an ElevationResult object.  Since we’re determining the elevation along a path there will be multiple ElevationResult objects each of which contain elevation and location objects.  We are interested in populating our Google Visualization Chart with the elevation for each point.  The ‘plotElevations’ chart has already been written for you but it is helpful to examine this code to understand what is being accomplished.

    If the ElevationStatus returned a message of ‘OK’ then we assign the ElevationResults to the ‘elevations’ variable.  We then create a DataTable from the Visualization library that will serve as the data source for the chart.  Inside this DataTable we add rows corresponding to the sample locations and elevations for each location.  Notice in the highlighted line of code that we are pulling out the ‘elevation’ property from the ElevationResult.  Finally, we draw the Google Visualization chart using the DataTable.

Step 7: View the Results

  • Save your work and open in a web browser.  Click anywhere on the map to deifne the first point.  Add additional points.  To add the final point in our elevation path you can right click the map display.  That will trigger the creation of the polyline and the Elevation profile as seen below.



    Want to learn more about programming the Google Maps API?  The first session of our instructor guided, web based course, Introduction to Programming the Google Maps API begins June 20th and runs through July 1st.  Course cost is $249.00.  The first 10 students receive a free pass to our follow-up course Advanced Google Maps API Programming which runs from July 11th-July 22nd.  Both courses are taught by Eric Pimpler, Qualified Google Maps API Developer.

Read Full Post | Make a Comment ( None so far )

Introduction to Programming the Google Maps API (v3)

Posted on May 19, 2011. Filed under: GeoSpatial Training Services, Google Fusion Tables, Google Maps |

GeoSpatial Training Services is pleased to announce the release of our newest instructor guided, Internet based course, Introduction to Programming the Google Maps API.  This is for version 3 of the API.

The first session of this course runs from June 20th – July 1st

This course will be taught by Eric Pimpler, Qualified Google Maps Developer.

The first 10 students to register will receive free entry to our follow-up course, Advanced Google Maps API Programming which runs from July 11th – July 22nd.

This is our entry level programming course for the Google Maps API (version 3), and is designed to enable you to build Google Maps applications for the web.  We will cover a lot of ground in this course.  By the end of our time together you will understand all the basic concepts you need to create dynamic web mapping applications with the Google Maps API.  We’ll start with some basic information about programming the Maps API and then we’ll dive into the longest section of our course: Basic Concepts of the Google Maps API.  In this module you’ll learn how to add and remove map controls for panning, zooming, setting map types, overview map, and the scale bar.  You’ll then learn how to add your own data to the map display using markers, polylines, and polygons.  One of the more creative functions provided with the Google Maps API is the ability to drape images across the map.  For instance, you might want to display wildlife habitats on top of Google Maps.  This is done through the use of Ground Overlays.  Ground Overlays allow you to drape historical map images and specific purpose maps on top of a Google  base map.  Building on this concept you will then learn how to add KML, GeoRSS, and FusionTables layers on top of the map.  In module 3 you will learn how to handle events.  Events are actions that take place in your application such as map clicks or drags.  Normally they are initiated by the end user but they can also be internally generated events such as the re-setting of the map center.  In module 4 you will learn how to convert addresses into geographic coordinates that can be displayed as Marker locations on the map.  You’ll also learn how to take a point of interest and find the nearest address to the point.  This is known as reverse geocoding.  Finally, we’ll wrap up the course with a module on the Google Elevation Service.  In this module you’ll learn how to obtain elevation data for a point or an elevation profiles for points along a line.

Modules
Module 1: Introduction to Programming the Google Maps API
Module 2: Basic Concepts of the Google Maps API
– Adding Controls to the Map (Zoom, Pan, Map Types, Overview Map, Scale Bar, Street View)
–  Creating Overlays (Markers, Polylines, Polygons)
–  Display Images with Ground Overlays
–  Creating Layers (KML, GeoRSS, FusionTables)
Module 3: Handling Events
Module 4: Geocoding with the Google Maps API
– Geocoding
– Reverse Geocoding
Module 5: The Google Elevation Service

Course Exercises
Create Your First Google Map
Working with Map Options
Adding and Removing Map Controls
Adding Markers to the Map
Creating and Displaying Info Windows
Adding Ground Overlays to the Map
Display KML Files on the Map
Adding Fusion Tables to the Map
Responding to Map and Marker Events
Geocoding Addresses
Using Reverse Geocoding to Find an Address for a Location
Obtaining Elevation for Points and Paths

Register Now: $249
Add to Cart

Read Full Post | Make a Comment ( None so far )

Adding a Fusion Table to Google Maps

Posted on May 19, 2011. Filed under: Google Fusion Tables, Google Maps, Uncategorized |

Google Fusion Tables, still in the experimental stages of development, is a Google product that allows you to upload and share data in multiple tables.  These tables can be joined together to create derived tables and provide a way of visualizing and sharing data.  With the Fusion Tables API you can upload, query, download, and sync your datasets.  The Google Maps API provides a new FusionTablesLayer object that connects to these Fusion Tables and can automatically render the location data in a Fusion Table as well as display additional information about each feature through a clickable overlay.

 In this exercise you will learn how to display the Geo-tagged Wikipedia Articles Fusion Table in Google Maps. 

Step 1: Open the Exercise File

Step 2: Fusion Tables Basics

  • Note: Before continuing with this exercise you will want to make sure that you have a Google account which is necessary to access Fusion Tables.
  • Login to Fusion Tables
  • Once you’ve logged into Fusion Tables use the Search text box to enter the words “Geo-tagged Wikipedia”
  • This should return a relatively short list of available tables as seen in the figure below.  Your results may vary though.
  • Select the table that I’ve highlighted in the figure above.  There should be roughly 424,000 records in this table. 
  • When this table is open you will notice a ‘Location’ field that contains the latitude, longitude coordinates for each record.  This field needs to be present in a Fusion Table for it to be capable of being viewed in Google Maps. 
  • You can view the contents of this table in a Google Map by selecting Visualize –> Map.

    You can also use the Google Maps API to programmatically add a Fusion Table to your application.  In the next step you’ll learn how to do this.  However, before doing so you will need to obtain unique identifier for the table.
  • Select File –> About from the Fusion Table interface.  This will display a dialog box containing information about the table as seen in the figure below.  Please note the ID that I have highlighted below.  You will use this ID when programmatically adding this Fusion Table to a Google Map.

Step 3: Adding a Fusion Table with the Google Maps API
The FusionTablesLayer class in the Google Maps API is used to add Fusion Tables to your custom Google Maps applications.  The constructor for this object takes a FusionTablesLayerOptions object which can contain properties such as map, query, heatmap, styles, and others.  In this step we’ll focus on using the ‘query’ property to define the Fusion Table to add to the map.

  • Add the following code block and then we’ll discuss.

    The ‘query’ property of the FusionTablesLayerOptions object is essentially a SQL query.  The ‘select’ statement queries the ‘location’ field from table ‘423292’ which as you’ll remember from the previous step is the unique id for the Geo-tagged Wikipedia Fusion Table. 
  • Save your work and open in a web browser to display the data from the Fusion Table.
    You can also add a ‘where’ clause to your query to filter the results.  This particular Fusion Table doesn’t include additional fields that you can use to filter the results, but you can imagine that if there were a field named ‘Country’ you could restrict the results through the addition of a ‘where’ clause that might look something like this:

Step 4: Fusion Tables Heatmaps
Fusion Tables also provide limited support for heat maps, where the density of matched locations is depicted using a palette of colors. Current heatmaps use a red (dense) to green (sparse) gradient to indicate the relative prevalence of associated locations. You enable a heatmap by setting the layer’s FusionTablesLayerOptionsheatmap’ parameter to ‘enabled: true’.

  • Add the following code block to your exercise file to enable the heatmap for the Wikipedia Fusion Table.
  • Save your work and open in a web browser to display the data as a heatmap.  Pretty cool!

 Want to learn more about programming the Google Maps API?  The first session of our instructor guided, web based course, Introduction to Programming the Google Maps API begins June 20th and runs through July 1st.  Course cost is $249.00.  The first 10 students receive a free pass to our follow-up course Advanced Google Maps API Programming which runs from July 11th-July 22nd.  Both courses are taught by Eric Pimpler, Qualified Google Maps API Developer.

Read Full Post | Make a Comment ( None so far )

Arc2Earth Cloud Services Drives Vineyard Power Site Selection

Posted on January 20, 2011. Filed under: Arc2Earth, Dojo, GeoSpatial Training Services, Google Maps |

Recently, GeoSpatial Training Services completed a custom, web based GIS application using the new Arc2Earth Cloud Services and its associated REST API.  Arc2Earth Cloud Services is an excellent alternative for deploying GIS applications to the web without the hassles and costs of standing up and configuring a GIS server.  In this article we’ll provide you with an overview of Arc2Earth Cloud Services and then take a shallow dive into the REST API to show you how to take advantage of this new service for building web mapping applications.

Arc2Earth Cloud Services is particularly attractive to small and medium sized organizations that need to deploy their data and applications to the web but don’t have the expertise nor the budget to purchase, install and configure, administer, and maintain a GIS server.  Vineyard Power, a renewable energy cooperative in Massachusetts, is a perfect example of this scenario. Vineyard Power is planning a cooperatively owned offshore wind farm at a site to be selected by its members. They worked with their membership and the community to develop siting criteria to compare the suitability of potential sites. With these criteria as their guide they created and compiled a variety of GIS layers to describe the physical characteristics that affect a site’s economic viability, the locations of important wildlife habitats and commercial fishing areas, and potential visual impact. Other layers include shipping lanes, sub-merged shipwrecks and popular recreational fishing areas.

To support its members in making an informed decision Vineyard Power needed a way of distributing this data in a meaningful way to a broad audience.  Using Arc2Earth for ArcGIS Desktop and Arc2Earth Cloud Services, Vineyard Power was able to export these data layers to the cloud where they could then be integrated into a Google Maps viewing application using the Arc2Earth Cloud Services REST API.  You can see a screenshot of the application below.  Tilesets are displayed in the viewer as the user clicks an item from the table of contents on the right hand side of the application or when clicking a subject tab just below the map.

According to Tyler Studds, Project Manager, “The functionality provided by A2E has been an incredible asset to our site selection process. The interface between cloud and desktop GIS is smooth and it has made it very easy to upload tilesets and to experiment with how they will appear in the web application.”

What is Arc2Earth Cloud Services?
Arc2Earth Cloud Services is a new ArcGIS Desktop software extension (currently in public beta testing) for uploading your existing GIS datasets to the cloud as vector datasets or tileset map caches.  Once uploaded, vector datasets can be searched and edited through ArcGIS Desktop or a custom, browser based map viewer.  In addition, Arc2Earth Cloud Services also provides various services including the ability to combine attribute searches with spatial operations.

As we have done with the Vineyard Power application, you can extend your data into Google Maps, Bing, and OpenLayers and build both web and mobile applications.  The API is also compatible with the ArcGIS Server Open Geoservices REST specification which allows you to use all of the ArcGIS.com infrastructure, web applications, mobile applications, and web APIs with your Cloud hosted data.

Arc2Earth Cloud Services is built on Google App engine which is designed for automatic and instant scalability along with the reliability, performance, and security of Google’s infrastructure.  Storage costs are dramatically reduced due to the cost efficient hosting provided by Google App engine.  You only pay for the CPU/Bandwidth/Storage that you use.

Creating and Using an Arc2Earth Cloud Service
Before you can begin using Arc2Earth Cloud Services you’ll first need to create an instance which is hosted by Google App Engine.  This article from Arc2Earth fully describes this process.

After creating an Arc2Earth Cloud instance you can then start creating Tilesets and uploading vector layers.  You can then manage your instance through the interface as seen below.  Here you see a listing of tilesets that have been loaded for a cloud instance.

Clicking a particular tileset will display additional information including a display of the data on a Google basemap.

The Arc2Earth Cloud Services REST API

All data uploaded to an Arc2Earth Cloud instance is accessible through a standard REST API which exposes several APIs including the following:

Datasource API – Read/Write access to vector data using industry data standards

Tileset API – Read/Write access to all tile caches

Static Map API – All tilesets have built in support for combining multiple tilesets on the server to create a single static image.

Vineyard Power published several dozen layers as individual tile caches to their unique Arc2Earth Cloud.  We then used the Tileset API to access the various tiles that had been published to the Cloud and display them in a Google Maps application.    In addition to using the Tileset API and the Google Maps API we also took advantage of the Dojo JavaScript framework to create the user interface and handle browser differences.  Dojo widgets including the TabContainer and Tree were used to handle the display of various tilesets in the map viewer.  We also created a custom base map layer for Google Maps using a NOAA tileset that was uploaded to the Arc2Earth Cloud.  See the figure below.

Programming with the Tileset API
As I mentioned earlier in the article we only used the Tileset API for this particular application since we were dealing with tilesets.  In future articles we’ll explore the Datasource API and Static Map API and the capabilities of each, but for now we’ll concentrate on the Tileset API.

With the Tileset API you can get a list of all tilesets for a Cloud instance, get an individual tileset, add a new tilset, delete a tileset, and bulk uploaded tiles.  You can view the documentation for the Tileset API.

In the Vineyard Power application which functions solely as a map viewer the only thing we’re interested in doing is accessing tilesets from the Cloud instance.  The tileset that we access depends upon the layer that has been clicked in the table of contents.  Map tiles can be accessed using either the Google Maps or Microsoft Bing naming conventions as seen below.

We used the Google Maps naming convention along with the ImageMapType class from the Google Maps API v3 to add a tileset to the map.  A code example is provided below.  The ImageMapType class is provided for rendering image tiles such as the ones stored in our Arc2Earth Cloud instance.  This class takes a parameter of type ImageMapTypeOptions which is used to set various properties of the new ImageMapType including the Url (getTileUrl) to the tileset, tilesize, if the image is a PNG, transparency value (opacity) and others.  Once these parameters are set we simply call the ‘push’ method on map.overlayMapTypes to push the tileset into the Google Maps display.

There was a lot of additional code that we implemented in the application to create the tree and tab structures, layout the application, clear the layers, and add a NOAA basemap, but the primary purpose of the application was to display tilesets on a Google Maps base layer and this is pretty easy to accomplish using the Tileset API for Arc2Earth Cloud Services.  In future posts we’ll take a look at other functionality provided by the Tileset API along with the Datasource API and Static Map API.

GeoSpatial Training Services is an authorized reseller of Arc2Earth and a Google Maps Qualified Developer.

Read Full Post | Make a Comment ( None so far )

Google Maps News from Google I/O Conference

Posted on May 20, 2010. Filed under: GeoSpatial Training Services, Google Maps |

Lots of exciting news regarding Google Maps coming out of the Google I/O Conference this week.

Google Maps API V3 Graduates!
Google Maps API V3 was introduced as a Google Code Labs project, and at this year’s conference it has graduated out of labs and is now the recommended version for Google Maps application development efforts.  According to Google:

Version 3 was built from the ground up to offer a clean, fast, and powerful maps application development platform for both desktop web browsers and mobile devices.

It was also announced that StreetView is now available at Version 3 in addition to new features such as such as elevation, bicycling directions, and optimised routing.  StreetView is noticeably different at Version 3:

When you use Street View in v3 you will notice a number of differences with v2. The most significant change is that Street View is entirely implemented in HTML in order to accommodate all of the mobile devices on which v3 is supported. We have also added Pegman support to the map, and a number of new features, including markers, infowindows, and custom imagery.

The Maps API V2 and Mapplets have now been deprecated which indicates that no future development will take place on these versions.  However, they will be maintained and supported for a minimum of 3 years.

At GeoSpatial Training Services we are planning to release updated versions of our Introduction to the Google Maps API and Advanced Google Maps Programming courses this summer to reflect the many changes in the Google Maps API at Version 3.

Directions Web Service
The Directions Web Service is a companion to the existing Geocoding and Elevation Web Services, and allows applications to obtain Driving, Bicycling, and Walking directions through an XML/JSON REST interface. All of the features of the Map API v3 Directions service are supported, including “avoid highways”, “avoid tolls”, and waypoint optimization (travelling salesman solver). For more information, check out the Directions Web Services documentation.

New Nearby Places Widget
Today’s big announcement is the new Nearby Places widget.  The Nearby Places widget is a user interface element that will launch in the Google Maps API v3.  It combines the W3C Geolocation API with location based Place search to present the user with a list of Places in their immediate vicinity. The user can select a Place which the Maps API application can use as a check-in, or to tag content supplied by the user about that place. The application can also obtain more detailed information about the Place, such as the address, telephone number, and Place Page URL.

The Nearby Places widget is built on top of the Places Web Service, a new addition to the family of Google Maps API Web Services. The Places Web service offers search for nearby places to native mobile applications through an XML/JSON REST interface.

Read Full Post | Make a Comment ( None so far )

Arc2Earth Version 3 Released!

Posted on May 18, 2010. Filed under: Arc2Earth, ESRI, GeoSpatial Training Services, Google Earth, Google Maps, OpenLayers |

Arc2Earth Version 3 is now available as a general release.

Do you need to get your GIS data online in a hurry? Or export your complex maps in KML format for viewing in Google Earth?
There’s no need for servers or server software, all you need is a single ArcView seat and Arc2Earth. Export locally, directly to Amazon S3 or to your own Arc2Earth Cloud instance. Click and you’re done.

Arc2Earth is the premier ArcGIS extension for exporting and importing your data into the leading GeoWeb formats. Import or Export complex KML files, map tile caches or use the new Cloud services to host your data online. And new at Arc2Earth V3, live editing with Cloud Layers. Upload and manage your data in an Arc2Earth Cloud, Google Maps Data or Open Street Map.

GeoSpatial Training Services is an authorized reseller of Arc2Earth. More information on Arc2Earth here.

Read Full Post | Make a Comment ( None so far )

Google Maps Adds Elevation Service

Posted on April 5, 2010. Filed under: Google Maps |

The Google Maps team continues to add really useful functionality to the Maps API.  Now the Google Maps API team has  introduced a new Elevation Service that enables applications to determine elevation profiles.  The Maps API v3 contains an ElevationService class or you can simply use the Elevation Web Service as an HTTP request from v2 applications.  You can request the elevation in meters for one or more sets of coordinates, or you can request a specific number of elevation samples spaced along a path.

The figure below shows a sample application that uses the Google Visualization API to plot elevation profiles. You can add additional points by clicking on the map or entering an address, and you can switch between different modes of travel to see the affect on the profile. If you roll your mouse over the profile chart you can see on the map the point that the given sample relates to

I’ll have some code examples on this new service soon.

Read Full Post | Make a Comment ( None so far )

Google Public Data Explorer

Posted on March 10, 2010. Filed under: Google Maps, Google Visualization API |

Another fantastic data visualization tool has been released by Google.  The Google Public Data Explorer (currently in labs) makes large publicly available datasets available for exploration, visualization, and communication. 

Visualizations of public data can be explored, linked to, or embedded on a web page. 

Note the ability to animate data over time as seen in the figures below.

In addition to visualizing data in a map format you can also mash up data using line graphs, bar graphs, and bubble charts.  As I mentioned visualizations can display data over time, but you can also change topics, highlight different entries and change the scale.  Once you have created the chart you can share the results by embedding on your website or blog. 

Data source include the World Bank, U.S. Bureau of Labor Statistics, U.S. Census Bureau, Organization of Economic Co-Operation and Development, California Dept. of Education, Eurostat, U.S. Center for Disease Control, and the U.S. bureau of Economic Analysis.

Read Full Post | Make a Comment ( None so far )

New Google Geocoding Web Service

Posted on March 10, 2010. Filed under: Google Maps |

Google has announced a new Geocoding Web Service  which contains a number of improvements over its previous version  including the following:

  • A flatter response format for address components that is easier to parse
  • The ability to tag an address component with multiple types
  • Both full names and abbreviations for countries and states
  • Differentiation between rooftop and interpolated geocoder results
  • Both the bounding box and recommended viewport for each result

The geocoding web service enables pre-caching of geocoded results for commonly used addresses in your application.  Results are cached on your server and any additional requests for these addresses will be served out of the cache rather than having to be geocoded each time.

Other items of interest from the announcement

  • Google also announce the deprecation of its previous geocoding service. 
  • Requests no longer require a Maps API key
  • CSV output not supported
  • 2,500 requests per day from a single IP address
  • Service must be used in conjunction with maps generated by Google Maps APIs or Google Earth API
Read Full Post | Make a Comment ( None so far )

« Previous Entries

Liked it here?
Why not try sites on the blogroll...