001 //$HeadURL: svn+ssh://developername@svn.wald.intevation.org/deegree/base/trunk/src/org/deegree/graphics/legend/LegendElement.java $ 002 /*---------------- FILE HEADER ------------------------------------------ 003 004 This file is part of deegree. 005 Copyright (C) 2001-2008 by: 006 EXSE, Department of Geography, University of Bonn 007 http://www.giub.uni-bonn.de/deegree/ 008 lat/lon GmbH 009 http://www.lat-lon.de 010 011 This library is free software; you can redistribute it and/or 012 modify it under the terms of the GNU Lesser General Public 013 License as published by the Free Software Foundation; either 014 version 2.1 of the License, or (at your option) any later version. 015 016 This library is distributed in the hope that it will be useful, 017 but WITHOUT ANY WARRANTY; without even the implied warranty of 018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 019 Lesser General Public License for more details. 020 021 You should have received a copy of the GNU Lesser General Public 022 License along with this library; if not, write to the Free Software 023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 024 025 Contact: 026 027 Andreas Poth 028 lat/lon GmbH 029 Aennchenstr. 19 030 53115 Bonn 031 Germany 032 E-Mail: poth@lat-lon.de 033 034 Prof. Dr. Klaus Greve 035 Department of Geography 036 University of Bonn 037 Meckenheimer Allee 166 038 53115 Bonn 039 Germany 040 E-Mail: greve@giub.uni-bonn.de 041 042 043 ---------------------------------------------------------------------------*/ 044 package org.deegree.graphics.legend; 045 046 import java.awt.BasicStroke; 047 import java.awt.Color; 048 import java.awt.FontMetrics; 049 import java.awt.Graphics; 050 import java.awt.Graphics2D; 051 import java.awt.image.BufferedImage; 052 import java.util.ArrayList; 053 054 import org.deegree.framework.log.ILogger; 055 import org.deegree.framework.log.LoggerFactory; 056 import org.deegree.graphics.displayelements.DisplayElementFactory; 057 import org.deegree.graphics.displayelements.IncompatibleGeometryTypeException; 058 import org.deegree.graphics.displayelements.PolygonDisplayElement; 059 import org.deegree.graphics.sld.LineSymbolizer; 060 import org.deegree.graphics.sld.PointSymbolizer; 061 import org.deegree.graphics.sld.PolygonSymbolizer; 062 import org.deegree.graphics.sld.RasterSymbolizer; 063 import org.deegree.graphics.sld.Rule; 064 import org.deegree.graphics.sld.Symbolizer; 065 import org.deegree.graphics.sld.TextSymbolizer; 066 import org.deegree.graphics.transformation.WorldToScreenTransform; 067 import org.deegree.model.filterencoding.FilterEvaluationException; 068 import org.deegree.model.spatialschema.Envelope; 069 import org.deegree.model.spatialschema.GeometryFactory; 070 import org.deegree.model.spatialschema.Position; 071 import org.deegree.model.spatialschema.Surface; 072 import org.deegree.ogcwebservices.wms.GraphicContextFactory; 073 074 /** 075 * The implements the basic legend element. a legend element may has a label that can be set to 076 * eight positions relative to the legend graphic. A <tt>LegendElement</tt> can be activated or 077 * deactivated. It depends on the using application what effect this behavior will have. 078 * <p> 079 * <tt>LegendElement</tt>s can be collected in a <tt>LegendElementCollection</tt> which also is 080 * a <tt>LegendElement</tt> to group elements or to create more complex elements. 081 * <p> 082 * Each <tt>LegendElement</tt> is able to paint itself as <tt>BufferedImage</tt> 083 * 084 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 085 * @version $Revision: 7363 $ $Date: 2007-05-29 20:47:55 +0200 (Di, 29 Mai 2007) $ 086 */ 087 public class LegendElement { 088 089 private static final ILogger LOG = LoggerFactory.getLogger( LegendElement.class ); 090 091 protected ArrayList<Rule> ruleslist = null; 092 093 protected String label = ""; 094 095 protected double orientation = 0; 096 097 protected int labelPosition = -1; 098 099 protected boolean active = false; 100 101 protected int width = 0; 102 103 protected int height = 0; 104 105 protected int bufferBetweenLegendAndLabel = 10; 106 107 protected BufferedImage bi; 108 109 /** 110 * empty constructor 111 * 112 */ 113 protected LegendElement() { 114 this.ruleslist = new ArrayList<Rule>(); 115 } 116 117 /** 118 * 119 * 120 */ 121 LegendElement( BufferedImage legendImage ) { 122 this(); 123 bi = legendImage; 124 } 125 126 /** 127 * constructor 128 * 129 * @param rules 130 * the different rules from the SLD 131 * @param label 132 * the label beneath the legend symbol 133 * @param orientation 134 * the rotation of the text in the legend 135 * @param labelPosition 136 * the position of the text according to the symbol 137 * @param active 138 * whether the legendsymbol is active or not 139 * @param width 140 * the requested width of the legend symbol 141 * @param height 142 * the requested height of the legend symbol 143 */ 144 LegendElement( Rule[] rules, String label, double orientation, int labelPosition, boolean active, int width, 145 int height ) { 146 this(); 147 setRules( rules ); 148 setLabel( label ); 149 setLabelOrientation( orientation ); 150 setLabelPlacement( labelPosition ); 151 setActive( active ); 152 setWidth( width ); 153 setHeight( height ); 154 } 155 156 /** 157 * gets the Rules as an array 158 * 159 * @return array of sld rules 160 */ 161 public Rule[] getRules() { 162 if ( ruleslist != null && ruleslist.size() > 0 ) { 163 return ruleslist.toArray( new Rule[ruleslist.size()] ); 164 } 165 return null; 166 } 167 168 /** 169 * adds a rule to the ArrayList ruleslist 170 * 171 * @param rule 172 * a sld rule 173 */ 174 public void addRule( Rule rule ) { 175 this.ruleslist.add( rule ); 176 } 177 178 /** 179 * sets the rules 180 * 181 * @param rules 182 * an array of sld rules 183 */ 184 public void setRules( Rule[] rules ) { 185 this.ruleslist.clear(); 186 187 if ( rules != null ) { 188 for ( int i = 0; i < rules.length; i++ ) { 189 this.ruleslist.add( rules[i] ); 190 } 191 } 192 } 193 194 /** 195 * sets the label of the <tt>LegendElement</tt> 196 * 197 * @param label 198 * label of the <tt>LegendElement</tt> 199 * 200 */ 201 public void setLabel( String label ) { 202 this.label = label; 203 } 204 205 /** 206 * returns the label set to <tt>LegendElement</tt>. If no label is set, the method returns 207 * <tt>null</tt> 208 * 209 * @return label of the <tt>LegendElement</tt> or <tt>null</tt> 210 * 211 */ 212 public String getLabel() { 213 return this.label; 214 } 215 216 /** 217 * sets the orientation of the label of the <tt>LegendElement</tt>. A label can have an 218 * orientation from -90� to 90� expressed in radians, where 0� is horizontal 219 * 220 * @param orientation 221 */ 222 public void setLabelOrientation( double orientation ) { 223 this.orientation = orientation; 224 } 225 226 /** 227 * returns the current orientation of the label of the <tt>LegendElement</tt> in radians. If 228 * the element hasn't a label <tt>Double.NEGATIVE_INFINITY</tt> will be returned. 229 * 230 * @return orientation of the label of the <tt>LegendElement</tt> in radians 231 */ 232 public double getLabelOrientation() { 233 return this.orientation; 234 } 235 236 /** 237 * sets the placement of the label relative to the legend symbol. Possible values are: 238 * <ul> 239 * <li>LP_TOPCENTER 240 * <li>LP_TOPLEFT 241 * <li>LP_TOPRIGHT 242 * <li>LP_RIGHT 243 * <li>LP_LEFT 244 * <li>LP_BOTTOMCENTER 245 * <li>LP_BOTTOMRIGHT 246 * <li>LP_BOTTOMLEFT 247 * </ul> 248 * 249 * <pre> 250 * +---+---+---+ 251 * | 1 | 0 | 2 | 252 * +---+---+---+ 253 * | 4 |LEG| 3 | 254 * +---+---+---+ 255 * | 7 | 5 | 6 | 256 * +---+---+---+ 257 * </pre> 258 * 259 * An implementation of the interface may not supoort all positions. 260 * 261 * @param labelPosition 262 */ 263 public void setLabelPlacement( int labelPosition ) { 264 this.labelPosition = labelPosition; 265 } 266 267 /** 268 * returns the placement of the label relative to the legend symbol. If the element hasn't a 269 * label <tt>LegendElement.LP_NOLABEL</tt> will be returned. Otherwise possible values are: 270 * <ul> 271 * <li>LP_TOPCENTER 272 * <li>LP_TOPLEFT 273 * <li>LP_TOPRIGHT 274 * <li>LP_RIGHT 275 * <li>LP_LEFT 276 * <li>LP_BOTTOMCENTER 277 * <li>LP_BOTTOMRIGHT 278 * <li>LP_BOTTOMLEFT 279 * </ul> 280 * 281 * @return coded placement of the label relative to the legend symbol 282 */ 283 public int getLabelPlacement() { 284 return this.labelPosition; 285 } 286 287 /** 288 * activates or deactivates the label 289 * 290 * @param active 291 */ 292 public void setActive( boolean active ) { 293 this.active = active; 294 } 295 296 /** 297 * @return the activtion-status of the label 298 */ 299 public boolean isActive() { 300 return this.active; 301 } 302 303 /** 304 * sets the width of the LegendSymbol (in pixels) 305 * 306 * @param width 307 */ 308 public void setWidth( int width ) { 309 this.width = width; 310 } 311 312 /** 313 * @return the width of the LegendSymbol (in pixels) 314 */ 315 public int getWidth() { 316 return this.width; 317 } 318 319 /** 320 * sets the height of the LegendSymbol (in pixels) 321 * 322 * @param height 323 */ 324 public void setHeight( int height ) { 325 this.height = height; 326 } 327 328 /** 329 * @return the height of the LegendSymbol (in pixels) 330 */ 331 public int getHeight() { 332 return this.height; 333 } 334 335 /** 336 * returns the buffer place between the legend symbol and the legend label in pixels 337 * 338 * @return the buffer as integer in pixels 339 */ 340 public int getBufferBetweenLegendAndLabel() { 341 return this.bufferBetweenLegendAndLabel; 342 } 343 344 /** 345 * @see org.deegree.graphics.legend.LegendElement#getBufferBetweenLegendAndLabel() 346 * @param i 347 * the buffer as integer in pixels 348 */ 349 public void setBufferBetweenLegendAndLabel( int i ) { 350 this.bufferBetweenLegendAndLabel = i; 351 } 352 353 /** 354 * draws a legendsymbol, if the SLD defines a point 355 * 356 * @param g 357 * the graphics context 358 * @param c 359 * the PointSymbolizer representing the drawable point 360 * @param width 361 * the requested width of the symbol 362 * @param height 363 * the requested height of the symbol 364 * @throws LegendException 365 * is thrown, if the parsing of the sld failes. 366 */ 367 protected void drawPointLegend( Graphics g, PointSymbolizer c, int width, int height ) 368 throws LegendException { 369 org.deegree.graphics.sld.Graphic deegreegraphic = c.getGraphic(); 370 try { 371 BufferedImage buffi = deegreegraphic.getAsImage( null ); 372 int w = buffi.getWidth(); 373 int h = buffi.getHeight(); 374 g.drawImage( buffi, width / 2 - w / 2, height / 2 - h / 2, null ); 375 } catch ( FilterEvaluationException feex ) { 376 throw new LegendException( "FilterEvaluationException occured during " + "the creation of the legend:\n" 377 + "The legend for the PointSymbol can't be processed.\n" + feex.getMessage() ); 378 } 379 380 } 381 382 /** 383 * draws a legendsymbol, if the SLD defines a line 384 * 385 * @param g 386 * the graphics context 387 * @param ls 388 * the LineSymbolizer representing the drawable line 389 * @param width 390 * the requested width of the symbol 391 * @param height 392 * the requested height of the symbol 393 * @throws LegendException 394 * is thrown, if the parsing of the sld failes. 395 */ 396 protected void drawLineStringLegend( Graphics2D g, LineSymbolizer ls, int width, int height ) 397 throws LegendException { 398 399 org.deegree.graphics.sld.Stroke sldstroke = ls.getStroke(); 400 try { 401 // color, opacity 402 setColor( g, sldstroke.getStroke( null ), sldstroke.getOpacity( null ) ); 403 g.setStroke( getBasicStroke( sldstroke ) ); 404 } catch ( FilterEvaluationException feex ) { 405 throw new LegendException( "FilterEvaluationException occured during the creation " 406 + "of the legend:\n The legend for the LineSymbol can't be " + "processed.\n" 407 + feex.getMessage() ); 408 } 409 410 // p1 = [0 | height] 411 // p2 = [width / 3 | height / 3] 412 // p3 = [width - width / 3 | height - height / 3] 413 // p4 = [width | 0] 414 int[] xPoints = { 0, width / 3, width - width / 3, width }; 415 int[] yPoints = { height, height / 3, height - height / 3, 0 }; 416 int nPoints = 4; 417 418 g.drawPolyline( xPoints, yPoints, nPoints ); 419 420 } 421 422 /** 423 * draws a legendsymbol, if the SLD defines a polygon 424 * 425 * @param g 426 * the graphics context 427 * @param ps 428 * the PolygonSymbolizer representing the drawable polygon 429 * @param width 430 * the requested width of the symbol 431 * @param height 432 * the requested height of the symbol 433 * @throws LegendException 434 * if the parsing of the sld failes. 435 */ 436 protected void drawPolygonLegend( Graphics2D g, PolygonSymbolizer ps, int width, int height ) 437 throws LegendException { 438 439 Position p1 = GeometryFactory.createPosition( 0, 0 ); 440 Position p2 = GeometryFactory.createPosition( 0, height - 1 ); 441 Position p3 = GeometryFactory.createPosition( width - 1, height - 1 ); 442 Position p4 = GeometryFactory.createPosition( width - 1, 0 ); 443 444 Position[] pos = { p1, p2, p3, p4, p1 }; 445 Surface surface = null; 446 try { 447 surface = GeometryFactory.createSurface( pos, null, null, null ); 448 } catch ( Exception ex ) { 449 throw new LegendException( "Exception occured during the creation of the legend:\n" 450 + "The legendsymbol for the Polygon can't be processed.\n" 451 + "Error in creating the Surface from the Positions.\n" + ex.getMessage() ); 452 } 453 454 PolygonDisplayElement pde = null; 455 try { 456 // Feature, Geometry, PolygonSymbolizer 457 pde = DisplayElementFactory.buildPolygonDisplayElement( null, surface, ps ); 458 } catch ( IncompatibleGeometryTypeException igtex ) { 459 throw new LegendException( "IncompatibleGeometryTypeException occured during " 460 + "the creation of the legend:\n The legendsymbol for " 461 + "the Polygon can't be processed.\nError in creating " 462 + "the PolygonDisplayElement.\n" + igtex.getMessage() ); 463 } catch ( Exception e ) { 464 throw new LegendException( "Could not create symbolizer:\n" + e.getMessage() ); 465 } 466 467 Envelope envelope = GeometryFactory.createEnvelope( p1, p3, null ); 468 469 WorldToScreenTransform wtst = new WorldToScreenTransform( envelope, envelope ); 470 pde.paint( g, wtst, -1 ); 471 472 } 473 474 /** 475 * sets the color including an opacity 476 * 477 * @param g2 478 * the graphics contect as Graphics2D 479 * @param color 480 * the requested color of the legend symbol 481 * @param opacity 482 * the requested opacity of the legend symbol 483 * @return the Graphics2D object containing color and opacity 484 */ 485 private Graphics2D setColor( Graphics2D g2, Color color, double opacity ) { 486 if ( opacity < 0.999 ) { 487 final int alpha = (int) Math.round( opacity * 255 ); 488 final int red = color.getRed(); 489 final int green = color.getGreen(); 490 final int blue = color.getBlue(); 491 color = new Color( red, green, blue, alpha ); 492 } 493 g2.setColor( color ); 494 return g2; 495 } 496 497 /** 498 * constructs a java.awt.BasicStroke for painting a LineString legend symbol. 499 * 500 * @param sldstroke 501 * the deegree sld stroke 502 * @return a java.awt.BasicStroke 503 * @throws LegendException 504 * if the sld cannot be processed 505 */ 506 private BasicStroke getBasicStroke( org.deegree.graphics.sld.Stroke sldstroke ) 507 throws LegendException { 508 BasicStroke bs = null; 509 try { 510 float width = (float) sldstroke.getWidth( null ); 511 int cap = sldstroke.getLineCap( null ); 512 int join = sldstroke.getLineJoin( null ); 513 float miterlimit = 1f; 514 float[] dash = sldstroke.getDashArray( null ); 515 float dash_phase = sldstroke.getDashOffset( null ); 516 517 bs = new BasicStroke( width, cap, join, miterlimit, dash, dash_phase ); 518 // return new BasicStroke((float)sldstroke.getWidth(null), sldstroke.getLineCap(null), 519 // sldstroke.getLineJoin(null), 1f, sldstroke.getDashArray(null), 520 // sldstroke.getDashOffset(null)); 521 522 } catch ( FilterEvaluationException ex ) { 523 throw new LegendException( "FilterEvaluationException occured during the creation of the legend:\n" 524 + "The Stroke of the element can't be processed.\n" + ex.getMessage() ); 525 } 526 return bs; 527 } 528 529 /** 530 * calculates the FontMetrics of the LegendLabel in pixels. It returns an 3-dimensional array 531 * containing [0] the width, [1] the ascent and [2] the descent. 532 * 533 * @param label 534 * the label of the LegendElement 535 * @return the 3-dimensional INT-Array contains [0] the width of the string, [1] the ascent and 536 * [2] the descent. 537 */ 538 protected int[] calculateFontMetrics( String label ) { 539 int[] fontmetrics = new int[3]; 540 541 BufferedImage bi = new BufferedImage( 1, 1, BufferedImage.TYPE_INT_ARGB ); 542 Graphics g = bi.getGraphics(); 543 544 FontMetrics fm = g.getFontMetrics(); 545 546 if ( label != null && label.length() > 0 ) { 547 fontmetrics[0] = fm.stringWidth( label ); 548 fontmetrics[1] = fm.getAscent(); 549 fontmetrics[2] = fm.getDescent(); 550 } else { 551 fontmetrics[0] = 0; 552 fontmetrics[1] = 0; 553 fontmetrics[2] = 0; 554 // value = 1, because of a bug, which doesn't paint the right border of the 555 // polygon-symbol. 556 setBufferBetweenLegendAndLabel( 1 ); 557 } 558 g.dispose(); 559 560 return fontmetrics; 561 } 562 563 /** 564 * calculates the width and height of the resulting LegendSymbol depending on the LabelPlacement 565 */ 566 private BufferedImage calculateImage( int labelposition, int labelwidth, int ascent, int descent, int legendwidth, 567 int legendheight, int buffer, String mime ) { 568 // eliminate buffer if label width is zero, so pixel counting works for the reference 569 // implementation 570 if ( labelwidth == 0 ) { 571 buffer = 0; 572 } 573 574 BufferedImage bi = (BufferedImage) GraphicContextFactory.createGraphicTarget( 575 mime, 576 ( legendwidth + buffer + labelwidth ), 577 legendheight ); 578 579 Graphics g = bi.getGraphics(); 580 if ( !( mime.equalsIgnoreCase( "image/png" ) || mime.equalsIgnoreCase( "image/gif" ) ) ) { 581 g.setColor( Color.WHITE ); 582 g.fillRect( 0, 0, bi.getWidth(), bi.getHeight() ); 583 } 584 g.setColor( Color.BLACK ); 585 // TODO labelposition 586 587 switch ( labelposition ) { 588 // LP_TOPCENTER 589 case 0: { 590 LOG.logInfo( "The text-position LP_TOPCENTER in the legend is not " 591 + "implemented yet.\n We put the text on the right side (EAST) of " + "the legendsymbol." ); 592 g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) ); 593 break; 594 } 595 // LP_TOPLEFT 596 case 1: { 597 LOG.logInfo( "The text-position LP_TOPLEFT in the legend is not implemented " 598 + "yet.\n We put the text on the right side (EAST) of the legendsymbol." ); 599 g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) ); 600 break; 601 } 602 // LP_TOPRIGHT 603 case 2: { 604 LOG.logInfo( "The text-position LP_TOPRIGHT in the legend is not implemented " 605 + "yet.\n We put the text on the right side (EAST) of the legendsymbol." ); 606 g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) ); 607 break; 608 } 609 // LP_RIGHT 610 case 3: { 611 LOG.logInfo( "The text-position LP_RIGHT in the legend is not implemented " 612 + "yet.\n We put the text on the right side (EAST) of the legendsymbol." ); 613 g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) ); 614 break; 615 616 } 617 // LP_LEFT 618 case 4: { 619 g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) ); 620 break; 621 } 622 // LP_BOTTOMCENTER 623 case 5: { 624 LOG.logInfo( "The text-position LP_BOTTOMCENTER in the legend is not " 625 + "implemented yet.\n We put the text on the right side (EAST) of " + "the legendsymbol." ); 626 g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) ); 627 break; 628 } 629 // LP_BOTTOMRIGHT 630 case 6: { 631 LOG.logInfo( "The text-position LP_BOTTOMRIGHT in the legend is not " 632 + "implemented yet.\n We put the text on the right side (EAST) of " + "the legendsymbol." ); 633 g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) ); 634 break; 635 } 636 // LP_BOTTOMLEFT 637 case 7: { 638 LOG.logInfo( "The text-position LP_BOTTOMLEFT in the legend is not implemented " 639 + "yet.\n We put the text on the right side (EAST) of the legendsymbol." ); 640 g.drawString( getLabel(), width + 10, height / 2 + ( ( ascent - descent ) / 2 ) ); 641 break; 642 } 643 } 644 g.dispose(); 645 return bi; 646 } 647 648 /** 649 * exports the <tt>LegendElement</tt> as </tt>BufferedImage</tt> 650 * 651 * @param mime 652 * 653 * @return the image 654 * @throws LegendException 655 */ 656 public BufferedImage exportAsImage( String mime ) 657 throws LegendException { 658 659 if ( bi == null ) { 660 // calculates the fontmetrics and creates the bufferedimage 661 // if getLabel() is null is checked in calculateFontMetrics! 662 int[] fontmetrics = calculateFontMetrics( getLabel() ); 663 bi = calculateImage( getLabelPlacement(), fontmetrics[0], fontmetrics[1], fontmetrics[2], getWidth(), 664 getHeight(), getBufferBetweenLegendAndLabel(), mime ); 665 Graphics g = bi.getGraphics(); 666 ( (Graphics2D) g ).setClip( 0, 0, getWidth(), getHeight() ); 667 g.setColor( Color.WHITE ); 668 Rule[] myrules = getRules(); 669 Symbolizer[] symbolizer = null; 670 // determines the legendsymbol and paints it 671 for ( int a = 0; a < myrules.length; a++ ) { 672 symbolizer = myrules[a].getSymbolizers(); 673 674 for ( int b = 0; b < symbolizer.length; b++ ) { 675 if ( symbolizer[b] instanceof PointSymbolizer ) { 676 drawPointLegend( g, (PointSymbolizer) symbolizer[b], getWidth(), getHeight() ); 677 } 678 if ( symbolizer[b] instanceof LineSymbolizer ) { 679 drawLineStringLegend( (Graphics2D) g, (LineSymbolizer) symbolizer[b], width, height ); 680 } 681 if ( symbolizer[b] instanceof PolygonSymbolizer ) { 682 drawPolygonLegend( (Graphics2D) g, (PolygonSymbolizer) symbolizer[b], width, height ); 683 } 684 if ( symbolizer[b] instanceof RasterSymbolizer ) { 685 // throw new LegendException("RasterSymbolizer is not implemented yet!"); 686 } 687 if ( symbolizer[b] instanceof TextSymbolizer ) { 688 // throw new LegendException("TextSymbolizer is not implemented yet!"); 689 } 690 } 691 692 // g.setColor(Color.black); 693 // g.drawString(getLabel(), width + 10, height / 2 + ((fontmetrics[1] - 694 // fontmetrics[2]) / 2)); 695 696 } 697 } else { 698 if ( mime.equalsIgnoreCase( "image/gif" ) || mime.equalsIgnoreCase( "image/png" ) ) { 699 BufferedImage bii = new BufferedImage( bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_INT_ARGB ); 700 Graphics g = bii.getGraphics(); 701 g.drawImage( bi, 0, 0, null ); 702 g.dispose(); 703 bi = bii; 704 } else if ( mime.equalsIgnoreCase( "image/jpg" ) || mime.equalsIgnoreCase( "image/jpeg" ) 705 || mime.equalsIgnoreCase( "image/tif" ) || mime.equalsIgnoreCase( "image/tiff" ) 706 || mime.equalsIgnoreCase( "image/bmp" ) ) { 707 BufferedImage bii = new BufferedImage( bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_INT_RGB ); 708 Graphics g = bii.getGraphics(); 709 g.drawImage( bi, 0, 0, null ); 710 g.dispose(); 711 bi = bii; 712 } else if ( mime.equalsIgnoreCase( "image/svg+xml" ) ) { 713 // not implemented yet 714 } 715 } 716 return bi; 717 } 718 }