public static HashMap<String, Double> getRegionParamsFromGridCoverage( GridCoverage2D gridCoverage) { HashMap<String, Double> envelopeParams = new HashMap<String, Double>(); Envelope envelope = gridCoverage.getEnvelope(); DirectPosition lowerCorner = envelope.getLowerCorner(); double[] westSouth = lowerCorner.getCoordinate(); DirectPosition upperCorner = envelope.getUpperCorner(); double[] eastNorth = upperCorner.getCoordinate(); GridGeometry2D gridGeometry = gridCoverage.getGridGeometry(); GridEnvelope2D gridRange = gridGeometry.getGridRange2D(); int height = gridRange.height; int width = gridRange.width; AffineTransform gridToCRS = (AffineTransform) gridGeometry.getGridToCRS(); double xRes = XAffineTransform.getScaleX0(gridToCRS); double yRes = XAffineTransform.getScaleY0(gridToCRS); envelopeParams.put(NORTH, eastNorth[1]); envelopeParams.put(SOUTH, westSouth[1]); envelopeParams.put(WEST, westSouth[0]); envelopeParams.put(EAST, eastNorth[0]); envelopeParams.put(XRES, xRes); envelopeParams.put(YRES, yRes); envelopeParams.put(ROWS, (double) height); envelopeParams.put(COLS, (double) width); return envelopeParams; }
@Test public void NetCDFProjectedEnvelopeTest() throws NoSuchAuthorityCodeException, FactoryException, IOException, ParseException { File mosaic = new File(TestData.file(this, "."), "NetCDFProjection"); if (mosaic.exists()) { FileUtils.deleteDirectory(mosaic); } assertTrue(mosaic.mkdirs()); File file = TestData.file(this, "wind.nc"); FileUtils.copyFileToDirectory(file, mosaic); file = new File(mosaic, "wind.nc"); // Get format final NetCDFReader reader = new NetCDFReader(file, null); try { String[] names = reader.getGridCoverageNames(); String coverageName = names[0]; // subsetting the envelope final ParameterValue<GridGeometry2D> gg = AbstractGridFormat.READ_GRIDGEOMETRY2D.createValue(); final GeneralEnvelope originalEnvelope = reader.getOriginalEnvelope(coverageName); final CoordinateReferenceSystem epsg3857 = CRS.decode("EPSG:3857", true); final GeneralEnvelope projectedEnvelope = CRS.transform(originalEnvelope, epsg3857); gg.setValue( new GridGeometry2D(new GridEnvelope2D(new Rectangle(0, 0, 30, 30)), projectedEnvelope)); GeneralParameterValue[] values = new GeneralParameterValue[] {gg}; GridCoverage2D coverage = reader.read(coverageName, values); // reader doesn't perform reprojection. It simply transforms reprojected envelope // to native envelope so BBOX and CRS should be wgs84 CoordinateReferenceSystem coverageCRS = coverage.getCoordinateReferenceSystem(); final int code = CRS.lookupEpsgCode(coverageCRS, false); assertEquals(4326, code); Extent extent = coverageCRS.getDomainOfValidity(); Collection<? extends GeographicExtent> geoElements = extent.getGeographicElements(); GeographicExtent geographicExtent = geoElements.iterator().next(); GeographicBoundingBoxImpl impl = (GeographicBoundingBoxImpl) geographicExtent; // Getting the coverage Envelope for coordinates check Envelope coverageEnvelope = coverage.getEnvelope(); assertTrue(impl.getEastBoundLongitude() >= coverageEnvelope.getMaximum(0)); assertTrue(impl.getWestBoundLongitude() <= coverageEnvelope.getMinimum(0)); assertTrue(impl.getNorthBoundLatitude() >= coverageEnvelope.getMaximum(1)); assertTrue(impl.getSouthBoundLatitude() <= coverageEnvelope.getMinimum(1)); } catch (Throwable t) { throw new RuntimeException(t); } finally { if (reader != null) { try { reader.dispose(); } catch (Throwable t) { // Does nothing } } } }
/** * Performs a translation using the "Resample" operation. * * @param grid the {@link GridCoverage2D} to apply the translation on. * @throws NoninvertibleTransformException If a "grid to CRS" transform is not invertible. */ private void doTranslation(GridCoverage2D grid) throws NoninvertibleTransformException { final int transX = -253; final int transY = -456; final double scaleX = 0.04; final double scaleY = -0.04; final ParameterBlock block = new ParameterBlock() .addSource(grid.getRenderedImage()) .add((float) transX) .add((float) transY); RenderedImage image = JAI.create("Translate", block); assertEquals("Incorrect X translation", transX, image.getMinX()); assertEquals("Incorrect Y translation", transY, image.getMinY()); /* * Create a grid coverage from the translated image but with the same envelope. * Consequently, the 'gridToCoordinateSystem' should be translated by the same * amount, with the opposite sign. */ AffineTransform expected = getAffineTransform(grid); assertNotNull(expected); expected = new AffineTransform(expected); // Get a mutable instance. final GridCoverageFactory factory = CoverageFactoryFinder.getGridCoverageFactory(null); grid = factory.create( "Translated", image, grid.getEnvelope(), grid.getSampleDimensions(), new GridCoverage2D[] {grid}, grid.getProperties()); expected.translate(-transX, -transY); assertTransformEquals(expected, getAffineTransform(grid)); /* * Apply the "Resample" operation with a specific 'gridToCoordinateSystem' transform. * The envelope is left unchanged. The "Resample" operation should compute automatically * new image bounds. */ final AffineTransform at = AffineTransform.getScaleInstance(scaleX, scaleY); final MathTransform tr = ProjectiveTransform.create(at); // account for the half pixel correction between the two spaces since we are talking raster here // but the resample will talk model! final MathTransform correctedTransform = PixelTranslation.translate(tr, PixelInCell.CELL_CORNER, PixelInCell.CELL_CENTER); final GridGeometry2D geometry = new GridGeometry2D(null, correctedTransform, null); final GridCoverage2D newGrid = (GridCoverage2D) Operations.DEFAULT.resample(grid, grid.getCoordinateReferenceSystem(), geometry, null); assertEquals(correctedTransform, getAffineTransform(newGrid)); image = newGrid.getRenderedImage(); expected.preConcatenate(at.createInverse()); final Point point = new Point(transX, transY); assertSame(point, expected.transform(point, point)); // Round toward neareast integer }
@Test public void testCrs84wms13() throws Exception { // prepare the responses MockHttpClient client = new MockHttpClient() { public HTTPResponse get(URL url) throws IOException { if (url.getQuery().contains("GetCapabilities")) { URL caps130 = WMSCoverageReaderTest.class.getResource("caps130_crs84.xml"); return new MockHttpResponse(caps130, "text/xml"); } else if (url.getQuery().contains("GetMap") && url.getQuery().contains("world84")) { Map<String, String> params = parseParams(url.getQuery()); assertEquals("1.3.0", params.get("VERSION")); assertEquals("CRS:84", params.get("CRS")); assertEquals("-180.0,-90.0,180.0,90.0", params.get("BBOX")); URL world = WMSCoverageReaderTest.class.getResource("world.png"); return new MockHttpResponse(world, "image/png"); } else { throw new IllegalArgumentException( "Don't know how to handle a get request over " + url.toExternalForm()); } } }; WebMapServer server = new WebMapServer(new URL("http://geoserver.org/geoserver/wms"), client); WMSCoverageReader reader = new WMSCoverageReader(server, getLayer(server, "world84")); // setup the request and check it CoordinateReferenceSystem wgs84 = CRS.decode("EPSG:4326", true); ReferencedEnvelope worldEnvelope = new ReferencedEnvelope(-180, 180, -90, 90, wgs84); GridGeometry2D gg = new GridGeometry2D(new GridEnvelope2D(0, 0, 180, 90), worldEnvelope); final Parameter<GridGeometry2D> ggParam = (Parameter<GridGeometry2D>) AbstractGridFormat.READ_GRIDGEOMETRY2D.createValue(); ggParam.setValue(gg); GridCoverage2D coverage = reader.read(new GeneralParameterValue[] {ggParam}); assertTrue(CRS.equalsIgnoreMetadata(wgs84, coverage.getCoordinateReferenceSystem())); assertEquals(worldEnvelope, new ReferencedEnvelope(coverage.getEnvelope())); }
/** * Tests the "Resample" operation with a stereographic coordinate system on a paletted image * * @throws FactoryException * @throws NoSuchAuthorityCodeException */ @Test public void testReprojectPalette() throws NoSuchAuthorityCodeException, FactoryException { // do it again, make sure the image does not turn black since GridCoverage2D input = ushortCoverage; // Create a Palette image from the input coverage RenderedImage src = input.getRenderedImage(); ImageWorker iw = new ImageWorker(src).rescaleToBytes().forceIndexColorModel(false); src = iw.getRenderedOperation(); // Setting Force ReplaceIndexColorModel and CoverageProcessingView as SAME Hints hints = GeoTools.getDefaultHints().clone(); hints.put(JAI.KEY_REPLACE_INDEX_COLOR_MODEL, true); hints.put(Hints.COVERAGE_PROCESSING_VIEW, ViewType.SAME); // Create a new GridCoverage GridCoverageFactory factory = new GridCoverageFactory(hints); GridCoverage2D palette = factory.create("test", src, input.getEnvelope()); CoordinateReferenceSystem targetCRS = CRS.parseWKT(GOOGLE_MERCATOR_WKT); GridCoverage2D coverage_ = project(palette, targetCRS, null, "bilinear", hints, true); // reproject the ushort and check that things did not go bad, that is it turned black coverage_ = (GridCoverage2D) Operations.DEFAULT.extrema(coverage_); Object minimums = coverage_.getProperty(Extrema.GT_SYNTHETIC_PROPERTY_MINIMUM); Assert.assertTrue(minimums instanceof double[]); final double[] mins = (double[]) minimums; Object maximums = coverage_.getProperty(Extrema.GT_SYNTHETIC_PROPERTY_MAXIMUM); Assert.assertTrue(maximums instanceof double[]); final double[] max = (double[]) maximums; boolean fail = true; for (int i = 0; i < mins.length; i++) if (mins[i] != max[i] && max[i] > 0) fail = false; Assert.assertFalse("Reprojection failed", fail); // Ensure the CRS is correct CoordinateReferenceSystem targetCoverageCRS = coverage_.getCoordinateReferenceSystem(); Assert.assertTrue(CRS.equalsIgnoreMetadata(targetCRS, targetCoverageCRS)); }
@Override public void encode(Object o) throws IllegalArgumentException { // register namespaces provided by extended capabilities NamespaceSupport namespaces = getNamespaceSupport(); namespaces.declarePrefix("wcscrs", "http://www.opengis.net/wcs/service-extension/crs/1.0"); namespaces.declarePrefix( "int", "http://www.opengis.net/WCS_service-extension_interpolation/1.0"); namespaces.declarePrefix("gml", "http://www.opengis.net/gml/3.2"); namespaces.declarePrefix("gmlcov", "http://www.opengis.net/gmlcov/1.0"); namespaces.declarePrefix("swe", "http://www.opengis.net/swe/2.0"); namespaces.declarePrefix("xlink", "http://www.w3.org/1999/xlink"); namespaces.declarePrefix("xsi", "http://www.w3.org/2001/XMLSchema-instance"); for (WCS20CoverageMetadataProvider cp : extensions) { cp.registerNamespaces(namespaces); } // is this a GridCoverage? if (!(o instanceof GridCoverage2D)) { throw new IllegalArgumentException( "Provided object is not a GridCoverage2D:" + (o != null ? o.getClass().toString() : "null")); } final GridCoverage2D gc2d = (GridCoverage2D) o; // we are going to use this name as an ID final String gcName = gc2d.getName().toString(Locale.getDefault()); // get the crs and look for an EPSG code final CoordinateReferenceSystem crs = gc2d.getCoordinateReferenceSystem2D(); List<String> axesNames = GMLTransformer.this.envelopeDimensionsMapper.getAxesNames(gc2d.getEnvelope2D(), true); // lookup EPSG code Integer EPSGCode = null; try { EPSGCode = CRS.lookupEpsgCode(crs, false); } catch (FactoryException e) { throw new IllegalStateException("Unable to lookup epsg code for this CRS:" + crs, e); } if (EPSGCode == null) { throw new IllegalStateException("Unable to lookup epsg code for this CRS:" + crs); } final String srsName = GetCoverage.SRS_STARTER + EPSGCode; // handle axes swap for geographic crs final boolean axisSwap = CRS.getAxisOrder(crs).equals(AxisOrder.EAST_NORTH); final AttributesImpl attributes = new AttributesImpl(); helper.registerNamespaces(getNamespaceSupport(), attributes); // using Name as the ID attributes.addAttribute( "", "gml:id", "gml:id", "", gc2d.getName().toString(Locale.getDefault())); start("gml:RectifiedGridCoverage", attributes); // handle domain final StringBuilder builder = new StringBuilder(); for (String axisName : axesNames) { builder.append(axisName).append(" "); } String axesLabel = builder.substring(0, builder.length() - 1); try { GeneralEnvelope envelope = new GeneralEnvelope(gc2d.getEnvelope()); handleBoundedBy(envelope, axisSwap, srsName, axesLabel, null); } catch (IOException ex) { throw new WCS20Exception(ex); } // handle domain builder.setLength(0); axesNames = GMLTransformer.this.envelopeDimensionsMapper.getAxesNames(gc2d.getEnvelope2D(), false); for (String axisName : axesNames) { builder.append(axisName).append(" "); } axesLabel = builder.substring(0, builder.length() - 1); handleDomainSet(gc2d.getGridGeometry(), gc2d.getDimension(), gcName, srsName, axisSwap); // handle rangetype handleRangeType(gc2d); // handle coverage function final GridEnvelope2D ge2D = gc2d.getGridGeometry().getGridRange2D(); handleCoverageFunction(ge2D, axisSwap); // handle range handleRange(gc2d); // handle metadata OPTIONAL try { handleMetadata(null, null); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } end("gml:RectifiedGridCoverage"); }