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