Example #1
0
  /** create parallel coordinates display for data */
  public static void parallel(DisplayImpl display, FlatField data)
      throws VisADException, RemoteException {

    FunctionType ftype = (FunctionType) data.getType();
    RealType index = (RealType) ftype.getDomain().getComponent(0);
    RealTupleType range = (RealTupleType) ftype.getRange();
    int ncoords = range.getDimension();
    int nrows = data.getLength();
    Set index_set = data.getDomainSet();
    float[][] samples = data.getFloats(false);

    RealType x = RealType.getRealType("coordinate");
    RealType y = RealType.getRealType("value");
    SetType xy = new SetType(new RealTupleType(x, y));
    FunctionType ptype = new FunctionType(index, xy);
    FieldImpl pfield = new FieldImpl(ptype, index_set);
    for (int j = 0; j < nrows; j++) {
      float[][] locs = new float[2][ncoords];
      for (int i = 0; i < ncoords; i++) {
        locs[0][i] = i;
        locs[1][i] = samples[i][j];
      }
      Gridded2DSet set = new Gridded2DSet(xy, locs, ncoords);
      pfield.setSample(j, set, false);
    }

    // create a DataReference for river system
    DataReference parallel_ref = new DataReferenceImpl("parallel");
    parallel_ref.setData(pfield);

    display.addMap(new ScalarMap(x, Display.XAxis));
    display.addMap(new ScalarMap(y, Display.YAxis));

    // enable axis scales
    display.getGraphicsModeControl().setScaleEnable(true);

    // link display to parallel display
    display.addReference(parallel_ref);
  }
Example #2
0
  /**
   * 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");
  }
Example #3
0
  /**
   * Create a front from the curve
   *
   * @param curve the curve coordinates
   * @param flip true to flip the pips
   * @return The front as a FieldImpl
   * @throws RemoteException On badness
   * @throws VisADException On badness
   */
  private FieldImpl curveToFront(float[][] curve, boolean flip)
      throws VisADException, RemoteException {

    if (flipTheFlip) {
      flip = !flip;
    }

    // compute various scaling factors
    int len = curve[0].length;
    if (len < 2) {
      return null;
    }
    float[] seg_length = new float[len - 1];
    float curve_length = curveLength(curve, seg_length);
    float delta = curve_length / (len - 1);
    // curve[findex] where
    // float findex = ibase + mul * repeat_shapes[shape][0][j]
    float mul = rprofile_length * zoom / rsegment_length;
    // curve_perp[][findex] * ratio * repeat_shapes[shape][1][j]
    float ratio = delta * mul;

    // compute unit perpendiculars to curve
    float[][] curve_perp = new float[2][len];
    for (int i = 0; i < len; i++) {
      int im = i - 1;
      int ip = i + 1;
      if (im < 0) {
        im = 0;
      }
      if (ip > len - 1) {
        ip = len - 1;
      }
      float yp = curve[0][ip] - curve[0][im];
      float xp = curve[1][ip] - curve[1][im];
      xp = -xp;
      float d = (float) Math.sqrt(xp * xp + yp * yp);
      if (flip) {
        d = -d;
      }
      xp = xp / d;
      yp = yp / d;
      curve_perp[0][i] = xp;
      curve_perp[1][i] = yp;
    }

    // build Vector of FlatFields for each shape of each segment
    Vector inner_field_vector = new Vector();
    for (int segment = 0; true; segment++) {

      // curve[findex] where
      // float findex = ibase + mul * repeat_shapes[shape][0][j]
      float segment_length = (segment == 0) ? fsegment_length : rsegment_length;
      int profile_length = (segment == 0) ? fprofile_length : rprofile_length;
      mul = profile_length * zoom / segment_length;
      // curve_perp[][findex] * ratio * repeat_shapes[shape][1][j]
      // float ratio = delta * mul;

      // figure out if clipping is needed for this segment
      // only happens for last segment
      boolean clip = false;
      float xclip = 0.0f;
      // int ibase = segment * profile_length;
      int ibase = (segment == 0) ? 0 : fprofile_length + (segment - 1) * rprofile_length;
      int iend = ibase + profile_length;
      if (ibase > len - 1) {
        break;
      }
      if (iend > len - 1) {
        clip = true;
        iend = len - 1;
        xclip = (iend - ibase) / mul;
      }

      // set up shapes for first or repeating segment
      int nshapes = nrshapes;
      float[][][] shapes = repeat_shapes;
      int[][][] tris = repeat_tris;
      float[] red = repeat_red;
      float[] green = repeat_green;
      float[] blue = repeat_blue;
      if (segment == 0) {
        nshapes = nfshapes;
        shapes = first_shapes;
        tris = first_tris;
        red = first_red;
        green = first_green;
        blue = first_blue;
      }

      // iterate over shapes for segment
      for (int shape = 0; shape < nshapes; shape++) {
        float[][] samples = shapes[shape];
        int[][] ts = tris[shape];
        /*
        // if needed, clip shape
        if (clip) {
        float[][][] outs = new float[1][][];
        int[][][] outt = new int[1][][];
        DelaunayCustom.clip(samples, ts, 1.0f, 0.0f, xclip, outs, outt);
        samples = outs[0];
        ts = outt[0];
        }
        */
        if ((samples == null) || (samples[0].length < 1)) {
          break;
        }

        float[][] ss = mapShape(samples, len, ibase, mul, ratio, curve, curve_perp);

        // **** get rid of previous calls to fill() ****
        ts = DelaunayCustom.fill(ss);

        // jeffmc: For now don't clip. This seems to fix the problem of too short a front
        boolean DOCLIP = false;
        if (clip && DOCLIP) {
          float[][] clip_samples = {
            {xclip, xclip, xclip - CLIP_DELTA},
            {CLIP_DELTA, -CLIP_DELTA, 0.0f}
          };
          float[][] clip_ss = mapShape(clip_samples, len, ibase, mul, ratio, curve, curve_perp);
          // now solve for:
          //   xc * clip_samples[0][0] + yc * clip_samples[1][0] = 1
          //   xc * clip_samples[0][1] + yc * clip_samples[1][1] = 1
          //   xc * clip_samples[0][2] + yc * clip_samples[1][2] < 1
          float det =
              (clip_samples[0][1] * clip_samples[1][0] - clip_samples[0][0] * clip_samples[1][1]);
          float xc = (clip_samples[1][0] - clip_samples[1][1]) / det;
          float yc = (clip_samples[0][1] - clip_samples[0][0]) / det;
          float v = 1.0f;
          if (xc * clip_samples[0][2] + yc * clip_samples[1][2] > v) {
            xc = -xc;
            yc = -yc;
            v = -v;
          }

          float[][][] outs = new float[1][][];
          int[][][] outt = new int[1][][];
          DelaunayCustom.clip(ss, ts, xc, yc, v, outs, outt);
          ss = outs[0];
          ts = outt[0];
        }

        if (ss == null) {
          break;
        }
        int n = ss[0].length;

        // create color values for field
        float[][] values = new float[3][n];
        float r = red[shape];
        float g = green[shape];
        float b = blue[shape];
        for (int i = 0; i < n; i++) {
          values[0][i] = r;
          values[1][i] = g;
          values[2][i] = b;
        }

        // construct set and field
        DelaunayCustom delaunay = new DelaunayCustom(ss, ts);
        Irregular2DSet set = new Irregular2DSet(curve_type, ss, null, null, null, delaunay);
        FlatField field = new FlatField(front_inner, set);
        field.setSamples(values, false);
        inner_field_vector.addElement(field);
        // some crazy bug - see Gridded3DSet.makeNormals()
      } // end for (int shape=0; shape<nshapes; shape++)
    } // end for (int segment=0; true; segment++)

    int nfields = inner_field_vector.size();
    Integer1DSet iset = new Integer1DSet(front_index, nfields);
    FieldImpl front = new FieldImpl(front_type, iset);
    FlatField[] fields = new FlatField[nfields];
    for (int i = 0; i < nfields; i++) {
      fields[i] = (FlatField) inner_field_vector.elementAt(i);
    }
    front.setSamples(fields, false);
    return front;
  }
Example #4
0
  /**
   * 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;
  }