Source Code Cross Referenced for AbstractGridCoverage2DReader.java in  » GIS » GeoTools-2.4.1 » org » geotools » data » coverage » grid » 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.data.coverage.grid 
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 Managment Committee (PMC)
005:         *    
006:         *    This library is free software; you can redistribute it and/or
007:         *    modify it under the terms of the GNU Lesser General Public
008:         *    License as published by the Free Software Foundation;
009:         *    version 2.1 of the License.
010:         *
011:         *    This library is distributed in the hope that it will be useful,
012:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
013:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014:         *    Lesser General Public License for more details.
015:         */
016:        package org.geotools.data.coverage.grid;
017:
018:        import java.awt.Color;
019:        import java.awt.Rectangle;
020:        import java.awt.color.ColorSpace;
021:        import java.awt.geom.AffineTransform;
022:        import java.awt.geom.Rectangle2D;
023:        import java.awt.image.ColorModel;
024:        import java.awt.image.DataBuffer;
025:        import java.awt.image.IndexColorModel;
026:        import java.io.IOException;
027:        import java.text.ParseException;
028:        import java.util.HashMap;
029:        import java.util.logging.Level;
030:        import java.util.logging.Logger;
031:
032:        import javax.imageio.ImageReadParam;
033:        import javax.imageio.ImageReader;
034:        import javax.imageio.stream.ImageInputStream;
035:        import javax.media.jai.IHSColorSpace;
036:        import javax.media.jai.PlanarImage;
037:        import javax.units.Unit;
038:        import javax.units.UnitFormat;
039:
040:        import org.geotools.coverage.Category;
041:        import org.geotools.coverage.FactoryFinder;
042:        import org.geotools.coverage.GridSampleDimension;
043:        import org.geotools.coverage.grid.GeneralGridRange;
044:        import org.geotools.coverage.grid.GridCoverage2D;
045:        import org.geotools.coverage.grid.GridCoverageFactory;
046:        import org.geotools.data.DataSourceException;
047:        import org.geotools.factory.Hints;
048:        import org.geotools.geometry.GeneralEnvelope;
049:        import org.geotools.referencing.operation.BufferedCoordinateOperationFactory;
050:        import org.geotools.referencing.operation.transform.LinearTransform1D;
051:        import org.geotools.resources.CRSUtilities;
052:        import org.geotools.util.NumberRange;
053:        import org.geotools.util.logging.Logging;
054:        import org.opengis.coverage.MetadataNameNotFoundException;
055:        import org.opengis.coverage.grid.GridCoverage;
056:        import org.opengis.coverage.grid.GridCoverageReader;
057:        import org.opengis.coverage.grid.GridRange;
058:        import org.opengis.referencing.FactoryException;
059:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
060:        import org.opengis.referencing.operation.CoordinateOperationFactory;
061:        import org.opengis.referencing.operation.MathTransform;
062:        import org.opengis.referencing.operation.TransformException;
063:
064:        /**
065:         * This class is a first attempt for providing a way to get more informations
066:         * out of a single 2D raster datasets (x,y). It is worth to remark that for the
067:         * moment this is thought for 2D rasters not for 3D or 4D rasters (x,y,z,t).
068:         * 
069:         * <p>
070:         * The main drawback I see with the current GeoApi GridCoverageReader interface
071:         * is that there is no way to get real information about a raster source unless
072:         * you instantiate a GridCoverage. As an instance it is impossible to know the
073:         * envelope, the number of overviews, the tile size. This information is needed
074:         * in order to perform decimation on reading or to use built-in overviews<br>
075:         * This really impacts the ability to exploit raster datasets in a desktop
076:         * environment where caching is crucial.
077:         * 
078:         * @author Simone Giannecchini
079:         * @since 2.3
080:         * @version 0.2
081:         * @deprecated use {@link org.geotools.coverage.grid.io.AbstractGridCoverage2DReader} instead.
082:         */
083:        public abstract class AbstractGridCoverage2DReader implements 
084:                GridCoverageReader {
085:
086:            /** The {@link Logger} for this {@link AbstractGridCoverage2DReader}. */
087:            private final static Logger LOGGER = Logging
088:                    .getLogger("org.geotools.data.coverage.grid");
089:
090:            /** Caches a default GridCoverageFactory for usage in plugins. */
091:            protected final static GridCoverageFactory coverageFactory = FactoryFinder
092:                    .getGridCoverageFactory(null);
093:
094:            protected static final double EPS = 1E-6;
095:
096:            /** Buffered factory for coordinate operations. */
097:            protected final static CoordinateOperationFactory operationFactory = new BufferedCoordinateOperationFactory(
098:                    new Hints(Hints.LENIENT_DATUM_SHIFT, Boolean.TRUE));
099:
100:            /**
101:             * Default color ramp. Preset colors used to generate an Image from the raw
102:             * data
103:             */
104:            protected final static Color[] demColors = new Color[] {
105:                    new Color(5, 90, 5), new Color(150, 200, 150),
106:                    new Color(190, 150, 20), new Color(100, 100, 50),
107:                    new Color(200, 210, 220), Color.WHITE, Color.WHITE,
108:                    Color.WHITE, Color.WHITE };
109:
110:            /**
111:             * This contains the maximum number of grid coverages in the file/stream.
112:             * Until multi-image files are supported, this is going to be 0 or 1.
113:             */
114:            protected volatile int numOverviews = 0;
115:
116:            /** 2DGridToWorld math transform. */
117:            protected MathTransform raster2Model = null;
118:
119:            /** crs for this coverage */
120:            protected CoordinateReferenceSystem crs = null;
121:
122:            /** Envelope read from file */
123:            protected GeneralEnvelope originalEnvelope = null;
124:
125:            /** Coverage name */
126:            protected String coverageName = "geotools_coverage";
127:
128:            /** Source to read from */
129:            protected Object source = null;
130:
131:            /** Hints used by the {@link AbstractGridCoverage2DReader} subclasses. */
132:            protected Hints hints = new Hints(new HashMap(5));
133:
134:            /**
135:             * Highest resolution availaible for this reader.
136:             */
137:            protected double[] highestRes = null;
138:
139:            /** Temp variable used in many readers. */
140:            protected boolean closeMe;
141:
142:            /**
143:             * In case we are trying to read from a GZipped file this will be set to
144:             * true.
145:             */
146:            protected boolean gzipped;
147:
148:            /**
149:             * The original {@link GridRange} for the {@link GridCoverage2D} of this
150:             * reader.
151:             */
152:            protected GeneralGridRange originalGridRange = null;
153:
154:            /**
155:             * Input stream that can be used to initialize subclasses of
156:             * {@link AbstractGridCoverage2DReader}.
157:             */
158:            protected ImageInputStream inStream = null;
159:
160:            /** Resolutions avialaible through an overviews based mechanism. */
161:            protected double[][] overViewResolutions = null;
162:
163:            // -------------------------------------------------------------------------
164:            //
165:            // old support methods
166:            //
167:            // -------------------------------------------------------------------------
168:            /**
169:             * This method is responsible for preparing the read param for doing an
170:             * {@link ImageReader#read(int, ImageReadParam)}.
171:             * 
172:             * 
173:             * <p>
174:             * This method is responsible for preparing the read param for doing an
175:             * {@link ImageReader#read(int, ImageReadParam)}. It sets the passed
176:             * {@link ImageReadParam} in terms of decimation on reading using the
177:             * provided requestedEnvelope and requestedDim to evaluate the needed
178:             * resolution. It also returns and {@link Integer} representing the index of
179:             * the raster to be read when dealing with multipage raster.
180:             * 
181:             * @param readP
182:             *            an instance of {@link ImageReadParam} for setting the
183:             *            subsampling factors.
184:             * @param requestedEnvelope
185:             *            the {@link GeneralEnvelope} we are requesting.
186:             * @param requestedDim
187:             *            the requested dimensions.
188:             * @return the index of the raster to read in the underlying data source.
189:             * @throws IOException
190:             * @throws TransformException
191:             */
192:            protected Integer setReadParams(ImageReadParam readP,
193:                    GeneralEnvelope requestedEnvelope, Rectangle requestedDim)
194:                    throws IOException, TransformException {
195:
196:                readP.setSourceSubsampling(1, 1, 0, 0);// default values for
197:                // subsampling
198:                // //
199:                //
200:                // Default image index 0
201:                //
202:                // //
203:                Integer imageChoice = new Integer(0);
204:
205:                // we are able to handle overviews properly only if the transformation is
206:                // an affine transform with pure scale and translation, no rotational components
207:                if (raster2Model != null && !isScaleTranslate(raster2Model))
208:                    return imageChoice;
209:
210:                // //
211:                //
212:                // Check Hint to ignore overviews
213:                //
214:                // //
215:                Object o = hints.get(Hints.IGNORE_COVERAGE_OVERVIEW);
216:                if (o != null && ((Boolean) o).booleanValue()) {
217:                    return imageChoice;
218:
219:                }
220:
221:                // //
222:                //
223:                // Am I going to decimate or to use overviews? If this geotiff has only
224:                // one page we use decimation, otherwise we use the best page avalabile.
225:                // Future versions should use both.
226:                //
227:                // //
228:                final boolean decimate = (numOverviews <= 0) ? true : false;
229:
230:                // //
231:                //
232:                // Resolution requested. I am here computing the resolution required by
233:                // the user.
234:                //
235:                // //
236:                double[] requestedRes = getResolution(requestedEnvelope,
237:                        requestedDim, crs);
238:                if (requestedRes == null)
239:                    return imageChoice;
240:
241:                // //
242:                //
243:                // overviews or decimation
244:                //
245:                // //
246:                if (!decimate) {
247:                    // /////////////////////////////////////////////////////////////////////
248:                    // OVERVIEWS
249:                    // /////////////////////////////////////////////////////////////////////
250:                    // Should we leave now? In case the resolution of the first level is
251:                    // already lower than the requested one we should use the first
252:                    // level and leave.
253:                    if (highestRes[0] - requestedRes[0] > EPS
254:                            && highestRes[1] - requestedRes[1] > EPS)
255:                        return imageChoice;
256:
257:                    // Should we leave now? In case the resolution of the first level is
258:                    // already lower than the requested one we should use the first
259:                    // level and leave.
260:                    int axis = 0;
261:                    if (requestedRes[0] - requestedRes[1] > EPS)
262:                        axis = 1;
263:
264:                    // //
265:                    //
266:                    // looking for the overview with the highest lower resolution
267:                    // compared
268:                    // to the requested one.
269:                    // This ensure more speed but less quality. In the future we should
270:                    // provide a hint to control this behaviour.
271:                    //
272:                    // //
273:                    double actRes;
274:                    int i = 0;
275:                    for (; i < numOverviews; i++) {
276:                        actRes = (axis == 0) ? overViewResolutions[i][0]
277:                                : overViewResolutions[i][1];
278:                        // is actual resolution lower than the requested resolution?
279:                        if (actRes - requestedRes[axis] > EPS) {
280:
281:                            i--;
282:                            break;
283:
284:                        }
285:
286:                    }
287:                    // checking that we did not exceeded the maximum number of pages.
288:                    if (i == numOverviews) {
289:                        // int subsamplingFactor=
290:                        imageChoice = new Integer(numOverviews);
291:                    } else
292:                        // keeping the first image at highest resolution into account in
293:                        // order to get the overview wit
294:                        imageChoice = new Integer(i + 1);
295:                }
296:                // /////////////////////////////////////////////////////////////////////
297:                // DECIMATION ON READING
298:                // /////////////////////////////////////////////////////////////////////
299:                decimationOnReadingControl(imageChoice, readP, requestedRes);
300:                return imageChoice;
301:            }
302:
303:            /**
304:             * Checks the transformation is a pure scale/translate instance (using a tolerance)
305:             * @param transform
306:             * @return
307:             */
308:            protected final boolean isScaleTranslate(MathTransform transform) {
309:                if (!(transform instanceof  AffineTransform))
310:                    return false;
311:                AffineTransform at = (AffineTransform) transform;
312:                return at.getShearX() < EPS && at.getShearY() < EPS;
313:            }
314:
315:            /**
316:             * This method is responsible for evaluating possible subsampling factors
317:             * once the best resolution level has been found, in case we have support
318:             * for overviews, or starting from the original coverage in case there are
319:             * no overviews availaible.
320:             * 
321:             * Anyhow this methof should not be called directly but subclasses should
322:             * make use of the setReadParams method instead in order to transparently
323:             * look for overviews.
324:             * 
325:             * @param imageChoice
326:             * @param readP
327:             * @param requestedRes
328:             */
329:            protected final void decimationOnReadingControl(
330:                    Integer imageChoice, ImageReadParam readP,
331:                    double[] requestedRes) {
332:                {
333:
334:                    int w, h;
335:                    double selectedRes[] = new double[2];
336:                    final int choice = imageChoice.intValue();
337:                    if (choice == 0) {
338:                        // highest resolution
339:                        w = originalGridRange.getLength(0);
340:                        h = originalGridRange.getLength(1);
341:                        selectedRes[0] = highestRes[0];
342:                        selectedRes[1] = highestRes[1];
343:                    } else {
344:                        // some overview
345:                        selectedRes[0] = overViewResolutions[choice - 1][0];
346:                        selectedRes[1] = overViewResolutions[choice - 1][1];
347:                        w = (int) Math.round(originalEnvelope.getLength(0)
348:                                / selectedRes[0]);
349:                        h = (int) Math.round(originalEnvelope.getLength(1)
350:                                / selectedRes[1]);
351:
352:                    }
353:                    // /////////////////////////////////////////////////////////////////////
354:                    // DECIMATION ON READING
355:                    // Setting subsampling factors with some checkings
356:                    // 1) the subsampling factors cannot be zero
357:                    // 2) the subsampling factors cannot be such that the w or h are
358:                    // zero
359:                    // /////////////////////////////////////////////////////////////////////
360:                    if (requestedRes == null) {
361:                        readP.setSourceSubsampling(1, 1, 0, 0);
362:
363:                    } else {
364:                        int subSamplingFactorX = (int) Math
365:                                .floor(requestedRes[0] / selectedRes[0]);
366:                        subSamplingFactorX = subSamplingFactorX == 0 ? 1
367:                                : subSamplingFactorX;
368:
369:                        while (w / subSamplingFactorX <= 0
370:                                && subSamplingFactorX >= 0)
371:                            subSamplingFactorX--;
372:                        subSamplingFactorX = subSamplingFactorX == 0 ? 1
373:                                : subSamplingFactorX;
374:
375:                        int subSamplingFactorY = (int) Math
376:                                .floor(requestedRes[1] / selectedRes[1]);
377:                        subSamplingFactorY = subSamplingFactorY == 0 ? 1
378:                                : subSamplingFactorY;
379:
380:                        while (h / subSamplingFactorY <= 0
381:                                && subSamplingFactorY >= 0)
382:                            subSamplingFactorY--;
383:                        subSamplingFactorY = subSamplingFactorY == 0 ? 1
384:                                : subSamplingFactorY;
385:
386:                        readP.setSourceSubsampling(subSamplingFactorX,
387:                                subSamplingFactorY, 0, 0);
388:                    }
389:
390:                }
391:            }
392:
393:            /**
394:             * Creates a {@link GridCoverage} for the provided {@link PlanarImage} using
395:             * the {@link #originalEnvelope} that was provided for this coverage.
396:             * 
397:             * @param image contains the data for the coverage to create.
398:             * @return a {@link GridCoverage}
399:             * @throws IOException
400:             */
401:            protected final GridCoverage createImageCoverage(PlanarImage image)
402:                    throws IOException {
403:                return createImageCoverage(image, null);
404:
405:            }
406:
407:            /**
408:             * Creates a {@link GridCoverage} for the provided {@link PlanarImage} using
409:             * the {@link #raster2Model} that was provided for this coverage.
410:             * 
411:             * <p>
412:             * This method is vital when working with coverages that have a raster to model transformation
413:             * that is not a simple scale and translate.
414:             * 
415:             * @param image contains the data for the coverage to create.
416:             * @param raster2Model is the {@link MathTransform} that maps from the 
417:             * 		  raster space to the model space.
418:             * @return a {@link GridCoverage}
419:             * @throws IOException
420:             */
421:            protected final GridCoverage createImageCoverage(PlanarImage image,
422:                    MathTransform raster2Model) throws IOException {
423:
424:                // deciding the number range
425:                NumberRange geophysicRange = null;
426:
427:                switch (image.getSampleModel().getTransferType()) {
428:                case DataBuffer.TYPE_BYTE:
429:                    geophysicRange = new NumberRange(0, 255);
430:
431:                    break;
432:
433:                case DataBuffer.TYPE_USHORT:
434:                    geophysicRange = new NumberRange(0, 65535);
435:
436:                    break;
437:                // going to treat following cases as DEM
438:                case DataBuffer.TYPE_INT:
439:                    geophysicRange = new NumberRange(Integer.MIN_VALUE,
440:                            Integer.MAX_VALUE);
441:                    break;
442:                case DataBuffer.TYPE_SHORT:
443:                    geophysicRange = new NumberRange(Short.MIN_VALUE,
444:                            Short.MAX_VALUE);
445:                    break;
446:                case DataBuffer.TYPE_DOUBLE:
447:
448:                    geophysicRange = new NumberRange(Double.MIN_VALUE,
449:                            Double.MAX_VALUE);
450:                    break;
451:                case DataBuffer.TYPE_FLOAT:
452:                    geophysicRange = new NumberRange(Float.MIN_VALUE,
453:                            Float.MAX_VALUE);
454:                    return createDEMCoverage(image);
455:                default:
456:                    throw new DataSourceException(
457:                            "createImageCoverage:Data buffer type not supported by this world image reader! Use byte, ushort or int");
458:                }
459:
460:                /**
461:                 * Now we shuld be able to create the sample dimensions and the
462:                 * categories for this coverage in a much better and meaningful way
463:                 * using the color model and the color space type.
464:                 * 
465:                 * @todo How do we handle the NoData when it is 0?
466:                 * 
467:                 */
468:                // convenieience category in order to
469:                final Category values = new Category("values",
470:                        new Color[] { Color.BLACK }, geophysicRange,
471:                        LinearTransform1D.IDENTITY);
472:
473:                // creating bands
474:                final int numBands = image.getSampleModel().getNumBands();
475:                final GridSampleDimension[] bands = new GridSampleDimension[numBands];
476:                // checking the names
477:                final ColorModel cm = image.getColorModel();
478:                final String names[] = new String[numBands];
479:                // in case of index color model we are already done.
480:                if (cm instanceof  IndexColorModel) {
481:                    names[0] = "index band";
482:                } else {
483:                    // in case of multiband image we are not done yet.
484:                    final ColorSpace cs = cm.getColorSpace();
485:
486:                    if (cs instanceof  IHSColorSpace) {
487:                        names[0] = "Intensity band";
488:                        names[1] = "Hue band";
489:                        names[2] = "Saturation band";
490:
491:                    } else {
492:                        /**
493:                         * 
494:                         * 
495:                         * @TODO we need to support more types than the ones we have
496:                         *       here.
497:                         * 
498:                         * 
499:                         */
500:                        // not IHS, let's take the type
501:                        final int type = cs.getType();
502:                        switch (type) {
503:                        case ColorSpace.CS_GRAY:
504:                        case ColorSpace.TYPE_GRAY:
505:                            names[0] = "grayscale band";
506:                            break;
507:                        case ColorSpace.CS_sRGB:
508:                        case ColorSpace.CS_LINEAR_RGB:
509:                        case ColorSpace.TYPE_RGB:
510:                            names[0] = "Red band";
511:                            names[1] = "Green band";
512:                            names[2] = "Blue band";
513:                            break;
514:                        case ColorSpace.TYPE_CMY:
515:                            names[0] = "Cyan band";
516:                            names[1] = "Magenta band";
517:                            names[2] = "Yellow band";
518:                            break;
519:                        case ColorSpace.TYPE_CMYK:
520:                            names[0] = "Cyan band";
521:                            names[1] = "Magenta band";
522:                            names[2] = "Yellow band";
523:                            names[3] = "K band";
524:                            break;
525:
526:                        }
527:                    }
528:                }
529:                // setting bands names.
530:                for (int i = 0; i < numBands; i++) {
531:
532:                    bands[i] = new GridSampleDimension(names[i],
533:                            new Category[] { values }, null).geophysics(true);
534:                }
535:
536:                // creating coverage
537:                if (raster2Model != null) {
538:                    return coverageFactory.create(coverageName, image, crs,
539:                            raster2Model, bands, null, null);
540:                }
541:
542:                return coverageFactory.create(coverageName, image,
543:                        new GeneralEnvelope(originalEnvelope), bands, null,
544:                        null);
545:
546:            }
547:
548:            /**
549:             * Creates a {@link GridCoverage} for a coverage that is not a simple image
550:             * but that contains complex dadta from measurements.
551:             * 
552:             * 
553:             * <p>
554:             * This usually means that the original {@link DataBuffer#getDataType()} is
555:             * of one of the following types:
556:             * 
557:             * <ul>
558:             * <li>{@link DataBuffer#TYPE_FLOAT}</li>
559:             * <li>{@link DataBuffer#TYPE_DOUBLE}</li>
560:             * <li>{@link DataBuffer#TYPE_INT}</li>
561:             * <li>{@link DataBuffer#TYPE_SHORT}</li>
562:             * </ul>
563:             * 
564:             * and it implies that we have to prepare a transformation from geophysics
565:             * values to non-geophysics values.
566:             * 
567:             * @param coverage
568:             *            a {@link PlanarImage} containing the source coverage.
569:             * @return a {@link GridCoverage}.
570:             */
571:            private GridCoverage createDEMCoverage(PlanarImage coverage) {
572:                // Create the SampleDimension, with colors and byte transformation
573:                // needed for visualization
574:                final UnitFormat unitFormat = UnitFormat.getStandardInstance();
575:                Unit uom = null;
576:
577:                // unit of measure is meter usually, is this a good guess?
578:                try {
579:                    uom = unitFormat.parseUnit("m");
580:                } catch (ParseException e) {
581:                    uom = null;
582:                }
583:
584:                final Category values = new Category("elevation", demColors,
585:                        new NumberRange(2, 10), new NumberRange(-1, 8849));
586:
587:                final GridSampleDimension band = new GridSampleDimension(
588:                        "digital elevation", new Category[] { values }, uom)
589:                        .geophysics(true);
590:
591:                return coverageFactory.create(coverageName, coverage,
592:                        originalEnvelope, new GridSampleDimension[] { band },
593:                        null, null);
594:
595:            }
596:
597:            /**
598:             * This method is responsible for computing the resolutions in for the
599:             * provided grid geometry in the provided crs.
600:             * 
601:             * <P>
602:             * It is worth to note that the returned resolution array is of length of 2
603:             * and it always is lon, lat for the moment.<br>
604:             * It might be worth to remove the axes reordering code when we are
605:             * confident enough with the code to handle the north-up crs.
606:             * <p>
607:             * TODO use orthodromic distance?
608:             * 
609:             * @param envelope
610:             *            the GeneralEnvelope
611:             * @param dim
612:             * @param crs
613:             * @throws DataSourceException
614:             */
615:            protected final double[] getResolution(GeneralEnvelope envelope,
616:                    Rectangle2D dim, CoordinateReferenceSystem crs)
617:                    throws DataSourceException {
618:                double[] requestedRes = null;
619:                try {
620:                    if (dim != null && envelope != null) {
621:                        // do we need to transform the originalEnvelope?
622:                        final CoordinateReferenceSystem crs2D = CRSUtilities
623:                                .getCRS2D(envelope
624:                                        .getCoordinateReferenceSystem());
625:
626:                        if (crs != null
627:                                && !CRSUtilities.equalsIgnoreMetadata(crs,
628:                                        crs2D)) {
629:                            final MathTransform tr = operationFactory
630:                                    .createOperation(crs2D, crs)
631:                                    .getMathTransform();
632:                            if (!tr.isIdentity())
633:                                envelope = CRSUtilities.transform(tr, envelope);
634:                        }
635:                        requestedRes = new double[2];
636:                        requestedRes[0] = envelope.getLength(0)
637:                                / dim.getWidth();
638:                        requestedRes[1] = envelope.getLength(1)
639:                                / dim.getHeight();
640:                    }
641:                    return requestedRes;
642:                } catch (TransformException e) {
643:                    throw new DataSourceException(
644:                            "Unable to get the resolution", e);
645:                } catch (FactoryException e) {
646:                    throw new DataSourceException(
647:                            "Unable to get the resolution", e);
648:                }
649:            }
650:
651:            /**
652:             * Retrieves the {@link CoordinateReferenceSystem} for dataset pointed by
653:             * this {@link AbstractGridCoverage2DReader}.
654:             * 
655:             * @return the {@link CoordinateReferenceSystem} for dataset pointed by this
656:             *         {@link AbstractGridCoverage2DReader}.
657:             */
658:            public final CoordinateReferenceSystem getCrs() {
659:                return crs;
660:            }
661:
662:            /**
663:             * Retrieves the {@link GeneralGridRange} that represents the raster grid
664:             * dimensions of the highest resolution level in this dataset.
665:             * 
666:             * @return the {@link GeneralGridRange} that represents the raster grid
667:             *         dimensions of the highest resolution level in this dataset.
668:             */
669:            public final GeneralGridRange getOriginalGridRange() {
670:                return originalGridRange;
671:            }
672:
673:            /**
674:             * Retrieves the {@link GeneralEnvelope} for this
675:             * {@link AbstractGridCoverage2DReader}.
676:             * 
677:             * @return the {@link GeneralEnvelope} for this
678:             *         {@link AbstractGridCoverage2DReader}.
679:             */
680:            public final GeneralEnvelope getOriginalEnvelope() {
681:                return originalEnvelope;
682:            }
683:
684:            /**
685:             * Retrieves the source for this {@link AbstractGridCoverage2DReader}.
686:             * 
687:             * @return the source for this {@link AbstractGridCoverage2DReader}.
688:             */
689:            public final Object getSource() {
690:                return source;
691:            }
692:
693:            /**
694:             * Disposes this reader.
695:             * 
696:             * <p>
697:             * This method just tries to close the underlying {@link ImageInputStream}.
698:             */
699:            public void dispose() {
700:                if (inStream != null) {
701:                    try {
702:                        inStream.close();
703:                    } catch (IOException e) {
704:                        if (LOGGER.isLoggable(Level.FINE))
705:                            LOGGER.log(Level.FINE, e.getLocalizedMessage(), e);
706:                    }
707:                }
708:
709:            }
710:
711:            /**
712:             * @see org.opengis.coverage.grid.GridCoverageReader#skip()
713:             */
714:            public void skip() {
715:                throw new UnsupportedOperationException("Unsupported opertion.");
716:            }
717:
718:            /**
719:             * @see org.opengis.coverage.grid.GridCoverageReader#hasMoreGridCoverages()
720:             */
721:            public boolean hasMoreGridCoverages() {
722:                throw new UnsupportedOperationException("Unsupported opertion.");
723:            }
724:
725:            /**
726:             * @see org.opengis.coverage.grid.GridCoverageReader#listSubNames()
727:             */
728:            public String[] listSubNames() {
729:                throw new UnsupportedOperationException("Unsupported opertion.");
730:            }
731:
732:            /**
733:             * @see org.opengis.coverage.grid.GridCoverageReader#getCurrentSubname()
734:             */
735:            public String getCurrentSubname() {
736:                throw new UnsupportedOperationException("Unsupported opertion.");
737:            }
738:
739:            /**
740:             * @see org.opengis.coverage.grid.GridCoverageReader#getMetadataNames()
741:             */
742:            public String[] getMetadataNames() {
743:                throw new UnsupportedOperationException("Unsupported opertion.");
744:            }
745:
746:            /**
747:             * @see org.opengis.coverage.grid.GridCoverageReader#getMetadataValue(java.lang.String)
748:             */
749:            public String getMetadataValue(final String name)
750:                    throws MetadataNameNotFoundException {
751:                throw new UnsupportedOperationException("Unsupported opertion.");
752:            }
753:
754:            /**
755:             * @see org.opengis.coverage.grid.GridCoverageReader#getGridCoverageCount()
756:             */
757:            public int getGridCoverageCount() {
758:                throw new UnsupportedOperationException("Unsupported opertion.");
759:            }
760:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.