001: /*
002: * Geotools2 - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002, 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: */
017: package org.geotools.gce.arcgrid;
018:
019: import it.geosolutions.imageio.plugins.arcgrid.AsciiGridsImageMetadata;
020: import it.geosolutions.imageio.plugins.arcgrid.spi.AsciiGridsImageReaderSpi;
021:
022: import java.awt.Color;
023: import java.awt.Rectangle;
024: import java.awt.image.renderable.ParameterBlock;
025: import java.io.File;
026: import java.io.FileInputStream;
027: import java.io.FileNotFoundException;
028: import java.io.IOException;
029: import java.io.InputStream;
030: import java.io.UnsupportedEncodingException;
031: import java.net.URL;
032: import java.net.URLDecoder;
033: import java.nio.channels.FileChannel;
034: import java.util.HashMap;
035: import java.util.Map;
036: import java.util.NoSuchElementException;
037: import java.util.logging.Level;
038: import java.util.logging.Logger;
039: import java.util.zip.GZIPInputStream;
040:
041: import javax.imageio.ImageIO;
042: import javax.imageio.ImageReadParam;
043: import javax.imageio.ImageReader;
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.RenderedOp;
050: import javax.units.Unit;
051:
052: import org.geotools.coverage.Category;
053: import org.geotools.coverage.GridSampleDimension;
054: import org.geotools.coverage.grid.GeneralGridRange;
055: import org.geotools.coverage.grid.GridCoverage2D;
056: import org.geotools.coverage.grid.GridGeometry2D;
057: import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
058: import org.geotools.coverage.grid.io.AbstractGridFormat;
059: import org.geotools.data.DataSourceException;
060: import org.geotools.data.PrjFileReader;
061: import org.geotools.factory.Hints;
062: import org.geotools.geometry.GeneralEnvelope;
063: import org.geotools.resources.i18n.Vocabulary;
064: import org.geotools.resources.i18n.VocabularyKeys;
065: import org.geotools.util.NumberRange;
066: import org.opengis.coverage.grid.Format;
067: import org.opengis.coverage.grid.GridCoverage;
068: import org.opengis.coverage.grid.GridCoverageReader;
069: import org.opengis.geometry.Envelope;
070: import org.opengis.geometry.MismatchedDimensionException;
071: import org.opengis.parameter.GeneralParameterValue;
072: import org.opengis.parameter.ParameterValue;
073: import org.opengis.referencing.FactoryException;
074: import org.opengis.referencing.crs.CoordinateReferenceSystem;
075: import org.opengis.referencing.operation.TransformException;
076: import org.w3c.dom.NamedNodeMap;
077: import org.w3c.dom.Node;
078:
079: import com.vividsolutions.jts.io.InStream;
080:
081: /**
082: * This class can read an arc grid data source (ArcGrid or GRASS ASCII) and
083: * create a {@link GridCoverage2D} from the data.
084: *
085: * @author Daniele Romagnoli, GeoSolutions
086: * @author Simone Giannecchini, GeoSolutions
087: * @since 2.3.x
088: */
089: public final class ArcGridReader extends AbstractGridCoverage2DReader
090: implements GridCoverageReader {
091: /** Logger. */
092: private final static Logger LOGGER = org.geotools.util.logging.Logging
093: .getLogger("org.geotools.gce.arcgrid");
094:
095: /** Caches and ImageReaderSpi for an AsciiGridsImageReader. */
096: private final static ImageReaderSpi readerSPI = new AsciiGridsImageReaderSpi();
097:
098: /** Absolute path to the parent dir for this coverage. */
099: private String parentPath;
100:
101: /** No data value for this dataset. */
102: private double inNoData = Double.NaN;
103:
104: /**
105: * Creates a new instance of an ArcGridReader basing the decision on whether
106: * the file is compressed or not. I assume nothing about file extension.
107: *
108: * @param input
109: * Source object for which we want to build an ArcGridReader.
110: * @throws DataSourceException
111: */
112: public ArcGridReader(Object input) throws DataSourceException {
113: this (input, null);
114:
115: }
116:
117: /**
118: * Creates a new instance of an ArcGridReader basing the decision on whether
119: * the file is compressed or not. I assume nothing about file extension.
120: *
121: * @param input
122: * Source object for which we want to build an ArcGridReader.
123: * @param hints
124: * Hints to be used by this reader throughout his life.
125: * @throws DataSourceException
126: */
127: public ArcGridReader(Object input, final Hints hints)
128: throws DataSourceException {
129:
130: // /////////////////////////////////////////////////////////////////////
131: //
132: // Checking input
133: //
134: // /////////////////////////////////////////////////////////////////////
135: coverageName = "AsciiGrid";
136: try {
137:
138: // /////////////////////////////////////////////////////////////////////
139: //
140: // Source management
141: //
142: // /////////////////////////////////////////////////////////////////////
143: checkSource(input, hints);
144:
145: // /////////////////////////////////////////////////////////////////////
146: //
147: // CRS
148: //
149: // /////////////////////////////////////////////////////////////////////
150: final Object tempCRS = this .hints
151: .get(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM);
152: if (tempCRS != null) {
153: this .crs = (CoordinateReferenceSystem) tempCRS;
154: LOGGER.log(Level.WARNING, new StringBuffer(
155: "Using forced coordinate reference system ")
156: .append(crs.toWKT()).toString());
157: } else
158: getCoordinateReferenceSystem();
159:
160: // /////////////////////////////////////////////////////////////////////
161: //
162: // Reader and metadata
163: //
164: // /////////////////////////////////////////////////////////////////////
165: // //
166: //
167: // Getting a reader for this format
168: //
169: // //
170: final ImageReader reader = readerSPI.createReaderInstance();
171: reader.setInput(inStream);
172:
173: // //
174: //
175: // Getting metadata
176: //
177: // //
178: final Object metadata = reader.getImageMetadata(0);
179: if (!(metadata instanceof AsciiGridsImageMetadata))
180: throw new DataSourceException(
181: "Unexpected error! Metadata are not of the expected class.");
182: // casting the metadata
183: final AsciiGridsImageMetadata gridMetadata = (AsciiGridsImageMetadata) metadata;
184:
185: // /////////////////////////////////////////////////////////////////////
186: //
187: // Envelope and other metadata
188: //
189: // /////////////////////////////////////////////////////////////////////
190: parseMetadata(gridMetadata);
191:
192: // /////////////////////////////////////////////////////////////////////
193: //
194: // Informations about multiple levels and such
195: //
196: // /////////////////////////////////////////////////////////////////////
197: getResolutionInfo(reader);
198:
199: // release the stream if we can.
200: finalStreamPreparation();
201: } catch (IOException e) {
202: if (LOGGER.isLoggable(Level.SEVERE))
203: LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
204: throw new DataSourceException(e);
205: } catch (TransformException e) {
206: if (LOGGER.isLoggable(Level.SEVERE))
207: LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
208: throw new DataSourceException(e);
209: }
210:
211: }
212:
213: /**
214: * Close the {@link InStream} {@link ImageInputStream} if we open it up on
215: * purpose toread header info for this {@link AbstractGridCoverage2DReader}.
216: * If the stream cannot be closed, we just reset and mark it.
217: *
218: * @throws IOException
219: */
220: private void finalStreamPreparation() throws IOException {
221: if (closeMe)
222: inStream.close();
223: else {
224: inStream.reset();
225: inStream.mark();
226: }
227: }
228:
229: /**
230: * Checks the input provided to this {@link ArcGridReader} and sets all the
231: * other objects and flags accordingly.
232: *
233: * @param input
234: * provided to this {@link ArcGridReader}.
235: * @param hints
236: * Hints to be used by this reader throughout his life.
237: *
238: * @throws UnsupportedEncodingException
239: * @throws DataSourceException
240: * @throws IOException
241: * @throws FileNotFoundException
242: */
243: private void checkSource(Object input, final Hints hints)
244: throws UnsupportedEncodingException, DataSourceException,
245: IOException, FileNotFoundException {
246:
247: // //
248: //
249: // managing hints
250: //
251: // //
252: if (this .hints == null)
253: this .hints = new Hints(hints);
254: if (hints != null) {
255: this .hints.add(hints);
256: }
257:
258: if (input == null) {
259: final DataSourceException ex = new DataSourceException(
260: "No source set to read this coverage.");
261: if (LOGGER.isLoggable(Level.SEVERE))
262: LOGGER.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
263: throw ex;
264: }
265: this .source = input;
266: if (hints != null)
267: this .hints.add(hints);
268: closeMe = true;
269: // //
270: //
271: // URL to FIle
272: //
273: // //
274: // if it is a URL ponting to a File I convert it to a file,
275: // otherwis, later on, I will try to get an inputstream out of it.
276: if (input instanceof URL) {
277: // URL that point to a file
278: final URL sourceURL = ((URL) input);
279: if (sourceURL.getProtocol().compareToIgnoreCase("file") == 0) {
280: this .source = input = new File(URLDecoder.decode(
281: sourceURL.getFile(), "UTF-8"));
282:
283: }
284: }
285:
286: // //
287: //
288: // File
289: //
290: // //
291: if (input instanceof File) {
292: final File sourceFile = (File) input;
293: if (!sourceFile.exists() || sourceFile.isDirectory()
294: || !sourceFile.canRead())
295: throw new DataSourceException(
296: "Provided file does not exist or is a directory or is not readable!");
297: this .parentPath = sourceFile.getParent();
298: this .coverageName = sourceFile.getName();
299: final int dotIndex = coverageName.indexOf(".");
300: gzipped = coverageName.toLowerCase().endsWith("gz");
301: coverageName = (dotIndex == -1) ? coverageName
302: : coverageName.substring(0, dotIndex);
303: inStream = gzipped ? ImageIO
304: .createImageInputStream(new GZIPInputStream(
305: new FileInputStream(sourceFile))) : ImageIO
306: .createImageInputStream(sourceFile);
307: } else
308: // //
309: //
310: // URL
311: //
312: // //
313: if (input instanceof URL) {
314: final URL tempURL = ((URL) input);
315: input = tempURL.openConnection().getInputStream();
316: GZIPInputStream gzInStream = null;
317: try {
318: gzInStream = new GZIPInputStream((InputStream) input);
319: gzipped = false;
320: } catch (Exception e) {
321: gzipped = false;
322: }
323: input = tempURL.openConnection().getInputStream();
324: inStream = gzipped ? ImageIO
325: .createImageInputStream(gzInStream) : ImageIO
326: .createImageInputStream(tempURL.openConnection()
327: .getInputStream());
328: } else
329: // //
330: //
331: // InputStream
332: //
333: // //
334: if (input instanceof InputStream) {
335: closeMe = false;
336: if (ImageIO.getUseCache())
337: inStream = new FileCacheImageInputStream(
338: (InputStream) input, null);
339: else
340: inStream = new MemoryCacheImageInputStream(
341: (InputStream) input);
342: // let's mark it
343: inStream.mark();
344: } else
345: // //
346: //
347: // ImageInputStream
348: //
349: // //
350: if (input instanceof ImageInputStream) {
351: closeMe = false;
352: inStream = (ImageInputStream) input;
353: inStream.mark();
354: } else
355: throw new IllegalArgumentException("Unsupported input type");
356:
357: if (inStream == null)
358: throw new DataSourceException(
359: "No input stream for the provided source");
360: }
361:
362: /**
363: * Gets resolution information about the coverage itself.
364: *
365: * @param reader
366: * an {@link ImageReader} to use for getting the resolution
367: * information.
368: * @throws IOException
369: * @throws TransformException
370: */
371: private void getResolutionInfo(ImageReader reader)
372: throws IOException, TransformException {
373:
374: // //
375: //
376: // get the dimension of the hr image and build the model as well as
377: // computing the resolution
378: // //
379: final Rectangle actualDim = new Rectangle(0, 0, reader
380: .getWidth(0), reader.getHeight(0));
381: originalGridRange = new GeneralGridRange(actualDim);
382:
383: // ///
384: //
385: // setting the higher resolution avalaible for this coverage
386: //
387: // ///
388: highestRes = getResolution(originalEnvelope, actualDim, crs);
389:
390: }
391:
392: /**
393: * @see org.opengis.coverage.grid.GridCoverageReader#getFormat()
394: */
395: public Format getFormat() {
396: return new ArcGridFormat();
397: }
398:
399: /**
400: * Reads a {@link GridCoverage2D} possibly matching as close as possible the
401: * resolution computed by using the input params provided by using the
402: * parameters for this {@link #read(GeneralParameterValue[])}.
403: *
404: * <p>
405: * To have an idea about the possible read parameters take a look at
406: * {@link AbstractGridFormat} class and {@link ArcGridFormat} class.
407: *
408: * @param params
409: * an array of {@link GeneralParameterValue} containing the
410: * parameters to control this read process.
411: *
412: * @return a {@link GridCoverage2D}.
413: *
414: * @see AbstractGridFormat
415: * @see ArcGridFormat
416: * @see org.opengis.coverage.grid.GridCoverageReader#read(org.opengis.parameter.GeneralParameterValue[])
417: */
418: public GridCoverage read(GeneralParameterValue[] params)
419: throws IllegalArgumentException, IOException {
420: GeneralEnvelope readEnvelope = null;
421: Rectangle requestedDim = null;
422: String overviewPolicy = null;
423: if (params != null) {
424: final int length = params.length;
425: for (int i = 0; i < length; i++) {
426: final ParameterValue param = (ParameterValue) params[i];
427: final String name = param.getDescriptor().getName()
428: .getCode();
429: if (name.equals(AbstractGridFormat.READ_GRIDGEOMETRY2D
430: .getName().toString())) {
431: final GridGeometry2D gg = (GridGeometry2D) param
432: .getValue();
433: readEnvelope = new GeneralEnvelope((Envelope) gg
434: .getEnvelope2D());
435: requestedDim = gg.getGridRange2D().getBounds();
436: continue;
437: }
438: }
439: }
440: return createCoverage(readEnvelope, requestedDim,
441: overviewPolicy);
442: }
443:
444: /**
445: * This method creates the GridCoverage2D from the underlying file.
446: *
447: * @param requestedDim
448: * @param readEnvelope
449: *
450: *
451: * @return a GridCoverage
452: *
453: * @throws java.io.IOException
454: */
455: private GridCoverage createCoverage(
456: GeneralEnvelope requestedEnvelope, Rectangle requestedDim,
457: String overviewPolicy) throws IOException {
458:
459: if (!closeMe) {
460:
461: inStream.reset();
462: inStream.mark();
463: }
464: // /////////////////////////////////////////////////////////////////////
465: //
466: // Doing an image read for reading the coverage.
467: //
468: // /////////////////////////////////////////////////////////////////////
469:
470: // //
471: //
472: // Setting subsampling factors with some checkings
473: // 1) the subsampling factors cannot be zero
474: // 2) the subsampling factors cannot be such that the w or h are zero
475: //
476: // //
477: final ImageReadParam readP = new ImageReadParam();
478: final Integer imageChoice;
479: try {
480: imageChoice = setReadParams(readP, requestedEnvelope,
481: requestedDim);
482: } catch (IOException e) {
483: if (LOGGER.isLoggable(Level.SEVERE))
484: LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
485: return null;
486: } catch (TransformException e) {
487: if (LOGGER.isLoggable(Level.SEVERE))
488: LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
489: return null;
490: }
491:
492: // //
493: //
494: // image and metadata
495: //
496: // //
497: final ParameterBlock pbjImageRead = new ParameterBlock();
498: // prepare input to handle possible parallelism between different
499: // readers
500: if (source instanceof File) {
501: if (!gzipped)
502: pbjImageRead
503: .add(ImageIO.createImageInputStream(source));
504: else
505: pbjImageRead.add(ImageIO
506: .createImageInputStream(new GZIPInputStream(
507: new FileInputStream((File) source))));
508: } else if (source instanceof ImageInputStream
509: || source instanceof InputStream)
510: pbjImageRead.add(inStream);
511: else if (source instanceof URL) {
512: if (gzipped)
513: ImageIO.createImageInputStream(new GZIPInputStream(
514: ((URL) source).openConnection()
515: .getInputStream()));
516: else
517: pbjImageRead.add(ImageIO
518: .createImageInputStream(((URL) source)
519: .openConnection().getInputStream()));
520:
521: }
522: pbjImageRead.add(imageChoice);
523: pbjImageRead.add(Boolean.FALSE);
524: pbjImageRead.add(Boolean.FALSE);
525: pbjImageRead.add(Boolean.FALSE);
526: pbjImageRead.add(null);
527: pbjImageRead.add(null);
528: pbjImageRead.add(readP);
529: pbjImageRead.add(readerSPI.createReaderInstance());
530: final RenderedOp asciiCoverage = JAI.create("ImageRead",
531: pbjImageRead, hints);
532:
533: // /////////////////////////////////////////////////////////////////////
534: //
535: // Creating the coverage
536: //
537: // /////////////////////////////////////////////////////////////////////
538: try {
539:
540: //
541: // ///////////////////////////////////////////////////////////////////
542: //
543: // Categories
544: //
545: //
546: // ///////////////////////////////////////////////////////////////////
547: Unit uom = null;
548: final Category nan;
549: final Category values;
550: if (Double.isNaN(inNoData)) {
551: nan = new Category(Vocabulary
552: .formatInternational(VocabularyKeys.NODATA),
553: new Color(0, 0, 0, 0), 0);
554: values = new Category("values", demColors,
555: new NumberRange(1, 255), new NumberRange(0,
556: 9000));
557:
558: } else {
559: nan = new Category(Vocabulary
560: .formatInternational(VocabularyKeys.NODATA),
561: new Color[] { new Color(0, 0, 0, 0) },
562: new NumberRange(0, 0), new NumberRange(
563: inNoData, inNoData));
564: values = new Category("values", demColors,
565: new NumberRange(1, 255), new NumberRange(
566: inNoData + Math.abs(inNoData) * 0.1,
567: inNoData + Math.abs(inNoData) * 10));
568:
569: }
570:
571: //
572: // ///////////////////////////////////////////////////////////////////
573: //
574: // Sample dimension
575: //
576: //
577: // ///////////////////////////////////////////////////////////////////
578: final GridSampleDimension band = new GridSampleDimension(
579: coverageName, new Category[] { nan, values }, uom)
580: .geophysics(true);
581: final Map properties = new HashMap();
582: properties.put("GC_NODATA", new Double(inNoData));
583:
584: // /////////////////////////////////////////////////////////////////////
585: //
586: // Coverage
587: //
588: // /////////////////////////////////////////////////////////////////////
589: return coverageFactory.create(coverageName, asciiCoverage,
590: originalEnvelope,
591: new GridSampleDimension[] { band }, null,
592: properties);
593:
594: } catch (NoSuchElementException e) {
595: if (LOGGER.isLoggable(Level.SEVERE))
596: LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
597: throw new DataSourceException(e);
598: }
599: }
600:
601: /**
602: * This method is responsible for building up an envelope according to the
603: * definition of the crs. It assumes that X coordinate on the ascii grid
604: * itself maps to longitude and y coordinate maps to latitude.
605: *
606: * @param gridMetadata
607: * The {@link AsciiGridsImageMetadata} to parse.
608: *
609: * @throws MismatchedDimensionException
610: */
611: private void parseMetadata(AsciiGridsImageMetadata gridMetadata)
612: throws MismatchedDimensionException {
613:
614: // getting metadata
615: final Node root = gridMetadata
616: .getAsTree("it.geosolutions.imageio.plugins.arcgrid.AsciiGridsImageMetadata_1.0");
617:
618: // getting Grid Properties
619: Node child = root.getFirstChild();
620: NamedNodeMap attributes = child.getAttributes();
621: final boolean grass = attributes.getNamedItem("GRASS")
622: .getNodeValue().equalsIgnoreCase("True");
623:
624: // getting Grid Properties
625: child = child.getNextSibling();
626: attributes = child.getAttributes();
627: final int hrWidth = Integer.parseInt(attributes.getNamedItem(
628: "nColumns").getNodeValue());
629: final int hrHeight = Integer.parseInt(attributes.getNamedItem(
630: "nRows").getNodeValue());
631: originalGridRange = new GeneralGridRange(new Rectangle(0, 0,
632: hrWidth, hrHeight));
633: final boolean pixelIsArea = attributes.getNamedItem(
634: "rasterSpaceType").getNodeValue().equalsIgnoreCase(
635: AsciiGridsImageMetadata.rasterSpaceTypes[1]);
636: if (!grass)
637: inNoData = Double.parseDouble(attributes.getNamedItem(
638: "noDataValue").getNodeValue());
639:
640: // getting Envelope Properties
641: child = child.getNextSibling();
642: attributes = child.getAttributes();
643: final double cellsizeX = Double.parseDouble(attributes
644: .getNamedItem("cellsizeX").getNodeValue());
645: final double cellsizeY = Double.parseDouble(attributes
646: .getNamedItem("cellsizeY").getNodeValue());
647: double xll = Double.parseDouble(attributes.getNamedItem("xll")
648: .getNodeValue());
649: double yll = Double.parseDouble(attributes.getNamedItem("yll")
650: .getNodeValue());
651:
652: // /////////////////////////////////////////////////////////////////////
653: //
654: // OGC specifications says that PixelIsArea map a pixel to the corner
655: // of the grid while PixelIsPoint map a pixel to the centre of the grid.
656: //
657: // /////////////////////////////////////////////////////////////////////
658: if (!pixelIsArea) {
659: final double correctionX = cellsizeX / 2d;
660: final double correctionY = cellsizeY / 2d;
661: xll -= correctionX;
662: yll -= correctionY;
663: }
664:
665: originalEnvelope = new GeneralEnvelope(
666: new double[] { xll, yll }, new double[] {
667: xll + (hrWidth * cellsizeX),
668: yll + (hrHeight * cellsizeY) });
669:
670: // setting the coordinate reference system for the envelope
671: originalEnvelope.setCoordinateReferenceSystem(crs);
672:
673: }
674:
675: /**
676: * Gets the coordinate system that will be associated to the
677: * {@link GridCoverage}. The WGS84 coordinate system is used by default. It
678: * is worth to point out that when reading from a stream which is not
679: * connected to a file, like from an http connection (e.g. from a WCS) we
680: * cannot rely on receiving a prj file too. In this case the exchange of
681: * information about referencing should proceed the exchange of data thus I
682: * rely on this and I ask the user who's invoking the read operation to
683: * provide me a valid crs and envelope through read parameters.
684: *
685: * @throws FactoryException
686: * @throws IOException
687: * @throws FileNotFoundException
688: */
689: private void getCoordinateReferenceSystem()
690: throws FileNotFoundException, IOException {
691:
692: // check to see if there is a projection file
693: if (source instanceof File
694: || (source instanceof URL && (((URL) source)
695: .getProtocol() == "file"))) {
696: // getting name for the prj file
697: final String sourceAsString;
698:
699: if (source instanceof File) {
700: sourceAsString = ((File) source).getAbsolutePath();
701: } else {
702: sourceAsString = ((URL) source).getFile();
703: }
704:
705: final int index = sourceAsString.lastIndexOf(".");
706: final StringBuffer base = new StringBuffer(sourceAsString
707: .substring(0, index)).append(".prj");
708:
709: // does it exist?
710: final File prjFile = new File(base.toString());
711: if (prjFile.exists()) {
712: // it exists then we have top read it
713: PrjFileReader projReader = null;
714: try {
715: FileChannel channel = new FileInputStream(prjFile)
716: .getChannel();
717: projReader = new PrjFileReader(channel);
718: crs = projReader.getCoordinateReferenceSystem();
719: } catch (FileNotFoundException e) {
720: // warn about the error but proceed, it is not fatal
721: // we have at least the default crs to use
722: LOGGER
723: .log(Level.SEVERE, e.getLocalizedMessage(),
724: e);
725: } catch (IOException e) {
726: // warn about the error but proceed, it is not fatal
727: // we have at least the default crs to use
728: LOGGER
729: .log(Level.SEVERE, e.getLocalizedMessage(),
730: e);
731: } catch (FactoryException e) {
732: // warn about the error but proceed, it is not fatal
733: // we have at least the default crs to use
734: LOGGER
735: .log(Level.SEVERE, e.getLocalizedMessage(),
736: e);
737: } finally {
738: if (projReader != null)
739: try {
740: projReader.close();
741: } catch (IOException e) {
742: // warn about the error but proceed, it is not fatal
743: // we have at least the default crs to use
744: LOGGER.log(Level.SEVERE, e
745: .getLocalizedMessage(), e);
746: }
747: }
748: }
749: }
750: if (crs == null) {
751: crs = AbstractGridFormat.getDefaultCRS();
752: LOGGER
753: .info(new StringBuffer(
754: "Unable to find crs, continuing with default WGS4 CRS")
755: .append("\n").append(crs.toWKT())
756: .toString());
757: }
758: }
759: }
|