/** * Load the volume data to the display * * @throws RemoteException problem loading remote data * @throws VisADException problem loading the data */ private void loadVolumeData() throws VisADException, RemoteException { Trace.call1("VRC.loadVolumeData"); FieldImpl grid = getGridDataInstance().getGrid(); FieldImpl newGrid = grid; if (getSkipValue() > 0) { grid = GridUtil.subset(grid, getSkipValue() + 1); newGrid = grid; } if (!usePoints) { // make sure the projection is correct before we start // transforming the data setProjectionInView(true, true); CoordinateSystem cs = getNavigatedDisplay().getDisplayCoordinateSystem(); if ((cs != null) && (getNavigatedDisplay() instanceof MapProjectionDisplay)) { try { if (GridUtil.isConstantSpatialDomain(grid)) { newGrid = makeLinearGrid(grid, cs); } else { Set timeSet = GridUtil.getTimeSet(grid); for (int i = 0; i < timeSet.getLength(); i++) { FieldImpl timeField = makeLinearGrid((FieldImpl) grid.getSample(i, false), cs); if (i == 0) { FunctionType ft = new FunctionType( ((SetType) timeSet.getType()).getDomain(), timeField.getType()); newGrid = new FieldImpl(ft, timeSet); } newGrid.setSample(i, timeField, false); } } } catch (VisADException ve) { ve.printStackTrace(); userErrorMessage( "Can't render volume for " + paramName + " in this projection. Try using the data projection"); newGrid = grid; } } } Trace.call1("VRC.loadVolumeData.loadData"); myDisplay.loadData(newGrid); Trace.call2("VRC.loadVolumeData.loadData"); Trace.call2("loadVolumeData"); }
/** * A utility method that will wait until all displays are finished being created. This looks at * the DisplayControls, data sources, global wait cursor count, the visad thread pool and looks at * any active java3d threads * * @param uiManager The ui manager. We use this to access the wait cursor count * @param timeToWait (milliseconds) elapsed time to wait for nothing to be active */ public static void waitUntilDisplaysAreDone(IdvUIManager uiManager, long timeToWait) { Trace.call1("Waiting on displays"); int successiveTimesWithNoActive = 0; int sleepTime = 10; long firstTime = System.currentTimeMillis(); int cnt = 0; while (true) { boolean cursorCount = (uiManager.getWaitCursorCount() > 0); boolean actionCount = ActionImpl.getTaskCount() > 0; boolean dataActive = DataSourceImpl.getOutstandingGetDataCalls() > 0; boolean anyJ3dActive = anyJava3dThreadsActive(); boolean allDisplaysInitialized = uiManager.getIdv().getAllDisplaysIntialized(); // System.err.println ("\tAll displays init:" + allDisplaysInitialized +" cursor // cnt:" + uiManager.getWaitCursorCount() + " action cnt:" +actionCount + " data active: " + // dataActive); // if ((cnt++) % 30 == 0) { // System.err.println ("\tcnt:" + uiManager.getWaitCursorCount() + " " // +actionCount + " " + dataActive); // } boolean anyActive = actionCount || cursorCount || dataActive || !allDisplaysInitialized || anyJ3dActive; if (dataActive) { firstTime = System.currentTimeMillis(); } if (anyActive) { successiveTimesWithNoActive = 0; } else { successiveTimesWithNoActive++; } if ((timeToWait == 0) && !anyActive) { break; } if (successiveTimesWithNoActive * sleepTime > timeToWait) { break; } Misc.sleep(sleepTime); // At most wait 120 seconds if (System.currentTimeMillis() - firstTime > 120000) { System.err.println("Error waiting for to be done:" + LogUtil.getStackDump(false)); return; } } Trace.call2("Waiting on displays"); }
/** * Add the new view manager into the list if we don't have one with the {@link ViewDescriptor} of * the new view manager already. * * @param newViewManager The new view manager */ public void addViewManager(ViewManager newViewManager) { ViewManager vm = findViewManagerInList(newViewManager.getViewDescriptor()); if (vm == null) { synchronized (viewManagers) { viewManagers.add(newViewManager); } try { Trace.call1("VMManager calling ViewManager.init"); newViewManager.init(); Trace.call2("VMManager calling ViewManager.init"); } catch (Exception exc) { logException("Adding view manager", exc); } setLastActiveViewManager(newViewManager); } getIdvUIManager().viewManagerAdded(newViewManager); }
/** * Make a grid with a Linear3DSet for the volume rendering * * @param grid grid to transform * @param cs coordinate system to transform to XYZ * @return transformed grid * @throws RemoteException Java RMI Exception * @throws VisADException problem creating grid */ private FieldImpl makeLinearGrid(FieldImpl grid, CoordinateSystem cs) throws VisADException, RemoteException { Trace.call1("VRC.makeLinearGrid"); GriddedSet domainSet = (GriddedSet) GridUtil.getSpatialDomain(grid); SampledSet ss = null; boolean latLonOrder = GridUtil.isLatLonOrder(domainSet); // System.out.println("grid is latLonOrder " + latLonOrder); Trace.call1("VRC.convertDomain"); if (latLonOrder) { ss = Util.convertDomain(domainSet, RealTupleType.LatitudeLongitudeAltitude, null); } else { ss = Util.convertDomain(domainSet, RealTupleType.SpatialEarth3DTuple, null); } Trace.call2("VRC.convertDomain"); float[][] refVals = ss.getSamples(true); MapProjectionDisplay mpd = (MapProjectionDisplay) getNavigatedDisplay(); MapProjection mp = mpd.getMapProjection(); boolean mapLatLonOrder = mp.isLatLonOrder(); // System.out.println("map is latLonOrder " + mapLatLonOrder); float[][] newVals = (latLonOrder) ? refVals : new float[][] {refVals[1], refVals[0], refVals[2]}; Trace.call1("VRC.toRef"); newVals = cs.toReference(newVals); Trace.call2("VRC.toRef"); Trace.call1("VRC.scaleVerticalValues"); newVals[2] = mpd.scaleVerticalValues(newVals[2]); Trace.call2("VRC.scaleVerticalValues"); int[] lengths = domainSet.getLengths(); // Misc.printArray("lengths",lengths); GriddedSet xyzSet = GriddedSet.create( RealTupleType.SpatialCartesian3DTuple, newVals, domainSet.getLengths(), (CoordinateSystem) null, (Unit[]) null, (ErrorEstimate[]) null, false, true); Trace.call1("VRC.setSpatialDomain"); FieldImpl newGrid = GridUtil.setSpatialDomain(grid, xyzSet); // , true); Trace.call2("VRC.setSpatialDomain"); float[] lows = xyzSet.getLow(); float[] highs = xyzSet.getHi(); // Misc.printArray("lows",lows); // Misc.printArray("highs",highs); Linear3DSet volumeXYZ = new Linear3DSet( RealTupleType.SpatialCartesian3DTuple, lows[0], highs[0], lengths[0], lows[1], highs[1], lengths[1], lows[2], highs[2], lengths[2]); // System.out.println(volumeXYZ); Trace.call1("VRC.resampleGrid"); newGrid = GridUtil.resampleGrid(newGrid, volumeXYZ); Trace.call2("VRC.resampleGrid"); Trace.call2("VRC.makeLinearGrid"); return newGrid; }
/** * Actually get the data identified by the given DataChoce. The default is to call the * getDataInner that does not take the requestProperties. This allows other, non unidata.data * DataSource-s (that follow the old API) to work. * * @param dataChoice The data choice that identifies the requested data. * @param category The data category of the request. * @param dataSelection Identifies any subsetting of the data. * @param requestProperties Hashtable that holds any detailed request properties. * @return The visad.Data object * @throws RemoteException Java RMI problem * @throws VisADException VisAD problem */ protected Data getDataInner( DataChoice dataChoice, DataCategory category, DataSelection dataSelection, Hashtable requestProperties) throws VisADException, RemoteException { loadId = JobManager.getManager().stopAndRestart(loadId, "WMSControl"); Object myLoadId = loadId; if (requestProperties == null) { requestProperties = new Hashtable(); } WmsSelection wmsInfo = (WmsSelection) dataChoice.getId(); // Look if there was a layer that overrides the one in the data choice Object tfoLayer = requestProperties.get(PROP_LAYER); if ((tfoLayer != null) && (tfoLayer instanceof TwoFacedObject)) { String layer = ((TwoFacedObject) tfoLayer).getId().toString(); for (int i = 0; i < wmsSelections.size(); i++) { WmsSelection tmpSelection = (WmsSelection) wmsSelections.get(i); if (Misc.equals(tmpSelection.getLayer(), layer)) { wmsInfo = tmpSelection; break; } } } GeoLocationInfo boundsToUse = (GeoLocationInfo) requestProperties.get(PROP_BOUNDS); Image image = null; FieldImpl xyData = null; byte[] imageContent = null; // System.err.println(wmsInfo.getImageFile()); if (wmsInfo.getImageFile() != null) { try { boundsToUse = new GeoLocationInfo(90, -180, -90, 180); InputStream is = IOUtil.getInputStream(wmsInfo.getImageFile()); imageContent = IOUtil.readBytes(is, myLoadId); image = Toolkit.getDefaultToolkit().createImage(imageContent); // javax.swing.JLabel l = new javax.swing.JLabel(new // javax.swing.ImageIcon(image)); // l.setBackground(Color.red); // ucar.unidata.util.GuiUtils.showOkCancelDialog(null,null, l,null); xyData = ucar.visad.Util.makeField(image, 0, false, true); } catch (Exception iexc) { logException("There was an error accessing the image:\n" + wmsInfo.getImageFile(), iexc); return null; } } else { String writeFile = (String) requestProperties.get(PROP_WRITEFILE); int imageWidth = Misc.getProperty(requestProperties, PROP_IMAGEWIDTH, 800); int imageHeight = Misc.getProperty(requestProperties, PROP_IMAGEHEIGHT, -1); double resolution = Misc.getProperty(requestProperties, PROP_RESOLUTION, (float) 1.0); if (wmsInfo.getLegendIcon() != null) { requestProperties.put(PROP_ICONPATH, wmsInfo.getLegendIcon()); } if (!wmsInfo.getAllowSubsets() || (boundsToUse == null)) { boundsToUse = wmsInfo.getBounds(); } else { boundsToUse.rectify(wmsInfo.getBounds(), 0.0); boundsToUse.snapToGrid(); boundsToUse.rectify(wmsInfo.getBounds(), 0.0); } double widthDegrees = boundsToUse.getMaxLon() - boundsToUse.getMinLon(); double heightDegrees = boundsToUse.getMaxLat() - boundsToUse.getMinLat(); if ((widthDegrees == 0) || (heightDegrees == 0)) { return null; } if (wmsInfo.getFixedWidth() > -1) { imageWidth = wmsInfo.getFixedWidth(); } if (wmsInfo.getFixedHeight() > -1) { imageHeight = wmsInfo.getFixedHeight(); } else { if (imageHeight < 0) { imageHeight = Math.abs((int) (imageWidth * boundsToUse.getDegreesY() / boundsToUse.getDegreesX())); } } imageWidth = Math.min(Math.max(imageWidth, 50), 2056); imageHeight = Math.min(Math.max(imageHeight, 50), 2056); if (maintainRatio) { imageHeight = (int) (imageWidth * (heightDegrees / widthDegrees)); } double diff = Math.abs(boundsToUse.getMinLon() - boundsToUse.getMaxLon()); String url = wmsInfo.assembleRequest( boundsToUse, (int) (imageWidth / resolution), (int) (imageHeight / resolution)); String cacheGroup = "WMS"; synchronized (cachedUrls) { if (writeFile == null) { for (int i = 0; i < cachedUrls.size(); i++) { if (url.equals(cachedUrls.get(i))) { image = (Image) cachedData.get(i); break; } } } } try { if (image == null) { if (Misc.equals(url, lastUrl) && (lastImageContent != null)) { imageContent = lastImageContent; } else { } if (imageContent == null) { long t1 = System.currentTimeMillis(); // System.err.println("getting image:" + url); LogUtil.message("Reading WMS image: " + wmsInfo); // System.err.println ("url:" + url); InputStream is = IOUtil.getInputStream(url); long t2 = System.currentTimeMillis(); imageContent = IOUtil.readBytes(is, myLoadId); long t3 = System.currentTimeMillis(); LogUtil.message(""); // System.err.println("Done"); } // If it is null then there is another thread that is doing // a subsequent read lastImageContent = null; if (imageContent == null) { return null; } Trace.call2("Getting image"); Trace.call1("Making image"); image = Toolkit.getDefaultToolkit().createImage(imageContent); // Wait on the image image = ucar.unidata.ui.ImageUtils.waitOnImage(image); if (image == null) { throw new IllegalStateException(); } Trace.call2("Making image"); lastImageContent = imageContent; lastUrl = url; updateDetailsText(); if (!JobManager.getManager().canContinue(myLoadId)) { Trace.call2("WMSControl.loadImage"); return null; } synchronized (cachedUrls) { if (cachedUrls.size() > 5) { cachedUrls.remove(cachedUrls.size() - 1); cachedData.remove(cachedData.size() - 1); } // For now don't cache // cachedUrls.add(0, url); // cachedData.add(0, image); } } ImageHelper ih = new ImageHelper(); int width = image.getWidth(ih); if (ih.badImage) { throw new IllegalStateException(); } long tt1 = System.currentTimeMillis(); xyData = ucar.visad.Util.makeField(image, 0, false, true); long tt2 = System.currentTimeMillis(); // System.err.println("time to make field:" + (tt2-tt1)); } catch (Exception iexc) { if (imageContent != null) { String msg = new String(imageContent); // System.err.println ("msg:" + msg); /* Check to see if this is of the form: <?xml version='1.0' encoding="UTF-8" standalone="no" ?> <!DOCTYPE ServiceExceptionReport SYSTEM "http://www.digitalearth.gov/wmt/xml/exception_1_1_0.dtd "> <ServiceExceptionReport version="1.1.0"> <ServiceException> Service denied due to system overload. Please try again later. </ServiceException> </ServiceExceptionReport> */ if (msg.indexOf("<ServiceExceptionReport") >= 0) { try { StringBuffer errors = new StringBuffer(); errors.append("\n"); Element root = XmlUtil.getRoot(msg); List children = XmlUtil.findChildren(root, "ServiceException"); for (int i = 0; i < children.size(); i++) { Element node = (Element) children.get(i); String code = XmlUtil.getAttribute(node, "code", (String) null); String body = XmlUtil.getChildText(node); if (code != null) { errors.append(code + "\n"); } errors.append(body.trim() + "\n"); } LogUtil.userErrorMessage( "Error accessing image with the url:\n" + url + "\nError:\n" + errors); } catch (Exception exc) { LogUtil.userErrorMessage( "Error accessing image with the url:\n" + url + "\nError:\n" + StringUtil.stripTags(msg)); } return null; } msg = StringUtil.replace(msg, "\n", " ").toLowerCase(); if (StringUtil.stringMatch(msg, "service\\s*exception")) { if (StringUtil.stringMatch(msg, "cannot\\s*be\\s*less\\s*than")) { return null; } } if (msg.indexOf("error") >= 0) { LogUtil.userErrorMessage( "There was an error accessing the image with the url:\n" + url + "\nError:\n" + new String(imageContent)); return null; } } logException("There was an error accessing the image with the url:\n" + url, iexc); return null; } if (writeFile != null) { try { ImageXmlDataSource.writeToFile(writeFile, boundsToUse, imageContent, wmsInfo.getFormat()); } catch (Exception exc) { throw new IllegalArgumentException( "Error writing image xml file:" + writeFile + " " + exc); } } } Linear2DSet domain = (Linear2DSet) xyData.getDomainSet(); Linear2DSet imageDomain = new Linear2DSet( RealTupleType.SpatialEarth2DTuple, boundsToUse.getMinLon(), boundsToUse.getMaxLon(), domain.getX().getLength(), boundsToUse.getMaxLat(), boundsToUse.getMinLat(), domain.getY().getLength()); // System.err.println("image domain:" + imageDomain); /* new Linear2DSet(RealTupleType.SpatialEarth2DTuple, boundsToUse.getMinLon(), boundsToUse.getMaxLon(), domain.getX().getLength(), boundsToUse.getMinLat() +diff, boundsToUse.getMinLat(), domain.getY().getLength());*/ FieldImpl field = GridUtil.setSpatialDomain(xyData, imageDomain, true); return field; }