/*
* 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.geometry;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.WKBReader;
import java.util.Iterator;
import eu.geopaparazzi.library.database.GPLog;
import jsqlite.Constants;
import jsqlite.Database;
import jsqlite.Exception;
import jsqlite.Stmt;
/**
* Class that iterates over Database geometries and doesn't keep everything in memory.
*
* @author Andrea Antonello (www.hydrologis.com)
*/
@SuppressWarnings("nls")
public class GeometryIterator implements Iterator<Geometry> {
private WKBReader wkbReader = new WKBReader();
private Stmt stmt;
private String labelText = "";
/**
* Returns Label String (if any)
*
* <p>
* - if any label is being supported, will build s_label from column 1 to end<br>
* -- each column (after 1) will have a ', ' inserted<br>
* -- s_label will be empty if no label was requested<br>
* @return s_label
*/
public String getLabelText() {
return labelText;
}
/**
* Builds Label String (if any)
*
* <p>
* - assumes that column 0 is ALWAYS a Geometry<br>
* - if any label is being supported, will build s_label from column 1 to end<br>
* -- each column (after 1) will have a ', ' inserted<br>
* -- s_label will be set to blank before filling<br>
* @param stmt statement being executed
*/
private void setLabelText( Stmt stmt ) {
labelText = "";
int i = 1;
int columnCount = 0;
try {
if ((stmt != null) && (columnCount = stmt.column_count()) > 1) {
for( i = 1; i < columnCount; i++ ) {
if (!labelText.equals("")) {
labelText += ", ";
}
switch( stmt.column_type(i) ) {
case Constants.SQLITE_INTEGER: {
labelText = labelText + stmt.column_int(i);
}
break;
case Constants.SQLITE_FLOAT: {
labelText += String.format("%.5f", stmt.column_double(i));
}
break;
case Constants.SQLITE_BLOB: { // not supported
}
break;
case Constants.SQLITE3_TEXT: {
labelText += stmt.column_string(i);
}
break;
}
}
}
} catch (Exception e) {
GPLog.error(this, "GeometryIterator.setLabelText column_count[" + columnCount + "] column[" + i + "]", e);
}
}
/**
* Constructor.
*
* @param database the database to use.
* @param query the query to use.
*/
public GeometryIterator( Database database, String query ) {
try {
stmt = database.prepare(query);
} catch (Exception e) {
GPLog.error(this, "GeometryIterator.creation sql[" + query + "]", e);
}
}
@Override
public boolean hasNext() {
if (stmt == null) {
return false;
}
try { // sqlite-amalgamation-3080100 allways returns false with BLOBS
return stmt.step();
} catch (Exception e) {
GPLog.error(this, "GeometryIterator.hasNext()[stmt.step() failed]", e);
return false;
}
}
@Override
public Geometry next() {
if (stmt == null) {
GPLog.androidLog(4, "GeometryIterator.next() [stmt=null]");
return null;
}
try {
byte[] geomBytes = stmt.column_bytes(0);
Geometry geometry = wkbReader.read(geomBytes);
setLabelText(stmt);
return geometry;
} catch (java.lang.Exception e) {
GPLog.error(this, "GeometryIterator.next()[wkbReader.read() failed]", e);
}
return null;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
/**
* Reset the iterator.
*
* @throws Exception if something goes wrong.
*/
public void reset() throws Exception {
if (stmt != null)
stmt.reset();
}
/**
* Close the iterator.
*
* @throws Exception if something goes wrong.
*/
public void close() throws Exception {
if (stmt != null)
stmt.close();
}
}