Strabon

changeset 561:1559214d32c6

Partially fixes Ticket #10

KMLWriter now creates a KML file with different colors for every geometry that comes from a different spatial variable (max colors are 4 but we can add more).
Also, geometries that belong to the same result are highlighted when the mouse is over one of them.

Unfortunately, that doesn't work with google maps API and every geometry has the default (blue) color.
Unfortunately, that doesn't work with geoxml extension too (different geometries do have different colors but same-result geometries are not highlighted).

You can test it with a query like this:

SELECT ?g ?s
WHERE
{
<http://geo.linkedopendata.gr/gag/id/9186> <http://geo.linkedopendata.gr/gag/ontology/έχει_γεωμετρία> ?g.
<http://geo.linkedopendata.gr/gag/id/9185> <http://geo.linkedopendata.gr/gag/ontology/έχει_γεωμετρία> ?s.
}

Select View Result: 1) On a map, 2) On a map (localhost), 3) Download and open it with google earth.
author Panayiotis Smeros <psmeros@di.uoa.gr>
date Thu Sep 20 13:18:18 2012 +0300 (2012-09-20)
parents 319dcc2c9a03
children 942a48b43164
files resultio/src/main/java/org/openrdf/query/resultio/sparqlkml/stSPARQLResultsKMLWriter.java
line diff
     1.1 --- a/resultio/src/main/java/org/openrdf/query/resultio/sparqlkml/stSPARQLResultsKMLWriter.java	Tue Sep 18 21:30:07 2012 +0300
     1.2 +++ b/resultio/src/main/java/org/openrdf/query/resultio/sparqlkml/stSPARQLResultsKMLWriter.java	Thu Sep 20 13:18:18 2012 +0300
     1.3 @@ -1,22 +1,18 @@
     1.4  /**
     1.5 - * This Source Code Form is subject to the terms of the Mozilla Public
     1.6 - * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 - * file, You can obtain one at http://mozilla.org/MPL/2.0/.
     1.8 - * 
     1.9 - * Copyright (C) 2010, 2011, 2012, Pyravlos Team
    1.10 - * 
    1.11 - * http://www.strabon.di.uoa.gr/
    1.12 + * This Source Code Form is subject to the terms of the Mozilla Public License,
    1.13 + * v. 2.0. If a copy of the MPL was not distributed with this file, You can
    1.14 + * obtain one at http://mozilla.org/MPL/2.0/. Copyright (C) 2010, 2011, 2012,
    1.15 + * Pyravlos Team http://www.strabon.di.uoa.gr/
    1.16   */
    1.17  package org.openrdf.query.resultio.sparqlkml;
    1.18  
    1.19  import java.io.ByteArrayOutputStream;
    1.20  import java.io.IOException;
    1.21  import java.io.OutputStream;
    1.22 +import java.util.ArrayList;
    1.23  import java.util.List;
    1.24 -
    1.25  import javax.xml.bind.JAXBException;
    1.26  import javax.xml.namespace.QName;
    1.27 -
    1.28  import org.geotools.kml.KML;
    1.29  import org.geotools.kml.KMLConfiguration;
    1.30  import org.geotools.xml.Encoder;
    1.31 @@ -37,7 +33,6 @@
    1.32  import org.openrdf.sail.generaldb.model.XMLGSDatatypeUtil;
    1.33  import org.slf4j.Logger;
    1.34  import org.slf4j.LoggerFactory;
    1.35 -
    1.36  import com.vividsolutions.jts.geom.Geometry;
    1.37  import com.vividsolutions.jts.geom.GeometryCollection;
    1.38  import com.vividsolutions.jts.geom.LineString;
    1.39 @@ -53,84 +48,70 @@
    1.40   * @author Charalampos Nikolaou <charnik@di.uoa.gr>
    1.41   *
    1.42   */
    1.43 -public class stSPARQLResultsKMLWriter implements TupleQueryResultWriter {
    1.44 -
    1.45 +public class stSPARQLResultsKMLWriter implements TupleQueryResultWriter
    1.46 +{
    1.47  	private static final Logger logger = LoggerFactory.getLogger(org.openrdf.query.resultio.sparqlkml.stSPARQLResultsKMLWriter.class);
    1.48 -
    1.49 -	private static final String ROOT_TAG 			= "kml";
    1.50 -	private static final String NAMESPACE 			= "http://www.opengis.net/kml/2.2";
    1.51 -	private static final String RESULT_SET_TAG		= "Folder";
    1.52 -
    1.53 -	private static final String PLACEMARK_TAG		= "Placemark";
    1.54 -	private static final String NAME_TAG			= "name";
    1.55 -	private static final String DESC_TAG			= "description";
    1.56 -
    1.57 +	private static final String ROOT_TAG = "kml";
    1.58 +	private static final String NAMESPACE = "http://www.opengis.net/kml/2.2";
    1.59 +	private static final String RESULT_SET_TAG = "Folder";
    1.60 +	private static final String PLACEMARK_TAG = "Placemark";
    1.61 +	private static final String NAME_TAG = "name";
    1.62 +	private static final String DESC_TAG = "description";
    1.63  	private static final String STYLE_TAG = "Style";
    1.64  	private static final String STYLEMAP_TAG = "StyleMap";
    1.65  	private static final String LINESTYLE_TAG = "LineStyle";
    1.66  	private static final String POLYSTYLE_TAG = "PolyStyle";
    1.67  	private static final String STYLE_ID = "resultStyle";
    1.68 +	private static final String TABLE_ROW_BEGIN = "<TR>";
    1.69 +	private static final String TABLE_ROW_END = "</TR>";
    1.70 +	private static final String TABLE_DATA_BEGIN = "<TD>";
    1.71 +	private static final String TABLE_DATA_END = "</TD>";
    1.72 +	private static final String NEWLINE = "\n";
    1.73 +	private static final String TABLE_DESC_BEGIN = "<![CDATA[<TABLE border=\"1\">" + NEWLINE;
    1.74 +	private static final String TABLE_DESC_END = "</TABLE>]]>" + NEWLINE;
    1.75 +	private static final String GEOMETRY_NAME = "Geometry";
    1.76 +	private static final String MULTIGEOMETRY = "MultiGeometry";
    1.77 +	// Styling options
    1.78 +	private static final int numOfStyles=5;
    1.79 +	private static final String[][] styles = {
    1.80 +		// note that colors are encoded as "aabbggrr" strings where
    1.81 +		// aa=alpha (00 to ff); bb=blue (00 to ff); gg=green (00 to ff); rr=red
    1.82 +		// (00 to ff).
    1.83 +		// id, line width, line color, polygon fill, mouse over line width,
    1.84 +		// mouse over line color mouse over polygon fill
    1.85 +	{STYLE_ID + "1", "1.5", "7dff0000", "7dff0000", "1.5", "7d0000ff", "7d0000ff"}, {STYLE_ID + "2", "1.5", "7d00ff00", "7d00ff00", "1.5", "7d0000ff", "7d0000ff"}, {STYLE_ID + "3", "1.5", "7d550000", "7d550000", "1.5", "7d0000ff", "7d0000ff"}, {STYLE_ID + "4", "1.5", "7d005500", "7d005500", "1.5", "7d0000ff", "7d0000ff"}, {STYLE_ID + "5", "1.5", "7d000055", "7d000055", "1.5", "7d0000ff", "7d0000ff"},};
    1.86 +	
    1.87  
    1.88 -	private static final String TABLE_ROW_BEGIN		= "<TR>";
    1.89 -	private static final String TABLE_ROW_END		= "</TR>";
    1.90 -	private static final String TABLE_DATA_BEGIN	= "<TD>";
    1.91 -	private static final String TABLE_DATA_END		= "</TD>";
    1.92 -
    1.93 -	private static final String NEWLINE				= "\n";
    1.94 -
    1.95 -	private static final String TABLE_DESC_BEGIN	= "<![CDATA[<TABLE border=\"1\">" + NEWLINE;
    1.96 -	private static final String TABLE_DESC_END		= "</TABLE>]]>" + NEWLINE;
    1.97 -
    1.98 -	private static final String GEOMETRY_NAME		= "Geometry";
    1.99 -
   1.100 -	//Styling options
   1.101 -	String [][] styles = {
   1.102 -			// note that colors are encoded as "aabbggrr" strings where  
   1.103 -			// aa=alpha (00 to ff); bb=blue (00 to ff); gg=green (00 to ff); rr=red (00 to ff). 
   1.104 -			// id, line width, line color, polygon fill, mouse over line width, mouse over line color mouse over polygon fill
   1.105 -			{STYLE_ID+"1", "1.5", "7dff0000", "7dff0000", "1.5", "7d0000ff", "7d0000ff"},
   1.106 -			{STYLE_ID+"2", "1.5", "7d00ff00", "7d00ff00", "1.5", "7d0000ff", "7d0000ff"},
   1.107 -			{STYLE_ID+"3", "1.5", "7d550000", "7d550000", "1.5", "7d0000ff", "7d0000ff"},
   1.108 -			{STYLE_ID+"4", "1.5", "7d005500", "7d005500", "1.5", "7d0000ff", "7d0000ff"},
   1.109 -			{STYLE_ID+"5", "1.5", "7d000055", "7d000055", "1.5", "7d0000ff", "7d0000ff"},
   1.110 -	};
   1.111  	/**
   1.112  	 * The underlying XML formatter.
   1.113  	 */
   1.114  	private stSPARQLXMLWriter xmlWriter;
   1.115 -
   1.116  	/**
   1.117  	 * The number of results seen.
   1.118  	 */
   1.119  	private int nresults;
   1.120 -
   1.121  	/**
   1.122  	 * The number of geometries seen.
   1.123  	 */
   1.124  	private int ngeometries;
   1.125 -
   1.126  	/**
   1.127  	 * The JTS wrapper
   1.128  	 */
   1.129  	private JTSWrapper jts;
   1.130 -
   1.131  	/**
   1.132  	 * Stream for manipulating geometries
   1.133  	 */
   1.134  	private ByteArrayOutputStream baos;
   1.135 -
   1.136  	/**
   1.137  	 * Description string holding the projected variables
   1.138  	 * of the SPARQL query
   1.139  	 */
   1.140  	private StringBuilder descHeader;
   1.141 -
   1.142  	/**
   1.143  	 * Description string holding the values for the
   1.144  	 * projected variables of the SPARQL query
   1.145  	 */
   1.146  	private StringBuilder descData;
   1.147 -
   1.148  	/**
   1.149  	 * Indentation used in tags that are constructed manually
   1.150  	 */
   1.151 @@ -142,38 +123,35 @@
   1.152  	 * 
   1.153  	 * @param out
   1.154  	 */
   1.155 -	public stSPARQLResultsKMLWriter(OutputStream out) {
   1.156 +	public stSPARQLResultsKMLWriter(OutputStream out)
   1.157 +	{
   1.158  		this(new stSPARQLXMLWriter(out));
   1.159  	}
   1.160  
   1.161 -	public stSPARQLResultsKMLWriter(stSPARQLXMLWriter writer) {
   1.162 +	public stSPARQLResultsKMLWriter(stSPARQLXMLWriter writer)
   1.163 +	{
   1.164  		xmlWriter = writer;
   1.165  		xmlWriter.setPrettyPrint(true);
   1.166 -
   1.167  		depth = 4;
   1.168 -
   1.169  		jts = JTSWrapper.getInstance();
   1.170 -
   1.171  		baos = new ByteArrayOutputStream();
   1.172 -
   1.173  		descHeader = new StringBuilder();
   1.174  		descData = new StringBuilder();
   1.175 -
   1.176  		nresults = 0;
   1.177  		ngeometries = 0;
   1.178  	}
   1.179  
   1.180 -	@Override
   1.181 -	public void startQueryResult(List<String> bindingNames) throws TupleQueryResultHandlerException {
   1.182 -		try {
   1.183 +	@Override public void startQueryResult(List<String> bindingNames) throws TupleQueryResultHandlerException
   1.184 +	{
   1.185 +		try
   1.186 +		{
   1.187  			xmlWriter.startDocument();
   1.188 -
   1.189  			xmlWriter.setAttribute("xmlns", NAMESPACE);
   1.190  			xmlWriter.startTag(ROOT_TAG);
   1.191  			xmlWriter.startTag(RESULT_SET_TAG);
   1.192 -			
   1.193 -			//add default styles
   1.194 -			for (String[] style: styles) {
   1.195 +			// add default styles
   1.196 +			for(String[] style: styles)
   1.197 +			{
   1.198  				String id = style[0];
   1.199  				String lineWidth = style[1];
   1.200  				String lineColor = style[2];
   1.201 @@ -181,9 +159,8 @@
   1.202  				String mouseOverLineWidth = style[4];
   1.203  				String mouseOverLineColor = style[5];
   1.204  				String mouseOverPolygonFill = style[6];
   1.205 -
   1.206 -				xmlWriter.setAttribute("id", "normal_"+id);
   1.207 -				xmlWriter.startTag(STYLE_TAG);			
   1.208 +				xmlWriter.setAttribute("id", "normal_" + id);
   1.209 +				xmlWriter.startTag(STYLE_TAG);
   1.210  				xmlWriter.startTag(LINESTYLE_TAG);
   1.211  				xmlWriter.textElement("width", lineWidth);
   1.212  				xmlWriter.textElement("color", lineColor);
   1.213 @@ -192,9 +169,8 @@
   1.214  				xmlWriter.textElement("color", polygonFill);
   1.215  				xmlWriter.endTag(POLYSTYLE_TAG);
   1.216  				xmlWriter.endTag(STYLE_TAG);
   1.217 -
   1.218 -				xmlWriter.setAttribute("id", "highlight_"+id);
   1.219 -				xmlWriter.startTag(STYLE_TAG);			
   1.220 +				xmlWriter.setAttribute("id", "highlight_" + id);
   1.221 +				xmlWriter.startTag(STYLE_TAG);
   1.222  				xmlWriter.startTag(LINESTYLE_TAG);
   1.223  				xmlWriter.textElement("width", mouseOverLineWidth);
   1.224  				xmlWriter.textElement("color", mouseOverLineColor);
   1.225 @@ -203,229 +179,251 @@
   1.226  				xmlWriter.textElement("color", mouseOverPolygonFill);
   1.227  				xmlWriter.endTag(POLYSTYLE_TAG);
   1.228  				xmlWriter.endTag(STYLE_TAG);
   1.229 -
   1.230  				xmlWriter.setAttribute("id", id);
   1.231  				xmlWriter.startTag(STYLEMAP_TAG);
   1.232  				xmlWriter.startTag("Pair");
   1.233  				xmlWriter.textElement("key", "normal");
   1.234 -				xmlWriter.textElement("styleUrl", "#normal_"+id);
   1.235 +				xmlWriter.textElement("styleUrl", "#normal_" + id);
   1.236  				xmlWriter.endTag("Pair");
   1.237  				xmlWriter.startTag("Pair");
   1.238  				xmlWriter.textElement("key", "highlight");
   1.239 -				xmlWriter.textElement("styleUrl", "#highlight_"+id);
   1.240 +				xmlWriter.textElement("styleUrl", "#highlight_" + id);
   1.241  				xmlWriter.endTag("Pair");
   1.242  				xmlWriter.endTag(STYLEMAP_TAG);
   1.243  			}
   1.244 -			//end of default style definition
   1.245 +			// end of default style definition
   1.246  		}
   1.247 -		catch (IOException e) {
   1.248 +		catch(IOException e)
   1.249 +		{
   1.250  			throw new TupleQueryResultHandlerException(e);
   1.251  		}
   1.252  	}
   1.253  
   1.254 -	@Override
   1.255 -	public void endQueryResult() throws TupleQueryResultHandlerException {
   1.256 -		try {
   1.257 +	@Override public void endQueryResult() throws TupleQueryResultHandlerException
   1.258 +	{
   1.259 +		try
   1.260 +		{
   1.261  			xmlWriter.endTag(RESULT_SET_TAG);
   1.262  			xmlWriter.endTag(ROOT_TAG);
   1.263 -
   1.264  			xmlWriter.endDocument();
   1.265 -
   1.266  			baos.close();
   1.267 -
   1.268 -			if (ngeometries < nresults) {
   1.269 +			if(ngeometries < nresults)
   1.270 +			{
   1.271  				logger.warn("[Strabon.KMLWriter] No spatial binding found in the result. KML requires that at least one binding maps to a geometry.", nresults);
   1.272  			}
   1.273  		}
   1.274 -		catch (IOException e) {
   1.275 +		catch(IOException e)
   1.276 +		{
   1.277  			throw new TupleQueryResultHandlerException(e);
   1.278  		}
   1.279  	}
   1.280  
   1.281 -	@Override
   1.282 -	public void handleSolution(BindingSet bindingSet) throws TupleQueryResultHandlerException {
   1.283 -		try {
   1.284 +	@Override public void handleSolution(BindingSet bindingSet) throws TupleQueryResultHandlerException
   1.285 +	{
   1.286 +		try
   1.287 +		{
   1.288  			// true if there are bindings that do not correspond to geometries
   1.289  			boolean hasDesc = false;
   1.290 -
   1.291  			// increase result size
   1.292  			nresults++;
   1.293 -
   1.294  			// create description table and header
   1.295  			indent(descHeader, depth);
   1.296  			descHeader.append(TABLE_DESC_BEGIN);
   1.297  			indent(descHeader, depth);
   1.298  			descHeader.append(TABLE_ROW_BEGIN);
   1.299 -
   1.300  			// create description table data row
   1.301  			descData.append(NEWLINE);
   1.302  			indent(descData, depth);
   1.303  			descData.append(TABLE_ROW_BEGIN);
   1.304 -
   1.305 -			// write placemark tag
   1.306 -			xmlWriter.startTag(PLACEMARK_TAG);
   1.307 -			xmlWriter.textElement(NAME_TAG, GEOMETRY_NAME + nresults + "_" + ngeometries);
   1.308 -
   1.309 -			//TODO: Hardcoded style selection. Modify this line after adding 
   1.310 -			//support for multiple geometry variables in the select clause
   1.311 -			xmlWriter.textElement("styleUrl", "#"+styles[0][0]);
   1.312 -
   1.313 +			
   1.314 +			List<String> polygons = new ArrayList<String>();
   1.315  			// parse binding set
   1.316 -			for (Binding binding : bindingSet) {
   1.317 +			for(Binding binding: bindingSet)
   1.318 +			{
   1.319  				Value value = binding.getValue();
   1.320 -
   1.321  				// check for geometry value
   1.322 -				if (XMLGSDatatypeUtil.isGeometryValue(value)) {
   1.323 +				if(XMLGSDatatypeUtil.isGeometryValue(value))
   1.324 +				{
   1.325  					ngeometries++;
   1.326 -
   1.327 -					if (logger.isDebugEnabled()) {
   1.328 +					if(logger.isDebugEnabled())
   1.329 +					{
   1.330  						logger.debug("[Strabon] Found geometry: {}", value);
   1.331  					}
   1.332 -
   1.333 -					xmlWriter.unescapedText(getKML(value));
   1.334 -
   1.335 -				} else { // URI, BlankNode, or Literal other than spatial literal 
   1.336 -					if (logger.isDebugEnabled()) {
   1.337 +					polygons.add(getPolygon(value));
   1.338 +				}
   1.339 +				else
   1.340 +				{ // URI, BlankNode, or Literal other than spatial literal
   1.341 +					if(logger.isDebugEnabled())
   1.342 +					{
   1.343  						logger.debug("[Strabon.KMLWriter] Found URI/BlankNode/Literal ({}): {}", value.getClass(), value);
   1.344  					}
   1.345 -
   1.346  					// mark that we found sth corresponding to the description
   1.347  					hasDesc = true;
   1.348 -
   1.349  					// write description
   1.350  					writeDesc(binding);
   1.351  				}
   1.352  			}
   1.353 +			
   1.354 +			
   1.355 +			//write each polygon in separate placemarks
   1.356 +			for(String polygon : polygons)
   1.357 +			{
   1.358 +				xmlWriter.startTag(PLACEMARK_TAG);
   1.359 +				xmlWriter.textElement(NAME_TAG, GEOMETRY_NAME + polygons.indexOf(polygon)%(numOfStyles-2) + "_" + ngeometries);			
   1.360 +				xmlWriter.textElement("styleUrl", "#" + styles[polygons.indexOf(polygon)%(numOfStyles-2)][0]);
   1.361  
   1.362 -			// we have found and constructed a description for this result. Write it down.
   1.363 -			if (hasDesc) {
   1.364 +				xmlWriter.startTag(MULTIGEOMETRY);
   1.365 +				xmlWriter.unescapedText(polygon);
   1.366 +				xmlWriter.endTag(MULTIGEOMETRY);
   1.367 +				
   1.368 +				xmlWriter.endTag(PLACEMARK_TAG);
   1.369 +			}
   1.370 +			
   1.371 +			
   1.372 +			//also write them in the same placemarks
   1.373 +			
   1.374 +			xmlWriter.startTag(PLACEMARK_TAG);
   1.375 +			xmlWriter.textElement(NAME_TAG, GEOMETRY_NAME + ngeometries + "_" + ngeometries);			
   1.376 +			xmlWriter.textElement("styleUrl", "#" + styles[numOfStyles-1][0]);
   1.377 +			
   1.378 +			xmlWriter.startTag(MULTIGEOMETRY);
   1.379 +			for(String polygon : polygons)
   1.380 +			{
   1.381 +				xmlWriter.unescapedText(polygon);
   1.382 +			}
   1.383 +			xmlWriter.endTag(MULTIGEOMETRY);
   1.384 +			
   1.385 +			// we have found and constructed a description for this result.
   1.386 +			// Write it down.
   1.387 +			if(hasDesc)
   1.388 +			{
   1.389  				// close the header of the description
   1.390  				descHeader.append(NEWLINE);
   1.391  				indent(descHeader, depth);
   1.392  				descHeader.append(TABLE_ROW_END);
   1.393 -
   1.394  				// end the placeholder for the description data
   1.395  				descData.append(NEWLINE);
   1.396  				indent(descData, depth);
   1.397  				descData.append(TABLE_ROW_END);
   1.398 -
   1.399  				// append to the table header the actual content from
   1.400  				// the bindings
   1.401  				descHeader.append(descData);
   1.402 -
   1.403  				// close the table for the description
   1.404  				descHeader.append(NEWLINE);
   1.405  				indent(descHeader, depth);
   1.406  				descHeader.append(TABLE_DESC_END);
   1.407 -
   1.408  				// begin the "description" tag
   1.409  				xmlWriter.startTag(DESC_TAG);
   1.410 -
   1.411  				// write the actual description
   1.412  				xmlWriter.unescapedText(descHeader.toString());
   1.413 -
   1.414  				// end the "description" tag
   1.415  				xmlWriter.endTag(DESC_TAG);
   1.416  			}
   1.417 -
   1.418  			// clear description string builders
   1.419  			descHeader.setLength(0);
   1.420  			descData.setLength(0);
   1.421  
   1.422 -			// write the placemark
   1.423  			xmlWriter.endTag(PLACEMARK_TAG);
   1.424  		}
   1.425 -		catch (IOException e) {
   1.426 +		catch(IOException e)
   1.427 +		{
   1.428  			throw new TupleQueryResultHandlerException(e);
   1.429  		}
   1.430  	}
   1.431  
   1.432 -	private String getKML(Value value) {
   1.433 -		String kml = "";
   1.434 +	private String getPolygon(Value value)
   1.435 +	{
   1.436 +		String polygon="";
   1.437  		QName geometryType = null;
   1.438 -
   1.439  		// the underlying geometry in value
   1.440  		Geometry geom = null;
   1.441 -
   1.442  		// the underlying SRID of the geometry
   1.443  		int srid = -1;
   1.444 -
   1.445  		// get the KML encoder
   1.446  		Encoder encoder = null;
   1.447 -
   1.448 -		try {
   1.449 +		try
   1.450 +		{
   1.451  			encoder = new Encoder(new KMLConfiguration());
   1.452  			encoder.setIndenting(true);
   1.453 -
   1.454 -			if (value instanceof GeneralDBPolyhedron) {
   1.455 +			if(value instanceof GeneralDBPolyhedron)
   1.456 +			{
   1.457  				GeneralDBPolyhedron dbpolyhedron = (GeneralDBPolyhedron) value;
   1.458 -
   1.459  				geom = dbpolyhedron.getPolyhedron().getGeometry();
   1.460  				srid = dbpolyhedron.getPolyhedron().getGeometry().getSRID();
   1.461 -
   1.462 -			} else { // spatial literal
   1.463 +			}
   1.464 +			else
   1.465 +			{ // spatial literal
   1.466  				Literal spatial = (Literal) value;
   1.467  				String geomRep = spatial.stringValue();
   1.468 -
   1.469 -				if (XMLGSDatatypeUtil.isWKTLiteral(spatial)) { // WKT
   1.470 +				if(XMLGSDatatypeUtil.isWKTLiteral(spatial))
   1.471 +				{ // WKT
   1.472  					geom = jts.WKTread(WKTHelper.getWithoutSRID(geomRep));
   1.473  					srid = WKTHelper.getSRID(geomRep);
   1.474 -
   1.475 -				} else { // GML
   1.476 +				}
   1.477 +				else
   1.478 +				{ // GML
   1.479  					geom = jts.GMLread(geomRep);
   1.480  					srid = geom.getSRID();
   1.481 -
   1.482  				}
   1.483  			}
   1.484 -
   1.485  			// transform the geometry to {@link GeoConstants#defaultSRID}
   1.486  			geom = jts.transform(geom, srid, GeoConstants.defaultSRID);
   1.487 -
   1.488 -			if (geom instanceof Point) {
   1.489 +			if(geom instanceof Point)
   1.490 +			{
   1.491  				geometryType = KML.Point;
   1.492 -
   1.493 -			} else if (geom instanceof Polygon) {
   1.494 +			}
   1.495 +			else if(geom instanceof Polygon)
   1.496 +			{
   1.497  				geometryType = KML.Polygon;
   1.498 -
   1.499 -			} else if (geom instanceof LineString) {
   1.500 +			}
   1.501 +			else if(geom instanceof LineString)
   1.502 +			{
   1.503  				geometryType = KML.LineString;
   1.504 -
   1.505 -			} else if (geom instanceof MultiPoint) {
   1.506 +			}
   1.507 +			else if(geom instanceof MultiPoint)
   1.508 +			{
   1.509  				geometryType = KML.MultiGeometry;
   1.510 -
   1.511 -			} else if (geom instanceof MultiLineString) {
   1.512 +			}
   1.513 +			else if(geom instanceof MultiLineString)
   1.514 +			{
   1.515  				geometryType = KML.MultiGeometry;
   1.516 -
   1.517 -			} else if (geom instanceof MultiPolygon) {
   1.518 +			}
   1.519 +			else if(geom instanceof MultiPolygon)
   1.520 +			{
   1.521  				geometryType = KML.MultiGeometry;
   1.522 -
   1.523 -			} else if (geom instanceof GeometryCollection) {
   1.524 +			}
   1.525 +			else if(geom instanceof GeometryCollection)
   1.526 +			{
   1.527  				geometryType = KML.MultiGeometry;
   1.528 -
   1.529 -			} 
   1.530 -
   1.531 -			if (geometryType == null) {
   1.532 +			}
   1.533 +			if(geometryType == null)
   1.534 +			{
   1.535  				logger.warn("[Strabon.KMLWriter] Found unknown geometry type.");
   1.536 -
   1.537 -			} else {
   1.538 -
   1.539 +			}
   1.540 +			else
   1.541 +			{
   1.542  				encoder.encode(geom, geometryType, baos);
   1.543 -				kml = baos.toString().substring(38).replaceAll(" xmlns:kml=\"http://earth.google.com/kml/2.1\"","").replaceAll("kml:","");
   1.544 +				polygon=baos.toString().substring(38).replaceAll(" xmlns:kml=\"http://earth.google.com/kml/2.1\"", "").replaceAll("kml:", "");
   1.545 +				
   1.546 +				/*get the polygon from the kml*/
   1.547 +				polygon=polygon.substring(polygon.indexOf("<Polygon>"), polygon.indexOf("</MultiGeometry>"));
   1.548  				baos.reset();
   1.549  			}
   1.550 -
   1.551 -		} catch (ParseException e) {
   1.552 +		}
   1.553 +		catch(ParseException e)
   1.554 +		{
   1.555  			logger.error("[Strabon.KMLWriter] Parse error exception of geometry: {}", e.getMessage());
   1.556 -
   1.557 -		} catch (IOException e) {
   1.558 +		}
   1.559 +		catch(IOException e)
   1.560 +		{
   1.561  			logger.error("[Strabon.KMLWriter] IOException during KML encoding of geometry: {}", e.getMessage());
   1.562 -
   1.563 -		} catch (JAXBException e) {
   1.564 +		}
   1.565 +		catch(JAXBException e)
   1.566 +		{
   1.567  			logger.error("[Strabon.KMLWriter] Exception during GML parsing: {}", e.getMessage());
   1.568 -
   1.569  		}
   1.570 -
   1.571 -		return kml;
   1.572 +		
   1.573 +		return polygon;
   1.574  	}
   1.575  
   1.576  	/**
   1.577 @@ -433,26 +431,26 @@
   1.578  	 * 
   1.579  	 * @param binding
   1.580  	 */
   1.581 -	private void writeDesc(Binding binding) {
   1.582 +	private void writeDesc(Binding binding)
   1.583 +	{
   1.584  		descHeader.append(NEWLINE);
   1.585  		indent(descHeader, depth + 1);
   1.586  		descHeader.append(TABLE_DATA_BEGIN);
   1.587  		descHeader.append(binding.getName());
   1.588  		descHeader.append(TABLE_DATA_END);
   1.589 -
   1.590  		descData.append(NEWLINE);
   1.591  		indent(descData, depth + 1);
   1.592  		descData.append(TABLE_DATA_BEGIN);
   1.593 -		if (binding.getValue() instanceof BNode) {
   1.594 +		if(binding.getValue() instanceof BNode)
   1.595 +		{
   1.596  			descData.append("_:");
   1.597  		}
   1.598  		descData.append(binding.getValue().stringValue());
   1.599  		descData.append(TABLE_DATA_END);
   1.600 -
   1.601  	}
   1.602  
   1.603 -	@Override
   1.604 -	public TupleQueryResultFormat getTupleQueryResultFormat() {
   1.605 +	@Override public TupleQueryResultFormat getTupleQueryResultFormat()
   1.606 +	{
   1.607  		return stSPARQLQueryResultFormat.KML;
   1.608  	}
   1.609  
   1.610 @@ -463,8 +461,10 @@
   1.611  	 * @param sb
   1.612  	 * @param depth
   1.613  	 */
   1.614 -	private void indent(StringBuilder sb, int depth) {
   1.615 -		for (int i = 0; i < depth; i++) {
   1.616 +	private void indent(StringBuilder sb, int depth)
   1.617 +	{
   1.618 +		for(int i = 0; i < depth; i++)
   1.619 +		{
   1.620  			sb.append(xmlWriter.getIndentString());
   1.621  		}
   1.622  	}