001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/io/ecwapi/ECWReader.java $
002: /*---------------- FILE HEADER ------------------------------------------
003:
004: This file is part of deegree.
005: Copyright (C) 2003 by:
006: IDgis bv, Holten, The Netherlands
007: http://www.idgis.nl
008:
009: This library is free software; you can redistribute it and/or
010: modify it under the terms of the GNU Lesser General Public
011: License as published by the Free Software Foundation; either
012: version 2.1 of the License, or (at your option) any later version.
013:
014: This library is distributed in the hope that it will be useful,
015: but WITHOUT ANY WARRANTY; without even the implied warranty of
016: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017: Lesser General Public License for more details.
018:
019: You should have received a copy of the GNU Lesser General Public
020: License along with this library; if not, write to the Free Software
021: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
022:
023: ---------------------------------------------------------------------------*/
024: package org.deegree.io.ecwapi;
025:
026: import java.awt.Graphics;
027: import java.awt.image.BufferedImage;
028: import java.io.File;
029: import java.net.URL;
030:
031: import org.deegree.framework.log.ILogger;
032: import org.deegree.framework.log.LoggerFactory;
033: import org.deegree.model.spatialschema.Envelope;
034:
035: import com.ermapper.ecw.JNCSException;
036: import com.ermapper.ecw.JNCSFile;
037:
038: /**
039: * ECWReader.java
040: *
041: * @author Herman Assink
042: * @author last edited by: $Author: apoth $
043: * @version 1.0 2003-11-06
044: */
045:
046: public class ECWReader {
047:
048: private static final ILogger LOG = LoggerFactory
049: .getLogger(ECWReader.class);
050:
051: private static boolean ECW_USE_CACHE = true;
052:
053: private boolean usedCacheOnOpen = true;
054: private JNCSFile ecwFile;
055:
056: /**
057: * read part from ECW-file which falls within env and return this part
058: * dimenions width and height
059: *
060: * @param fileName
061: * full pathname of the ECW-file
062: */
063: public ECWReader(String fileName) throws JNCSException {
064:
065: if (fileName.toLowerCase().startsWith("file:/")) {
066: try {
067: File f = new File(new URL(fileName).getFile());
068: fileName = f.getAbsolutePath();
069: } catch (Exception e) {
070: new JNCSException(fileName + " is not a valid URL");
071: }
072: }
073: LOG.logDebug("ECWReader: " + fileName);
074:
075: if (ECW_USE_CACHE) {
076: this .ecwFile = ECWFileCache.claimAccess(fileName);
077: usedCacheOnOpen = true;
078: } else {
079: this .ecwFile = new JNCSFile(fileName, false);
080: usedCacheOnOpen = false;
081: }
082: }
083:
084: /** Decide, if to use the cache.
085: * <p>
086: * Default is TRUE.
087: */
088: public static void useECWCache(boolean Use) {
089: ECW_USE_CACHE = Use;
090: }
091:
092: /** Free the memory of the image cache
093: */
094: public void close() {
095: if (usedCacheOnOpen) {
096: ECWFileCache.releaseFile(ecwFile);
097: } else {
098: ecwFile.close(true);
099: }
100: }
101:
102: /**
103: * retuns the width of the entire image encapsulated in the ECW file
104: * @return width of the image
105: */
106: public int getWidth() {
107: return ecwFile.width;
108: }
109:
110: /**
111: * retuns the height of the entire image encapsulated in the ECW file
112: * @return height of the image
113: */
114: public int getHeight() {
115: return ecwFile.height;
116: }
117:
118: /**
119: * read part from ECW-file which falls within env and return this part as
120: * BufferedImage with dimenions width and height
121: *
122: * @param env
123: * bounding box in world coordinates of requested part
124: * @param width
125: * width of the returned image
126: * @param height
127: * height of the returned image
128: */
129: public BufferedImage getBufferedImage(Envelope env, int width,
130: int height) throws JNCSException {
131:
132: int bandlist[];
133: int line, pRGBArray[] = null;
134:
135: // Setup the view parameters for the ecw file.
136: bandlist = new int[ecwFile.numBands];
137: for (int i = 0; i < ecwFile.numBands; i++) {
138: bandlist[i] = i;
139: }
140:
141: //Check if the envelope is within the area of the ecw-image
142: double dWorldTLX = env.getMin().getX();
143: double dWorldTLY = env.getMax().getY();
144:
145: LOG.logDebug("tlx: " + dWorldTLX + " tly: " + dWorldTLY);
146:
147: if (dWorldTLX < ecwFile.originX)
148: dWorldTLX = ecwFile.originX;
149: if (dWorldTLY > ecwFile.originY)
150: dWorldTLY = ecwFile.originY;
151: double dWorldBRX = env.getMax().getX();
152: double dWorldBRY = env.getMin().getY();
153:
154: LOG.logDebug("brx: " + dWorldBRX + " bry: " + dWorldBRY);
155:
156: if (dWorldBRX > (ecwFile.originX + ((ecwFile.width - 1) * ecwFile.cellIncrementX))) // Huh?
157: // ECW
158: // does
159: // not
160: // except
161: // the
162: // full
163: // width
164: dWorldBRX = ecwFile.originX
165: + ((ecwFile.width - 1) * ecwFile.cellIncrementX);
166: if (dWorldBRY < (ecwFile.originY
167: + (ecwFile.height * ecwFile.cellIncrementY) - (ecwFile.cellIncrementY / 2)))
168: dWorldBRY = ecwFile.originY
169: + (ecwFile.height * ecwFile.cellIncrementY)
170: - (ecwFile.cellIncrementY / 2);
171:
172: // Work out the correct aspect for the setView call.
173: //double dEnvAspect = (dWorldBRX - dWorldTLX) / (dWorldTLY - dWorldBRY);
174: //double dImgAspect = (double) width / (double) height;
175:
176: LOG.logDebug("tlx: " + dWorldTLX + " tly: " + dWorldTLY);
177: LOG.logDebug("brx: " + dWorldBRX + " bry: " + dWorldBRY);
178: LOG.logDebug("width: " + width + " height: " + height);
179:
180: int nDatasetTLX = (int) Math
181: .round((dWorldTLX - ecwFile.originX)
182: / ecwFile.cellIncrementX);
183: int nDatasetTLY = (int) Math
184: .round((dWorldTLY - ecwFile.originY)
185: / ecwFile.cellIncrementY);
186:
187: LOG.logDebug("ptlx: " + nDatasetTLX + " ptly: " + nDatasetTLY);
188:
189: int nDatasetBRX = (int) Math
190: .round((dWorldBRX - ecwFile.originX)
191: / ecwFile.cellIncrementX);
192: int nDatasetBRY = (int) Math
193: .round((dWorldBRY - ecwFile.originY)
194: / ecwFile.cellIncrementY);
195:
196: LOG.logDebug("pbrx: " + nDatasetBRX + " pbry: " + nDatasetBRY);
197:
198: if (nDatasetBRX > (ecwFile.width - 1))
199: nDatasetBRX = ecwFile.width - 1;
200: if (nDatasetBRY > (ecwFile.height - 1))
201: nDatasetBRY = ecwFile.height - 1;
202:
203: LOG.logDebug("pbrx: " + nDatasetBRX + " pbry: " + nDatasetBRY);
204:
205: // Check for supersampling
206: int viewWidth = width;
207: int viewHeight = height;
208: if ((nDatasetBRX - nDatasetTLX) < viewWidth
209: || (nDatasetBRY - nDatasetTLY) < viewHeight) {
210: viewWidth = nDatasetBRX - nDatasetTLX;
211: viewHeight = nDatasetBRY - nDatasetTLY;
212: }
213: if (viewWidth == 0)
214: viewWidth = 1;
215: if (viewHeight == 0)
216: viewHeight = 1;
217:
218: LOG.logDebug("Width: " + width + " Height: " + height);
219: LOG.logDebug("viewWidth: " + viewWidth + " viewHeight: "
220: + viewHeight);
221:
222: // Create an image of the ecw file.
223: BufferedImage ecwImage = new BufferedImage(viewWidth,
224: viewHeight, BufferedImage.TYPE_INT_RGB);
225: pRGBArray = new int[width];
226:
227: // Set the view
228: ecwFile.setView(ecwFile.numBands, bandlist, nDatasetTLX,
229: nDatasetTLY, nDatasetBRX, nDatasetBRY, viewWidth,
230: viewHeight);
231:
232: // Read the scan lines
233: for (line = 0; line < viewHeight; line++) {
234: ecwFile.readLineRGBA(pRGBArray);
235: ecwImage.setRGB(0, line, viewWidth, 1, pRGBArray, 0,
236: viewWidth);
237: }
238:
239: if (width != viewWidth || height != viewHeight) {
240: LOG.logDebug("enlarge image");
241: BufferedImage enlargedImg = new BufferedImage(width,
242: height, BufferedImage.TYPE_INT_RGB);
243: Graphics g = enlargedImg.getGraphics();
244: g.drawImage(ecwImage, 0, 0, width, height, 0, 0, viewWidth,
245: viewHeight, null);
246: ecwImage = enlargedImg;
247: g.dispose();
248: }
249:
250: return ecwImage;
251:
252: }
253: }
|