001 //$HeadURL: https://sushibar/svn/deegree/base/trunk/resources/eclipse/svn_classfile_header_template.xml $ 002 /*---------------------------------------------------------------------------- 003 This file is part of deegree, http://deegree.org/ 004 Copyright (C) 2001-2009 by: 005 Department of Geography, University of Bonn 006 and 007 lat/lon GmbH 008 009 This library is free software; you can redistribute it and/or modify it under 010 the terms of the GNU Lesser General Public License as published by the Free 011 Software Foundation; either version 2.1 of the License, or (at your option) 012 any later version. 013 This library is distributed in the hope that it will be useful, but WITHOUT 014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 016 details. 017 You should have received a copy of the GNU Lesser General Public License 018 along with this library; if not, write to the Free Software Foundation, Inc., 019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 020 021 Contact information: 022 023 lat/lon GmbH 024 Aennchenstr. 19, 53177 Bonn 025 Germany 026 http://lat-lon.de/ 027 028 Department of Geography, University of Bonn 029 Prof. Dr. Klaus Greve 030 Postfach 1147, 53001 Bonn 031 Germany 032 http://www.geographie.uni-bonn.de/deegree/ 033 034 e-mail: info@deegree.org 035 ----------------------------------------------------------------------------*/ 036 037 package org.deegree.io.mapinfoapi; 038 039 import static java.awt.Color.black; 040 import static java.awt.Color.decode; 041 import static java.awt.Color.white; 042 import static java.awt.Font.TRUETYPE_FONT; 043 import static java.awt.Font.createFont; 044 import static java.awt.image.BufferedImage.TYPE_INT_ARGB; 045 import static java.io.File.createTempFile; 046 import static java.lang.Integer.parseInt; 047 import static java.lang.Integer.toHexString; 048 import static java.lang.Math.sqrt; 049 import static javax.imageio.ImageIO.write; 050 import static javax.media.jai.JAI.create; 051 import static org.apache.batik.transcoder.SVGAbstractTranscoder.KEY_HEIGHT; 052 import static org.apache.batik.transcoder.SVGAbstractTranscoder.KEY_WIDTH; 053 import static org.deegree.framework.log.LoggerFactory.getLogger; 054 import static org.deegree.framework.xml.XMLTools.appendElement; 055 import static org.deegree.framework.xml.XMLTools.getNodes; 056 import static org.deegree.framework.xml.XMLTools.getRequiredElement; 057 import static org.deegree.ogcbase.CommonNamespaces.GMLNS; 058 import static org.deegree.ogcbase.CommonNamespaces.GML_PREFIX; 059 import static org.deegree.ogcbase.CommonNamespaces.OGCNS; 060 import static org.deegree.ogcbase.CommonNamespaces.OGC_PREFIX; 061 import static org.deegree.ogcbase.CommonNamespaces.SLDNS; 062 import static org.deegree.ogcbase.CommonNamespaces.SLD_PREFIX; 063 import static org.deegree.ogcbase.CommonNamespaces.XLINK_PREFIX; 064 import static org.deegree.ogcbase.CommonNamespaces.XLNNS; 065 import static org.deegree.ogcbase.CommonNamespaces.XSINS; 066 import static org.deegree.ogcbase.CommonNamespaces.XSI_PREFIX; 067 import static org.deegree.ogcbase.CommonNamespaces.getNamespaceContext; 068 069 import java.awt.Color; 070 import java.awt.Font; 071 import java.awt.FontFormatException; 072 import java.awt.Graphics2D; 073 import java.awt.image.BufferedImage; 074 import java.io.ByteArrayInputStream; 075 import java.io.ByteArrayOutputStream; 076 import java.io.File; 077 import java.io.FileOutputStream; 078 import java.io.IOException; 079 import java.io.InputStream; 080 import java.io.InputStreamReader; 081 import java.io.StringReader; 082 import java.net.MalformedURLException; 083 import java.net.URL; 084 import java.text.DecimalFormat; 085 import java.util.HashMap; 086 import java.util.HashSet; 087 import java.util.List; 088 import java.util.Map; 089 import java.util.zip.ZipEntry; 090 import java.util.zip.ZipFile; 091 092 import javax.media.jai.RenderedOp; 093 094 import org.apache.batik.transcoder.TranscoderException; 095 import org.apache.batik.transcoder.TranscoderInput; 096 import org.apache.batik.transcoder.TranscoderOutput; 097 import org.apache.batik.transcoder.image.PNGTranscoder; 098 import org.deegree.datatypes.QualifiedName; 099 import org.deegree.framework.log.ILogger; 100 import org.deegree.framework.xml.NamespaceContext; 101 import org.deegree.framework.xml.XMLFragment; 102 import org.deegree.framework.xml.XMLParsingException; 103 import org.deegree.graphics.Theme; 104 import org.w3c.dom.DOMException; 105 import org.w3c.dom.Element; 106 import org.w3c.dom.Node; 107 import org.xml.sax.SAXException; 108 109 import com.sun.media.jai.codec.MemoryCacheSeekableStream; 110 111 /** 112 * <code>MIFStyle2SLD</code> 113 * 114 * @author <a href="mailto:schmitz@lat-lon.de">Andreas Schmitz</a> 115 * @author last edited by: $Author:$ 116 * 117 * @version $Revision:$, $Date:$ 118 */ 119 public class MIFStyle2SLD { 120 121 private static final NamespaceContext nsContext = getNamespaceContext(); 122 123 private static final ILogger LOG = getLogger( MIFStyle2SLD.class ); 124 125 private Font symbolFont; 126 127 private static File BRUSHES, POINTS; 128 129 private static final double SQRT2 = sqrt( 2 ); 130 131 static { 132 // copy the brushes.zip to temp dir 133 // necessary, because we cannot directly extract a singe entry from jar-enclosed zip 134 try { 135 BRUSHES = File.createTempFile( "brushes", ".zip" ); 136 BRUSHES.deleteOnExit(); 137 138 InputStream in = MIFStyle2SLD.class.getResourceAsStream( "brushes.zip" ); 139 if ( in == null ) { 140 in = Theme.class.getResourceAsStream( "fillpatterns.zip" ); 141 } 142 FileOutputStream out = new FileOutputStream( BRUSHES ); 143 144 byte[] buf = new byte[16384]; 145 146 int read; 147 if ( in != null ) { 148 while ( ( read = in.read( buf ) ) != -1 ) { 149 out.write( buf, 0, read ); 150 } 151 in.close(); 152 } 153 out.close(); 154 155 } catch ( IOException e ) { 156 LOG.logError( "Could not find the brushes zip file", e ); 157 } 158 // same for more complicated points 159 try { 160 POINTS = File.createTempFile( "points", ".zip" ); 161 POINTS.deleteOnExit(); 162 163 InputStream in = MIFStyle2SLD.class.getResourceAsStream( "points.zip" ); 164 if ( in == null ) { 165 in = Theme.class.getResourceAsStream( "points.zip" ); 166 } 167 FileOutputStream out = new FileOutputStream( POINTS ); 168 169 byte[] buf = new byte[16384]; 170 171 int read; 172 if ( in != null ) { 173 while ( ( read = in.read( buf ) ) != -1 ) { 174 out.write( buf, 0, read ); 175 } 176 in.close(); 177 } 178 out.close(); 179 } catch ( IOException e ) { 180 LOG.logError( "Could not find the points zip file", e ); 181 } 182 } 183 184 /** 185 * @param symbolFont 186 * @throws FontFormatException 187 * @throws IOException 188 */ 189 public MIFStyle2SLD( String symbolFont ) throws FontFormatException, IOException { 190 this.symbolFont = createFont( TRUETYPE_FONT, new File( symbolFont ) ); 191 } 192 193 /** 194 * @param symbolFont 195 * @throws FontFormatException 196 * @throws IOException 197 */ 198 public MIFStyle2SLD( URL symbolFont ) throws FontFormatException, IOException { 199 this.symbolFont = createFont( TRUETYPE_FONT, symbolFont.openStream() ); 200 } 201 202 /** 203 * @param name 204 * the layer name 205 * @return an empty SLD document 206 */ 207 public static XMLFragment getSLDTemplate( String name ) { 208 XMLFragment doc = new XMLFragment( new QualifiedName( SLD_PREFIX, "StyledLayerDescriptor", SLDNS ) ); 209 Element root = doc.getRootElement(); 210 root.setAttribute( "version", "1.0.0" ); 211 root.setAttribute( "xmlns:app", "http://www.deegree.org/app" ); 212 root.setAttribute( "xmlns:" + XLINK_PREFIX, XLNNS.toASCIIString() ); 213 root.setAttribute( "xmlns:" + OGC_PREFIX, OGCNS.toASCIIString() ); 214 root.setAttribute( "xmlns:" + GML_PREFIX, GMLNS.toASCIIString() ); 215 root.setAttribute( "xmlns:" + XSI_PREFIX, XSINS.toASCIIString() ); 216 root.setAttribute( XSI_PREFIX + ":schemaLocation", 217 SLDNS.toASCIIString() + " http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd" ); 218 219 Element e = appendElement( root, SLDNS, SLD_PREFIX + ":NamedLayer" ); 220 appendElement( e, SLDNS, SLD_PREFIX + ":Name", "default:" + name ); 221 e = appendElement( e, SLDNS, SLD_PREFIX + ":UserStyle" ); 222 appendElement( e, SLDNS, SLD_PREFIX + ":Name", "default:" + name ); 223 appendElement( e, SLDNS, SLD_PREFIX + ":Title", "default:" + name ); 224 appendElement( e, SLDNS, SLD_PREFIX + ":IsDefault", "1" ); 225 e = appendElement( e, SLDNS, SLD_PREFIX + ":FeatureTypeStyle" ); 226 appendElement( e, SLDNS, SLD_PREFIX + ":Name", "default:" + name ); 227 228 String str = doc.getAsString(); 229 230 // wrap it, so the namespace bindings are correct (is there a better way to add them to the 231 // root element?) 232 try { 233 return new XMLFragment( new StringReader( str ), "http://www.systemid.org" ); 234 } catch ( SAXException ex ) { 235 // eat it, it must be parseable 236 } catch ( IOException ex ) { 237 // eat it, it must be parseable 238 } 239 240 return null; 241 } 242 243 /** 244 * @param id 245 * @param rule 246 */ 247 public static void appendIDFilter( String id, Element rule ) { 248 appendElement( rule, SLDNS, SLD_PREFIX + ":Name", id ); 249 Element e = appendElement( rule, OGCNS, OGC_PREFIX + ":Filter" ); 250 Element or = appendElement( e, OGCNS, OGC_PREFIX + ":Or" ); 251 e = appendElement( or, OGCNS, OGC_PREFIX + ":PropertyIsLike" ); 252 e.setAttribute( "wildCard", "*" ); 253 e.setAttribute( "escape", "\\" ); 254 e.setAttribute( "singleChar", "?" ); 255 appendElement( e, OGCNS, OGC_PREFIX + ":PropertyName", "app:styleid" ); 256 appendElement( e, OGCNS, OGC_PREFIX + ":Literal", id ); 257 258 // it could be part of a combined (polygon) style 259 e = appendElement( or, OGCNS, OGC_PREFIX + ":PropertyIsLike" ); 260 e.setAttribute( "wildCard", "*" ); 261 e.setAttribute( "escape", "\\" ); 262 e.setAttribute( "singleChar", "?" ); 263 appendElement( e, OGCNS, OGC_PREFIX + ":PropertyName", "app:styleid" ); 264 appendElement( e, OGCNS, OGC_PREFIX + ":Literal", "*_" + id ); 265 266 e = appendElement( or, OGCNS, OGC_PREFIX + ":PropertyIsLike" ); 267 e.setAttribute( "wildCard", "*" ); 268 e.setAttribute( "escape", "\\" ); 269 e.setAttribute( "singleChar", "?" ); 270 appendElement( e, OGCNS, OGC_PREFIX + ":PropertyName", "app:styleid" ); 271 appendElement( e, OGCNS, OGC_PREFIX + ":Literal", id + "_*" ); 272 } 273 274 /** 275 * @param map 276 * @param doc 277 * @throws DOMException 278 * @throws IOException 279 * @throws XMLParsingException 280 * @throws SAXException 281 */ 282 public void insertSymbolStyle( Map<String, String> map, XMLFragment doc ) 283 throws DOMException, IOException, XMLParsingException, SAXException { 284 285 if ( map.size() != 4 && map.size() != 5 ) { 286 LOG.logWarning( "Symbol style not supported yet: " + map ); 287 return; 288 } 289 290 // custom bitmap symbol style 291 if ( map.size() == 5 ) { 292 int size = parseInt( map.get( "size" ) ); 293 294 if ( map.get( "filename" ) == null ) { 295 LOG.logWarning( "Symbol style not supported yet: " + map ); 296 return; 297 } 298 299 File file = new File( map.get( "filename" ) ); 300 if ( !file.exists() ) { 301 LOG.logWarning( "The specified symbol does not exist: " + file.toString() ); 302 return; 303 } 304 305 Element e = getRequiredElement( doc.getRootElement(), ".//" + SLD_PREFIX + ":FeatureTypeStyle", nsContext ); 306 e = appendElement( e, SLDNS, SLD_PREFIX + ":Rule" ); 307 appendIDFilter( map.get( "styleid" ), e ); 308 e = appendElement( e, SLDNS, SLD_PREFIX + ":PointSymbolizer" ); 309 e = appendElement( e, SLDNS, SLD_PREFIX + ":Graphic" ); 310 appendElement( e, SLDNS, SLD_PREFIX + ":Size", "" + size ); 311 e = appendElement( e, SLDNS, SLD_PREFIX + ":ExternalGraphic" ); 312 Element o = appendElement( e, SLDNS, SLD_PREFIX + ":OnlineResource" ); 313 o.setAttributeNS( XLNNS.toASCIIString(), XLINK_PREFIX + ":href", file.toURI().toURL().toExternalForm() ); 314 o.setAttributeNS( XLNNS.toASCIIString(), XLINK_PREFIX + ":type", "simple" ); 315 appendElement( e, SLDNS, SLD_PREFIX + ":Format", "image/bmp" ); 316 317 return; 318 } 319 320 Color c = decode( map.get( "color" ) ); 321 322 int size = parseInt( map.get( "size" ) ); 323 int symbol = parseInt( map.get( "shape" ) ); 324 325 BufferedImage img = null; 326 327 switch ( symbol ) { 328 case 31: 329 // don't do anything 330 return; 331 case 32: 332 img = symbolFromTwoChars( symbolFont, (char) 61473, (char) 61479, size, c, black ); 333 break; 334 case 33: 335 img = symbolFromTwoChars( symbolFont, (char) 61474, (char) 61480, size, c, black ); 336 break; 337 case 34: 338 img = symbolFromTwoChars( symbolFont, (char) 61475, (char) 61481, size, c, black ); 339 break; 340 case 35: 341 img = symbolFromTwoChars( symbolFont, (char) 61476, (char) 61482, size, c, black ); 342 break; 343 case 36: 344 img = symbolFromTwoChars( symbolFont, (char) 61477, (char) 61483, size, c, black ); 345 break; 346 case 37: 347 img = symbolFromTwoChars( symbolFont, (char) 61478, (char) 61484, size, c, black ); 348 break; 349 case 38: 350 case 39: 351 case 40: 352 case 41: 353 case 42: 354 case 43: 355 case 49: 356 case 50: 357 case 51: 358 case 52: 359 case 53: 360 case 54: 361 case 55: 362 case 56: 363 case 57: 364 case 58: 365 case 60: 366 case 61: 367 case 62: 368 case 63: 369 case 64: 370 img = symbolFromFont( symbolFont, (char) ( 61473 + symbol - 32 ), size, c ); 371 break; 372 case 44: 373 case 45: 374 case 46: 375 case 47: 376 case 48: 377 case 65: 378 case 66: 379 case 67: { 380 ZipFile zip = new ZipFile( POINTS ); 381 ZipEntry entry = zip.getEntry( symbol + ".svg" ); 382 XMLFragment svg = new XMLFragment( new InputStreamReader( zip.getInputStream( entry ) ), 383 "http://www.systemid.org" ); 384 zip.close(); 385 updateSVGColors( svg, toHexColor( c ), toHexColor( c ) ); 386 img = renderSVGImage( svg, size ); 387 break; 388 } 389 case 59: { 390 ZipFile zip = new ZipFile( POINTS ); 391 ZipEntry entry = zip.getEntry( symbol + ".svg" ); 392 XMLFragment svg = new XMLFragment( new InputStreamReader( zip.getInputStream( entry ) ), 393 "http://www.systemid.org" ); 394 zip.close(); 395 updateSVGColors( svg, toHexColor( c ), toHexColor( c ) ); 396 img = renderSVGImage( svg, size ); 397 break; 398 } 399 } 400 401 if ( img == null ) { 402 img = new BufferedImage( 1, 1, TYPE_INT_ARGB ); 403 } 404 405 File symbolFile = createTempFile( "mmsvg", ".png" ); 406 write( img, "png", symbolFile ); 407 symbolFile.deleteOnExit(); 408 409 Element e = getRequiredElement( doc.getRootElement(), ".//" + SLD_PREFIX + ":FeatureTypeStyle", nsContext ); 410 e = appendElement( e, SLDNS, SLD_PREFIX + ":Rule" ); 411 appendIDFilter( map.get( "styleid" ), e ); 412 e = appendElement( e, SLDNS, SLD_PREFIX + ":PointSymbolizer" ); 413 e = appendElement( e, SLDNS, SLD_PREFIX + ":Graphic" ); 414 e = appendElement( e, SLDNS, SLD_PREFIX + ":ExternalGraphic" ); 415 Element o = appendElement( e, SLDNS, SLD_PREFIX + ":OnlineResource" ); 416 o.setAttributeNS( XLNNS.toASCIIString(), XLINK_PREFIX + ":href", symbolFile.toURI().toURL().toExternalForm() ); 417 o.setAttributeNS( XLNNS.toASCIIString(), XLINK_PREFIX + ":type", "simple" ); 418 appendElement( e, SLDNS, SLD_PREFIX + ":Format", "image/png" ); 419 } 420 421 private static void appendSimpleLine( Element rule, String cssPattern, int width, Color c ) { 422 Element e = appendElement( rule, SLDNS, SLD_PREFIX + ":LineSymbolizer" ); 423 e = appendElement( e, SLDNS, SLD_PREFIX + ":Stroke" ); 424 appendElement( e, SLDNS, SLD_PREFIX + ":CssParameter", toHexColor( c ) ).setAttribute( "name", "stroke" ); 425 appendElement( e, SLDNS, SLD_PREFIX + ":CssParameter", "" + width ).setAttribute( "name", "stroke-width" ); 426 if ( cssPattern != null ) { 427 appendElement( e, SLDNS, SLD_PREFIX + ":CssParameter", cssPattern ).setAttribute( "name", 428 "stroke-dasharray" ); 429 } 430 } 431 432 private static void appendImageLine( Element rule, String image, int width, Color c ) 433 throws MalformedURLException, IOException, SAXException, XMLParsingException { 434 XMLFragment svg = new XMLFragment( MIFStyle2SLD.class.getResource( "lines/" + image ) ); 435 updateSVGColors( svg, toHexColor( c ), toHexColor( c ) ); 436 BufferedImage img = renderSVGImage( svg, 0 ); 437 File svgFile = createTempFile( "mmsvg", ".png" ); 438 write( img, "png", svgFile ); 439 svgFile.deleteOnExit(); 440 441 Element e = appendElement( rule, SLDNS, SLD_PREFIX + ":LineSymbolizer" ); 442 e = appendElement( e, SLDNS, SLD_PREFIX + ":Stroke" ); 443 appendElement( e, SLDNS, SLD_PREFIX + ":CssParameter", "0" ).setAttribute( "name", "stroke-width" ); 444 appendElement( e, SLDNS, SLD_PREFIX + ":CssParameter", "0" ).setAttribute( "name", "stroke-opacity" ); 445 e = appendElement( e, SLDNS, SLD_PREFIX + ":GraphicStroke" ); 446 e = appendElement( e, SLDNS, SLD_PREFIX + ":Graphic" ); 447 appendElement( e, SLDNS, SLD_PREFIX + ":Size", "" + width ); 448 e = appendElement( e, SLDNS, SLD_PREFIX + ":ExternalGraphic" ); 449 Element o = appendElement( e, SLDNS, SLD_PREFIX + ":OnlineResource" ); 450 o.setAttributeNS( XLNNS.toASCIIString(), XLINK_PREFIX + ":href", svgFile.toURI().toURL().toExternalForm() ); 451 o.setAttributeNS( XLNNS.toASCIIString(), XLINK_PREFIX + ":type", "simple" ); 452 appendElement( e, SLDNS, SLD_PREFIX + ":Format", "image/png" ); 453 } 454 455 /** 456 * @param pattern 457 * a pattern like "1 2 1 2" 458 * @param mult 459 * @return the new pattern with each value multiplied by mult 460 */ 461 public static String multiplyPattern( String pattern, int mult ) { 462 String[] elems = pattern.split( "[ ]" ); 463 StringBuffer sb = new StringBuffer( pattern.length() ); 464 465 for ( int i = 0; i < elems.length; ++i ) { 466 int k = mult * parseInt( elems[i] ); 467 sb.append( k ); 468 if ( i < elems.length - 1 ) { 469 sb.append( " " ); 470 } 471 } 472 473 return sb.toString(); 474 } 475 476 /** 477 * @param map 478 * @param doc 479 * @throws XMLParsingException 480 * @throws SAXException 481 * @throws IOException 482 * @throws MalformedURLException 483 */ 484 public static void insertPenStyle( Map<String, String> map, XMLFragment doc ) 485 throws MalformedURLException, IOException, SAXException, XMLParsingException { 486 int pattern = parseInt( map.get( "pattern" ) ); 487 Color c = decode( map.get( "color" ) ); 488 int width = parseInt( map.get( "width" ) ); 489 if ( width > 10 ) { 490 width = width * 10 + 10; 491 width = (int) ( width / 72d / SQRT2 ); 492 LOG.logDebug( "Calculated pixel width from points", width ); 493 } 494 495 Element e = getRequiredElement( doc.getRootElement(), ".//" + SLD_PREFIX + ":FeatureTypeStyle", nsContext ); 496 Element rule = appendElement( e, SLDNS, SLD_PREFIX + ":Rule" ); 497 appendIDFilter( map.get( "styleid" ), rule ); 498 499 switch ( pattern ) { 500 case 1: 501 break; 502 case 2: 503 appendSimpleLine( rule, null, width, c ); 504 break; 505 case 3: 506 appendSimpleLine( rule, multiplyPattern( "1 1", width ), width, c ); 507 break; 508 case 4: 509 appendSimpleLine( rule, multiplyPattern( "2 2", width ), width, c ); 510 break; 511 case 5: 512 appendSimpleLine( rule, multiplyPattern( "3 1", width ), width, c ); 513 break; 514 case 6: 515 appendSimpleLine( rule, multiplyPattern( "5 1", width ), width, c ); 516 break; 517 case 7: 518 appendSimpleLine( rule, multiplyPattern( "10 3", width ), width, c ); 519 break; 520 case 8: 521 appendSimpleLine( rule, multiplyPattern( "20 5", width ), width, c ); 522 break; 523 case 9: 524 appendSimpleLine( rule, multiplyPattern( "5 5", width ), width, c ); 525 break; 526 case 10: 527 appendSimpleLine( rule, multiplyPattern( "1 5", width ), width, c ); 528 break; 529 case 11: 530 appendSimpleLine( rule, multiplyPattern( "3 5", width ), width, c ); 531 break; 532 case 12: 533 appendSimpleLine( rule, multiplyPattern( "7 7", width ), width, c ); 534 break; 535 case 13: 536 appendSimpleLine( rule, multiplyPattern( "10 10", width ), width, c ); 537 break; 538 case 14: 539 appendSimpleLine( rule, multiplyPattern( "9 3 1 3", width ), width, c ); 540 break; 541 case 15: 542 appendSimpleLine( rule, multiplyPattern( "12 2 1 2", width ), width, c ); 543 break; 544 case 16: 545 appendSimpleLine( rule, multiplyPattern( "12 2 2 2", width ), width, c ); 546 break; 547 case 17: 548 appendSimpleLine( rule, multiplyPattern( "20 10 5 10", width ), width, c ); 549 break; 550 case 18: 551 appendSimpleLine( rule, multiplyPattern( "20 4 4 4 4 4", width ), width, c ); 552 break; 553 case 19: 554 appendSimpleLine( rule, multiplyPattern( "20 4 4 4 4 4 4 4", width ), width, c ); 555 break; 556 case 20: 557 appendSimpleLine( rule, multiplyPattern( "9 3 1 3 1 3", width ), width, c ); 558 break; 559 case 21: 560 appendSimpleLine( rule, multiplyPattern( "12 3 1 3 1 3", width ), width, c ); 561 break; 562 case 22: 563 appendSimpleLine( rule, multiplyPattern( "12 3 1 3 1 3 1 3", width ), width, c ); 564 break; 565 case 23: 566 appendSimpleLine( rule, multiplyPattern( "5 1 1 1", width ), width, c ); 567 break; 568 case 24: 569 appendSimpleLine( rule, multiplyPattern( "5 1 1 1 1 1", width ), width, c ); 570 break; 571 case 25: 572 appendSimpleLine( rule, multiplyPattern( "9 1 1 1 3 1 1 1", width ), width, c ); 573 break; 574 case 26: { 575 appendSimpleLine( rule, null, width, c ); 576 appendSimpleLine( rule, multiplyPattern( "1 8", width ), width * 5, c ); 577 break; 578 } 579 case 27: { 580 appendSimpleLine( rule, null, width, c ); 581 appendSimpleLine( rule, multiplyPattern( "1 10", width ), width * 5, c ); 582 break; 583 } 584 case 28: { 585 appendSimpleLine( rule, null, width, c ); 586 appendSimpleLine( rule, multiplyPattern( "1 15", width ), width * 5, c ); 587 break; 588 } 589 case 29: { 590 appendSimpleLine( rule, null, width, c ); 591 appendImageLine( rule, "29.svg", width * 16, c ); 592 break; 593 } 594 case 30: { 595 appendSimpleLine( rule, null, width, c ); 596 appendImageLine( rule, "30.svg", width * 16, c ); 597 break; 598 } 599 case 31: { 600 appendSimpleLine( rule, null, width, c ); 601 appendSimpleLine( rule, multiplyPattern( "1 1 12", width ), width * 5, c ); 602 break; 603 } 604 case 32: { 605 appendSimpleLine( rule, multiplyPattern( "6 3 5 0", width ), width, c ); 606 appendSimpleLine( rule, multiplyPattern( "1 13", width ), width * 5, c ); 607 break; 608 } 609 case 33: { 610 appendSimpleLine( rule, multiplyPattern( "7 3 4 0", width ), width, c ); 611 appendSimpleLine( rule, multiplyPattern( "1 1 1 11", width ), width * 5, c ); 612 break; 613 } 614 case 34: { 615 appendSimpleLine( rule, multiplyPattern( "0 1 10 2", width ), width, c ); 616 appendImageLine( rule, "34.svg", width * 26, c ); 617 break; 618 } 619 case 35: { 620 appendSimpleLine( rule, multiplyPattern( "0 1 10 2", width ), width, c ); 621 appendImageLine( rule, "35.svg", width * 26, c ); 622 break; 623 } 624 case 36: { 625 appendImageLine( rule, "36.svg", width * 11, c ); 626 break; 627 } 628 case 37: { 629 appendSimpleLine( rule, multiplyPattern( "10 3", width ), width, c ); 630 appendSimpleLine( rule, multiplyPattern( "1 8 1 3", width ), width * 5, c ); 631 break; 632 } 633 case 38: { 634 appendSimpleLine( rule, null, width, c ); 635 appendImageLine( rule, "38-39.svg", width * 20, c ); 636 break; 637 } 638 case 39: { 639 appendSimpleLine( rule, multiplyPattern( "0 3 10 7", width ), width, c ); 640 appendImageLine( rule, "38-39.svg", width * 20, c ); 641 break; 642 } 643 case 40: { 644 appendSimpleLine( rule, multiplyPattern( "10 3 3 3", width ), width, c ); 645 appendSimpleLine( rule, multiplyPattern( "0 14 1 4", width ), width * 5, c ); 646 break; 647 } 648 case 41: { 649 appendSimpleLine( rule, multiplyPattern( "0 5 4 1", width ), width, c ); 650 appendSimpleLine( rule, multiplyPattern( "4 1 0 5", width ), width * 3, c ); 651 break; 652 } 653 case 42: { 654 appendSimpleLine( rule, multiplyPattern( "0 5 4 1 4 1", width ), width, c ); 655 appendSimpleLine( rule, multiplyPattern( "5 10", width ), width * 3, c ); 656 break; 657 } 658 case 43: { 659 appendSimpleLine( rule, multiplyPattern( "0 5 4 1 4 1 4 1", width ), width, c ); 660 appendSimpleLine( rule, multiplyPattern( "5 15", width ), width * 3, c ); 661 break; 662 } 663 case 44: { 664 appendSimpleLine( rule, multiplyPattern( "0 5 4 1 4 1 4 1 4 1", width ), width, c ); 665 appendSimpleLine( rule, multiplyPattern( "5 20", width ), width * 3, c ); 666 break; 667 } 668 case 45: { 669 appendSimpleLine( rule, null, width, c ); 670 appendSimpleLine( rule, multiplyPattern( "4 15", width ), width * 3, c ); 671 break; 672 } 673 case 46: { 674 appendSimpleLine( rule, multiplyPattern( "1 3", width ), width * 4, c ); 675 break; 676 } 677 case 47: { 678 appendImageLine( rule, "47.svg", width * 7, c ); 679 break; 680 } 681 case 48: { 682 appendSimpleLine( rule, null, width, c ); 683 appendImageLine( rule, "48.svg", width * 5, c ); 684 break; 685 } 686 case 49: { 687 appendSimpleLine( rule, null, width, c ); 688 appendImageLine( rule, "49.svg", width * 5, c ); 689 break; 690 } 691 case 50: { 692 appendSimpleLine( rule, null, width, c ); 693 appendImageLine( rule, "50.svg", width * 6, c ); 694 break; 695 } 696 case 51: { 697 appendSimpleLine( rule, null, width, c ); 698 appendImageLine( rule, "51.svg", width * 6, c ); 699 break; 700 } 701 case 52: { 702 appendSimpleLine( rule, multiplyPattern( "0 3 10 1", width ), width, c ); 703 appendImageLine( rule, "52.svg", width * 14, c ); 704 break; 705 } 706 case 53: { 707 appendSimpleLine( rule, multiplyPattern( "0 3 10 1", width ), width, c ); 708 appendImageLine( rule, "53.svg", width * 14, c ); 709 break; 710 } 711 case 54: { 712 appendSimpleLine( rule, null, width, c ); 713 appendImageLine( rule, "54.svg", width * 11, c ); 714 break; 715 } 716 case 55: { 717 appendSimpleLine( rule, null, width, c ); 718 appendImageLine( rule, "55.svg", width * 11, c ); 719 break; 720 } 721 case 56: { 722 appendSimpleLine( rule, null, width, c ); 723 appendImageLine( rule, "56.svg", width * 16, c ); 724 break; 725 } 726 case 57: 727 case 58: { 728 appendImageLine( rule, pattern + ".svg", width * 11, c ); 729 break; 730 } 731 case 63: { 732 appendSimpleLine( rule, null, width + 1, c ); 733 appendSimpleLine( rule, null, width, white ); 734 break; 735 } 736 case 65: { 737 appendSimpleLine( rule, null, width + 1, black ); 738 appendSimpleLine( rule, null, width, c ); 739 break; 740 } 741 case 67: { 742 appendSimpleLine( rule, null, width + 1, c ); 743 appendSimpleLine( rule, null, width, black ); 744 break; 745 } 746 case 68: { 747 appendSimpleLine( rule, multiplyPattern( "12 3", width ), width + 1, c ); 748 appendSimpleLine( rule, null, width, white ); 749 break; 750 } 751 case 69: { 752 appendSimpleLine( rule, null, width + 1, c ); 753 appendSimpleLine( rule, null, width, white ); 754 appendSimpleLine( rule, "1 " + 20 * width, width * 5, c ); 755 break; 756 } 757 case 70: { 758 appendSimpleLine( rule, multiplyPattern( "15 15", width ), width, c ); 759 appendSimpleLine( rule, multiplyPattern( "0 15 15 0", width ), width, black ); 760 break; 761 } 762 case 71: { 763 appendSimpleLine( rule, multiplyPattern( "17 23", width ), width, c ); 764 appendSimpleLine( rule, multiplyPattern( "0 20 17 3", width ), width, black ); 765 break; 766 } 767 case 72: { 768 appendSimpleLine( rule, multiplyPattern( "25 5", width ), width + 1, black ); 769 appendSimpleLine( rule, null, width, c ); 770 break; 771 } 772 case 73: { 773 appendSimpleLine( rule, null, width + 1, c ); 774 appendSimpleLine( rule, multiplyPattern( "12 12", width ), width, white ); 775 break; 776 } 777 case 74: { 778 appendSimpleLine( rule, null, width + 1, black ); 779 appendSimpleLine( rule, multiplyPattern( "12 12", width ), width, c ); 780 break; 781 } 782 case 75: { 783 appendSimpleLine( rule, null, width + 1, black ); 784 appendSimpleLine( rule, multiplyPattern( "12 12", width ), width, c ); 785 appendSimpleLine( rule, multiplyPattern( "0 12 12 0", width ), width, white ); 786 break; 787 } 788 case 76: { 789 appendSimpleLine( rule, null, width + 1, black ); 790 appendSimpleLine( rule, multiplyPattern( "25 25", width ), width, c ); 791 appendSimpleLine( rule, multiplyPattern( "0 25 25 0", width ), width, white ); 792 break; 793 } 794 case 77: { 795 appendSimpleLine( rule, null, width + 1, c ); 796 appendSimpleLine( rule, multiplyPattern( "12 12", width ), width, black ); 797 appendSimpleLine( rule, multiplyPattern( "0 12 12 0", width ), width, white ); 798 break; 799 } 800 case 81: { 801 appendSimpleLine( rule, null, width, black ); 802 appendImageLine( rule, "81-85.svg", width * 10, c ); 803 break; 804 } 805 case 82: { 806 appendImageLine( rule, "81-85.svg", width * 10, c ); 807 break; 808 } 809 case 83: { 810 appendSimpleLine( rule, multiplyPattern( "0 2 1 7", width ), width, black ); 811 appendImageLine( rule, "81-85.svg", width * 10, c ); 812 break; 813 } 814 case 84: { 815 appendSimpleLine( rule, null, width * 5, black ); 816 appendSimpleLine( rule, null, width * 5 - 1, white ); 817 appendImageLine( rule, "81-85.svg", width * 10, c ); 818 break; 819 } 820 case 85: { 821 appendSimpleLine( rule, null, width * 6 + 1, black ); 822 appendSimpleLine( rule, null, width * 6, white ); 823 appendImageLine( rule, "81-85.svg", width * 10, c ); 824 break; 825 } 826 case 89: { 827 appendSimpleLine( rule, null, width, black ); 828 appendSimpleLine( rule, multiplyPattern( "5 5", width ), width * 5, c ); 829 break; 830 } 831 case 90: { 832 appendSimpleLine( rule, multiplyPattern( "5 5", width ), width * 5, c ); 833 break; 834 } 835 case 91: { 836 appendSimpleLine( rule, multiplyPattern( "0 7 1 2", width ), width, black ); 837 appendSimpleLine( rule, multiplyPattern( "5 5", width ), width * 5, c ); 838 break; 839 } 840 case 92: { 841 appendSimpleLine( rule, null, width * 5, black ); 842 appendSimpleLine( rule, null, width * 5 - 1, white ); 843 appendSimpleLine( rule, multiplyPattern( "5 5", width ), width * 5, c ); 844 break; 845 } 846 case 93: { 847 appendSimpleLine( rule, null, width * 6 + 1, black ); 848 appendSimpleLine( rule, null, width * 6, white ); 849 appendSimpleLine( rule, multiplyPattern( "5 5", width ), width * 5, c ); 850 break; 851 } 852 case 97: { 853 appendSimpleLine( rule, null, width, black ); 854 appendImageLine( rule, "97-101.svg", width * 10, c ); 855 break; 856 } 857 case 98: { 858 appendImageLine( rule, "97-101.svg", width * 10, c ); 859 break; 860 } 861 case 99: { 862 appendSimpleLine( rule, multiplyPattern( "0 2 1 7", width ), width, black ); 863 appendImageLine( rule, "97-101.svg", width * 10, c ); 864 break; 865 } 866 case 100: { 867 appendSimpleLine( rule, null, width * 5, black ); 868 appendSimpleLine( rule, null, width * 5 - 1, white ); 869 appendImageLine( rule, "97-101.svg", width * 10, c ); 870 break; 871 } 872 case 101: { 873 appendSimpleLine( rule, null, width * 6 + 1, black ); 874 appendSimpleLine( rule, null, width * 6, white ); 875 appendImageLine( rule, "97-101.svg", width * 10, c ); 876 break; 877 } 878 case 105: { 879 appendSimpleLine( rule, null, width, black ); 880 appendImageLine( rule, "105-109.svg", width * 10, c ); 881 break; 882 } 883 case 106: { 884 appendImageLine( rule, "105-109.svg", width * 10, c ); 885 break; 886 } 887 case 107: { 888 appendSimpleLine( rule, multiplyPattern( "0 2 1 7", width ), width, black ); 889 appendImageLine( rule, "105-109.svg", width * 10, c ); 890 break; 891 } 892 case 108: { 893 appendSimpleLine( rule, null, width * 5, black ); 894 appendSimpleLine( rule, null, width * 5 - 1, white ); 895 appendImageLine( rule, "105-109.svg", width * 10, c ); 896 break; 897 } 898 case 109: { 899 appendSimpleLine( rule, null, width * 6 + 1, black ); 900 appendSimpleLine( rule, null, width * 6, white ); 901 appendImageLine( rule, "105-109.svg", width * 10, c ); 902 break; 903 } 904 case 114: { 905 appendSimpleLine( rule, null, width * 3, c ); 906 appendImageLine( rule, "114.svg", width * 20, c ); 907 break; 908 } 909 case 115: { 910 appendSimpleLine( rule, null, width * 3, c ); 911 appendImageLine( rule, "115.svg", width * 20, c ); 912 break; 913 } 914 case 116: { 915 appendSimpleLine( rule, null, width * 3, c ); 916 appendImageLine( rule, "116.svg", width * 20, c ); 917 break; 918 } 919 case 117: { 920 appendSimpleLine( rule, null, width * 2, c ); 921 appendImageLine( rule, "117.svg", width * 10, c ); 922 break; 923 } 924 case 118: { 925 appendSimpleLine( rule, null, width * 5 + 1, black ); 926 appendSimpleLine( rule, null, width * 5, white ); 927 appendSimpleLine( rule, multiplyPattern( "1 5", width ), width * 10, c ); 928 break; 929 } 930 default: 931 LOG.logWarning( "Ignoring fancy pen style, as it cannot be mapped to SLD." ); 932 break; 933 } 934 935 } 936 937 private static final DecimalFormat formatter = new DecimalFormat( "000" ); 938 939 /** 940 * @param map 941 * @param doc 942 * @param name 943 * @throws SAXException 944 * @throws IOException 945 * @throws MalformedURLException 946 * @throws XMLParsingException 947 */ 948 public static void insertBrushStyle( Map<String, String> map, XMLFragment doc, String name ) 949 throws MalformedURLException, IOException, SAXException, XMLParsingException { 950 int pattern = parseInt( map.get( "pattern" ) ); 951 Color fore = decode( map.get( "forecolor" ) ); 952 Color back = null; 953 if ( map.get( "backcolor" ) != null ) { 954 back = decode( map.get( "backcolor" ) ); 955 } 956 957 if ( pattern == 1 ) { 958 return; 959 } 960 961 if ( pattern == 2 ) { 962 Element e = getRequiredElement( doc.getRootElement(), ".//" + SLD_PREFIX + ":FeatureTypeStyle", nsContext ); 963 e = appendElement( e, SLDNS, SLD_PREFIX + ":Rule" ); 964 appendIDFilter( map.get( "styleid" ), e ); 965 appendElement( e, SLDNS, SLD_PREFIX + ":Name", "default:" + name ); 966 e = appendElement( e, SLDNS, SLD_PREFIX + ":PolygonSymbolizer" ); 967 e = appendElement( e, SLDNS, SLD_PREFIX + ":Fill" ); 968 appendElement( e, SLDNS, SLD_PREFIX + ":CssParameter", toHexColor( fore ) ).setAttribute( "name", "fill" ); 969 return; 970 } 971 972 ZipFile zip = new ZipFile( MIFStyle2SLD.BRUSHES ); 973 ZipEntry entry = zip.getEntry( formatter.format( pattern ) + ".svg" ); 974 975 XMLFragment svg = null; 976 try { 977 svg = new XMLFragment( new InputStreamReader( zip.getInputStream( entry ), "UTF-8" ), 978 "http://www.systemid.org" ); 979 zip.close(); 980 } catch ( NullPointerException npe ) { 981 LOG.logWarning( "Could not find brush symbol for brush number " + pattern ); 982 return; 983 } 984 985 updateFillPatternSVG( svg, toHexColor( fore ), back == null ? null : toHexColor( back ) ); 986 987 BufferedImage img = renderSVGImage( svg, 0 ); 988 File svgFile = createTempFile( "mmsvg", ".png" ); 989 write( img, "png", svgFile ); 990 svgFile.deleteOnExit(); 991 992 Element e = getRequiredElement( doc.getRootElement(), ".//" + SLD_PREFIX + ":FeatureTypeStyle", nsContext ); 993 e = appendElement( e, SLDNS, SLD_PREFIX + ":Rule" ); 994 appendIDFilter( map.get( "styleid" ), e ); 995 e = appendElement( e, SLDNS, SLD_PREFIX + ":PolygonSymbolizer" ); 996 e = appendElement( e, SLDNS, SLD_PREFIX + ":Fill" ); 997 e = appendElement( e, SLDNS, SLD_PREFIX + ":GraphicFill" ); 998 e = appendElement( e, SLDNS, SLD_PREFIX + ":Graphic" ); 999 e = appendElement( e, SLDNS, SLD_PREFIX + ":ExternalGraphic" ); 1000 Element o = appendElement( e, SLDNS, SLD_PREFIX + ":OnlineResource" ); 1001 o.setAttributeNS( XLNNS.toASCIIString(), XLINK_PREFIX + ":href", svgFile.toURI().toURL().toExternalForm() ); 1002 o.setAttributeNS( XLNNS.toASCIIString(), XLINK_PREFIX + ":type", "simple" ); 1003 appendElement( e, SLDNS, SLD_PREFIX + ":Format", "image/png" ); 1004 } 1005 1006 /** 1007 * @param map 1008 * @param doc 1009 * @throws XMLParsingException 1010 */ 1011 public static void insertTextStyle( Map<String, String> map, XMLFragment doc ) 1012 throws XMLParsingException { 1013 String fontName = map.get( "fontname" ); 1014 int styles = parseInt( map.get( "style" ) ); 1015 String style = ( styles & 2 ) == 2 ? "italic" : "normal"; 1016 String weight = ( styles & 1 ) == 1 ? "bold" : "normal"; 1017 boolean halo = ( styles & 256 ) == 256; 1018 Color fore = decode( map.get( "forecolor" ) ); 1019 Color back = null; 1020 if ( map.get( "backcolor" ) != null ) { 1021 back = decode( map.get( "backcolor" ) ); 1022 } 1023 1024 Element e = getRequiredElement( doc.getRootElement(), ".//" + SLD_PREFIX + ":FeatureTypeStyle", nsContext ); 1025 e = appendElement( e, SLDNS, SLD_PREFIX + ":Rule" ); 1026 appendIDFilter( map.get( "styleid" ), e ); 1027 Element symbolizer = appendElement( e, SLDNS, SLD_PREFIX + ":TextSymbolizer" ); 1028 e = appendElement( symbolizer, SLDNS, SLD_PREFIX + ":Label" ); 1029 appendElement( e, OGCNS, OGC_PREFIX + ":PropertyName", "app:text_geometry" ); 1030 e = appendElement( symbolizer, SLDNS, SLD_PREFIX + ":Font" ); 1031 appendElement( e, SLDNS, SLD_PREFIX + ":CssParameter", fontName ).setAttribute( "name", "font-family" ); 1032 appendElement( e, SLDNS, SLD_PREFIX + ":CssParameter", style ).setAttribute( "name", "font-style" ); 1033 appendElement( e, SLDNS, SLD_PREFIX + ":CssParameter", weight ).setAttribute( "name", "font-weight" ); 1034 appendElement( e, SLDNS, SLD_PREFIX + ":CssParameter", toHexColor( fore ) ).setAttribute( "name", "font-color" ); 1035 e = appendElement( e, SLDNS, SLD_PREFIX + ":CssParameter", "92" ); // TODO max font size? 1036 e.setAttribute( "name", "font-size" ); 1037 // Element div = appendElement( e, OGCNS, OGC_PREFIX + ":Div" ); 1038 // appendElement( div, OGCNS, OGC_PREFIX + ":Literal", map.get( "ratio" ) ); 1039 // appendElement( div, OGCNS, OGC_PREFIX + ":PropertyName", "app:$SCALE" ); 1040 if ( halo ) { 1041 e = appendElement( symbolizer, SLDNS, SLD_PREFIX + ":Halo" ); 1042 appendElement( e, SLDNS, SLD_PREFIX + ":Radius", "2" ); 1043 e = appendElement( e, SLDNS, SLD_PREFIX + ":Fill" ); 1044 e = appendElement( e, SLDNS, SLD_PREFIX + ":CssParameter", back == null ? "#ffffff" : toHexColor( back ) ); 1045 e.setAttribute( "name", "fill" ); 1046 } 1047 e = appendElement( symbolizer, SLDNS, SLD_PREFIX + ":Fill" ); 1048 appendElement( e, SLDNS, SLD_PREFIX + ":CssParameter", toHexColor( fore ) ).setAttribute( "name", "fill" ); 1049 1050 e = appendElement( symbolizer, SLDNS, SLD_PREFIX + ":BoundingBox" ); 1051 Element m = appendElement( e, SLDNS, SLD_PREFIX + ":Minx" ); 1052 appendElement( m, OGCNS, OGC_PREFIX + ":PropertyName", "app:text_minx" ); 1053 m = appendElement( e, SLDNS, SLD_PREFIX + ":Miny" ); 1054 appendElement( m, OGCNS, OGC_PREFIX + ":PropertyName", "app:text_miny" ); 1055 m = appendElement( e, SLDNS, SLD_PREFIX + ":Maxx" ); 1056 appendElement( m, OGCNS, OGC_PREFIX + ":PropertyName", "app:text_maxx" ); 1057 m = appendElement( e, SLDNS, SLD_PREFIX + ":Maxy" ); 1058 appendElement( m, OGCNS, OGC_PREFIX + ":PropertyName", "app:text_maxy" ); 1059 } 1060 1061 /** 1062 * @param styles 1063 * @param name 1064 * the layer name 1065 * @return a SLD document with temporary file references for point symbols 1066 */ 1067 public XMLFragment getStyle( Map<String, HashSet<HashMap<String, String>>> styles, String name ) { 1068 XMLFragment doc = getSLDTemplate( name ); 1069 1070 HashSet<HashMap<String, String>> symbols = styles.get( "symbol" ); 1071 if ( LOG.isDebug() ) { 1072 LOG.logDebug( "Found " + ( symbols == null ? "no" : symbols.size() ) + " symbol styles." ); 1073 } 1074 if ( symbols != null ) { 1075 for ( Map<String, String> map : symbols ) { 1076 try { 1077 insertSymbolStyle( map, doc ); 1078 } catch ( DOMException e ) { 1079 LOG.logError( "Unknown error", e ); 1080 } catch ( IOException e ) { 1081 LOG.logError( "Unknown error", e ); 1082 } catch ( XMLParsingException e ) { 1083 LOG.logError( "Unknown error", e ); 1084 } catch ( SAXException e ) { 1085 LOG.logError( "Unknown error", e ); 1086 } 1087 } 1088 } 1089 1090 HashSet<HashMap<String, String>> pens = styles.get( "pen" ); 1091 if ( LOG.isDebug() ) { 1092 LOG.logDebug( "Found " + ( pens == null ? "no" : pens.size() ) + " pen styles." ); 1093 } 1094 if ( pens != null ) { 1095 for ( Map<String, String> map : pens ) { 1096 try { 1097 insertPenStyle( map, doc ); 1098 } catch ( MalformedURLException e ) { 1099 LOG.logError( "Unknown error", e ); 1100 } catch ( IOException e ) { 1101 LOG.logError( "Unknown error", e ); 1102 } catch ( SAXException e ) { 1103 LOG.logError( "Unknown error", e ); 1104 } catch ( XMLParsingException e ) { 1105 LOG.logError( "Unknown error", e ); 1106 } 1107 } 1108 } 1109 1110 HashSet<HashMap<String, String>> brushes = styles.get( "brush" ); 1111 if ( LOG.isDebug() ) { 1112 LOG.logDebug( "Found " + ( brushes == null ? "no" : brushes.size() ) + " brushes." ); 1113 } 1114 if ( brushes != null ) { 1115 for ( Map<String, String> map : brushes ) { 1116 try { 1117 insertBrushStyle( map, doc, name ); 1118 } catch ( MalformedURLException e ) { 1119 LOG.logError( "Unknown error", e ); 1120 } catch ( IOException e ) { 1121 LOG.logError( "Unknown error", e ); 1122 } catch ( SAXException e ) { 1123 LOG.logError( "Unknown error", e ); 1124 } catch ( XMLParsingException e ) { 1125 LOG.logError( "Unknown error", e ); 1126 } 1127 } 1128 } 1129 1130 HashSet<HashMap<String, String>> texts = styles.get( "text" ); 1131 if ( LOG.isDebug() ) { 1132 LOG.logDebug( "Found " + ( texts == null ? "no" : texts.size() ) + " texts." ); 1133 } 1134 if ( texts != null ) { 1135 for ( Map<String, String> map : texts ) { 1136 try { 1137 insertTextStyle( map, doc ); 1138 } catch ( XMLParsingException e ) { 1139 LOG.logError( "Unknown error", e ); 1140 } 1141 } 1142 } 1143 1144 if ( LOG.isDebug() ) { 1145 LOG.logDebug( "Generated SLD document", doc.getAsPrettyString() ); 1146 } 1147 1148 return doc; 1149 } 1150 1151 /** 1152 * @param doc 1153 * @param size 1154 * @return an SVG image with black colors overwritten with the given colors 1155 */ 1156 public static BufferedImage renderSVGImage( XMLFragment doc, int size ) { 1157 ByteArrayOutputStream bos = new ByteArrayOutputStream( size * size * 4 ); 1158 TranscoderOutput output = new TranscoderOutput( bos ); 1159 1160 PNGTranscoder trc = new PNGTranscoder(); 1161 try { 1162 Element root = doc.getRootElement(); 1163 TranscoderInput input = new TranscoderInput( root.getOwnerDocument() ); 1164 if ( size > 0 ) { 1165 trc.addTranscodingHint( KEY_HEIGHT, new Float( size ) ); 1166 trc.addTranscodingHint( KEY_WIDTH, new Float( size ) ); 1167 } 1168 trc.transcode( input, output ); 1169 bos.close(); 1170 ByteArrayInputStream is = new ByteArrayInputStream( bos.toByteArray() ); 1171 MemoryCacheSeekableStream mcss = new MemoryCacheSeekableStream( is ); 1172 RenderedOp rop = create( "stream", mcss ); 1173 return rop.getAsBufferedImage(); 1174 } catch ( TranscoderException e ) { 1175 LOG.logError( "Unknown error", e ); 1176 } catch ( MalformedURLException e ) { 1177 LOG.logError( "Unknown error", e ); 1178 } catch ( IOException e ) { 1179 LOG.logError( "Unknown error", e ); 1180 } 1181 1182 return null; 1183 } 1184 1185 /** 1186 * @param col 1187 * @return a #rrggbb string 1188 */ 1189 public static String toHexColor( Color col ) { 1190 if ( col == null ) { 1191 col = black; 1192 } 1193 String scol = toHexString( col.getRGB() & 0xffffff ); 1194 while ( scol.length() < 6 ) { 1195 scol = "0" + scol; 1196 } 1197 1198 return "#" + scol; 1199 } 1200 1201 /** 1202 * @param doc 1203 * @param stroke 1204 * @param fill 1205 * @throws XMLParsingException 1206 */ 1207 public static void updateSVGColors( XMLFragment doc, String fill, String stroke ) 1208 throws XMLParsingException { 1209 List<Node> ns = getNodes( doc.getRootElement(), ".//@style", nsContext ); 1210 for ( Node n : ns ) { 1211 String v = n.getTextContent(); 1212 v = v.replace( "fill:#000000", "fill:" + fill ); 1213 v = v.replace( "fill:black", "fill:" + fill ); 1214 v = v.replace( "stroke:#000000", "stroke:" + stroke ); 1215 v = v.replace( "stroke:black", "stroke:" + stroke ); 1216 n.setTextContent( v ); 1217 } 1218 } 1219 1220 /** 1221 * @param doc 1222 * @param foreground 1223 * @param background 1224 * @throws XMLParsingException 1225 */ 1226 public static void updateFillPatternSVG( XMLFragment doc, String foreground, String background ) 1227 throws XMLParsingException { 1228 List<Node> ns = getNodes( doc.getRootElement(), ".//@style", nsContext ); 1229 for ( Node n : ns ) { 1230 String v = n.getTextContent(); 1231 v = v.replace( "fill:#000000", "fill:" + foreground ); 1232 v = v.replace( "fill:black", "fill:" + foreground ); 1233 v = v.replace( "stroke:#000000", "stroke:" + foreground ); 1234 v = v.replace( "stroke:black", "stroke:" + foreground ); 1235 if ( background != null ) { 1236 v = v.replace( "fill:none", "fill:" + background ); 1237 } 1238 n.setTextContent( v ); 1239 } 1240 } 1241 1242 /** 1243 * @param font 1244 * @param theChar 1245 * @param size 1246 * @param color 1247 * @return an image the char has been written onto 1248 */ 1249 public static BufferedImage symbolFromFont( Font font, char theChar, int size, Color color ) { 1250 if ( font.canDisplay( theChar ) ) { 1251 BufferedImage img = new BufferedImage( size, size, TYPE_INT_ARGB ); 1252 Graphics2D g = img.createGraphics(); 1253 g.setFont( font.deriveFont( (float) size ) ); 1254 g.setColor( color ); 1255 g.drawString( theChar + "", 0, size ); 1256 g.dispose(); 1257 return img; 1258 } 1259 1260 return null; 1261 } 1262 1263 /** 1264 * @param font 1265 * @param theChar1 1266 * @param theChar2 1267 * @param size 1268 * @param color1 1269 * @param color2 1270 * @return an image with the second char written over the first one 1271 */ 1272 public static BufferedImage symbolFromTwoChars( Font font, char theChar1, char theChar2, int size, Color color1, 1273 Color color2 ) { 1274 if ( font.canDisplay( theChar1 ) && font.canDisplay( theChar2 ) ) { 1275 BufferedImage img = new BufferedImage( size, size, TYPE_INT_ARGB ); 1276 Graphics2D g = img.createGraphics(); 1277 g.setFont( font.deriveFont( (float) size ) ); 1278 g.setColor( color1 ); 1279 g.drawString( theChar1 + "", 0, size ); 1280 g.setColor( color2 ); 1281 g.drawString( theChar2 + "", 0, size ); 1282 g.dispose(); 1283 return img; 1284 } 1285 1286 return null; 1287 } 1288 1289 }