/** {@inheritDoc } */ @Override protected Map<String, String> toString(final Envelope env) { final Map<String, String> map = new HashMap<String, String>(); final StringBuilder sb = new StringBuilder(); final double minx = env.getMinimum(0); final double maxx = env.getMaximum(0); final double miny = env.getMinimum(1); final double maxy = env.getMaximum(1); sb.append(minx).append(',').append(miny).append(',').append(maxx).append(',').append(maxy); map.put("BBOX", sb.toString()); try { String code = IdentifiedObjects.lookupIdentifier(env.getCoordinateReferenceSystem(), true); if (code == null) { code = IdentifiedObjects.lookupIdentifier( CRSUtilities.getCRS2D(env.getCoordinateReferenceSystem()), true); } map.put("CRS", code); } catch (FactoryException ex) { LOGGER.log(Level.WARNING, null, ex); } catch (TransformException ex) { LOGGER.log(Level.WARNING, null, ex); } encodeNDParameters(env, map); return map; }
/** * Check if the envelope corresponds to full extent. It will probably not equal the full extent * envelope because of slack space in the display area, so we check that at least one pair of * opposite edges are equal to the full extent envelope, allowing for slack space on the other two * sides. * * <p>Note: this method returns {@code false} if the full extent envelope is wholly within the * requested envelope (e.g. user has zoomed out from full extent), only touches one edge, or * touches two adjacent edges. In all these cases we assume that the user wants to maintain the * slack space in the display. * * <p>This method is part of the work-around that the map pane needs because of the differences in * how raster and vector layers are treated by the renderer classes. * * @param envelope a pending display envelope to compare to the full extent envelope * @return true if the envelope is coincident with the full extent evenlope on at least two edges; * false otherwise * @todo My logic here seems overly complex - I'm sure there must be a simpler way for the map * pane to handle this. */ private boolean equalsFullExtent(final Envelope envelope) { if (fullExtent == null || envelope == null) { return false; } final double TOL = 1.0e-6d * (fullExtent.getWidth() + fullExtent.getHeight()); boolean touch = false; if (Math.abs(envelope.getMinimum(0) - fullExtent.getMinimum(0)) < TOL) { touch = true; } if (Math.abs(envelope.getMaximum(0) - fullExtent.getMaximum(0)) < TOL) { if (touch) { return true; } } if (Math.abs(envelope.getMinimum(1) - fullExtent.getMinimum(1)) < TOL) { touch = true; } if (Math.abs(envelope.getMaximum(1) - fullExtent.getMaximum(1)) < TOL) { if (touch) { return true; } } return false; }
/** * Cast to a ReferencedEnvelope (used to ensure that an Envelope if a ReferencedEnvelope). * Supporting 2d as well as 3d envelopes (returning the right class). * * @param env The opgenis Envelope object * @return ReferencedEnvelope, ReferencedEnvelope3D if it is 3d,<br> * results in a null/an empty envelope, if input envelope was a null/an empty envelope (by JTS * Envelope definition: getMaximum(0) < getMinimum(0)) */ public static ReferencedEnvelope reference(org.opengis.geometry.Envelope env) { if (env == null) { return null; } if (env instanceof ReferencedEnvelope3D) { return (ReferencedEnvelope3D) env; } if (env instanceof ReferencedEnvelope) { return (ReferencedEnvelope) env; } if (env.getDimension() >= 3) { // emptiness test according to com.vividsolutions.jts.geom.Envelope if (env.getMaximum(0) < env.getMinimum(0)) { return new ReferencedEnvelope3D(env.getCoordinateReferenceSystem()); } else { return new ReferencedEnvelope3D(env); } } // emptiness test according to com.vividsolutions.jts.geom.Envelope if (env.getMaximum(0) < env.getMinimum(0)) return new ReferencedEnvelope(env.getCoordinateReferenceSystem()); return new ReferencedEnvelope(env); }
@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 } } } }
/** * Display the bounding coordinates of the given envelope * * @param bounds the bounds to display */ public void displayBounds(Envelope bounds) { if (bounds != null) { boundsLabel.setText( String.format( "Min:%.2f %.2f Span:%.2f %.2f", bounds.getMinimum(0), bounds.getMinimum(1), bounds.getSpan(0), bounds.getSpan(1))); } }
/** * Creates a new envelope from an existing OGC envelope. * * <p>NOTE: if the envelope is empty, the resulting ReferencedEnvelope will not be. In case this * is needed use {@link #create(org.opengis.geometry.Envelope, CoordinateReferenceSystem) * ReferencedEnvelope.create(envelope, envelope.getCoordinateReferenceSystem())} * * @param envelope The envelope to initialize from. * @throws MismatchedDimensionException if the CRS dimension is not valid. * @since 2.4 */ public ReferencedEnvelope(final org.opengis.geometry.Envelope envelope) throws MismatchedDimensionException { super( envelope.getMinimum(0), envelope.getMaximum(0), envelope.getMinimum(1), envelope.getMaximum(1)); this.crs = envelope.getCoordinateReferenceSystem(); checkCoordinateReferenceSystemDimension(); }
/** * Constructs two-dimensional envelope defined by an other {@link Envelope}. * * @param envelope The envelope to copy. */ public Envelope2D(final Envelope envelope) { super( envelope.getMinimum(0), envelope.getMinimum(1), envelope.getSpan(0), envelope.getSpan(1)); // TODO: check below should be first, if only Sun could fix RFE #4093999. final int dimension = envelope.getDimension(); if (dimension != 2) { throw new MismatchedDimensionException( Errors.format(ErrorKeys.NOT_TWO_DIMENSIONAL_$1, dimension)); } setCoordinateReferenceSystem(envelope.getCoordinateReferenceSystem()); }
/** * Compare the bounds of this envelope with those of another. * * <p>Note: in this test: * * <ul> * <li>the coordinate reference systems of the envelopes are not examined * <li>only the first two dimensions of the envelopes are compared * <li>it is assumed that each dimension equates to the same axis for both envelopes * </ul> * * @param other other envelope * @param eps a small tolerance factor (e.g. 1.0e-6d) which will be scaled relative to this * envlope's width and height * @return true if all bounding coordinates are equal within the set tolerance; false otherwise */ public boolean boundsEquals2D(final org.opengis.geometry.Envelope other, double eps) { eps *= 0.5 * (getWidth() + getHeight()); double[] delta = new double[4]; delta[0] = getMinimum(0) - other.getMinimum(0); delta[1] = getMaximum(0) - other.getMaximum(0); delta[2] = getMinimum(1) - other.getMinimum(1); delta[3] = getMaximum(1) - other.getMaximum(1); for (int i = 0; i < delta.length; i++) { /* * As per Envelope2D#boundsEquals we use ! here to * catch any NaN values */ if (!(Math.abs(delta[i]) <= eps)) { return false; } } return true; }
/** {@inheritDoc } */ @Override protected Map<String, String> toString(final Envelope env) { final Map<String, String> map = new HashMap<String, String>(); final StringBuilder sb = new StringBuilder(); final double minx = env.getMinimum(0); final double maxx = env.getMaximum(0); final double miny = env.getMinimum(1); final double maxy = env.getMaximum(1); sb.append(minx).append(',').append(miny).append(',').append(maxx).append(',').append(maxy); map.put("BBOX", sb.toString()); try { map.put("CRS", IdentifiedObjects.lookupIdentifier(env.getCoordinateReferenceSystem(), true)); } catch (FactoryException ex) { LOGGER.log(Level.WARNING, null, ex); } encodeTimeAndElevation(env, map); return map; }
private Map<String, String> toString(final Envelope envelope) { final Map<String, String> params = new HashMap<String, String>(); final StringBuilder sb = new StringBuilder(); final double minx = envelope.getMinimum(0); final double maxx = envelope.getMaximum(0); final double miny = envelope.getMinimum(1); final double maxy = envelope.getMaximum(1); sb.append(minx).append(',').append(miny).append(',').append(maxx).append(',').append(maxy); if (envelope.getDimension() > 2) { sb.append(',').append(envelope.getMinimum(2)).append(',').append(envelope.getMaximum(2)); } params.put("BBOX", sb.toString()); try { CoordinateReferenceSystem crs2d = CRSUtilities.getCRS2D(envelope.getCoordinateReferenceSystem()); params.put("CRS", IdentifiedObjects.lookupIdentifier(crs2d, true)); } catch (FactoryException ex) { LOGGER.log(Level.WARNING, null, ex); } catch (TransformException ex) { LOGGER.log(Level.WARNING, null, ex); } return params; }
/** * Returns a string representation of the {@code Bounding Box}. It is a comma-separated list * matching with this pattern: minx,miny,maxx,maxy. * * @param envelope The envelope to return the string representation. */ public static String toBboxValue(final Envelope envelope) { final StringBuilder builder = new StringBuilder(); final int dimEnv = envelope.getDimension(); for (int i = 0; i < dimEnv; i++) { builder.append(envelope.getMinimum(i)).append(','); } for (int j = 0; j < dimEnv; j++) { if (j > 0) { builder.append(','); } builder.append(envelope.getMaximum(j)); } return builder.toString(); }
/** * Returns {@code true} if {@code this} envelope bounds is equals to {@code that} envelope bounds * in two specified dimensions. The coordinate reference system is not compared, since it doesn't * need to have the same number of dimensions. * * @param that The envelope to compare to. * @param xDim The dimension of {@code that} envelope to compare to the <var>x</var> dimension of * {@code this} envelope. * @param yDim The dimension of {@code that} envelope to compare to the <var>y</var> dimension of * {@code this} envelope. * @param eps A small tolerance number for floating point number comparaisons. This value will be * scaled according this envelope {@linkplain #width width} and {@linkplain #height height}. * @return {@code true} if the envelope bounds are the same (up to the specified tolerance level) * in the specified dimensions, or {@code false} otherwise. */ public boolean boundsEquals(final Envelope that, final int xDim, final int yDim, double eps) { eps *= 0.5 * (width + height); for (int i = 0; i < 4; i++) { final int dim2D = (i & 1); final int dimND = (dim2D == 0) ? xDim : yDim; final double value2D, valueND; if ((i & 2) == 0) { value2D = this.getMinimum(dim2D); valueND = that.getMinimum(dimND); } else { value2D = this.getMaximum(dim2D); valueND = that.getMaximum(dimND); } // Use '!' for catching NaN values. if (!(Math.abs(value2D - valueND) <= eps)) { return false; } } return true; }
/** * 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); }