Source Code Cross Referenced for SpatioTemporalCoverage3D.java in  » GIS » GeoTools-2.4.1 » org » geotools » coverage » 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.coverage 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2005-2006, Geotools Project Management Committee (PMC)
005:         *    (C) 2003, Institut de Recherche pour le Développement
006:         *
007:         *    This library is free software; you can redistribute it and/or
008:         *    modify it under the terms of the GNU Lesser General Public
009:         *    License as published by the Free Software Foundation; either
010:         *    version 2.1 of the License, or (at your option) any later version.
011:         *
012:         *    This library is distributed in the hope that it will be useful,
013:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015:         *    Lesser General Public License for more details.
016:         */
017:        package org.geotools.coverage;
018:
019:        // J2SE dependencies
020:        import java.awt.geom.Point2D;
021:        import java.awt.geom.Dimension2D;
022:        import java.awt.geom.Rectangle2D;
023:        import java.awt.geom.AffineTransform;
024:        import java.awt.image.RenderedImage;
025:        import java.awt.image.renderable.RenderableImage;
026:        import java.util.Date;
027:
028:        // JAI dependencies
029:        import javax.media.jai.util.Range;
030:
031:        // OpenGIS dependencies
032:        import org.opengis.coverage.Coverage;
033:        import org.opengis.coverage.SampleDimension;
034:        import org.opengis.coverage.CannotEvaluateException;
035:        import org.opengis.referencing.FactoryException;
036:        import org.opengis.referencing.cs.AxisDirection;
037:        import org.opengis.referencing.cs.CoordinateSystem;
038:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
039:        import org.opengis.referencing.operation.CoordinateOperation;
040:        import org.opengis.referencing.operation.CoordinateOperationFactory;
041:        import org.opengis.referencing.operation.MathTransform;
042:        import org.opengis.referencing.operation.MathTransform2D;
043:        import org.opengis.referencing.operation.TransformException;
044:        import org.opengis.geometry.Envelope;
045:        import org.opengis.geometry.DirectPosition;
046:        import org.opengis.geometry.MismatchedDimensionException;
047:        import org.opengis.metadata.extent.GeographicBoundingBox;
048:        import org.opengis.util.InternationalString;
049:
050:        // Geotools dependencies
051:        import org.geotools.factory.Hints;
052:        import org.geotools.coverage.grid.GridCoverage2D;
053:        import org.geotools.coverage.grid.GridCoverageFactory;
054:        import org.geotools.geometry.GeneralDirectPosition;
055:        import org.geotools.referencing.CRS;
056:        import org.geotools.referencing.ReferencingFactoryFinder;
057:        import org.geotools.referencing.crs.DefaultGeographicCRS;
058:        import org.geotools.referencing.crs.DefaultTemporalCRS;
059:        import org.geotools.referencing.operation.transform.ProjectiveTransform;
060:        import org.geotools.referencing.operation.TransformPathNotFoundException;
061:        import org.geotools.metadata.iso.extent.GeographicBoundingBoxImpl;
062:        import org.geotools.resources.geometry.XRectangle2D;
063:        import org.geotools.resources.CRSUtilities;
064:        import org.geotools.resources.i18n.Errors;
065:        import org.geotools.resources.i18n.ErrorKeys;
066:
067:        /**
068:         * Convenience view of an other coverage with <var>x</var>, <var>y</var> and <var>time</var> axis.
069:         * This class provides {@code evaluate} methods in two versions: the usual one expecting
070:         * a complete {@linkplain DirectPosition direct position}, and an other one expecting the
071:         * {@linkplain Point2D spatial position} and the {@linkplain Date date} as separated arguments.
072:         * This class will detects by itself which dimension is the time axis. It will also tries to uses
073:         * the {@code Point2D}'s {@linkplain java.awt.geom.Point2D.Double#x x} value for
074:         * {@linkplain AxisDirection#EAST east} or west direction, and the
075:         * {@linkplain java.awt.geom.Point2D.Double#y y} value for {@linkplain AxisDirection#NORTH north}
076:         * or south direction. The dimension mapping can be examined with the {@link #toSourceDimension}
077:         * method.
078:         * <br><br>
079:         * <strong>Note:</strong> This class is not thread safe for performance reasons. If desired,
080:         * users should create one instance of {@code SpatioTemporalCoverage3D} for each thread.
081:         *
082:         * @since 2.1
083:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/coverage/src/main/java/org/geotools/coverage/SpatioTemporalCoverage3D.java $
084:         * @version $Id: SpatioTemporalCoverage3D.java 25787 2007-06-10 16:04:55Z desruisseaux $
085:         * @author Martin Desruisseaux
086:         */
087:        public class SpatioTemporalCoverage3D extends AbstractCoverage {
088:            /**
089:             * The hints for the creation of coordinate operation.
090:             * The default coordinate operation factory should be suffisient.
091:             */
092:            private static final Hints HINTS = null;
093:
094:            /**
095:             * A set of usual axis directions for <var>x</var> and <var>y</var> values (opposite directions
096:             * not required). If an ordinate value is orientated toward one of those directions, it will be
097:             * interpreted as the {@link java.awt.geom.Point2D.Double#x} value if the direction was found at
098:             * an even index, or as the {@link java.awt.geom.Point2D.Double#y} value if the direction was
099:             * found at an odd index.
100:             */
101:            private static final AxisDirection[] DIRECTIONS = {
102:                    AxisDirection.EAST, AxisDirection.NORTH,
103:                    AxisDirection.DISPLAY_RIGHT, AxisDirection.DISPLAY_UP,
104:                    AxisDirection.COLUMN_POSITIVE, AxisDirection.ROW_POSITIVE };
105:
106:            /**
107:             * The wrapped coverage.
108:             */
109:            private final Coverage coverage;
110:
111:            /**
112:             * The temporal coordinate system, as a Geotools implementation in order to gets the
113:             * {@link DefaultTemporalCRS#toDate} and {@link DefaultTemporalCRS#toValue} methods.
114:             */
115:            private final DefaultTemporalCRS temporalCRS;
116:
117:            /**
118:             * The dimension of the temporal coordinate system.
119:             * All other dimensions are expected to be the temporal ones.
120:             */
121:            private final int temporalDimension;
122:
123:            /**
124:             * The dimension for <var>x</var> and <var>y</var> coordinates.
125:             */
126:            private final int xDimension, yDimension;
127:
128:            /**
129:             * The geographic bounding box. Will be computed only when first needed.
130:             */
131:            private transient GeographicBoundingBox boundingBox;
132:
133:            /**
134:             * The direct position to uses for {@code evaluate(...)} methods.
135:             * This object is cached and reused for performance purpose. However,
136:             * this caching sacrifies {@code SpatioTemporalCoverage3D} thread safety.
137:             */
138:            private final GeneralDirectPosition coordinate;
139:
140:            /**
141:             * The grid coverage factory for {@link #getCoverage2D} method.
142:             * Will be created only when first needed.
143:             */
144:            private transient GridCoverageFactory factory;
145:
146:            /**
147:             * Constructs a new coverage. The coordinate reference system will be the same than the
148:             * wrapped coverage, which must be three dimensional. This CRS must have a
149:             * {@linkplain DefaultTemporalCRS temporal} component.
150:             *
151:             * @param name The name for this coverage, or {@code null} for the same than {@code coverage}.
152:             * @param coverage The source coverage.
153:             * @throws IllegalArgumentException if the coverage CRS doesn't have a temporal component.
154:             */
155:            public SpatioTemporalCoverage3D(final CharSequence name,
156:                    final Coverage coverage) throws IllegalArgumentException {
157:                super (name, coverage);
158:                final CoordinateSystem cs = crs.getCoordinateSystem();
159:                final int dimension = cs.getDimension();
160:                if (dimension != 3) {
161:                    throw new MismatchedDimensionException(Errors.format(
162:                            ErrorKeys.MISMATCHED_DIMENSION_$2, new Integer(3),
163:                            new Integer(dimension)));
164:                }
165:                if (coverage instanceof  SpatioTemporalCoverage3D) {
166:                    final SpatioTemporalCoverage3D source = (SpatioTemporalCoverage3D) coverage;
167:                    this .coverage = source.coverage;
168:                    this .temporalCRS = source.temporalCRS;
169:                    this .temporalDimension = source.temporalDimension;
170:                    this .xDimension = source.xDimension;
171:                    this .yDimension = source.yDimension;
172:                    this .boundingBox = source.boundingBox;
173:                } else {
174:                    this .coverage = coverage;
175:                    temporalCRS = DefaultTemporalCRS.wrap(CRS
176:                            .getTemporalCRS(crs));
177:                    if (temporalCRS == null) {
178:                        throw new IllegalArgumentException(
179:                                Errors
180:                                        .format(ErrorKeys.ILLEGAL_COORDINATE_REFERENCE_SYSTEM));
181:                    }
182:                    temporalDimension = CRSUtilities.getDimensionOf(crs,
183:                            temporalCRS.getClass());
184:                    final int xDimension = (temporalDimension != 0) ? 0 : 1;
185:                    final int yDimension = (temporalDimension != 2) ? 2 : 1;
186:                    Boolean swap = null; // 'null' if unknown, otherwise TRUE or FALSE.
187:                    control: for (int p = 0; p <= 1; p++) {
188:                        final AxisDirection direction;
189:                        direction = cs
190:                                .getAxis(p == 0 ? xDimension : yDimension)
191:                                .getDirection().absolute();
192:                        for (int i = 0; i < DIRECTIONS.length; i++) {
193:                            if (direction.equals(DIRECTIONS[i])) {
194:                                final boolean needSwap = (i & 1) != p;
195:                                if (swap == null) {
196:                                    swap = Boolean.valueOf(needSwap);
197:                                } else if (swap.booleanValue() != needSwap) {
198:                                    swap = null; // Found an ambiguity; stop the search.
199:                                    break control;
200:                                }
201:                            }
202:                        }
203:                    }
204:                    if (swap != null && swap.booleanValue()) {
205:                        this .xDimension = yDimension;
206:                        this .yDimension = xDimension;
207:                    } else {
208:                        this .xDimension = xDimension;
209:                        this .yDimension = yDimension;
210:                    }
211:                }
212:                assert temporalDimension >= 0 && temporalDimension < dimension : temporalDimension;
213:                coordinate = new GeneralDirectPosition(dimension); // Each instance must have its own.
214:            }
215:
216:            /**
217:             * Returns the coverage specified at construction time.
218:             *
219:             * @since 2.2
220:             */
221:            public final Coverage getWrappedCoverage() {
222:                return coverage;
223:            }
224:
225:            /**
226:             * The number of sample dimensions in the coverage.
227:             * For grid coverages, a sample dimension is a band.
228:             *
229:             * @return The number of sample dimensions in the coverage.
230:             */
231:            public int getNumSampleDimensions() {
232:                return coverage.getNumSampleDimensions();
233:            }
234:
235:            /**
236:             * Retrieve sample dimension information for the coverage.
237:             *
238:             * @param  index Index for sample dimension to retrieve. Indices are numbered 0 to
239:             *         (<var>{@linkplain #getNumSampleDimensions n}</var>-1).
240:             * @return Sample dimension information for the coverage.
241:             * @throws IndexOutOfBoundsException if {@code index} is out of bounds.
242:             */
243:            public SampleDimension getSampleDimension(final int index)
244:                    throws IndexOutOfBoundsException {
245:                return coverage.getSampleDimension(index);
246:            }
247:
248:            /**
249:             * Returns the {@linkplain #getEnvelope envelope} geographic bounding box.
250:             * The bounding box coordinates uses the {@linkplain DefaultGeographicCRS#WGS84 WGS84} CRS.
251:             *
252:             * @return The geographic bounding box.
253:             * @throws TransformException if the envelope can't be transformed.
254:             */
255:            public GeographicBoundingBox getGeographicBoundingBox()
256:                    throws TransformException {
257:                if (boundingBox == null) {
258:                    final Envelope envelope = getEnvelope();
259:                    Rectangle2D geographicArea = XRectangle2D
260:                            .createFromExtremums(envelope
261:                                    .getMinimum(xDimension), envelope
262:                                    .getMinimum(yDimension), envelope
263:                                    .getMaximum(xDimension), envelope
264:                                    .getMaximum(yDimension));
265:                    final CoordinateReferenceSystem sourceCRS = CRS
266:                            .getHorizontalCRS(crs);
267:                    final CoordinateReferenceSystem targetCRS = DefaultGeographicCRS.WGS84;
268:                    if (!CRS.equalsIgnoreMetadata(targetCRS, sourceCRS)) {
269:                        final CoordinateOperation transform;
270:                        final CoordinateOperationFactory factory;
271:                        factory = ReferencingFactoryFinder
272:                                .getCoordinateOperationFactory(HINTS);
273:                        try {
274:                            transform = factory.createOperation(sourceCRS,
275:                                    targetCRS);
276:                        } catch (FactoryException exception) {
277:                            throw new TransformPathNotFoundException(exception);
278:                        }
279:                        geographicArea = CRS.transform(transform,
280:                                geographicArea, geographicArea);
281:                    }
282:                    boundingBox = (GeographicBoundingBox) new GeographicBoundingBoxImpl(
283:                            geographicArea).unmodifiable();
284:                }
285:                return boundingBox;
286:            }
287:
288:            /**
289:             * Returns the {@linkplain #getEnvelope envelope} time range.
290:             * The returned range contains {@link Date} objects.
291:             */
292:            public Range getTimeRange() {
293:                final Envelope envelope = getEnvelope();
294:                return new Range(Date.class, temporalCRS.toDate(envelope
295:                        .getMinimum(temporalDimension)), temporalCRS
296:                        .toDate(envelope.getMaximum(temporalDimension)));
297:            }
298:
299:            /**
300:             * Returns the dimension in the wrapped coverage for the specified dimension in this coverage.
301:             * The {@code evaluate(Point2D, Date)} methods expect ordinates in the
302:             * (<var>x</var>,&nbsp;<var>y</var>,&nbsp;<var>t</var>) order.
303:             * The {@code evaluate(DirectPosition)} methods and the wrapped coverage way uses a different
304:             * order.
305:             *
306:             * @param  dimension A dimension in this coverage:
307:             *         0 for <var>x</var>,
308:             *         1 for <var>y</var> or
309:             *         2 for <var>t</var>.
310:             * @return The corresponding dimension in the wrapped coverage.
311:             *
312:             * @see #toDate
313:             * @see #toPoint2D
314:             * @see #toDirectPosition
315:             */
316:            public final int toSourceDimension(final int dimension) {
317:                switch (dimension) {
318:                case 0:
319:                    return xDimension;
320:                case 1:
321:                    return yDimension;
322:                case 2:
323:                    return temporalDimension;
324:                default:
325:                    throw new IllegalArgumentException();
326:                }
327:            }
328:
329:            /**
330:             * Returns a coordinate point for the given spatial position and date.
331:             *
332:             * @param  point The spatial position.
333:             * @param  date  The date.
334:             * @return The coordinate point.
335:             *
336:             * @see #toDate
337:             * @see #toPoint2D
338:             *
339:             * @since 2.2
340:             */
341:            public final DirectPosition toDirectPosition(final Point2D point,
342:                    final Date date) {
343:                coordinate.ordinates[xDimension] = point.getX();
344:                coordinate.ordinates[yDimension] = point.getY();
345:                coordinate.ordinates[temporalDimension] = temporalCRS
346:                        .toValue(date);
347:                return coordinate;
348:            }
349:
350:            /**
351:             * Returns the date for the specified direct position. This method (together with
352:             * {@link #toPoint2D toPoint2D}) is the converse of {@link #toDirectPosition toDirectPosition}.
353:             *
354:             * @param  position The direct position, as computed by
355:             *                  {@link #toDirectPosition toDirectPosition}.
356:             * @return The date.
357:             *
358:             * @see #toPoint2D
359:             * @see #toDirectPosition
360:             *
361:             * @since 2.2
362:             */
363:            public final Date toDate(final DirectPosition position) {
364:                return temporalCRS.toDate(position
365:                        .getOrdinate(temporalDimension));
366:            }
367:
368:            /**
369:             * Returns the spatial coordinate for the specified direct position. This method (together with
370:             * {@link #toDate toDate}) is the converse of {@link #toDirectPosition toDirectPosition}.
371:             *
372:             * @param  position The direct position, as computed by
373:             *                  {@link #toDirectPosition toDirectPosition}.
374:             * @return The spatial coordinate.
375:             *
376:             * @see #toDate
377:             * @see #toDirectPosition
378:             *
379:             * @since 2.2
380:             */
381:            public final Point2D toPoint2D(final DirectPosition position) {
382:                return new Point2D.Double(position.getOrdinate(xDimension),
383:                        position.getOrdinate(yDimension));
384:            }
385:
386:            /**
387:             * Returns a sequence of boolean values for a given point in the coverage.
388:             *
389:             * @param  point The coordinate point where to evaluate.
390:             * @param  time  The date where to evaluate.
391:             * @param  dest  An array in which to store values, or {@code null} to create a new array.
392:             * @return The {@code dest} array, or a newly created array if {@code dest} was null.
393:             * @throws PointOutsideCoverageException if {@code point} or {@code time} is outside coverage.
394:             * @throws CannotEvaluateException if the computation failed for some other reason.
395:             */
396:            public final boolean[] evaluate(final Point2D point,
397:                    final Date time, boolean[] dest)
398:                    throws CannotEvaluateException {
399:                try {
400:                    return evaluate(toDirectPosition(point, time), dest);
401:                } catch (OrdinateOutsideCoverageException exception) {
402:                    if (exception.getOutOfBoundsDimension() == temporalDimension) {
403:                        exception = new OrdinateOutsideCoverageException(
404:                                exception, time);
405:                    }
406:                    throw exception;
407:                }
408:            }
409:
410:            /**
411:             * Returns a sequence of byte values for a given point in the coverage.
412:             *
413:             * @param  point The coordinate point where to evaluate.
414:             * @param  time  The date where to evaluate.
415:             * @param  dest  An array in which to store values, or {@code null} to create a new array.
416:             * @return The {@code dest} array, or a newly created array if {@code dest} was null.
417:             * @throws PointOutsideCoverageException if {@code point} or {@code time} is outside coverage.
418:             * @throws CannotEvaluateException if the computation failed for some other reason.
419:             */
420:            public final byte[] evaluate(final Point2D point, final Date time,
421:                    byte[] dest) throws CannotEvaluateException {
422:                try {
423:                    return evaluate(toDirectPosition(point, time), dest);
424:                } catch (OrdinateOutsideCoverageException exception) {
425:                    if (exception.getOutOfBoundsDimension() == temporalDimension) {
426:                        exception = new OrdinateOutsideCoverageException(
427:                                exception, time);
428:                    }
429:                    throw exception;
430:                }
431:            }
432:
433:            /**
434:             * Returns a sequence of integer values for a given point in the coverage.
435:             *
436:             * @param  point The coordinate point where to evaluate.
437:             * @param  time  The date where to evaluate.
438:             * @param  dest  An array in which to store values, or {@code null} to create a new array.
439:             * @return The {@code dest} array, or a newly created array if {@code dest} was null.
440:             * @throws PointOutsideCoverageException if {@code point} or {@code time} is outside coverage.
441:             * @throws CannotEvaluateException if the computation failed for some other reason.
442:             */
443:            public final int[] evaluate(final Point2D point, final Date time,
444:                    int[] dest) throws CannotEvaluateException {
445:                try {
446:                    return evaluate(toDirectPosition(point, time), dest);
447:                } catch (OrdinateOutsideCoverageException exception) {
448:                    if (exception.getOutOfBoundsDimension() == temporalDimension) {
449:                        exception = new OrdinateOutsideCoverageException(
450:                                exception, time);
451:                    }
452:                    throw exception;
453:                }
454:            }
455:
456:            /**
457:             * Returns a sequence of float values for a given point in the coverage.
458:             *
459:             * @param  point The coordinate point where to evaluate.
460:             * @param  time  The date where to evaluate.
461:             * @param  dest  An array in which to store values, or {@code null} to create a new array.
462:             * @return The {@code dest} array, or a newly created array if {@code dest} was null.
463:             * @throws PointOutsideCoverageException if {@code point} or {@code time} is outside coverage.
464:             * @throws CannotEvaluateException if the computation failed for some other reason.
465:             */
466:            public final float[] evaluate(final Point2D point, final Date time,
467:                    float[] dest) throws CannotEvaluateException {
468:                try {
469:                    return evaluate(toDirectPosition(point, time), dest);
470:                } catch (OrdinateOutsideCoverageException exception) {
471:                    if (exception.getOutOfBoundsDimension() == temporalDimension) {
472:                        exception = new OrdinateOutsideCoverageException(
473:                                exception, time);
474:                    }
475:                    throw exception;
476:                }
477:            }
478:
479:            /**
480:             * Returns a sequence of double values for a given point in the coverage.
481:             *
482:             * @param  point The coordinate point where to evaluate.
483:             * @param  time  The date where to evaluate.
484:             * @param  dest  An array in which to store values, or {@code null} to create a new array.
485:             * @return The {@code dest} array, or a newly created array if {@code dest} was null.
486:             * @throws PointOutsideCoverageException if {@code point} or {@code time} is outside coverage.
487:             * @throws CannotEvaluateException if the computation failed for some other reason.
488:             */
489:            public final double[] evaluate(final Point2D point,
490:                    final Date time, double[] dest)
491:                    throws CannotEvaluateException {
492:                try {
493:                    return evaluate(toDirectPosition(point, time), dest);
494:                } catch (OrdinateOutsideCoverageException exception) {
495:                    if (exception.getOutOfBoundsDimension() == temporalDimension) {
496:                        exception = new OrdinateOutsideCoverageException(
497:                                exception, time);
498:                    }
499:                    throw exception;
500:                }
501:            }
502:
503:            /**
504:             * Returns the value vector for a given point in the coverage.
505:             *
506:             * @param  coord The coordinate point where to evaluate.
507:             * @throws PointOutsideCoverageException if {@code coord} is outside coverage.
508:             * @throws CannotEvaluateException if the computation failed for some other reason.
509:             */
510:            public final Object evaluate(final DirectPosition coord)
511:                    throws CannotEvaluateException {
512:                return coverage.evaluate(coord);
513:            }
514:
515:            /**
516:             * Returns a sequence of boolean values for a given point in the coverage.
517:             */
518:            public final boolean[] evaluate(final DirectPosition coord,
519:                    boolean[] dest) throws CannotEvaluateException {
520:                return coverage.evaluate(coord, dest);
521:            }
522:
523:            /**
524:             * Returns a sequence of byte values for a given point in the coverage.
525:             */
526:            public final byte[] evaluate(final DirectPosition coord, byte[] dest)
527:                    throws CannotEvaluateException {
528:                return coverage.evaluate(coord, dest);
529:            }
530:
531:            /**
532:             * Returns a sequence of integer values for a given point in the coverage.
533:             */
534:            public final int[] evaluate(final DirectPosition coord, int[] dest)
535:                    throws CannotEvaluateException {
536:                return coverage.evaluate(coord, dest);
537:            }
538:
539:            /**
540:             * Returns a sequence of float values for a given point in the coverage.
541:             */
542:            public final float[] evaluate(final DirectPosition coord,
543:                    float[] dest) throws CannotEvaluateException {
544:                return coverage.evaluate(coord, dest);
545:            }
546:
547:            /**
548:             * Returns a sequence of double values for a given point in the coverage.
549:             */
550:            public final double[] evaluate(final DirectPosition coord,
551:                    final double[] dest) throws CannotEvaluateException {
552:                return coverage.evaluate(coord, dest);
553:            }
554:
555:            /**
556:             * Returns a 2 dimensional grid coverage for the given date. The grid geometry will be computed
557:             * in order to produces image with the {@linkplain #getDefaultPixelSize() default pixel size},
558:             * if any.
559:             *
560:             * @param  time The date where to evaluate.
561:             * @return The grid coverage at the specified time, or {@code null}
562:             *         if the requested date fall in a hole in the data.
563:             * @throws PointOutsideCoverageException if {@code time} is outside coverage.
564:             * @throws CannotEvaluateException if the computation failed for some other reason.
565:             *
566:             * @see #getRenderableImage(Date)
567:             * @see RenderableImage#createDefaultRendering()
568:             *
569:             * @todo Find some way to avoid the cast in the {@code return} statement.
570:             */
571:            public GridCoverage2D getGridCoverage2D(final Date time)
572:                    throws CannotEvaluateException {
573:                final InternationalString name = getName();
574:                final CoordinateReferenceSystem crs = CRS
575:                        .getHorizontalCRS(this .crs);
576:                final RenderedImage image = getRenderableImage(time)
577:                        .createDefaultRendering();
578:                final GridSampleDimension[] bands = new GridSampleDimension[getNumSampleDimensions()];
579:                for (int i = 0; i < getNumSampleDimensions(); i++) {
580:                    bands[i] = GridSampleDimension.wrap(getSampleDimension(i));
581:                }
582:                final MathTransform gridToCRS;
583:                gridToCRS = ProjectiveTransform.create((AffineTransform) image
584:                        .getProperty("gridToCRS"));
585:                if (factory == null) {
586:                    factory = org.geotools.coverage.FactoryFinder
587:                            .getGridCoverageFactory(HINTS);
588:                }
589:                return (GridCoverage2D) factory.create(name, image, crs,
590:                        gridToCRS, bands, null, null);
591:            }
592:
593:            /**
594:             * Returns 2D view of this grid coverage at the given date. For images produced by the
595:             * {@linkplain RenderableImage#createDefaultRendering() default rendering}, the size
596:             * will be computed from the {@linkplain #getDefaultPixelSize() default pixel size},
597:             * if any.
598:             *
599:             * @param  date The date where to evaluate the images.
600:             * @return The renderable image.
601:             */
602:            public RenderableImage getRenderableImage(final Date date) {
603:                return new Renderable(date);
604:            }
605:
606:            /**
607:             * Constructs rendered images on demand.
608:             *
609:             * @version $Id: SpatioTemporalCoverage3D.java 25787 2007-06-10 16:04:55Z desruisseaux $
610:             * @author Martin Desruisseaux
611:             */
612:            private final class Renderable extends AbstractCoverage.Renderable {
613:                /**
614:                 * Construct a {@code Renderable} object for the supplied date.
615:                 */
616:                public Renderable(final Date date) {
617:                    super (xDimension, yDimension);
618:                    coordinate.ordinates[temporalDimension] = temporalCRS
619:                            .toValue(date);
620:                }
621:
622:                /**
623:                 * Returns a rendered image with width and height computed from
624:                 * {@link Coverage3D#getDefaultPixelSize()}.
625:                 */
626:                public RenderedImage createDefaultRendering() {
627:                    final Dimension2D pixelSize = getDefaultPixelSize();
628:                    if (pixelSize == null) {
629:                        return super .createDefaultRendering();
630:                    }
631:                    return createScaledRendering((int) Math.round(getWidth()
632:                            / pixelSize.getWidth()), (int) Math
633:                            .round(getHeight() / pixelSize.getHeight()), null);
634:                }
635:            }
636:
637:            /**
638:             * Returns the default pixel size for images to be produced by {@link #getRenderableImage(Date)}.
639:             * This method is invoked by {@link RenderableImage#createDefaultRendering()} for computing a
640:             * default image size. The default implementation for this method always returns {@code null}.
641:             * Subclasses should overrides this method in order to provides a pixel size better suited to
642:             * their data.
643:             *
644:             * @return The default pixel size, or {@code null} if no default is provided.
645:             */
646:            protected Dimension2D getDefaultPixelSize() {
647:                return null;
648:            }
649:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.