Strabon

changeset 338:d54aacf6aae7

completed support for GeoJSONWriter (fixes Bug #05)
author Babis Nikolaou <charnik@di.uoa.gr>
date Sun Jun 24 16:02:09 2012 +0300 (2012-06-24)
parents 6acd5a415449
children e3b82b96b3bc
files resultio/src/main/java/org/openrdf/query/resultio/sparqljson/stSPARQLResultsGeoJSONWriter.java runtime/src/main/java/eu/earthobservatory/runtime/generaldb/Strabon.java
line diff
     1.1 --- a/resultio/src/main/java/org/openrdf/query/resultio/sparqljson/stSPARQLResultsGeoJSONWriter.java	Sun Jun 24 14:17:03 2012 +0300
     1.2 +++ b/resultio/src/main/java/org/openrdf/query/resultio/sparqljson/stSPARQLResultsGeoJSONWriter.java	Sun Jun 24 16:02:09 2012 +0300
     1.3 @@ -1,206 +1,239 @@
     1.4  package org.openrdf.query.resultio.sparqljson;
     1.5  
     1.6 -import info.aduna.io.IndentingWriter;
     1.7 -import info.aduna.text.StringUtil;
     1.8 -
     1.9 -import java.io.BufferedWriter;
    1.10  import java.io.IOException;
    1.11  import java.io.OutputStream;
    1.12 -import java.io.OutputStreamWriter;
    1.13 -import java.io.Writer;
    1.14  import java.nio.charset.Charset;
    1.15 -import java.util.Iterator;
    1.16 +import java.util.ArrayList;
    1.17  import java.util.List;
    1.18  
    1.19 -import org.openrdf.model.BNode;
    1.20 +import org.geotools.data.simple.SimpleFeatureCollection;
    1.21 +import org.geotools.feature.FeatureCollections;
    1.22 +import org.geotools.feature.simple.SimpleFeatureBuilder;
    1.23 +import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
    1.24 +import org.geotools.geojson.feature.FeatureJSON;
    1.25 +import org.geotools.referencing.CRS;
    1.26 +import org.opengis.feature.simple.SimpleFeature;
    1.27 +import org.opengis.feature.simple.SimpleFeatureType;
    1.28  import org.openrdf.model.Literal;
    1.29 -import org.openrdf.model.URI;
    1.30  import org.openrdf.model.Value;
    1.31 +import org.openrdf.query.Binding;
    1.32  import org.openrdf.query.BindingSet;
    1.33  import org.openrdf.query.TupleQueryResultHandlerException;
    1.34 +import org.openrdf.query.algebra.evaluation.function.spatial.StrabonPolyhedron;
    1.35 +import org.openrdf.query.algebra.evaluation.function.spatial.WKTHelper;
    1.36 +import org.openrdf.query.algebra.evaluation.util.JTSWrapper;
    1.37  import org.openrdf.query.resultio.TupleQueryResultFormat;
    1.38  import org.openrdf.query.resultio.TupleQueryResultWriter;
    1.39 +import org.slf4j.Logger;
    1.40 +import org.slf4j.LoggerFactory;
    1.41 +
    1.42 +import com.vividsolutions.jts.geom.Geometry;
    1.43  
    1.44  /**
    1.45   * A TupleQueryResultWriter that writes query results in the <a
    1.46   * href="http://www.geojson.org/geojson-spec.html/">GeoJSON Format</a>.
    1.47   * 
    1.48 + * @author Manos Karpathiotakis <mk@di.uoa.gr>
    1.49   * @author Charalampos Nikolaou <charnik@di.uoa.gr>
    1.50   */
    1.51  public class stSPARQLResultsGeoJSONWriter implements TupleQueryResultWriter {
    1.52  
    1.53 -	private IndentingWriter writer;
    1.54 +	private static final Logger logger = LoggerFactory.getLogger(org.openrdf.query.resultio.sparqljson.stSPARQLResultsGeoJSONWriter.class);
    1.55 +	
    1.56 +	/**
    1.57 +	 * The underlying output stream to write
    1.58 +	 */
    1.59 +	private OutputStream out;
    1.60 +	
    1.61 +	/**
    1.62 +	 * Set a Feature Collection
    1.63 +	 */
    1.64 +	private SimpleFeatureCollection sfCollection;
    1.65 +	
    1.66 +	/**
    1.67 +	 * The wrapper of JTS library
    1.68 +	 */
    1.69 +	private JTSWrapper jts;
    1.70 +	
    1.71 +	/**
    1.72 +	 * Keep track of the number of results
    1.73 +	 */
    1.74 +	private int nresults;
    1.75 +	
    1.76 +	/**
    1.77 +	 * The class to use for serializing to GeoJSON
    1.78 +	 */
    1.79 +	private FeatureJSON fjson;
    1.80 +	
    1.81 +	/**
    1.82 +	 * True to write a warning when there are no features
    1.83 +	 * in the answer
    1.84 +	 */
    1.85 +	private boolean warn;
    1.86  	
    1.87  	public stSPARQLResultsGeoJSONWriter(OutputStream out) {
    1.88 -		Writer w = new OutputStreamWriter(out, Charset.forName("UTF-8"));
    1.89 -		w = new BufferedWriter(w, 1024);
    1.90 -		writer = new IndentingWriter(w);
    1.91 +		this.out = out;
    1.92 +		
    1.93 +		// set the feature collection
    1.94 +		sfCollection = FeatureCollections.newCollection("geomOutput");
    1.95 +		
    1.96 +		// get the instance of JTSWrapper
    1.97 +		jts = JTSWrapper.getInstance();
    1.98 +		
    1.99 +		// initialize results
   1.100 +		nresults = 0;
   1.101 +		
   1.102 +		warn = false;
   1.103  	}
   1.104  
   1.105  	@Override
   1.106  	public void startQueryResult(List<String> bindingNames) throws TupleQueryResultHandlerException {
   1.107 +		fjson = new FeatureJSON();
   1.108 +		fjson.setEncodeFeatureCRS(true);
   1.109 +	}
   1.110 +
   1.111 +	@Override
   1.112 +	public void endQueryResult() throws TupleQueryResultHandlerException {
   1.113  		try {
   1.114 -			openBraces();
   1.115 +			fjson.writeFeatureCollection(sfCollection, out);
   1.116 +			out.write("\n".getBytes(Charset.defaultCharset()));
   1.117  			
   1.118 +			if (warn) {
   1.119 +				logger.warn("[Strabon.GeoJSONWriter] No spatial binding found in the result, hence the result is empty eventhough query evaluation produced {} results. GeoJSON requires that at least one binding maps to a geometry.", nresults);
   1.120 +				
   1.121 +			}
   1.122  		} catch (IOException e) {
   1.123  			throw new TupleQueryResultHandlerException(e);
   1.124  		}
   1.125  	}
   1.126  
   1.127  	@Override
   1.128 -	public void endQueryResult() throws TupleQueryResultHandlerException {
   1.129 -	}
   1.130 +	public void handleSolution(BindingSet bindingSet) throws TupleQueryResultHandlerException {
   1.131 +		try {
   1.132 +			// we might have more than one feature in the result, so we count them
   1.133 +			int nfeatures = 0;
   1.134 +			
   1.135 +			nresults++;
   1.136 +			
   1.137 +			// list keeping binding names that are not binded to geometries
   1.138 +			ArrayList<String> properties = new ArrayList<String>();
   1.139 +			
   1.140 +			// list keeping values for binding names
   1.141 +			ArrayList<Value> values = new ArrayList<Value>();
   1.142 +			
   1.143 +			// list keeping the features of the result
   1.144 +			ArrayList<SimpleFeatureTypeBuilder> features = new ArrayList<SimpleFeatureTypeBuilder>();
   1.145 +			
   1.146 +			// list keeping the geometries of features
   1.147 +			ArrayList<Geometry> geometries = new ArrayList<Geometry>();
   1.148 +			
   1.149 +			// parse binding set
   1.150 +			for (Binding binding : bindingSet) {
   1.151 +				Value value = binding.getValue();
   1.152 +				if (value instanceof Literal) {
   1.153 +					Literal litValue = (Literal) value;
   1.154  
   1.155 -	@Override
   1.156 -	public void handleSolution(BindingSet bindingSet) throws TupleQueryResultHandlerException {
   1.157 +					// it's a spatial literal
   1.158 +					if (litValue.getDatatype().stringValue().equals(StrabonPolyhedron.ogcGeometry)) {
   1.159 +						// TODO Check for GML (when added to StrabonPolyhedron)
   1.160 +						
   1.161 +						nfeatures++;
   1.162 +						
   1.163 +						if (logger.isDebugEnabled()) {
   1.164 +							logger.debug("[Strabon] Found geometry: {}", litValue);
   1.165 +						}
   1.166 +						
   1.167 +						// get the geometry and SRID
   1.168 +						Geometry geom = null;
   1.169 +						int srid = -1;
   1.170 +						
   1.171 +						// TODO add dependency to pom.xml for GeneralDBPolyhedron 
   1.172 +						// Regardless of our geometry's input, we need its SRID
   1.173 +//						if (unparsedGeometry instanceof GeneralDBPolyhedron) {
   1.174 +//							geom = ((GeneralDBPolyhedron) value).getPolyhedron().getGeometry();
   1.175 +//							srid = ((GeneralDBPolyhedron) value).getPolyhedron().getGeometry().getSRID();
   1.176 +//							
   1.177 +//						} else { // WKT
   1.178 +							// get the WKT as it is present in the result
   1.179 +							String wkt = value.stringValue();
   1.180 +							
   1.181 +							// get its geometry
   1.182 +							geom = jts.WKTread(WKTHelper.getWithoutSRID(wkt));
   1.183 +							
   1.184 +							// get its SRID
   1.185 +							srid = WKTHelper.getSRID(wkt);
   1.186 +								
   1.187 +							// TODO: GML support to be added
   1.188 +						//}
   1.189 +					
   1.190 +						SimpleFeatureTypeBuilder sftb = new SimpleFeatureTypeBuilder();
   1.191 +						sftb.setName("Feature_" + nresults + "_" + nfeatures);
   1.192 +						sftb.setCRS(CRS.decode("EPSG:" + srid));
   1.193 +						sftb.setSRS("EPSG:" + srid);
   1.194 +						sftb.add("geometry", Geometry.class);
   1.195 +						
   1.196 +						// add the feature in the list of features
   1.197 +						features.add(sftb);
   1.198 +						
   1.199 +						// add the geometry of the feature in the list of geometries
   1.200 +						geometries.add(geom);
   1.201 +						
   1.202 +					
   1.203 +					} else { // Literal other than geometry
   1.204 +						if (logger.isDebugEnabled()) {
   1.205 +							logger.debug("[Strabon.GeoJSONWriter] Found Literal: {}", value);
   1.206 +						}
   1.207 +
   1.208 +						properties.add(binding.getName());
   1.209 +						values.add(value);
   1.210 +					}
   1.211 +					
   1.212 +				} else { // URI or BlankNode
   1.213 +					if (logger.isDebugEnabled()) {
   1.214 +						logger.debug("[Strabon.GeoJSONWriter] Found URI/BlankNode: {}", value);
   1.215 +					}
   1.216 +					
   1.217 +					properties.add(binding.getName());
   1.218 +					values.add(value);
   1.219 +				}
   1.220 +			}
   1.221 +			
   1.222 +			// construct the feature of the result
   1.223 +			for (int i = 0; i < features.size(); i++) {
   1.224 +				SimpleFeatureTypeBuilder sftb = features.get(i);
   1.225 +				
   1.226 +				// add the properties
   1.227 +				for (int p = 0; p < properties.size(); p++) {
   1.228 +					sftb.add(properties.get(p), String.class);
   1.229 +				}
   1.230 +				
   1.231 +				SimpleFeatureType featureType = sftb.buildFeatureType();
   1.232 +				SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(featureType);				
   1.233 +				
   1.234 +				// add the geometry to the builder of the feature
   1.235 +				featureBuilder.add(geometries.get(i));
   1.236 +				
   1.237 +				// add the values to the builder of the feature
   1.238 +				for (int v = 0; v < values.size(); v++) {
   1.239 +					featureBuilder.add(values.get(v));
   1.240 +				}
   1.241 +				
   1.242 +				SimpleFeature feature = featureBuilder.buildFeature(null);
   1.243 +				sfCollection.add(feature);	
   1.244 +			}
   1.245 +			
   1.246 +			if (nfeatures == 0) {
   1.247 +				warn = true;
   1.248 +			}
   1.249 +			
   1.250 +		} catch (Exception e) {
   1.251 +			throw new TupleQueryResultHandlerException(e);
   1.252 +		}
   1.253 +					
   1.254  	}
   1.255  
   1.256  	@Override
   1.257  	public TupleQueryResultFormat getTupleQueryResultFormat() {
   1.258  		return TupleQueryResultFormat.JSON;
   1.259  	}
   1.260 -	
   1.261 -
   1.262 -	protected void writeKeyValue(String key, String value)
   1.263 -		throws IOException
   1.264 -	{
   1.265 -		writeKey(key);
   1.266 -		writeString(value);
   1.267 -	}
   1.268 -
   1.269 -	protected void writeKeyValue(String key, Value value)
   1.270 -		throws IOException, TupleQueryResultHandlerException
   1.271 -	{
   1.272 -		writeKey(key);
   1.273 -		writeValue(value);
   1.274 -	}
   1.275 -
   1.276 -	protected void writeKeyValue(String key, Iterable<String> array)
   1.277 -		throws IOException
   1.278 -	{
   1.279 -		writeKey(key);
   1.280 -		writeArray(array);
   1.281 -	}
   1.282 -
   1.283 -	protected void writeKey(String key)
   1.284 -		throws IOException
   1.285 -	{
   1.286 -		writeString(key);
   1.287 -		writer.write(": ");
   1.288 -	}
   1.289 -
   1.290 -	protected void writeValue(Value value)
   1.291 -		throws IOException, TupleQueryResultHandlerException
   1.292 -	{
   1.293 -		writer.write("{ ");
   1.294 -
   1.295 -		if (value instanceof URI) {
   1.296 -			writeKeyValue("type", "uri");
   1.297 -			writer.write(", ");
   1.298 -			writeKeyValue("value", ((URI)value).toString());
   1.299 -		}
   1.300 -		else if (value instanceof BNode) {
   1.301 -			writeKeyValue("type", "bnode");
   1.302 -			writer.write(", ");
   1.303 -			writeKeyValue("value", ((BNode)value).getID());
   1.304 -		}
   1.305 -		else if (value instanceof Literal) {
   1.306 -			Literal lit = (Literal)value;
   1.307 -
   1.308 -			if (lit.getDatatype() != null) {
   1.309 -				writeKeyValue("type", "typed-literal");
   1.310 -				writer.write(", ");
   1.311 -				writeKeyValue("datatype", lit.getDatatype().toString());
   1.312 -			}
   1.313 -			else {
   1.314 -				writeKeyValue("type", "literal");
   1.315 -				if (lit.getLanguage() != null) {
   1.316 -					writer.write(", ");
   1.317 -					writeKeyValue("xml:lang", lit.getLanguage());
   1.318 -				}
   1.319 -			}
   1.320 -
   1.321 -			writer.write(", ");
   1.322 -			writeKeyValue("value", lit.getLabel());
   1.323 -		}
   1.324 -		else {
   1.325 -			throw new TupleQueryResultHandlerException("Unknown Value object type: " + value.getClass());
   1.326 -		}
   1.327 -
   1.328 -		writer.write(" }");
   1.329 -	}
   1.330 -
   1.331 -	protected void writeString(String value) throws IOException
   1.332 -	{
   1.333 -		// Escape special characters
   1.334 -		value = StringUtil.gsub("\\", "\\\\", value);
   1.335 -		value = StringUtil.gsub("\"", "\\\"", value);
   1.336 -		value = StringUtil.gsub("/", "\\/", value);
   1.337 -		value = StringUtil.gsub("\b", "\\b", value);
   1.338 -		value = StringUtil.gsub("\f", "\\f", value);
   1.339 -		value = StringUtil.gsub("\n", "\\n", value);
   1.340 -		value = StringUtil.gsub("\r", "\\r", value);
   1.341 -		value = StringUtil.gsub("\t", "\\t", value);
   1.342 -
   1.343 -		writer.write("\"");
   1.344 -		writer.write(value);
   1.345 -		writer.write("\"");
   1.346 -	}
   1.347 -
   1.348 -	protected void writeArray(Iterable<String> array)
   1.349 -		throws IOException
   1.350 -	{
   1.351 -		writer.write("[ ");
   1.352 -
   1.353 -		Iterator<String> iter = array.iterator();
   1.354 -		while (iter.hasNext()) {
   1.355 -			String value = iter.next();
   1.356 -
   1.357 -			writeString(value);
   1.358 -
   1.359 -			if (iter.hasNext()) {
   1.360 -				writer.write(", ");
   1.361 -			}
   1.362 -		}
   1.363 -
   1.364 -		writer.write(" ]");
   1.365 -	}
   1.366 -
   1.367 -	protected void openArray() throws IOException
   1.368 -	{
   1.369 -		writer.write("[");
   1.370 -		writer.writeEOL();
   1.371 -		writer.increaseIndentation();
   1.372 -	}
   1.373 -
   1.374 -	protected void closeArray() throws IOException
   1.375 -	{
   1.376 -		writer.writeEOL();
   1.377 -		writer.decreaseIndentation();
   1.378 -		writer.write("]");
   1.379 -	}
   1.380 -
   1.381 -	protected void openBraces()
   1.382 -		throws IOException
   1.383 -	{
   1.384 -		writer.write("{");
   1.385 -		writer.writeEOL();
   1.386 -		writer.increaseIndentation();
   1.387 -	}
   1.388 -
   1.389 -	protected void closeBraces()
   1.390 -		throws IOException
   1.391 -	{
   1.392 -		writer.writeEOL();
   1.393 -		writer.decreaseIndentation();
   1.394 -		writer.write("}");
   1.395 -	}
   1.396 -
   1.397 -	protected void writeComma()
   1.398 -		throws IOException
   1.399 -	{
   1.400 -		writer.write(", ");
   1.401 -		writer.writeEOL();
   1.402 -	}
   1.403 -
   1.404  }
     2.1 --- a/runtime/src/main/java/eu/earthobservatory/runtime/generaldb/Strabon.java	Sun Jun 24 14:17:03 2012 +0300
     2.2 +++ b/runtime/src/main/java/eu/earthobservatory/runtime/generaldb/Strabon.java	Sun Jun 24 16:02:09 2012 +0300
     2.3 @@ -44,6 +44,7 @@
     2.4  import org.openrdf.query.Update;
     2.5  import org.openrdf.query.UpdateExecutionException;
     2.6  import org.openrdf.query.algebra.evaluation.function.spatial.StrabonPolyhedron;
     2.7 +import org.openrdf.query.resultio.sparqljson.stSPARQLResultsGeoJSONWriter;
     2.8  import org.openrdf.query.resultio.sparqlxml.Format;
     2.9  import org.openrdf.query.resultio.sparqlxml.stSPARQLResultsKMLWriter;
    2.10  import org.openrdf.query.resultio.sparqlxml.stSPARQLResultsXMLWriter;
    2.11 @@ -309,183 +310,13 @@
    2.12  				break;
    2.13  				
    2.14  			case GEOJSON:
    2.15 +				if (logger.isDebugEnabled()) {
    2.16 +					logger.debug("Serializing results (GEOJSON)");
    2.17 +				}
    2.18  
    2.19 -				DataOutputStream dos = new DataOutputStream(out);
    2.20 -	
    2.21 -				try {
    2.22 -					result = tupleQuery.evaluate();
    2.23 -					
    2.24 -				} catch (QueryEvaluationException e) {
    2.25 -					logger.error("[Strabon.query] Error during query evaluation.", e);
    2.26 -					status = false;
    2.27 -					
    2.28 -					return status;
    2.29 -				}
    2.30 -	
    2.31 -				int resultsCounter = 0;
    2.32 -	
    2.33 -				//Setting a Feature Collection
    2.34 -				SimpleFeatureCollection sfCollection = FeatureCollections.newCollection("geomOutput");
    2.35 -	
    2.36 -				int spatialBindingsNo=0;
    2.37 -	
    2.38 -				//May not need that much - still initializing it
    2.39 -				String[] spatialBindings = new String[result.getBindingNames().size()];
    2.40 -				SimpleFeatureTypeBuilder[] tb = new SimpleFeatureTypeBuilder[result.getBindingNames().size()];
    2.41 -	
    2.42 -				for(int i=0;i<result.getBindingNames().size();i++)
    2.43 -				{
    2.44 -					tb[i] = new SimpleFeatureTypeBuilder(); 
    2.45 -				}
    2.46 -	
    2.47 -				BindingSet bindingSet;
    2.48 -				if(result.hasNext())
    2.49 -				{
    2.50 -					//Sneak Peek to obtain info on which bindings are spatial
    2.51 -					bindingSet = result.next();
    2.52 -					boolean spatial = false;
    2.53 -					for(String bindingName : bindingSet.getBindingNames())
    2.54 -					{
    2.55 -						Value val = bindingSet.getValue(bindingName);
    2.56 -	
    2.57 -						if(val instanceof RdbmsLiteral)
    2.58 -						{
    2.59 -							if(((RdbmsLiteral) val).getDatatype()!=null)
    2.60 -							{
    2.61 -								if(((RdbmsLiteral) val).getDatatype().toString().equals(StrabonPolyhedron.ogcGeometry))
    2.62 -								{
    2.63 -									spatial = true;
    2.64 -								}
    2.65 -							}
    2.66 -						}
    2.67 -	
    2.68 -						if(val instanceof GeneralDBPolyhedron)
    2.69 -						{
    2.70 -							spatial = true;
    2.71 -	
    2.72 -						}
    2.73 -	
    2.74 -						if(spatial)
    2.75 -						{
    2.76 -							spatial = false;
    2.77 -							spatialBindings[spatialBindingsNo] = bindingName;
    2.78 -							spatialBindingsNo++;
    2.79 -						}
    2.80 -					}
    2.81 -	
    2.82 -				} else {
    2.83 -					return status;//empty
    2.84 -				}
    2.85 -	
    2.86 -				boolean firstLineParsed = false;
    2.87 -	
    2.88 -				do {
    2.89 -					if(firstLineParsed)
    2.90 -					{
    2.91 -						bindingSet = result.next();
    2.92 -					}
    2.93 -	
    2.94 -					firstLineParsed = true;
    2.95 -	
    2.96 -					//How many features will occur from a single result? --> spatialBindingsNo
    2.97 -					for(int i=0; i<spatialBindingsNo;i++)
    2.98 -					{
    2.99 -						tb[i].setName("Feature_"+(++resultsCounter));
   2.100 -	
   2.101 -						//Every time a featureType is built, the builder is nullified!!
   2.102 -						//Can't avoid re-iterating...
   2.103 -						for(String otherBinding : bindingSet.getBindingNames())
   2.104 -						{
   2.105 -							if(!otherBinding.equals(spatialBindings[i]))
   2.106 -							{
   2.107 -								tb[i].add(otherBinding,String.class);
   2.108 -							}
   2.109 -						}
   2.110 -	
   2.111 -	
   2.112 -						int SRID=4326;
   2.113 -						Geometry geom = null;
   2.114 -						Value unparsedGeometry = bindingSet.getValue(spatialBindings[i]);
   2.115 -						//Regardless of our geometry's input, we need its SRID
   2.116 -						if(unparsedGeometry instanceof GeneralDBPolyhedron)
   2.117 -						{
   2.118 -							geom = ((GeneralDBPolyhedron) unparsedGeometry).getPolyhedron().getGeometry();
   2.119 -							SRID = ((GeneralDBPolyhedron) unparsedGeometry).getPolyhedron().getGeometry().getSRID();
   2.120 -						}
   2.121 -						else //RdbmsLiteral
   2.122 -							//TODO GML support to be added
   2.123 -						{
   2.124 -							String unparsedWKT = ((RdbmsLiteral)unparsedGeometry).getLabel();
   2.125 -							try {
   2.126 -								int pos = unparsedWKT.indexOf(";");
   2.127 -								if(pos!=-1)
   2.128 -								{
   2.129 -									geom = new WKTReader().read(unparsedWKT.substring(0,pos));
   2.130 -									int whereToCut = unparsedWKT.lastIndexOf('/');
   2.131 -									SRID = Integer.parseInt(unparsedWKT.substring(whereToCut+1));
   2.132 -								}
   2.133 -								else
   2.134 -								{
   2.135 -									geom = new WKTReader().read(unparsedWKT);
   2.136 -									SRID=4326;
   2.137 -								}
   2.138 -	
   2.139 -							} 
   2.140 -							catch (ParseException e) {
   2.141 -								logger.error("[Strabon.query] Faults detected in spatial literal representation.", e);
   2.142 -								status = false;
   2.143 -							}
   2.144 -						}
   2.145 -	
   2.146 -						CoordinateReferenceSystem geomCRS = null;
   2.147 -						try {
   2.148 -							geomCRS = CRS.decode("EPSG:"+SRID);
   2.149 -							
   2.150 -						} catch (NoSuchAuthorityCodeException e) {
   2.151 -							logger.error("[Strabon.query] Error decoding returned geometry's SRID", e);
   2.152 -							status = false;
   2.153 -							
   2.154 -							return status;
   2.155 -						} catch (FactoryException e) {
   2.156 -							logger.error("[Strabon.query]", e);
   2.157 -							status = false;
   2.158 -							
   2.159 -							return status;
   2.160 -						}
   2.161 -	
   2.162 -						tb[i].setCRS(geomCRS);
   2.163 -						tb[i].setSRS("EPSG:" + SRID);
   2.164 -						tb[i].add("geometry", Geometry.class);
   2.165 -	
   2.166 -						SimpleFeatureType featureType = tb[i].buildFeatureType();
   2.167 -						SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(featureType);
   2.168 -	
   2.169 -						for(String otherBinding : bindingSet.getBindingNames())
   2.170 -						{
   2.171 -							if(!otherBinding.equals(spatialBindings[i]))
   2.172 -							{
   2.173 -								featureBuilder.add(bindingSet.getValue(otherBinding));
   2.174 -							}
   2.175 -						}
   2.176 -	
   2.177 -						featureBuilder.add(geom);
   2.178 -	
   2.179 -	
   2.180 -						SimpleFeature feature = featureBuilder.buildFeature(null);
   2.181 -						sfCollection.add(feature);
   2.182 -					}
   2.183 -	
   2.184 -				}
   2.185 +				tupleQuery.evaluate(new stSPARQLResultsGeoJSONWriter(out));
   2.186 +				break;
   2.187  				
   2.188 -				while((result.hasNext()));
   2.189 -	
   2.190 -				FeatureJSON fjson = new FeatureJSON();
   2.191 -				fjson.setEncodeFeatureCRS(true);
   2.192 -				fjson.writeFeatureCollection(sfCollection, dos);
   2.193 -				writeString(out, NEWLINE);
   2.194 -				
   2.195 -				break;
   2.196 -
   2.197  			case HTML:
   2.198  		
   2.199  				result = tupleQuery.evaluate();