[192] | 1 | /* |
---|
| 2 | * $Id: GridCartesianRenderer.java,v 1.30 2003/08/22 23:02:32 dwd Exp $ |
---|
| 3 | * |
---|
| 4 | * This software is provided by NOAA for full, free and open release. It is |
---|
| 5 | * understood by the recipient/user that NOAA assumes no liability for any |
---|
| 6 | * errors contained in the code. Although this software is released without |
---|
| 7 | * conditions or restrictions in its use, it is expected that appropriate |
---|
| 8 | * credit be given to its author and to the National Oceanic and Atmospheric |
---|
| 9 | * Administration should the software be included by the recipient as an |
---|
| 10 | * element in other product development. |
---|
| 11 | */ |
---|
| 12 | |
---|
| 13 | package gov.noaa.pmel.sgt; |
---|
| 14 | |
---|
| 15 | import gov.noaa.pmel.sgt.contour.Contour; |
---|
| 16 | import gov.noaa.pmel.sgt.contour.ContourLine; |
---|
| 17 | import gov.noaa.pmel.sgt.dm.SGTData; |
---|
| 18 | import gov.noaa.pmel.sgt.dm.SGTGrid; |
---|
| 19 | import gov.noaa.pmel.sgt.dm.SimpleGrid; |
---|
| 20 | import gov.noaa.pmel.util.Debug; |
---|
| 21 | import gov.noaa.pmel.util.GeoDate; |
---|
| 22 | import gov.noaa.pmel.util.Range2D; |
---|
| 23 | |
---|
| 24 | import java.awt.*; |
---|
| 25 | import java.beans.PropertyChangeEvent; |
---|
| 26 | import java.util.Enumeration; |
---|
| 27 | |
---|
| 28 | /** |
---|
| 29 | * Produces a cartesian plot from a <code>SGTGrid</code> object. |
---|
| 30 | * |
---|
| 31 | * @author Donald Denbo |
---|
| 32 | * @version $Revision: 1.30 $, $Date: 2003/08/22 23:02:32 $ |
---|
| 33 | * @since 1.0 |
---|
| 34 | */ |
---|
| 35 | public class GridCartesianRenderer |
---|
| 36 | extends CartesianRenderer |
---|
| 37 | { |
---|
| 38 | /** |
---|
| 39 | * @shapeType AggregationLink |
---|
| 40 | * @label grid |
---|
| 41 | * @undirected |
---|
| 42 | * @supplierCardinality 1 |
---|
| 43 | */ |
---|
| 44 | private SGTGrid grid_; |
---|
| 45 | /** |
---|
| 46 | * @shapeType AggregationLink |
---|
| 47 | * @label attr |
---|
| 48 | * @undirected |
---|
| 49 | * @supplierCardinality 1 |
---|
| 50 | */ |
---|
| 51 | private GridAttribute attr_ = null; |
---|
| 52 | |
---|
| 53 | /** |
---|
| 54 | * @link aggregationByValue |
---|
| 55 | * @supplierCardinality 1 |
---|
| 56 | * @label con |
---|
| 57 | */ |
---|
| 58 | private Contour con_ = null; |
---|
| 59 | |
---|
| 60 | // |
---|
| 61 | private void drawRaster( Graphics g ) |
---|
| 62 | { |
---|
| 63 | int nT, nX, nY, nZ; |
---|
| 64 | int[] xp, yp; |
---|
[554] | 65 | int i, xLon, yLat; |
---|
[192] | 66 | Color color; |
---|
| 67 | int xSize, ySize, count; |
---|
| 68 | double[] xValues, yValues, gValues; |
---|
| 69 | double val; |
---|
| 70 | GeoDate[] tValues; |
---|
| 71 | // |
---|
| 72 | if( grid_.isXTime() ) |
---|
| 73 | { |
---|
| 74 | if( grid_.getTimeArray().length <= 2 ) return; |
---|
| 75 | if( grid_.hasXEdges() ) |
---|
| 76 | { |
---|
| 77 | tValues = grid_.getTimeEdges(); |
---|
| 78 | xSize = tValues.length; |
---|
| 79 | xp = new int[xSize]; |
---|
| 80 | for( count = 0; count < xSize; count++ ) |
---|
| 81 | { |
---|
| 82 | xp[count] = cg_.getXUtoD( tValues[count] ); |
---|
| 83 | } |
---|
| 84 | } |
---|
| 85 | else |
---|
| 86 | { |
---|
| 87 | tValues = grid_.getTimeArray(); |
---|
| 88 | xSize = tValues.length; |
---|
| 89 | xp = new int[xSize + 1]; |
---|
| 90 | xp[0] = cg_.getXUtoD( tValues[0].subtract( |
---|
| 91 | ( tValues[1].subtract( tValues[0] ) ).divide( 2.0 ) ) ); |
---|
| 92 | for( count = 1; count < xSize; count++ ) |
---|
| 93 | { |
---|
| 94 | xp[count] = cg_.getXUtoD( |
---|
| 95 | ( tValues[count - 1].add( tValues[count] ) ).divide( 2.0 ) ); |
---|
| 96 | } |
---|
| 97 | xp[xSize] = cg_.getXUtoD( tValues[xSize - 1].add( |
---|
| 98 | ( tValues[xSize - 1].subtract( tValues[xSize - 2] ) ).divide( 2.0 ) ) ); |
---|
| 99 | } |
---|
| 100 | } |
---|
| 101 | else |
---|
| 102 | { |
---|
| 103 | if( grid_.getXArray().length <= 2 ) return; |
---|
| 104 | if( grid_.hasXEdges() ) |
---|
| 105 | { |
---|
| 106 | xValues = grid_.getXEdges(); |
---|
| 107 | xSize = xValues.length; |
---|
| 108 | xp = new int[xSize]; |
---|
| 109 | for( count = 0; count < xSize; count++ ) |
---|
| 110 | { |
---|
| 111 | xp[count] = cg_.getXUtoD( xValues[count] ); |
---|
| 112 | } |
---|
| 113 | } |
---|
| 114 | // VMIPSL |
---|
[555] | 115 | else if( grid_ instanceof SimpleGrid && !( (SimpleGrid) grid_ ).isFullGridForRasterContour() ) |
---|
[192] | 116 | { |
---|
| 117 | xValues = grid_.getXArray(); |
---|
| 118 | xSize = xValues.length; |
---|
| 119 | xp = new int[xSize]; |
---|
| 120 | for( count = 0; count < xSize; count++ ) |
---|
| 121 | xp[count] = cg_.getXUtoD( xValues[count] ); |
---|
| 122 | } |
---|
| 123 | else |
---|
| 124 | { |
---|
| 125 | xValues = grid_.getXArray(); |
---|
| 126 | xSize = xValues.length; |
---|
| 127 | xp = new int[xSize + 1]; |
---|
| 128 | xp[0] = cg_.getXUtoD( xValues[0] - ( xValues[1] - xValues[0] ) * 0.5 ); |
---|
| 129 | for( count = 1; count < xSize; count++ ) |
---|
| 130 | { |
---|
| 131 | xp[count] = cg_.getXUtoD( ( xValues[count - 1] + xValues[count] ) * 0.5 ); |
---|
| 132 | } |
---|
| 133 | xp[xSize] = cg_.getXUtoD( xValues[xSize - 1] + |
---|
| 134 | ( xValues[xSize - 1] - xValues[xSize - 2] ) * 0.5 ); |
---|
| 135 | } |
---|
| 136 | } |
---|
| 137 | if( grid_.isYTime() ) |
---|
| 138 | { |
---|
| 139 | if( grid_.getTimeArray().length <= 2 ) return; |
---|
| 140 | if( grid_.hasYEdges() ) |
---|
| 141 | { |
---|
| 142 | tValues = grid_.getTimeEdges(); |
---|
| 143 | ySize = tValues.length; |
---|
| 144 | yp = new int[ySize]; |
---|
| 145 | for( count = 0; count < ySize; count++ ) |
---|
| 146 | { |
---|
| 147 | yp[count] = cg_.getYUtoD( tValues[count] ); |
---|
| 148 | } |
---|
| 149 | } |
---|
| 150 | else |
---|
| 151 | { |
---|
| 152 | tValues = grid_.getTimeArray(); |
---|
| 153 | ySize = tValues.length; |
---|
| 154 | yp = new int[ySize + 1]; |
---|
| 155 | yp[0] = cg_.getYUtoD( tValues[0].subtract( |
---|
| 156 | ( tValues[1].subtract( tValues[0] ) ).divide( 2.0 ) ) ); |
---|
| 157 | for( count = 1; count < ySize; count++ ) |
---|
| 158 | { |
---|
| 159 | yp[count] = cg_.getYUtoD( ( tValues[count - 1].add( |
---|
| 160 | tValues[count] ) ).divide( 2.0 ) ); |
---|
| 161 | } |
---|
| 162 | yp[ySize] = cg_.getYUtoD( tValues[ySize - 1].add( |
---|
| 163 | ( tValues[ySize - 1].subtract( tValues[ySize - 2] ) ).divide( 2.0 ) ) ); |
---|
| 164 | } |
---|
| 165 | } |
---|
| 166 | else |
---|
| 167 | { |
---|
| 168 | if( grid_.getYArray().length <= 2 ) return; |
---|
| 169 | if( grid_.hasYEdges() ) |
---|
| 170 | { |
---|
| 171 | yValues = grid_.getYEdges(); |
---|
| 172 | ySize = yValues.length; |
---|
| 173 | yp = new int[ySize]; |
---|
| 174 | for( count = 0; count < ySize; count++ ) |
---|
| 175 | { |
---|
| 176 | yp[count] = cg_.getYUtoD( yValues[count] ); |
---|
| 177 | } |
---|
| 178 | } |
---|
| 179 | else |
---|
| 180 | { |
---|
| 181 | yValues = grid_.getYArray(); |
---|
| 182 | ySize = yValues.length; |
---|
| 183 | yp = new int[ySize + 1]; |
---|
| 184 | yp[0] = cg_.getYUtoD( yValues[0] - ( yValues[1] - yValues[0] ) * 0.5 ); |
---|
| 185 | for( count = 1; count < ySize; count++ ) |
---|
| 186 | { |
---|
| 187 | yp[count] = cg_.getYUtoD( ( yValues[count - 1] + yValues[count] ) * 0.5 ); |
---|
| 188 | } |
---|
| 189 | yp[ySize] = cg_.getYUtoD( yValues[ySize - 1] + |
---|
| 190 | ( yValues[ySize - 1] - yValues[ySize - 2] ) * 0.5 ); |
---|
| 191 | } |
---|
| 192 | } |
---|
| 193 | // |
---|
| 194 | // draw raster |
---|
| 195 | // |
---|
| 196 | gValues = grid_.getZArray(); |
---|
| 197 | count = 0; |
---|
| 198 | |
---|
| 199 | // VMIPSl |
---|
[555] | 200 | if( grid_ instanceof SimpleGrid && !( (SimpleGrid) grid_ ).isFullGridForRasterContour() ) |
---|
[192] | 201 | { |
---|
| 202 | for( i = 0; i < Math.max( xSize, ySize ); i++ ) |
---|
| 203 | { |
---|
| 204 | val = gValues[i]; |
---|
| 205 | if( !Double.isNaN( val ) ) |
---|
| 206 | { |
---|
| 207 | color = attr_.getColorMap().getColor( val ); |
---|
| 208 | g.setColor( color ); |
---|
| 209 | drawPoint( g, xp[i], yp[i], attr_ ); |
---|
| 210 | } |
---|
| 211 | } |
---|
| 212 | } |
---|
| 213 | else |
---|
| 214 | { |
---|
[554] | 215 | // VMIPSL |
---|
[555] | 216 | if( ( (SimpleGrid) grid_ ).isFullGridForRasterContour() ) |
---|
[192] | 217 | { |
---|
[554] | 218 | for( yLat = 0; yLat < ySize; yLat++ ) |
---|
[192] | 219 | { |
---|
[554] | 220 | for( xLon = 0; xLon < xSize; xLon++ ) |
---|
[192] | 221 | { |
---|
[554] | 222 | val = gValues[count]; |
---|
| 223 | if( !Double.isNaN( val ) ) |
---|
| 224 | { |
---|
| 225 | color = attr_.getColorMap().getColor( val ); |
---|
| 226 | g.setColor( color ); |
---|
| 227 | drawRect( g, xp[xLon], yp[yLat], xp[xLon + 1], yp[yLat + 1] ); |
---|
| 228 | } |
---|
| 229 | count++; |
---|
[192] | 230 | } |
---|
| 231 | } |
---|
| 232 | } |
---|
[554] | 233 | else |
---|
| 234 | { |
---|
| 235 | for( xLon = 0; xLon < xSize; xLon++ ) |
---|
| 236 | { |
---|
| 237 | for( yLat = 0; yLat < ySize; yLat++ ) |
---|
| 238 | { |
---|
| 239 | val = gValues[count]; |
---|
| 240 | if( !Double.isNaN( val ) ) |
---|
| 241 | { |
---|
| 242 | color = attr_.getColorMap().getColor( val ); |
---|
| 243 | g.setColor( color ); |
---|
| 244 | drawRect( g, xp[xLon], yp[yLat], xp[xLon + 1], yp[yLat + 1] ); |
---|
| 245 | } |
---|
| 246 | count++; |
---|
| 247 | } |
---|
| 248 | } |
---|
| 249 | } |
---|
[192] | 250 | } |
---|
| 251 | } |
---|
| 252 | |
---|
| 253 | /** |
---|
| 254 | * Get the <code>Attribute</code> associated with |
---|
| 255 | * the <code>SGTGrid</code> data. |
---|
| 256 | * |
---|
| 257 | * @return <code>Attribute</code> |
---|
| 258 | */ |
---|
| 259 | public Attribute getAttribute() |
---|
| 260 | { |
---|
| 261 | return attr_; |
---|
| 262 | } |
---|
| 263 | |
---|
| 264 | /** |
---|
| 265 | * Set the <code>GridAttribute</code> for the renderer. |
---|
| 266 | * |
---|
| 267 | * @since 2.0 |
---|
| 268 | */ |
---|
| 269 | public void setAttribute( GridAttribute attr ) |
---|
| 270 | { |
---|
| 271 | if( attr_ != null ) attr_.removePropertyChangeListener( this ); |
---|
| 272 | attr_ = attr; |
---|
| 273 | attr_.addPropertyChangeListener( this ); |
---|
| 274 | } |
---|
| 275 | |
---|
| 276 | private void drawRect( Graphics g, int x1, int y1, int x2, int y2 ) |
---|
| 277 | { |
---|
| 278 | int x, y, width, height; |
---|
| 279 | if( x1 < x2 ) |
---|
| 280 | { |
---|
| 281 | x = x1; |
---|
| 282 | width = x2 - x1; |
---|
| 283 | } |
---|
| 284 | else |
---|
| 285 | { |
---|
| 286 | x = x2; |
---|
| 287 | width = x1 - x2; |
---|
| 288 | } |
---|
| 289 | if( y1 < y2 ) |
---|
| 290 | { |
---|
| 291 | y = y1; |
---|
| 292 | height = y2 - y1; |
---|
| 293 | } |
---|
| 294 | else |
---|
| 295 | { |
---|
| 296 | y = y2; |
---|
| 297 | height = y1 - y2; |
---|
| 298 | } |
---|
| 299 | g.fillRect( x, y, width, height ); |
---|
| 300 | } |
---|
| 301 | |
---|
| 302 | // VMIPSL |
---|
[560] | 303 | // http://www.epic.noaa.gov/java/sgt/sgt-doc/gov/noaa/pmel/sgt/PlotMark.html |
---|
[192] | 304 | protected void drawPoint( final Graphics g, final int x, final int y, final GridAttribute attr ) |
---|
| 305 | { |
---|
| 306 | Layer ly = cg_.getLayer(); |
---|
| 307 | final PointAttribute pointAttribute = new PointAttribute(); |
---|
| 308 | PlotMark pm = new PlotMark( pointAttribute ); |
---|
[560] | 309 | pm.setMark( 9 ); |
---|
| 310 | pm.setMarkHeightP( 0.15 ); |
---|
| 311 | pm.setFill( true ); |
---|
[192] | 312 | |
---|
| 313 | pm.paintMark( g, ly, x, y ); |
---|
| 314 | } |
---|
| 315 | |
---|
| 316 | /** |
---|
| 317 | * Default constructor. The <code>GridCartesianRenderer</code> should |
---|
| 318 | * be created using the <code>CartesianRenderer.getRenderer</code> |
---|
| 319 | * method. |
---|
| 320 | * |
---|
| 321 | * @see Graph |
---|
| 322 | */ |
---|
| 323 | public GridCartesianRenderer( CartesianGraph cg ) |
---|
| 324 | { |
---|
| 325 | this( cg, null, null ); |
---|
| 326 | } |
---|
| 327 | |
---|
| 328 | /** |
---|
| 329 | * Construct a <code>GridCartesianRenderer</code>. |
---|
| 330 | * The <code>GridCartesianRenderer</code> should |
---|
| 331 | * be created using the <code>CartesianRenderer.getRenderer</code> |
---|
| 332 | * method. |
---|
| 333 | * |
---|
| 334 | * @see Graph |
---|
| 335 | */ |
---|
| 336 | public GridCartesianRenderer( CartesianGraph cg, SGTGrid data ) |
---|
| 337 | { |
---|
| 338 | this( cg, data, null ); |
---|
| 339 | } |
---|
| 340 | |
---|
| 341 | /** |
---|
| 342 | * Construct a <code>GridCartesianRenderer</code>. |
---|
| 343 | * The <code>GridCartesianRenderer</code> should |
---|
| 344 | * be created using the <code>CartesianRenderer.getRenderer</code> |
---|
| 345 | * method. |
---|
| 346 | * |
---|
| 347 | * @see Graph |
---|
| 348 | */ |
---|
| 349 | public GridCartesianRenderer( CartesianGraph cg, SGTGrid grid, GridAttribute attr ) |
---|
| 350 | { |
---|
| 351 | cg_ = cg; |
---|
| 352 | grid_ = grid; |
---|
| 353 | attr_ = attr; |
---|
| 354 | if( attr_ != null ) attr_.addPropertyChangeListener( this ); |
---|
| 355 | } |
---|
| 356 | |
---|
| 357 | /** |
---|
| 358 | * Render the <code>SGTData</code>. This method should not |
---|
| 359 | * be directly called. |
---|
| 360 | * |
---|
| 361 | * @param g graphics context |
---|
| 362 | * @see Pane#draw |
---|
| 363 | */ |
---|
| 364 | public void draw( Graphics g ) |
---|
| 365 | { |
---|
| 366 | if( cg_.clipping_ ) |
---|
| 367 | { |
---|
| 368 | int xmin, xmax, ymin, ymax; |
---|
| 369 | int x, y, width, height; |
---|
| 370 | if( cg_.xTransform_.isSpace() ) |
---|
| 371 | { |
---|
| 372 | xmin = cg_.getXUtoD( cg_.xClipRange_.start ); |
---|
| 373 | xmax = cg_.getXUtoD( cg_.xClipRange_.end ); |
---|
| 374 | } |
---|
| 375 | else |
---|
| 376 | { |
---|
| 377 | xmin = cg_.getXUtoD( cg_.tClipRange_.start ); |
---|
| 378 | xmax = cg_.getXUtoD( cg_.tClipRange_.end ); |
---|
| 379 | } |
---|
| 380 | if( cg_.yTransform_.isSpace() ) |
---|
| 381 | { |
---|
| 382 | ymin = cg_.getYUtoD( cg_.yClipRange_.start ); |
---|
| 383 | ymax = cg_.getYUtoD( cg_.yClipRange_.end ); |
---|
| 384 | } |
---|
| 385 | else |
---|
| 386 | { |
---|
| 387 | ymin = cg_.getYUtoD( cg_.tClipRange_.start ); |
---|
| 388 | ymax = cg_.getYUtoD( cg_.tClipRange_.end ); |
---|
| 389 | } |
---|
| 390 | if( xmin < xmax ) |
---|
| 391 | { |
---|
| 392 | x = xmin; |
---|
| 393 | width = xmax - xmin; |
---|
| 394 | } |
---|
| 395 | else |
---|
| 396 | { |
---|
| 397 | x = xmax; |
---|
| 398 | width = xmin - xmax; |
---|
| 399 | } |
---|
| 400 | if( ymin < ymax ) |
---|
| 401 | { |
---|
| 402 | y = ymin; |
---|
| 403 | height = ymax - ymin; |
---|
| 404 | } |
---|
| 405 | else |
---|
| 406 | { |
---|
| 407 | y = ymax; |
---|
| 408 | height = ymin - ymax; |
---|
| 409 | } |
---|
| 410 | g.setClip( x, y, width, height ); |
---|
| 411 | } |
---|
| 412 | if( attr_.isRaster() ) |
---|
| 413 | { |
---|
| 414 | drawRaster( g ); |
---|
| 415 | } |
---|
| 416 | if( attr_.isAreaFill() ) |
---|
| 417 | { |
---|
| 418 | // |
---|
| 419 | // This is a temporary method based on the |
---|
| 420 | // PPLUS area fill algorthim |
---|
| 421 | // |
---|
| 422 | // To be replaced by a area fill method that |
---|
| 423 | // uses the ContourLines |
---|
| 424 | // |
---|
| 425 | double[] x = xArrayP(); |
---|
| 426 | double[] y = yArrayP(); |
---|
| 427 | double[] z = grid_.getZArray(); |
---|
| 428 | int i, j; |
---|
| 429 | int nx = x.length; |
---|
| 430 | int ny = y.length; |
---|
| 431 | double[] xt = new double[5]; |
---|
| 432 | double[] yt = new double[5]; |
---|
| 433 | double[] zt = new double[5]; |
---|
| 434 | for( i = 0; i < nx - 1; i++ ) |
---|
| 435 | { |
---|
| 436 | for( j = 0; j < ny - 1; j++ ) |
---|
| 437 | { |
---|
| 438 | xt[0] = x[i]; |
---|
| 439 | yt[0] = y[j]; |
---|
| 440 | zt[0] = z[j + i * ny]; |
---|
| 441 | // |
---|
| 442 | xt[1] = x[i + 1]; |
---|
| 443 | yt[1] = y[j]; |
---|
| 444 | zt[1] = z[j + ( i + 1 ) * ny]; |
---|
| 445 | // |
---|
| 446 | xt[2] = x[i + 1]; |
---|
| 447 | yt[2] = y[j + 1]; |
---|
| 448 | zt[2] = z[j + 1 + ( i + 1 ) * ny]; |
---|
| 449 | // |
---|
| 450 | xt[3] = xt[0]; |
---|
| 451 | yt[3] = yt[2]; |
---|
| 452 | zt[3] = z[j + 1 + i * ny]; |
---|
| 453 | // |
---|
| 454 | // repeat first point |
---|
| 455 | // |
---|
| 456 | xt[4] = xt[0]; |
---|
| 457 | yt[4] = yt[0]; |
---|
| 458 | zt[4] = zt[0]; |
---|
| 459 | // |
---|
| 460 | fillSquare( g, xt, yt, zt ); |
---|
| 461 | } |
---|
| 462 | } |
---|
| 463 | } |
---|
| 464 | if( attr_.isContour() ) |
---|
| 465 | { |
---|
| 466 | double val; |
---|
| 467 | String label; |
---|
| 468 | Range2D range = computeRange( 10 ); |
---|
| 469 | Format format; |
---|
| 470 | // con_ = new Contour(cg_, grid_, range); |
---|
| 471 | con_ = new Contour( cg_, grid_, attr_.getContourLevels() ); |
---|
| 472 | ContourLevels clevels = con_.getContourLevels(); |
---|
| 473 | DefaultContourLineAttribute attr; |
---|
| 474 | // |
---|
| 475 | // set labels |
---|
| 476 | // |
---|
| 477 | for( int i = 0; i < clevels.size(); i++ ) |
---|
| 478 | { |
---|
| 479 | try |
---|
| 480 | { |
---|
| 481 | val = clevels.getLevel( i ); |
---|
| 482 | attr = clevels.getDefaultContourLineAttribute( i ); |
---|
| 483 | if( attr.isAutoLabel() ) |
---|
| 484 | { |
---|
| 485 | if( attr.getLabelFormat().length() <= 0 ) |
---|
| 486 | { |
---|
| 487 | format = new Format( Format.computeFormat( range.start, |
---|
| 488 | range.end, |
---|
| 489 | attr.getSignificantDigits() ) ); |
---|
| 490 | } |
---|
| 491 | else |
---|
| 492 | { |
---|
| 493 | format = new Format( attr.getLabelFormat() ); |
---|
| 494 | } |
---|
| 495 | label = format.form( val ); |
---|
| 496 | attr.setLabelText( label ); |
---|
| 497 | } |
---|
| 498 | } |
---|
| 499 | catch( ContourLevelNotFoundException e ) |
---|
| 500 | { |
---|
| 501 | System.out.println( e ); |
---|
| 502 | } |
---|
| 503 | } |
---|
| 504 | con_.generateContourLines(); |
---|
| 505 | con_.generateContourLabels( g ); |
---|
| 506 | Enumeration elem = con_.elements(); |
---|
| 507 | ContourLine cl; |
---|
| 508 | while( elem.hasMoreElements() ) |
---|
| 509 | { |
---|
| 510 | cl = (ContourLine) elem.nextElement(); |
---|
| 511 | if( Debug.CONTOUR ) |
---|
| 512 | { |
---|
| 513 | System.out.println( " level = " + cl.getLevel() + |
---|
| 514 | ", length = " + cl.getKmax() + |
---|
| 515 | ", closed = " + cl.isClosed() ); |
---|
| 516 | } |
---|
| 517 | cl.draw( g ); |
---|
| 518 | } |
---|
| 519 | } |
---|
| 520 | // |
---|
| 521 | // reset clip |
---|
| 522 | // |
---|
| 523 | Rectangle rect = cg_.getLayer().getPane().getBounds(); |
---|
| 524 | g.setClip( rect ); |
---|
| 525 | } |
---|
| 526 | |
---|
| 527 | private void fillSquare( Graphics g, double[] x, |
---|
| 528 | double[] y, double[] z ) |
---|
| 529 | { |
---|
| 530 | ContourLevels clevels = attr_.getContourLevels(); |
---|
| 531 | IndexedColor cmap = (IndexedColor) attr_.getColorMap(); |
---|
| 532 | int i, j, cindex, npoly, maxindex; |
---|
| 533 | double zlev, zlevp1, f; |
---|
| 534 | Color col; |
---|
| 535 | double[] xpoly = new double[20]; |
---|
| 536 | double[] ypoly = new double[20]; |
---|
| 537 | double zmin = Math.min( z[0], z[1] ); |
---|
| 538 | double zmax = Math.max( z[0], z[1] ); |
---|
| 539 | for( i = 2; i <= 3; i++ ) |
---|
| 540 | { |
---|
| 541 | zmin = Math.min( zmin, z[i] ); |
---|
| 542 | zmax = Math.max( zmax, z[i] ); |
---|
| 543 | } |
---|
| 544 | if( Double.isNaN( zmax ) ) return; |
---|
| 545 | maxindex = clevels.getMaximumIndex(); |
---|
| 546 | for( cindex = -1; cindex <= maxindex; cindex++ ) |
---|
| 547 | { |
---|
| 548 | try |
---|
| 549 | { |
---|
| 550 | if( cindex == -1 ) |
---|
| 551 | { |
---|
| 552 | zlev = -Double.MAX_VALUE; |
---|
| 553 | } |
---|
| 554 | else |
---|
| 555 | { |
---|
| 556 | zlev = clevels.getLevel( cindex ); |
---|
| 557 | } |
---|
| 558 | if( cindex == maxindex ) |
---|
| 559 | { |
---|
| 560 | zlevp1 = Double.MAX_VALUE; |
---|
| 561 | } |
---|
| 562 | else |
---|
| 563 | { |
---|
| 564 | zlevp1 = clevels.getLevel( cindex + 1 ); |
---|
| 565 | } |
---|
| 566 | } |
---|
| 567 | catch( ContourLevelNotFoundException e ) |
---|
| 568 | { |
---|
| 569 | System.out.println( e ); |
---|
| 570 | break; |
---|
| 571 | } |
---|
| 572 | col = cmap.getColorByIndex( cindex + 1 ); |
---|
| 573 | if( zmin > zlevp1 || zmax < zlev ) continue; |
---|
| 574 | if( zmin >= zlev && zmax <= zlevp1 ) |
---|
| 575 | { |
---|
| 576 | fillPolygon( g, col, x, y, 4 ); |
---|
| 577 | return; |
---|
| 578 | } |
---|
| 579 | npoly = -1; |
---|
| 580 | for( j = 0; j < 4; j++ ) |
---|
| 581 | { /* sides */ |
---|
| 582 | if( z[j] < zlev ) |
---|
| 583 | { |
---|
| 584 | // |
---|
| 585 | // z[j] is below |
---|
| 586 | // |
---|
| 587 | if( z[j + 1] > zlevp1 ) |
---|
| 588 | { |
---|
| 589 | // |
---|
| 590 | // z[j+1] is above |
---|
| 591 | // |
---|
| 592 | npoly = npoly + 1; |
---|
| 593 | f = ( z[j] - zlev ) / ( z[j] - z[j + 1] ); |
---|
| 594 | xpoly[npoly] = x[j] - f * ( x[j] - x[j + 1] ); |
---|
| 595 | ypoly[npoly] = y[j] - f * ( y[j] - y[j + 1] ); |
---|
| 596 | // |
---|
| 597 | npoly = npoly + 1; |
---|
| 598 | f = ( z[j] - zlevp1 ) / ( z[j] - z[j + 1] ); |
---|
| 599 | xpoly[npoly] = x[j] - f * ( x[j] - x[j + 1] ); |
---|
| 600 | ypoly[npoly] = y[j] - f * ( y[j] - y[j + 1] ); |
---|
| 601 | } |
---|
| 602 | else if( z[j + 1] >= zlev && |
---|
| 603 | z[j + 1] <= zlevp1 ) |
---|
| 604 | { |
---|
| 605 | // |
---|
| 606 | // z[j+1] is inside |
---|
| 607 | // |
---|
| 608 | npoly = npoly + 1; |
---|
| 609 | f = ( z[j] - zlev ) / ( z[j] - z[j + 1] ); |
---|
| 610 | xpoly[npoly] = x[j] - f * ( x[j] - x[j + 1] ); |
---|
| 611 | ypoly[npoly] = y[j] - f * ( y[j] - y[j + 1] ); |
---|
| 612 | // |
---|
| 613 | npoly = npoly + 1; |
---|
| 614 | xpoly[npoly] = x[j + 1]; |
---|
| 615 | ypoly[npoly] = y[j + 1]; |
---|
| 616 | } |
---|
| 617 | } |
---|
| 618 | else if( z[j] > zlevp1 ) |
---|
| 619 | { |
---|
| 620 | // |
---|
| 621 | // z[j] is above |
---|
| 622 | // |
---|
| 623 | if( z[j + 1] < zlev ) |
---|
| 624 | { |
---|
| 625 | // |
---|
| 626 | // z[j+1] is below |
---|
| 627 | // |
---|
| 628 | npoly = npoly + 1; |
---|
| 629 | f = ( z[j] - zlevp1 ) / ( z[j] - z[j + 1] ); |
---|
| 630 | xpoly[npoly] = x[j] - f * ( x[j] - x[j + 1] ); |
---|
| 631 | ypoly[npoly] = y[j] - f * ( y[j] - y[j + 1] ); |
---|
| 632 | // |
---|
| 633 | npoly = npoly + 1; |
---|
| 634 | f = ( z[j] - zlev ) / ( z[j] - z[j + 1] ); |
---|
| 635 | xpoly[npoly] = x[j] - f * ( x[j] - x[j + 1] ); |
---|
| 636 | ypoly[npoly] = y[j] - f * ( y[j] - y[j + 1] ); |
---|
| 637 | } |
---|
| 638 | else if( z[j + 1] >= zlev && z[j + 1] <= zlevp1 ) |
---|
| 639 | { |
---|
| 640 | // |
---|
| 641 | // z[j+1] is inside |
---|
| 642 | // |
---|
| 643 | npoly = npoly + 1; |
---|
| 644 | f = ( z[j] - zlevp1 ) / ( z[j] - z[j + 1] ); |
---|
| 645 | xpoly[npoly] = x[j] - f * ( x[j] - x[j + 1] ); |
---|
| 646 | ypoly[npoly] = y[j] - f * ( y[j] - y[j + 1] ); |
---|
| 647 | // |
---|
| 648 | npoly = npoly + 1; |
---|
| 649 | xpoly[npoly] = x[j + 1]; |
---|
| 650 | ypoly[npoly] = y[j + 1]; |
---|
| 651 | } |
---|
| 652 | } |
---|
| 653 | else |
---|
| 654 | { |
---|
| 655 | // |
---|
| 656 | // x[j] is inside |
---|
| 657 | // |
---|
| 658 | if( z[j + 1] > zlevp1 ) |
---|
| 659 | { |
---|
| 660 | // |
---|
| 661 | // z[j+1] is above |
---|
| 662 | // |
---|
| 663 | npoly = npoly + 1; |
---|
| 664 | f = ( z[j] - zlevp1 ) / ( z[j] - z[j + 1] ); |
---|
| 665 | xpoly[npoly] = x[j] - f * ( x[j] - x[j + 1] ); |
---|
| 666 | ypoly[npoly] = y[j] - f * ( y[j] - y[j + 1] ); |
---|
| 667 | } |
---|
| 668 | else if( z[j + 1] < zlev ) |
---|
| 669 | { |
---|
| 670 | // |
---|
| 671 | // z[j+1] is below |
---|
| 672 | // |
---|
| 673 | npoly = npoly + 1; |
---|
| 674 | f = ( z[j] - zlev ) / ( z[j] - z[j + 1] ); |
---|
| 675 | xpoly[npoly] = x[j] - f * ( x[j] - x[j + 1] ); |
---|
| 676 | ypoly[npoly] = y[j] - f * ( y[j] - y[j + 1] ); |
---|
| 677 | } |
---|
| 678 | else |
---|
| 679 | { |
---|
| 680 | // |
---|
| 681 | // z[j+1] is inside |
---|
| 682 | // |
---|
| 683 | npoly = npoly + 1; |
---|
| 684 | xpoly[npoly] = x[j + 1]; |
---|
| 685 | ypoly[npoly] = y[j + 1]; |
---|
| 686 | } |
---|
| 687 | } |
---|
| 688 | } |
---|
| 689 | fillPolygon( g, col, xpoly, ypoly, npoly + 1 ); |
---|
| 690 | } |
---|
| 691 | } |
---|
| 692 | |
---|
| 693 | private void fillPolygon( Graphics g, Color c, |
---|
| 694 | double[] x, double[] y, |
---|
| 695 | int npoints ) |
---|
| 696 | { |
---|
| 697 | Layer layer = cg_.getLayer(); |
---|
| 698 | int[] xt = new int[20]; |
---|
| 699 | int[] yt = new int[20]; |
---|
| 700 | g.setColor( c ); |
---|
| 701 | for( int i = 0; i < npoints; i++ ) |
---|
| 702 | { |
---|
| 703 | xt[i] = layer.getXPtoD( x[i] ); |
---|
| 704 | yt[i] = layer.getYPtoD( y[i] ); |
---|
| 705 | } |
---|
| 706 | g.fillPolygon( xt, yt, npoints ); |
---|
| 707 | } |
---|
| 708 | |
---|
| 709 | private double[] xArrayP() |
---|
| 710 | { |
---|
| 711 | int i; |
---|
| 712 | double[] p; |
---|
| 713 | if( grid_.isXTime() ) |
---|
| 714 | { |
---|
| 715 | GeoDate[] t = grid_.getTimeArray(); |
---|
| 716 | p = new double[t.length]; |
---|
| 717 | for( i = 0; i < t.length; i++ ) |
---|
| 718 | { |
---|
| 719 | p[i] = cg_.getXUtoP( t[i] ); |
---|
| 720 | } |
---|
| 721 | } |
---|
| 722 | else |
---|
| 723 | { |
---|
| 724 | double[] x = grid_.getXArray(); |
---|
| 725 | p = new double[x.length]; |
---|
| 726 | for( i = 0; i < x.length; i++ ) |
---|
| 727 | { |
---|
| 728 | p[i] = cg_.getXUtoP( x[i] ); |
---|
| 729 | } |
---|
| 730 | } |
---|
| 731 | return p; |
---|
| 732 | } |
---|
| 733 | |
---|
| 734 | private double[] yArrayP() |
---|
| 735 | { |
---|
| 736 | int i; |
---|
| 737 | double[] p; |
---|
| 738 | if( grid_.isYTime() ) |
---|
| 739 | { |
---|
| 740 | GeoDate[] t = grid_.getTimeArray(); |
---|
| 741 | p = new double[t.length]; |
---|
| 742 | for( i = 0; i < t.length; i++ ) |
---|
| 743 | { |
---|
| 744 | p[i] = cg_.getYUtoP( t[i] ); |
---|
| 745 | } |
---|
| 746 | } |
---|
| 747 | else |
---|
| 748 | { |
---|
| 749 | double[] y = grid_.getYArray(); |
---|
| 750 | p = new double[y.length]; |
---|
| 751 | for( i = 0; i < y.length; i++ ) |
---|
| 752 | { |
---|
| 753 | p[i] = cg_.getYUtoP( y[i] ); |
---|
| 754 | } |
---|
| 755 | } |
---|
| 756 | return p; |
---|
| 757 | } |
---|
| 758 | |
---|
| 759 | private Range2D computeRange( int levels ) |
---|
| 760 | { |
---|
| 761 | Range2D range; |
---|
| 762 | double zmin = Double.POSITIVE_INFINITY; |
---|
| 763 | double zmax = Double.NEGATIVE_INFINITY; |
---|
| 764 | double[] array = grid_.getZArray(); |
---|
| 765 | for( int i = 0; i < array.length; i++ ) |
---|
| 766 | { |
---|
| 767 | if( !Double.isNaN( array[i] ) ) |
---|
| 768 | { |
---|
| 769 | zmin = Math.min( zmin, array[i] ); |
---|
| 770 | zmax = Math.max( zmax, array[i] ); |
---|
| 771 | } |
---|
| 772 | } |
---|
| 773 | range = Graph.computeRange( zmin, zmax, levels ); |
---|
| 774 | return range; |
---|
| 775 | } |
---|
| 776 | |
---|
| 777 | /** |
---|
| 778 | * Get the <code>SGTGrid</code>. |
---|
| 779 | * |
---|
| 780 | * @return <code>SGTGrid</code> |
---|
| 781 | */ |
---|
| 782 | public SGTGrid getGrid() |
---|
| 783 | { |
---|
| 784 | return grid_; |
---|
| 785 | } |
---|
| 786 | |
---|
| 787 | /** |
---|
| 788 | * Get the associated <code>CartesianGraph</code> object. |
---|
| 789 | * |
---|
| 790 | * @return <code>CartesianGraph</code> |
---|
| 791 | * @since 2.0 |
---|
| 792 | */ |
---|
| 793 | public CartesianGraph getCartesianGraph() |
---|
| 794 | { |
---|
| 795 | return cg_; |
---|
| 796 | } |
---|
| 797 | |
---|
| 798 | public void propertyChange( PropertyChangeEvent evt ) |
---|
| 799 | { |
---|
| 800 | // if(Debug.EVENT) { |
---|
| 801 | // System.out.println("GridCartesianRenderer: " + evt); |
---|
| 802 | // System.out.println(" " + evt.getPropertyName()); |
---|
| 803 | // } |
---|
| 804 | modified( "GridCartesianRenderer: propertyChange(" + |
---|
| 805 | evt.getSource().toString() + "[" + |
---|
| 806 | evt.getPropertyName() + "]" + ")" ); |
---|
| 807 | } |
---|
| 808 | |
---|
| 809 | /** |
---|
| 810 | * @since 3.0 |
---|
| 811 | */ |
---|
| 812 | public SGTData getDataAt( Point pt ) |
---|
| 813 | { |
---|
| 814 | return null; |
---|
| 815 | } |
---|
| 816 | } |
---|