001: /*
002: * Geotools2 - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2006, Geotools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: */
017: package org.geotools.data;
018:
019: import java.io.BufferedReader;
020: import java.io.File;
021: import java.io.FileReader;
022: import java.io.IOException;
023:
024: import org.geotools.referencing.operation.LinearTransform;
025: import org.geotools.referencing.operation.matrix.GeneralMatrix;
026: import org.geotools.referencing.operation.transform.ProjectiveTransform;
027: import org.opengis.referencing.operation.MathTransform;
028:
029: /**
030: * This class is responsible for parsing a world file in order to build an
031: * affine transform using the parameters provided in the file itself.
032: *
033: * <p>
034: * The parameters found in the file should be as follows:
035: * <ol>
036: * <li>size of pixel in x direction</li>
037: * <li>rotation term for row</li>
038: * <li>rotation term for column</li>
039: * <li>size of pixel in y direction</li>
040: * <li>x coordinate of centre of upper left pixel in map units</li>
041: * <li>y coordinate of centre of upper left pixel in map units</li>
042: * </ol>
043: * <strong>Note that the last two coordinates refer to the centre of the pixel!</strong>
044: *
045: *
046: * <p>
047: * It is worth to point out that various data sources describe the parameters in
048: * the world file as the mapping from the pixel centres' to the associated world
049: * coords. Here we directly build the needed grid to world transform and we DO
050: * NOT add any half a pixel translation given that, as stated above, the values
051: * we receive should map to the centre of the pixel.
052: *
053: *
054: * @author Simone Giannecchini
055: * @since 2.3
056: *
057: */
058: public final class WorldFileReader {
059:
060: /**
061: * Default size for the underlying buffer,
062: */
063: private final static int DEFAULT_BUFFER_SIZE = 8192;
064:
065: /** Resolution on the first dimension. */
066: private double xPixelSize = 0.0;
067:
068: /** Rotation on the first dimension. */
069: private double rotationX = 0.0;
070:
071: /** Resolution on the second dimension. */
072: private double rotationY = 0.0;
073:
074: /** Resolution on the second dimension. */
075: private double yPixelSize = 0.0;
076:
077: /** Upper left centre coordinate of first dimension. */
078: private double xULC = 0.0;
079:
080: /** Upper left centre coordinate of second dimension. */
081: private double yULC = 0.0;
082:
083: /** Resulting linear transform. */
084: private LinearTransform transform;
085:
086: /**
087: * Constructor.
088: *
089: * @param worldFile
090: * @throws IOException
091: */
092: public WorldFileReader(final File worldFile) throws IOException {
093: this (worldFile, DEFAULT_BUFFER_SIZE);
094: }
095:
096: /**
097: * Constructor.
098: *
099: * @param worldFile
100: * @param bufferSize
101: * @throws IOException
102: */
103: public WorldFileReader(final File worldFile, final int bufferSize)
104: throws IOException {
105: final BufferedReader bufferedreader = new BufferedReader(
106: new FileReader(worldFile));
107:
108: int index = 0;
109: double value = 0;
110: String str;
111: while ((str = bufferedreader.readLine()) != null) {
112:
113: value = 0;
114:
115: try {
116: value = Double.parseDouble(str.trim());
117: } catch (NumberFormatException e) {
118: // A trick to bypass invalid lines ...
119: continue;
120: }
121:
122: switch (index) {
123: case 0:
124: xPixelSize = value;
125:
126: break;
127:
128: case 1:
129: rotationX = value;
130:
131: break;
132:
133: case 2:
134: rotationY = value;
135:
136: break;
137:
138: case 3:
139: yPixelSize = value;
140:
141: break;
142:
143: case 4:
144: xULC = value;
145:
146: break;
147:
148: case 5:
149: yULC = value;
150:
151: break;
152:
153: default:
154: break;
155: }
156:
157: index++;
158: }
159: bufferedreader.close();
160:
161: // did we find all we were looking for?
162: if (index < 5)
163: throw new IOException(
164: "Not all the values were found for this world file!");
165: }
166:
167: public double getRotationX() {
168: return rotationX;
169: }
170:
171: public double getRotationY() {
172: return rotationY;
173: }
174:
175: public double getXPixelSize() {
176: return xPixelSize;
177: }
178:
179: public double getXULC() {
180: return xULC;
181: }
182:
183: public double getYPixelSize() {
184: return yPixelSize;
185: }
186:
187: public double getYULC() {
188: return yULC;
189: }
190:
191: public synchronized MathTransform getTransform() {
192: if (transform == null) {
193: // building the transform
194: final GeneralMatrix gm = new GeneralMatrix(3); // identity
195:
196: // compute an "offset and scale" matrix
197: gm.setElement(0, 0, xPixelSize);
198: gm.setElement(1, 1, yPixelSize);
199: gm.setElement(0, 1, rotationX);
200: gm.setElement(1, 0, rotationY);
201:
202: gm.setElement(0, 2, xULC);
203: gm.setElement(1, 2, yULC);
204:
205: // make it a LinearTransform
206: transform = ProjectiveTransform.create(gm);
207: }
208: return transform;
209: }
210:
211: }
|