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.image;
018:
019: import java.awt.Rectangle;
020: import java.awt.RenderingHints;
021: import java.awt.geom.AffineTransform;
022: import java.awt.image.renderable.ParameterBlock;
023: import java.io.BufferedReader;
024: import java.io.File;
025: import java.io.FileInputStream;
026: import java.io.FileNotFoundException;
027: import java.io.FileReader;
028: import java.io.IOException;
029: import java.net.URL;
030: import java.net.URLDecoder;
031: import java.nio.channels.FileChannel;
032: import java.util.Iterator;
033: import java.util.Set;
034: import java.util.logging.Level;
035: import java.util.logging.Logger;
036:
037: import javax.imageio.ImageIO;
038: import javax.imageio.ImageReadParam;
039: import javax.imageio.ImageReader;
040: import javax.imageio.spi.ImageReaderSpi;
041: import javax.imageio.stream.ImageInputStream;
042: import javax.media.jai.JAI;
043: import javax.media.jai.PlanarImage;
044:
045: import org.geotools.coverage.grid.GeneralGridRange;
046: import org.geotools.coverage.grid.GridGeometry2D;
047: import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
048: import org.geotools.coverage.grid.io.AbstractGridFormat;
049: import org.geotools.data.DataSourceException;
050: import org.geotools.data.PrjFileReader;
051: import org.geotools.data.WorldFileReader;
052: import org.geotools.factory.Hints;
053: import org.geotools.geometry.GeneralEnvelope;
054: import org.geotools.parameter.Parameter;
055: import org.geotools.referencing.CRS;
056: import org.geotools.referencing.operation.matrix.AffineTransform2D;
057: import org.geotools.referencing.operation.matrix.XAffineTransform;
058: import org.geotools.referencing.operation.transform.ProjectiveTransform;
059: import org.opengis.coverage.grid.Format;
060: import org.opengis.coverage.grid.GridCoverage;
061: import org.opengis.coverage.grid.GridCoverageReader;
062: import org.opengis.parameter.GeneralParameterValue;
063: import org.opengis.referencing.FactoryException;
064: import org.opengis.referencing.NoSuchAuthorityCodeException;
065: import org.opengis.referencing.crs.CoordinateReferenceSystem;
066: import org.opengis.referencing.operation.TransformException;
067: import org.opengis.geometry.Envelope;
068: import org.opengis.geometry.MismatchedDimensionException;
069:
070: /**
071: * Reads a GridCoverage from a given source. WorldImage sources only support one
072: * GridCoverage so hasMoreGridCoverages() will return true until the only
073: * GridCoverage is read. No metadata is currently supported, so all related
074: * methods return null. In the early future we will start (hopefully supporting
075: * them).
076: *
077: * @author simone giannecchini
078: * @author alessio fabiani
079: * @author rgould
080: */
081: public final class WorldImageReader extends
082: AbstractGridCoverage2DReader implements GridCoverageReader {
083:
084: /** Logger. */
085: private Logger LOGGER = org.geotools.util.logging.Logging
086: .getLogger("org.geotools.gce.image");
087:
088: private boolean wmsRequest;
089:
090: private boolean metaFile;
091:
092: private String parentPath;
093:
094: private String extension;
095:
096: private ImageReaderSpi readerSPI;
097:
098: /**
099: * Class constructor. Construct a new ImageWorldReader to read a
100: * GridCoverage from the source object. The source must point to the raster
101: * file itself, not the world file. If the source is a Java URL it checks if
102: * it is ponting to a file and if so it converts the url into a file.
103: *
104: * @param input
105: * The source of a GridCoverage, can be a File, a URL or an input
106: * stream.
107: * @throws DataSourceException
108: */
109: public WorldImageReader(Object input) throws DataSourceException {
110: this (input, null);
111: }
112:
113: /**
114: * Class constructor. Construct a new ImageWorldReader to read a
115: * GridCoverage from the source object. The source must point to the raster
116: * file itself, not the world file. If the source is a Java URL it checks if
117: * it is ponting to a file and if so it converts the url into a file.
118: *
119: * @param input
120: * The source of a GridCoverage, can be a File, a URL or an input
121: * stream.
122: * @throws DataSourceException
123: */
124: public WorldImageReader(Object input, final Hints hints)
125: throws DataSourceException {
126: // /////////////////////////////////////////////////////////////////////
127: //
128: // Checking input
129: //
130: // /////////////////////////////////////////////////////////////////////
131: if (input == null) {
132:
133: final IOException ex = new IOException(
134: "WorldImage:No source set to read this coverage.");
135: LOGGER.logp(Level.SEVERE,
136: WorldImageReader.class.toString(),
137: "WorldImageReader", ex.getLocalizedMessage(), ex);
138: throw new DataSourceException(ex);
139: }
140: this .source = input;
141: if (hints != null)
142: this .hints.add(hints);
143: coverageName = "image_coverage";
144: try {
145: boolean closeMe = true;
146:
147: // /////////////////////////////////////////////////////////////////////
148: //
149: // Source management
150: //
151: // /////////////////////////////////////////////////////////////////////
152: if (input instanceof URL) {
153: // URL that point to a file
154: final URL sourceURL = ((URL) input);
155: if (sourceURL.getProtocol().compareToIgnoreCase("file") == 0) {
156: String auth = sourceURL.getAuthority();
157: String path = sourceURL.getPath();
158: if (auth != null && !auth.equals("")) {
159: path = "//" + auth + path;
160: }
161: this .source = input = new File(URLDecoder.decode(
162: path, "UTF-8"));
163: } else if (sourceURL.getProtocol().equalsIgnoreCase(
164: "http")) {
165: // // getting a stream to the reader
166: // this.source = sourceURL.openStream();
167:
168: // /////////////////////////////////////////////////////////////////////
169: //
170: // WMS Request? I want to be able to handle that case too
171: //
172: // /////////////////////////////////////////////////////////////////////
173: wmsRequest = WMSRequest(input);
174: }
175: }
176:
177: // //
178: //
179: // Name, path, etc...
180: //
181: // //
182: if (input instanceof File) {
183: final File sourceFile = (File) input;
184: final String filename = sourceFile.getName();
185: final int i = filename.lastIndexOf('.');
186: final int length = filename.length();
187: if (i > 0 && i < length - 1) {
188: extension = filename.substring(i + 1).toLowerCase();
189: }
190: this .parentPath = sourceFile.getParent();
191: this .coverageName = filename;
192: final int dotIndex = coverageName.lastIndexOf(".");
193: coverageName = (dotIndex == -1) ? coverageName
194: : coverageName.substring(0, dotIndex);
195: } else if (input instanceof URL)
196: input = ((URL) input).openStream();
197: // //
198: //
199: // Get a stream in order to read from it for getting the basic
200: // information for this coverfage
201: //
202: // //
203: if (input instanceof ImageInputStream)
204: closeMe = false;
205:
206: inStream = (ImageInputStream) (this .source instanceof ImageInputStream ? this .source
207: : ImageIO
208: .createImageInputStream((this .source instanceof URL) ? ((URL) this .source)
209: .openStream()
210: : this .source));
211: if (inStream == null)
212: throw new IllegalArgumentException(
213: "No input stream for the provided source");
214:
215: // /////////////////////////////////////////////////////////////////////
216: //
217: // CRS
218: //
219: // /////////////////////////////////////////////////////////////////////
220: if (!wmsRequest) {
221: final Object tempCRS = this .hints
222: .get(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM);
223: if (tempCRS != null) {
224: this .crs = (CoordinateReferenceSystem) tempCRS;
225: LOGGER
226: .log(
227: Level.WARNING,
228: new StringBuffer(
229: "Using forced coordinate reference system ")
230: .append(crs.toWKT())
231: .toString());
232: } else
233: readCRS();
234: }
235:
236: // /////////////////////////////////////////////////////////////////////
237: //
238: // Informations about multiple levels and such
239: //
240: // /////////////////////////////////////////////////////////////////////
241: getHRInfo();
242:
243: // release the stream
244: if (closeMe)
245: inStream.close();
246: } catch (IOException e) {
247: LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
248: throw new DataSourceException(e);
249: } catch (TransformException e) {
250: LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
251: throw new DataSourceException(e);
252: }
253: }
254:
255: /**
256: * Gets the relevant information for the underlying raster.
257: *
258: * @throws IOException
259: * @throws TransformException
260: */
261: private void getHRInfo() throws IOException, TransformException {
262:
263: // //
264: //
265: // Get a reader for this format
266: // TODO optimize this using image file extension when possible
267: //
268: // //
269: final Iterator it = ImageIO.getImageReaders(inStream);
270: if (!it.hasNext())
271: throw new DataSourceException(
272: "No reader avalaible for this source");
273: final ImageReader reader = (ImageReader) it.next();
274: readerSPI = reader.getOriginatingProvider();
275: reader.setInput(inStream);
276:
277: // //
278: //
279: // get the dimension of the hr image and build the model as well as
280: // computing the resolution
281: // //
282: numOverviews = wmsRequest ? 0 : reader.getNumImages(true) - 1;
283: int hrWidth = reader.getWidth(0);
284: int hrHeight = reader.getHeight(0);
285: final Rectangle actualDim = new Rectangle(0, 0, hrWidth,
286: hrHeight);
287: originalGridRange = new GeneralGridRange(actualDim);
288:
289: // /////////////////////////////////////////////////////////////////////
290: //
291: // Envelope, coverage name and other resolution information
292: //
293: // /////////////////////////////////////////////////////////////////////
294: if (source instanceof File) {
295: prepareWorldImageGridToWorldTransform();
296:
297: // //
298: //
299: // In case we read from a real world file we have toget the envelope
300: //
301: // //
302: if (!metaFile) {
303: final AffineTransform tempTransform = new AffineTransform(
304: (AffineTransform) raster2Model);
305: tempTransform.translate(-0.5, -0.5);
306:
307: originalEnvelope = CRS.transform(ProjectiveTransform
308: .create(tempTransform), new GeneralEnvelope(
309: actualDim));
310: originalEnvelope.setCoordinateReferenceSystem(crs);
311: }
312:
313: // ///
314: //
315: // setting the higher resolution avalaible for this coverage
316: //
317: // ///
318: highestRes = getResolution(originalEnvelope, actualDim, crs);
319:
320: }
321: // //
322: //
323: // get information for the overviews in case ony exists
324: //
325: // //
326: if (numOverviews > 1) {
327: overViewResolutions = new double[numOverviews][2];
328: double res[];
329: for (int i = 0; i < numOverviews; i++) {
330: res = getResolution(originalEnvelope, new Rectangle(0,
331: 0, reader.getWidth(i), reader.getHeight(i)),
332: crs);
333: overViewResolutions[i][0] = res[0];
334: overViewResolutions[i][1] = res[1];
335: }
336: } else
337: overViewResolutions = null;
338: }
339:
340: /**
341: * Returns the format that this Reader accepts.
342: *
343: * @return a new WorldImageFormat class
344: */
345: public Format getFormat() {
346: return new WorldImageFormat();
347: }
348:
349: /**
350: * Reads an image from a source stream. Loads an image from a source stream,
351: * then loads the values from the world file and constructs a new
352: * GridCoverage from this information. When reading from a remote stream we
353: * do not look for a world fiel but we suppose those information comes from
354: * a different way (xml, gml, pigeon?)
355: *
356: * @param params
357: * WorldImageReader supports no parameters, it just ignores them.
358: *
359: * @return a new GridCoverage read from the source.
360: *
361: * @throws IllegalArgumentException
362: * DOCUMENT ME!
363: * @throws IOException
364: * DOCUMENT ME!
365: */
366: public GridCoverage read(GeneralParameterValue[] params)
367: throws IllegalArgumentException, IOException {
368:
369: // /////////////////////////////////////////////////////////////////////
370: //
371: // do we have paramters to use for reading from the specified source
372: //
373: // /////////////////////////////////////////////////////////////////////
374: GeneralEnvelope requestedEnvelope = null;
375: Rectangle dim = null;
376: if (params != null) {
377: // /////////////////////////////////////////////////////////////////////
378: //
379: // Checking params
380: //
381: // /////////////////////////////////////////////////////////////////////
382: if (params != null) {
383: for (int i = 0; i < params.length; i++) {
384: final Parameter param = (Parameter) params[i];
385: if (param
386: .getDescriptor()
387: .getName()
388: .getCode()
389: .equals(
390: AbstractGridFormat.READ_GRIDGEOMETRY2D
391: .getName().toString())) {
392: final GridGeometry2D gg = (GridGeometry2D) param
393: .getValue();
394: requestedEnvelope = new GeneralEnvelope(
395: (Envelope) gg.getEnvelope2D());
396: dim = gg.getGridRange2D().getBounds();
397: }
398: }
399: }
400: }
401:
402: // /////////////////////////////////////////////////////////////////////
403: //
404: // set params
405: //
406: // /////////////////////////////////////////////////////////////////////
407: Integer imageChoice = new Integer(0);
408: final ImageReadParam readP = new ImageReadParam();
409: if (!wmsRequest) {
410: try {
411: imageChoice = setReadParams(readP, requestedEnvelope,
412: dim);
413: } catch (TransformException e) {
414: new DataSourceException(e);
415: }
416: }
417: // /////////////////////////////////////////////////////////////////////
418: //
419: // Reading the source layer
420: //
421: // /////////////////////////////////////////////////////////////////////
422: // final ImageReader reader = readerSPI.createReaderInstance();
423: // final ImageInputStream inStream = wmsRequest ? ImageIO
424: // .createImageInputStream(((URL) source).openStream()) : ImageIO
425: // .createImageInputStream(source);
426: //
427: final Hints newHints = (Hints) hints.clone();
428: // if (!wmsRequest) {
429: // reader.setInput(inStream);
430: // if (!reader.isImageTiled(imageChoice.intValue())) {
431: // final Dimension tileSize = ImageUtilities
432: // .toTileSize(new Dimension(reader.getWidth(imageChoice
433: // .intValue()), reader.getHeight(imageChoice
434: // .intValue())));
435: // final ImageLayout layout = new ImageLayout();
436: // layout.setTileGridXOffset(0);
437: // layout.setTileGridYOffset(0);
438: // layout.setTileHeight(tileSize.height);
439: // layout.setTileWidth(tileSize.width);
440: // newHints.add(new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout));
441: // }
442: // }
443: // inStream.close();
444: final ParameterBlock pbjRead = new ParameterBlock();
445: pbjRead.add(wmsRequest ? ImageIO
446: .createImageInputStream(((URL) source).openStream())
447: : ImageIO.createImageInputStream(source));
448: pbjRead.add(imageChoice);
449: pbjRead.add(Boolean.FALSE);
450: pbjRead.add(Boolean.FALSE);
451: pbjRead.add(Boolean.FALSE);
452: pbjRead.add(null);
453: pbjRead.add(null);
454: pbjRead.add(readP);
455: pbjRead.add(readerSPI.createReaderInstance());
456:
457: // /////////////////////////////////////////////////////////////////////
458: //
459: // BUILDING COVERAGE
460: //
461: // /////////////////////////////////////////////////////////////////////
462: // get the raster -> model transformation and
463: // create the coverage
464: if (imageChoice.intValue() == 0 && !metaFile) {
465: final AffineTransform tempRaster2Model = new AffineTransform(
466: (AffineTransform) raster2Model);
467: tempRaster2Model.concatenate(new AffineTransform(readP
468: .getSourceXSubsampling(), 0, 0, readP
469: .getSourceYSubsampling(), 0, 0));
470: return createImageCoverage(JAI.create("ImageRead", pbjRead,
471: (RenderingHints) newHints), ProjectiveTransform
472: .create((AffineTransform) tempRaster2Model));
473:
474: }
475: return createImageCoverage(JAI.create("ImageRead", pbjRead,
476: (RenderingHints) newHints));
477:
478: }
479:
480: /**
481: * This method is used to check if we are connecting directly to a WMS with
482: * a getmap request. In such a case we skip reading all the parameters we
483: * can read from this http string.
484: *
485: * @param input
486: *
487: * @return true if we are dealing with a WMS request, false otherwise.
488: */
489: private boolean WMSRequest(Object input) {
490: // TODO do we need the requested envelope?
491: if (input instanceof URL
492: && (((URL) input).getProtocol()
493: .equalsIgnoreCase("http"))) {
494: try {
495: // getting the query
496: final String query = java.net.URLDecoder.decode(
497: ((URL) input).getQuery().intern(), "UTF-8");
498:
499: // should we proceed? Let's look for a getmap WMS request
500: if (query.intern().indexOf("GetMap") == -1) {
501: return false;
502: }
503:
504: // tokenizer on $
505: final String[] pairs = query.split("&");
506:
507: // parse each pair
508: final int numPairs = pairs.length;
509: String[] kvp = null;
510:
511: for (int i = 0; i < numPairs; i++) {
512: // splitting the pairs
513: kvp = pairs[i].split("=");
514:
515: // checking the fields
516: // BBOX
517: if (kvp[0].equalsIgnoreCase("BBOX")) {
518: // splitting fields
519: kvp = kvp[1].split(",");
520: originalEnvelope = new GeneralEnvelope(
521: new double[] {
522: Double.parseDouble(kvp[0]),
523: Double.parseDouble(kvp[1]) },
524: new double[] {
525: Double.parseDouble(kvp[2]),
526: Double.parseDouble(kvp[3]) });
527: }
528:
529: // SRS
530: if (kvp[0].equalsIgnoreCase("SRS")) {
531: crs = CRS.decode(kvp[1], true);
532: }
533:
534: // layers
535: if (kvp[0].equalsIgnoreCase("layers")) {
536: this .coverageName = kvp[1].replaceAll(",", "_");
537: }
538: }
539:
540: } catch (IOException e) {
541: // TODO how to handle this?
542: return false;
543:
544: } catch (NoSuchAuthorityCodeException e) {
545: // TODO how to handle this?
546: return false;
547: } catch (MismatchedDimensionException e) {
548: // TODO how to handle this?
549: return false;
550: } catch (IndexOutOfBoundsException e) {
551: // TODO how to handle this?
552: return false;
553: } catch (FactoryException e) {
554: // TODO how to handle this?
555: return false;
556: }
557:
558: return true;
559: }
560:
561: return false;
562: }
563:
564: /**
565: * This method is responsible for reading the CRS whhther a projection file
566: * is provided. If no projection file is provided the second choice is the
567: * CRS supplied via the crs paramter. If even this one is not avalaible we
568: * default to EPSG:4326.
569: *
570: * @throws IOException
571: */
572: private void readCRS() throws IOException {
573:
574: // check to see if there is a projection file
575: if (source instanceof File
576: || (source instanceof URL && (((URL) source)
577: .getProtocol() == "file"))) {
578: // getting name for the prj file
579: final String sourceAsString;
580:
581: if (source instanceof File) {
582: sourceAsString = ((File) source).getAbsolutePath();
583: } else {
584: String auth = ((URL) source).getAuthority();
585: String path = ((URL) source).getPath();
586: if (auth != null && !auth.equals("")) {
587: sourceAsString = "//" + auth + path;
588: } else {
589: sourceAsString = path;
590: }
591: }
592:
593: final int index = sourceAsString.lastIndexOf(".");
594: final StringBuffer base = new StringBuffer(sourceAsString
595: .substring(0, index)).append(".prj");
596:
597: // does it exist?
598: final File prjFile = new File(base.toString());
599: if (prjFile.exists()) {
600: // it exists then we have top read it
601: PrjFileReader projReader = null;
602: try {
603: final FileChannel channel = new FileInputStream(
604: prjFile).getChannel();
605: projReader = new PrjFileReader(channel);
606: crs = projReader.getCoordinateReferenceSystem();
607: } catch (FileNotFoundException e) {
608: // warn about the error but proceed, it is not fatal
609: // we have at least the default crs to use
610: LOGGER.log(Level.INFO, e.getLocalizedMessage(), e);
611: } catch (IOException e) {
612: // warn about the error but proceed, it is not fatal
613: // we have at least the default crs to use
614: LOGGER.log(Level.INFO, e.getLocalizedMessage(), e);
615: } catch (FactoryException e) {
616: // warn about the error but proceed, it is not fatal
617: // we have at least the default crs to use
618: LOGGER.log(Level.INFO, e.getLocalizedMessage(), e);
619: } finally {
620: if (projReader != null)
621: try {
622: projReader.close();
623: } catch (IOException e) {
624: // warn about the error but proceed, it is not fatal
625: // we have at least the default crs to use
626: LOGGER.log(Level.SEVERE, e
627: .getLocalizedMessage(), e);
628: }
629: }
630:
631: }
632: }
633: if (crs == null) {
634: crs = AbstractGridFormat.getDefaultCRS();
635: LOGGER
636: .info(new StringBuffer(
637: "Unable to find crs, continuing with default WGS4 CRS")
638: .append("\n").append(crs.toWKT())
639: .toString());
640: }
641:
642: }
643:
644: /**
645: * This method is in charge for reading the metadata file and for creating a
646: * valid envelope (whether possible);
647: *
648: * TODO it would be great to having a centralized management for the world
649: * file
650: *
651: * @throws IOException
652: */
653: private void prepareWorldImageGridToWorldTransform()
654: throws IOException {
655:
656: // getting name and extension
657: final String base = (parentPath != null) ? new StringBuffer(
658: this .parentPath).append(File.separator).append(
659: coverageName).toString() : coverageName;
660:
661: // We can now construct the baseURL from this string.
662: File file2Parse = new File(new StringBuffer(base)
663: .append(".wld").toString());
664:
665: if (file2Parse.exists()) {
666: final WorldFileReader reader = new WorldFileReader(
667: file2Parse);
668: raster2Model = reader.getTransform();
669: } else {
670: // looking for another extension
671: final Set ext = WorldImageFormat
672: .getWorldExtension(extension);
673: final Iterator it = ext.iterator();
674: if (!it.hasNext())
675: throw new DataSourceException(
676: "Unable to parse extension " + extension);
677: do {
678: file2Parse = new File(new StringBuffer(base).append(
679: (String) it.next()).toString());
680: } while (!file2Parse.exists() && it.hasNext());
681:
682: if (file2Parse.exists()) {
683: // parse world file
684: final WorldFileReader reader = new WorldFileReader(
685: file2Parse);
686: raster2Model = reader.getTransform();
687: metaFile = false;
688: } else {
689: // looking for a meta file
690: file2Parse = new File(new StringBuffer(base).append(
691: ".meta").toString());
692:
693: if (file2Parse.exists()) {
694: parseMetaFile(file2Parse);
695: metaFile = true;
696: } else {
697: final IOException ex = new IOException(
698: "No file with meta information found: "
699: + file2Parse.getAbsolutePath());
700: LOGGER
701: .logp(
702: Level.SEVERE,
703: WorldImageReader.class.toString(),
704: "private void prepareWorldImage2Model() throws IOException",
705: ex.getLocalizedMessage(), ex);
706: throw ex;
707: }
708: }
709: }
710: }
711:
712: /**
713: * This method is responsible for parsing a META file which is nothing more
714: * than another format of a WorldFile used by the GIDB database.
715: *
716: * @param file2Parse
717: *
718: *
719: * @throws NumberFormatException
720: * @throws IOException
721: *
722: * @task move me to a separate implementation
723: */
724: private void parseMetaFile(File file2Parse)
725: throws NumberFormatException, IOException {
726: double xMin = 0.0;
727: double yMax = 0.0;
728: double xMax = 0.0;
729: double yMin = 0.0;
730:
731: // getting a buffered reader
732: final BufferedReader in = new BufferedReader(new FileReader(
733: file2Parse));
734:
735: // parsing the lines
736: String str = null;
737: int index = 0;
738: double value = 0;
739:
740: while ((str = in.readLine()) != null) {
741: switch (index) {
742: case 1:
743: value = Double.parseDouble(str
744: .substring("Origin Longitude = ".intern()
745: .length()));
746: xMin = value;
747:
748: break;
749:
750: case 2:
751: value = Double.parseDouble(str
752: .substring("Origin Latitude = ".intern()
753: .length()));
754: yMin = value;
755:
756: break;
757:
758: case 3:
759: value = Double.parseDouble(str
760: .substring("Corner Longitude = ".intern()
761: .length()));
762: xMax = value;
763:
764: break;
765:
766: case 4:
767: value = Double.parseDouble(str
768: .substring("Corner Latitude = ".intern()
769: .length()));
770: yMax = value;
771:
772: break;
773:
774: default:
775: break;
776: }
777:
778: index++;
779: }
780:
781: in.close();
782:
783: // building up envelope of this coverage
784: originalEnvelope = new GeneralEnvelope(new double[] { xMin,
785: yMin }, new double[] { xMax, yMax });
786: originalEnvelope.setCoordinateReferenceSystem(crs);
787: }
788:
789: }
|