@Test public void testWCS10GetCoverageDifferentCrs() throws Exception { // xMin,yMin 5988504.35,851278.90 : xMax,yMax 7585113.55,1950872.01 // xMin,yMin -95.1193,42.2802 : xMax,yMax -71.295,53.73 GetCoverageType gc = Wcs10Factory.eINSTANCE.createGetCoverageType(); net.opengis.wcs10.SpatialSubsetType spatialSubset = Wcs10Factory.eINSTANCE.createSpatialSubsetType(); CoordinateReferenceSystem crs = CRS.decode("EPSG:3348", false); CoordinateReferenceSystem logCrs = CRS.decode("EPSG:4326", false); GeneralEnvelope env = new GeneralEnvelope( new double[] {5988504.35, 851278.90}, new double[] {7585113.55, 1950872.01}); env.setCoordinateReferenceSystem(crs); BoundingBox bbox = new ReferencedEnvelope(42.2802, 53.73, -95.1193, -71.295, logCrs); spatialSubset.getEnvelope().clear(); spatialSubset.getEnvelope().add(env); net.opengis.wcs10.DomainSubsetType domainSubset = Wcs10Factory.eINSTANCE.createDomainSubsetType(); domainSubset.setSpatialSubset(spatialSubset); gc.setSourceCoverage("acme:foo"); gc.setDomainSubset(domainSubset); callback.operationDispatched(new Request(), op("GetCoverage", "WCS", "1.0.0", gc)); assertEquals("acme:foo", data.getResources().get(0)); BBoxAsserts.assertEqualsBbox(bbox, data.getBbox(), 0.1); }
private GeneralEnvelope getResultEnvelope( final List<RasterQueryInfo> queryInfos, final GridEnvelope mosaicGeometry) { // use the same queryInfo used by setMosaicLocations final RasterQueryInfo baseQueryInfo = RasterUtils.findLowestResolution(queryInfos); GeneralEnvelope finalEnvelope = null; // if (queryInfos.size() == 1) { // finalEnvelope = queryInfos.get(0).getResultEnvelope(); // } else { int rasterIndex = baseQueryInfo.getRasterIndex(); int pyramidLevel = baseQueryInfo.getPyramidLevel(); MathTransform rasterToModel = rasterInfo.getRasterToModel(rasterIndex, pyramidLevel); CoordinateReferenceSystem coverageCrs = rasterInfo.getCoverageCrs(); GeneralEnvelope mosaicGeometryEnv = new GeneralEnvelope(coverageCrs); mosaicGeometryEnv.setEnvelope( mosaicGeometry.getLow(0), mosaicGeometry.getLow(1), 1 + mosaicGeometry.getHigh(0), 1 + mosaicGeometry.getHigh(1)); try { finalEnvelope = CRS.transform(rasterToModel, mosaicGeometryEnv); finalEnvelope.setCoordinateReferenceSystem(coverageCrs); } catch (TransformException e) { throw new RuntimeException(e); } // } // double[] resolution = baseQueryInfo.getResolution(); // finalEnvelope = toPixelCenter(resolution, finalEnvelope); return finalEnvelope; }
@Test public void testWCS10GetCoverage() throws Exception { GetCoverageType gc = Wcs10Factory.eINSTANCE.createGetCoverageType(); net.opengis.wcs10.SpatialSubsetType spatialSubset = Wcs10Factory.eINSTANCE.createSpatialSubsetType(); CoordinateReferenceSystem crs = CRS.decode("EPSG:4326"); GeneralEnvelope env = new GeneralEnvelope(new double[] {-123.4, 48.2}, new double[] {-120.9, 50.1}); env.setCoordinateReferenceSystem(crs); BoundingBox bbox = new ReferencedEnvelope(env); spatialSubset.getEnvelope().clear(); spatialSubset.getEnvelope().add(env); net.opengis.wcs10.DomainSubsetType domainSubset = Wcs10Factory.eINSTANCE.createDomainSubsetType(); domainSubset.setSpatialSubset(spatialSubset); gc.setSourceCoverage("acme:foo"); gc.setDomainSubset(domainSubset); callback.operationDispatched(new Request(), op("GetCoverage", "WCS", "1.0.0", gc)); assertEquals("acme:foo", data.getResources().get(0)); BBoxAsserts.assertEqualsBbox(bbox, data.getBbox(), 0.1); }
@Test public void testWCS11GetCoverage() throws Exception { net.opengis.wcs11.GetCoverageType gc = Wcs11Factory.eINSTANCE.createGetCoverageType(); CoordinateReferenceSystem crs = CRS.decode("EPSG:4326"); GeneralEnvelope env = new GeneralEnvelope(new double[] {48.2, -123.4}, new double[] {50.1, -120.9}); env.setCoordinateReferenceSystem(crs); BoundingBox bbox = new ReferencedEnvelope(env); net.opengis.ows11.BoundingBoxType wcsBbox = net.opengis.ows11.Ows11Factory.eINSTANCE.createBoundingBoxType(); wcsBbox.setLowerCorner(Arrays.asList(48.2d, -123.4d)); wcsBbox.setUpperCorner(Arrays.asList(50.1d, -120.9d)); // wcsBbox.setCrs("urn:ogc:def:crs:OGC:1.3:CRS84"); wcsBbox.setCrs("urn:ogc:def:crs:EPSG:4326"); net.opengis.wcs11.DomainSubsetType domainSubset = Wcs11Factory.eINSTANCE.createDomainSubsetType(); domainSubset.setBoundingBox(wcsBbox); gc.setDomainSubset(domainSubset); CodeType c = Ows11Factory.eINSTANCE.createCodeType(); c.setValue("acme:bar"); gc.setIdentifier(c); callback.operationDispatched(new Request(), op("GetCoverage", "WCS", "1.1.0", gc)); assertEquals("acme:bar", data.getResources().get(0)); BBoxAsserts.assertEqualsBbox(bbox, data.getBbox(), 0.1); }
/** * This method is responsible for computing the resolutions in for the provided grid geometry in * the provided crs. * * <p>It is worth to note that the returned resolution array is of length of 2 and it always is * lon, lat for the moment.<br> * It might be worth to remove the axes reordering code when we are confident enough with the code * to handle the north-up crs. * * <p>TODO use orthodromic distance? * * @param envelope the GeneralEnvelope * @param dim * @param crs * @throws DataSourceException */ protected static final double[] getResolution( GeneralEnvelope envelope, Rectangle2D dim, CoordinateReferenceSystem crs) throws DataSourceException { double[] requestedRes = null; try { if (dim != null && envelope != null && crs != null) { // do we need to transform the originalEnvelope? final CoordinateReferenceSystem envelopeCrs2D = CRS.getHorizontalCRS(envelope.getCoordinateReferenceSystem()); if (envelopeCrs2D != null && !CRS.equalsIgnoreMetadata(crs, envelopeCrs2D)) { CoordinateOperationFactory operationFactory = CRS.getCoordinateOperationFactory(true); CoordinateOperation op = operationFactory.createOperation(envelopeCrs2D, crs); envelope = CRS.transform(op, envelope); envelope.setCoordinateReferenceSystem(crs); } requestedRes = new double[2]; requestedRes[0] = envelope.getSpan(0) / dim.getWidth(); requestedRes[1] = envelope.getSpan(1) / dim.getHeight(); } return requestedRes; } catch (TransformException e) { throw new DataSourceException("Unable to get resolution", e); } catch (FactoryException e) { throw new DataSourceException("Unable to get resolution", e); } }
public void appendLoggingGeometries(String geomName, GeneralEnvelope env) { if (LOGGER.isLoggable(GEOM_LEVEL)) { StringBuilder sb = getGeom(geomName); sb.append( " ((" + env.getMinimum(0) + " " + env.getMinimum(1) + ", " + env.getMaximum(0) + " " + env.getMinimum(1) + ", " + env.getMaximum(0) + " " + env.getMaximum(1) + ", " + env.getMinimum(0) + " " + env.getMaximum(1) + ", " + env.getMinimum(0) + " " + env.getMinimum(1) + ")),"); } }
private static ReferencedEnvelope toReferencedEnvelope(GeneralEnvelope envelope) { double minx = envelope.getMinimum(0); double maxx = envelope.getMaximum(0); double miny = envelope.getMinimum(1); double maxy = envelope.getMaximum(1); CoordinateReferenceSystem crs = envelope.getCoordinateReferenceSystem(); ReferencedEnvelope refEnv = new ReferencedEnvelope(minx, maxx, miny, maxy, crs); return refEnv; }
private GeneralEnvelope toPixelCenter(double[] resolution, GeneralEnvelope pixelCornerEnv) { double deltaX = resolution[0] / 2; double deltaY = resolution[1] / 2; GeneralEnvelope env = new GeneralEnvelope(pixelCornerEnv.getCoordinateReferenceSystem()); env.setEnvelope( pixelCornerEnv.getMinimum(0) + deltaX, pixelCornerEnv.getMinimum(1) + deltaY, pixelCornerEnv.getMaximum(0) - deltaX, pixelCornerEnv.getMaximum(1) - deltaY); return env; }
@Test public void testDomainSubsetRxRy() throws Exception { // get base coverage final GridCoverage baseCoverage = catalog.getCoverageByName(TASMANIA_BM.getLocalPart()).getGridCoverage(null, null); final AffineTransform2D expectedTx = (AffineTransform2D) baseCoverage.getGridGeometry().getGridToCRS(); final GeneralEnvelope originalEnvelope = (GeneralEnvelope) baseCoverage.getEnvelope(); final GeneralEnvelope newEnvelope = new GeneralEnvelope(originalEnvelope); newEnvelope.setEnvelope( originalEnvelope.getMinimum(0), originalEnvelope.getMaximum(1) - originalEnvelope.getSpan(1) / 2, originalEnvelope.getMinimum(0) + originalEnvelope.getSpan(0) / 2, originalEnvelope.getMaximum(1)); final MathTransform cornerWorldToGrid = PixelTranslation.translate(expectedTx, PixelInCell.CELL_CENTER, PixelInCell.CELL_CORNER); final GeneralGridEnvelope expectedGridEnvelope = new GeneralGridEnvelope( CRS.transform(cornerWorldToGrid.inverse(), newEnvelope), PixelInCell.CELL_CORNER, false); final StringBuilder envelopeBuilder = new StringBuilder(); envelopeBuilder.append(newEnvelope.getMinimum(0)).append(","); envelopeBuilder.append(newEnvelope.getMinimum(1)).append(","); envelopeBuilder.append(newEnvelope.getMaximum(0)).append(","); envelopeBuilder.append(newEnvelope.getMaximum(1)); Map<String, Object> raw = baseMap(); final String layerID = getLayerId(TASMANIA_BM); raw.put("sourcecoverage", layerID); raw.put("version", "1.0.0"); raw.put("format", "image/geotiff"); raw.put("BBox", envelopeBuilder.toString()); raw.put("crs", "EPSG:4326"); raw.put("resx", Double.toString(expectedTx.getScaleX())); raw.put("resy", Double.toString(Math.abs(expectedTx.getScaleY()))); final GridCoverage[] coverages = executeGetCoverageKvp(raw); final GridCoverage2D result = (GridCoverage2D) coverages[0]; assertTrue(coverages.length == 1); final AffineTransform2D tx = (AffineTransform2D) result.getGridGeometry().getGridToCRS(); assertEquals("resx", expectedTx.getScaleX(), tx.getScaleX(), 1E-6); assertEquals("resx", Math.abs(expectedTx.getScaleY()), Math.abs(tx.getScaleY()), 1E-6); final GridEnvelope gridEnvelope = result.getGridGeometry().getGridRange(); assertEquals("w", 180, gridEnvelope.getSpan(0)); assertEquals("h", 180, gridEnvelope.getSpan(1)); assertEquals("grid envelope", expectedGridEnvelope, gridEnvelope); // dispose CoverageCleanerCallback.disposeCoverage(baseCoverage); CoverageCleanerCallback.disposeCoverage(coverages[0]); }
/** * Transforms the referenced envelope to the specified coordinate reference system using the * specified amount of points. * * <p>This method can handle the case where the envelope contains the North or South pole, or when * it cross the ±180� longitude. * * @param targetCRS The target coordinate reference system. * @param lenient {@code true} if datum shift should be applied even if there is insuffisient * information. Otherwise (if {@code false}), an exception is thrown in such case. * @param numPointsForTransformation The number of points to use for sampling the envelope. * @return The transformed envelope. * @throws FactoryException if the math transform can't be determined. * @throws TransformException if at least one coordinate can't be transformed. * @see CRS#transform(CoordinateOperation, org.opengis.geometry.Envelope) * @since 2.3 */ public ReferencedEnvelope transform( final CoordinateReferenceSystem targetCRS, final boolean lenient, final int numPointsForTransformation) throws TransformException, FactoryException { if (crs == null) { if (isEmpty()) { // We don't have a CRS yet because we are still empty, being empty is // something we can represent in the targetCRS return new ReferencedEnvelope(targetCRS); } else { // really this is a the code that created this ReferencedEnvelope throw new NullPointerException( "Unable to transform referenced envelope, crs has not yet been provided."); } } if (getDimension() != targetCRS.getCoordinateSystem().getDimension()) { if (lenient) { return JTS.transformTo3D(this, targetCRS, lenient, numPointsForTransformation); } else { throw new MismatchedDimensionException( Errors.format( ErrorKeys.MISMATCHED_DIMENSION_$3, crs.getName().getCode(), new Integer(getDimension()), new Integer(targetCRS.getCoordinateSystem().getDimension()))); } } /* * Gets a first estimation using an algorithm capable to take singularity in account * (North pole, South pole, 180� longitude). We will expand this initial box later. */ CoordinateOperationFactory coordinateOperationFactory = CRS.getCoordinateOperationFactory(lenient); final CoordinateOperation operation = coordinateOperationFactory.createOperation(crs, targetCRS); final GeneralEnvelope transformed = CRS.transform(operation, this); transformed.setCoordinateReferenceSystem(targetCRS); /* * Now expands the box using the usual utility methods. */ final ReferencedEnvelope target = new ReferencedEnvelope(transformed); final MathTransform transform = operation.getMathTransform(); JTS.transform(this, target, transform, numPointsForTransformation); return target; }
/** * Convert the crop envelope into a polygon and the use the world-to-grid transform to get a ROI * for the source coverage. */ public static Polygon getPolygon(final GeneralEnvelope env, final GeometryFactory gf) throws IllegalStateException, MismatchedDimensionException { final Rectangle2D rect = env.toRectangle2D(); final Coordinate[] coord = new Coordinate[] { new Coordinate(rect.getMinX(), rect.getMinY()), new Coordinate(rect.getMinX(), rect.getMaxY()), new Coordinate(rect.getMaxX(), rect.getMaxY()), new Coordinate(rect.getMaxX(), rect.getMinY()), new Coordinate(rect.getMinX(), rect.getMinY()) }; final LinearRing ring = gf.createLinearRing(coord); final Polygon modelSpaceROI = new Polygon(ring, null, gf); // check that we have the same thing here assert modelSpaceROI .getEnvelopeInternal() .equals(new ReferencedEnvelope(rect, env.getCoordinateReferenceSystem())); return modelSpaceROI; }
private GridCoverage2D convertImageToGridCoverage( ReferencedEnvelope requestBBox, BufferedImage image) throws RenderException { Envelope env = requestBBox; GeneralEnvelope gtEnv = new GeneralEnvelope( new double[] {env.getMinX(), env.getMinY()}, new double[] {env.getMaxX(), env.getMaxY()}); try { gtEnv.setCoordinateReferenceSystem(requestBBox.getCoordinateReferenceSystem()); } catch (Exception e) { throw wrapException(e); } GridCoverageFactory factory = new GridCoverageFactory(); GridCoverage2D gc = (GridCoverage2D) factory.create("GridCoverage", image, gtEnv); // $NON-NLS-1$ return gc; }
/** * Tests the transformations of an envelope when the two CRS have identify transforms but * different datum names */ @Test public void testEnvelopeTransformation2() throws FactoryException, TransformException { final CoordinateReferenceSystem WGS84Altered = CRS.parseWKT(WKT.WGS84_ALTERED); final CoordinateReferenceSystem WGS84 = DefaultGeographicCRS.WGS84; final MathTransform crsTransform = CRS.findMathTransform(WGS84, WGS84Altered, true); assertTrue(crsTransform.isIdentity()); final GeneralEnvelope firstEnvelope; firstEnvelope = new GeneralEnvelope(new double[] {-124, 42}, new double[] {-122, 43}); firstEnvelope.setCoordinateReferenceSystem(WGS84); // this triggered a assertion error in GEOT-2934 Envelope transformed = CRS.transform(firstEnvelope, WGS84Altered); // check the envelope is what we expect assertEquals(transformed.getCoordinateReferenceSystem(), WGS84Altered); double EPS = 1e-9; assertEquals(transformed.getMinimum(0), firstEnvelope.getMinimum(0), EPS); assertEquals(transformed.getMinimum(1), firstEnvelope.getMinimum(1), EPS); assertEquals(transformed.getMaximum(0), firstEnvelope.getMaximum(0), EPS); assertEquals(transformed.getMaximum(1), firstEnvelope.getMaximum(1), EPS); }
/** Tests the transformations of an envelope. */ @Test public void testEnvelopeTransformation() throws FactoryException, TransformException { final CoordinateReferenceSystem mapCRS = CRS.parseWKT(WKT.UTM_10N); final CoordinateReferenceSystem WGS84 = DefaultGeographicCRS.WGS84; final MathTransform crsTransform = CRS.findMathTransform(WGS84, mapCRS, true); assertFalse(crsTransform.isIdentity()); final GeneralEnvelope firstEnvelope, transformedEnvelope, oldEnvelope; firstEnvelope = new GeneralEnvelope(new double[] {-124, 42}, new double[] {-122, 43}); firstEnvelope.setCoordinateReferenceSystem(WGS84); transformedEnvelope = CRS.transform(crsTransform, firstEnvelope); transformedEnvelope.setCoordinateReferenceSystem(mapCRS); oldEnvelope = CRS.transform(crsTransform.inverse(), transformedEnvelope); oldEnvelope.setCoordinateReferenceSystem(WGS84); assertTrue(oldEnvelope.contains(firstEnvelope, true)); assertTrue(oldEnvelope.equals(firstEnvelope, 0.02, true)); }
/** * @param env GeneralEnvelope * @return Polygon object with the same boundary as env */ protected Polygon polyFromEnvelope(GeneralEnvelope env) { GeometryFactory factory = new GeometryFactory(); Coordinate[] coords = new Coordinate[] { new Coordinate(env.getMinimum(0), env.getMinimum(1)), new Coordinate(env.getMinimum(0), env.getMaximum(1)), new Coordinate(env.getMaximum(0), env.getMaximum(1)), new Coordinate(env.getMaximum(0), env.getMinimum(1)), new Coordinate(env.getMinimum(0), env.getMinimum(1)) }; return factory.createPolygon(factory.createLinearRing(coords), new LinearRing[0]); }
/** * <strong>Cropping</strong><br> * The crop operation is responsible for selecting geographic subareas of the source coverage. * * @param coverage Coverage * @param sourceEnvelope GeneralEnvelope * @param sourceCRS CoordinateReferenceSystem * @param destinationEnvelopeInSourceCRS GeneralEnvelope * @return GridCoverage2D * @throws WcsException */ public static GridCoverage2D crop( final Coverage coverage, final GeneralEnvelope sourceEnvelope, final CoordinateReferenceSystem sourceCRS, final GeneralEnvelope destinationEnvelopeInSourceCRS, final Boolean conserveEnvelope) throws WcsException { // /////////////////////////////////////////////////////////////////// // // CROP // // // /////////////////////////////////////////////////////////////////// final GridCoverage2D croppedGridCoverage; // intersect the envelopes final GeneralEnvelope intersectionEnvelope = new GeneralEnvelope(destinationEnvelopeInSourceCRS); intersectionEnvelope.setCoordinateReferenceSystem(sourceCRS); intersectionEnvelope.intersect((GeneralEnvelope) sourceEnvelope); // dow we have something to show? if (intersectionEnvelope.isEmpty()) { throw new WcsException("The Intersection is null. Check the requested BBOX!"); } if (!intersectionEnvelope.equals((GeneralEnvelope) sourceEnvelope)) { // get the cropped grid geometry // final GridGeometry2D cropGridGeometry = getCroppedGridGeometry( // intersectionEnvelope, gridCoverage); /* Operations.DEFAULT.crop(coverage, intersectionEnvelope) */ final ParameterValueGroup param = (ParameterValueGroup) cropParams.clone(); param.parameter("Source").setValue(coverage); param.parameter("Envelope").setValue(intersectionEnvelope); // param.parameter("ConserveEnvelope").setValue(conserveEnvelope); croppedGridCoverage = (GridCoverage2D) cropFactory.doOperation(param, hints); } else { croppedGridCoverage = (GridCoverage2D) coverage; } // prefetch to be faster afterwards. // This step is important since at this stage we might be loading tiles // from disk croppedGridCoverage.prefetch(intersectionEnvelope.toRectangle2D()); return croppedGridCoverage; }
@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 } } } }
/* * (non-Javadoc) * * @see org.geotools.gce.imagemosaic.jdbc.JDBCAccess#startTileDecoders(java.awt.Rectangle, * org.geotools.geometry.GeneralEnvelope, * org.geotools.gce.imagemosaic.jdbc.ImageLevelInfo, * java.util.concurrent.LinkedBlockingQueue) */ public void startTileDecoders( Rectangle pixelDimension, GeneralEnvelope requestEnvelope, ImageLevelInfo levelInfo, LinkedBlockingQueue<TileQueueElement> tileQueue, GridCoverageFactory coverageFactory) throws IOException { Date start = new Date(); Connection con = null; List<ImageDecoderThread> threads = new ArrayList<ImageDecoderThread>(); ExecutorService pool = getExecutorServivicePool(); String statementString = getGridSelectStatement(levelInfo); try { con = dataSource.getConnection(); PreparedStatement s = con.prepareStatement(statementString); setGridSelectParams(s, requestEnvelope, levelInfo); ResultSet r = s.executeQuery(); while (r.next()) { byte[] tileBytes = getTileBytes(r); Envelope env = getEnvelopeFromResultSet(r); String location = r.getString(config.getKeyAttributeNameInSpatialTable()); Rectangle2D tmp = new Rectangle2D.Double(env.getMinX(), env.getMinY(), env.getWidth(), env.getHeight()); GeneralEnvelope tileGeneralEnvelope = new GeneralEnvelope(tmp); tileGeneralEnvelope.setCoordinateReferenceSystem( requestEnvelope.getCoordinateReferenceSystem()); ImageDecoderThread thread = new ImageDecoderThread( tileBytes, location, tileGeneralEnvelope, pixelDimension, requestEnvelope, levelInfo, tileQueue, config); // thread.start(); threads.add(thread); pool.execute(thread); } ; r.close(); s.close(); // if (con.getAutoCommit() == false) { // con.commit(); // } con.close(); } catch (SQLException e) { try { // if (con.getAutoCommit() == false) { // con.rollback(); // } con.close(); } catch (SQLException e1) { } LOGGER.log(Level.SEVERE, e.getMessage(), e); throw new IOException(e); } if (LOGGER.isLoggable(Level.INFO)) LOGGER.info( "Getting " + threads.size() + " Tiles needs " + ((new Date()).getTime() - start.getTime()) + " millisecs"); // wait for all threads dto finish and write end marker pool.shutdown(); try { pool.awaitTermination(3600, TimeUnit.SECONDS); // wait for one hour } catch (InterruptedException e) { throw new RuntimeException(e.getLocalizedMessage()); } // for (AbstractThread thread : threads) { // try { // thread.join(); // } catch (InterruptedException e) { // throw new RuntimeException(e.getLocalizedMessage()); // } // } tileQueue.add(TileQueueElement.ENDELEMENT); if (LOGGER.isLoggable(Level.INFO)) LOGGER.info( "Getting and decoding " + threads.size() + " Tiles needs " + ((new Date()).getTime() - start.getTime()) + " millisecs"); }
@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 } } } }
/** * Applies the band select operation to a grid coverage. * * @param cropEnvelope the target envelope; always not null * @param cropROI the target ROI shape; nullable * @param roiTolerance; as read from op's params * @param sourceCoverage is the source {@link GridCoverage2D} that we want to crop. * @param hints A set of rendering hints, or {@code null} if none. * @param sourceGridToWorldTransform is the 2d grid-to-world transform for the source coverage. * @return The result as a grid coverage. */ private static GridCoverage2D buildResult( final GeneralEnvelope cropEnvelope, final Geometry cropROI, final double roiTolerance, final boolean forceMosaic, final Hints hints, final GridCoverage2D sourceCoverage, final AffineTransform sourceGridToWorldTransform) { // // Getting the source coverage and its child geolocation objects // final RenderedImage sourceImage = sourceCoverage.getRenderedImage(); final GridGeometry2D sourceGridGeometry = ((GridGeometry2D) sourceCoverage.getGridGeometry()); final GridEnvelope2D sourceGridRange = sourceGridGeometry.getGridRange2D(); // // Now we try to understand if we have a simple scale and translate or a // more elaborated grid-to-world transformation n which case a simple // crop could not be enough, but we may need a more elaborated chain of // operation in order to do a good job. As an instance if we // have a rotation which is not multiple of PI/2 we have to use // the mosaic with a ROI // final boolean isSimpleTransform = CoverageUtilities.isSimpleGridToWorldTransform(sourceGridToWorldTransform, EPS); // Do we need to explode the Palette to RGB(A)? // int actionTaken = 0; // // // // Layout // // // final RenderingHints targetHints = new RenderingHints(null); if (hints != null) targetHints.add(hints); final ImageLayout layout = initLayout(sourceImage, targetHints); targetHints.put(JAI.KEY_IMAGE_LAYOUT, layout); // // prepare the processor to use for this operation // final JAI processor = OperationJAI.getJAI(targetHints); final boolean useProvidedProcessor = !processor.equals(JAI.getDefaultInstance()); try { if (cropROI != null) { // replace the cropEnvelope with the envelope of the intersection // of the ROI and the cropEnvelope. // Remember that envelope(intersection(roi,cropEnvelope)) != intersection(cropEnvelope, // envelope(roi)) final Polygon modelSpaceROI = FeatureUtilities.getPolygon(cropEnvelope, GFACTORY); Geometry intersection = IntersectUtils.intersection(cropROI, modelSpaceROI); Envelope2D e2d = JTS.getEnvelope2D( intersection.getEnvelopeInternal(), cropEnvelope.getCoordinateReferenceSystem()); GeneralEnvelope ge = new GeneralEnvelope((org.opengis.geometry.Envelope) e2d); cropEnvelope.setEnvelope(ge); } // // // // Build the new range by keeping into // account translation of grid geometry constructor for respecting // OGC PIXEL-IS-CENTER ImageDatum assumption. // // // final AffineTransform sourceWorldToGridTransform = sourceGridToWorldTransform.createInverse(); // // // // finalRasterArea will hold the smallest rectangular integer raster area that contains the // floating point raster // area which we obtain when applying the world-to-grid transform to the cropEnvelope. Note // that we need to intersect // such an area with the area covered by the source coverage in order to be sure we do not try // to crop outside the // bounds of the source raster. // // // final Rectangle2D finalRasterAreaDouble = XAffineTransform.transform( sourceWorldToGridTransform, cropEnvelope.toRectangle2D(), null); final Rectangle finalRasterArea = finalRasterAreaDouble.getBounds(); // intersection with the original range in order to not try to crop outside the image bounds Rectangle.intersect(finalRasterArea, sourceGridRange, finalRasterArea); if (finalRasterArea.isEmpty()) throw new CannotCropException(Errors.format(ErrorKeys.CANT_CROP)); // // // // It is worth to point out that doing a crop the G2W transform // should not change while the envelope might change as // a consequence of the rounding of the underlying image datum // which uses integer factors or in case the G2W is very // complex. Note that we will always strive to // conserve the original grid-to-world transform. // // // // we do not have to crop in this case (should not really happen at // this time) if (finalRasterArea.equals(sourceGridRange) && isSimpleTransform && cropROI == null) return sourceCoverage; // // // // if I get here I have something to crop // using the world-to-grid transform for going from envelope to the // new grid range. // // // final double minX = finalRasterArea.getMinX(); final double minY = finalRasterArea.getMinY(); final double width = finalRasterArea.getWidth(); final double height = finalRasterArea.getHeight(); // // // // Check if we need to use mosaic or crop // // // final PlanarImage croppedImage; final ParameterBlock pbj = new ParameterBlock(); pbj.addSource(sourceImage); java.awt.Polygon rasterSpaceROI = null; String operatioName = null; if (!isSimpleTransform || cropROI != null) { // ///////////////////////////////////////////////////////////////////// // // We don't have a simple scale and translate transform, JAI // crop MAY NOT suffice. Let's decide whether or not we'll use // the Mosaic. // // ///////////////////////////////////////////////////////////////////// Polygon modelSpaceROI = FeatureUtilities.getPolygon(cropEnvelope, GFACTORY); // // // // Now convert this polygon back into a shape for the source // raster space. // // // final List<Point2D> points = new ArrayList<Point2D>(5); rasterSpaceROI = FeatureUtilities.convertPolygonToPointArray( modelSpaceROI, ProjectiveTransform.create(sourceWorldToGridTransform), points); if (rasterSpaceROI == null || rasterSpaceROI.getBounds().isEmpty()) if (finalRasterArea.isEmpty()) throw new CannotCropException(Errors.format(ErrorKeys.CANT_CROP)); final boolean doMosaic = forceMosaic ? true : decideJAIOperation(roiTolerance, rasterSpaceROI.getBounds2D(), points); if (doMosaic || cropROI != null) { // prepare the params for the mosaic final ROI[] roiarr; try { if (cropROI != null) { final LiteShape2 cropRoiLS2 = new LiteShape2( cropROI, ProjectiveTransform.create(sourceWorldToGridTransform), null, false); ROI cropRS = new ROIShape(cropRoiLS2); Rectangle2D rt = cropRoiLS2.getBounds2D(); if (!hasIntegerBounds(rt)) { // Approximate Geometry Geometry geo = (Geometry) cropRoiLS2.getGeometry().clone(); transformGeometry(geo); cropRS = new ROIShape(new LiteShape2(geo, null, null, false)); } roiarr = new ROI[] {cropRS}; } else { final ROIShape roi = new ROIShape(rasterSpaceROI); roiarr = new ROI[] {roi}; } } catch (FactoryException ex) { throw new CannotCropException(Errors.format(ErrorKeys.CANT_CROP), ex); } pbj.add(MosaicDescriptor.MOSAIC_TYPE_OVERLAY); pbj.add(null); pbj.add(roiarr); pbj.add(null); pbj.add(CoverageUtilities.getBackgroundValues(sourceCoverage)); // prepare the final layout final Rectangle bounds = rasterSpaceROI.getBounds2D().getBounds(); Rectangle.intersect(bounds, sourceGridRange, bounds); if (bounds.isEmpty()) throw new CannotCropException(Errors.format(ErrorKeys.CANT_CROP)); // we do not have to crop in this case (should not really happen at // this time) if (!doMosaic && bounds.getBounds().equals(sourceGridRange) && isSimpleTransform) return sourceCoverage; // nice trick, we use the layout to do the actual crop final Rectangle boundsInt = bounds.getBounds(); layout.setMinX(boundsInt.x); layout.setWidth(boundsInt.width); layout.setMinY(boundsInt.y); layout.setHeight(boundsInt.height); operatioName = "Mosaic"; } } // do we still have to set the operation name? If so that means we have to go for crop. if (operatioName == null) { // executing the crop pbj.add((float) minX); pbj.add((float) minY); pbj.add((float) width); pbj.add((float) height); operatioName = "GTCrop"; } // // // // Apply operation // // // if (!useProvidedProcessor) { croppedImage = JAI.create(operatioName, pbj, targetHints); } else { croppedImage = processor.createNS(operatioName, pbj, targetHints); } // conserve the input grid to world transformation Map sourceProperties = sourceCoverage.getProperties(); Map properties = null; if (sourceProperties != null && !sourceProperties.isEmpty()) { properties = new HashMap(sourceProperties); } if (rasterSpaceROI != null) { if (properties != null) { properties.put("GC_ROI", rasterSpaceROI); } else { properties = Collections.singletonMap("GC_ROI", rasterSpaceROI); } } return new GridCoverageFactory(hints) .create( sourceCoverage.getName(), croppedImage, new GridGeometry2D( new GridEnvelope2D(croppedImage.getBounds()), sourceGridGeometry.getGridToCRS2D(PixelOrientation.CENTER), sourceCoverage.getCoordinateReferenceSystem()), (GridSampleDimension[]) (actionTaken == 1 ? null : sourceCoverage.getSampleDimensions().clone()), new GridCoverage[] {sourceCoverage}, properties); } catch (TransformException e) { throw new CannotCropException(Errors.format(ErrorKeys.CANT_CROP), e); } catch (NoninvertibleTransformException e) { throw new CannotCropException(Errors.format(ErrorKeys.CANT_CROP), e); } }
/** * Applies a crop operation to a coverage. * * @see * org.geotools.coverage.processing.AbstractOperation#doOperation(org.opengis.parameter.ParameterValueGroup, * org.geotools.factory.Hints) */ @SuppressWarnings("unchecked") public Coverage doOperation(ParameterValueGroup parameters, Hints hints) { final Geometry cropRoi; // extracted from parameters GeneralEnvelope cropEnvelope = null; // extracted from parameters final GridCoverage2D source; // extracted from parameters final double roiTolerance = parameters.parameter(Crop.PARAMNAME_ROITOLERANCE).doubleValue(); final boolean forceMosaic = parameters.parameter(Crop.PARAMNAME_FORCEMOSAIC).booleanValue(); // ///////////////////////////////////////////////////////////////////// // // Assigning and checking input parameters // // /////////////////////////////////////////////////////////////////// // source coverage final ParameterValue sourceParameter = parameters.parameter("Source"); if (sourceParameter == null || !(sourceParameter.getValue() instanceof GridCoverage2D)) { throw new CannotCropException( Errors.format(ErrorKeys.NULL_PARAMETER_$2, "Source", GridCoverage2D.class.toString())); } source = (GridCoverage2D) sourceParameter.getValue(); // Check Envelope and ROI existence - we need at least one of them final ParameterValue envelopeParameter = parameters.parameter(PARAMNAME_ENVELOPE); final ParameterValue roiParameter = parameters.parameter(PARAMNAME_ROI); if ((envelopeParameter == null || envelopeParameter.getValue() == null) && (roiParameter == null || roiParameter.getValue() == null)) throw new CannotCropException( Errors.format( ErrorKeys.NULL_PARAMETER_$2, PARAMNAME_ENVELOPE, GeneralEnvelope.class.toString())); Object envelope = envelopeParameter.getValue(); if (envelope != null) { if (envelope instanceof GeneralEnvelope) { cropEnvelope = (GeneralEnvelope) envelope; } else if (envelope instanceof Envelope) { cropEnvelope = new GeneralEnvelope((Envelope) envelope); } } // may be null // Check crop ROI try { cropRoi = IntersectUtils.unrollGeometries( (Geometry) roiParameter.getValue()); // may throw if format not correct } catch (IllegalArgumentException ex) { throw new CannotCropException( Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$2, PARAMNAME_ROI, ex.getMessage()), ex); } // Setting a GeneralEnvelope from ROI if needed if (cropRoi != null && cropEnvelope == null) { Envelope e2d = JTS.getEnvelope2D(cropRoi.getEnvelopeInternal(), source.getCoordinateReferenceSystem()); cropEnvelope = new GeneralEnvelope(e2d); } // ///////////////////////////////////////////////////////////////////// // // Initialization // // We take the crop envelope and the source envelope then we check their // crs and we also check if they ever overlap. // // ///////////////////////////////////////////////////////////////////// // envelope of the source coverage final Envelope2D sourceEnvelope = source.getEnvelope2D(); // crop envelope Envelope2D destinationEnvelope = new Envelope2D(cropEnvelope); CoordinateReferenceSystem sourceCRS = sourceEnvelope.getCoordinateReferenceSystem(); CoordinateReferenceSystem destinationCRS = destinationEnvelope.getCoordinateReferenceSystem(); if (destinationCRS == null) { // Do not change the user provided object - clone it first. final Envelope2D ge = new Envelope2D(destinationEnvelope); destinationCRS = source.getCoordinateReferenceSystem2D(); ge.setCoordinateReferenceSystem(destinationCRS); destinationEnvelope = ge; } // // // // Source and destination crs must be equals // // // if (!CRS.equalsIgnoreMetadata(sourceCRS, destinationCRS)) { throw new CannotCropException( Errors.format( ErrorKeys.MISMATCHED_ENVELOPE_CRS_$2, sourceCRS.getName().getCode(), destinationCRS.getName().getCode())); } if (cropRoi != null) { // TODO: check ROI SRID } // // // // Check the intersection and, if needed, do the crop operation. // // // final GeneralEnvelope intersectionEnvelope = new GeneralEnvelope((Envelope) destinationEnvelope); intersectionEnvelope.setCoordinateReferenceSystem(source.getCoordinateReferenceSystem()); // intersect the envelopes intersectionEnvelope.intersect(sourceEnvelope); if (intersectionEnvelope.isEmpty()) throw new CannotCropException(Errors.format(ErrorKeys.CANT_CROP)); // intersect the ROI with the intersection envelope and throw an error if they do not intersect if (cropRoi != null) { final Geometry jis = JTS.toGeometry( (com.vividsolutions.jts.geom.Envelope) new ReferencedEnvelope(intersectionEnvelope)); if (!IntersectUtils.intersects(cropRoi, jis)) throw new CannotCropException(Errors.format(ErrorKeys.CANT_CROP)); } // // // // Get the grid-to-world transform by keeping into account translation // of grid geometry constructor for respecting OGC PIXEL-IS-CENTER // ImageDatum assumption. // // // final AffineTransform sourceCornerGridToWorld = (AffineTransform) ((GridGeometry2D) source.getGridGeometry()).getGridToCRS(PixelInCell.CELL_CORNER); // // // // I set the tolerance as half the scale factor of the grid-to-world // transform. This should more or less means in most cases "don't bother // to crop if the new envelope is as close to the old one that we go // deep under pixel size." // // // final double tolerance = XAffineTransform.getScale(sourceCornerGridToWorld); if (cropRoi != null || !intersectionEnvelope.equals(sourceEnvelope, tolerance / 2.0, false)) { cropEnvelope = intersectionEnvelope.clone(); return buildResult( cropEnvelope, cropRoi, roiTolerance, forceMosaic, (hints instanceof Hints) ? (Hints) hints : new Hints(hints), source, sourceCornerGridToWorld); } else { // // // // Note that in case we don't crop at all, WE DO NOT UPDATE the // envelope. If we did we might end up doing multiple successive // crop without actually cropping the image but, still, we would // shrink the envelope each time. Just think about having a loop // that crops recursively the same coverage specifying each time an // envelope whose URC is only a a scale quarter close to the LLC of // the old one. We would never crop the raster but we would modify // the grid-to-world transform each time. // // // return source; } }
@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 } } } }
private ArcSDEGridCoverage2DReaderJAI.ReadParameters parseReadParams( final GeneralParameterValue[] params) throws IllegalArgumentException { if (params == null) { throw new IllegalArgumentException("No GeneralParameterValue given to read operation"); } GeneralEnvelope reqEnvelope = null; GridEnvelope dim = null; OverviewPolicy overviewPolicy = null; // ///////////////////////////////////////////////////////////////////// // // Checking params // // ///////////////////////////////////////////////////////////////////// for (int i = 0; i < params.length; i++) { final ParameterValue<?> param = (ParameterValue<?>) params[i]; final String name = param.getDescriptor().getName().getCode(); if (name.equals(AbstractGridFormat.READ_GRIDGEOMETRY2D.getName().toString())) { final GridGeometry2D gg = (GridGeometry2D) param.getValue(); reqEnvelope = new GeneralEnvelope((Envelope) gg.getEnvelope2D()); final GeneralEnvelope coverageEnvelope = getOriginalEnvelope(); CoordinateReferenceSystem nativeCrs = coverageEnvelope.getCoordinateReferenceSystem(); CoordinateReferenceSystem requestCrs = reqEnvelope.getCoordinateReferenceSystem(); if (!CRS.equalsIgnoreMetadata(nativeCrs, requestCrs)) { LOGGER.fine( "Request CRS and native CRS differ, " + "reprojecting request envelope to native CRS"); ReferencedEnvelope nativeCrsEnv; nativeCrsEnv = toNativeCrs(reqEnvelope, nativeCrs); reqEnvelope = new GeneralEnvelope(nativeCrsEnv); } dim = gg.getGridRange2D(); continue; } if (name.equals(AbstractGridFormat.OVERVIEW_POLICY.getName().toString())) { overviewPolicy = (OverviewPolicy) param.getValue(); continue; } } if (reqEnvelope == null && dim == null) { reqEnvelope = getOriginalEnvelope(); dim = getOriginalGridRange(); } if (reqEnvelope == null) { reqEnvelope = getOriginalEnvelope(); } if (dim == null) { final GeneralEnvelope adjustedGRange; try { MathTransform gridToWorld = getOriginalGridToWorld(PixelInCell.CELL_CENTER); MathTransform worldToGrid = gridToWorld.inverse(); adjustedGRange = CRS.transform(worldToGrid, reqEnvelope); } catch (Exception e) { throw new RuntimeException(e); } int xmin = (int) Math.floor(adjustedGRange.getMinimum(0)); int ymin = (int) Math.floor(adjustedGRange.getMinimum(1)); int xmax = (int) Math.ceil(adjustedGRange.getMaximum(0)); int ymax = (int) Math.ceil(adjustedGRange.getMaximum(1)); dim = new GridEnvelope2D(xmin, ymin, xmax - xmin, ymax - ymin); } if (!reqEnvelope.intersects(getOriginalEnvelope(), true)) { throw new IllegalArgumentException( "The requested extend does not overlap the coverage extent: " + getOriginalEnvelope()); } if (dim.getSpan(0) <= 0 || dim.getSpan(1) <= 0) { throw new IllegalArgumentException("The requested coverage dimension can't be null: " + dim); } if (overviewPolicy == null) { overviewPolicy = OverviewPolicy.NEAREST; LOGGER.finer("No overview policy requested, defaulting to " + overviewPolicy); } LOGGER.fine("Overview policy is " + overviewPolicy); ArcSDEGridCoverage2DReaderJAI.ReadParameters parsedParams = new ArcSDEGridCoverage2DReaderJAI.ReadParameters(); parsedParams.requestedEnvelope = reqEnvelope; parsedParams.dim = dim; parsedParams.overviewPolicy = overviewPolicy; return parsedParams; }
/** * @see GridCoverageReader#read(GeneralParameterValue[]) * @return A new {@linkplain GridCoverage grid coverage} from the input source, or {@code null} if * the requested envelope is outside the data bounds */ public GridCoverage2D read(GeneralParameterValue[] params) throws IOException { final GeneralEnvelope requestedEnvelope; final GridEnvelope requestedDim; final OverviewPolicy overviewPolicy; { final ReadParameters opParams = parseReadParams(params); overviewPolicy = opParams.overviewPolicy; requestedEnvelope = opParams.requestedEnvelope; requestedDim = opParams.dim; } /* * For each raster in the raster dataset, obtain the tiles, pixel range, and resulting * envelope */ final List<RasterQueryInfo> queries; queries = findMatchingRasters(requestedEnvelope, requestedDim, overviewPolicy); if (queries.isEmpty()) { if (requestedEnvelope.intersects(getOriginalEnvelope(), true)) { /* * No matching rasters but envelopes intersect, meaning it's a raster catalog with * irregular coverage and the request lies on an area with no coverage */ ImageTypeSpecifier imageTypeSpecifier; imageTypeSpecifier = RasterUtils.createFullImageTypeSpecifier(rasterInfo, 0); SampleModel sampleModel = imageTypeSpecifier.getSampleModel(); Point location = new Point(0, 0); WritableRaster raster = Raster.createWritableRaster(sampleModel, location); GridCoverage2D emptyCoverage; emptyCoverage = coverageFactory.create(coverageName, raster, requestedEnvelope); return emptyCoverage; } /* * none of the rasters match the requested envelope. */ return null; } final LoggingHelper log = new LoggingHelper(); /* * Once we collected the matching rasters and their image subsets, find out where in the * overall resulting mosaic they fit. If the rasters does not share the spatial resolution, * the QueryInfo.resultDimension and QueryInfo.mosaicLocation width or height won't match */ final GridEnvelope mosaicGeometry; mosaicGeometry = RasterUtils.setMosaicLocations(rasterInfo, queries); if (mosaicGeometry.getSpan(0) == 0 || mosaicGeometry.getSpan(1) == 0) { LOGGER.finer( "Mosaic geometry width or height is zero," + " returning fake coverage for pixels " + mosaicGeometry); return null; } /* * Gather the rendered images for each of the rasters that match the requested envelope */ final TiledRasterReader rasterReader = rasterReaderFactory.create(rasterInfo); try { readAllTiledRasters(queries, rasterReader, log); } finally { // rasterReader.dispose(); } log.log(LoggingHelper.REQ_ENV); log.log(LoggingHelper.RES_ENV); log.log(LoggingHelper.MOSAIC_ENV); log.log(LoggingHelper.MOSAIC_EXPECTED); final RenderedImage coverageRaster = createMosaic(queries, mosaicGeometry, log); assert mosaicGeometry.getSpan(0) == coverageRaster.getWidth(); assert mosaicGeometry.getSpan(1) == coverageRaster.getHeight(); /* * BUILDING COVERAGE */ GridSampleDimension[] bands = getSampleDimensions(coverageRaster); final GeneralEnvelope resultEnvelope = getResultEnvelope(queries, mosaicGeometry); log.appendLoggingGeometries(LoggingHelper.REQ_ENV, requestedEnvelope); log.appendLoggingGeometries(LoggingHelper.RES_ENV, resultEnvelope); GridCoverage2D resultCoverage = coverageFactory.create(coverageName, coverageRaster, resultEnvelope, bands, null, null); // MathTransform gridToCRS = rasterInfo.getRasterToModel(queries.get(0).getRasterIndex(), // queries.get(0).getPyramidLevel()); // // GridGeometry2D gridGeometry = new GridGeometry2D(PixelInCell.CELL_CORNER, gridToCRS, // resultEnvelope, hints); // // GridCoverage[] sources = null; // Map<?, ?> properties = null; // GridCoverage2D resultCoverage = coverageFactory.create(coverageName, coverageRaster, // gridGeometry, bands, sources, properties); return resultCoverage; }
public boolean extractTiffMetadata(File tifFile, TiffMeta surface) throws UnknownCRSException, FactoryException, TransformException, IOException { Preconditions.checkArgument(tifFile != null, "File is null."); GeoTiffReader gtr = new GeoTiffReader(tifFile); try { CoordinateReferenceSystem crs = gtr.getCoordinateReferenceSystem(); surface.setCRS(crs); Integer epsgCode = CRS.lookupEpsgCode(crs, true); if (epsgCode == null) { ReferenceIdentifier name = crs.getName(); String crsName = "Unknown"; if (name != null) { crsName = name.toString(); } throw new UnknownCRSException(crsName); } String srid = "EPSG:" + epsgCode; surface.setSrid(srid); // // extremaOp(surface, gtr.read(null)); /* * Build the envelope and set to WGS84 */ GeneralEnvelope origEnv = gtr.getOriginalEnvelope(); DirectPosition ll = origEnv.getLowerCorner(); DirectPosition ur = origEnv.getUpperCorner(); Envelope e = new Envelope(); e.expandToInclude(ll.getOrdinate(0), ll.getOrdinate(1)); e.expandToInclude(ur.getOrdinate(0), ur.getOrdinate(1)); Geometry poly = envelopeToWgs84(epsgCode, e); if (poly instanceof Polygon) { surface.setEnvelope((Polygon) poly); } /* * Figure out the pixel size */ ImageLayout imageLayout = gtr.getImageLayout(); int imageWidth = imageLayout.getWidth(null); int imageHeight = imageLayout.getHeight(null); double pixelSizeX = e.getWidth() / imageWidth; double pixelSizeY = e.getHeight() / imageHeight; surface.setPixelSizeX(pixelSizeX); surface.setPixelSizeY(pixelSizeY); surface.setMinVal(0d); surface.setMaxVal(100d); GridCoverage2D gridCoverage2D = gtr.read(null); try { int nDims = gridCoverage2D.getNumSampleDimensions(); surface.setNumSampleDimensions(nDims); extremaOp(surface, gridCoverage2D); } finally { gridCoverage2D.dispose(false); } } finally { gtr.dispose(); } return true; }
private void computeCropBBOX() throws DataSourceException { // get the crs for the requested bbox if (requestCRS == null) requestCRS = CRS.getHorizontalCRS(requestedBBox.getCoordinateReferenceSystem()); try { // // The destination to source transform has been computed (and eventually erased) already // by inspectCoordinateSystem() // now transform the requested envelope to source crs if (destinationToSourceTransform != null && !destinationToSourceTransform.isIdentity()) { final GeneralEnvelope temp = new GeneralEnvelope(CRS.transform(requestedBBox, coverageProperties.crs2D)); temp.setCoordinateReferenceSystem(coverageProperties.crs2D); cropBBox = new ReferencedEnvelope(temp); needsReprojection = true; } else { // we do not need to do anything, but we do this in order to aboid problems with the // envelope checks cropBBox = new ReferencedEnvelope( requestedBBox.getMinX(), requestedBBox.getMaxX(), requestedBBox.getMinY(), requestedBBox.getMaxY(), coverageProperties.crs2D); } // intersect requested BBox in native CRS with coverage native bbox to get the crop bbox // intersect the requested area with the bounds of this layer in native crs if (!cropBBox.intersects((BoundingBox) coverageProperties.bbox)) { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine( new StringBuilder("The computed CropBoundingBox ") .append(cropBBox) .append(" Doesn't intersect the coverage BoundingBox ") .append(coverageProperties.bbox) .append(" resulting in an empty request") .toString()); } cropBBox = null; empty = true; return; } // TODO XXX Optimize when referenced envelope has intersection method that actually retains // the CRS, this is the JTS one cropBBox = new ReferencedEnvelope( ((ReferencedEnvelope) cropBBox).intersection(coverageProperties.bbox), coverageProperties.crs2D); return; } catch (TransformException te) { // something bad happened while trying to transform this // envelope. let's try with wgs84 if (LOGGER.isLoggable(Level.FINE)) LOGGER.log(Level.FINE, te.getLocalizedMessage(), te); } try { // can we proceed? Do we have geo stuff to do all these operations? if (coverageProperties.geographicCRS2D != null && coverageProperties.geographicBBox != null) { // // If we can not reproject the requested envelope to the native CRS, // we go back to reproject in the geographic crs of the native // coverage since this usually happens for conversions between CRS // whose area of definition is different // // STEP 1 reproject the requested envelope to the coverage geographic bbox if (!CRS.equalsIgnoreMetadata(coverageProperties.geographicCRS2D, requestCRS)) { // try to convert the requested bbox to the coverage geocrs requestCRSToCoverageGeographicCRS2D = CRS.findMathTransform(requestCRS, coverageProperties.geographicCRS2D, true); if (!requestCRSToCoverageGeographicCRS2D.isIdentity()) { requestedBBOXInCoverageGeographicCRS = CRS.transform(requestedBBox, coverageProperties.geographicCRS2D); requestedBBOXInCoverageGeographicCRS.setCoordinateReferenceSystem( coverageProperties.geographicCRS2D); } } if (requestedBBOXInCoverageGeographicCRS == null) { requestedBBOXInCoverageGeographicCRS = new GeneralEnvelope(requestCRS); } // STEP 2 intersection with the geographic bbox for this coverage if (!requestedBBOXInCoverageGeographicCRS.intersects( coverageProperties.geographicBBox, true)) { cropBBox = null; empty = true; return; } // intersect with the coverage native geographic bbox // note that for the moment we got to use general envelope since there is no intersection // otherwise requestedBBOXInCoverageGeographicCRS.intersect(coverageProperties.geographicBBox); requestedBBOXInCoverageGeographicCRS.setCoordinateReferenceSystem( coverageProperties.geographicCRS2D); // now go back to the coverage native CRS in order to compute an approximate requested // resolution approximateRequestedBBoInNativeCRS = CRS.transform(requestedBBOXInCoverageGeographicCRS, coverageProperties.crs2D); approximateRequestedBBoInNativeCRS.setCoordinateReferenceSystem(coverageProperties.crs2D); cropBBox = new ReferencedEnvelope(approximateRequestedBBoInNativeCRS); return; } } catch (TransformException te) { // something bad happened while trying to transform this // envelope. let's try with wgs84 if (LOGGER.isLoggable(Level.FINE)) LOGGER.log(Level.FINE, te.getLocalizedMessage(), te); } catch (FactoryException fe) { // something bad happened while trying to transform this // envelope. let's try with wgs84 if (LOGGER.isLoggable(Level.FINE)) LOGGER.log(Level.FINE, fe.getLocalizedMessage(), fe); } LOGGER.log( Level.INFO, "We did not manage to crop the requested envelope, we fall back onto loading the whole coverage."); cropBBox = null; }
/** * Return a crop region from a specified envelope, leveraging on the grid to world transformation. * * @param refinedRequestedBBox the crop envelope * @return a {@code Rectangle} representing the crop region. * @throws TransformException in case a problem occurs when going back to raster space. * @throws DataSourceException */ private void computeCropRasterArea() throws DataSourceException { // we have nothing to crop if (cropBBox == null) { destinationRasterArea = null; return; } // // We need to invert the requested gridToWorld and then adjust the requested raster area are // accordingly // // invert the requested grid to world keeping into account the fact that it is related to cell // center // while the raster is related to cell corner MathTransform2D requestedWorldToGrid; try { requestedWorldToGrid = (MathTransform2D) PixelTranslation.translate( ProjectiveTransform.create(requestedGridToWorld), PixelInCell.CELL_CENTER, PixelInCell.CELL_CORNER) .inverse(); } catch (NoninvertibleTransformException e) { throw new DataSourceException(e); } if (destinationToSourceTransform == null || destinationToSourceTransform.isIdentity()) { // now get the requested bbox which have been already adjusted and project it back to raster // space try { destinationRasterArea = new GeneralGridEnvelope( CRS.transform(requestedWorldToGrid, new GeneralEnvelope(cropBBox)), PixelInCell.CELL_CORNER, false) .toRectangle(); } catch (IllegalStateException e) { throw new DataSourceException(e); } catch (TransformException e) { throw new DataSourceException(e); } } else { // // reproject the crop bbox back and then crop, notice that we are imposing // try { final GeneralEnvelope cropBBOXInRequestCRS = CRS.transform(cropBBox, requestedBBox.getCoordinateReferenceSystem()); cropBBOXInRequestCRS.setCoordinateReferenceSystem( requestedBBox.getCoordinateReferenceSystem()); // make sure it falls within the requested envelope cropBBOXInRequestCRS.intersect(requestedBBox); // now go back to raster space destinationRasterArea = new GeneralGridEnvelope( CRS.transform(requestedWorldToGrid, cropBBOXInRequestCRS), PixelInCell.CELL_CORNER, false) .toRectangle(); // intersect with the original requested raster space to be sure that we stay within the // requested raster area XRectangle2D.intersect(destinationRasterArea, requestedRasterArea, destinationRasterArea); } catch (NoninvertibleTransformException e) { throw new DataSourceException(e); } catch (TransformException e) { throw new DataSourceException(e); } } // is it empty?? if (destinationRasterArea.isEmpty()) { if (LOGGER.isLoggable(Level.FINE)) LOGGER.log( Level.FINE, "Requested envelope too small resulting in empty cropped raster region. cropBbox:" + cropBBox); // TODO: Future versions may define a 1x1 rectangle starting // from the lower coordinate empty = true; return; } }
/** * Encodes the boundedBy element * * <p>e.g.: * * <pre>{@code * <gml:boundedBy> * <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326" axisLabels="Lat Long" uomLabels="deg deg" srsDimension="2"> * <gml:lowerCorner>1 1</gml:lowerCorner> * <gml:upperCorner>5 3</gml:upperCorner> * </gml:Envelope> * </gml:boundedBy> * }</pre> * * @param ci * @param gc2d * @param ePSGCode * @param axisSwap * @param srsName * @param axesNames * @param axisLabels * @throws IOException */ public void handleBoundedBy( final GeneralEnvelope envelope, boolean axisSwap, String srsName, String axisLabels, WCSDimensionsHelper dimensionHelper) throws IOException { final CoordinateReferenceSystem crs = envelope.getCoordinateReferenceSystem(); final CoordinateSystem cs = crs.getCoordinateSystem(); // TODO time String uomLabels = extractUoM(crs, cs.getAxis(axisSwap ? 1 : 0).getUnit()) + " " + extractUoM(crs, cs.getAxis(axisSwap ? 0 : 1).getUnit()); // time and elevation dimensions management boolean hasElevation = false; boolean hasTime = false; if (dimensionHelper != null) { if (dimensionHelper.getElevationDimension() != null) { uomLabels = uomLabels + " m"; // TODO: Check elevation uom hasElevation = true; } if (dimensionHelper.getTimeDimension() != null) { uomLabels = uomLabels + " s"; hasTime = true; } } final int srsDimension = cs.getDimension() + (hasElevation ? 1 : 0); // Setting up envelope bounds (including elevation) final String lower = new StringBuilder() .append(envelope.getLowerCorner().getOrdinate(axisSwap ? 1 : 0)) .append(" ") .append(envelope.getLowerCorner().getOrdinate(axisSwap ? 0 : 1)) .append(hasElevation ? " " + dimensionHelper.getBeginElevation() : "") .toString(); final String upper = new StringBuilder() .append(envelope.getUpperCorner().getOrdinate(axisSwap ? 1 : 0)) .append(" ") .append(envelope.getUpperCorner().getOrdinate(axisSwap ? 0 : 1)) .append(hasElevation ? " " + dimensionHelper.getEndElevation() : "") .toString(); // build the fragment final AttributesImpl envelopeAttrs = new AttributesImpl(); envelopeAttrs.addAttribute("", "srsName", "srsName", "", srsName); envelopeAttrs.addAttribute("", "axisLabels", "axisLabels", "", axisLabels); envelopeAttrs.addAttribute("", "uomLabels", "uomLabels", "", uomLabels); envelopeAttrs.addAttribute( "", "srsDimension", "srsDimension", "", String.valueOf(srsDimension)); start("gml:boundedBy"); String envelopeName; if (dimensionHelper != null && (hasTime || hasElevation)) { envelopeName = "gml:EnvelopeWithTimePeriod"; } else { envelopeName = "gml:Envelope"; } start(envelopeName, envelopeAttrs); element("gml:lowerCorner", lower); element("gml:upperCorner", upper); if (dimensionHelper != null && hasTime) { element("gml:beginPosition", dimensionHelper.getBeginTime()); element("gml:endPosition", dimensionHelper.getEndTime()); } end(envelopeName); end("gml:boundedBy"); }
@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 } } } }