Map rendering in JavaFX

Map rendering in JavaFX I have been writing location-based software for a long time. In this area, JavaFX has some nice benefits that allows you to write map-related software easily. As a very simple example, I wrote a map renderer that renders tiles generated by the OpenStreetMap project. The OpenStreetMap project (OSM) is a collaborative effort where map data is provided by different sources and people, and I am very impressed with the quality of the data that is in the OSM database.
Apart from viewing the mapdata at the OpenStreetMap website itself, developers can use the OpenStreetMap API or the Tile Rendering service to integrate OSM based data in their projects.

I wrote a very small JavaFX project that retrieve tiles from the Tiles@home rendering project and shows them. This project is far from a functional mapping project, but it shows how easy it is to move around on a map and to zoom in or zoom out using JavaFX.
http://javafx.lodgon.com/osmtile/TileClient.jnlp will start the map renderer.

I made the code for this project available as well:

The code is pretty simple and self-explaining, so I am not diving too deep into it here. The one thing I want to point out, is how easy it is to show a scaled image while transferring the zoomed images.
If you zoom into a specific area, the application will first show the existing tiles in a scaled way, while downloading the new tiles. Downloading the new, more detailed tiles, can take some time and the user needs to view "something" while waiting. We solve this by scaling the tile from the lower zoom level, and showing this until the needed tiles are downloaded.
Each TileUI instance represents a tile, and contains a reference to its "zoomParent", which is the tile at the lower zoomlevel that covers this tile. It also contains a list of tiles at the next zoomlevel that are covering the same area as this tiles. When a new tile is requested, its parent tile is looked up and the new tile is added to the list of "covering" tiles for this parent:
100             if (tileMap.containsKey(pidx)) {                          
101               var ptile: TileUI = tileMap.get(pidx) as TileUI;                                                                                                           
102               insert newtile into ptile.covering;                                                                                           
103               newtile.zoomParent = ptile;                                                      
104            }
Once all tiles for the new zoom level are downloaded, the scaled tile at the lower zoom level should not be visible anymore. This is accomplished by removing the dowloaded tile from the list of covering tiles
30   var image: Image = Image {
31       url: resource;
32       backgroundLoading: true;
33     }
...
35   var loading = bind image.progress on replace {
36     if (loading ==100) {
37       delete this from zoomParent.covering;
38     }
39   }
and by only showing a tile when its zoomlevel is the active zoomlevel or when this tile is covering higher-zoom tiles:
47   override var visible =  bind ((zoom == mapView.zoom) or (sizeof covering > 0) );
I like the simplicity of JavaFX. I should stress though, that this application is not a production-ready application. Ideally, we need to remove tiles from the cache to save memory, and many other things should be improved as well. But the goal was to show how easy it is to write a tile renderer in JavaFX.

written on 26 Mar 2010 13:45.

no comments

Create comment