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