Source Code Cross Referenced for GeneralEnvelope.java in  » GIS » GeoTools-2.4.1 » org » geotools » geometry » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » GeoTools 2.4.1 » org.geotools.geometry 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *    GeoTools - OpenSource mapping toolkit
0003:         *    http://geotools.org
0004:         *    (C) 2004-2006, GeoTools Project Managment Committee (PMC)
0005:         *    (C) 2004, Institut de Recherche pour le Développement
0006:         *
0007:         *    This library is free software; you can redistribute it and/or
0008:         *    modify it under the terms of the GNU Lesser General Public
0009:         *    License as published by the Free Software Foundation;
0010:         *    version 2.1 of the License.
0011:         *
0012:         *    This library is distributed in the hope that it will be useful,
0013:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
0014:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015:         *    Lesser General Public License for more details.
0016:         */
0017:        package org.geotools.geometry;
0018:
0019:        // J2SE dependencies
0020:        import java.awt.geom.Rectangle2D;
0021:        import java.io.Serializable;
0022:        import java.util.Arrays;
0023:        import javax.units.Unit;
0024:        import javax.units.ConversionException;
0025:
0026:        // OpenGIS dependencies
0027:        import org.opengis.util.Cloneable;
0028:        import org.opengis.coverage.grid.GridRange;
0029:        import org.opengis.metadata.extent.GeographicBoundingBox;
0030:        import org.opengis.referencing.datum.PixelInCell;
0031:        import org.opengis.referencing.operation.MathTransform;
0032:        import org.opengis.referencing.operation.TransformException;
0033:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
0034:        import org.opengis.geometry.DirectPosition;
0035:        import org.opengis.geometry.Envelope;
0036:        import org.opengis.geometry.MismatchedDimensionException;
0037:        import org.opengis.geometry.MismatchedReferenceSystemException;
0038:
0039:        // Geotools dependencies
0040:        import org.geotools.referencing.CRS;
0041:        import org.geotools.resources.Utilities;
0042:        import org.geotools.resources.i18n.Errors;
0043:        import org.geotools.resources.i18n.ErrorKeys;
0044:        import org.geotools.resources.geometry.XRectangle2D;
0045:        import org.geotools.referencing.crs.DefaultGeographicCRS;
0046:
0047:        /**
0048:         * A minimum bounding box or rectangle. Regardless of dimension, an {@code Envelope} can
0049:         * be represented without ambiguity as two {@linkplain DirectPosition direct positions}
0050:         * (coordinate points). To encode an {@code Envelope}, it is sufficient to encode these
0051:         * two points.
0052:         * <p>
0053:         * This particular implementation of {@code Envelope} is said "General" because it
0054:         * uses coordinates of an arbitrary dimension.
0055:         * <p>
0056:         * <strong>Tip:</strong> The metadata package provides a
0057:         * {@link org.opengis.metadata.extent.GeographicBoundingBox}, which can be used as
0058:         * a kind of envelope with a coordinate reference system fixed to WGS 84 (EPSG:4326).
0059:         *
0060:         * @since 2.0
0061:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/geometry/GeneralEnvelope.java $
0062:         * @version $Id: GeneralEnvelope.java 26151 2007-07-04 18:54:48Z desruisseaux $
0063:         * @author Martin Desruisseaux
0064:         * @author Simone Giannecchini
0065:         *
0066:         * @see Envelope2D
0067:         * @see org.geotools.geometry.jts.ReferencedEnvelope
0068:         * @see org.opengis.metadata.extent.GeographicBoundingBox
0069:         */
0070:        public class GeneralEnvelope extends AbstractEnvelope implements 
0071:                Cloneable, Serializable {
0072:            /**
0073:             * Serial number for interoperability with different versions.
0074:             */
0075:            private static final long serialVersionUID = 1752330560227688940L;
0076:
0077:            /**
0078:             * Minimum and maximum ordinate values. The first half contains minimum
0079:             * ordinates, while the last half contains maximum ordinates. Consider
0080:             * this reference as final; it is modified by {@link #clone} only.
0081:             */
0082:            private double[] ordinates;
0083:
0084:            /**
0085:             * The coordinate reference system, or {@code null}.
0086:             */
0087:            private CoordinateReferenceSystem crs;
0088:
0089:            /**
0090:             * Constructs an empty envelope of the specified dimension.
0091:             * All ordinates are initialized to 0 and the coordinate reference
0092:             * system is undefined.
0093:             */
0094:            public GeneralEnvelope(final int dimension) {
0095:                ordinates = new double[dimension * 2];
0096:            }
0097:
0098:            /**
0099:             * Constructs one-dimensional envelope defined by a range of values.
0100:             *
0101:             * @param min The minimal value.
0102:             * @param max The maximal value.
0103:             */
0104:            public GeneralEnvelope(final double min, final double max) {
0105:                ordinates = new double[] { min, max };
0106:                checkCoherence();
0107:            }
0108:
0109:            /**
0110:             * Constructs a envelope defined by two positions.
0111:             *
0112:             * @param  minDP Minimum ordinate values.
0113:             * @param  maxDP Maximum ordinate values.
0114:             * @throws MismatchedDimensionException if the two positions don't have the same dimension.
0115:             * @throws IllegalArgumentException if an ordinate value in the minimum point is not
0116:             *         less than or equal to the corresponding ordinate value in the maximum point.
0117:             */
0118:            public GeneralEnvelope(final double[] minDP, final double[] maxDP)
0119:                    throws IllegalArgumentException {
0120:                ensureNonNull("minDP", minDP);
0121:                ensureNonNull("maxDP", maxDP);
0122:                ensureSameDimension(minDP.length, maxDP.length);
0123:                ordinates = new double[minDP.length + maxDP.length];
0124:                System.arraycopy(minDP, 0, ordinates, 0, minDP.length);
0125:                System.arraycopy(maxDP, 0, ordinates, minDP.length,
0126:                        maxDP.length);
0127:                checkCoherence();
0128:            }
0129:
0130:            /**
0131:             * Constructs a envelope defined by two positions. The coordinate
0132:             * reference system is inferred from the supplied direct position.
0133:             *
0134:             * @param  minDP Point containing minimum ordinate values.
0135:             * @param  maxDP Point containing maximum ordinate values.
0136:             * @throws MismatchedDimensionException if the two positions don't have the same dimension.
0137:             * @throws MismatchedReferenceSystemException if the two positions don't use the same CRS.
0138:             * @throws IllegalArgumentException if an ordinate value in the minimum point is not
0139:             *         less than or equal to the corresponding ordinate value in the maximum point.
0140:             */
0141:            public GeneralEnvelope(final GeneralDirectPosition minDP,
0142:                    final GeneralDirectPosition maxDP)
0143:                    throws IllegalArgumentException {
0144:                //  Uncomment next lines if Sun fixes RFE #4093999
0145:                //      ensureNonNull("minDP", minDP);
0146:                //      ensureNonNull("maxDP", maxDP);
0147:                this (minDP.ordinates, maxDP.ordinates);
0148:                crs = getCoordinateReferenceSystem(minDP, maxDP);
0149:                AbstractDirectPosition.checkCoordinateReferenceSystemDimension(
0150:                        crs, ordinates.length / 2);
0151:            }
0152:
0153:            /**
0154:             * Constructs an empty envelope with the specified coordinate reference system.
0155:             * All ordinates are initialized to 0.
0156:             *
0157:             * @since 2.2
0158:             */
0159:            public GeneralEnvelope(final CoordinateReferenceSystem crs) {
0160:                //  Uncomment next line if Sun fixes RFE #4093999
0161:                //      ensureNonNull("envelope", envelope);
0162:                this (crs.getCoordinateSystem().getDimension());
0163:                this .crs = crs;
0164:            }
0165:
0166:            /**
0167:             * Constructs a new envelope with the same data than the specified envelope.
0168:             */
0169:            public GeneralEnvelope(final Envelope envelope) {
0170:                ensureNonNull("envelope", envelope);
0171:                if (envelope instanceof  GeneralEnvelope) {
0172:                    final GeneralEnvelope e = (GeneralEnvelope) envelope;
0173:                    ordinates = (double[]) e.ordinates.clone();
0174:                    crs = e.crs;
0175:                } else {
0176:                    crs = envelope.getCoordinateReferenceSystem();
0177:                    final int dimension = envelope.getDimension();
0178:                    ordinates = new double[2 * dimension];
0179:                    for (int i = 0; i < dimension; i++) {
0180:                        ordinates[i] = envelope.getMinimum(i);
0181:                        ordinates[i + dimension] = envelope.getMaximum(i);
0182:                    }
0183:                    checkCoherence();
0184:                }
0185:            }
0186:
0187:            /**
0188:             * Constructs a new envelope with the same data than the specified
0189:             * geographic bounding box. The coordinate reference system is set
0190:             * to {@linkplain DefaultGeographicCRS#WGS84 WGS84}.
0191:             *
0192:             * @since 2.4
0193:             */
0194:            public GeneralEnvelope(final GeographicBoundingBox box) {
0195:                ensureNonNull("box", box);
0196:                ordinates = new double[] { box.getWestBoundLongitude(),
0197:                        box.getSouthBoundLatitude(),
0198:                        box.getEastBoundLongitude(),
0199:                        box.getNorthBoundLatitude() };
0200:                crs = DefaultGeographicCRS.WGS84;
0201:            }
0202:
0203:            /**
0204:             * Constructs two-dimensional envelope defined by a {@link Rectangle2D}.
0205:             * The coordinate reference system is initially undefined.
0206:             */
0207:            public GeneralEnvelope(final Rectangle2D rect) {
0208:                ensureNonNull("rect", rect);
0209:                ordinates = new double[] { rect.getMinX(), rect.getMinY(),
0210:                        rect.getMaxX(), rect.getMaxY() };
0211:                checkCoherence();
0212:            }
0213:
0214:            /**
0215:             * Creates an envelope for a grid range transformed using the specified math transform.
0216:             *
0217:             * @param gridRange The grid range.
0218:             * @param gridType  Whatever grid range coordinates map to pixel center or pixel corner.
0219:             * @param gridToCRS The transform (usually affine) from grid range to the envelope CRS.
0220:             * @param crs       The envelope CRS, or {@code null} if unknow.
0221:             *
0222:             * @throws MismatchedDimensionException If one of the supplied object doesn't have
0223:             *         a dimension compatible with the other objects.
0224:             * @throws IllegalArgumentException if an argument is illegal for some other reason,
0225:             *         including failure to use the provided math transform.
0226:             *
0227:             * @since 2.3
0228:             */
0229:            public GeneralEnvelope(final GridRange gridRange,
0230:                    final PixelInCell gridType, final MathTransform gridToCRS,
0231:                    final CoordinateReferenceSystem crs)
0232:                    throws IllegalArgumentException {
0233:                ensureNonNull("gridRange", gridRange);
0234:                ensureNonNull("gridToCRS", gridToCRS);
0235:                final int dimRange = gridRange.getDimension();
0236:                final int dimSource = gridToCRS.getSourceDimensions();
0237:                final int dimTarget = gridToCRS.getTargetDimensions();
0238:                ensureSameDimension(dimRange, dimSource);
0239:                ensureSameDimension(dimRange, dimTarget);
0240:                ordinates = new double[dimSource * 2];
0241:                final double offset;
0242:                if (PixelInCell.CELL_CENTER.equals(gridType)) {
0243:                    offset = 0.5;
0244:                } else if (PixelInCell.CELL_CORNER.equals(gridType)) {
0245:                    offset = 0.0;
0246:                } else {
0247:                    throw new IllegalArgumentException(Errors
0248:                            .format(ErrorKeys.ILLEGAL_ARGUMENT_$2, "gridType",
0249:                                    gridType));
0250:                }
0251:                for (int i = 0; i < dimSource; i++) {
0252:                    // According OpenGIS specification, GridGeometry maps pixel's center.
0253:                    // We want a bounding box for all pixels, not pixel's centers. Offset by
0254:                    // 0.5 (use -0.5 for maximum too, not +0.5, since maximum is exclusive).
0255:                    setRange(i, gridRange.getLower(i) - offset, gridRange
0256:                            .getUpper(i)
0257:                            - offset);
0258:                }
0259:                final GeneralEnvelope transformed;
0260:                try {
0261:                    transformed = CRS.transform(gridToCRS, this );
0262:                } catch (TransformException exception) {
0263:                    throw new IllegalArgumentException(Errors.format(
0264:                            ErrorKeys.BAD_TRANSFORM_$1, Utilities
0265:                                    .getShortClassName(gridToCRS))/*, exception*/);
0266:                    // TODO: uncomment the exception cause when we will be allowed to target J2SE 1.5.
0267:                }
0268:                assert transformed.ordinates.length == this .ordinates.length;
0269:                System.arraycopy(transformed.ordinates, 0, this .ordinates, 0,
0270:                        ordinates.length);
0271:                setCoordinateReferenceSystem(crs);
0272:            }
0273:
0274:            /**
0275:             * Makes sure an argument is non-null.
0276:             *
0277:             * @param  name   Argument name.
0278:             * @param  object User argument.
0279:             * @throws InvalidParameterValueException if {@code object} is null.
0280:             */
0281:            private static void ensureNonNull(final String name,
0282:                    final Object object) throws IllegalArgumentException {
0283:                if (object == null) {
0284:                    throw new IllegalArgumentException(Errors.format(
0285:                            ErrorKeys.NULL_ARGUMENT_$1, name));
0286:                }
0287:            }
0288:
0289:            /**
0290:             * Make sure the specified dimensions are identical.
0291:             */
0292:            private static void ensureSameDimension(final int dim1,
0293:                    final int dim2) throws MismatchedDimensionException {
0294:                if (dim1 != dim2) {
0295:                    throw new MismatchedDimensionException(Errors.format(
0296:                            ErrorKeys.MISMATCHED_DIMENSION_$2,
0297:                            new Integer(dim1), new Integer(dim2)));
0298:                }
0299:            }
0300:
0301:            /**
0302:             * Checks if ordinate values in the minimum point are less than or
0303:             * equal to the corresponding ordinate value in the maximum point.
0304:             *
0305:             * @throws IllegalArgumentException if an ordinate value in the minimum
0306:             *         point is not less than or equal to the corresponding ordinate
0307:             *         value in the maximum point.
0308:             */
0309:            private void checkCoherence() throws IllegalArgumentException {
0310:                final int dimension = ordinates.length / 2;
0311:                for (int i = 0; i < dimension; i++) {
0312:                    if (!(ordinates[i] <= ordinates[dimension + i])) { // Use '!' in order to catch 'NaN'.
0313:                        throw new IllegalArgumentException(Errors.format(
0314:                                ErrorKeys.ILLEGAL_ENVELOPE_ORDINATE_$1,
0315:                                new Integer(i)));
0316:                    }
0317:                }
0318:            }
0319:
0320:            /**
0321:             * Returns the coordinate reference system from an arbitrary envelope, or {@code null}
0322:             * if unknown. This method performs some sanity checking for ensuring that the envelope
0323:             * CRS is consistent.
0324:             *
0325:             * @deprecated Use {@link Envelope#getCoordinateReferenceSystem()} instead.
0326:             *
0327:             * @since 2.3
0328:             */
0329:            public static CoordinateReferenceSystem getCoordinateReferenceSystem(
0330:                    final Envelope envelope) {
0331:                if (envelope == null) {
0332:                    return null;
0333:                }
0334:                if (envelope instanceof  GeneralEnvelope) {
0335:                    return ((GeneralEnvelope) envelope)
0336:                            .getCoordinateReferenceSystem();
0337:                }
0338:                if (envelope instanceof  Envelope2D) {
0339:                    return ((Envelope2D) envelope)
0340:                            .getCoordinateReferenceSystem();
0341:                }
0342:                final DirectPosition lower = envelope.getLowerCorner();
0343:                final DirectPosition upper = envelope.getUpperCorner();
0344:                if (lower.getDimension() == upper.getDimension()) {
0345:                    final CoordinateReferenceSystem crs = lower
0346:                            .getCoordinateReferenceSystem();
0347:                    if (Utilities.equals(crs, upper
0348:                            .getCoordinateReferenceSystem())) {
0349:                        return crs;
0350:                    }
0351:                }
0352:                throw new IllegalArgumentException(Errors
0353:                        .format(ErrorKeys.MALFORMED_ENVELOPE));
0354:            }
0355:
0356:            /**
0357:             * Returns the coordinate reference system in which the coordinates are given.
0358:             *
0359:             * @return The coordinate reference system, or {@code null}.
0360:             */
0361:            public final CoordinateReferenceSystem getCoordinateReferenceSystem() {
0362:                assert crs == null
0363:                        || crs.getCoordinateSystem().getDimension() == getDimension();
0364:                return crs;
0365:            }
0366:
0367:            /**
0368:             * Set the coordinate reference system in which the coordinate are given.
0369:             * Note: this method <strong>do not</strong> reproject the envelope.
0370:             *
0371:             * @param  crs The new coordinate reference system, or {@code null}.
0372:             * @throws MismatchedDimensionException if the specified CRS doesn't have the expected
0373:             *         number of dimensions.
0374:             */
0375:            public void setCoordinateReferenceSystem(
0376:                    final CoordinateReferenceSystem crs)
0377:                    throws MismatchedDimensionException {
0378:                AbstractDirectPosition.checkCoordinateReferenceSystemDimension(
0379:                        crs, getDimension());
0380:                this .crs = crs;
0381:            }
0382:
0383:            /**
0384:             * Returns the number of dimensions.
0385:             */
0386:            public final int getDimension() {
0387:                return ordinates.length / 2;
0388:            }
0389:
0390:            /**
0391:             * A coordinate position consisting of all the {@linkplain #getMinimum minimal ordinates}
0392:             * for each dimension for all points within the {@code Envelope}.
0393:             *
0394:             * @return The lower corner.
0395:             */
0396:            //@Override
0397:            public DirectPosition getLowerCorner() {
0398:                final int dim = ordinates.length / 2;
0399:                final GeneralDirectPosition position = new GeneralDirectPosition(
0400:                        dim);
0401:                System.arraycopy(ordinates, 0, position.ordinates, 0, dim);
0402:                position.setCoordinateReferenceSystem(crs);
0403:                return position;
0404:            }
0405:
0406:            /**
0407:             * A coordinate position consisting of all the {@linkplain #getMaximum maximal ordinates}
0408:             * for each dimension for all points within the {@code Envelope}.
0409:             *
0410:             * @return The upper corner.
0411:             */
0412:            //@Override
0413:            public DirectPosition getUpperCorner() {
0414:                final int dim = ordinates.length / 2;
0415:                final GeneralDirectPosition position = new GeneralDirectPosition(
0416:                        dim);
0417:                System.arraycopy(ordinates, dim, position.ordinates, 0, dim);
0418:                position.setCoordinateReferenceSystem(crs);
0419:                return position;
0420:            }
0421:
0422:            /**
0423:             * A coordinate position consisting of all the {@linkplain #getCenter(int) middle ordinates}
0424:             * for each dimension for all points within the {@code Envelope}.
0425:             *
0426:             * @since 2.3
0427:             */
0428:            public DirectPosition getCenter() {
0429:                final GeneralDirectPosition position = new GeneralDirectPosition(
0430:                        ordinates.length / 2);
0431:                for (int i = position.ordinates.length; --i >= 0;) {
0432:                    position.ordinates[i] = getCenter(i);
0433:                }
0434:                position.setCoordinateReferenceSystem(crs);
0435:                return position;
0436:            }
0437:
0438:            /**
0439:             * Returns the minimal ordinate along the specified dimension.
0440:             */
0441:            public final double getMinimum(final int dimension) {
0442:                if (dimension < ordinates.length / 2) {
0443:                    return ordinates[dimension];
0444:                } else {
0445:                    throw new ArrayIndexOutOfBoundsException(dimension);
0446:                }
0447:            }
0448:
0449:            /**
0450:             * Returns the maximal ordinate along the specified dimension.
0451:             */
0452:            public final double getMaximum(final int dimension) {
0453:                if (dimension >= 0) {
0454:                    return ordinates[dimension + ordinates.length / 2];
0455:                } else {
0456:                    throw new ArrayIndexOutOfBoundsException(dimension);
0457:                }
0458:            }
0459:
0460:            /**
0461:             * Returns the center ordinate along the specified dimension.
0462:             */
0463:            public final double getCenter(final int dimension) {
0464:                return 0.5 * (ordinates[dimension] + ordinates[dimension
0465:                        + ordinates.length / 2]);
0466:            }
0467:
0468:            /**
0469:             * Returns the envelope length along the specified dimension.
0470:             * This length is equals to the maximum ordinate minus the
0471:             * minimal ordinate.
0472:             */
0473:            public final double getLength(final int dimension) {
0474:                return ordinates[dimension + ordinates.length / 2]
0475:                        - ordinates[dimension];
0476:            }
0477:
0478:            /**
0479:             * Returns the envelope length along the specified dimension, in terms of the given units.
0480:             *
0481:             * @param  unit The unit for the return value.
0482:             * @return The length in terms of the given unit.
0483:             * @throws ConversionException if the length can't be converted to the specified units.
0484:             *
0485:             * @since 2.2
0486:             */
0487:            public double getLength(final int dimension, final Unit unit)
0488:                    throws ConversionException {
0489:                double value = getLength(dimension);
0490:                if (crs != null) {
0491:                    final Unit source = crs.getCoordinateSystem().getAxis(
0492:                            dimension).getUnit();
0493:                    if (source != null) {
0494:                        value = source.getConverterTo(unit).convert(value);
0495:                    }
0496:                }
0497:                return value;
0498:            }
0499:
0500:            /**
0501:             * Set the envelope's range along the specified dimension.
0502:             *
0503:             * @param dimension The dimension to set.
0504:             * @param minimum   The minimum value along the specified dimension.
0505:             * @param maximum   The maximum value along the specified dimension.
0506:             */
0507:            public void setRange(final int dimension, double minimum,
0508:                    double maximum) {
0509:                if (minimum > maximum) {
0510:                    // Make an empty envelope (min==max)
0511:                    // while keeping it legal (min<=max).
0512:                    minimum = maximum = 0.5 * (minimum + maximum);
0513:                }
0514:                if (dimension >= 0) {
0515:                    // An exception will be thrown before any change if 'dimension' is out of range.
0516:                    ordinates[dimension + ordinates.length / 2] = maximum;
0517:                    ordinates[dimension] = minimum;
0518:                } else {
0519:                    throw new ArrayIndexOutOfBoundsException(dimension);
0520:                }
0521:            }
0522:
0523:            /**
0524:             * Set this envelope to the same coordinate values than the specified envelope.
0525:             *
0526:             * @param  envelope The new envelope to copy coordinates from.
0527:             * @throws MismatchedDimensionException if the specified envelope doesn't have the expected
0528:             *         number of dimensions.
0529:             *
0530:             * @since 2.2
0531:             */
0532:            public void setEnvelope(final GeneralEnvelope envelope)
0533:                    throws MismatchedDimensionException {
0534:                ensureNonNull("envelope", envelope);
0535:                AbstractDirectPosition.ensureDimensionMatch("envelope",
0536:                        envelope.getDimension(), getDimension());
0537:                System.arraycopy(envelope.ordinates, 0, ordinates, 0,
0538:                        ordinates.length);
0539:                if (envelope.crs != null) {
0540:                    crs = envelope.crs;
0541:                    assert crs.getCoordinateSystem().getDimension() == getDimension() : crs;
0542:                    assert !envelope.getClass().equals(getClass())
0543:                            || equals(envelope) : envelope;
0544:                }
0545:            }
0546:
0547:            /**
0548:             * Sets the lower corner to {@linkplain Double#NEGATIVE_INFINITY negative infinity}
0549:             * and the upper corner to {@linkplain Double#POSITIVE_INFINITY positive infinity}.
0550:             * The {@linkplain #getCoordinateReferenceSystem coordinate reference system} (if any)
0551:             * stay unchanged.
0552:             *
0553:             * @since 2.2
0554:             */
0555:            public void setToInfinite() {
0556:                final int mid = ordinates.length / 2;
0557:                Arrays.fill(ordinates, 0, mid, Double.NEGATIVE_INFINITY);
0558:                Arrays.fill(ordinates, mid, ordinates.length,
0559:                        Double.POSITIVE_INFINITY);
0560:                assert isInfinite() : this ;
0561:            }
0562:
0563:            /**
0564:             * Returns {@code true} if at least one ordinate has an
0565:             * {@linkplain Double#isInfinite infinite} value.
0566:             *
0567:             * @since 2.2
0568:             */
0569:            public boolean isInfinite() {
0570:                for (int i = 0; i < ordinates.length; i++) {
0571:                    if (Double.isInfinite(ordinates[i])) {
0572:                        return true;
0573:                    }
0574:                }
0575:                return false;
0576:            }
0577:
0578:            /**
0579:             * Sets all ordinate values to {@linkplain Double#NaN NaN}. The
0580:             * {@linkplain #getCoordinateReferenceSystem coordinate reference system} (if any) stay
0581:             * unchanged.
0582:             *
0583:             * @since 2.2
0584:             */
0585:            public void setToNull() {
0586:                Arrays.fill(ordinates, Double.NaN);
0587:                assert isNull() : this ;
0588:            }
0589:
0590:            /**
0591:             * Returns {@code false} if at least one ordinate value is not {@linkplain Double#NaN NaN}. The
0592:             * {@code isNull()} check is a little bit different than {@link #isEmpty()} since it returns
0593:             * {@code false} for a partially initialized envelope, while {@code isEmpty()} returns
0594:             * {@code false} only after all dimensions have been initialized. More specifically, the
0595:             * following rules apply:
0596:             * <p>
0597:             * <ul>
0598:             *   <li>If <code>isNull() == true</code>, then <code>{@linkplain #isEmpty()} == true</code></li>
0599:             *   <li>If <code>{@linkplain #isEmpty()} == false</code>, then <code>isNull() == false</code></li>
0600:             *   <li>The converse of the above-cited rules are not always true.</li>
0601:             * </ul>
0602:             *
0603:             * @since 2.2
0604:             */
0605:            public boolean isNull() {
0606:                for (int i = 0; i < ordinates.length; i++) {
0607:                    if (!Double.isNaN(ordinates[i])) {
0608:                        return false;
0609:                    }
0610:                }
0611:                assert isEmpty() : this ;
0612:                return true;
0613:            }
0614:
0615:            /**
0616:             * Determines whether or not this envelope is empty. An envelope is non-empty only if it has
0617:             * at least one {@linkplain #getDimension dimension}, and the {@linkplain #getLength length}
0618:             * is greater than 0 along all dimensions. Note that a non-empty envelope is always
0619:             * non-{@linkplain #isNull null}, but the converse is not always true.
0620:             */
0621:            public boolean isEmpty() {
0622:                final int dimension = ordinates.length / 2;
0623:                if (dimension == 0) {
0624:                    return true;
0625:                }
0626:                for (int i = 0; i < dimension; i++) {
0627:                    if (!(ordinates[i] < ordinates[i + dimension])) { // Use '!' in order to catch NaN
0628:                        return true;
0629:                    }
0630:                }
0631:                assert !isNull() : this ;
0632:                return false;
0633:            }
0634:
0635:            /**
0636:             * Returns {@code true} if at least one of the specified CRS is null, or both CRS are equals.
0637:             * This special processing for {@code null} values is different from the usual contract of an
0638:             * {@code equals} method, but allow to handle the case where the CRS is unknown.
0639:             */
0640:            private static boolean equalsIgnoreMetadata(
0641:                    final CoordinateReferenceSystem crs1,
0642:                    final CoordinateReferenceSystem crs2) {
0643:                return crs1 == null || crs2 == null
0644:                        || CRS.equalsIgnoreMetadata(crs1, crs2);
0645:            }
0646:
0647:            /**
0648:             * Adds a point to this envelope. The resulting envelope is the smallest envelope that
0649:             * contains both the original envelope and the specified point. After adding a point,
0650:             * a call to {@link #contains} with the added point as an argument will return {@code true},
0651:             * except if one of the point's ordinates was {@link Double#NaN} (in which case the
0652:             * corresponding ordinate have been ignored).
0653:             * <p>
0654:             * This method assumes that the specified point uses the same CRS than this envelope.
0655:             * For performance reason, it will no be verified unless J2SE assertions are enabled.
0656:             *
0657:             * @param  position The point to add.
0658:             * @throws MismatchedDimensionException if the specified point doesn't have
0659:             *         the expected dimension.
0660:             */
0661:            public void add(final DirectPosition position)
0662:                    throws MismatchedDimensionException {
0663:                ensureNonNull("position", position);
0664:                final int dim = ordinates.length / 2;
0665:                AbstractDirectPosition.ensureDimensionMatch("position",
0666:                        position.getDimension(), dim);
0667:                assert equalsIgnoreMetadata(crs, position
0668:                        .getCoordinateReferenceSystem()) : position;
0669:                for (int i = 0; i < dim; i++) {
0670:                    final double value = position.getOrdinate(i);
0671:                    if (value < ordinates[i])
0672:                        ordinates[i] = value;
0673:                    if (value > ordinates[i + dim])
0674:                        ordinates[i + dim] = value;
0675:                }
0676:                assert isEmpty() || contains(position);
0677:            }
0678:
0679:            /**
0680:             * Adds an envelope object to this envelope. The resulting envelope is the union of the
0681:             * two {@code Envelope} objects.
0682:             * <p>
0683:             * This method assumes that the specified envelope uses the same CRS than this envelope.
0684:             * For performance reason, it will no be verified unless J2SE assertions are enabled.
0685:             *
0686:             * @param  envelope the {@code Envelope} to add to this envelope.
0687:             * @throws MismatchedDimensionException if the specified envelope doesn't
0688:             *         have the expected dimension.
0689:             */
0690:            public void add(final Envelope envelope)
0691:                    throws MismatchedDimensionException {
0692:                ensureNonNull("envelope", envelope);
0693:                final int dim = ordinates.length / 2;
0694:                AbstractDirectPosition.ensureDimensionMatch("envelope",
0695:                        envelope.getDimension(), dim);
0696:                assert equalsIgnoreMetadata(crs, envelope
0697:                        .getCoordinateReferenceSystem()) : envelope;
0698:                for (int i = 0; i < dim; i++) {
0699:                    final double min = envelope.getMinimum(i);
0700:                    final double max = envelope.getMaximum(i);
0701:                    if (min < ordinates[i])
0702:                        ordinates[i] = min;
0703:                    if (max > ordinates[i + dim])
0704:                        ordinates[i + dim] = max;
0705:                }
0706:                assert isEmpty() || contains(envelope, true);
0707:            }
0708:
0709:            /**
0710:             * Tests if a specified coordinate is inside the boundary of this envelope.
0711:             * <p>
0712:             * This method assumes that the specified point uses the same CRS than this envelope.
0713:             * For performance reason, it will no be verified unless J2SE assertions are enabled.
0714:             *
0715:             * @param  position The point to text.
0716:             * @return {@code true} if the specified coordinates are inside the boundary
0717:             *         of this envelope; {@code false} otherwise.
0718:             * @throws MismatchedDimensionException if the specified point doesn't have
0719:             *         the expected dimension.
0720:             */
0721:            public boolean contains(final DirectPosition position)
0722:                    throws MismatchedDimensionException {
0723:                ensureNonNull("position", position);
0724:                final int dim = ordinates.length / 2;
0725:                AbstractDirectPosition.ensureDimensionMatch("point", position
0726:                        .getDimension(), dim);
0727:                assert equalsIgnoreMetadata(crs, position
0728:                        .getCoordinateReferenceSystem()) : position;
0729:                for (int i = 0; i < dim; i++) {
0730:                    final double value = position.getOrdinate(i);
0731:                    if (!(value >= ordinates[i]))
0732:                        return false;
0733:                    if (!(value <= ordinates[i + dim]))
0734:                        return false;
0735:                    // Use '!' in order to take 'NaN' in account.
0736:                }
0737:                return true;
0738:            }
0739:
0740:            /**
0741:             * Returns {@code true} if this envelope completly encloses the specified envelope.
0742:             * If one or more edges from the specified envelope coincide with an edge from this
0743:             * envelope, then this method returns {@code true} only if {@code edgesInclusive}
0744:             * is {@code true}.
0745:             * <p>
0746:             * This method assumes that the specified envelope uses the same CRS than this envelope.
0747:             * For performance reason, it will no be verified unless J2SE assertions are enabled.
0748:             *
0749:             * @param  envelope The envelope to test for inclusion.
0750:             * @param  edgesInclusive {@code true} if this envelope edges are inclusive.
0751:             * @return {@code true} if this envelope completly encloses the specified one.
0752:             * @throws MismatchedDimensionException if the specified envelope doesn't have
0753:             *         the expected dimension.
0754:             *
0755:             * @see #intersects(Envelope, boolean)
0756:             * @see #equals(Envelope, double)
0757:             *
0758:             * @since 2.2
0759:             */
0760:            public boolean contains(final Envelope envelope,
0761:                    final boolean edgesInclusive)
0762:                    throws MismatchedDimensionException {
0763:                ensureNonNull("envelope", envelope);
0764:                final int dim = ordinates.length / 2;
0765:                AbstractDirectPosition.ensureDimensionMatch("envelope",
0766:                        envelope.getDimension(), dim);
0767:                assert equalsIgnoreMetadata(crs, envelope
0768:                        .getCoordinateReferenceSystem()) : envelope;
0769:                for (int i = 0; i < dim; i++) {
0770:                    double inner = envelope.getMinimum(i);
0771:                    double outer = ordinates[i];
0772:                    if (!(edgesInclusive ? inner >= outer : inner > outer)) { // ! is for catching NaN.
0773:                        return false;
0774:                    }
0775:                    inner = envelope.getMaximum(i);
0776:                    outer = ordinates[i + dim];
0777:                    if (!(edgesInclusive ? inner <= outer : inner < outer)) { // ! is for catching NaN.
0778:                        return false;
0779:                    }
0780:                }
0781:                assert intersects(envelope, edgesInclusive);
0782:                return true;
0783:            }
0784:
0785:            /**
0786:             * Returns {@code true} if this envelope intersects the specified envelope.
0787:             * If one or more edges from the specified envelope coincide with an edge from this
0788:             * envelope, then this method returns {@code true} only if {@code edgesInclusive}
0789:             * is {@code true}.
0790:             * <p>
0791:             * This method assumes that the specified envelope uses the same CRS than this envelope.
0792:             * For performance reason, it will no be verified unless J2SE assertions are enabled.
0793:             *
0794:             * @param  envelope The envelope to test for intersection.
0795:             * @param  edgesInclusive {@code true} if this envelope edges are inclusive.
0796:             * @return {@code true} if this envelope intersects the specified one.
0797:             * @throws MismatchedDimensionException if the specified envelope doesn't have
0798:             *         the expected dimension.
0799:             *
0800:             * @see #contains(Envelope, boolean)
0801:             * @see #equals(Envelope, double)
0802:             *
0803:             * @since 2.2
0804:             */
0805:            public boolean intersects(final Envelope envelope,
0806:                    final boolean edgesInclusive)
0807:                    throws MismatchedDimensionException {
0808:                ensureNonNull("envelope", envelope);
0809:                final int dim = ordinates.length / 2;
0810:                AbstractDirectPosition.ensureDimensionMatch("envelope",
0811:                        envelope.getDimension(), dim);
0812:                assert equalsIgnoreMetadata(crs, envelope
0813:                        .getCoordinateReferenceSystem()) : envelope;
0814:                for (int i = 0; i < dim; i++) {
0815:                    double inner = envelope.getMaximum(i);
0816:                    double outer = ordinates[i];
0817:                    if (!(edgesInclusive ? inner >= outer : inner > outer)) { // ! is for catching NaN.
0818:                        return false;
0819:                    }
0820:                    inner = envelope.getMinimum(i);
0821:                    outer = ordinates[i + dim];
0822:                    if (!(edgesInclusive ? inner <= outer : inner < outer)) { // ! is for catching NaN.
0823:                        return false;
0824:                    }
0825:                }
0826:                return true;
0827:            }
0828:
0829:            /**
0830:             * Sets this envelope to the intersection if this envelope with the specified one.
0831:             * <p>
0832:             * This method assumes that the specified envelope uses the same CRS than this envelope.
0833:             * For performance reason, it will no be verified unless J2SE assertions are enabled.
0834:             *
0835:             * @param  envelope the {@code Envelope} to intersect to this envelope.
0836:             * @throws MismatchedDimensionException if the specified envelope doesn't
0837:             *         have the expected dimension.
0838:             */
0839:            public void intersect(final Envelope envelope)
0840:                    throws MismatchedDimensionException {
0841:                ensureNonNull("envelope", envelope);
0842:                final int dim = ordinates.length / 2;
0843:                AbstractDirectPosition.ensureDimensionMatch("envelope",
0844:                        envelope.getDimension(), dim);
0845:                assert equalsIgnoreMetadata(crs, envelope
0846:                        .getCoordinateReferenceSystem()) : envelope;
0847:                for (int i = 0; i < dim; i++) {
0848:                    double min = Math.max(ordinates[i], envelope.getMinimum(i));
0849:                    double max = Math.min(ordinates[i + dim], envelope
0850:                            .getMaximum(i));
0851:                    if (min > max) {
0852:                        // Make an empty envelope (min==max)
0853:                        // while keeping it legal (min<=max).
0854:                        min = max = 0.5 * (min + max);
0855:                    }
0856:                    ordinates[i] = min;
0857:                    ordinates[i + dim] = max;
0858:                }
0859:            }
0860:
0861:            /**
0862:             * Returns a new envelope that encompass only some dimensions of this envelope.
0863:             * This method copy this envelope's ordinates into a new envelope, beginning at
0864:             * dimension <code>lower</code> and extending to dimension <code>upper-1</code>.
0865:             * Thus the dimension of the subenvelope is <code>upper-lower</code>.
0866:             *
0867:             * @param  lower The first dimension to copy, inclusive.
0868:             * @param  upper The last  dimension to copy, exclusive.
0869:             * @return The subenvelope.
0870:             * @throws IndexOutOfBoundsException if an index is out of bounds.
0871:             */
0872:            public GeneralEnvelope getSubEnvelope(final int lower,
0873:                    final int upper) throws IndexOutOfBoundsException {
0874:                final int curDim = ordinates.length / 2;
0875:                final int newDim = upper - lower;
0876:                if (lower < 0 || lower > curDim) {
0877:                    throw new IndexOutOfBoundsException(Errors.format(
0878:                            ErrorKeys.ILLEGAL_ARGUMENT_$2, "lower",
0879:                            new Integer(lower)));
0880:                }
0881:                if (newDim < 0 || upper > curDim) {
0882:                    throw new IndexOutOfBoundsException(Errors.format(
0883:                            ErrorKeys.ILLEGAL_ARGUMENT_$2, "upper",
0884:                            new Integer(upper)));
0885:                }
0886:                final GeneralEnvelope envelope = new GeneralEnvelope(newDim);
0887:                System.arraycopy(ordinates, lower, envelope.ordinates, 0,
0888:                        newDim);
0889:                System.arraycopy(ordinates, lower + curDim, envelope.ordinates,
0890:                        newDim, newDim);
0891:                return envelope;
0892:            }
0893:
0894:            /**
0895:             * Returns a new envelope with the same values than this envelope minus the
0896:             * specified range of dimensions.
0897:             *
0898:             * @param  lower The first dimension to omit, inclusive.
0899:             * @param  upper The last  dimension to omit, exclusive.
0900:             * @return The subenvelope.
0901:             * @throws IndexOutOfBoundsException if an index is out of bounds.
0902:             */
0903:            public GeneralEnvelope getReducedEnvelope(final int lower,
0904:                    final int upper) throws IndexOutOfBoundsException {
0905:                final int curDim = ordinates.length / 2;
0906:                final int rmvDim = upper - lower;
0907:                if (lower < 0 || lower > curDim) {
0908:                    throw new IndexOutOfBoundsException(Errors.format(
0909:                            ErrorKeys.ILLEGAL_ARGUMENT_$2, "lower",
0910:                            new Integer(lower)));
0911:                }
0912:                if (rmvDim < 0 || upper > curDim) {
0913:                    throw new IndexOutOfBoundsException(Errors.format(
0914:                            ErrorKeys.ILLEGAL_ARGUMENT_$2, "upper",
0915:                            new Integer(upper)));
0916:                }
0917:                final GeneralEnvelope envelope = new GeneralEnvelope(curDim
0918:                        - rmvDim);
0919:                System.arraycopy(ordinates, 0, envelope.ordinates, 0, lower);
0920:                System.arraycopy(ordinates, lower, envelope.ordinates, upper,
0921:                        curDim - upper);
0922:                return envelope;
0923:            }
0924:
0925:            /**
0926:             * Returns a {@link Rectangle2D} with the same bounds as this {@code Envelope}.
0927:             * This is a convenience method for interoperability with Java2D.
0928:             *
0929:             * @throws IllegalStateException if this envelope is not two-dimensional.
0930:             */
0931:            public Rectangle2D toRectangle2D() throws IllegalStateException {
0932:                if (ordinates.length == 4) {
0933:                    return XRectangle2D.createFromExtremums(ordinates[0],
0934:                            ordinates[1], ordinates[2], ordinates[3]);
0935:                } else {
0936:                    throw new IllegalStateException(Errors.format(
0937:                            ErrorKeys.NOT_TWO_DIMENSIONAL_$1, new Integer(
0938:                                    getDimension())));
0939:                }
0940:            }
0941:
0942:            /**
0943:             * Returns a hash value for this envelope.
0944:             */
0945:            public int hashCode() {
0946:                int code = GeneralDirectPosition.hashCode(ordinates);
0947:                if (crs != null) {
0948:                    code += crs.hashCode();
0949:                }
0950:                assert code == super .hashCode();
0951:                return code;
0952:            }
0953:
0954:            /**
0955:             * Compares the specified object with this envelope for equality.
0956:             */
0957:            public boolean equals(final Object object) {
0958:                if (object != null && object.getClass().equals(getClass())) {
0959:                    final GeneralEnvelope that = (GeneralEnvelope) object;
0960:                    return Arrays.equals(this .ordinates, that.ordinates)
0961:                            && Utilities.equals(this .crs, that.crs);
0962:                }
0963:                return false;
0964:            }
0965:
0966:            /**
0967:             * Compares to the specified envelope for equality up to the specified relative tolerance value.
0968:             * The tolerance value {@code eps} is relative to the {@linkplain #getLength envelope length}
0969:             * along each dimension. More specifically, the actual tolerance value for a given dimension
0970:             * <var>i</var> is {@code eps}&times;{@code length} where {@code length} is the maximum of
0971:             * {@linkplain #getLength this envelope length} and the specified envelope length along
0972:             * dimension <var>i</var>.
0973:             * <p>
0974:             * Relative tolerance value (as opposed to absolute tolerance value) help to workaround the
0975:             * fact that tolerance value are CRS dependent. For example the tolerance value need to be
0976:             * smaller for geographic CRS than for UTM projections, because the former typically has a
0977:             * range of -180 to 180° while the later can have a range of thousands of meters.
0978:             * <p>
0979:             * This method assumes that the specified envelope uses the same CRS than this envelope.
0980:             * For performance reason, it will no be verified unless J2SE assertions are enabled.
0981:             *
0982:             * @see #contains(Envelope, boolean)
0983:             * @see #intersects(Envelope, boolean)
0984:             *
0985:             * @since 2.3
0986:             *
0987:             * @deprecated Use {@link #equals(Envelope, double, boolean)} instead.
0988:             */
0989:            public boolean equals(final Envelope envelope, final double eps) {
0990:                return equals(envelope, eps, true);
0991:            }
0992:
0993:            /**
0994:             * Compares to the specified envelope for equality up to the specified tolerance value.
0995:             * The tolerance value {@code eps} can be either relative to the {@linkplain #getLength 
0996:             * envelope length} along each dimension or can be an absolute value (as for example some
0997:             * ground resolution of a {@linkplain org.opengis.coverage.grid.GridCoverage grid coverage}).
0998:             * <p>
0999:             * If {@code relativeToLength} is set to {@code true}, the actual tolerance value for a given
1000:             * dimension <var>i</var> is {@code eps}&times;{@code length} where {@code length} is the
1001:             * maximum of {@linkplain #getLength this envelope length} and the specified envelope length
1002:             * along dimension <var>i</var>.
1003:             * <p>
1004:             * If {@code relativeToLength} is set to {@code false}, the actual tolerance value for a
1005:             * given dimension <var>i</var> is {@code eps}.
1006:             * <p>
1007:             * Relative tolerance value (as opposed to absolute tolerance value) help to workaround the
1008:             * fact that tolerance value are CRS dependent. For example the tolerance value need to be
1009:             * smaller for geographic CRS than for UTM projections, because the former typically has a
1010:             * range of -180 to 180° while the later can have a range of thousands of meters.
1011:             * <p>
1012:             * This method assumes that the specified envelope uses the same CRS than this envelope.
1013:             * For performance reason, it will no be verified unless J2SE assertions are enabled.
1014:             *
1015:             * @param envelope The envelope to compare with.
1016:             * @param eps The tolerance value to use for numerical comparaisons.
1017:             * @param relativeToLength {@code true} if the tolerance value should be relative to
1018:             *        axis length, or {@code false} if it is an absolute value.
1019:             *
1020:             * @see #contains(Envelope, boolean)
1021:             * @see #intersects(Envelope, boolean)
1022:             *
1023:             * @since 2.4
1024:             */
1025:            public boolean equals(final Envelope envelope, final double eps,
1026:                    final boolean relativeToLength) {
1027:                ensureNonNull("envelope", envelope);
1028:                final int dimension = getDimension();
1029:                if (envelope.getDimension() != dimension) {
1030:                    return false;
1031:                }
1032:                assert equalsIgnoreMetadata(crs, envelope
1033:                        .getCoordinateReferenceSystem()) : envelope;
1034:                for (int i = 0; i < dimension; i++) {
1035:                    double epsilon;
1036:                    if (relativeToLength) {
1037:                        epsilon = Math.max(getLength(i), envelope.getLength(i));
1038:                        epsilon = (epsilon > 0 && epsilon < Double.POSITIVE_INFINITY) ? epsilon
1039:                                * eps
1040:                                : eps;
1041:                    } else {
1042:                        epsilon = eps;
1043:                    }
1044:                    // Comparaison below uses '!' in order to catch NaN values.
1045:                    if (!(Math.abs(getMinimum(i) - envelope.getMinimum(i)) <= epsilon && Math
1046:                            .abs(getMaximum(i) - envelope.getMaximum(i)) <= epsilon)) {
1047:                        return false;
1048:                    }
1049:                }
1050:                return true;
1051:            }
1052:
1053:            /**
1054:             * Returns a deep copy of this envelope.
1055:             */
1056:            public Object clone() {
1057:                try {
1058:                    GeneralEnvelope e = (GeneralEnvelope) super .clone();
1059:                    e.ordinates = (double[]) e.ordinates.clone();
1060:                    return e;
1061:                } catch (CloneNotSupportedException exception) {
1062:                    // Should not happen, since we are cloneable.
1063:                    throw new AssertionError(exception);
1064:                }
1065:            }
1066:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.