예제 #1
0
  /**
   * Test using this netcdf image: data: LAI= 20,20,20,30,30, 40,40,40,50,50, 60,60,60,70,70,
   * 80,80,80,90,90; lon= 10,15,20,25,30; lat= 70,60,50,40;
   *
   * @throws IOException
   */
  @Test
  public void testHDF5Image() throws IOException, FactoryException {
    final File testURL = TestData.file(this, "2DLatLonCoverage.nc");
    // Get format
    // final AbstractGridFormat format = (AbstractGridFormat)
    GridFormatFinder.findFormat(testURL.toURI().toURL(), null);
    final NetCDFReader reader = new NetCDFReader(testURL, null);
    // assertNotNull(format);
    assertNotNull(reader);
    try {
      String[] names = reader.getGridCoverageNames();
      assertNotNull(names);
      assertEquals(2, names.length);
      assertEquals("ROOT/LEVEL1/V2", names[1]);
      GridCoverage2D grid = reader.read("ROOT/LAI", null);
      assertNotNull(grid);
      byte[] byteValue =
          grid.evaluate(new DirectPosition2D(DefaultGeographicCRS.WGS84, 12, 70), new byte[1]);
      assertEquals(20, byteValue[0]);

      byteValue =
          grid.evaluate(new DirectPosition2D(DefaultGeographicCRS.WGS84, 23, 40), new byte[1]);
      assertEquals(90, byteValue[0]);

    } finally {
      if (reader != null) {
        try {
          reader.dispose();
        } catch (Throwable t) {
          // Does nothing
        }
      }
    }
  }
예제 #2
0
 AbstractGridFormat lookupGridFormat(Object obj) {
   AbstractGridFormat format = (AbstractGridFormat) GridFormatFinder.findFormat(obj);
   if (format == null) {
     throw new RuntimeException("No format for " + obj);
   }
   return format;
 }
  @Override
  public CloseableIterator<GeoWaveData<GridCoverage>> toGeoWaveData(
      final File input,
      final Collection<ByteArrayId> primaryIndexIds,
      final String globalVisibility) {

    final AbstractGridFormat format = GridFormatFinder.findFormat(input);
    final GridCoverage2DReader reader = format.getReader(input);
    if (reader == null) {
      LOGGER.error("Unable to get reader instance, getReader returned null");
      return new Wrapper(Collections.emptyIterator());
    }
    try {
      final GridCoverage2D coverage = reader.read(null);
      if (coverage != null) {
        final Map<String, String> metadata = new HashMap<String, String>();
        final String coverageName = coverage.getName().toString();
        final String[] mdNames = reader.getMetadataNames(coverageName);
        if ((mdNames != null) && (mdNames.length > 0)) {
          for (final String mdName : mdNames) {
            metadata.put(mdName, reader.getMetadataValue(coverageName, mdName));
          }
        }
        final RasterDataAdapter adapter =
            new RasterDataAdapter(
                input.getName(),
                metadata,
                coverage,
                optionProvider.getTileSize(),
                optionProvider.isBuildPyramid());
        final List<GeoWaveData<GridCoverage>> coverages =
            new ArrayList<GeoWaveData<GridCoverage>>();
        coverages.add(new GeoWaveData<GridCoverage>(adapter, primaryIndexIds, coverage));
        return new Wrapper(coverages.iterator()) {

          @Override
          public void close() throws IOException {
            reader.dispose();
          }
        };
      } else {
        LOGGER.warn(
            "Null grid coverage from file '"
                + input.getAbsolutePath()
                + "' for discovered geotools format '"
                + format.getName()
                + "'");
      }
    } catch (final IOException e) {
      LOGGER.warn(
          "Unable to read grid coverage of file '"
              + input.getAbsolutePath()
              + "' for discovered geotools format '"
              + format.getName()
              + "'",
          e);
    }
    return new Wrapper(Collections.emptyIterator());
  }
  @Override
  public boolean supportsFile(final File file) {

    final AbstractGridFormat format = GridFormatFinder.findFormat(file);
    // the null check is enough and we don't need to check the format
    // accepts this file because the finder should have previously validated
    // this
    return (format != null);
  }
예제 #5
0
  public void testIsAvailable() throws NoSuchAuthorityCodeException, FactoryException {
    GridFormatFinder.scanForPlugins();
    Iterator<GridFormatFactorySpi> list = GridFormatFinder.getAvailableFormats().iterator();
    boolean found = false;
    GridFormatFactorySpi fac = null;
    while (list.hasNext()) {
      fac = (GridFormatFactorySpi) list.next();

      if (fac instanceof ArcGridFormatFactory) {
        found = true;

        break;
      }
    }

    assertTrue("ArcGridFormatFactory not registered", found);
    assertTrue("ArcGridFormatFactory not available", fac.isAvailable());
    assertNotNull(new ArcGridFormatFactory().createFormat());
  }
예제 #6
0
  @Test
  public void NetCDFNoDataOperation()
      throws NoSuchAuthorityCodeException, FactoryException, IOException, ParseException {
    File mosaic = new File(TestData.file(this, "."), "NetCDFGOME2");
    if (mosaic.exists()) {
      FileUtils.deleteDirectory(mosaic);
    }
    assertTrue(mosaic.mkdirs());
    File file = TestData.file(this, "DUMMY.GOME2.NO2.PGL.nc");
    FileUtils.copyFileToDirectory(file, mosaic);
    file = new File(mosaic, "DUMMY.GOME2.NO2.PGL.nc");

    final Hints hints =
        new Hints(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM, CRS.decode("EPSG:4326", true));
    // Get format
    final AbstractGridFormat format =
        (AbstractGridFormat) GridFormatFinder.findFormat(file.toURI().toURL(), hints);
    final NetCDFReader reader = (NetCDFReader) format.getReader(file.toURI().toURL(), hints);

    assertNotNull(format);
    GridCoverage2D gc = null;
    try {
      String[] names = reader.getGridCoverageNames();
      names = new String[] {names[0]};
      gc = reader.read(null);
    } catch (Throwable t) {
      throw new RuntimeException(t);
    } finally {
      if (reader != null) {
        try {
          reader.dispose();
        } catch (Throwable t) {
          // Does nothing
        }
      }
    }
    // Checking NoData
    Object noData = CoverageUtilities.getNoDataProperty(gc);
    assertNotNull(noData);
    assertTrue(noData instanceof NoDataContainer);
    Double d = ((NoDataContainer) noData).getAsSingleValue();
    assertEquals(d, -999d, DELTA);
    // Try to execute an operation on the NoData and check if the result contains also NoData
    CoverageProcessor instance = CoverageProcessor.getInstance();
    Operation scale = instance.getOperation("Scale");
    ParameterValueGroup params = scale.getParameters();
    params.parameter("Source0").setValue(gc);
    params.parameter("backgroundValues").setValue(new double[] {0});
    GridCoverage2D result = (GridCoverage2D) instance.doOperation(params);
    noData = CoverageUtilities.getNoDataProperty(result);
    assertNotNull(noData);
    assertTrue(noData instanceof NoDataContainer);
    d = ((NoDataContainer) noData).getAsSingleValue();
    assertEquals(d, 0d, DELTA);
  }
예제 #7
0
  @Test
  public void testNetCDFWithDifferentTimeDimensions() throws MalformedURLException, IOException {
    // Selection of the input file
    final File workDir = new File(TestData.file(this, "."), "times");
    if (!workDir.mkdir()) {
      FileUtils.deleteDirectory(workDir);
      assertTrue("Unable to create workdir:" + workDir, workDir.mkdir());
    }

    FileUtils.copyFile(TestData.file(this, "times.zip"), new File(workDir, "times.zip"));
    TestData.unzipFile(this, "times/times.zip");

    final File inputFile = TestData.file(this, "times/times.nc");
    // Get format
    final AbstractGridFormat format =
        (AbstractGridFormat) GridFormatFinder.findFormat(inputFile.toURI().toURL(), null);
    final NetCDFReader reader = new NetCDFReader(inputFile, null);
    Assert.assertNotNull(format);
    Assert.assertNotNull(reader);
    try {
      // Selection of all the Coverage names
      String[] names = reader.getGridCoverageNames();
      assertNotNull(names);
      assertEquals(2, names.length);

      // Parsing metadata values
      assertEquals("true", reader.getMetadataValue(names[0], "HAS_TIME_DOMAIN"));

      List<DimensionDescriptor> descriptors = reader.getDimensionDescriptors(names[0]);
      assertEquals(1, descriptors.size());
      DimensionDescriptor descriptor = descriptors.get(0);
      assertEquals("time", descriptor.getStartAttribute());
      assertEquals("TIME", descriptor.getName());

      descriptors = reader.getDimensionDescriptors(names[1]);
      assertEquals(1, descriptors.size());
      descriptor = descriptors.get(0);
      assertEquals("time1", descriptor.getStartAttribute());
      assertEquals("TIME", descriptor.getName());

      assertEquals("true", reader.getMetadataValue(names[1], "HAS_TIME_DOMAIN"));
    } finally {
      if (reader != null) {
        try {
          reader.dispose();
        } catch (Throwable t) {
          // Does nothing
        }
      }
      FileUtils.deleteDirectory(TestData.file(this, "times"));
    }
  }
예제 #8
0
  @Test
  public void NetCDFGOME2()
      throws NoSuchAuthorityCodeException, FactoryException, IOException, ParseException {
    File mosaic = new File(TestData.file(this, "."), "NetCDFGOME2");
    if (mosaic.exists()) {
      FileUtils.deleteDirectory(mosaic);
    }
    assertTrue(mosaic.mkdirs());
    File file = TestData.file(this, "DUMMY.GOME2.NO2.PGL.nc");
    FileUtils.copyFileToDirectory(file, mosaic);
    file = new File(mosaic, "DUMMY.GOME2.NO2.PGL.nc");

    final Hints hints =
        new Hints(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM, CRS.decode("EPSG:4326", true));
    // Get format
    final AbstractGridFormat format =
        (AbstractGridFormat) GridFormatFinder.findFormat(file.toURI().toURL(), hints);
    final NetCDFReader reader = (NetCDFReader) format.getReader(file.toURI().toURL(), hints);

    assertNotNull(format);
    try {
      String[] names = reader.getGridCoverageNames();
      names = new String[] {names[0]};

      for (String coverageName : names) {

        final String[] metadataNames = reader.getMetadataNames(coverageName);
        assertNotNull(metadataNames);
        assertEquals(metadataNames.length, 12);

        // Parsing metadata values
        assertEquals("false", reader.getMetadataValue(coverageName, "HAS_TIME_DOMAIN"));
        final String timeMetadata = reader.getMetadataValue(coverageName, "TIME_DOMAIN");
        assertNull(timeMetadata);

        assertEquals("false", reader.getMetadataValue(coverageName, "HAS_ELEVATION_DOMAIN"));
        final String elevationMetadata = reader.getMetadataValue(coverageName, "ELEVATION_DOMAIN");
        assertNull(elevationMetadata);
      }
    } catch (Throwable t) {
      throw new RuntimeException(t);
    } finally {
      if (reader != null) {
        try {
          reader.dispose();
        } catch (Throwable t) {
          // Does nothing
        }
      }
    }
  }
예제 #9
0
  @Override
  public GridCoverage2D read(GeneralParameterValue[] parameters)
      throws IllegalArgumentException, IOException {
    File baseDir = FileUtils.createTempDirectory();

    try {
      File file = readToFile(baseDir, "WcsCoverageReader", parameters);

      // since the requested format may be one of several we need to look
      // up the format object
      // for reading the coverage from the file
      Format format = GridFormatFinder.findFormat(file);

      if (format instanceof AbstractGridFormat && UnknownFormat.class != format.getClass()) {
        AbstractGridFormat gridFormat = (AbstractGridFormat) format;

        // Now we need to find the parameters provided by the caller for
        // reading the coverage from the file
        // See the format API for details
        GeneralParameterValue[] readParams = new GeneralParameterValue[0];
        try {
          ParameterValueGroup group = format.getReadParameters();
          List<GeneralParameterValue> list = new ArrayList<GeneralParameterValue>();
          for (GeneralParameterValue paramValue : group.values()) {
            list.addAll(find(paramValue, parameters));
          }
          LOG.debug("Reading coverage from file using parameters: " + list);
          readParams = list.toArray(new GeneralParameterValue[list.size()]);
        } catch (Exception e) {
          // if can't configure the parameters then try to read with
          // what we have been able to configure
          LOG.warn("Exception occurred while getting request params for reading coverage", e);
        }
        AbstractGridCoverage2DReader reader = gridFormat.getReader(file);
        GridCoverage2D coverage = reader.read(readParams);
        return coverage;
      }
      throw new IllegalArgumentException(
          "Current configuration is unable to read coverage of "
              + file.getName()
              + " format.  "
              + "Check that you have the correct geotools plugins");

    } finally {
      FileUtils.delete(baseDir);
    }
  }
예제 #10
0
  public void run() {
    Display display = Display.getCurrent();
    Shell shell = new Shell(display);
    File openFile = JFileImageChooser.showOpenFile(shell);

    if (openFile != null && openFile.exists()) {
      AbstractGridFormat format = GridFormatFinder.findFormat(openFile);
      AbstractGridCoverage2DReader tiffReader = format.getReader(openFile);
      StyleFactoryImpl sf = new StyleFactoryImpl();
      RasterSymbolizer symbolizer = sf.getDefaultRasterSymbolizer();
      Style defaultStyle = SLD.wrapSymbolizers(symbolizer);

      MapContext mapContext = mapPane.getMapContext();
      MapLayer layer = new MapLayer(tiffReader, defaultStyle);
      layer.setTitle(openFile.getName());
      mapContext.addLayer(layer);
      mapPane.redraw();
    }
  }
예제 #11
0
  @Test
  public void NetCDFNoData()
      throws NoSuchAuthorityCodeException, FactoryException, IOException, ParseException {
    File mosaic = new File(TestData.file(this, "."), "NetCDFGOME2");
    if (mosaic.exists()) {
      FileUtils.deleteDirectory(mosaic);
    }
    assertTrue(mosaic.mkdirs());
    File file = TestData.file(this, "DUMMY.GOME2.NO2.PGL.nc");
    FileUtils.copyFileToDirectory(file, mosaic);
    file = new File(mosaic, "DUMMY.GOME2.NO2.PGL.nc");

    final Hints hints =
        new Hints(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM, CRS.decode("EPSG:4326", true));
    // Get format
    final AbstractGridFormat format =
        (AbstractGridFormat) GridFormatFinder.findFormat(file.toURI().toURL(), hints);
    final NetCDFReader reader = (NetCDFReader) format.getReader(file.toURI().toURL(), hints);

    assertNotNull(format);
    try {
      String[] names = reader.getGridCoverageNames();
      names = new String[] {names[0]};
      GridCoverage2D gc = reader.read(null);
      Object noData = CoverageUtilities.getNoDataProperty(gc);
      assertNotNull(noData);
      assertTrue(noData instanceof NoDataContainer);
      Double d = ((NoDataContainer) noData).getAsSingleValue();
      assertEquals(d, -999d, DELTA);

    } catch (Throwable t) {
      throw new RuntimeException(t);
    } finally {
      if (reader != null) {
        try {
          reader.dispose();
        } catch (Throwable t) {
          // Does nothing
        }
      }
    }
  }
예제 #12
0
  @Test
  public void testFullReadOnCoverageWithIncreasingLat() throws IOException, FactoryException {
    final File testURL = TestData.file(this, "O3-NO2.nc");
    // Get format
    // final AbstractGridFormat format = (AbstractGridFormat)
    GridFormatFinder.findFormat(testURL.toURI().toURL(), null);
    final NetCDFReader reader = new NetCDFReader(testURL, null);
    // assertNotNull(format);
    assertNotNull(reader);
    try {
      String[] names = reader.getGridCoverageNames();
      assertNotNull(names);
      assertEquals(2, names.length);

      GridCoverage2D grid = reader.read("O3", null);
      assertFalse(grid.getSampleDimension(0).getDescription().toString().endsWith(":sd"));
      assertNotNull(grid);
      float[] value =
          grid.evaluate(
              (DirectPosition) new DirectPosition2D(DefaultGeographicCRS.WGS84, 5, 45),
              new float[1]);
      assertEquals(47.63341f, value[0], 0.00001);

      value =
          grid.evaluate(
              (DirectPosition) new DirectPosition2D(DefaultGeographicCRS.WGS84, 5, 45.125),
              new float[1]);
      assertEquals(52.7991f, value[0], 0.000001);

    } finally {
      if (reader != null) {
        try {
          reader.dispose();
        } catch (Throwable t) {
          // Does nothing
        }
      }
    }
  }
예제 #13
0
  @SuppressWarnings({"rawtypes", "unchecked"})
  @Test
  @Ignore
  public void IASI() throws Exception {

    final URL testURL = TestData.url(this, "IASI_C_EUMP_20121120062959_31590_eps_o_l2.nc");
    final Hints hints =
        new Hints(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM, CRS.decode("EPSG:4326", true));
    // Get format
    final AbstractGridFormat format =
        (AbstractGridFormat) GridFormatFinder.findFormat(testURL, hints);
    final NetCDFReader reader = (NetCDFReader) format.getReader(testURL, hints);
    assertNotNull(format);
    assertNotNull(reader);
    try {
      String[] names = reader.getGridCoverageNames();
      assertNotNull(names);
      assertEquals(names.length, 20);

      // surface_emissivity
      final String coverageName = "surface_emissivity";
      final String[] metadataNames = reader.getMetadataNames(coverageName);
      assertNotNull(metadataNames);
      assertEquals(14, metadataNames.length);

      // Parsing metadata values
      assertEquals("false", reader.getMetadataValue(coverageName, "HAS_TIME_DOMAIN"));
      assertEquals("false", reader.getMetadataValue(coverageName, "HAS_ELEVATION_DOMAIN"));
      assertEquals("true", reader.getMetadataValue(coverageName, "HAS_NEW_DOMAIN"));

      // additional domains
      final String newDomain = reader.getMetadataValue(coverageName, "NEW_DOMAIN");
      assertNotNull(metadataNames);
      final String[] newDomainValues = newDomain.split(",");
      assertNotNull(newDomainValues);
      assertEquals(12, newDomainValues.length);
      assertEquals(13.063399669990758, Double.valueOf(newDomainValues[11]), 1E-6);
      assertEquals(3.6231999084702693, Double.valueOf(newDomainValues[0]), 1E-6);

      // subsetting the envelope
      final ParameterValue<GridGeometry2D> gg =
          AbstractGridFormat.READ_GRIDGEOMETRY2D.createValue();
      final GeneralEnvelope originalEnvelope = reader.getOriginalEnvelope(coverageName);
      final GeneralEnvelope reducedEnvelope =
          new GeneralEnvelope(
              new double[] {
                originalEnvelope.getLowerCorner().getOrdinate(0),
                originalEnvelope.getLowerCorner().getOrdinate(1)
              },
              new double[] {
                originalEnvelope.getMedian().getOrdinate(0),
                originalEnvelope.getMedian().getOrdinate(1)
              });
      reducedEnvelope.setCoordinateReferenceSystem(
          reader.getCoordinateReferenceSystem(coverageName));

      // Selecting bigger gridRange for a zoomed result
      final Dimension dim = new Dimension();
      GridEnvelope gridRange = reader.getOriginalGridRange(coverageName);
      dim.setSize(gridRange.getSpan(0) * 4.0, gridRange.getSpan(1) * 2.0);
      final Rectangle rasterArea = ((GridEnvelope2D) gridRange);
      rasterArea.setSize(dim);
      final GridEnvelope2D range = new GridEnvelope2D(rasterArea);
      gg.setValue(new GridGeometry2D(range, reducedEnvelope));

      // specify additional Dimensions
      Set<ParameterDescriptor<List>> params = reader.getDynamicParameters(coverageName);
      ParameterValue<List> new_ = null;
      for (ParameterDescriptor param : params) {
        if (param.getName().getCode().equalsIgnoreCase("NEW")) {
          new_ = param.createValue();
          new_.setValue(
              new ArrayList() {
                {
                  add(Double.valueOf(newDomainValues[11]));
                }
              });
        }
      }

      GeneralParameterValue[] values = new GeneralParameterValue[] {gg, new_};
      GridCoverage2D coverage = reader.read(coverageName, values);
      assertNotNull(coverage);
      if (TestData.isInteractiveTest()) {
        coverage.show();
      } else {
        PlanarImage.wrapRenderedImage(coverage.getRenderedImage()).getTiles();
      }
    } finally {
      if (reader != null) {
        try {
          reader.dispose();
        } catch (Throwable t) {
          // Does nothing
        }
      }
    }
  }
예제 #14
0
  @Test
  public void NetCDFTestOnFilter()
      throws NoSuchAuthorityCodeException, FactoryException, IOException, ParseException {
    File mosaic = new File(TestData.file(this, "."), "NetCDFTestOnFilter");
    if (mosaic.exists()) {
      FileUtils.deleteDirectory(mosaic);
    }
    assertTrue(mosaic.mkdirs());

    File file = TestData.file(this, "O3-NO2.nc");
    FileUtils.copyFileToDirectory(file, mosaic);
    file = new File(mosaic, "O3-NO2.nc");

    final Hints hints =
        new Hints(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM, CRS.decode("EPSG:4326", true));
    // Get format
    final AbstractGridFormat format =
        (AbstractGridFormat) GridFormatFinder.findFormat(file.toURI().toURL(), hints);
    final NetCDFReader reader = (NetCDFReader) format.getReader(file.toURI().toURL(), hints);

    assertNotNull(format);
    try {
      String[] names = reader.getGridCoverageNames();
      names = new String[] {names[1]};

      for (String coverageName : names) {

        final String[] metadataNames = reader.getMetadataNames(coverageName);
        assertNotNull(metadataNames);
        assertEquals(12, metadataNames.length);

        // Parsing metadata values
        assertEquals("true", reader.getMetadataValue(coverageName, "HAS_TIME_DOMAIN"));
        final String timeMetadata = reader.getMetadataValue(coverageName, "TIME_DOMAIN");
        assertEquals(
            "2012-04-01T00:00:00.000Z/2012-04-01T00:00:00.000Z,2012-04-01T01:00:00.000Z/2012-04-01T01:00:00.000Z",
            timeMetadata);
        assertNotNull(timeMetadata);
        assertEquals(
            "2012-04-01T00:00:00.000Z",
            reader.getMetadataValue(coverageName, "TIME_DOMAIN_MINIMUM"));
        assertEquals(
            "2012-04-01T01:00:00.000Z",
            reader.getMetadataValue(coverageName, "TIME_DOMAIN_MAXIMUM"));

        assertEquals("true", reader.getMetadataValue(coverageName, "HAS_ELEVATION_DOMAIN"));
        final String elevationMetadata = reader.getMetadataValue(coverageName, "ELEVATION_DOMAIN");
        assertNotNull(elevationMetadata);
        assertEquals("10.0/10.0,450.0/450.0", elevationMetadata);
        assertEquals(2, elevationMetadata.split(",").length);
        assertEquals("10.0", reader.getMetadataValue(coverageName, "ELEVATION_DOMAIN_MINIMUM"));
        assertEquals("450.0", reader.getMetadataValue(coverageName, "ELEVATION_DOMAIN_MAXIMUM"));

        // subsetting the envelope
        final ParameterValue<GridGeometry2D> gg =
            AbstractGridFormat.READ_GRIDGEOMETRY2D.createValue();
        final GeneralEnvelope originalEnvelope = reader.getOriginalEnvelope(coverageName);
        final GeneralEnvelope reducedEnvelope =
            new GeneralEnvelope(
                new double[] {
                  originalEnvelope.getLowerCorner().getOrdinate(0),
                  originalEnvelope.getLowerCorner().getOrdinate(1)
                },
                new double[] {
                  originalEnvelope.getMedian().getOrdinate(0),
                  originalEnvelope.getMedian().getOrdinate(1)
                });
        reducedEnvelope.setCoordinateReferenceSystem(
            reader.getCoordinateReferenceSystem(coverageName));

        // Selecting bigger gridRange for a zoomed result
        final Dimension dim = new Dimension();
        GridEnvelope gridRange = reader.getOriginalGridRange(coverageName);
        dim.setSize(gridRange.getSpan(0) * 4.0, gridRange.getSpan(1) * 2.0);
        final Rectangle rasterArea = ((GridEnvelope2D) gridRange);
        rasterArea.setSize(dim);
        final GridEnvelope2D range = new GridEnvelope2D(rasterArea);
        gg.setValue(new GridGeometry2D(range, reducedEnvelope));

        final ParameterValue<Filter> filterParam = NetCDFFormat.FILTER.createValue();
        FilterFactory2 FF = FeatureUtilities.DEFAULT_FILTER_FACTORY;
        Filter filter = FF.equals(FF.property("z"), FF.literal(450.0));
        filterParam.setValue(filter);

        GeneralParameterValue[] values = new GeneralParameterValue[] {filterParam};
        GridCoverage2D coverage = reader.read(coverageName, values);
        assertNotNull(coverage);
        if (TestData.isInteractiveTest()) {
          coverage.show();
        } else {
          PlanarImage.wrapRenderedImage(coverage.getRenderedImage()).getTiles();
        }
      }
    } catch (Throwable t) {
      throw new RuntimeException(t);
    } finally {
      if (reader != null) {
        try {
          reader.dispose();
        } catch (Throwable t) {
          // Does nothing
        }
      }
    }
  }
예제 #15
0
  /**
   * Tests the {@link OverviewsController} with support for different resolutions/different number
   * of overviews.
   *
   * <p>world_a.tif => Pixel Size = (0.833333333333333,-0.833333333333333); 4 overviews world_b.tif
   * => Pixel Size = (1.406250000000000,-1.406250000000000); 2 overviews
   *
   * @throws IOException
   * @throws MismatchedDimensionException
   * @throws FactoryException
   * @throws TransformException
   */
  @Test
  public void testHeterogeneousGranules()
      throws IOException, MismatchedDimensionException, FactoryException, TransformException {

    final CoordinateReferenceSystem WGS84 = CRS.decode("EPSG:4326", true);
    final ReferencedEnvelope TEST_BBOX_A = new ReferencedEnvelope(-180, 0, -90, 90, WGS84);
    final ReferencedEnvelope TEST_BBOX_B = new ReferencedEnvelope(0, 180, 0, 90, WGS84);

    URL heterogeneousGranulesURL = TestData.url(this, "heterogeneous");
    // //
    //
    // Initialize mosaic variables
    //
    // //
    final Hints hints = new Hints(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM, WGS84);
    final AbstractGridFormat format =
        (AbstractGridFormat) GridFormatFinder.findFormat(heterogeneousGranulesURL, hints);
    Assert.assertNotNull(format);
    Assert.assertFalse("UknownFormat", format instanceof UnknownFormat);

    final ImageMosaicReader reader =
        (ImageMosaicReader) format.getReader(heterogeneousGranulesURL, hints);
    Assert.assertNotNull(reader);

    final int nOv = reader.getNumberOfOvervies();
    final double[] hRes = reader.getHighestRes();
    final RasterManager rasterManager = new RasterManager(reader);

    // //
    //
    // Initialize granules related variables
    //
    // //
    final File g1File = new File(DataUtilities.urlToFile(heterogeneousGranulesURL), "world_a.tif");
    final File g2File = new File(DataUtilities.urlToFile(heterogeneousGranulesURL), "world_b.tif");
    final ImageReadParam readParamsG1 = new ImageReadParam();
    final ImageReadParam readParamsG2 = new ImageReadParam();
    int imageIndexG1 = 0;
    int imageIndexG2 = 0;

    final GranuleDescriptor granuleDescriptor1 =
        new GranuleDescriptor(g1File.getAbsolutePath(), TEST_BBOX_A, spi, (Geometry) null, true);
    final GranuleDescriptor granuleDescriptor2 =
        new GranuleDescriptor(g2File.getAbsolutePath(), TEST_BBOX_B, spi, (Geometry) null, true);
    assertNotNull(granuleDescriptor1.toString());
    assertNotNull(granuleDescriptor2.toString());

    final OverviewsController ovControllerG1 = granuleDescriptor1.overviewsController;
    final OverviewsController ovControllerG2 = granuleDescriptor2.overviewsController;

    // //
    //
    // Initializing read request
    //
    // //
    final GeneralEnvelope envelope = reader.getOriginalEnvelope();
    final GridEnvelope originalRange = reader.getOriginalGridRange();
    final Rectangle rasterArea =
        new Rectangle(
            0,
            0,
            (int) Math.ceil(originalRange.getSpan(0) / 9.0),
            (int) Math.ceil(originalRange.getSpan(1) / 9.0));
    final GridEnvelope2D range = new GridEnvelope2D(rasterArea);
    final GridToEnvelopeMapper geMapper = new GridToEnvelopeMapper(range, envelope);
    geMapper.setPixelAnchor(PixelInCell.CELL_CENTER);
    final AffineTransform gridToWorld = geMapper.createAffineTransform();
    final double requestedResolution[] =
        new double[] {
          XAffineTransform.getScaleX0(gridToWorld), XAffineTransform.getScaleY0(gridToWorld)
        };

    TestSet at = null;
    if (nOv == 4 && Math.abs(hRes[0] - 0.833333333333) <= THRESHOLD) {
      at = at1;
    } else if (nOv == 2 && Math.abs(hRes[0] - 1.40625) <= THRESHOLD) {
      at = at2;
    } else {
      return;
    }

    // //
    //
    // Starting OverviewsController tests
    //
    // //
    final OverviewPolicy[] ovPolicies =
        new OverviewPolicy[] {
          OverviewPolicy.QUALITY,
          OverviewPolicy.SPEED,
          OverviewPolicy.NEAREST,
          OverviewPolicy.IGNORE
        };
    for (int i = 0; i < ovPolicies.length; i++) {
      OverviewPolicy ovPolicy = ovPolicies[i];
      LOGGER.info("Testing with OverviewPolicy = " + ovPolicy.toString());
      imageIndexG1 =
          ReadParamsController.setReadParams(
              requestedResolution,
              ovPolicy,
              DecimationPolicy.ALLOW,
              readParamsG1,
              rasterManager,
              ovControllerG1);
      imageIndexG2 =
          ReadParamsController.setReadParams(
              requestedResolution,
              ovPolicy,
              DecimationPolicy.ALLOW,
              readParamsG2,
              rasterManager,
              ovControllerG2);
      assertSame(at.ot[i].g1.imageIndex, imageIndexG1);
      assertSame(at.ot[i].g2.imageIndex, imageIndexG2);
      assertSame(at.ot[i].g1.ssx, readParamsG1.getSourceXSubsampling());
      assertSame(at.ot[i].g1.ssy, readParamsG1.getSourceYSubsampling());
      assertSame(at.ot[i].g2.ssx, readParamsG2.getSourceXSubsampling());
      assertSame(at.ot[i].g2.ssy, readParamsG2.getSourceYSubsampling());
    }
  }
예제 #16
0
  /**
   * Adds a raster layer to the setup.
   *
   * <p>This method configures a raster layer with the name <code>qName.getLocalPart()</code>. A
   * coverage store is created (if it doesn't already exist) with the same name. The workspace of
   * the resulting store and layer is determined by <code>qName.getPrefix()</code>.
   *
   * <p>The <tt>filename</tt> parameter defines the raster file to be loaded from the classpath and
   * copied into the data directory. The <tt>scope</tt> is used as the class from which to load the
   * file from.
   *
   * <p>In the case of adding a zipped archive that contains multiple file the <tt>filename</tt>
   * paramter should have a ".zip" extension and the <tt>extension</tt> parameter must define the
   * extension of the main raster file. The parameter is not necessary and may be null if the
   * <tt>filename</tt> does not refer to a zip file.
   *
   * <p>The <tt>props</tt> parameter is used to define custom properties for the layer. See the
   * {@link LayerProperty} class for supported properties.
   *
   * @param qName The name of the raster layer.
   * @param filename The name of the file containing the raster, to be loaded from the classpath.
   * @param extension The file extension (without a ".") of the main raster file. This parameter my
   *     be <code>null</code> only if <tt>filename</tt> does not refer to a zip file.
   * @param props Custom properties to assign to the created raster layer.
   * @param scope The class from which to load the <tt>filename</tt> resource from.
   */
  public void addRasterLayer(
      QName qName,
      String filename,
      String extension,
      Map<LayerProperty, Object> props,
      Class scope,
      Catalog catalog)
      throws IOException {

    String prefix = qName.getPrefix();
    String name = qName.getLocalPart();

    // setup the data
    File dir = new File(data, name);
    dir.mkdirs();

    File file = new File(dir, filename);
    catalog.getResourceLoader().copyFromClassPath(filename, file, scope);

    String ext = FilenameUtils.getExtension(filename);
    if ("zip".equalsIgnoreCase(ext)) {

      // unpack the archive
      IOUtils.decompress(file, dir);

      // delete archive
      file.delete();

      if (extension == null) {
        // zip with no extension, we just the directory as the file
        file = dir;
      } else {
        // files may have been top level, or one directory level deep
        file = new File(dir, FilenameUtils.getBaseName(filename) + "." + extension);
        if (!file.exists()) {
          File file2 = new File(new File(dir, dir.getName()), file.getName());
          if (file2.exists()) {
            file = file2;
          }
        }
      }

      if (!file.exists()) {
        throw new FileNotFoundException(file.getPath());
      }
    }

    // load the format/reader
    AbstractGridFormat format = (AbstractGridFormat) GridFormatFinder.findFormat(file);
    if (format == null) {
      throw new RuntimeException("No format for " + file.getCanonicalPath());
    }
    AbstractGridCoverage2DReader reader = null;
    try {
      reader = (AbstractGridCoverage2DReader) format.getReader(file);
      if (reader == null) {
        throw new RuntimeException(
            "No reader for " + file.getCanonicalPath() + " with format " + format.getName());
      }

      // configure workspace if it doesn;t already exist
      if (catalog.getWorkspaceByName(prefix) == null) {
        addWorkspace(prefix, qName.getNamespaceURI(), catalog);
      }
      // create the store
      CoverageStoreInfo store = catalog.getCoverageStoreByName(prefix, name);
      if (store == null) {
        store = catalog.getFactory().createCoverageStore();
      }

      store.setName(name);
      store.setWorkspace(catalog.getWorkspaceByName(prefix));
      store.setEnabled(true);
      store.setURL(DataUtilities.fileToURL(file).toString());
      store.setType(format.getName());

      if (store.getId() == null) {
        catalog.add(store);
      } else {
        catalog.save(store);
      }

      // create the coverage
      CatalogBuilder builder = new CatalogBuilder(catalog);
      builder.setStore(store);

      CoverageInfo coverage = null;

      try {

        coverage = builder.buildCoverage(reader, null);
        // coverage read params
        if (format instanceof ImageMosaicFormat) {
          //  make sure we work in immediate mode
          coverage
              .getParameters()
              .put(AbstractGridFormat.USE_JAI_IMAGEREAD.getName().getCode(), Boolean.FALSE);
        }
      } catch (Exception e) {
        throw new IOException(e);
      }

      coverage.setName(name);
      coverage.setTitle(name);
      coverage.setDescription(name);
      coverage.setEnabled(true);

      CoverageInfo cov = catalog.getCoverageByCoverageStore(store, name);
      if (cov == null) {
        catalog.add(coverage);
      } else {
        builder.updateCoverage(cov, coverage);
        catalog.save(cov);
        coverage = cov;
      }

      LayerInfo layer = catalog.getLayerByName(new NameImpl(qName));
      if (layer == null) {
        layer = catalog.getFactory().createLayer();
      }
      layer.setResource(coverage);

      layer.setDefaultStyle(
          catalog.getStyleByName(LayerProperty.STYLE.get(props, DEFAULT_RASTER_STYLE)));
      layer.setType(LayerInfo.Type.RASTER);
      layer.setEnabled(true);

      if (layer.getId() == null) {
        catalog.add(layer);
      } else {
        catalog.save(layer);
      }
    } finally {
      if (reader != null) {
        reader.dispose();
      }
    }
  }
예제 #17
0
  @Test
  public void NetCDFTestOn4DcoveragesWithImposedSchemas()
      throws NoSuchAuthorityCodeException, FactoryException, IOException, ParseException {
    File mosaic = new File(TestData.file(this, "."), "NetCDFTestOn4DcoveragesWithImposedSchemas");
    if (mosaic.exists()) {
      FileUtils.deleteDirectory(mosaic);
    }
    assertTrue(mosaic.mkdirs());

    File file = TestData.file(this, "O3NO2-noZ.nc");
    File auxFile = TestData.file(this, "O3NO2-noZ.xml");
    FileUtils.copyFileToDirectory(file, mosaic);
    FileUtils.copyFileToDirectory(auxFile, mosaic);
    file = new File(mosaic, "O3NO2-noZ.nc");

    final Hints hints =
        new Hints(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM, CRS.decode("EPSG:4326", true));
    hints.put(
        Utils.AUXILIARY_FILES_PATH,
        new File(mosaic, "O3NO2-noZ.xml").getAbsolutePath()); // impose def

    // Get format
    final AbstractGridFormat format =
        (AbstractGridFormat) GridFormatFinder.findFormat(file.toURI().toURL(), hints);
    final NetCDFReader reader = (NetCDFReader) format.getReader(file.toURI().toURL(), hints);

    assertNotNull(format);
    try {
      String[] names = reader.getGridCoverageNames();
      for (String coverageName : names) {

        final String[] metadataNames = reader.getMetadataNames(coverageName);
        assertNotNull(metadataNames);
        assertEquals(metadataNames.length, 12);

        // Parsing metadata values
        assertEquals("true", reader.getMetadataValue(coverageName, "HAS_TIME_DOMAIN"));
        final String timeMetadata = reader.getMetadataValue(coverageName, "TIME_DOMAIN");
        assertEquals(
            "2012-04-01T00:00:00.000Z/2012-04-01T00:00:00.000Z,2012-04-01T01:00:00.000Z/2012-04-01T01:00:00.000Z",
            timeMetadata);
        assertNotNull(timeMetadata);
        assertEquals(
            "2012-04-01T00:00:00.000Z",
            reader.getMetadataValue(coverageName, "TIME_DOMAIN_MINIMUM"));
        assertEquals(
            "2012-04-01T01:00:00.000Z",
            reader.getMetadataValue(coverageName, "TIME_DOMAIN_MAXIMUM"));

        if (coverageName.equalsIgnoreCase("O3")) {
          assertEquals("true", reader.getMetadataValue(coverageName, "HAS_ELEVATION_DOMAIN"));
          final String elevationMetadata =
              reader.getMetadataValue(coverageName, "ELEVATION_DOMAIN");
          assertNotNull(elevationMetadata);
          assertEquals("10.0/10.0,450.0/450.0", elevationMetadata);
          assertEquals(2, elevationMetadata.split(",").length);
          assertEquals("10.0", reader.getMetadataValue(coverageName, "ELEVATION_DOMAIN_MINIMUM"));
          assertEquals("450.0", reader.getMetadataValue(coverageName, "ELEVATION_DOMAIN_MAXIMUM"));
        } else {
          // Note that This sample doesn't have elevation for NO2
          assertEquals("false", reader.getMetadataValue(coverageName, "HAS_ELEVATION_DOMAIN"));
          final String elevationMetadata =
              reader.getMetadataValue(coverageName, "ELEVATION_DOMAIN");
          assertNull(elevationMetadata);
        }

        // subsetting the envelope
        final ParameterValue<GridGeometry2D> gg =
            AbstractGridFormat.READ_GRIDGEOMETRY2D.createValue();
        final GeneralEnvelope originalEnvelope = reader.getOriginalEnvelope(coverageName);
        final GeneralEnvelope reducedEnvelope =
            new GeneralEnvelope(
                new double[] {
                  originalEnvelope.getLowerCorner().getOrdinate(0),
                  originalEnvelope.getLowerCorner().getOrdinate(1)
                },
                new double[] {
                  originalEnvelope.getMedian().getOrdinate(0),
                  originalEnvelope.getMedian().getOrdinate(1)
                });
        reducedEnvelope.setCoordinateReferenceSystem(
            reader.getCoordinateReferenceSystem(coverageName));

        // Selecting bigger gridRange for a zoomed result
        final Dimension dim = new Dimension();
        GridEnvelope gridRange = reader.getOriginalGridRange(coverageName);
        dim.setSize(gridRange.getSpan(0) * 4.0, gridRange.getSpan(1) * 2.0);
        final Rectangle rasterArea = ((GridEnvelope2D) gridRange);
        rasterArea.setSize(dim);
        final GridEnvelope2D range = new GridEnvelope2D(rasterArea);
        gg.setValue(new GridGeometry2D(range, reducedEnvelope));

        final ParameterValue<List> time = ImageMosaicFormat.TIME.createValue();
        final SimpleDateFormat formatD = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
        formatD.setTimeZone(TimeZone.getTimeZone("GMT"));
        final Date timeD = formatD.parse("2012-04-01T00:00:00.000Z");
        time.setValue(
            new ArrayList() {
              {
                add(timeD);
              }
            });

        final ParameterValue<List> elevation = ImageMosaicFormat.ELEVATION.createValue();
        elevation.setValue(
            new ArrayList() {
              {
                add(450d); // Elevation
              }
            });

        GeneralParameterValue[] values =
            coverageName.equalsIgnoreCase("O3")
                ? new GeneralParameterValue[] {gg, time, elevation}
                : new GeneralParameterValue[] {gg, time};

        GridCoverage2D coverage = reader.read(coverageName, values);
        assertNotNull(coverage);
        if (TestData.isInteractiveTest()) {
          coverage.show();
        } else {
          PlanarImage.wrapRenderedImage(coverage.getRenderedImage()).getTiles();
        }
      }
    } catch (Throwable t) {
      throw new RuntimeException(t);
    } finally {
      if (reader != null) {
        try {
          reader.dispose();
        } catch (Throwable t) {
          // Does nothing
        }
      }
    }
  }
예제 #18
0
  @Test
  public void testFileInfo()
      throws NoSuchAuthorityCodeException, FactoryException, IOException, ParseException {
    File nc2 = new File(TestData.file(this, "."), "nc2");
    if (nc2.exists()) {
      FileUtils.deleteDirectory(nc2);
    }
    assertTrue(nc2.mkdirs());

    File file = TestData.file(this, "O3-NO2.nc");
    FileUtils.copyFileToDirectory(file, nc2);
    file = new File(nc2, "O3-NO2.nc");
    final Hints hints =
        new Hints(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM, CRS.decode("EPSG:4326", true));
    // Get format
    final AbstractGridFormat format =
        (AbstractGridFormat) GridFormatFinder.findFormat(file.toURI().toURL(), hints);
    final NetCDFReader reader = (NetCDFReader) format.getReader(file.toURI().toURL(), hints);

    assertNotNull(format);
    CloseableIterator<FileGroup> files = null;
    try {
      String[] names = reader.getGridCoverageNames();
      names = new String[] {names[1]};

      for (String coverageName : names) {

        final String[] metadataNames = reader.getMetadataNames(coverageName);
        assertNotNull(metadataNames);
        assertEquals(metadataNames.length, 12);

        ResourceInfo info = reader.getInfo(coverageName);
        assertTrue(info instanceof FileResourceInfo);
        FileResourceInfo fileInfo = (FileResourceInfo) info;
        files = fileInfo.getFiles(null);

        int fileGroups = 0;
        FileGroup fg = null;
        while (files.hasNext()) {
          fg = files.next();
          fileGroups++;
        }
        assertEquals(1, fileGroups);
        File mainFile = fg.getMainFile();
        assertEquals("O3-NO2", FilenameUtils.getBaseName(mainFile.getAbsolutePath()));
        Map<String, Object> metadata = fg.getMetadata();
        assertNotNull(metadata);
        assertFalse(metadata.isEmpty());
        Set<String> keys = metadata.keySet();

        // envelope, time, elevation = 3 elements
        assertEquals(3, keys.size());

        // Check time
        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sss'Z'");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+0"));
        Date start = sdf.parse("2012-04-01T00:00:00.000Z");
        Date end = sdf.parse("2012-04-01T01:00:00.000Z");
        DateRange timeRange = new DateRange(start, end);
        assertEquals(timeRange, metadata.get(Utils.TIME_DOMAIN));

        // Check elevation
        NumberRange<Double> elevationRange = NumberRange.create(10.0, 450.0);
        assertEquals(elevationRange, metadata.get(Utils.ELEVATION_DOMAIN));
      }
    } catch (Throwable t) {
      throw new RuntimeException(t);
    } finally {
      if (files != null) {
        files.close();
      }
      if (reader != null) {
        try {
          reader.dispose();
        } catch (Throwable t) {
          // Does nothing
        }
      }
    }
  }
예제 #19
0
  @Test
  public void NetCDFTestAscatL1()
      throws NoSuchAuthorityCodeException, FactoryException, IOException, ParseException {
    File mosaic = new File(TestData.file(this, "."), "NetCDFTestAscatL1");
    if (mosaic.exists()) {
      FileUtils.deleteDirectory(mosaic);
    }
    assertTrue(mosaic.mkdirs());
    File file = TestData.file(this, "ascatl1.nc");
    FileUtils.copyFileToDirectory(file, mosaic);
    file = new File(mosaic, "ascatl1.nc");

    final Hints hints =
        new Hints(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM, CRS.decode("EPSG:4326", true));
    hints.add(new Hints(Utils.EXCLUDE_MOSAIC, true));

    // Get format
    final AbstractGridFormat format =
        (AbstractGridFormat) GridFormatFinder.findFormat(file.toURI().toURL(), hints);
    final NetCDFReader reader = (NetCDFReader) format.getReader(file.toURI().toURL(), hints);

    assertNotNull(format);
    try {
      String[] names = reader.getGridCoverageNames();
      names = new String[] {names[1]};

      for (String coverageName : names) {

        final String[] metadataNames = reader.getMetadataNames(coverageName);
        assertNotNull(metadataNames);
        assertEquals(17, metadataNames.length);

        // Parsing metadata values
        assertEquals("false", reader.getMetadataValue(coverageName, "HAS_TIME_DOMAIN"));

        assertEquals("false", reader.getMetadataValue(coverageName, "HAS_ELEVATION_DOMAIN"));

        assertEquals("true", reader.getMetadataValue(coverageName, "HAS_NUMSIGMA_DOMAIN"));
        final String sigmaMetadata = reader.getMetadataValue(coverageName, "NUMSIGMA_DOMAIN");
        assertNotNull(sigmaMetadata);
        assertEquals("0,1,2", sigmaMetadata);
        assertEquals(3, sigmaMetadata.split(",").length);

        // subsetting the envelope
        final ParameterValue<GridGeometry2D> gg =
            AbstractGridFormat.READ_GRIDGEOMETRY2D.createValue();
        final GeneralEnvelope originalEnvelope = reader.getOriginalEnvelope(coverageName);
        final GeneralEnvelope reducedEnvelope =
            new GeneralEnvelope(
                new double[] {
                  originalEnvelope.getLowerCorner().getOrdinate(0),
                  originalEnvelope.getLowerCorner().getOrdinate(1)
                },
                new double[] {
                  originalEnvelope.getMedian().getOrdinate(0),
                  originalEnvelope.getMedian().getOrdinate(1)
                });
        reducedEnvelope.setCoordinateReferenceSystem(
            reader.getCoordinateReferenceSystem(coverageName));

        // Selecting bigger gridRange for a zoomed result
        final Dimension dim = new Dimension();
        GridEnvelope gridRange = reader.getOriginalGridRange(coverageName);
        dim.setSize(gridRange.getSpan(0) * 4.0, gridRange.getSpan(1) * 2.0);
        final Rectangle rasterArea = ((GridEnvelope2D) gridRange);
        rasterArea.setSize(dim);
        final GridEnvelope2D range = new GridEnvelope2D(rasterArea);
        gg.setValue(new GridGeometry2D(range, reducedEnvelope));

        ParameterValue<List<String>> sigmaValue = null;
        final String selectedSigma = "1";
        Set<ParameterDescriptor<List>> params = reader.getDynamicParameters(coverageName);
        for (ParameterDescriptor param : params) {
          if (param.getName().getCode().equalsIgnoreCase("NUMSIGMA")) {
            sigmaValue = param.createValue();
            sigmaValue.setValue(
                new ArrayList<String>() {
                  {
                    add(selectedSigma);
                  }
                });
          }
        }

        GeneralParameterValue[] values = new GeneralParameterValue[] {gg, sigmaValue};
        GridCoverage2D coverage = reader.read(coverageName, values);
        assertNotNull(coverage);
        if (TestData.isInteractiveTest()) {
          coverage.show();
        } else {
          PlanarImage.wrapRenderedImage(coverage.getRenderedImage()).getTiles();
        }
      }
    } catch (Throwable t) {
      throw new RuntimeException(t);
    } finally {
      if (reader != null) {
        try {
          reader.dispose();
        } catch (Throwable t) {
          // Does nothing
        }
      }
    }
  }