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


001:        /*
002:         *    Geotools2 - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2007, Geotools Project Managment Committee (PMC)
005:         *	  (C) 2007, GeoSolutions S.A.S.
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;
010:         *    version 2.1 of the License.
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:         */
018:        package org.geotools.gce.ecw;
019:
020:        import it.geosolutions.imageio.gdalframework.GDALCommonIIOImageMetadata;
021:        import it.geosolutions.imageio.plugins.ecw.ECWImageReaderSpi;
022:        import it.geosolutions.imageio.stream.input.FileImageInputStreamExtImpl;
023:
024:        import java.awt.Rectangle;
025:        import java.awt.geom.AffineTransform;
026:        import java.awt.image.renderable.ParameterBlock;
027:        import java.io.File;
028:        import java.io.FileInputStream;
029:        import java.io.FileNotFoundException;
030:        import java.io.IOException;
031:        import java.io.InputStream;
032:        import java.io.UnsupportedEncodingException;
033:        import java.net.URL;
034:        import java.net.URLDecoder;
035:        import java.util.NoSuchElementException;
036:        import java.util.logging.Level;
037:        import java.util.logging.Logger;
038:
039:        import javax.imageio.ImageIO;
040:        import javax.imageio.ImageReadParam;
041:        import javax.imageio.ImageReader;
042:        import javax.imageio.metadata.IIOMetadata;
043:        import javax.imageio.spi.ImageReaderSpi;
044:        import javax.imageio.stream.FileCacheImageInputStream;
045:        import javax.imageio.stream.ImageInputStream;
046:        import javax.imageio.stream.MemoryCacheImageInputStream;
047:        import javax.media.jai.JAI;
048:        import javax.media.jai.PlanarImage;
049:
050:        import org.geotools.coverage.grid.GeneralGridRange;
051:        import org.geotools.coverage.grid.GridCoverage2D;
052:        import org.geotools.coverage.grid.GridGeometry2D;
053:        import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
054:        import org.geotools.coverage.grid.io.AbstractGridFormat;
055:        import org.geotools.data.DataSourceException;
056:        import org.geotools.data.PrjFileReader;
057:        import org.geotools.data.WorldFileReader;
058:        import org.geotools.factory.Hints;
059:        import org.geotools.geometry.GeneralEnvelope;
060:        import org.geotools.parameter.Parameter;
061:        import org.geotools.referencing.CRS;
062:        import org.geotools.referencing.operation.builder.GridToEnvelopeMapper;
063:        import org.geotools.referencing.operation.transform.ProjectiveTransform;
064:        import org.opengis.coverage.grid.Format;
065:        import org.opengis.coverage.grid.GridCoverage;
066:        import org.opengis.coverage.grid.GridCoverageReader;
067:        import org.opengis.geometry.Envelope;
068:        import org.opengis.geometry.MismatchedDimensionException;
069:        import org.opengis.parameter.GeneralParameterValue;
070:        import org.opengis.referencing.FactoryException;
071:        import org.opengis.referencing.datum.PixelInCell;
072:        import org.opengis.referencing.operation.MathTransform;
073:        import org.opengis.referencing.operation.NoninvertibleTransformException;
074:        import org.opengis.referencing.operation.TransformException;
075:
076:        /**
077:         * This class can read a ECW data source and create a {@link GridCoverage2D}
078:         * from the data.
079:         * 
080:         * @author Daniele Romagnoli, GeoSolutions
081:         * @author Simone Giannecchini, GeoSolutions
082:         * @since 2.4.x
083:         */
084:        public final class ECWReader extends AbstractGridCoverage2DReader
085:                implements  GridCoverageReader {
086:            /** Logger. */
087:            private final static Logger LOGGER = org.geotools.util.logging.Logging
088:                    .getLogger("org.geotools.gce.ecw");
089:
090:            /** Caches an <code>ImageReaderSpi</code> for a <code>ECWImageReader</code> */
091:            private final static ImageReaderSpi readerSPI = new ECWImageReaderSpi();
092:
093:            /** Absolute path to the parent dir for this coverage. */
094:            private String parentPath;
095:
096:            /**
097:             * Creates a new instance of a {@link ECWReader}. I assume nothing about
098:             * file extension.
099:             * 
100:             * @param input
101:             *            Source object for which we want to build an {@link ECWReader}.
102:             * @throws DataSourceException
103:             * @throws FactoryException
104:             * @throws MismatchedDimensionException
105:             */
106:            public ECWReader(Object input) throws DataSourceException,
107:                    MismatchedDimensionException {
108:                this (input, null);
109:            }
110:
111:            /**
112:             * Creates a new instance of a {@link ECWReader}. I assume nothing about
113:             * file extension.
114:             * 
115:             * @param input
116:             *            Source object for which we want to build an {@link ECWReader}.
117:             * @param hints
118:             *            Hints to be used by this reader throughout his life.
119:             * @throws DataSourceException
120:             * @throws FactoryException
121:             * @throws MismatchedDimensionException
122:             */
123:            public ECWReader(Object input, final Hints hints)
124:                    throws DataSourceException, MismatchedDimensionException {
125:
126:                // /////////////////////////////////////////////////////////////////////
127:                //
128:                // Checking input
129:                //
130:                // /////////////////////////////////////////////////////////////////////
131:                coverageName = "ECW";
132:                try {
133:                    // //
134:                    //
135:                    // Hints
136:                    //
137:                    // //
138:                    if (hints != null)
139:                        this .hints.add(hints);
140:
141:                    // //
142:                    //
143:                    // Source management
144:                    //
145:                    // //
146:                    checkSource(input);
147:
148:                    // Getting a reader for this format
149:                    final ImageReader reader = readerSPI.createReaderInstance();
150:                    reader.setInput(inStream);
151:
152:                    // //
153:                    //
154:                    // Setting Envelope, GridRange and CRS
155:                    //
156:                    // //
157:                    setOriginalProperties(reader);
158:
159:                    // //
160:                    //
161:                    // Information about multiple levels and such
162:                    //
163:                    // //
164:                    getResolutionInfo(reader);
165:                    reader.reset();
166:
167:                    coverageName = (source instanceof  File) ? ((File) source)
168:                            .getName() : "ECW_coverage";
169:                    // release the stream if we can.
170:                    finalStreamPreparation();
171:                } catch (IOException e) {
172:                    if (LOGGER.isLoggable(Level.SEVERE))
173:                        LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
174:                    throw new DataSourceException(e);
175:                } catch (TransformException e) {
176:                    if (LOGGER.isLoggable(Level.SEVERE))
177:                        LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
178:                    throw new DataSourceException(e);
179:                }
180:
181:            }
182:
183:            /**
184:             * Setting Envelope, GridRange and CRS from the given
185:             * <code>ImageReader</code>
186:             * 
187:             * @param reader
188:             *            the <code>ImageReader</code> from which to retrieve metadata
189:             *            (if available) for setting properties
190:             * @throws IOException
191:             * @throws IllegalStateException
192:             * @throws TransformException
193:             * @throws MismatchedDimensionException
194:             */
195:            private void setOriginalProperties(ImageReader reader)
196:                    throws IOException, IllegalStateException,
197:                    TransformException, MismatchedDimensionException {
198:
199:                // /////////////////////////////////////////////////////////////////////
200:                //
201:                // Setting Envelope and CRS
202:                //
203:                // ////////////////////////////////////////////////////////////////////
204:
205:                // //
206:                //
207:                // Using Common metadata from GDAL
208:                //
209:                // //
210:                IIOMetadata metadata = reader.getImageMetadata(0);
211:                if (!(metadata instanceof  GDALCommonIIOImageMetadata))
212:                    throw new DataSourceException(
213:                            "Unexpected error! Metadata are not of the expected class.");
214:                getPropertiesFromCommonMetadata(metadata);
215:
216:                // //
217:                //
218:                // If common metadata don't have sufficient information to set CRS
219:                // envelope, try other ways, such as looking for a PRJ
220:                //
221:                // //
222:                if (crs == null)
223:                    getCoordinateReferenceSystemFromPrj();
224:
225:                if (crs == null) {
226:                    LOGGER.info("crs not found proceeding with EPSG:4326");
227:                    crs = ECWFormat.getDefaultCRS();
228:                }
229:
230:                // //
231:                //
232:                // If common metadata doesn't have sufficient information to set the
233:                // envelope, try other ways, such as looking for a WorldFile
234:                //
235:                // //
236:                if (originalEnvelope == null)
237:                    checkForWorldFile();
238:
239:                originalEnvelope.setCoordinateReferenceSystem(crs);
240:
241:            }
242:
243:            /**
244:             * Checks whether a world file is associated with the data source. If found,
245:             * set the envelope.
246:             * 
247:             * @throws IllegalStateException
248:             * @throws TransformException
249:             * @throws IOException
250:             */
251:            private void checkForWorldFile() throws IllegalStateException,
252:                    TransformException, IOException {
253:
254:                final String worldFilePath = new StringBuffer(this .parentPath)
255:                        .append(File.separatorChar).append(this .coverageName)
256:                        .toString();
257:
258:                // TODO: Check if "eww" is the right extension of ecw world files.
259:                File file2Parse = new File(worldFilePath + ".eww");
260:                boolean worldFileExists = file2Parse.exists();
261:                if (!worldFileExists) {
262:                    file2Parse = new File(worldFilePath + ".wld");
263:                    worldFileExists = file2Parse.exists();
264:                }
265:                if (worldFileExists) {
266:                    final WorldFileReader reader = new WorldFileReader(
267:                            file2Parse);
268:                    raster2Model = reader.getTransform();
269:
270:                    // //
271:                    //
272:                    // In case we read from a real world file we have together the
273:                    // envelope
274:                    //
275:                    // //
276:
277:                    final AffineTransform tempTransform = new AffineTransform(
278:                            (AffineTransform) raster2Model);
279:                    tempTransform.translate(-0.5, -0.5);
280:
281:                    originalEnvelope = CRS.transform(ProjectiveTransform
282:                            .create(tempTransform), new GeneralEnvelope(
283:                            originalGridRange.toRectangle()));
284:                }
285:            }
286:
287:            /**
288:             * Given a <code>IIOMetadata</code> metadata object, retrieves several
289:             * properties to properly set envelope, gridrange and crs.
290:             * 
291:             * @param metadata
292:             */
293:            private void getPropertiesFromCommonMetadata(IIOMetadata metadata) {
294:                // casting metadata
295:                final GDALCommonIIOImageMetadata commonMetadata = (GDALCommonIIOImageMetadata) metadata;
296:
297:                // setting CRS and Envelope directly from GDAL, if available
298:                final String wkt = commonMetadata.getProjection();
299:
300:                if (wkt != null && !(wkt.equalsIgnoreCase("")))
301:                    try {
302:                        crs = CRS.parseWKT(wkt);
303:
304:                    } catch (FactoryException fe) {
305:                        // unable to get CRS from WKT
306:                        if (LOGGER.isLoggable(Level.WARNING))
307:                            LOGGER.log(Level.WARNING, fe.getLocalizedMessage(),
308:                                    fe);
309:                        crs = null;
310:                    }
311:
312:                final int hrWidth = commonMetadata.getWidth();
313:                final int hrHeight = commonMetadata.getHeight();
314:                originalGridRange = new GeneralGridRange(new Rectangle(0, 0,
315:                        hrWidth, hrHeight));
316:
317:                // getting Grid Properties
318:                final double geoTransform[] = commonMetadata
319:                        .getGeoTransformation();
320:                if (geoTransform != null && geoTransform.length == 6) {
321:                    final AffineTransform tempTransform = new AffineTransform(
322:                            geoTransform[1], geoTransform[4], geoTransform[2],
323:                            geoTransform[5], geoTransform[0], geoTransform[3]);
324:                    // attention gdal geotransform does not uses the pixel is centre
325:                    // convention like world files.
326:                    // tempTransform.translate(-0.5, -0.5);
327:                    this .raster2Model = ProjectiveTransform
328:                            .create(tempTransform);
329:                    try {
330:
331:                        // Setting Envelope
332:                        originalEnvelope = CRS.transform(raster2Model,
333:                                new GeneralEnvelope(originalGridRange
334:                                        .toRectangle()));
335:                    } catch (IllegalStateException e) {
336:                        if (LOGGER.isLoggable(Level.WARNING))
337:                            LOGGER.log(Level.WARNING, e.getLocalizedMessage(),
338:                                    e);
339:                    } catch (TransformException e) {
340:                        if (LOGGER.isLoggable(Level.WARNING))
341:                            LOGGER.log(Level.WARNING, e.getLocalizedMessage(),
342:                                    e);
343:                    }
344:                }
345:            }
346:
347:            /**
348:             * Close the <code>InStream</code> <code>ImageInputStream</code> if we
349:             * open it up on purpose to read header info for this
350:             * {@link AbstractGridCoverage2DReader}. If the stream cannot be closed, we
351:             * just reset and mark it.
352:             * 
353:             * @throws IOException
354:             */
355:            private void finalStreamPreparation() throws IOException {
356:                if (closeMe)
357:                    inStream.close();
358:                else {
359:                    inStream.reset();
360:                    inStream.mark();
361:                }
362:            }
363:
364:            /**
365:             * Checks the input provided to this {@link ECWReader} and sets all the
366:             * other objects and flags accordingly.
367:             * 
368:             * @param input
369:             *            provided to this {@link ECWReader}.
370:             * 
371:             * @throws UnsupportedEncodingException
372:             * @throws DataSourceException
373:             * @throws IOException
374:             * @throws FileNotFoundException
375:             */
376:            private void checkSource(Object input)
377:                    throws UnsupportedEncodingException, DataSourceException,
378:                    IOException, FileNotFoundException {
379:                if (input == null) {
380:                    final DataSourceException ex = new DataSourceException(
381:                            "No source set to read this coverage.");
382:                    if (LOGGER.isLoggable(Level.SEVERE))
383:                        LOGGER.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
384:                    throw ex;
385:                }
386:                this .source = input;
387:                closeMe = true;
388:                // //
389:                //
390:                // URL to FIle
391:                //
392:                // //
393:                // if it is a URL ponting to a File I convert it to a file,
394:                // otherwis, later on, I will try to get an inputstream out of it.
395:                if (input instanceof  URL) {
396:                    // URL that point to a file
397:                    final URL sourceURL = ((URL) input);
398:                    if (sourceURL.getProtocol().compareToIgnoreCase("file") == 0) {
399:                        this .source = input = new File(URLDecoder.decode(
400:                                sourceURL.getFile(), "UTF-8"));
401:                    }
402:                }
403:
404:                // //
405:                //
406:                // File
407:                //
408:                // //
409:                if (input instanceof  File) {
410:                    final File sourceFile = (File) input;
411:                    if (!sourceFile.exists() || sourceFile.isDirectory()
412:                            || !sourceFile.canRead())
413:                        throw new DataSourceException(
414:                                "Provided file does not exist or is a directory or is not readable!");
415:                    this .parentPath = sourceFile.getParent();
416:                    this .coverageName = sourceFile.getName();
417:                    final int dotIndex = coverageName.indexOf(".");
418:                    coverageName = (dotIndex == -1) ? coverageName
419:                            : coverageName.substring(0, dotIndex);
420:                    inStream = new FileImageInputStreamExtImpl(sourceFile);
421:                } else
422:                // //
423:                //
424:                // URL
425:                //
426:                // //
427:                if (input instanceof  URL) {
428:                    final URL tempURL = ((URL) input);
429:                    inStream = ImageIO.createImageInputStream(tempURL
430:                            .openConnection().getInputStream());
431:                } else
432:                // //
433:                //
434:                // InputStream
435:                //
436:                // //
437:                if (input instanceof  InputStream) {
438:                    closeMe = false;
439:                    if (ImageIO.getUseCache())
440:                        inStream = new FileCacheImageInputStream(
441:                                (InputStream) input, null);
442:                    else
443:                        inStream = new MemoryCacheImageInputStream(
444:                                (InputStream) input);
445:                    // let's mark it
446:                    inStream.mark();
447:                } else
448:                // //
449:                //
450:                // ImageInputStream
451:                //
452:                // //
453:                if (input instanceof  ImageInputStream) {
454:                    closeMe = false;
455:                    inStream = (ImageInputStream) input;
456:                    inStream.mark();
457:                } else
458:                    throw new IllegalArgumentException("Unsupported input type");
459:
460:                if (inStream == null)
461:                    throw new DataSourceException(
462:                            "No input stream for the provided source");
463:            }
464:
465:            /**
466:             * Gets resolution information about the coverage itself.
467:             * 
468:             * @param reader
469:             *            an {@link ImageReader} to use for getting the resolution
470:             *            information.
471:             * @throws IOException
472:             * @throws TransformException
473:             */
474:            private void getResolutionInfo(ImageReader reader)
475:                    throws IOException, TransformException {
476:
477:                // //
478:                //
479:                // get the dimension of the hr image and build the model as well as
480:                // computing the resolution
481:                //
482:                // //
483:                final Rectangle actualDim = new Rectangle(0, 0, reader
484:                        .getWidth(0), reader.getHeight(0));
485:                originalGridRange = new GeneralGridRange(actualDim);
486:
487:                // ///
488:                //
489:                // setting the higher resolution avalaible for this coverage
490:                //
491:                // ///
492:                highestRes = getResolution(originalEnvelope, actualDim, crs);
493:
494:                // ///
495:                //
496:                // Setting raster to model transformation
497:                //
498:                // ///
499:                final GridToEnvelopeMapper geMapper = new GridToEnvelopeMapper();
500:                geMapper.setEnvelope(originalEnvelope);
501:                geMapper.setGridRange(originalGridRange);
502:                geMapper.setGridType(PixelInCell.CELL_CENTER);
503:                this .raster2Model = geMapper.createTransform();
504:
505:            }
506:
507:            /**
508:             * @see org.opengis.coverage.grid.GridCoverageReader#getFormat()
509:             */
510:            public Format getFormat() {
511:                return new ECWFormat();
512:            }
513:
514:            /**
515:             * Reads a {@link GridCoverage2D} possibly matching as close as possible the
516:             * resolution computed by using the input params provided by using the
517:             * parameters for this {@link #read(GeneralParameterValue[])}.
518:             * 
519:             * <p>
520:             * To have an idea about the possible read parameters take a look at
521:             * {@link AbstractGridFormat} class and {@link ECWFormat} class.
522:             * 
523:             * @param params
524:             *            an array of {@link GeneralParameterValue} containing the
525:             *            parameters to control this read process.
526:             * 
527:             * @return a {@link GridCoverage2D}.
528:             * 
529:             * @see AbstractGridFormat
530:             * @see ECWFormat
531:             * @see org.opengis.coverage.grid.GridCoverageReader#read(org.opengis.parameter.GeneralParameterValue[])
532:             */
533:            public GridCoverage read(GeneralParameterValue[] params)
534:                    throws IllegalArgumentException, IOException {
535:                GeneralEnvelope readEnvelope = null;
536:                Rectangle requestedDim = null;
537:                if (params != null) {
538:
539:                    final int length = params.length;
540:                    for (int i = 0; i < length; i++) {
541:                        Parameter param = (Parameter) params[i];
542:                        String name = param.getDescriptor().getName().getCode();
543:                        if (name.equals(AbstractGridFormat.READ_GRIDGEOMETRY2D
544:                                .getName().toString())) {
545:                            final GridGeometry2D gg = (GridGeometry2D) param
546:                                    .getValue();
547:                            if (gg == null)
548:                                continue;
549:                            readEnvelope = new GeneralEnvelope((Envelope) gg
550:                                    .getEnvelope2D());
551:                            requestedDim = gg.getGridRange2D().getBounds();
552:                        }
553:
554:                    }
555:                }
556:                return createCoverage(readEnvelope, requestedDim);
557:            }
558:
559:            /**
560:             * This method creates the GridCoverage2D from the underlying file.
561:             * 
562:             * @param requestedDim
563:             * @param readEnvelope
564:             * 
565:             * 
566:             * @return a GridCoverage
567:             * 
568:             * @throws java.io.IOException
569:             */
570:            private GridCoverage createCoverage(
571:                    GeneralEnvelope requestedEnvelope, Rectangle requestedDim)
572:                    throws IOException {
573:
574:                if (!closeMe) {
575:                    inStream.reset();
576:                    inStream.mark();
577:                }
578:                // /////////////////////////////////////////////////////////////////////
579:                //
580:                // Doing an image read for reading the coverage.
581:                //
582:                // /////////////////////////////////////////////////////////////////////
583:
584:                // //
585:                //
586:                // Setting subsampling factors with some checkings
587:                // 1) the subsampling factors cannot be zero
588:                // 2) the subsampling factors cannot be such that the w 7or h are zero
589:                //
590:                // //
591:                final ImageReadParam readP = new ImageReadParam();
592:                final Integer imageChoice;
593:                try {
594:                    imageChoice = setReadParams(readP, requestedEnvelope,
595:                            requestedDim);
596:                } catch (IOException e) {
597:                    if (LOGGER.isLoggable(Level.SEVERE))
598:                        LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
599:                    return null;
600:                } catch (TransformException e) {
601:                    if (LOGGER.isLoggable(Level.SEVERE))
602:                        LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
603:                    return null;
604:                }
605:
606:                // /////////////////////////////////////////////////////////////////////
607:                //
608:                // Check if we have something to load by intersecting the requested
609:                // envelope with the bounds of the data set.
610:                //
611:                // If the requested envelope is not in the same crs of the data set crs
612:                // we have to perform a conversion towards the latter crs before
613:                // intersecting anything.
614:                //
615:                // /////////////////////////////////////////////////////////////////////
616:                GeneralEnvelope intersectionEnvelope = null;
617:                Rectangle sourceRegion = null;
618:                if (requestedEnvelope != null) {
619:                    if (!CRS.equalsIgnoreMetadata(requestedEnvelope
620:                            .getCoordinateReferenceSystem(), this .crs)) {
621:                        try {
622:                            // //
623:                            //
624:                            // transforming the envelope back to the dataset crs in
625:                            // order to interact with the original envelope
626:                            //
627:                            // //
628:                            final MathTransform transform = operationFactory
629:                                    .createOperation(
630:                                            requestedEnvelope
631:                                                    .getCoordinateReferenceSystem(),
632:                                            crs).getMathTransform();
633:                            if (!transform.isIdentity()) {
634:                                requestedEnvelope = CRS.transform(transform,
635:                                        requestedEnvelope);
636:                                requestedEnvelope
637:                                        .setCoordinateReferenceSystem(this .crs);
638:
639:                                if (LOGGER.isLoggable(Level.FINE))
640:                                    LOGGER.fine(new StringBuffer(
641:                                            "Reprojected envelope ").append(
642:                                            requestedEnvelope.toString())
643:                                            .append(" crs ")
644:                                            .append(crs.toWKT()).toString());
645:                            }
646:                        } catch (TransformException e) {
647:                            throw new DataSourceException(
648:                                    "Unable to create a coverage for this source",
649:                                    e);
650:                        } catch (FactoryException e) {
651:                            throw new DataSourceException(
652:                                    "Unable to create a coverage for this source",
653:                                    e);
654:                        }
655:                    }
656:                    if (!requestedEnvelope.intersects(this .originalEnvelope,
657:                            true)) {
658:                        if (LOGGER.isLoggable(Level.FINE))
659:                            LOGGER
660:                                    .warning("The requested envelope does not intersect the envelope of this coverage, we will return a null coverage.");
661:                        return null;
662:                    }
663:                    intersectionEnvelope = new GeneralEnvelope(
664:                            requestedEnvelope);
665:                    // intersect the requested area with the bounds of this layer
666:                    intersectionEnvelope.intersect(originalEnvelope);
667:                    intersectionEnvelope.setCoordinateReferenceSystem(this .crs);
668:
669:                    // ///
670:                    //
671:                    // Crop the sourced region
672:                    //
673:                    // ///
674:                    try {
675:                        final GeneralGridRange finalRange = new GeneralGridRange(
676:                                CRS.transform(this .raster2Model.inverse(),
677:                                        intersectionEnvelope));
678:                        // CROP
679:                        sourceRegion = finalRange.toRectangle();
680:                        if (!sourceRegion.intersects(this .originalGridRange
681:                                .toRectangle()))
682:                            sourceRegion = null;
683:                        else
684:                            sourceRegion = sourceRegion
685:                                    .intersection(this .originalGridRange
686:                                            .toRectangle());
687:
688:                    } catch (NoninvertibleTransformException e) {
689:                        if (LOGGER.isLoggable(Level.WARNING))
690:                            LOGGER.log(Level.WARNING, e.getLocalizedMessage(),
691:                                    e);
692:                        sourceRegion = null;
693:                    } catch (TransformException e) {
694:                        if (LOGGER.isLoggable(Level.WARNING))
695:                            LOGGER.log(Level.WARNING, e.getLocalizedMessage(),
696:                                    e);
697:                        sourceRegion = null;
698:                    }
699:                }
700:
701:                Object input;
702:                if (source instanceof  File)
703:                    input = new FileImageInputStreamExtImpl((File) source);
704:                else if (source instanceof  ImageInputStream
705:                        || source instanceof  InputStream)
706:                    input = inStream;
707:                else if (source instanceof  URL) {
708:                    input = ImageIO.createImageInputStream(((URL) source)
709:                            .openConnection().getInputStream());
710:                } else
711:                    throw new IllegalArgumentException();
712:
713:                final PlanarImage ecwCoverage;
714:                if (sourceRegion != null)
715:                    readP.setSourceRegion(sourceRegion);
716:
717:                // //
718:                //
719:                // image and metadata
720:                //
721:                // //
722:                final ParameterBlock pbjImageRead = new ParameterBlock();
723:                pbjImageRead.add(input);
724:                pbjImageRead.add(imageChoice);
725:                pbjImageRead.add(Boolean.FALSE);
726:                pbjImageRead.add(Boolean.FALSE);
727:                pbjImageRead.add(Boolean.FALSE);
728:                pbjImageRead.add(null);
729:                pbjImageRead.add(null);
730:                pbjImageRead.add(readP);
731:                pbjImageRead.add(readerSPI.createReaderInstance());
732:                ecwCoverage = JAI.create("ImageRead", pbjImageRead, hints);
733:
734:                // /////////////////////////////////////////////////////////////////////
735:                //
736:                // Creating the coverage
737:                //
738:                // /////////////////////////////////////////////////////////////////////
739:                try {
740:
741:                    if (intersectionEnvelope != null) {
742:                        // I need to calculate a new transformation (raster2Model)
743:                        // between the cropped image and the required
744:                        // intersectionEnvelope
745:                        final GridToEnvelopeMapper gem = new GridToEnvelopeMapper();
746:                        gem.setEnvelope(intersectionEnvelope);
747:                        final int ssWidth = ecwCoverage.getWidth();
748:                        final int ssHeight = ecwCoverage.getHeight();
749:                        gem.setGridRange(new GeneralGridRange(new Rectangle(0,
750:                                0, ssWidth, ssHeight)));
751:                        gem.setGridType(PixelInCell.CELL_CENTER);
752:                        return super .createImageCoverage(ecwCoverage, gem
753:                                .createTransform());
754:                    } else {
755:                        // In case of not intersectionEnvelope (As an instance, when
756:                        // reading the whole image), I can use the originalEnvelope. So,
757:                        // no need to specify a raster2model parameter
758:                        return super .createImageCoverage(ecwCoverage);
759:                    }
760:                } catch (NoSuchElementException e) {
761:                    if (LOGGER.isLoggable(Level.SEVERE))
762:                        LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
763:                    throw new DataSourceException(e);
764:                }
765:            }
766:
767:            /**
768:             * Gets the coordinate system that will be associated to the
769:             * {@link GridCoverage}. The WGS84 coordinate system is used by default. It
770:             * is worth to point out that when reading from a stream which is not
771:             * connected to a file, like from an http connection (e.g. from a WCS) we
772:             * cannot rely on receiving a prj file too. In this case the exchange of
773:             * information about referencing should proceed the exchange of data thus I
774:             * rely on this and I ask the user who's invoking the read operation to
775:             * provide me a valid crs and envelope through read parameters.
776:             * 
777:             * @throws FactoryException
778:             * @throws IOException
779:             * @throws FileNotFoundException
780:             */
781:            private void getCoordinateReferenceSystemFromPrj()
782:                    throws FileNotFoundException, IOException {
783:
784:                String prjPath = null;
785:                if (source instanceof  File) {
786:                    crs = null;
787:                    prjPath = new StringBuffer(this .parentPath).append(
788:                            File.separatorChar).append(this .coverageName)
789:                            .append(".prj").toString();
790:                    // read the prj info from the file
791:                    PrjFileReader projReader = null;
792:                    try {
793:                        final File prj = new File(prjPath);
794:                        if (prj.exists()) {
795:                            projReader = new PrjFileReader(new FileInputStream(
796:                                    prj).getChannel());
797:                            crs = projReader.getCoordinateReferenceSystem();
798:                        }
799:                    } catch (FileNotFoundException e) {
800:                        // warn about the error but proceed, it is not fatal
801:                        // we have at least the default crs to use
802:                        LOGGER.log(Level.INFO, e.getLocalizedMessage(), e);
803:                    } catch (IOException e) {
804:                        // warn about the error but proceed, it is not fatal
805:                        // we have at least the default crs to use
806:                        LOGGER.log(Level.INFO, e.getLocalizedMessage(), e);
807:                    } catch (FactoryException e) {
808:                        // warn about the error but proceed, it is not fatal
809:                        // we have at least the default crs to use
810:                        LOGGER.log(Level.INFO, e.getLocalizedMessage(), e);
811:                    } finally {
812:                        if (projReader != null)
813:                            try {
814:                                projReader.close();
815:                            } catch (IOException e) {
816:                                // warn about the error but proceed, it is not fatal
817:                                // we have at least the default crs to use
818:                                LOGGER.log(Level.INFO, e.getLocalizedMessage(),
819:                                        e);
820:                            }
821:                    }
822:                }
823:            }
824:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.