Exemplo n.º 1
0
  /**
   * Get the data for the given DataChoice and selection criteria.
   *
   * @param dataChoice DataChoice for selection
   * @param category DataCategory for the DataChoice (not used)
   * @param subset subsetting criteria
   * @param requestProperties extra request properties
   * @return the Data object for the request
   * @throws RemoteException couldn't create a remote data object
   * @throws VisADException couldn't create the data
   */
  protected Data getDataInner(
      final DataChoice dataChoice,
      DataCategory category,
      final DataSelection subset,
      final Hashtable requestProperties)
      throws VisADException, RemoteException {

    try {
      List times = null;
      if (subset != null) {
        times = getTimesFromDataSelection(subset, dataChoice);
      }
      if (times == null) {
        times = dataChoice.getSelectedDateTimes();
      }

      List dtimes = subset.getTimeDriverTimes();

      if (dtimes != null && useDriverTime == false) {
        useDriverTime = true;
      }

      List<RadarAdapter> adapters = getAdapters();

      DateTime[] realDateTimes = new DateTime[adapters.size()];
      for (int i = 0; i < adapters.size(); i++) {
        realDateTimes[i] = ((RadarAdapter) adapters.get(i)).getBaseTime();
      }
      Arrays.sort(realDateTimes);
      // Flip it to get youngest date first
      boolean isRealTime = isRealTime();
      if (isRealTime) {
        realDateTimes =
            (DateTime[]) Misc.reverseArray(realDateTimes, new DateTime[realDateTimes.length]);
      }
      // if use time driver
      if (useDriverTime) {
        List tests = resetTimesList(realDateTimes, times);
        if (!compareTimeLists(times, tests)) {
          reloadData();
          adapters = getAdapters();

          realDateTimes = new DateTime[adapters.size()];
          for (int i = 0; i < adapters.size(); i++) {
            realDateTimes[i] = ((RadarAdapter) adapters.get(i)).getBaseTime();
          }
          Arrays.sort(realDateTimes);
          // Flip it to get youngest date first
          isRealTime = isRealTime();
          if (isRealTime) {
            realDateTimes =
                (DateTime[]) Misc.reverseArray(realDateTimes, new DateTime[realDateTimes.length]);
          }
          tests = resetTimesList(realDateTimes, times);
        }
        times = tests;
      }
      // if times are null, then that means all times
      DateTime[] dateTimes = null;

      if ((times == null) || (times.size() == 0)) {
        dateTimes = realDateTimes;
      } else {
        dateTimes = new DateTime[times.size()];
        for (int i = 0; i < times.size(); i++) {
          Object time = times.get(i);
          if (time instanceof TwoFacedObject) {
            int index = ((Integer) ((TwoFacedObject) time).getId()).intValue();
            dateTimes[i] = realDateTimes[index];
          } else if (time instanceof DateTime) {
            dateTimes[i] = (DateTime) time;
          }
        }
      }
      Arrays.sort(dateTimes);
      final Data[] datas = new Data[dateTimes.length];
      int timeIndex = 0;
      final MathType[] mt = {null};
      // create a new field of (Time -> (radar data)).
      // fill in the times array and data array with dates/data
      // only from those adapters which match the selected times.
      // if a data object is null, stick it in the list.
      // if all are null, then the MathType (mt) will never get set,
      // so return null.
      //            System.err.println ("Reading " + adapters.size() + " radar files");
      int cnt = 0;
      ThreadManager threadManager = new visad.util.ThreadManager("radar data reading");

      for (Iterator iter = adapters.iterator(); iter.hasNext(); ) {
        final RadarAdapter adapter = (RadarAdapter) iter.next();
        timeIndex = Arrays.binarySearch(dateTimes, adapter.getBaseTime());
        //              System.err.println ("timeIndex:" + timeIndex);
        if (timeIndex < 0) {
          continue;
        }
        cnt++;
        LogUtil.message("Time: " + (cnt) + "/" + dateTimes.length + " From:" + toString());
        final int theTimeIndex = timeIndex;
        threadManager.addRunnable(
            new visad.util.ThreadManager.MyRunnable() {
              public void run() throws Exception {
                Trace.call1("RDS.getData");
                Data d = adapter.getData(dataChoice, subset, requestProperties);
                Trace.call2("RDS.getData");
                datas[theTimeIndex] = d;
                if (d != null) {
                  mt[0] = d.getType();
                } else {
                }
              }
            });
      }

      try {
        // threadManager.debug = true;
        threadManager.runInParallel(getDataContext().getIdv().getMaxDataThreadCount());
      } catch (VisADException ve) {
        LogUtil.printMessage(ve.toString());
      }

      if (mt[0] == null) {
        return null;
      }

      FunctionType ft = new FunctionType(RealType.Time, mt[0]);
      SampledSet domainSet =
          (dateTimes.length == 1)
              ? (SampledSet) new SingletonSet(new RealTuple(dateTimes))
              : (SampledSet) DateTime.makeTimeSet(dateTimes);
      FieldImpl fi = new FieldImpl(ft, domainSet);
      fi.setSamples(datas, false);
      return fi;
    } catch (Exception exc) {
      logException("Creating obs", exc);
    }
    return null;
  }
Exemplo n.º 2
0
  /**
   * Get the data represented by this class. Calls makeObs, real work needs to be implemented there.
   *
   * @param dataChoice choice for data
   * @param category category of data
   * @param dataSelection subselection properties
   * @param requestProperties additional selection properties (not used here)
   * @return Data object representative of the choice
   * @throws RemoteException Java RMI error
   * @throws VisADException VisAD Error
   */
  protected Data getDataInner(
      DataChoice dataChoice,
      DataCategory category,
      DataSelection dataSelection,
      Hashtable requestProperties)
      throws VisADException, RemoteException {

    Object id = dataChoice.getId();
    // CompositeDataChoice

    // If it is a list then we are doing a grid field
    boolean doGriddedData = false;
    if (id instanceof List) {
      if (((List) id).get(0) instanceof Integer) {
        doGriddedData = true;
      }
    }
    if (doGriddedData) {
      List idList = (List) id;
      //            Integer   i          = (Integer) idList.get(0);
      RealType type = (RealType) idList.get(1);
      Hashtable properties = dataChoice.getProperties();
      if (properties == null) {
        properties = new Hashtable();
      }

      Data firstGuessData = null;
      boolean doFirstGuessField = false;
      if (idList.size() > 2) {
        doFirstGuessField = ((Boolean) idList.get(2)).booleanValue();
      }

      if (doFirstGuessField) {
        DataChoice firstGuessDataChoice = (DataChoice) dataChoice.getProperty(PROP_FIRSTGUESS);
        if (firstGuessDataChoice == null) {
          List operands = new ArrayList();
          List categories = DataCategory.parseCategories("GRID-2D-TIME;GRID-3D-TIME", false);
          operands.add(
              new DataOperand("First Guess Field", "First Guess Field", categories, false));
          List userValues = getDataContext().selectDataChoices(operands);
          if (userValues == null) {
            return null;
          }

          firstGuessDataChoice = (DataChoice) userValues.get(0);
          dataChoice.setObjectProperty(PROP_FIRSTGUESS, firstGuessDataChoice);
        }

        if (firstGuessDataChoice != null) {
          firstGuessData = firstGuessDataChoice.getData(null);
          if (firstGuessData == null) {
            return null;
          }
        }
      }

      // Merge the point obs
      properties.put(PROP_GRID_PARAM, type);
      FieldImpl pointObs = null;
      List datas = new ArrayList();
      for (int i = 0; i < sources.size(); i++) {
        DataChoice choice =
            new DirectDataChoice(
                this, new Integer(i), "", "", dataChoice.getCategories(), properties);
        pointObs = (FieldImpl) getDataInner(choice, category, dataSelection, requestProperties);
        if (pointObs != null) {
          datas.add(pointObs);
        }
      }
      if (datas.size() == 0) {
        return null;
      }
      pointObs = PointObFactory.mergeData(datas);
      if (pointObs == null) {
        return null;
      }

      // { minY, minX, maxY, maxX };
      float spacingX = this.gridX;
      float spacingY = this.gridY;
      int passes = this.numGridPasses;
      float gain = this.gridGain;
      float searchRadius = this.gridSearchRadius;
      Number tmp;
      tmp = (Float) dataSelection.getProperty(PROP_GRID_X);
      if (tmp != null) {
        spacingX = tmp.floatValue();
      }
      tmp = (Float) dataSelection.getProperty(PROP_GRID_Y);
      if (tmp != null) {
        spacingY = tmp.floatValue();
      }
      tmp = (Integer) dataSelection.getProperty(PROP_GRID_NUMPASSES);
      if (tmp != null) {
        passes = tmp.intValue();
      }
      String theUnit = (String) dataSelection.getProperty(PROP_GRID_UNIT);
      if (theUnit == null) {
        theUnit = this.gridUnit;
      }
      tmp = (Float) dataSelection.getProperty(PROP_GRID_GAIN);
      if (tmp != null) {
        gain = tmp.floatValue();
      }
      tmp = (Float) dataSelection.getProperty(PROP_GRID_SEARCH_RADIUS);
      if (tmp != null) {
        searchRadius = tmp.floatValue();
      }

      float degreesX = 0, degreesY = 0;
      pointObs = PointObFactory.makeTimeSequenceOfPointObs(pointObs);
      if (theUnit.equals(SPACING_COMPUTE) || (spacingX <= 0) || (spacingY <= 0)) {
        degreesX = PointObFactory.OA_GRID_DEFAULT;
        degreesY = PointObFactory.OA_GRID_DEFAULT;
        if ((searchRadius == DEFAULT_RADIUS) && (firstGuessData == null)) {
          searchRadius = PointObFactory.OA_GRID_DEFAULT;
        }
      } else if (theUnit.equals(SPACING_POINTS)) {
        double[] bbox = PointObFactory.getBoundingBox(pointObs);
        float spanX = (float) Math.abs(bbox[1] - bbox[3]);
        float spanY = (float) Math.abs(bbox[0] - bbox[2]);
        degreesX = spanX / (int) spacingX;
        degreesY = spanY / (int) spacingY;
      } else if (theUnit.equals(SPACING_DEGREES)) {
        degreesX = spacingX;
        degreesY = spacingY;
      }
      Barnes.AnalysisParameters ap =
          new Barnes.AnalysisParameters(degreesX, degreesY, searchRadius, 0.0d);
      log_.debug(
          "X = "
              + degreesX
              + " Y = "
              + degreesY
              + " unit = "
              + theUnit
              + " gain = "
              + gain
              + " search = "
              + searchRadius);

      LogUtil.message("Doing Barnes Analysis");
      FieldImpl fi =
          PointObFactory.barnes(
              pointObs,
              type,
              degreesX,
              degreesY,
              passes,
              gain,
              searchRadius,
              ap,
              (FieldImpl) firstGuessData);
      if (ap.getGridXArray() != null) {
        log_.debug(
            "Analysis params: X = "
                + ap.getGridXArray().length
                + " Y = "
                + ap.getGridYArray().length
                + " search = "
                + ap.getScaleLengthGU()
                + " random = "
                + ap.getRandomDataSpacing());
      }
      return fi;
    }

    GeoSelection geoSelection = ((dataSelection != null) ? dataSelection.getGeoSelection() : null);
    GeoLocationInfo bbox = ((geoSelection == null) ? null : geoSelection.getBoundingBox());

    LatLonRect llr = ((bbox != null) ? bbox.getLatLonRect() : null);

    FieldImpl retField = null;
    try {
      // List choices = (List) dataChoice.getId();
      List choices =
          (dataChoice instanceof CompositeDataChoice)
              ? ((CompositeDataChoice) dataChoice).getDataChoices()
              : Misc.toList(new DataChoice[] {dataChoice});
      List datas = new ArrayList(choices.size());
      for (int i = 0; i < choices.size(); i++) {
        DataChoice subDataChoice = (DataChoice) choices.get(i);
        FieldImpl obs = makeObs(subDataChoice, dataSelection, llr);
        if (obs == null) {
          continue;
        }

        //                if (true) {
        //                    return obs;
        //                }
        datas.add(obs);
        if (fieldsDescription == null) {
          makeFieldDescription(obs);
        }
      }
      if (datas.isEmpty()) {
        return null;
      }
      retField = PointObFactory.mergeData(datas);
    } catch (Exception exc) {
      logException("Creating obs", exc);
    }
    return retField;
  }
Exemplo n.º 3
0
  /**
   * Make the adapters for the given list of files
   *
   * @param files Data files
   * @throws Exception When bad things happen
   */
  private void makeAdapters(List files) throws Exception {
    adapters = new ArrayList<RadarAdapter>();
    Hashtable<String, RadarAdapter> oldAdapterMap = fileToAdapter;
    fileToAdapter = new Hashtable<String, RadarAdapter>();

    int cnt = 0;

    final List<String> badFiles = new ArrayList<String>();
    final List<Exception> badExceptions = new ArrayList<Exception>();

    final List<RadarAdapter> goodAdapters = new ArrayList<RadarAdapter>();
    final List<String> goodFiles = new ArrayList<String>();
    visad.util.ThreadManager threadManager =
        new visad.util.ThreadManager("radar data initialization");
    LogUtil.message("Initializing radar files");
    for (Iterator iter = files.iterator(); iter.hasNext(); ) {
      final String filename = iter.next().toString();
      RadarAdapter adapter = (RadarAdapter) oldAdapterMap.get(filename);
      cnt++;
      if (adapter == null) {
        threadManager.addRunnable(
            new visad.util.ThreadManager.MyRunnable() {
              public void run() throws Exception {
                try {
                  RadarAdapter myAdapter = makeRadarAdapter(filename);
                  synchronized (goodAdapters) {
                    goodAdapters.add(myAdapter);
                    goodFiles.add(filename);
                  }
                } catch (Exception e) {
                  synchronized (badExceptions) {
                    badExceptions.add(e);
                    badFiles.add(filename);
                  }
                }
              }
            });
      } else {
        goodAdapters.add(adapter);
        goodFiles.add(filename);
      }
    }

    //        threadManager.debug = true;
    threadManager.runInParallel(getDataContext().getIdv().getMaxDataThreadCount());
    LogUtil.message("");

    for (int i = 0; i < goodAdapters.size(); i++) {
      adapters.add(goodAdapters.get(i));
      fileToAdapter.put(goodFiles.get(i), goodAdapters.get(i));
    }

    if (!badFiles.isEmpty()) {
      StringBuffer buf = new StringBuffer();
      if (badFiles.size() < files.size()) {
        buf.append("<html>");
        buf.append("There were problems reading these files:");
        buf.append("<ul>");
        for (Iterator iterator = badFiles.iterator(); iterator.hasNext(); ) {
          buf.append("<li>");
          buf.append((String) iterator.next());
          buf.append("</li>");
        }
        buf.append("</ul>");
        buf.append("<p>Continue loading good data?<p></html>");
        boolean ok = ucar.unidata.util.GuiUtils.askYesNo("Error reading data", buf.toString());

        badExceptions.get(0).printStackTrace();
        if (ok) {
          files.removeAll(badFiles);
        } else {
          throw new VisADException("error reading files");
        }
      } else {
        throw badExceptions.get(0);
      }
    }
    // clean up any old adapters
    for (String source : oldAdapterMap.keySet()) {
      if (fileToAdapter.get(source) == null) {
        ((RadarAdapter) oldAdapterMap.get(source)).doRemove();
      }
    }
    oldAdapterMap = null;
  }
Exemplo n.º 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;
  }