package mobac.mapsources.mappacks.openstreetmap;
import java.awt.Color;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.ImageProducer;
import java.awt.image.RGBImageFilter;
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import mobac.exceptions.TileException;
import mobac.exceptions.UnrecoverableDownloadException;
import mobac.mapsources.AbstractHttpMapSource;
import mobac.mapsources.AbstractMultiLayerMapSource;
import mobac.program.Logging;
import mobac.program.interfaces.MapSource;
import mobac.program.interfaces.MapSourceTextAttribution;
import mobac.program.model.TileImageType;
import mobac.program.tilestore.TileStore;
import mobac.utilities.Utilities;
/**
* http://openseamap.org/
* @see OpenSeaMapLayer
*/
public class OpenSeaMap extends AbstractMultiLayerMapSource implements MapSourceTextAttribution {
public static final String LAYER_OPENSEA = "http://tiles.openseamap.org/seamark/";
public OpenSeaMap() {
super("OpenSeaMap", TileImageType.PNG);
mapSources = new MapSource[] { new Mapnik(), new OpenSeaMapLayer() };
initializeValues();
}
public String getAttributionText() {
return "© OpenStreetMap contributors, CC-BY-SA";
}
public String getAttributionLinkURL() {
return "http://openstreetmap.org";
}
/**
* Not working correctly:
*
* 1. The map is a "sparse map" (only tiles are present that have content - the other are missing) <br>
* 2. The map layer's background is not transparent!
*/
public static class OpenSeaMapLayer extends AbstractHttpMapSource {
public OpenSeaMapLayer() {
super("OpenSeaMapLayer", 11, 17, TileImageType.PNG, TileUpdate.LastModified);
}
public String getTileUrl(int zoom, int tilex, int tiley) {
return LAYER_OPENSEA + zoom + "/" + tilex + "/" + tiley + ".png";
}
@Override
public byte[] getTileData(int zoom, int x, int y, LoadMethod loadMethod) throws IOException,
InterruptedException, TileException {
byte[] data = super.getTileData(zoom, x, y, loadMethod);
if (data != null && data.length == 0) {
log.info("loaded non-existing tile");
return null;
}
return data;
}
@Override
public BufferedImage getTileImage(int zoom, int x, int y, LoadMethod loadMethod) throws IOException,
UnrecoverableDownloadException, InterruptedException {
try {
byte[] data = getTileData(zoom, x, y, loadMethod);
if (data == null) {
return null;
}
com.sixlegs.png.PngImage png = new com.sixlegs.png.PngImage();
BufferedImage image = png.read(new ByteArrayInputStream(data), true);
return image;
} catch (FileNotFoundException e) {
TileStore ts = TileStore.getInstance();
ts.putTile(ts.createNewEmptyEntry(x, y, zoom), this);
} catch (Exception e) {
Logging.LOG.error("Unknown error in OpenSeaMap", e);
}
return null;
}
@Override
public Color getBackgroundColor() {
return Utilities.COLOR_TRANSPARENT;
}
}
public static Image makeColorTransparent(Image im, final Color color) {
ImageFilter filter = new RGBImageFilter() {
// the color we are looking for... Alpha bits are set to opaque
public int markerRGB = color.getRGB() | 0xFF000000;
public final int filterRGB(int x, int y, int rgb) {
if ((rgb | 0xFF000000) == markerRGB) {
// Mark the alpha bits as zero - transparent
return 0x00FFFFFF & rgb;
} else {
// nothing to do
return rgb;
}
}
};
ImageProducer ip = new FilteredImageSource(im.getSource(), filter);
return Toolkit.getDefaultToolkit().createImage(ip);
}
}