001 /* 002 * This file is part of McIDAS-V 003 * 004 * Copyright 2007-2013 005 * Space Science and Engineering Center (SSEC) 006 * University of Wisconsin - Madison 007 * 1225 W. Dayton Street, Madison, WI 53706, USA 008 * https://www.ssec.wisc.edu/mcidas 009 * 010 * All Rights Reserved 011 * 012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and 013 * some McIDAS-V source code is based on IDV and VisAD source code. 014 * 015 * McIDAS-V is free software; you can redistribute it and/or modify 016 * it under the terms of the GNU Lesser Public License as published by 017 * the Free Software Foundation; either version 3 of the License, or 018 * (at your option) any later version. 019 * 020 * McIDAS-V is distributed in the hope that it will be useful, 021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 023 * GNU Lesser Public License for more details. 024 * 025 * You should have received a copy of the GNU Lesser Public License 026 * along with this program. If not, see http://www.gnu.org/licenses. 027 */ 028 029 package edu.wisc.ssec.mcidasv.data; 030 031 import java.awt.Image; 032 import java.rmi.RemoteException; 033 import java.util.ArrayList; 034 import java.util.Arrays; 035 import java.util.Calendar; 036 import java.util.Date; 037 import java.util.GregorianCalendar; 038 import java.util.Hashtable; 039 import java.util.Iterator; 040 import java.util.List; 041 import java.util.TimeZone; 042 043 import ucar.unidata.data.CompositeDataChoice; 044 import ucar.unidata.data.DataCategory; 045 import ucar.unidata.data.DataChoice; 046 import ucar.unidata.data.DataContext; 047 import ucar.unidata.data.DataSelection; 048 import ucar.unidata.data.DataSelectionComponent; 049 import ucar.unidata.data.DataSourceDescriptor; 050 import ucar.unidata.data.DataSourceImpl; 051 import ucar.unidata.data.DirectDataChoice; 052 import ucar.unidata.idv.IntegratedDataViewer; 053 import ucar.unidata.idv.control.DisplayControlImpl; 054 import ucar.unidata.idv.control.ImageSequenceControl; 055 import ucar.unidata.ui.colortable.ColorTableManager; 056 import ucar.unidata.util.ColorTable; 057 import ucar.unidata.util.Misc; 058 import visad.Data; 059 import visad.DateTime; 060 import visad.FlatField; 061 import visad.FunctionType; 062 import visad.Linear2DSet; 063 import visad.RealTupleType; 064 import visad.RealType; 065 import visad.VisADException; 066 import visad.data.mcidas.AREACoordinateSystem; 067 import visad.meteorology.NavigatedImage; 068 import visad.meteorology.SingleBandedImage; 069 import edu.wisc.ssec.mcidasv.control.FrameComponentInfo; 070 import edu.wisc.ssec.mcidasv.control.McIdasComponents; 071 import edu.wisc.ssec.mcidasv.control.McIdasImageSequenceControl; 072 073 /** 074 * Used to cache a data choice and its data 075 * 076 * @author IDV development team 077 * @version $Revision$ 078 */ 079 public class McIdasXDataSource extends DataSourceImpl { 080 081 /** list of frames to load */ 082 private List frameNumbers = new ArrayList(); 083 084 /** list of McIDAS-X frames */ 085 private List frameList = new ArrayList(); 086 087 /** McIDAS-X connection info */ 088 private McIdasXInfo mcidasxInfo; 089 090 /** list of 2D categories */ 091 private List twoDCategories; 092 093 /** list of 2D time series categories */ 094 private List twoDTimeSeriesCategories; 095 096 /** image data arrays */ 097 private double values[][] = new double[1][1]; 098 099 //private boolean hasImagePreview = false; 100 private boolean hasImagePreview = true; 101 private Image theImage; 102 private int lastPreview = -1; 103 104 DisplayControlImpl dci; 105 106 /** 107 * Default bean constructor; does nothing 108 */ 109 public McIdasXDataSource() {} 110 111 /** 112 * Create a McIdasXDataSource 113 * 114 * 115 * @param descriptor the datasource descriptor 116 * @param name my name 117 * @param properties my properties 118 */ 119 public McIdasXDataSource(DataSourceDescriptor descriptor, String name, 120 Hashtable properties) { 121 super(descriptor, "McIDAS-X", "McIDAS-X", properties); 122 /* 123 System.out.println("McIdasXDataSource:"); 124 System.out.println(" descriptor=" + descriptor); 125 System.out.println(" name=" + name); 126 System.out.println(" properties=" + properties); 127 */ 128 if ((properties == null) || (properties.get(edu.wisc.ssec.mcidasv.chooser.FrameChooser.FRAME_NUMBERS_KEY) == null)) { 129 List frames = new ArrayList(); 130 frames.add(new Integer(-1)); 131 properties.put(edu.wisc.ssec.mcidasv.chooser.FrameChooser.FRAME_NUMBERS_KEY, frames); 132 } 133 134 this.frameNumbers.clear(); 135 this.frameNumbers = getFrameNumbers(); 136 137 String host = (String)properties.get(edu.wisc.ssec.mcidasv.chooser.FrameChooser.REQUEST_HOST); 138 String port = (String)properties.get(edu.wisc.ssec.mcidasv.chooser.FrameChooser.REQUEST_PORT); 139 String key = (String)properties.get(edu.wisc.ssec.mcidasv.chooser.FrameChooser.REQUEST_KEY); 140 mcidasxInfo = new McIdasXInfo(host, port, key); 141 142 try { 143 this.frameList = makeFrames(this.frameNumbers); 144 } catch (Exception e) { 145 System.out.println("McIdasXDataSource constructor exception: " + e); 146 } 147 } 148 149 /** 150 * Make a list of McIDAS-X frames 151 * 152 * @param frames List of frame numbers 153 * 154 * @return ImageDataset 155 */ 156 public List makeFrames(List inFrameNumbers) { 157 List frames = new ArrayList(); 158 Integer frmInt; 159 for (int i = 0; i < inFrameNumbers.size(); i++) { 160 frmInt = (Integer)inFrameNumbers.get(i); 161 frames.add(new McIdasFrame(frmInt.intValue(), mcidasxInfo)); 162 } 163 // System.out.println("McIdasXDataSource makeFrames in: " + frameNumbers + ", out: " + frames); 164 return frames; 165 } 166 167 /** 168 * Get a frame from the frameList based on frame number 169 */ 170 public McIdasFrame getFrame(int frameNumber) { 171 McIdasFrame checkFrame; 172 for (int i=0; i<this.frameList.size(); i++) { 173 checkFrame = (McIdasFrame)frameList.get(i); 174 if (checkFrame.getFrameNumber() == frameNumber) { 175 return(checkFrame); 176 } 177 } 178 return new McIdasFrame(); 179 } 180 181 /** 182 * Set a frame in the framelist based on frame number 183 */ 184 public void setFrame(int frameNumber, McIdasFrame inFrame) { 185 McIdasFrame checkFrame; 186 for (int i=0; i<this.frameList.size(); i++) { 187 checkFrame = (McIdasFrame)frameList.get(i); 188 if (checkFrame.getFrameNumber() == frameNumber) { 189 this.frameList.set(i, inFrame); 190 } 191 } 192 } 193 194 /** 195 * This is called after this datasource has been fully created 196 * and initialized after being unpersisted by the XmlEncoder. 197 */ 198 public void initAfterUnpersistence() { 199 super.initAfterUnpersistence(); 200 this.frameNumbers.clear(); 201 this.frameNumbers = getFrameNumbers(); 202 this.frameList = makeFrames(this.frameNumbers); 203 } 204 205 /** 206 * Gets called after creation. Initialize the connection 207 */ 208 public void initAfterCreation() { 209 initConnection(); 210 } 211 212 /** 213 * Initialize the connection to McIdas-X. 214 * This gets called when the data source is newly created 215 * or decoded form a bundle. 216 */ 217 private void initConnection() { 218 int istat = 0; 219 220 if (istat < 0) 221 setInError(true,"Unable to connect to McIDAS-X"); 222 } 223 224 protected boolean shouldCache(Data data) { 225 return false; 226 } 227 228 protected void initDataSelectionComponents( 229 List<DataSelectionComponent> components, final DataChoice dataChoice) { 230 231 getDataContext().getIdv().showWaitCursor(); 232 makePreviewImage(dataChoice); 233 if (hasImagePreview) { 234 try { 235 components.add(new ImagePreviewSelection(theImage)); 236 } catch (Exception e) { 237 System.out.println("Can't make preview image: "+e); 238 e.printStackTrace(); 239 } 240 } 241 getDataContext().getIdv().showNormalCursor(); 242 } 243 244 private void makePreviewImage(DataChoice dataChoice) { 245 int dataFrame = -1; 246 if (dataChoice.getDescription().indexOf("Frame ") >= 0) { 247 try { 248 dataFrame = Integer.parseInt(dataChoice.getDescription().substring(6)); 249 } 250 catch (Exception e) { 251 hasImagePreview = false; 252 return; 253 } 254 } 255 if (dataFrame <= 0) { 256 hasImagePreview = false; 257 return; 258 } 259 if (dataFrame != lastPreview) { 260 McIdasFrame mxf = new McIdasFrame(dataFrame, mcidasxInfo); 261 theImage = mxf.getGIF(); 262 } 263 hasImagePreview = true; 264 lastPreview = dataFrame; 265 } 266 267 /** 268 * 269 * @param dataChoice The data choice that identifies the requested 270 * data. 271 * @param category The data category of the request. 272 * @param dataSelection Identifies any subsetting of the data. 273 * @param requestProperties Hashtable that holds any detailed request 274 * properties. 275 * 276 * @return The data 277 * 278 * @throws RemoteException Java RMI problem 279 * @throws VisADException VisAD problem 280 */ 281 protected Data getDataInner(DataChoice dataChoice, DataCategory category, 282 DataSelection dataSelection, Hashtable requestProperties) 283 throws VisADException, RemoteException { 284 /* 285 System.out.println("McIdasXDataSource getDataInner:"); 286 System.out.println(" dataChoice=" + dataChoice); 287 System.out.println(" category=" + category); 288 System.out.println(" dataSelection=" + dataSelection); 289 System.out.println(" requestProperties=" + requestProperties); 290 */ 291 292 // Read the properties to decide which frame components should be requested 293 FrameComponentInfo frameComponentInfo = new FrameComponentInfo(); 294 Boolean mc; 295 mc = (Boolean)(requestProperties.get(McIdasComponents.IMAGE)); 296 if (mc == null) mc=Boolean.TRUE; 297 frameComponentInfo.setIsImage(mc.booleanValue()); 298 mc = (Boolean)(requestProperties.get(McIdasComponents.GRAPHICS)); 299 if (mc == null) mc=Boolean.TRUE; 300 frameComponentInfo.setIsGraphics(mc.booleanValue()); 301 mc = (Boolean)(requestProperties.get(McIdasComponents.COLORTABLE)); 302 if (mc == null) mc=Boolean.TRUE; 303 frameComponentInfo.setIsColorTable(mc.booleanValue()); 304 mc = (Boolean)(requestProperties.get(McIdasComponents.ANNOTATION)); 305 if (mc == null) mc=Boolean.TRUE; 306 frameComponentInfo.setIsAnnotation(mc.booleanValue()); 307 mc = (Boolean)(requestProperties.get(McIdasComponents.FAKEDATETIME)); 308 if (mc == null) mc=Boolean.TRUE; 309 frameComponentInfo.setFakeDateTime(mc.booleanValue()); 310 311 List defList = null; 312 frameNumbers = (List)getProperty(edu.wisc.ssec.mcidasv.chooser.FrameChooser.FRAME_NUMBERS_KEY, defList); 313 314 // Read the properties to decide which frame components need to be requested 315 FrameDirtyInfo frameDirtyInfo = new FrameDirtyInfo(); 316 List frameDirtyInfoList = new ArrayList(); 317 frameDirtyInfoList = (ArrayList)(requestProperties.get(McIdasComponents.DIRTYINFO)); 318 319 if (frameDirtyInfoList == null) { 320 frameDirtyInfoList = new ArrayList(); 321 for (int i=0; i<frameNumbers.size(); i++) { 322 frameDirtyInfo = new FrameDirtyInfo((Integer)frameNumbers.get(i), true, true, true); 323 frameDirtyInfoList.add(frameDirtyInfo); 324 } 325 } 326 327 Data data=null; 328 if (frameNumbers.size() < 1) { 329 return data; 330 } 331 if (frameNumbers.size() < 2) { 332 for (int i=0; i<frameDirtyInfoList.size(); i++) { 333 frameDirtyInfo = (FrameDirtyInfo)frameDirtyInfoList.get(i); 334 if (frameDirtyInfo.getFrameNumber() == (Integer)frameNumbers.get(0)) { 335 // System.out.println("frameDirtyInfo: " + frameDirtyInfo); 336 data = (Data) getMcIdasSequence((Integer)frameNumbers.get(0), frameComponentInfo, frameDirtyInfo); 337 } 338 } 339 } else { 340 String dc=""; 341 String fd=""; 342 for (int i=0; i<frameNumbers.size(); i++) { 343 dc = dataChoice.toString(); 344 fd = (this.frameList.get(i)).toString(); 345 if (dc.compareTo(fd) == 0) { 346 if (i > 0) { 347 frameComponentInfo.setIsColorTable(false); 348 } 349 for (int j=0; j<frameDirtyInfoList.size(); j++) { 350 frameDirtyInfo = (FrameDirtyInfo)frameDirtyInfoList.get(j); 351 if (frameDirtyInfo.getFrameNumber() == (Integer)frameNumbers.get(i)) { 352 // System.out.println("frameDirtyInfo: " + frameDirtyInfo); 353 data = (Data) getMcIdasSequence((Integer)frameNumbers.get(i), frameComponentInfo, frameDirtyInfo); 354 } 355 } 356 } 357 } 358 } 359 return data; 360 } 361 362 /** 363 * make a time series from selected McIdas-X frames 364 */ 365 private SingleBandedImage getMcIdasSequence(int frameNumber, 366 FrameComponentInfo frameComponentInfo, 367 FrameDirtyInfo frameDirtyInfo) 368 throws VisADException, RemoteException { 369 /* 370 System.out.println("McIdasXDataSource getMcIdasSequence:"); 371 System.out.println(" frmNo=" + frmNo); 372 System.out.println(" frameComponentInfo=" + frameComponentInfo); 373 */ 374 SingleBandedImage image = getMcIdasFrame(frameNumber, frameComponentInfo, frameDirtyInfo); 375 if (image != null) { 376 if (shouldCache((Data)image)) { 377 Integer fo = new Integer(frameNumber); 378 putCache(fo,image); 379 } 380 } 381 return image; 382 } 383 384 private DisplayControlImpl getDisplayControlImpl() { 385 dci = null; 386 List dcl = getDataChangeListeners(); 387 if (dcl != null) { 388 for (int i=0; i< dcl.size(); i++) { 389 if (dcl.get(i) instanceof McIdasImageSequenceControl) { 390 dci= (DisplayControlImpl)(dcl.get(i)); 391 break; 392 } 393 } 394 } 395 return dci; 396 } 397 398 /** 399 * Get frame numbers 400 * 401 * @return frame numbers 402 */ 403 public List getFrameNumbers() { 404 List defList = null; 405 List gotFrameNumbers = (List)getProperty(edu.wisc.ssec.mcidasv.chooser.FrameChooser.FRAME_NUMBERS_KEY, defList); 406 return gotFrameNumbers; 407 } 408 409 /** 410 * Get the name for the main data object 411 * 412 * @return name of main data object 413 */ 414 public String getDataName() { 415 String dataName = (String) getProperty(edu.wisc.ssec.mcidasv.chooser.FrameChooser.DATA_NAME_KEY, "Frame Sequence"); 416 if (dataName.equals("")) { 417 dataName = "Frame Sequence"; 418 } 419 return dataName; 420 } 421 422 /** 423 * Get McIdasXInfo object 424 * 425 * @return mcidasxInfo 426 */ 427 public McIdasXInfo getMcIdasXInfo() { 428 return mcidasxInfo; 429 } 430 431 /** 432 * Initialize the {@link ucar.unidata.data.DataCategory} objects that 433 * this data source uses. 434 */ 435 private void makeCategories() { 436 twoDTimeSeriesCategories = DataCategory.parseCategories("MCIDASX;", false); 437 twoDCategories = DataCategory.parseCategories("MCIDASX;", false); 438 } 439 440 /** 441 * Return the list of {@link ucar.unidata.data.DataCategory} used for 442 * single time step data. 443 * 444 * @return A list of categories. 445 */ 446 public List getTwoDCategories() { 447 if (twoDCategories == null) { 448 makeCategories(); 449 } 450 return twoDCategories; 451 } 452 453 /** 454 * Return the list of {@link ucar.unidata.data.DataCategory} used for 455 * multiple time step data. 456 * 457 * @return A list of categories. 458 */ 459 460 public List getTwoDTimeSeriesCategories() { 461 if (twoDCategories == null) { 462 makeCategories(); 463 } 464 return twoDTimeSeriesCategories; 465 } 466 467 468 /** 469 * Create the set of {@link ucar.unidata.data.DataChoice} that represent 470 * the data held by this data source. We create one top-level 471 * {@link ucar.unidata.data.CompositeDataChoice} that represents 472 * all of the image time steps. We create a set of children 473 * {@link ucar.unidata.data.DirectDataChoice}, one for each time step. 474 */ 475 public void doMakeDataChoices() { 476 if (this.frameList == null) return; 477 CompositeDataChoice composite = new CompositeDataChoice(this, 478 getFrameNumbers(), getName(), 479 getDataName(), 480 (this.frameList.size() > 1) 481 ? getTwoDTimeSeriesCategories() 482 : getTwoDCategories()) { 483 public List getSelectedDateTimes() { 484 return dataSource.getSelectedDateTimes(); 485 } 486 }; 487 addDataChoice(composite); 488 doMakeDataChoices(composite); 489 } 490 491 /** 492 * Make the data choices and add them to the given composite 493 * 494 * @param composite The parent data choice to add to 495 */ 496 private void doMakeDataChoices(CompositeDataChoice composite) { 497 int cnt = 0; 498 List frameNos = new ArrayList(); 499 List frameChoices = new ArrayList(); 500 for (Iterator iter = frameList.iterator(); iter.hasNext(); ) { 501 Object object = iter.next(); 502 McIdasFrame frame = getFrame(object); 503 String name = frame.toString(); 504 DataSelection frameSelect = null; 505 Integer frameNo = frame.getFrameNumber(); 506 if (frameNo != null) { 507 frameNos.add(frameNo); 508 //We will create the data choice with an index, not with the actual frame number. 509 frameSelect = new DataSelection(Misc.newList(new Integer(cnt))); 510 } 511 frameSelect = null; 512 DataChoice choice = 513 new DirectDataChoice(this, new FrameDataInfo(cnt, frame), 514 composite.getName(), name, 515 getTwoDCategories(), frameSelect); 516 cnt++; 517 frameChoices.add(choice); 518 } 519 520 //Sort the data choices. 521 composite.replaceDataChoices(sortChoices(frameChoices)); 522 } 523 524 /** 525 * Sort the list of data choices on their frame numbers 526 * 527 * @param choices The data choices 528 * 529 * @return The data choices sorted 530 */ 531 private List sortChoices(List choices) { 532 Object[] choicesArray = choices.toArray(); 533 /* 534 Comparator comp = new Comparator() { 535 public int compare(Object o1, Object o2) { 536 McIdasFrameDescriptor fd1 = getDescriptor(o1); 537 McIdasFrameDescriptor fd2 = getDescriptor(o2); 538 return fd1.getFrameNumber().compareTo(fd2.getFrameNumber()); 539 } 540 }; 541 Arrays.sort(choicesArray, comp); 542 */ 543 return new ArrayList(Arrays.asList(choicesArray)); 544 } 545 546 /** 547 * A utility method that helps us deal with legacy bundles that used to 548 * have String file names as the id of a data choice. 549 * 550 * @param object May be an AddeImageDescriptor (for new bundles) or a 551 * String that is converted to an image descriptor. 552 * @return The image descriptor. 553 */ 554 private McIdasFrame getFrame(Object object) { 555 if (object == null) { 556 return null; 557 } 558 559 if (object instanceof McIdasFrame) { 560 return (McIdasFrame) object; 561 } 562 563 return new McIdasFrame(); 564 } 565 566 /** 567 * Class FrameDataInfo Holds an index and a McIdasFrame 568 */ 569 public class FrameDataInfo { 570 571 /** The index */ 572 private int index; 573 574 /** The FD */ 575 private McIdasFrame frame; 576 577 /** 578 * Ctor for xml encoding 579 */ 580 public FrameDataInfo() {} 581 582 /** 583 * CTOR 584 * 585 * @param index The index 586 * @param fd The fd 587 */ 588 public FrameDataInfo(int index, McIdasFrame frame) { 589 this.index = index; 590 this.frame = frame; 591 } 592 593 /** 594 * Get the index 595 * 596 * @return The index 597 */ 598 public int getIndex() { 599 return index; 600 } 601 602 /** 603 * Set the index 604 * 605 * @param v The index 606 */ 607 public void setIndex(int v) { 608 index = v; 609 } 610 611 /** 612 * Get the frame 613 * 614 * @return The frame 615 */ 616 public McIdasFrame getFrame() { 617 return frame; 618 } 619 620 /** 621 * Set the frame 622 * 623 * @param v The frame 624 */ 625 public void setFrame(McIdasFrame v) { 626 frame = v; 627 } 628 629 /** 630 * toString 631 * 632 * @return toString 633 */ 634 public String toString() { 635 return "index: " + index + ", frame: " + frame.getFrameNumber(); 636 } 637 638 } 639 640 public SingleBandedImage getMcIdasFrame(int frameNumber, 641 FrameComponentInfo frameComponentInfo, 642 FrameDirtyInfo frameDirtyInfo) 643 throws VisADException, RemoteException { 644 /* 645 System.out.println("McIdasXDataSource getMcIdasFrame:"); 646 System.out.println(" frameNumber=" + frameNumber); 647 System.out.println(" frameComponentInfo=" + frameComponentInfo); 648 System.out.println(" frameDirtyInfo=" + frameDirtyInfo); 649 */ 650 FlatField image_data = null; 651 SingleBandedImage field = null; 652 653 if (frameNumber < 1) return field; 654 655 // Get the appropriate frame out of the list 656 McIdasFrame frm = getFrame(frameNumber); 657 658 // Tell the frame once whether or not to refresh cached data 659 frm.setRefreshData(frameDirtyInfo.getDirtyImage() || frameDirtyInfo.getDirtyColorTable()); 660 661 FrameDirectory fd = frm.getFrameDirectory(frameDirtyInfo.getDirtyImage()); 662 int[] nav = fd.getFrameNav(); 663 int[] aux = fd.getFrameAux(); 664 665 if (nav[0] == 0) return field; 666 667 // Set the time of the frame. Because IDV uses time-based ordering, give the user the option 668 // of "faking" the date/time by using frame number for year. This preserves -X frame ordering. 669 Date nominal_time; 670 if (!frameComponentInfo.getFakeDateTime()) { 671 nominal_time = fd.getNominalTime(); 672 } 673 else { 674 Calendar calendarDate = new GregorianCalendar(frameNumber, Calendar.JANUARY, 1, 0, 0, 0); 675 calendarDate.setTimeZone(TimeZone.getTimeZone("UTC")); 676 nominal_time = calendarDate.getTime(); 677 } 678 679 int height = frm.getLineSize(frameDirtyInfo.getDirtyImage()); 680 if (height < 0) return field; 681 int width = frm.getElementSize(frameDirtyInfo.getDirtyImage()); 682 if (width < 0) return field; 683 684 // check for frameComponentInfo.isColorTable == true 685 if (frameComponentInfo.getIsColorTable()) { 686 DataContext dataContext = getDataContext(); 687 ColorTableManager colorTableManager = ((IntegratedDataViewer)dataContext).getColorTableManager(); 688 List dcl = ((IntegratedDataViewer)dataContext).getDisplayControls(); 689 DisplayControlImpl dc = null; 690 for (int i=dcl.size()-1; i>=0; i--) { 691 DisplayControlImpl dci = (DisplayControlImpl)dcl.get(i); 692 if (dci instanceof ImageSequenceControl) { 693 dc = dci; 694 break; 695 } 696 } 697 ColorTable mcidasXColorTable = frm.getColorTable(frameDirtyInfo.getDirtyColorTable()); 698 // TODO: Add a transparent value to the color table when only graphics were requested 699 /* 700 // if image wasn't requested, make color table with entry 0 as transparent 701 if (!frameComponentInfo.getIsImage()) { 702 float[][] mcidasXColorTableAlpha = mcidasXColorTable.getAlphaTable(); 703 mcidasXColorTableAlpha[3][0] = 0.0f; 704 mcidasXColorTable.setTable(mcidasXColorTableAlpha); 705 } 706 */ 707 colorTableManager.addUsers(mcidasXColorTable); 708 dc.setColorTable("default", mcidasXColorTable); 709 } 710 711 // check for frameComponentInfo.isAnnotation == true 712 int skip = 0; 713 if (!frameComponentInfo.getIsAnnotation()) { 714 skip = 12; 715 } 716 height = height - skip; 717 718 values = new double[1][width*height]; 719 720 // check for frameComponentInfo.isImage == true 721 if (frameComponentInfo.getIsImage()) { 722 byte[] image = frm.getImageData(frameDirtyInfo.getDirtyImage()); 723 double pixel; 724 for (int i=0; i<width*height; i++) { 725 pixel = (double)image[i]; 726 if (pixel < 0.0) pixel += 256.0; 727 values[0][i] = pixel; 728 } 729 } 730 else { 731 for (int i=0; i<width*height; i++) { 732 // TODO: Use a special value that is transparent in the color table 733 values[0][i] = 0.0; 734 } 735 } 736 737 // check for frameComponentInfo.isGraphics == true 738 if (frameComponentInfo.getIsGraphics()) { 739 byte[] graphics = frm.getGraphicsData(frameDirtyInfo.getDirtyGraphics()); 740 for (int i=0; i<width*height; i++) { 741 if (graphics[i] != (byte)255) { 742 values[0][i] = (double)graphics[i]; 743 } 744 } 745 } 746 747 // Done working with the frame, put it back in the list 748 setFrame(frameNumber, frm); 749 750 // fake an area directory 751 int[] adir = new int[64]; 752 adir[5] = fd.getULLine(); 753 adir[6] = fd.getULEle(); 754 adir[8] = height; 755 adir[9] = width; 756 adir[11] = fd.getLineRes(); 757 adir[12] = fd.getEleRes(); 758 759 AREACoordinateSystem cs; 760 try { 761 cs = new AREACoordinateSystem( adir, nav, aux); 762 } catch (Exception e) { 763 System.out.println("AREACoordinateSystem exception: " + e); 764 return field; 765 } 766 767 /* 768 double[][] linele = new double[2][4]; 769 double[][] latlon = new double[2][4]; 770 // LR 771 linele[0][0] = (double)(width-1); 772 linele[1][0] = 0.0; 773 // UL 774 linele[0][1] = 0.0; 775 linele[1][1] = (double)(height-1); 776 // LL 777 linele[0][2] = 0.0; 778 linele[1][2] = 0.0; 779 // UR 780 linele[0][3] = (double)(width-1); 781 linele[1][3] = (double)(height-1); 782 783 latlon = cs.toReference(linele); 784 System.out.println("linele: " + linele[0][0] + " " + linele[1][0] + " " + 785 linele[0][1] + " " + linele[1][1] + " " + 786 linele[0][2] + " " + linele[1][2] + " " + 787 linele[0][3] + " " + linele[1][3]); 788 System.out.println("latlon: " + latlon[0][0] + " " + latlon[1][0] + " " + 789 latlon[0][1] + " " + latlon[1][1] + " " + 790 latlon[0][2] + " " + latlon[1][2] + " " + 791 latlon[0][3] + " " + latlon[1][3]); 792 */ 793 794 RealType[] domain_components = {RealType.getRealType("ImageElement", null, null), 795 RealType.getRealType("ImageLine", null, null)}; 796 RealTupleType image_domain = 797 new RealTupleType(domain_components, cs, null); 798 799 // Image numbering is usually the first line is at the "top" 800 // whereas in VisAD, it is at the bottom. So define the 801 // domain set of the FlatField to map the Y axis accordingly 802 Linear2DSet domain_set = new Linear2DSet(image_domain, 803 0, (width - 1), width, 804 (height - 1), 0, height ); 805 RealType range = RealType.getRealType("brightness"); 806 807 FunctionType image_func = new FunctionType(image_domain, range); 808 809 // now, define the Data objects 810 image_data = new FlatField(image_func, domain_set); 811 DateTime date = new DateTime(nominal_time); 812 image_data = new NavigatedImage(image_data, date, "McIdas Image"); 813 814 // put the data values into the FlatField image_data 815 image_data.setSamples(values,false); 816 field = (SingleBandedImage) image_data; 817 818 return field; 819 } 820 821 }