OpenLayers is a free javascript mapping application that you can use to overlay maps from GeoServer on Google Maps, Virtual Earth, Yahoo! Maps, and other sources. You can actually use it as a pure client for GeoServer's WMS, but the huge advantage of using these proprietary APIs is all the great imagery and base street data available for free.
A short tutorial on the basics of WMS display is posted here, but please add links and more experiences you have with gmaps and GeoServer. Add directly here or as a Use Narrative or one of the End User Tutorials.
In addition GeoWebCache now supports Google maps tiles directly, so you can just use the gmaps API, with tiles rendered by GeoServer and cached by GeoWebCache for high performance. It is also in the process of being integrated directly with GeoServer, for now it is available as a drop in plugin, see the tutorial
Getting Started with Google Maps and GeoServer WMS
Prerequisites
Google Maps set-up
First you'll need to get started with Google Maps. Go to http://www.google.com/apis/maps/ and sign up for an API key with the url where you can test the map. After you enter the information a key and some html/javascript will be generated. Throw that on a webpage you can test, and you should have a map. If you don't, then consult the google maps documentation
GeoServer set-up
Next you'll need to get GeoServer running. Consult the Documentation. At the very least download and install GeoServer, and get it running - Quickstart should get you started. For this basic example we're just using a default layer, so no need for any extra configuration.
OpenLayers javascript library.
OpenLayers is included in the default GeoServer installation, so this should already be set up for you. There is an example page using OpenLayers with Google Maps, Virtual Earth, and Yahoo! Maps available at http://localhost:8080/geoserver/www/ol-demo.html . (The ol-demo.html file itself is in a subdirectory of the GeoServer data directory called www. You can place any static files that you would like to host in this folder.) Be advised that this map uses a Google Maps API key licensed to 'localhost' and will not work for a public-facing site. It is recommended that you copy the file before customizing it. You can easily modify it to use your own API key by editing the .html file and replacing the line that reads:
<script src='http://maps.google.com/maps?file=api&v=2&key=ABQIAAAAjpkAC9ePGem0lIq5XcMiuhR_wWLPFku8Ix9i2SXYRVK3e45q1BQUd_beF8dtzKET_EteAjPdGDwqpQ'></script>
with the appropriate line from the html page that you received from Google when you registered for your API key.
Modifications
Once you've got OpenLayers and GeoServer set up, all you need to do is customize the map to show your own information instead of the default map of the United States. The US map layer is defined in the following snippet of javascript:
var wms = new OpenLayers.Layer.WMS( "TOPP States", "http://localhost:8080/geoserver/wms?", { layers: 'topp:states', styles: '', srs: 'EPSG:4326', format: 'image/png', tiled: 'true', tilesOrigin : "143.60260815000004,-43.851764249999995", transparent: true }, { 'opacity': 0.75, 'isBaseLayer': false, 'wrapDateLine': true } );
Make sure to correct the second parameter with the url and proper port of your running geoserver. Be sure to include /geoserver/wms?. You can specify which of your own layers to show by modifying the 'layers' parameter. This is a comma-separated list, so you can have multiple layers from GeoServer treated as a single layer in the OpenLayers map. If you want to display multiple layers and allow them to be toggled independently, you should create multiple OpenLayers.Layer.WMS objects. These objects need to be registered with the map by adding them to the array in this line:
map.addLayers([gsat, veaer, yahoosat, wms]);
For information on actually loading your map information in GeoServer, see User Tutorial Shapefile for a step-by-step guide to setting up a shapefile, or 2.1 Data Configuration for a more in-depth explanation with specifics for oracle, db2, postgis, etc.
If you've done everything right, you should see something like this: 
Next Steps
Bounding Box
Next you'll want to get your map configured to start out with a reasonable view of your features rather than the United States. The initial viewing window, or "bounding box," for the map is defined by the lines
var usBounds = new OpenLayers.Bounds( -14392000, 2436200, -7279500, 6594375 ); \\ ... map.zoomToExtent(usBounds);
The best way to find the proper bounding box for your map is to navigate the map in your browser and use the bounding box when you have a nice view of your features. The example map page includes some javascript to make this easy; the current bounding box is displayed beneath the map as you navigate. When you have a view that you like, you can simply copy the bounding box from the demo page and replace the coordinates in the javascript code. Then you can disable the bounding box in the web page by deleting or commenting out the lines that display it:
// the part below is just to make the bounds show up on the page
var boundsOutput = document.getElementById('bounds');
function updateBounds() {
boundsOutput.innerHTML = map.getExtent().toBBOX().replace(/,/g, ', ');
}
// update the bounds with each map move
map.events.register('moveend', map, updateBounds);
// and update the bounds on first load
updateBounds();
Styling Your Map
After you have your layer displaying, you'll want to configure the way it looks. Start with the SLD Intro Tutorial and OGC SLD Explanations and Samples for more in depth information. SLD is an open standard that lets you configure 'rules' for how to display your data.
Further tweaks
Several other options are available to you in setting up the OpenLayers Layer. These values should be specified in the form { option : value } in the fourth parameter to the OpenLayers.Layer.WMS constructor; see the example code for details.
| option | example value |
use |
|---|---|---|
| opacity | 0.70 |
Specify how solid you want features to appear. 1.0 means that the feature completely obscures things beneath it, while 0.0 means that the feature is invisible. |
| isBaseLayer | false |
Specify whether OpenLayers should treat this layer as a base layer. One and only one base layer must be displayed at any time, although if you have multiple base layers you can allow users to toggle between them. As many or few non-base layers as you like can be overlayed at a time. |
| wrapDateLine | true | Specify whether or not OpenLayers should wrap the map at the International Date Line |
There are also some options that you can add to the WMS request; these are specified in the third parameter to the OpenLayers.Layer.WMS constructor.
| option | example value | use |
|---|---|---|
| format | 'image/gif' | Specify the mimetype of the image format that should be used for the map. Valid values include 'image/gif', 'image/jpeg', and 'image/png' |
| styles | 'myStyle' | Specify which styles to use for each WMS layer being displayed as a comma-separated list of style names. There should be as many styles specified as layers being requested. This replaces the default style specified in the geoserver configuration. |
| srs | 'EPSG:4326' | Specify the srs to use for displaying the map. |
| tiled | true | Load the map in smaller tiles rather than redrawing the entire screenfull of map information on every movement. |
Zoom level alignment
One feature of SLD is the MinScaleDenominator and MaxScaleDenominator. You can figure each 'rule' (which tells how to display data) to be different at different zoom levels. Google Maps has a set number of zoom levels, which correspond with certain scale denominators. One of the GeoServer users, Javier de la Torre, has mapped out the matching levels for Europe:
| Google Maps Zoom level | Geoserver scale denominator |
|---|---|
| 0 | 1.848079519342464E8 |
| 1 | 1.0337641452447231E8 |
| 2 | 2.615834533663211E7 |
| 3 | 6.269607959427761E7 |
| 4 | 3.368752114816766E7 |
| 5 | 1.3888080981982427E7 |
| 6 | 4684788.371727176 |
| 7 | 2692589.1937281643 |
| 8 | 1307893.1427936524 |
| 9 | 644425.5565537302 |
| 10 | 313562.9883854061 |
| 11 | 158544.31983237443 |
| 12 | 79321.27086307846 |
| 13 | 39599.27150781185 |
| 14 | 19772.040748579664 |
| 15 | 9874.52936126395 |
| 16 | 4935.5416457795045 |
| 17 | 2468.2015645037545 |
If you want a different view of the data at each layer you can set min/max scales for all 17 google maps. It also can be nice to split up your data in to different layers, with less data at zoomed out levels, and then just have them not display at certain zoom levels. If people have SLD's that work nicely with Google Maps please post them here.
Javier later found a side effect of Google's different projections, in that the scale denominators are different depending on the latitude. See GMapExample.sld.xml for an SLD of different zoom levels, and http://synthesys.csic.es/gmap/GmapExample.php to see how they play out at different latitudes. See: http://www.nabble.com/Matching-of-Google-Maps-zoom-levels-with-SLD-t1800929.html for some more info.
Beyond
There's obviously much more that can be done, using different styles, overlaying different maps, choosing different layers for different buttons, ect. But with these basics you should be able to figure out how to get GeoServer playing with all of them. Please report back here any useful tips and hints you might find, and add to the 6 User Experiences section.
If someone wanted to get WFS working with Gmap and write up a nice tutorial here that'd be great. The place to start would be: http://blog.kylemulka.com/?p=289
Also note that the script included here is a start, but does not align perfectly at all zoom levels in all places. If anyone makes progress on more accurate overlays, please let us know, posting here or to the geoserver devel mailing list. A great overview of how Google Maps handles things is at: http://cfis.savagexi.com/articles/2006/05/03/google-maps-deconstructed
This http://chignik.berkeley.edu/google/wms236.js version looks more accurate.