001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/graphics/optimizers/LabelChoice.java $ 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 package org.deegree.graphics.optimizers; 037 038 import org.deegree.graphics.displayelements.Label; 039 import org.deegree.graphics.displayelements.LabelDisplayElement; 040 041 /** 042 * Represents different possibilities (candidates) to draw a {@link LabelDisplayElement}. 043 * <p> 044 * A {@link LabelChoice} has several {@link Label} candidates, one of this candidates is selected and represents the 045 * best choice. 046 * 047 * @author <a href="mailto:mschneider@lat-lon.de">Andreas Poth</a> 048 * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider</a> 049 * @author last edited by: $Author: mschneider $ 050 * 051 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18 Jun 2009) $ 052 */ 053 public class LabelChoice { 054 055 // associated LabelDisplayElement 056 private LabelDisplayElement element; 057 058 // currently selected Label (in candidates array) 059 private int selected; 060 061 // candidate Label objects 062 private Label[] candidates; 063 064 // quality of each Label 065 private float[] qualities; 066 067 // boundingbox of all contained labels 068 private int maxX; 069 070 // boundingbox of all contained labels 071 private int maxY; 072 073 // boundingbox of all contained labels 074 private int minX; 075 076 // boundingbox of all contained labels 077 private int minY; 078 079 /** 080 * Creates a new instance of {@link LabelChoice}. 081 * 082 * @param element 083 * @param candidates 084 * @param qualities 085 * @param selected 086 * @param maxX 087 * @param maxY 088 * @param minX 089 * @param minY 090 */ 091 public LabelChoice( LabelDisplayElement element, Label[] candidates, float[] qualities, int selected, int maxX, 092 int maxY, int minX, int minY ) { 093 this.element = element; 094 this.candidates = candidates; 095 this.qualities = qualities; 096 this.selected = selected; 097 this.maxX = maxX; 098 this.maxY = maxY; 099 this.minX = minX; 100 this.minY = minY; 101 } 102 103 /** 104 * Selects one of the contained {@link Label} candidates randomly. 105 */ 106 public void selectLabelRandomly() { 107 selected = (int) ( Math.random() * ( candidates.length - 1 ) + 0.5 ); 108 } 109 110 /** 111 * Sets the selected {@link Label} candidate. 112 * 113 * @param selected 114 * the index of the {@link Label} to be selected 115 */ 116 public void setSelected( int selected ) { 117 this.selected = selected; 118 } 119 120 /** 121 * Returns the index of the currently selected {@link Label}. 122 * 123 * @return the index of the currently selected {@link Label} 124 */ 125 public int getSelected() { 126 return selected; 127 } 128 129 /** 130 * Returns the quality measure of the currently selected {@link Label} 131 * 132 * @return the quality of the currently selected {@link Label} 133 */ 134 public float getQuality() { 135 return qualities[selected]; 136 } 137 138 /** 139 * Returns the currently selected {@link Label} (which is the best choice of the candidates). 140 * 141 * @return the currently selected {@link Label} 142 */ 143 public Label getSelectedLabel() { 144 return candidates[selected]; 145 } 146 147 /** 148 * Returns the associated {@link LabelDisplayElement}. 149 * 150 * @return the associated {@link LabelDisplayElement} 151 */ 152 public LabelDisplayElement getElement() { 153 return element; 154 } 155 156 /** 157 * Returns the max x value of the bounding box of all {@link Label} candidates. 158 * 159 * @return max x value of the bounding box 160 */ 161 public int getMaxX() { 162 return maxX; 163 } 164 165 /** 166 * Returns the max y value of the bounding box of all {@link Label} candidates. 167 * 168 * @return max y value of the bounding box 169 */ 170 public int getMaxY() { 171 return maxY; 172 } 173 174 /** 175 * Returns the min x value of the bounding box of all {@link Label} candidates. 176 * 177 * @return min x value of the bounding box 178 */ 179 public int getMinX() { 180 return minX; 181 } 182 183 /** 184 * Returns the min y value of the bounding box of all {@link Label} candidates. 185 * 186 * @return min y value of the bounding box 187 */ 188 public int getMinY() { 189 return minY; 190 } 191 192 /** 193 * Determines if this {@link LabelChoice} can intersect with another {@link LabelChoice} by any chance, i.e. whether 194 * there are at least two {@link Label} candidates from each choice that intersect. 195 * 196 * @param that 197 * {@link LabelChoice} to be tested against this {@link LabelChoice} 198 * @return true if the two {@link LabelChoice}s can intersect 199 */ 200 public boolean intersects( LabelChoice that ) { 201 202 int west1 = getMinX(); 203 int south1 = getMinY(); 204 int east1 = getMaxX(); 205 int north1 = getMaxY(); 206 207 int west2 = that.getMinX(); 208 int south2 = that.getMinY(); 209 int east2 = that.getMaxX(); 210 int north2 = that.getMaxY(); 211 212 // special cases: one box lays completly inside the other one 213 if ( ( west1 <= west2 ) && ( south1 <= south2 ) && ( east1 >= east2 ) && ( north1 >= north2 ) ) { 214 return true; 215 } 216 if ( ( west1 >= west2 ) && ( south1 >= south2 ) && ( east1 <= east2 ) && ( north1 <= north2 ) ) { 217 return true; 218 } 219 // in any other case of intersection, at least one line of the BBOX has 220 // to cross a line of the other BBOX 221 // check western boundary of box 1 222 // "touching" boxes must not intersect 223 if ( ( west1 >= west2 ) && ( west1 < east2 ) ) { 224 if ( ( south1 <= south2 ) && ( north1 > south2 ) ) { 225 return true; 226 } 227 228 if ( ( south1 < north2 ) && ( north1 >= north2 ) ) { 229 return true; 230 } 231 } 232 // check eastern boundary of box 1 233 // "touching" boxes must not intersect 234 if ( ( east1 > west2 ) && ( east1 <= east2 ) ) { 235 if ( ( south1 <= south2 ) && ( north1 > south2 ) ) { 236 return true; 237 } 238 239 if ( ( south1 < north2 ) && ( north1 >= north2 ) ) { 240 return true; 241 } 242 } 243 // check southern boundary of box 1 244 // "touching" boxes must not intersect 245 if ( ( south1 >= south2 ) && ( south1 < north2 ) ) { 246 if ( ( west1 <= west2 ) && ( east1 > west2 ) ) { 247 return true; 248 } 249 250 if ( ( west1 < east2 ) && ( east1 >= east2 ) ) { 251 return true; 252 } 253 } 254 // check northern boundary of box 1 255 // "touching" boxes must not intersect 256 if ( ( north1 > south2 ) && ( north1 <= north2 ) ) { 257 if ( ( west1 <= west2 ) && ( east1 > west2 ) ) { 258 return true; 259 } 260 261 if ( ( west1 < east2 ) && ( east1 >= east2 ) ) { 262 return true; 263 } 264 } 265 return false; 266 } 267 268 @Override 269 public String toString() { 270 if ( candidates.length > 0 ) { 271 return candidates[0].toString(); 272 } 273 return "empty"; 274 } 275 }