Strabon

changeset 363:e3ed13f91924

moved KML writer/factory to sparqlkml package
author Babis Nikolaou <charnik@di.uoa.gr>
date Mon Jun 25 21:28:17 2012 +0300 (2012-06-25)
parents de06ce11788d
children 41c47d1e334e
files resultio/src/main/java/org/openrdf/query/resultio/sparqlkml/stSPARQLResultsKMLWriter.java resultio/src/main/java/org/openrdf/query/resultio/sparqlkml/stSPARQLResultsKMLWriterFactory.java resultio/src/main/java/org/openrdf/query/resultio/sparqlkml/stSPARQLResultsKMZWriter.java resultio/src/main/java/org/openrdf/query/resultio/sparqlxml/stSPARQLResultsKMLWriter.java resultio/src/main/java/org/openrdf/query/resultio/sparqlxml/stSPARQLResultsKMLWriterFactory.java resultio/src/main/java/org/openrdf/query/resultio/stSPARQLQueryResultWriterFactory.java runtime/src/main/java/eu/earthobservatory/runtime/generaldb/Strabon.java
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/resultio/src/main/java/org/openrdf/query/resultio/sparqlkml/stSPARQLResultsKMLWriter.java	Mon Jun 25 21:28:17 2012 +0300
     1.3 @@ -0,0 +1,389 @@
     1.4 +package org.openrdf.query.resultio.sparqlkml;
     1.5 +
     1.6 +import java.io.ByteArrayOutputStream;
     1.7 +import java.io.IOException;
     1.8 +import java.io.OutputStream;
     1.9 +import java.util.List;
    1.10 +
    1.11 +import javax.xml.namespace.QName;
    1.12 +
    1.13 +import org.geotools.kml.KML;
    1.14 +import org.geotools.kml.KMLConfiguration;
    1.15 +import org.geotools.xml.Encoder;
    1.16 +import org.openrdf.model.BNode;
    1.17 +import org.openrdf.model.Literal;
    1.18 +import org.openrdf.model.Value;
    1.19 +import org.openrdf.query.Binding;
    1.20 +import org.openrdf.query.BindingSet;
    1.21 +import org.openrdf.query.TupleQueryResultHandlerException;
    1.22 +import org.openrdf.query.algebra.evaluation.function.spatial.StrabonPolyhedron;
    1.23 +import org.openrdf.query.algebra.evaluation.function.spatial.WKTHelper;
    1.24 +import org.openrdf.query.algebra.evaluation.util.JTSWrapper;
    1.25 +import org.openrdf.query.resultio.TupleQueryResultFormat;
    1.26 +import org.openrdf.query.resultio.TupleQueryResultWriter;
    1.27 +import org.openrdf.query.resultio.stSPARQLQueryResultFormat;
    1.28 +import org.openrdf.query.resultio.sparqlxml.stSPARQLXMLWriter;
    1.29 +import org.openrdf.sail.generaldb.model.GeneralDBPolyhedron;
    1.30 +import org.openrdf.sail.generaldb.model.XMLGSDatatypeUtil;
    1.31 +import org.slf4j.Logger;
    1.32 +import org.slf4j.LoggerFactory;
    1.33 +
    1.34 +import com.vividsolutions.jts.geom.Geometry;
    1.35 +import com.vividsolutions.jts.geom.GeometryCollection;
    1.36 +import com.vividsolutions.jts.geom.LineString;
    1.37 +import com.vividsolutions.jts.geom.MultiLineString;
    1.38 +import com.vividsolutions.jts.geom.MultiPoint;
    1.39 +import com.vividsolutions.jts.geom.MultiPolygon;
    1.40 +import com.vividsolutions.jts.geom.Point;
    1.41 +import com.vividsolutions.jts.geom.Polygon;
    1.42 +import com.vividsolutions.jts.io.ParseException;
    1.43 +
    1.44 +/**
    1.45 + * @author Manos Karpathiotakis <mk@di.uoa.gr>
    1.46 + * @author Charalampos Nikolaou <charnik@di.uoa.gr>
    1.47 + *
    1.48 + */
    1.49 +public class stSPARQLResultsKMLWriter implements TupleQueryResultWriter {
    1.50 +
    1.51 +	private static final Logger logger = LoggerFactory.getLogger(org.openrdf.query.resultio.sparqlkml.stSPARQLResultsKMLWriter.class);
    1.52 +	
    1.53 +	private static final String ROOT_TAG 			= "kml";
    1.54 +	private static final String NAMESPACE 			= "http://www.opengis.net/kml/2.2";
    1.55 +	private static final String RESULT_SET_TAG		= "Folder";
    1.56 +	
    1.57 +	private static final String PLACEMARK_TAG		= "Placemark";
    1.58 +	private static final String NAME_TAG			= "name";
    1.59 +	private static final String DESC_TAG			= "description";
    1.60 +	
    1.61 +	private static final String TABLE_ROW_BEGIN		= "<TR>";
    1.62 +	private static final String TABLE_ROW_END		= "</TR>";
    1.63 +	private static final String TABLE_DATA_BEGIN	= "<TD>";
    1.64 +	private static final String TABLE_DATA_END		= "</TD>";
    1.65 +	
    1.66 +	private static final String NEWLINE				= "\n";
    1.67 +	
    1.68 +	private static final String TABLE_DESC_BEGIN	= "<![CDATA[<TABLE border=\"1\">" + NEWLINE;
    1.69 +	private static final String TABLE_DESC_END		= "</TABLE>]]>" + NEWLINE;
    1.70 +	
    1.71 +	private static final String GEOMETRY_NAME		= "Geometry";
    1.72 +	
    1.73 +	/**
    1.74 +	 * The underlying XML formatter.
    1.75 +	 */
    1.76 +	private stSPARQLXMLWriter xmlWriter;
    1.77 +	
    1.78 +	/**
    1.79 +	 * The number of results seen.
    1.80 +	 */
    1.81 +	private int nresults;
    1.82 +	
    1.83 +	/**
    1.84 +	 * The number of geometries seen.
    1.85 +	 */
    1.86 +	private int ngeometries;
    1.87 +
    1.88 +	/**
    1.89 +	 * The JTS wrapper
    1.90 +	 */
    1.91 +	private JTSWrapper jts;
    1.92 +	
    1.93 +	/**
    1.94 +	 * Stream for manipulating geometries
    1.95 +	 */
    1.96 +	private ByteArrayOutputStream baos;
    1.97 +	
    1.98 +	/**
    1.99 +	 * Description string holding the projected variables
   1.100 +	 * of the SPARQL query
   1.101 +	 */
   1.102 +	private StringBuilder descHeader;
   1.103 +	
   1.104 +	/**
   1.105 +	 * Description string holding the values for the
   1.106 +	 * projected variables of the SPARQL query
   1.107 +	 */
   1.108 +	private StringBuilder descData;
   1.109 +	
   1.110 +	/**
   1.111 +	 * Indentation used in tags that are constructed manually
   1.112 +	 */
   1.113 +	private int depth;
   1.114 +	
   1.115 +	/**
   1.116 +	 * Creates an stSPARQLResultsKMLWriter that encodes the SPARQL
   1.117 +	 * results in KML.
   1.118 +	 * 
   1.119 +	 * @param out
   1.120 +	 */
   1.121 +	public stSPARQLResultsKMLWriter(OutputStream out) {
   1.122 +		this(new stSPARQLXMLWriter(out));
   1.123 +	}
   1.124 +	
   1.125 +	public stSPARQLResultsKMLWriter(stSPARQLXMLWriter writer) {
   1.126 +		xmlWriter = writer;
   1.127 +		xmlWriter.setPrettyPrint(true);
   1.128 +		
   1.129 +		depth = 4;
   1.130 +				
   1.131 +		jts = JTSWrapper.getInstance();
   1.132 +		
   1.133 +		baos = new ByteArrayOutputStream();
   1.134 +		
   1.135 +		descHeader = new StringBuilder();
   1.136 +		descData = new StringBuilder();
   1.137 +		
   1.138 +		nresults = 0;
   1.139 +		ngeometries = 0;
   1.140 +	}
   1.141 +	
   1.142 +	@Override
   1.143 +	public void startQueryResult(List<String> bindingNames) throws TupleQueryResultHandlerException {
   1.144 +		try {
   1.145 +			xmlWriter.startDocument();
   1.146 +
   1.147 +			xmlWriter.setAttribute("xmlns", NAMESPACE);
   1.148 +			xmlWriter.startTag(ROOT_TAG);
   1.149 +			xmlWriter.startTag(RESULT_SET_TAG);
   1.150 +		}
   1.151 +		catch (IOException e) {
   1.152 +			throw new TupleQueryResultHandlerException(e);
   1.153 +		}
   1.154 +	}
   1.155 +
   1.156 +	@Override
   1.157 +	public void endQueryResult() throws TupleQueryResultHandlerException {
   1.158 +		try {
   1.159 +			xmlWriter.endTag(RESULT_SET_TAG);
   1.160 +			xmlWriter.endTag(ROOT_TAG);
   1.161 +
   1.162 +			xmlWriter.endDocument();
   1.163 +			
   1.164 +			baos.close();
   1.165 +			
   1.166 +			if (ngeometries < nresults) {
   1.167 +				logger.warn("[Strabon.KMLWriter] No spatial binding found in the result. KML requires that at least one binding maps to a geometry.", nresults);
   1.168 +			}
   1.169 +		}
   1.170 +		catch (IOException e) {
   1.171 +			throw new TupleQueryResultHandlerException(e);
   1.172 +		}
   1.173 +	}
   1.174 +
   1.175 +	@Override
   1.176 +	public void handleSolution(BindingSet bindingSet) throws TupleQueryResultHandlerException {
   1.177 +		try {
   1.178 +			// true if there are bindings that do not correspond to geometries
   1.179 +			boolean hasDesc = false;
   1.180 +			
   1.181 +			// increase result size
   1.182 +			nresults++;
   1.183 +			
   1.184 +			// create description table and header
   1.185 +			indent(descHeader, depth);
   1.186 +			descHeader.append(TABLE_DESC_BEGIN);
   1.187 +			indent(descHeader, depth);
   1.188 +			descHeader.append(TABLE_ROW_BEGIN);
   1.189 +			
   1.190 +			// create description table data row
   1.191 +			descData.append(NEWLINE);
   1.192 +			indent(descData, depth);
   1.193 +			descData.append(TABLE_ROW_BEGIN);
   1.194 +
   1.195 +			// write placemark tag
   1.196 +			xmlWriter.startTag(PLACEMARK_TAG);
   1.197 +			xmlWriter.textElement(NAME_TAG, GEOMETRY_NAME + nresults + "_" + ngeometries);
   1.198 +			
   1.199 +			// parse binding set
   1.200 +			for (Binding binding : bindingSet) {
   1.201 +				Value value = binding.getValue();
   1.202 +
   1.203 +				// check for geometry value
   1.204 +				if (XMLGSDatatypeUtil.isGeometryValue(value)) {
   1.205 +					ngeometries++;
   1.206 +						
   1.207 +					if (logger.isDebugEnabled()) {
   1.208 +						logger.debug("[Strabon] Found geometry: {}", value);
   1.209 +					}
   1.210 +					
   1.211 +					xmlWriter.unescapedText(getKML(value));
   1.212 +				
   1.213 +				} else { // URI, BlankNode, or Literal other than spatial literal 
   1.214 +					if (logger.isDebugEnabled()) {
   1.215 +						logger.debug("[Strabon.KMLWriter] Found URI/BlankNode/Literal: {}", value);
   1.216 +					}
   1.217 +					
   1.218 +					// mark that we found sth corresponding to the description
   1.219 +					hasDesc = true;
   1.220 +					
   1.221 +					// write description
   1.222 +					writeDesc(binding);
   1.223 +				}
   1.224 +			}
   1.225 +			
   1.226 +			// we have found and constructed a description for this result. Write it down.
   1.227 +			if (hasDesc) {
   1.228 +				// close the header of the description
   1.229 +				descHeader.append(NEWLINE);
   1.230 +				indent(descHeader, depth);
   1.231 +				descHeader.append(TABLE_ROW_END);
   1.232 +				
   1.233 +				// end the placeholder for the description data
   1.234 +				descData.append(NEWLINE);
   1.235 +				indent(descData, depth);
   1.236 +				descData.append(TABLE_ROW_END);
   1.237 +				
   1.238 +				// append to the table header the actual content from
   1.239 +				// the bindings
   1.240 +				descHeader.append(descData);
   1.241 +				
   1.242 +				// close the table for the description
   1.243 +				descHeader.append(NEWLINE);
   1.244 +				indent(descHeader, depth);
   1.245 +				descHeader.append(TABLE_DESC_END);
   1.246 +				
   1.247 +				// begin the "description" tag
   1.248 +				xmlWriter.startTag(DESC_TAG);
   1.249 +				
   1.250 +				// write the actual description
   1.251 +				xmlWriter.unescapedText(descHeader.toString());
   1.252 +				
   1.253 +				// end the "description" tag
   1.254 +				xmlWriter.endTag(DESC_TAG);
   1.255 +			}
   1.256 +			
   1.257 +			// clear description string builders
   1.258 +			descHeader.setLength(0);
   1.259 +			descData.setLength(0);
   1.260 +
   1.261 +			// write the placemark
   1.262 +			xmlWriter.endTag(PLACEMARK_TAG);
   1.263 +		}
   1.264 +		catch (IOException e) {
   1.265 +			throw new TupleQueryResultHandlerException(e);
   1.266 +		}
   1.267 +	}
   1.268 +
   1.269 +	private String getKML(Value value) {
   1.270 +		String kml = "";
   1.271 +		QName geometryType = null;
   1.272 +		
   1.273 +		// the underlying geometry in value
   1.274 +		Geometry geom = null;
   1.275 +		
   1.276 +		// the underlying SRID of the geometry
   1.277 +		int srid = -1;
   1.278 +		
   1.279 +		// get the KML encoder
   1.280 +		Encoder encoder = null;
   1.281 +		
   1.282 +		try {
   1.283 +			encoder = new Encoder(new KMLConfiguration());
   1.284 +			encoder.setIndenting(true);
   1.285 +			
   1.286 +			if (value instanceof GeneralDBPolyhedron) {
   1.287 +				GeneralDBPolyhedron dbpolyhedron = (GeneralDBPolyhedron) value;
   1.288 +				
   1.289 +				geom = dbpolyhedron.getPolyhedron().getGeometry();
   1.290 +				srid = dbpolyhedron.getPolyhedron().getGeometry().getSRID();
   1.291 +				
   1.292 +			} else { // spatial literal
   1.293 +				Literal spatial = (Literal) value;
   1.294 +				
   1.295 +				if (XMLGSDatatypeUtil.isWKTLiteral(spatial)) { // WKT
   1.296 +					String wkt = spatial.stringValue();
   1.297 +					
   1.298 +					geom = jts.WKTread(WKTHelper.getWithoutSRID(wkt));
   1.299 +					srid = WKTHelper.getSRID(wkt);
   1.300 +					
   1.301 +				} else { // GML
   1.302 +					logger.warn("[Strabon.KMLWriter] GML is not supported yet");
   1.303 +				}
   1.304 +			}
   1.305 +			
   1.306 +			// transform the geometry to 4326
   1.307 +			geom = jts.transform(geom, srid, StrabonPolyhedron.defaultSRID);
   1.308 +			
   1.309 +			if (geom instanceof Point) {
   1.310 +				geometryType = KML.Point;
   1.311 +				
   1.312 +			} else if (geom instanceof Polygon) {
   1.313 +				geometryType = KML.Polygon;
   1.314 +				
   1.315 +			} else if (geom instanceof LineString) {
   1.316 +				geometryType = KML.LineString;
   1.317 +				
   1.318 +			} else if (geom instanceof MultiPoint) {
   1.319 +				geometryType = KML.MultiGeometry;
   1.320 +				
   1.321 +			} else if (geom instanceof MultiLineString) {
   1.322 +				geometryType = KML.MultiGeometry;
   1.323 +				
   1.324 +			} else if (geom instanceof MultiPolygon) {
   1.325 +				geometryType = KML.MultiGeometry;
   1.326 +				
   1.327 +			} else if (geom instanceof GeometryCollection) {
   1.328 +				geometryType = KML.MultiGeometry;
   1.329 +				
   1.330 +			} 
   1.331 +			
   1.332 +			if (geometryType == null) {
   1.333 +				logger.warn("[Strabon.KMLWriter] Found unknown geometry type.");
   1.334 +				
   1.335 +			} else {
   1.336 +			
   1.337 +				encoder.encode(geom, geometryType, baos);
   1.338 +				kml = baos.toString().substring(38).replaceAll(" xmlns:kml=\"http://earth.google.com/kml/2.1\"","").replaceAll("kml:","");
   1.339 +				baos.reset();
   1.340 +			}
   1.341 +			
   1.342 +		} catch (ParseException e) {
   1.343 +			logger.error("[Strabon.KMLWriter] Parse error exception of geometry: {}", e.getMessage());
   1.344 +			
   1.345 +		} catch (IOException e) {
   1.346 +			logger.error("[Strabon.KMLWriter] IOException during KML encoding of geometry: {}", e.getMessage());
   1.347 +		}
   1.348 +		
   1.349 +		return kml;
   1.350 +	}
   1.351 +
   1.352 +	/**
   1.353 +	 * Adds to the description table information for a binding.
   1.354 +	 * 
   1.355 +	 * @param binding
   1.356 +	 */
   1.357 +	private void writeDesc(Binding binding) {
   1.358 +		descHeader.append(NEWLINE);
   1.359 +		indent(descHeader, depth + 1);
   1.360 +		descHeader.append(TABLE_DATA_BEGIN);
   1.361 +		descHeader.append(binding.getName());
   1.362 +		descHeader.append(TABLE_DATA_END);
   1.363 +		
   1.364 +		descData.append(NEWLINE);
   1.365 +		indent(descData, depth + 1);
   1.366 +		descData.append(TABLE_DATA_BEGIN);
   1.367 +		if (binding.getValue() instanceof BNode) {
   1.368 +			descData.append("_:");
   1.369 +		}
   1.370 +		descData.append(binding.getValue().stringValue());
   1.371 +		descData.append(TABLE_DATA_END);
   1.372 +		
   1.373 +	}
   1.374 +
   1.375 +	@Override
   1.376 +	public TupleQueryResultFormat getTupleQueryResultFormat() {
   1.377 +		return stSPARQLQueryResultFormat.KML;
   1.378 +	}
   1.379 +	
   1.380 +	/**
   1.381 +	 * Adds indentation to the given string builder according to 
   1.382 +	 * the specified depth.
   1.383 +	 * 
   1.384 +	 * @param sb
   1.385 +	 * @param depth
   1.386 +	 */
   1.387 +	private void indent(StringBuilder sb, int depth) {
   1.388 +		for (int i = 0; i < depth; i++) {
   1.389 +			sb.append(xmlWriter.getIndentString());
   1.390 +		}
   1.391 +	}
   1.392 +}
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/resultio/src/main/java/org/openrdf/query/resultio/sparqlkml/stSPARQLResultsKMLWriterFactory.java	Mon Jun 25 21:28:17 2012 +0300
     2.3 @@ -0,0 +1,26 @@
     2.4 +package org.openrdf.query.resultio.sparqlkml;
     2.5 +
     2.6 +import java.io.OutputStream;
     2.7 +
     2.8 +import org.openrdf.query.resultio.TupleQueryResultFormat;
     2.9 +import org.openrdf.query.resultio.TupleQueryResultWriter;
    2.10 +import org.openrdf.query.resultio.TupleQueryResultWriterFactory;
    2.11 +import org.openrdf.query.resultio.stSPARQLQueryResultFormat;
    2.12 +
    2.13 +/**
    2.14 + * @author Charalampos Nikolaou <charnik@di.uoa.gr>
    2.15 + *
    2.16 + */
    2.17 +public class stSPARQLResultsKMLWriterFactory implements TupleQueryResultWriterFactory {
    2.18 +
    2.19 +	@Override
    2.20 +	public TupleQueryResultFormat getTupleQueryResultFormat() {
    2.21 +		return stSPARQLQueryResultFormat.KML;
    2.22 +	}
    2.23 +
    2.24 +	@Override
    2.25 +	public TupleQueryResultWriter getWriter(OutputStream out) {
    2.26 +		return new stSPARQLResultsKMLWriter(out);
    2.27 +	}
    2.28 +
    2.29 +}
     3.1 --- a/resultio/src/main/java/org/openrdf/query/resultio/sparqlkml/stSPARQLResultsKMZWriter.java	Mon Jun 25 21:22:31 2012 +0300
     3.2 +++ b/resultio/src/main/java/org/openrdf/query/resultio/sparqlkml/stSPARQLResultsKMZWriter.java	Mon Jun 25 21:28:17 2012 +0300
     3.3 @@ -11,7 +11,7 @@
     3.4  import org.openrdf.query.resultio.TupleQueryResultFormat;
     3.5  import org.openrdf.query.resultio.TupleQueryResultWriter;
     3.6  import org.openrdf.query.resultio.stSPARQLQueryResultFormat;
     3.7 -import org.openrdf.query.resultio.sparqlxml.stSPARQLResultsKMLWriter;
     3.8 +import org.openrdf.query.resultio.sparqlkml.stSPARQLResultsKMLWriter;
     3.9  
    3.10  /**
    3.11   * @author Charalampos Nikolaou <charnik@di.uoa.gr>
     4.1 --- a/resultio/src/main/java/org/openrdf/query/resultio/sparqlxml/stSPARQLResultsKMLWriter.java	Mon Jun 25 21:22:31 2012 +0300
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,388 +0,0 @@
     4.4 -package org.openrdf.query.resultio.sparqlxml;
     4.5 -
     4.6 -import java.io.ByteArrayOutputStream;
     4.7 -import java.io.IOException;
     4.8 -import java.io.OutputStream;
     4.9 -import java.util.List;
    4.10 -
    4.11 -import javax.xml.namespace.QName;
    4.12 -
    4.13 -import org.geotools.kml.KML;
    4.14 -import org.geotools.kml.KMLConfiguration;
    4.15 -import org.geotools.xml.Encoder;
    4.16 -import org.openrdf.model.BNode;
    4.17 -import org.openrdf.model.Literal;
    4.18 -import org.openrdf.model.Value;
    4.19 -import org.openrdf.query.Binding;
    4.20 -import org.openrdf.query.BindingSet;
    4.21 -import org.openrdf.query.TupleQueryResultHandlerException;
    4.22 -import org.openrdf.query.algebra.evaluation.function.spatial.StrabonPolyhedron;
    4.23 -import org.openrdf.query.algebra.evaluation.function.spatial.WKTHelper;
    4.24 -import org.openrdf.query.algebra.evaluation.util.JTSWrapper;
    4.25 -import org.openrdf.query.resultio.TupleQueryResultFormat;
    4.26 -import org.openrdf.query.resultio.TupleQueryResultWriter;
    4.27 -import org.openrdf.query.resultio.stSPARQLQueryResultFormat;
    4.28 -import org.openrdf.sail.generaldb.model.GeneralDBPolyhedron;
    4.29 -import org.openrdf.sail.generaldb.model.XMLGSDatatypeUtil;
    4.30 -import org.slf4j.Logger;
    4.31 -import org.slf4j.LoggerFactory;
    4.32 -
    4.33 -import com.vividsolutions.jts.geom.Geometry;
    4.34 -import com.vividsolutions.jts.geom.GeometryCollection;
    4.35 -import com.vividsolutions.jts.geom.LineString;
    4.36 -import com.vividsolutions.jts.geom.MultiLineString;
    4.37 -import com.vividsolutions.jts.geom.MultiPoint;
    4.38 -import com.vividsolutions.jts.geom.MultiPolygon;
    4.39 -import com.vividsolutions.jts.geom.Point;
    4.40 -import com.vividsolutions.jts.geom.Polygon;
    4.41 -import com.vividsolutions.jts.io.ParseException;
    4.42 -
    4.43 -/**
    4.44 - * @author Manos Karpathiotakis <mk@di.uoa.gr>
    4.45 - * @author Charalampos Nikolaou <charnik@di.uoa.gr>
    4.46 - *
    4.47 - */
    4.48 -public class stSPARQLResultsKMLWriter implements TupleQueryResultWriter {
    4.49 -
    4.50 -	private static final Logger logger = LoggerFactory.getLogger(org.openrdf.query.resultio.sparqlxml.stSPARQLResultsKMLWriter.class);
    4.51 -	
    4.52 -	private static final String ROOT_TAG 			= "kml";
    4.53 -	private static final String NAMESPACE 			= "http://www.opengis.net/kml/2.2";
    4.54 -	private static final String RESULT_SET_TAG		= "Folder";
    4.55 -	
    4.56 -	private static final String PLACEMARK_TAG		= "Placemark";
    4.57 -	private static final String NAME_TAG			= "name";
    4.58 -	private static final String DESC_TAG			= "description";
    4.59 -	
    4.60 -	private static final String TABLE_ROW_BEGIN		= "<TR>";
    4.61 -	private static final String TABLE_ROW_END		= "</TR>";
    4.62 -	private static final String TABLE_DATA_BEGIN	= "<TD>";
    4.63 -	private static final String TABLE_DATA_END		= "</TD>";
    4.64 -	
    4.65 -	private static final String NEWLINE				= "\n";
    4.66 -	
    4.67 -	private static final String TABLE_DESC_BEGIN	= "<![CDATA[<TABLE border=\"1\">" + NEWLINE;
    4.68 -	private static final String TABLE_DESC_END		= "</TABLE>]]>" + NEWLINE;
    4.69 -	
    4.70 -	private static final String GEOMETRY_NAME		= "Geometry";
    4.71 -	
    4.72 -	/**
    4.73 -	 * The underlying XML formatter.
    4.74 -	 */
    4.75 -	private stSPARQLXMLWriter xmlWriter;
    4.76 -	
    4.77 -	/**
    4.78 -	 * The number of results seen.
    4.79 -	 */
    4.80 -	private int nresults;
    4.81 -	
    4.82 -	/**
    4.83 -	 * The number of geometries seen.
    4.84 -	 */
    4.85 -	private int ngeometries;
    4.86 -
    4.87 -	/**
    4.88 -	 * The JTS wrapper
    4.89 -	 */
    4.90 -	private JTSWrapper jts;
    4.91 -	
    4.92 -	/**
    4.93 -	 * Stream for manipulating geometries
    4.94 -	 */
    4.95 -	private ByteArrayOutputStream baos;
    4.96 -	
    4.97 -	/**
    4.98 -	 * Description string holding the projected variables
    4.99 -	 * of the SPARQL query
   4.100 -	 */
   4.101 -	private StringBuilder descHeader;
   4.102 -	
   4.103 -	/**
   4.104 -	 * Description string holding the values for the
   4.105 -	 * projected variables of the SPARQL query
   4.106 -	 */
   4.107 -	private StringBuilder descData;
   4.108 -	
   4.109 -	/**
   4.110 -	 * Indentation used in tags that are constructed manually
   4.111 -	 */
   4.112 -	private int depth;
   4.113 -	
   4.114 -	/**
   4.115 -	 * Creates an stSPARQLResultsKMLWriter that encodes the SPARQL
   4.116 -	 * results in KML.
   4.117 -	 * 
   4.118 -	 * @param out
   4.119 -	 */
   4.120 -	public stSPARQLResultsKMLWriter(OutputStream out) {
   4.121 -		this(new stSPARQLXMLWriter(out));
   4.122 -	}
   4.123 -	
   4.124 -	public stSPARQLResultsKMLWriter(stSPARQLXMLWriter writer) {
   4.125 -		xmlWriter = writer;
   4.126 -		xmlWriter.setPrettyPrint(true);
   4.127 -		
   4.128 -		depth = 4;
   4.129 -				
   4.130 -		jts = JTSWrapper.getInstance();
   4.131 -		
   4.132 -		baos = new ByteArrayOutputStream();
   4.133 -		
   4.134 -		descHeader = new StringBuilder();
   4.135 -		descData = new StringBuilder();
   4.136 -		
   4.137 -		nresults = 0;
   4.138 -		ngeometries = 0;
   4.139 -	}
   4.140 -	
   4.141 -	@Override
   4.142 -	public void startQueryResult(List<String> bindingNames) throws TupleQueryResultHandlerException {
   4.143 -		try {
   4.144 -			xmlWriter.startDocument();
   4.145 -
   4.146 -			xmlWriter.setAttribute("xmlns", NAMESPACE);
   4.147 -			xmlWriter.startTag(ROOT_TAG);
   4.148 -			xmlWriter.startTag(RESULT_SET_TAG);
   4.149 -		}
   4.150 -		catch (IOException e) {
   4.151 -			throw new TupleQueryResultHandlerException(e);
   4.152 -		}
   4.153 -	}
   4.154 -
   4.155 -	@Override
   4.156 -	public void endQueryResult() throws TupleQueryResultHandlerException {
   4.157 -		try {
   4.158 -			xmlWriter.endTag(RESULT_SET_TAG);
   4.159 -			xmlWriter.endTag(ROOT_TAG);
   4.160 -
   4.161 -			xmlWriter.endDocument();
   4.162 -			
   4.163 -			baos.close();
   4.164 -			
   4.165 -			if (ngeometries < nresults) {
   4.166 -				logger.warn("[Strabon.KMLWriter] No spatial binding found in the result. KML requires that at least one binding maps to a geometry.", nresults);
   4.167 -			}
   4.168 -		}
   4.169 -		catch (IOException e) {
   4.170 -			throw new TupleQueryResultHandlerException(e);
   4.171 -		}
   4.172 -	}
   4.173 -
   4.174 -	@Override
   4.175 -	public void handleSolution(BindingSet bindingSet) throws TupleQueryResultHandlerException {
   4.176 -		try {
   4.177 -			// true if there are bindings that do not correspond to geometries
   4.178 -			boolean hasDesc = false;
   4.179 -			
   4.180 -			// increase result size
   4.181 -			nresults++;
   4.182 -			
   4.183 -			// create description table and header
   4.184 -			indent(descHeader, depth);
   4.185 -			descHeader.append(TABLE_DESC_BEGIN);
   4.186 -			indent(descHeader, depth);
   4.187 -			descHeader.append(TABLE_ROW_BEGIN);
   4.188 -			
   4.189 -			// create description table data row
   4.190 -			descData.append(NEWLINE);
   4.191 -			indent(descData, depth);
   4.192 -			descData.append(TABLE_ROW_BEGIN);
   4.193 -
   4.194 -			// write placemark tag
   4.195 -			xmlWriter.startTag(PLACEMARK_TAG);
   4.196 -			xmlWriter.textElement(NAME_TAG, GEOMETRY_NAME + nresults + "_" + ngeometries);
   4.197 -			
   4.198 -			// parse binding set
   4.199 -			for (Binding binding : bindingSet) {
   4.200 -				Value value = binding.getValue();
   4.201 -
   4.202 -				// check for geometry value
   4.203 -				if (XMLGSDatatypeUtil.isGeometryValue(value)) {
   4.204 -					ngeometries++;
   4.205 -						
   4.206 -					if (logger.isDebugEnabled()) {
   4.207 -						logger.debug("[Strabon] Found geometry: {}", value);
   4.208 -					}
   4.209 -					
   4.210 -					xmlWriter.unescapedText(getKML(value));
   4.211 -				
   4.212 -				} else { // URI, BlankNode, or Literal other than spatial literal 
   4.213 -					if (logger.isDebugEnabled()) {
   4.214 -						logger.debug("[Strabon.KMLWriter] Found URI/BlankNode/Literal: {}", value);
   4.215 -					}
   4.216 -					
   4.217 -					// mark that we found sth corresponding to the description
   4.218 -					hasDesc = true;
   4.219 -					
   4.220 -					// write description
   4.221 -					writeDesc(binding);
   4.222 -				}
   4.223 -			}
   4.224 -			
   4.225 -			// we have found and constructed a description for this result. Write it down.
   4.226 -			if (hasDesc) {
   4.227 -				// close the header of the description
   4.228 -				descHeader.append(NEWLINE);
   4.229 -				indent(descHeader, depth);
   4.230 -				descHeader.append(TABLE_ROW_END);
   4.231 -				
   4.232 -				// end the placeholder for the description data
   4.233 -				descData.append(NEWLINE);
   4.234 -				indent(descData, depth);
   4.235 -				descData.append(TABLE_ROW_END);
   4.236 -				
   4.237 -				// append to the table header the actual content from
   4.238 -				// the bindings
   4.239 -				descHeader.append(descData);
   4.240 -				
   4.241 -				// close the table for the description
   4.242 -				descHeader.append(NEWLINE);
   4.243 -				indent(descHeader, depth);
   4.244 -				descHeader.append(TABLE_DESC_END);
   4.245 -				
   4.246 -				// begin the "description" tag
   4.247 -				xmlWriter.startTag(DESC_TAG);
   4.248 -				
   4.249 -				// write the actual description
   4.250 -				xmlWriter.unescapedText(descHeader.toString());
   4.251 -				
   4.252 -				// end the "description" tag
   4.253 -				xmlWriter.endTag(DESC_TAG);
   4.254 -			}
   4.255 -			
   4.256 -			// clear description string builders
   4.257 -			descHeader.setLength(0);
   4.258 -			descData.setLength(0);
   4.259 -
   4.260 -			// write the placemark
   4.261 -			xmlWriter.endTag(PLACEMARK_TAG);
   4.262 -		}
   4.263 -		catch (IOException e) {
   4.264 -			throw new TupleQueryResultHandlerException(e);
   4.265 -		}
   4.266 -	}
   4.267 -
   4.268 -	private String getKML(Value value) {
   4.269 -		String kml = "";
   4.270 -		QName geometryType = null;
   4.271 -		
   4.272 -		// the underlying geometry in value
   4.273 -		Geometry geom = null;
   4.274 -		
   4.275 -		// the underlying SRID of the geometry
   4.276 -		int srid = -1;
   4.277 -		
   4.278 -		// get the KML encoder
   4.279 -		Encoder encoder = null;
   4.280 -		
   4.281 -		try {
   4.282 -			encoder = new Encoder(new KMLConfiguration());
   4.283 -			encoder.setIndenting(true);
   4.284 -			
   4.285 -			if (value instanceof GeneralDBPolyhedron) {
   4.286 -				GeneralDBPolyhedron dbpolyhedron = (GeneralDBPolyhedron) value;
   4.287 -				
   4.288 -				geom = dbpolyhedron.getPolyhedron().getGeometry();
   4.289 -				srid = dbpolyhedron.getPolyhedron().getGeometry().getSRID();
   4.290 -				
   4.291 -			} else { // spatial literal
   4.292 -				Literal spatial = (Literal) value;
   4.293 -				
   4.294 -				if (XMLGSDatatypeUtil.isWKTLiteral(spatial)) { // WKT
   4.295 -					String wkt = spatial.stringValue();
   4.296 -					
   4.297 -					geom = jts.WKTread(WKTHelper.getWithoutSRID(wkt));
   4.298 -					srid = WKTHelper.getSRID(wkt);
   4.299 -					
   4.300 -				} else { // GML
   4.301 -					logger.warn("[Strabon.KMLWriter] GML is not supported yet");
   4.302 -				}
   4.303 -			}
   4.304 -			
   4.305 -			// transform the geometry to 4326
   4.306 -			geom = jts.transform(geom, srid, StrabonPolyhedron.defaultSRID);
   4.307 -			
   4.308 -			if (geom instanceof Point) {
   4.309 -				geometryType = KML.Point;
   4.310 -				
   4.311 -			} else if (geom instanceof Polygon) {
   4.312 -				geometryType = KML.Polygon;
   4.313 -				
   4.314 -			} else if (geom instanceof LineString) {
   4.315 -				geometryType = KML.LineString;
   4.316 -				
   4.317 -			} else if (geom instanceof MultiPoint) {
   4.318 -				geometryType = KML.MultiGeometry;
   4.319 -				
   4.320 -			} else if (geom instanceof MultiLineString) {
   4.321 -				geometryType = KML.MultiGeometry;
   4.322 -				
   4.323 -			} else if (geom instanceof MultiPolygon) {
   4.324 -				geometryType = KML.MultiGeometry;
   4.325 -				
   4.326 -			} else if (geom instanceof GeometryCollection) {
   4.327 -				geometryType = KML.MultiGeometry;
   4.328 -				
   4.329 -			} 
   4.330 -			
   4.331 -			if (geometryType == null) {
   4.332 -				logger.warn("[Strabon.KMLWriter] Found unknown geometry type.");
   4.333 -				
   4.334 -			} else {
   4.335 -			
   4.336 -				encoder.encode(geom, geometryType, baos);
   4.337 -				kml = baos.toString().substring(38).replaceAll(" xmlns:kml=\"http://earth.google.com/kml/2.1\"","").replaceAll("kml:","");
   4.338 -				baos.reset();
   4.339 -			}
   4.340 -			
   4.341 -		} catch (ParseException e) {
   4.342 -			logger.error("[Strabon.KMLWriter] Parse error exception of geometry: {}", e.getMessage());
   4.343 -			
   4.344 -		} catch (IOException e) {
   4.345 -			logger.error("[Strabon.KMLWriter] IOException during KML encoding of geometry: {}", e.getMessage());
   4.346 -		}
   4.347 -		
   4.348 -		return kml;
   4.349 -	}
   4.350 -
   4.351 -	/**
   4.352 -	 * Adds to the description table information for a binding.
   4.353 -	 * 
   4.354 -	 * @param binding
   4.355 -	 */
   4.356 -	private void writeDesc(Binding binding) {
   4.357 -		descHeader.append(NEWLINE);
   4.358 -		indent(descHeader, depth + 1);
   4.359 -		descHeader.append(TABLE_DATA_BEGIN);
   4.360 -		descHeader.append(binding.getName());
   4.361 -		descHeader.append(TABLE_DATA_END);
   4.362 -		
   4.363 -		descData.append(NEWLINE);
   4.364 -		indent(descData, depth + 1);
   4.365 -		descData.append(TABLE_DATA_BEGIN);
   4.366 -		if (binding.getValue() instanceof BNode) {
   4.367 -			descData.append("_:");
   4.368 -		}
   4.369 -		descData.append(binding.getValue().stringValue());
   4.370 -		descData.append(TABLE_DATA_END);
   4.371 -		
   4.372 -	}
   4.373 -
   4.374 -	@Override
   4.375 -	public TupleQueryResultFormat getTupleQueryResultFormat() {
   4.376 -		return stSPARQLQueryResultFormat.KML;
   4.377 -	}
   4.378 -	
   4.379 -	/**
   4.380 -	 * Adds indentation to the given string builder according to 
   4.381 -	 * the specified depth.
   4.382 -	 * 
   4.383 -	 * @param sb
   4.384 -	 * @param depth
   4.385 -	 */
   4.386 -	private void indent(StringBuilder sb, int depth) {
   4.387 -		for (int i = 0; i < depth; i++) {
   4.388 -			sb.append(xmlWriter.getIndentString());
   4.389 -		}
   4.390 -	}
   4.391 -}
     5.1 --- a/resultio/src/main/java/org/openrdf/query/resultio/sparqlxml/stSPARQLResultsKMLWriterFactory.java	Mon Jun 25 21:22:31 2012 +0300
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,26 +0,0 @@
     5.4 -package org.openrdf.query.resultio.sparqlxml;
     5.5 -
     5.6 -import java.io.OutputStream;
     5.7 -
     5.8 -import org.openrdf.query.resultio.TupleQueryResultFormat;
     5.9 -import org.openrdf.query.resultio.TupleQueryResultWriter;
    5.10 -import org.openrdf.query.resultio.TupleQueryResultWriterFactory;
    5.11 -import org.openrdf.query.resultio.stSPARQLQueryResultFormat;
    5.12 -
    5.13 -/**
    5.14 - * @author Charalampos Nikolaou <charnik@di.uoa.gr>
    5.15 - *
    5.16 - */
    5.17 -public class stSPARQLResultsKMLWriterFactory implements TupleQueryResultWriterFactory {
    5.18 -
    5.19 -	@Override
    5.20 -	public TupleQueryResultFormat getTupleQueryResultFormat() {
    5.21 -		return stSPARQLQueryResultFormat.KML;
    5.22 -	}
    5.23 -
    5.24 -	@Override
    5.25 -	public TupleQueryResultWriter getWriter(OutputStream out) {
    5.26 -		return new stSPARQLResultsKMLWriter(out);
    5.27 -	}
    5.28 -
    5.29 -}
     6.1 --- a/resultio/src/main/java/org/openrdf/query/resultio/stSPARQLQueryResultWriterFactory.java	Mon Jun 25 21:22:31 2012 +0300
     6.2 +++ b/resultio/src/main/java/org/openrdf/query/resultio/stSPARQLQueryResultWriterFactory.java	Mon Jun 25 21:28:17 2012 +0300
     6.3 @@ -5,13 +5,13 @@
     6.4  import org.openrdf.query.resultio.sparqlgeojson.stSPARQLResultsGeoJSONWriterFactory;
     6.5  import org.openrdf.query.resultio.sparqlhtml.stSPARQLResultsHTMLWriterFactory;
     6.6  import org.openrdf.query.resultio.sparqlkml.stSPARQLResultsKMZWriterFactory;
     6.7 -import org.openrdf.query.resultio.sparqlxml.stSPARQLResultsKMLWriterFactory;
     6.8 +import org.openrdf.query.resultio.sparqlkml.stSPARQLResultsKMLWriterFactory;
     6.9  import org.openrdf.query.resultio.sparqlxml.stSPARQLResultsXMLWriterFactory;
    6.10  import org.openrdf.query.resultio.text.stSPARQLResultsTSVWriterFactory;
    6.11  
    6.12  /**
    6.13   * This is a factory class for creating stSPARQLQueryResultWriter
    6.14 - * instances according to a format in @{link org.openrdf.query.resultio.sparqlxml.Format}.
    6.15 + * instances according to a format in {@link org.openrdf.query.resultio.sparqlxml.Format}.
    6.16   * 
    6.17   * @author Charalampos Nikolaou <charnik@di.uoa.gr>
    6.18   *
     7.1 --- a/runtime/src/main/java/eu/earthobservatory/runtime/generaldb/Strabon.java	Mon Jun 25 21:22:31 2012 +0300
     7.2 +++ b/runtime/src/main/java/eu/earthobservatory/runtime/generaldb/Strabon.java	Mon Jun 25 21:28:17 2012 +0300
     7.3 @@ -13,14 +13,9 @@
     7.4  import java.nio.charset.Charset;
     7.5  import java.sql.SQLException;
     7.6  import java.util.ArrayList;
     7.7 -import java.util.Set;
     7.8 -import java.util.zip.ZipEntry;
     7.9 -import java.util.zip.ZipOutputStream;
    7.10  
    7.11  import org.openrdf.model.URI;
    7.12 -import org.openrdf.model.Value;
    7.13  import org.openrdf.model.ValueFactory;
    7.14 -import org.openrdf.query.Binding;
    7.15  import org.openrdf.query.BindingSet;
    7.16  import org.openrdf.query.GraphQuery;
    7.17  import org.openrdf.query.MalformedQueryException;
    7.18 @@ -34,10 +29,6 @@
    7.19  import org.openrdf.query.resultio.Format;
    7.20  import org.openrdf.query.resultio.TupleQueryResultWriter;
    7.21  import org.openrdf.query.resultio.stSPARQLQueryResultWriterFactory;
    7.22 -import org.openrdf.query.resultio.sparqlgeojson.stSPARQLResultsGeoJSONWriterFactory;
    7.23 -import org.openrdf.query.resultio.sparqlxml.stSPARQLResultsKMLWriterFactory;
    7.24 -import org.openrdf.query.resultio.sparqlxml.stSPARQLResultsXMLWriterFactory;
    7.25 -import org.openrdf.query.resultio.text.stSPARQLResultsTSVWriterFactory;
    7.26  import org.openrdf.repository.RepositoryException;
    7.27  import org.openrdf.repository.sail.SailRepository;
    7.28  import org.openrdf.repository.sail.SailRepositoryConnection;