Strabon
changeset 557:9f107d4df339
Modified the KML results writer to append several styles to the KML file.
Partially fixes Ticket #10
Partially fixes Ticket #10
author | Kostis Kyzirakos <kkyzir@di.uoa.gr> |
---|---|
date | Mon Sep 17 23:01:48 2012 +0300 (2012-09-17) |
parents | 157780b4d79b |
children | 28812d96cfa5 |
files | endpoint/WebContent/WEB-INF/connection.properties resultio/src/main/java/org/openrdf/query/resultio/sparqlkml/stSPARQLResultsKMLWriter.java |
line diff
1.1 --- a/endpoint/WebContent/WEB-INF/connection.properties Mon Sep 17 21:02:57 2012 +0300 1.2 +++ b/endpoint/WebContent/WEB-INF/connection.properties Mon Sep 17 23:01:48 2012 +0300 1.3 @@ -1,6 +1,7 @@ 1.4 -dbname = endpoint 1.5 -username = postgres 1.6 -password = postgres 1.7 -port = 5432 1.8 -hostname = localhost 1.9 -dbengine = postgis 1.10 \ No newline at end of file 1.11 +#Mon Sep 17 20:48:10 EEST 2012 1.12 +hostname=localhost 1.13 +port=5432 1.14 +dbengine=postgis 1.15 +password=p1r3as 1.16 +dbname=dlr-gis 1.17 +username=kkyzir
2.1 --- a/resultio/src/main/java/org/openrdf/query/resultio/sparqlkml/stSPARQLResultsKMLWriter.java Mon Sep 17 21:02:57 2012 +0300 2.2 +++ b/resultio/src/main/java/org/openrdf/query/resultio/sparqlkml/stSPARQLResultsKMLWriter.java Mon Sep 17 23:01:48 2012 +0300 2.3 @@ -56,37 +56,54 @@ 2.4 public class stSPARQLResultsKMLWriter implements TupleQueryResultWriter { 2.5 2.6 private static final Logger logger = LoggerFactory.getLogger(org.openrdf.query.resultio.sparqlkml.stSPARQLResultsKMLWriter.class); 2.7 - 2.8 + 2.9 private static final String ROOT_TAG = "kml"; 2.10 private static final String NAMESPACE = "http://www.opengis.net/kml/2.2"; 2.11 private static final String RESULT_SET_TAG = "Folder"; 2.12 - 2.13 + 2.14 private static final String PLACEMARK_TAG = "Placemark"; 2.15 private static final String NAME_TAG = "name"; 2.16 private static final String DESC_TAG = "description"; 2.17 - 2.18 + 2.19 + private static final String STYLE_TAG = "Style"; 2.20 + private static final String STYLEMAP_TAG = "StyleMap"; 2.21 + private static final String LINESTYLE_TAG = "LineStyle"; 2.22 + private static final String POLYSTYLE_TAG = "PolyStyle"; 2.23 + private static final String STYLE_ID = "resultStyle"; 2.24 + 2.25 private static final String TABLE_ROW_BEGIN = "<TR>"; 2.26 private static final String TABLE_ROW_END = "</TR>"; 2.27 private static final String TABLE_DATA_BEGIN = "<TD>"; 2.28 private static final String TABLE_DATA_END = "</TD>"; 2.29 - 2.30 + 2.31 private static final String NEWLINE = "\n"; 2.32 - 2.33 + 2.34 private static final String TABLE_DESC_BEGIN = "<![CDATA[<TABLE border=\"1\">" + NEWLINE; 2.35 private static final String TABLE_DESC_END = "</TABLE>]]>" + NEWLINE; 2.36 - 2.37 + 2.38 private static final String GEOMETRY_NAME = "Geometry"; 2.39 - 2.40 + 2.41 + //Styling options 2.42 + String [][] styles = { 2.43 + // note that colors are encoded as "aabbggrr" strings where 2.44 + // aa=alpha (00 to ff); bb=blue (00 to ff); gg=green (00 to ff); rr=red (00 to ff). 2.45 + // id, line width, line color, polygon fill, mouse over line width, mouse over line color mouse over polygon fill 2.46 + {STYLE_ID+"1", "1.5", "7dff0000", "7dff0000", "1.5", "7d0000ff", "7d0000ff"}, 2.47 + {STYLE_ID+"2", "1.5", "7d00ff00", "7d00ff00", "1.5", "7d0000ff", "7d0000ff"}, 2.48 + {STYLE_ID+"3", "1.5", "7d550000", "7d550000", "1.5", "7d0000ff", "7d0000ff"}, 2.49 + {STYLE_ID+"4", "1.5", "7d005500", "7d005500", "1.5", "7d0000ff", "7d0000ff"}, 2.50 + {STYLE_ID+"5", "1.5", "7d000055", "7d000055", "1.5", "7d0000ff", "7d0000ff"}, 2.51 + }; 2.52 /** 2.53 * The underlying XML formatter. 2.54 */ 2.55 private stSPARQLXMLWriter xmlWriter; 2.56 - 2.57 + 2.58 /** 2.59 * The number of results seen. 2.60 */ 2.61 private int nresults; 2.62 - 2.63 + 2.64 /** 2.65 * The number of geometries seen. 2.66 */ 2.67 @@ -96,29 +113,29 @@ 2.68 * The JTS wrapper 2.69 */ 2.70 private JTSWrapper jts; 2.71 - 2.72 + 2.73 /** 2.74 * Stream for manipulating geometries 2.75 */ 2.76 private ByteArrayOutputStream baos; 2.77 - 2.78 + 2.79 /** 2.80 * Description string holding the projected variables 2.81 * of the SPARQL query 2.82 */ 2.83 private StringBuilder descHeader; 2.84 - 2.85 + 2.86 /** 2.87 * Description string holding the values for the 2.88 * projected variables of the SPARQL query 2.89 */ 2.90 private StringBuilder descData; 2.91 - 2.92 + 2.93 /** 2.94 * Indentation used in tags that are constructed manually 2.95 */ 2.96 private int depth; 2.97 - 2.98 + 2.99 /** 2.100 * Creates an stSPARQLResultsKMLWriter that encodes the SPARQL 2.101 * results in KML. 2.102 @@ -128,24 +145,24 @@ 2.103 public stSPARQLResultsKMLWriter(OutputStream out) { 2.104 this(new stSPARQLXMLWriter(out)); 2.105 } 2.106 - 2.107 + 2.108 public stSPARQLResultsKMLWriter(stSPARQLXMLWriter writer) { 2.109 xmlWriter = writer; 2.110 xmlWriter.setPrettyPrint(true); 2.111 - 2.112 + 2.113 depth = 4; 2.114 - 2.115 + 2.116 jts = JTSWrapper.getInstance(); 2.117 - 2.118 + 2.119 baos = new ByteArrayOutputStream(); 2.120 - 2.121 + 2.122 descHeader = new StringBuilder(); 2.123 descData = new StringBuilder(); 2.124 - 2.125 + 2.126 nresults = 0; 2.127 ngeometries = 0; 2.128 } 2.129 - 2.130 + 2.131 @Override 2.132 public void startQueryResult(List<String> bindingNames) throws TupleQueryResultHandlerException { 2.133 try { 2.134 @@ -154,6 +171,52 @@ 2.135 xmlWriter.setAttribute("xmlns", NAMESPACE); 2.136 xmlWriter.startTag(ROOT_TAG); 2.137 xmlWriter.startTag(RESULT_SET_TAG); 2.138 + 2.139 + //add default styles 2.140 + for (String[] style: styles) { 2.141 + String id = style[0]; 2.142 + String lineWidth = style[1]; 2.143 + String lineColor = style[2]; 2.144 + String polygonFill = style[3]; 2.145 + String mouseOverLineWidth = style[4]; 2.146 + String mouseOverLineColor = style[5]; 2.147 + String mouseOverPolygonFill = style[6]; 2.148 + 2.149 + xmlWriter.setAttribute("id", "normal_"+id); 2.150 + xmlWriter.startTag(STYLE_TAG); 2.151 + xmlWriter.startTag(LINESTYLE_TAG); 2.152 + xmlWriter.textElement("width", lineWidth); 2.153 + xmlWriter.textElement("color", lineColor); 2.154 + xmlWriter.endTag(LINESTYLE_TAG); 2.155 + xmlWriter.startTag(POLYSTYLE_TAG); 2.156 + xmlWriter.textElement("color", polygonFill); 2.157 + xmlWriter.endTag(POLYSTYLE_TAG); 2.158 + xmlWriter.endTag(STYLE_TAG); 2.159 + 2.160 + xmlWriter.setAttribute("id", "highlight_"+id); 2.161 + xmlWriter.startTag(STYLE_TAG); 2.162 + xmlWriter.startTag(LINESTYLE_TAG); 2.163 + xmlWriter.textElement("width", mouseOverLineWidth); 2.164 + xmlWriter.textElement("color", mouseOverLineColor); 2.165 + xmlWriter.endTag(LINESTYLE_TAG); 2.166 + xmlWriter.startTag(POLYSTYLE_TAG); 2.167 + xmlWriter.textElement("color", mouseOverPolygonFill); 2.168 + xmlWriter.endTag(POLYSTYLE_TAG); 2.169 + xmlWriter.endTag(STYLE_TAG); 2.170 + 2.171 + xmlWriter.setAttribute("id", id); 2.172 + xmlWriter.startTag(STYLEMAP_TAG); 2.173 + xmlWriter.startTag("Pair"); 2.174 + xmlWriter.textElement("key", "normal"); 2.175 + xmlWriter.textElement("styleUrl", "#normal_"+id); 2.176 + xmlWriter.endTag("Pair"); 2.177 + xmlWriter.startTag("Pair"); 2.178 + xmlWriter.textElement("key", "highlight"); 2.179 + xmlWriter.textElement("styleUrl", "#highlight_"+id); 2.180 + xmlWriter.endTag("Pair"); 2.181 + xmlWriter.endTag(STYLEMAP_TAG); 2.182 + } 2.183 + //end of default style definition 2.184 } 2.185 catch (IOException e) { 2.186 throw new TupleQueryResultHandlerException(e); 2.187 @@ -167,9 +230,9 @@ 2.188 xmlWriter.endTag(ROOT_TAG); 2.189 2.190 xmlWriter.endDocument(); 2.191 - 2.192 + 2.193 baos.close(); 2.194 - 2.195 + 2.196 if (ngeometries < nresults) { 2.197 logger.warn("[Strabon.KMLWriter] No spatial binding found in the result. KML requires that at least one binding maps to a geometry.", nresults); 2.198 } 2.199 @@ -184,16 +247,16 @@ 2.200 try { 2.201 // true if there are bindings that do not correspond to geometries 2.202 boolean hasDesc = false; 2.203 - 2.204 + 2.205 // increase result size 2.206 nresults++; 2.207 - 2.208 + 2.209 // create description table and header 2.210 indent(descHeader, depth); 2.211 descHeader.append(TABLE_DESC_BEGIN); 2.212 indent(descHeader, depth); 2.213 descHeader.append(TABLE_ROW_BEGIN); 2.214 - 2.215 + 2.216 // create description table data row 2.217 descData.append(NEWLINE); 2.218 indent(descData, depth); 2.219 @@ -202,7 +265,11 @@ 2.220 // write placemark tag 2.221 xmlWriter.startTag(PLACEMARK_TAG); 2.222 xmlWriter.textElement(NAME_TAG, GEOMETRY_NAME + nresults + "_" + ngeometries); 2.223 - 2.224 + 2.225 + //TODO: Hardcoded style selection. Modify this line after adding 2.226 + //support for multiple geometry variables in the select clause 2.227 + xmlWriter.textElement("styleUrl", "#"+styles[0][0]); 2.228 + 2.229 // parse binding set 2.230 for (Binding binding : bindingSet) { 2.231 Value value = binding.getValue(); 2.232 @@ -210,57 +277,57 @@ 2.233 // check for geometry value 2.234 if (XMLGSDatatypeUtil.isGeometryValue(value)) { 2.235 ngeometries++; 2.236 - 2.237 + 2.238 if (logger.isDebugEnabled()) { 2.239 logger.debug("[Strabon] Found geometry: {}", value); 2.240 } 2.241 - 2.242 + 2.243 xmlWriter.unescapedText(getKML(value)); 2.244 - 2.245 + 2.246 } else { // URI, BlankNode, or Literal other than spatial literal 2.247 if (logger.isDebugEnabled()) { 2.248 logger.debug("[Strabon.KMLWriter] Found URI/BlankNode/Literal ({}): {}", value.getClass(), value); 2.249 } 2.250 - 2.251 + 2.252 // mark that we found sth corresponding to the description 2.253 hasDesc = true; 2.254 - 2.255 + 2.256 // write description 2.257 writeDesc(binding); 2.258 } 2.259 } 2.260 - 2.261 + 2.262 // we have found and constructed a description for this result. Write it down. 2.263 if (hasDesc) { 2.264 // close the header of the description 2.265 descHeader.append(NEWLINE); 2.266 indent(descHeader, depth); 2.267 descHeader.append(TABLE_ROW_END); 2.268 - 2.269 + 2.270 // end the placeholder for the description data 2.271 descData.append(NEWLINE); 2.272 indent(descData, depth); 2.273 descData.append(TABLE_ROW_END); 2.274 - 2.275 + 2.276 // append to the table header the actual content from 2.277 // the bindings 2.278 descHeader.append(descData); 2.279 - 2.280 + 2.281 // close the table for the description 2.282 descHeader.append(NEWLINE); 2.283 indent(descHeader, depth); 2.284 descHeader.append(TABLE_DESC_END); 2.285 - 2.286 + 2.287 // begin the "description" tag 2.288 xmlWriter.startTag(DESC_TAG); 2.289 - 2.290 + 2.291 // write the actual description 2.292 xmlWriter.unescapedText(descHeader.toString()); 2.293 - 2.294 + 2.295 // end the "description" tag 2.296 xmlWriter.endTag(DESC_TAG); 2.297 } 2.298 - 2.299 + 2.300 // clear description string builders 2.301 descHeader.setLength(0); 2.302 descData.setLength(0); 2.303 @@ -276,88 +343,88 @@ 2.304 private String getKML(Value value) { 2.305 String kml = ""; 2.306 QName geometryType = null; 2.307 - 2.308 + 2.309 // the underlying geometry in value 2.310 Geometry geom = null; 2.311 - 2.312 + 2.313 // the underlying SRID of the geometry 2.314 int srid = -1; 2.315 - 2.316 + 2.317 // get the KML encoder 2.318 Encoder encoder = null; 2.319 - 2.320 + 2.321 try { 2.322 encoder = new Encoder(new KMLConfiguration()); 2.323 encoder.setIndenting(true); 2.324 - 2.325 + 2.326 if (value instanceof GeneralDBPolyhedron) { 2.327 GeneralDBPolyhedron dbpolyhedron = (GeneralDBPolyhedron) value; 2.328 - 2.329 + 2.330 geom = dbpolyhedron.getPolyhedron().getGeometry(); 2.331 srid = dbpolyhedron.getPolyhedron().getGeometry().getSRID(); 2.332 - 2.333 + 2.334 } else { // spatial literal 2.335 Literal spatial = (Literal) value; 2.336 String geomRep = spatial.stringValue(); 2.337 - 2.338 + 2.339 if (XMLGSDatatypeUtil.isWKTLiteral(spatial)) { // WKT 2.340 geom = jts.WKTread(WKTHelper.getWithoutSRID(geomRep)); 2.341 srid = WKTHelper.getSRID(geomRep); 2.342 - 2.343 + 2.344 } else { // GML 2.345 geom = jts.GMLread(geomRep); 2.346 srid = geom.getSRID(); 2.347 - 2.348 + 2.349 } 2.350 } 2.351 - 2.352 + 2.353 // transform the geometry to {@link GeoConstants#defaultSRID} 2.354 geom = jts.transform(geom, srid, GeoConstants.defaultSRID); 2.355 - 2.356 + 2.357 if (geom instanceof Point) { 2.358 geometryType = KML.Point; 2.359 - 2.360 + 2.361 } else if (geom instanceof Polygon) { 2.362 geometryType = KML.Polygon; 2.363 - 2.364 + 2.365 } else if (geom instanceof LineString) { 2.366 geometryType = KML.LineString; 2.367 - 2.368 + 2.369 } else if (geom instanceof MultiPoint) { 2.370 geometryType = KML.MultiGeometry; 2.371 - 2.372 + 2.373 } else if (geom instanceof MultiLineString) { 2.374 geometryType = KML.MultiGeometry; 2.375 - 2.376 + 2.377 } else if (geom instanceof MultiPolygon) { 2.378 geometryType = KML.MultiGeometry; 2.379 - 2.380 + 2.381 } else if (geom instanceof GeometryCollection) { 2.382 geometryType = KML.MultiGeometry; 2.383 - 2.384 + 2.385 } 2.386 - 2.387 + 2.388 if (geometryType == null) { 2.389 logger.warn("[Strabon.KMLWriter] Found unknown geometry type."); 2.390 - 2.391 + 2.392 } else { 2.393 - 2.394 + 2.395 encoder.encode(geom, geometryType, baos); 2.396 kml = baos.toString().substring(38).replaceAll(" xmlns:kml=\"http://earth.google.com/kml/2.1\"","").replaceAll("kml:",""); 2.397 baos.reset(); 2.398 } 2.399 - 2.400 + 2.401 } catch (ParseException e) { 2.402 logger.error("[Strabon.KMLWriter] Parse error exception of geometry: {}", e.getMessage()); 2.403 - 2.404 + 2.405 } catch (IOException e) { 2.406 logger.error("[Strabon.KMLWriter] IOException during KML encoding of geometry: {}", e.getMessage()); 2.407 - 2.408 + 2.409 } catch (JAXBException e) { 2.410 logger.error("[Strabon.KMLWriter] Exception during GML parsing: {}", e.getMessage()); 2.411 - 2.412 + 2.413 } 2.414 - 2.415 + 2.416 return kml; 2.417 } 2.418 2.419 @@ -372,7 +439,7 @@ 2.420 descHeader.append(TABLE_DATA_BEGIN); 2.421 descHeader.append(binding.getName()); 2.422 descHeader.append(TABLE_DATA_END); 2.423 - 2.424 + 2.425 descData.append(NEWLINE); 2.426 indent(descData, depth + 1); 2.427 descData.append(TABLE_DATA_BEGIN); 2.428 @@ -381,14 +448,14 @@ 2.429 } 2.430 descData.append(binding.getValue().stringValue()); 2.431 descData.append(TABLE_DATA_END); 2.432 - 2.433 + 2.434 } 2.435 2.436 @Override 2.437 public TupleQueryResultFormat getTupleQueryResultFormat() { 2.438 return stSPARQLQueryResultFormat.KML; 2.439 } 2.440 - 2.441 + 2.442 /** 2.443 * Adds indentation to the given string builder according to 2.444 * the specified depth.