|
Example 16 - Custom Maps
This example demonstrates the taglibrary's ability to support
custom map types. Custom map types are maps that use a custom set of images (known as tiles). For example,
a standard Google Map provides three map types, street maps, satellite maps and hybrid maps.
Now you can create your own map type. Complete with a map type button, copyright notice
and custom tile images.
It is beyond the scope of this tag library to define how Google Maps uses custom
tiles to create custom map types, but you can read the version 1 tutorial on the Mapki
here. You don't have to
understand the Google Map part of it, we do that for you. But you will have to know how to
create a tile server (a server side process that receives requests from the map and
dispenses the appropriate tile(s)) and how to create matching tile images. Just for
reference here's a great tool
for generating tiles.
That's enough chatting about it. Let's see it work. Without moving the map, click map type
button labelled "My House". You'll see my custom tiles suddenly appear.
They look pretty much like the standard tiles, only I drew on some of them with a paint
program. These tiles could be something more effective, like subway maps, detailed train
routes, etc. You'll also notice that the copyright notice in the bottom right-hand corner
has changed. This map type has a maximum defined zoom level of 0, so if you zoom out, you'll notice the map
type switch back to the standard street map type (because our baseType is set to map). Also if you move the map so
the centerpoint extends outside the map bounds, it reverts back to the standard map type.
Here's the code we used to create the map:
<googlemaps:map id="map" width="250" height="300" version="2" type="STREET"
zoom="0">
<googlemaps:key domain="localhost" key="xxxx"/>
<googlemaps:imageoverlay id="image_1"
url="/GoogleMaps/images/icon.png" opacity="0.50" x="10" y="10"
link="http://www.lamatek.com/GoogleMaps/"/>
<googlemaps:point id="point1" address="74 Connors Lane" city="Elkton"
state="MD" zipcode="21921" country="US"/>
<googlemaps:marker id="marker1" point="point1"/>
<googlemaps:zoomControl size="large" enable="true"/>
<googlemaps:typeControl enable="true"/>
<googlemaps:maptype id="type1" name="My House" baseType="map"
copyright="(c)2006 Tom Cole" maxZoom="17" minZoom="17"
url="/GoogleMaps/servlet/TileServlet" showOnStartup="false"
upperLeftBound="point1" lowerRightBound="point1"/>
<googlemaps:message>Please wait...</googlemaps:message>
</googlemaps:map>
It's the <googlemaps:maptype> tag that does the work for us. The parameters specified are:
- id = type1
- This is a map unique id for this map type.
- name = My House
- This is the map type name. The button that appears will have this label.
- baseType = map
- This is the base map type that this map type derives from. This is only
important if you want a hybrid map. This map type will also take over
when your map type has no tiles to display.
- copyright = (c)2006 Tom Cole
- This notice appears at the bottom of the map when this map type is displayed.
- maxZoom = 0
- Denotes that this map type is only available at zoom level 0 or lower (since there is
no lower, then 0 is it...)
- url = /GoogleMaps/servlet/TileServlet
- This is the path to the server side resource that will be providing the tile
data.
- showOnStartup = false
- Since we only have one zoom level supported and our map is not initialized
to that zoom level (0) we set this to false.
Just for completeness sake, we've included the code for our TileServlet. There are many other examples
using other server side technologies on the Google Maps
API Group. You'll notice that the map sends three parameters when requesting a tile, an x value, y value
and a zoom level. The tile tool referenced above may
help you better understand what the x and y values mean. Here our map only contains 24 tiles (6 wide x 4 high) and only
supports one zoom level. Therefore we only return a tile of the request is within the range of tiles, at zoom level 0, otherwise
we return a tile that shows our logo (isn't that special):
package com.lamatek.servlets;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TileServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
int x = Integer.parseInt(request.getParameter("x"));
int y = Integer.parseInt(request.getParameter("y"));
int z = Integer.parseInt(request.getParameter("zoom"));
String filename = "blank.gif";
if (z == 0 && x >= 37912 && x <= 37917 && y >= 49816 && y <= 49819) {
filename = "$x" + x + "_$y" + y + "_$z" + z + ".gif";
}
String path = "c:/Tomcat/webapps/GoogleMaps/images/" + filename;
File file = new File(path);
if (file.exists()) {
response.setContentType("image/gif");
BufferedInputStream input = new BufferedInputStream(
new FileInputStream(file));
BufferedOutputStream output = new BufferedOutputStream(
response.getOutputStream());
byte[] b = new byte[1024];
while (input.read(b) >= 0) {
output.write(b);
}
output.flush();
output.close();
input.close();
}
else {
System.err.println("Unable to locate file " + path);
}
}
catch(Exception ex) {
//do nothing...
}
}
}
We'd love to see how you use this feature. Drop us a line if you do.
Our next example shows how to display an
overview window.
|