/*
* Geopaparazzi - Digital field mapping on Android based devices
* Copyright (C) 2010 HydroloGIS (www.hydrologis.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.geopaparazzi.spatialite.database.spatial.core.daos;
import eu.geopaparazzi.library.database.GPLog;
import eu.geopaparazzi.spatialite.database.spatial.core.tables.AbstractSpatialTable;
import jsqlite.*;
/**
* SPL_Rasterlite related doa.
*
* @author Mark Johnson
*/
public class SPL_Rasterlite {
/**
* Retrieve rasterlite2 image of a given bound and size.
* <p/>
* <p>https://github.com/geopaparazzi/Spatialite-Tasks-with-Sql-Scripts/wiki/RL2_GetMapImageFromRaster
*
* @param db the database to use.
* @param rasterTable the table to use.
* @param tileBounds [west,south,east,north] [minx, miny, maxx, maxy] bounds.
* @param tileSize default 256 [Tile.TILE_SIZE].
* @return the image data as byte[]
*/
public static byte[] getRasterTileInBounds(Database db, AbstractSpatialTable rasterTable, double[] tileBounds, int tileSize) {
byte[] bytes = SPL_Rasterlite.rl2_GetMapImageFromRasterTile(db, rasterTable.getSrid(), rasterTable.getTableName(),
tileBounds, tileSize);
if (bytes != null) {
return bytes;
}
return null;
}
/**
* Retrieve rasterlite2 tile of a given bound [4326,wsg84] with the given size.
* <p/>
* https://github.com/geopaparazzi/Spatialite-Tasks-with-Sql-Scripts/wiki/RL2_GetMapImageFromRaster
*
* @param sqlite_db Database connection to use
* @param destSrid the destination srid (of the rasterlite2 image).
* @param coverageName the table to use.
* @param tileBounds [west,south,east,north] [minx, miny, maxx, maxy] bounds.
* @param i_tile_size default 256 [Tile.TILE_SIZE].
* @return the image data as byte[] as jpeg
*/
public static byte[] rl2_GetMapImageFromRasterTile(Database sqlite_db, String destSrid, String coverageName, double[] tileBounds,
int i_tile_size) {
return rl2_GetMapImageFromRaster(sqlite_db, "4326", destSrid, coverageName, i_tile_size, i_tile_size, tileBounds,
"default", "image/jpeg", "#ffffff", 0, 80, 1);
}
/**
* Retrieve rasterlite2 image of a given bound and size.
* - used by: SpatialiteUtilities.rl2_GetMapImageFromRasterTile to retrieve tiles only
* https://github.com/geopaparazzi/Spatialite-Tasks-with-Sql-Scripts/wiki/RL2_GetMapImageFromRaster
*
* @param sqlite_db Database connection to use
* @param sourceSrid the srid (of the n/s/e/w positions).
* @param destSrid the destination srid (of the rasterlite2 image).
* @param coverageName the table to use.
* @param width of image in pixel.
* @param height of image in pixel.
* @param tileBounds [west,south,east,north] [minx, miny, maxx, maxy] bounds.
* @param styleName used in coverage. default: 'default'
* @param mimeType 'image/tiff' etc. default: 'image/png'
* @param bgColor html-syntax etc. default: '#ffffff'
* @param transparent 0 to 100 (?).
* @param quality 0-100 (for 'image/jpeg')
* @param reaspect 1 = adapt image width,height if needed based on given bounds
* @return the image data as byte[]
*/
public static byte[] rl2_GetMapImageFromRaster(Database sqlite_db, String sourceSrid, String destSrid, String coverageName, int width,
int height, double[] tileBounds, String styleName, String mimeType, String bgColor, int transparent, int quality,
int reaspect) {
boolean doTransform = false;
if (!sourceSrid.equals(destSrid)) {
doTransform = true;
}
// sanity checks
if (styleName.equals(""))
styleName = "default";
if (mimeType.equals(""))
mimeType = "image/png";
if (bgColor.equals(""))
bgColor = "#ffffff";
if ((transparent < 0) || (transparent > 100))
transparent = 0;
if ((quality < 0) || (quality > 100))
quality = 0;
if ((reaspect < 0) || (reaspect > 1))
reaspect = 1; // adapt image width,height if needed based on given bounds [needed for
// tiles]
StringBuilder mbrSb = new StringBuilder();
if (doTransform)
mbrSb.append("ST_Transform(");
mbrSb.append("BuildMBR(");
mbrSb.append(tileBounds[0]);
mbrSb.append(",");
mbrSb.append(tileBounds[1]);
mbrSb.append(",");
mbrSb.append(tileBounds[2]);
mbrSb.append(",");
mbrSb.append(tileBounds[3]);
if (doTransform) {
mbrSb.append(",");
mbrSb.append(sourceSrid);
mbrSb.append("),");
mbrSb.append(destSrid);
}
mbrSb.append(")");
// SELECT
// RL2_GetMapImageFromRaster('1890.berlin_postgrenzen',BuildMBR(20800.0,22000.0,24000.0,19600.0),1200,1920,'default','image/png','#ffffff',0,0,1);
String mbr = mbrSb.toString();
StringBuilder qSb = new StringBuilder();
qSb.append("SELECT RL2_GetMapImageFromRaster('");
qSb.append(coverageName);
qSb.append("',");
qSb.append(mbr);
qSb.append(",");
qSb.append(Integer.toString(width));
qSb.append(",");
qSb.append(Integer.toString(height));
qSb.append(",'");
qSb.append(styleName);
qSb.append("','");
qSb.append(mimeType);
qSb.append("','");
qSb.append(bgColor);
qSb.append("',");
qSb.append(Integer.toString(transparent));
qSb.append(",");
qSb.append(Integer.toString(quality));
qSb.append(",");
qSb.append(Integer.toString(reaspect));
qSb.append(");");
String s_sql_command = qSb.toString();
Stmt stmt = null;
try {
stmt = sqlite_db.prepare(s_sql_command);
if (stmt.step()) {
byte[] ba_image = stmt.column_bytes(0);
return ba_image;
}
} catch (jsqlite.Exception e_stmt) {
/*
this internal lib error is not being caught and the application crashes
- the request was for a image 1/3 of the orignal size of 10607x8292 (3535x2764)
- big images should be avoided, since the application dies
'libc : Fatal signal 11 (SIGSEGV) at 0x80c7a000 (code=1), thread 4216 (AsyncTask #2)'
'/data/app-lib/eu.hydrologis.geopaparazzi-2/libjsqlite.so (rl2_raster_decode+8248)'
'I WindowState: WIN DEATH: Window{41ee0100 u0 eu.hydrologis.geopaparazzi/eu.hydrologis.geopaparazzi.GeoPaparazziActivity}'
*/
int i_rc = sqlite_db.last_error();
GPLog.error("SPL_Rasterlite", "rl2_GetMapImageFromRaster sql[" + s_sql_command + "] rc=" + i_rc + "]", e_stmt);
} finally {
try {
if (stmt != null) {
stmt.close();
}
} catch (jsqlite.Exception e) {
GPLog.error("SPL_Rasterlite", null, e);
}
}
return null;
}
}