Archive for June, 2008
As promised in my last blog entry Map Application in Swing - The Easy Way in this short blog entry i would like to explain how to change the default map providers for the JXMapKit component from the SwingX-WS project.
The sample application still has the same functionality as in my first blog entry - to simply show a map in which the host cities of the Euro2008 are marked but this time using the Google Maps Tile server as provider for the map tiles. This is how the resulting application will look like:

Some (un)necessary info before...
The Google Maps Tile server can be reached at following address: http://mt.google.com.
This server is responsible for delivering the Google Maps tiles, please take a deeper look into the Google Maps API to understand how Google Map Tiles are addressed (Google Map API Coordinates). To get a tile from the Google Maps server some additional parameter are necessary for to add to the http://mt.google.com url. First we need an x and y coordinate as well as the zoom level to address a specific tile. The parameters v and n are needed for to satisfy the Google server. For example the following url:
http://mt.google.com/mt?n=404&v=w2.75&x=8937&y=5681&zoom=3 delivers a tile from the inner city of vienna at zoom level 3.
... we finally can implement our own Map Provider
A TileFactoryInfo encapsulates all information specific to a map server. This includes everything from the url to load the map tiles from to the size and depth of the tiles. Theoretically any map server can be used by installing a customized TileFactoryInfo. That's what the API of the SwingX-WS project says about the TileFactoryInfo class and that's also exactly what we need 
The only thing we need to do is to construct a TileFactoryInfo object with the correct parameters for the Google Maps Tile server.
JAVA:
-
public class GoogleMapsTileProvider {
-
private static final String VERSION =
"2.75";
-
private static final int minZoom = 1;
-
private static final int maxZoom = 16;
-
private static final int mapZoom = 17;
-
private static final int tileSize = 256;
-
private static final boolean xr2l = true;
-
private static final boolean yt2b = true;
-
private static final String baseURL =
-
"http://mt1.google.com/mt?n=404&v=w" + VERSION;
-
private static final String x =
"x";
-
private static final String y =
"y";
-
private static final String z =
"zoom";
-
-
private static final TileFactoryInfo
-
GOOGLE_MAPS_TILE_INFO = new TileFactoryInfo(
-
minZoom, maxZoom, mapZoom, tileSize, xr2l,
-
yt2b, baseURL, x, y, z);
-
-
public static TileFactory getDefaultTileFactory()
-
{
-
return (new DefaultTileFactory(
-
GOOGLE_MAPS_TILE_INFO));
-
}
-
}
The minimal possible zoom level is 1, the maximum possible zoom level is 16, the tile size is 256x256 pixel, the x axis goes from left to right, and the y axis from top to bottom.
The following code sets the tile factory to our own implementation.
JAVA:
-
JXMapKit mapViewer = new JXMapKit();
-
mapViewer.setTileFactory(
-
GoogleMapsTileProvider.getDefaultTileFactory());
Voila, from now on you can use the Google Maps Tiles in your own images but please note that your are using a service from Google without having signed their Terms of Use. So this guide is more for scientific purposes than to use in real world applications.
June 30th, 2008
Ever tried to visually represent geographical information in your Swing Application? Wouldn't it be nice to have something similar to Google maps available as a Swing component. Many thanks to the guys at SwingLabs who provide such an easy way to integrate mapping into your own Swing application. I'll try to illustrate the very basic functionality of the mapping component JXMapKit from the SwingX-WS project.
First of I'll give you a hint how the final application will look like:

The application shows the location of the host cities of the Euro 2008 in a map.
Now to the interesting part - the Java code. First of all we have to instantiate an object from type JXMapKit:
JAVA:
-
JXMapKit mapViewer = new JXMapKit();
-
mapViewer.setDefaultProvider(
-
DefaultProviders.OpenStreetMaps);
-
mapViewer.setDataProviderCreditShown(true);
Add the mapViewer to a JFrame and that's all you need if you would like to show the user a map from OpenStreetMap centered at London with controls for zooming and a minimap. If you would like to change where the map is centered you simply have to instantiate a GeoPosition object with coordinates and call the setAddressLocation on the JXMapKit object. For example if you would like to center the map at the city of the Euro 2008 final
JAVA:
-
GeoPosition vienna =
-
new GeoPosition(48.20875, 16.372583);
-
mapViewer.setAddressLocation(vienna);
Adding Waypoints
Waypoints are sets of coordinates that identify a point in physical space (Quote from Wikipedia). To complete the "Euro2008 - Host Cities Viewer" Application we finally add a marker on the map at the position of the eight host cities.
JAVA:
-
GeoPosition zuerich =
-
new GeoPosition(47.366667, 8.55);
-
GeoPosition basel =
-
new GeoPosition(47.566667, 7.6);
-
...
-
-
Set<Waypoint> hostCitiesEuro08 =
-
new HashSet<Waypoint>();
-
hostCitiesEuro08.add(new Waypoint(zuerich));
-
hostCitiesEuro08.add(new Waypoint(basel));
-
...
-
-
WaypointPainter<JXMapViewer> painter =
-
new WaypointPainter<JXMapViewer>();
-
painter.setWaypoints(hostCitiesEuro08);
-
mapViewer.getMainMap().setOverlayPainter(painter);
The WaypointPainter is responsible for painting the markers for waypoints at the map. The default WaypointPainter draws a blue balloon at the given GeoPosition.
Changing the map provider
At the moment the SwingLabs library provides two implementations for map providers. The OpenStreetMap as we have seen in this example and NASA's BlueMarble. It is possible to write your own provider. How to do this i'll post in my next blog. So stay tuned and enjoy experimenting with the great JXMapKit component from SwingLabs.
Please feel free to download the complete source code and the needed libraries for the Euro2008 application: Source Code for the Euro2008 - Host Cities Viewer
June 16th, 2008
The company i am currently writing code for uses a proxy for outgoing network calls. The proxy requires a username and password to let you connect to the outside world. So far so good. To connect through the proxy in my Java application first i tried to set the following properties, as suggested in some forums:
- http.proxyHost=proxyHost
- http.proxyPort=proxyPort
- http.proxyUserName=username
- http.proxyPassword=pass
But this didn't work. I always got the HTTP error 407 which means Proxy authentication required. Reading Suns documentation for the possible proxy properties to my surprise showed that http.proxyUserName and http.proxyPassword are not listed as possible properties.
java.net.Authenticator to the rescue! The class Authenticator represents an object that knows how to obtain authentication for a network connection. Usually, it will do this by prompting the user for information. For a detailed description see the javadoc.
To get things working first we need to subclass Authenticator.
JAVA:
-
public class BasicAuthenticator
-
-
-
-
private char[] password;
-
-
public BasicAuthenticator
(String username,
-
-
-
this.username = username;
-
this.password = password.toCharArray();
-
}
-
-
@Override
-
-
getPasswordAuthentication() {
-
-
-
password);
-
}
-
}
The only thing that needs to be done is to override the getPasswordAuthentication method and return a PasswordAuthentication object with username and password character array.
This implementation has to be set as default:
In combination with correclty set http.proxyHost and http.proxyPort the authentication works like a charm, also for Proxies.
Now i can connect to the outside world, but still doesn't know why the properties http.proxyPassword and http.proxyUserName are not working for me... Any ideas?
June 9th, 2008