/*
* Geotoolkit - An Open Source Java GIS Toolkit
* http://www.geotoolkit.org
*
* (C) 2012, Geomatys
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotoolkit.coverage.postgresql;
import java.awt.Point;
import java.io.IOException;
import java.lang.ref.SoftReference;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import javax.imageio.ImageReader;
import javax.imageio.spi.ImageReaderSpi;
import net.iharder.Base64;
import org.geotoolkit.storage.coverage.TileReference;
import org.geotoolkit.coverage.wkb.WKBRasterImageReader;
/**
*
* @author Johann Sorel (Geomatys)
*/
public class PGTileReference implements TileReference{
private static final WKBRasterImageReader.Spi SPI = new WKBRasterImageReader.Spi();
private final PGGridMosaic mosaic;
private final Point position;
private SoftReference<byte[]> data = null;
public PGTileReference(final PGGridMosaic mosaic, final Point position) {
this.mosaic = mosaic;
this.position = position;
}
@Override
public ImageReader getImageReader() throws IOException {
final ImageReader reader = SPI.createReaderInstance();
reader.setInput(getInput());
return reader;
}
@Override
public ImageReaderSpi getImageReaderSpi() {
return SPI;
}
@Override
public synchronized Object getInput() {
final PGCoverageStore store = mosaic.getCoverageReference().getStore();
byte[] buffer = null;
if(data != null){
buffer = data.get();
}
if(buffer == null){
try {
buffer = download();
data = new SoftReference<byte[]>(buffer);
} catch (SQLException ex) {
store.getLogger().log(Level.WARNING, ex.getMessage(),ex);
}
}
return buffer;
}
private byte[] download() throws SQLException{
final PGCoverageStore store = mosaic.getCoverageReference().getStore();
Connection cnx = null;
Statement stmt = null;
ResultSet rs = null;
try{
cnx = store.getDataSource().getConnection();
stmt = cnx.createStatement();
final long mosaicId = mosaic.getDatabaseId();
final StringBuilder query = new StringBuilder();
query.append("SELECT encode(st_asbinary(\"raster\"),'base64') FROM ");
query.append(store.encodeTableName("Tile"));
query.append(" WHERE \"mosaicId\"=").append(mosaicId);
query.append(" AND \"positionX\"=").append(position.x);
query.append(" AND \"positionY\"=").append(position.y);
rs = stmt.executeQuery(query.toString());
if(rs.next()){
byte[] data = rs.getBytes(1);
try {
data = Base64.decode(data);
} catch (IOException ex) {
throw new SQLException("Failed to uncompressed base64 : "+ex.getMessage(),ex);
}
return data;
}
throw new SQLException("No tile found for mosaic "+mosaicId +" and position "+position.x+"/"+position.y);
}finally{
store.closeSafe(cnx, stmt, rs);
}
}
@Override
public int getImageIndex() {
return 0;
}
@Override
public Point getPosition() {
return position;
}
}