Saturday, September 22, 2007

Saving a WWJ layer tiles composite

Many have asked on the WW forum how to 'extract' a portion of a layer imagery and save it for further use with other applications. It happens that WWJ has a built in public method in TiledImageLayer that does exactly that - at least the hard part of it, the tiles retrieval and composition. All what's left to do is save the composited BufferedImage.

Here is some test code:

// Save a composite of a layer's tiles into a file
private void saveImageForSector(TiledImageLayer layer)
{
int imageSize = 1024; // Saved image max dimension
int level = 0; // level number (-1 = best)
Sector sector = new Sector(
Angle.fromDegrees(43.4), Angle.fromDegrees(44.4),
Angle.fromDegrees(6), Angle.fromDegrees(8));
java.awt.image.BufferedImage image =
layer.composeImageForSector(sector, imageSize, level);
try
{
javax.imageio.ImageIO.write(image, "png",
new java.io.File("SavedImageSector.png"));
}
catch (IOException e) {}
}

The above method needs a TiledImageLayer reference - the like of BMNGSurfaceLayer or LandsatI3. The level number must take into account the layer empty levels: if it has 10 levels with 4 empty ones then the first real level is 4, the second 5 and so on until 9. Chosing level zero will always give you the first non empty level anyway.

The composeImageForSector() method does quite a tedious work of tracking down all the tiles needed and will trigger download requests if necessary. It will then scale and paste each of them into the final image.

It works but would probably need some tuning, as you seem to quickly run out of memory when dealing with larger numbers of tiles or larger output dimensions. The final composited image quality may vary a lot too, depending on how much scaling has been applied to the original tiles... so dont expect too much ;)

No comments: