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