001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/tools/raster/RasterSplitter.java $
002: /*---------------- FILE HEADER ------------------------------------------
003:
004: This file is part of deegree.
005: Copyright (C) 2001-2008 by:
006: EXSE, Department of Geography, University of Bonn
007: http://www.giub.uni-bonn.de/deegree/
008: lat/lon GmbH
009: http://www.lat-lon.de
010:
011: This library is free software; you can redistribute it and/or
012: modify it under the terms of the GNU Lesser General Public
013: License as published by the Free Software Foundation; either
014: version 2.1 of the License, or (at your option) any later version.
015:
016: This library is distributed in the hope that it will be useful,
017: but WITHOUT ANY WARRANTY; without even the implied warranty of
018: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: Lesser General Public License for more details.
020:
021: You should have received a copy of the GNU Lesser General Public
022: License along with this library; if not, write to the Free Software
023: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024:
025: Contact:
026:
027: Andreas Poth
028: lat/lon GmbH
029: Aennchenstr. 19
030: 53177 Bonn
031: Germany
032: E-Mail: poth@lat-lon.de
033:
034: Prof. Dr. Klaus Greve
035: Department of Geography
036: University of Bonn
037: Meckenheimer Allee 166
038: 53115 Bonn
039: Germany
040: E-Mail: greve@giub.uni-bonn.de
041:
042: ---------------------------------------------------------------------------*/
043: package org.deegree.tools.raster;
044:
045: import java.awt.image.BufferedImage;
046: import java.io.File;
047: import java.io.FilenameFilter;
048: import java.net.URI;
049: import java.util.ArrayList;
050: import java.util.List;
051: import java.util.Properties;
052:
053: import javax.media.jai.TiledImage;
054:
055: import org.deegree.datatypes.QualifiedName;
056: import org.deegree.framework.log.ILogger;
057: import org.deegree.framework.log.LoggerFactory;
058: import org.deegree.framework.util.ImageUtils;
059: import org.deegree.framework.util.StringTools;
060: import org.deegree.io.dbaseapi.DBaseFile;
061: import org.deegree.model.coverage.grid.WorldFile;
062: import org.deegree.model.spatialschema.Envelope;
063: import org.deegree.model.spatialschema.GeometryFactory;
064: import org.deegree.ogcbase.CommonNamespaces;
065:
066: /**
067: *
068: *
069: * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
070: * @author last edited by: $Author: apoth $
071: *
072: * @version $Revision: 9346 $, $Date: 2007-12-27 08:39:07 -0800 (Thu, 27 Dec 2007) $
073: */
074: public class RasterSplitter {
075:
076: private static final ILogger LOG = LoggerFactory
077: .getLogger(RasterSplitter.class);
078:
079: private static final URI DEEGREEAPP = CommonNamespaces
080: .buildNSURI("http://www.deegree.org/app");
081:
082: private static final String APP_PREFIX = "app";
083:
084: private String outDir;
085:
086: private int tileWidth = 0;
087:
088: private int tileHeight = 0;
089:
090: private String format;
091:
092: private List<String> fileList;
093:
094: /**
095: *
096: * @param rootDir
097: * @param outDir
098: * @param tileWidth
099: * @param tileHeight
100: * @param format
101: * @param subDirs
102: */
103: RasterSplitter(String rootDir, String outDir, int tileWidth,
104: int tileHeight, String format, boolean subDirs) {
105: this .outDir = outDir;
106: this .format = format;
107: this .tileWidth = tileWidth;
108: this .tileHeight = tileHeight;
109: fileList = getFileList(rootDir, subDirs);
110: }
111:
112: /**
113: * @param rootDir
114: * @param outDir
115: * @param tileWidth
116: * @param tileHeight
117: * @param dBase
118: * @param format
119: * @param fileColumn
120: * @throws Exception
121: */
122: RasterSplitter(String rootDir, String outDir, int tileWidth,
123: int tileHeight, String dBase, String format,
124: String fileColumn) throws Exception {
125:
126: this .outDir = outDir;
127: this .format = format;
128: this .tileWidth = tileWidth;
129: this .tileHeight = tileHeight;
130: fileList = getFileList(dBase, fileColumn, rootDir);
131: }
132:
133: /**
134: * splits all files identified by the root dir or dbase file
135: *
136: * @throws Exception
137: */
138: public void perform() throws Exception {
139: for (int i = 0; i < fileList.size(); i++) {
140: System.out.print("processing: " + fileList.get(i));
141: splitFile(fileList.get(i));
142: }
143: }
144:
145: /**
146: * returns the list of image map files to consider read from a dbase file defined by the dbase
147: * parameter
148: *
149: * @param dbaseFile
150: * name of the dbase file
151: * @param fileColumn
152: * name of the column containing the image map files names
153: * @param baseDir
154: * name of the directory where the image map files are stored if this parameter is
155: * <code>null</code> it is assumed that the image map files are full referenced
156: * within the dbase
157: * @return the list of image map files to consider read from a dbase file defined by the dbase
158: * parameter
159: * @throws Exception
160: */
161: private static List<String> getFileList(String dBaseFile,
162: String fileColumn, String baseDir) throws Exception {
163:
164: System.out.println("reading file list ...");
165:
166: // handle dbase file extension and file location/reading problems
167: if (dBaseFile.endsWith(".dbf")) {
168: dBaseFile = dBaseFile.substring(0, dBaseFile
169: .lastIndexOf("."));
170: }
171: DBaseFile dbf = new DBaseFile(dBaseFile);
172:
173: // sort dbase file contents chronologicaly (oldest first)
174: int cnt = dbf.getRecordNum();
175:
176: Object[] mapItems = new Object[cnt];
177: QualifiedName fileC = new QualifiedName(APP_PREFIX, fileColumn
178: .toUpperCase(), DEEGREEAPP);
179:
180: for (int i = 0; i < cnt; i++) {
181: // name of map file
182: mapItems[i] = dbf.getFRow(i + 1).getDefaultProperty(fileC)
183: .getValue();
184: }
185:
186: // extract names of image files from dBase file and attach them to rootDir
187: if (baseDir == null) {
188: baseDir = "";
189: } else if (!baseDir.endsWith("/") && !baseDir.endsWith("\\")) {
190: baseDir = baseDir + '/';
191: }
192: List<String> imageFiles = new ArrayList<String>(mapItems.length);
193: for (int i = 0; i < mapItems.length; i++) {
194: if (mapItems[i] != null) {
195: imageFiles.add(baseDir + mapItems[i]);
196: }
197: }
198:
199: return imageFiles;
200: }
201:
202: /**
203: * returns the list of image map files to consider read from a defined root directory.
204: *
205: * @param rootDir
206: * root directory where to read image map files
207: * @param subdirs
208: * true if subdirectories of the root directory shall be parsed for image maps too
209: * @return the list of image map files to consider read from a defined root directory.
210: */
211: private static List<String> getFileList(String rootDir,
212: boolean subdirs) {
213: System.out.println("reading file list ...");
214: List<String> list = new ArrayList<String>(10000);
215: File file = new File(rootDir);
216: String[] entries = file.list(new DFileFilter());
217: if (entries != null) {
218: for (int i = 0; i < entries.length; i++) {
219: File entry = new File(rootDir + '/' + entries[i]);
220: if (entry.isDirectory() && subdirs) {
221: list = readSubDirs(entry, list);
222: } else {
223: list.add(rootDir + '/' + entries[i]);
224: }
225: }
226: }
227: return list;
228: }
229:
230: /**
231: *
232: * @param file
233: * @param list
234: * @return
235: */
236: private static List<String> readSubDirs(File file, List<String> list) {
237:
238: String[] entries = file.list(new DFileFilter());
239: if (entries != null) {
240: for (int i = 0; i < entries.length; i++) {
241: File entry = new File(file.getAbsolutePath() + '/'
242: + entries[i]);
243: if (entry.isDirectory()) {
244: list = readSubDirs(entry, list);
245: } else {
246: list.add(file.getAbsolutePath() + '/' + entries[i]);
247: }
248: }
249: }
250: return list;
251: }
252:
253: private void splitFile(String inFile) throws Exception {
254:
255: System.out.println("processing: " + inFile);
256: BufferedImage bi = ImageUtils.loadImage(inFile);
257: WorldFile wf = WorldFile.readWorldFile(inFile,
258: WorldFile.TYPE.CENTER, bi.getWidth(), bi.getHeight());
259: TiledImage ti = new TiledImage(bi, tileWidth, tileHeight);
260:
261: int cntx = bi.getWidth() / tileWidth;
262: if (cntx * tileWidth < bi.getWidth()) {
263: cntx++;
264: }
265: int cnty = bi.getHeight() / tileHeight;
266: if (cnty * tileHeight < bi.getHeight()) {
267: cnty++;
268: }
269:
270: int p = inFile.lastIndexOf('/');
271: String base = inFile.substring(p + 1, inFile.length());
272: base = StringTools.replace(base, ".", "_", true);
273:
274: double res = wf.getResx();
275: Envelope env = wf.getEnvelope();
276: for (int i = 0; i < cntx; i++) {
277: for (int j = 0; j < cnty; j++) {
278: String s = StringTools.concat(200, "processing tile: ",
279: i, ' ', j, " of ", cntx, '/', cnty, "\r");
280: System.out.print(s);
281: System.gc();
282: int w = tileWidth;
283: int h = tileHeight;
284: if (i * tileWidth + tileWidth > bi.getWidth()) {
285: w = bi.getWidth() - i * tileWidth;
286: }
287: if (i * tileHeight + tileHeight > bi.getHeight()) {
288: h = bi.getHeight() - i * tileHeight;
289: }
290: if (w > 0 && h > 0) {
291: BufferedImage sub = ti.getSubImage(i * tileWidth,
292: j * tileHeight, w, h).getAsBufferedImage();
293: double x1 = env.getMin().getX() + i * tileWidth
294: * res;
295: double y1 = env.getMax().getY() - (j + 1)
296: * tileHeight * res;
297: double x2 = env.getMin().getX() + (i + 1)
298: * tileWidth * res;
299: double y2 = env.getMax().getY() - j * tileHeight
300: * res;
301: ;
302: Envelope subEnv = GeometryFactory.createEnvelope(
303: x1, y1, x2, y2, null);
304: WorldFile subWf = new WorldFile(res, res, 0, 0,
305: subEnv);
306: s = StringTools.concat(300, outDir, '/', base, '_',
307: i, '_', j, '.', format);
308: ImageUtils.saveImage(sub, s, 1);
309: s = StringTools.concat(300, outDir, '/', base, '_',
310: i, '_', j);
311: WorldFile.writeWorldFile(subWf, s);
312: }
313: }
314: }
315: bi = null;
316: System.gc();
317: }
318:
319: private static void printHelp() {
320: System.out.println();
321: System.out.println("Parameter description for RasterSplitter:");
322: System.out
323: .println("-tileWidth : desired width of result images (mandatory)");
324: System.out
325: .println("-tileHeight : desired width of result images (mandatory)");
326: System.out
327: .println("-format : desired image format of result images (mandatory)");
328: System.out
329: .println("-outDir : directory where result images shall be stored (mandatory)");
330:
331: System.out
332: .println("-rootDir : directory from where images to split will be read (mandatory)");
333: System.out
334: .println("-subDirs : (true|false). If 'true' all sub directories of the 'rootDir' ");
335: System.out
336: .println(" will be searched for images too (optional; default = false)");
337: }
338:
339: private static boolean validate(Properties map) {
340: if (map.getProperty("-tileWidth") == null) {
341: System.out.println("-tileWidth must be set!");
342: return false;
343: }
344: if (map.getProperty("-tileHeight") == null) {
345: System.out.println("-tileHeight must be set!");
346: return false;
347: }
348: if (map.getProperty("-format") == null) {
349: System.out.println("-format must be set!");
350: return false;
351: }
352: if (map.getProperty("-outDir") == null) {
353: System.out.println("-outDir must be set!");
354: return false;
355: }
356: if (map.getProperty("-rootDir") == null) {
357: System.out.println("-rootDir must be set!");
358: return false;
359: }
360: if (map.getProperty("-subDirs") != null
361: && !"true".equals(map.getProperty("-subDirs"))
362: && !"false".equals(map.getProperty("-subDirs"))) {
363: System.out
364: .println("if -subDirs is set it must be true or false!");
365: return false;
366: }
367: return true;
368: }
369:
370: /**
371: *
372: * @param args
373: * @throws Exception
374: */
375: public static void main(String[] args) throws Exception {
376:
377: Properties map = new Properties();
378: for (int i = 0; i < args.length; i += 2) {
379: map.put(args[i], args[i + 1]);
380: }
381: if (!validate(map)) {
382: printHelp();
383: return;
384: }
385:
386: int tileWidth = Integer.parseInt(map.getProperty("-tileWidth"));
387: int tileHeight = Integer.parseInt(map
388: .getProperty("-tileHeight"));
389: String format = map.getProperty("-format");
390: String outDir = map.getProperty("-outDir");
391:
392: RasterSplitter rs = null;
393: if (map.get("-dbaseFile") != null) {
394: String dBaseFile = map.getProperty("-dbaseFile");
395: String fileColum = map.getProperty("-fileColumn");
396: String baseDir = map.getProperty("-baseDir");
397: if (baseDir == null) {
398: baseDir = map.getProperty("-rootDir");
399: }
400: rs = new RasterSplitter(baseDir, outDir, tileWidth,
401: tileHeight, dBaseFile, format, fileColum);
402: } else if (map.get("-rootDir") != null) {
403: String rootDir = map.getProperty("-rootDir");
404: boolean subDirs = "true".equals(map.get("-subDirs"));
405: rs = new RasterSplitter(rootDir, outDir, tileWidth,
406: tileHeight, format, subDirs);
407:
408: } else {
409: LOG.logInfo(map.toString());
410: System.out
411: .println("-rootDir or -dbaseFile parameter must be defined");
412: return;
413: }
414: rs.perform();
415: }
416:
417: /**
418: * class: official version of a FilenameFilter
419: */
420: static class DFileFilter implements FilenameFilter {
421:
422: private List<String> extensions = null;
423:
424: /**
425: *
426: */
427: public DFileFilter() {
428: extensions = new ArrayList<String>();
429: extensions.add("JPEG");
430: extensions.add("JPG");
431: extensions.add("BMP");
432: extensions.add("PNG");
433: extensions.add("GIF");
434: extensions.add("TIF");
435: extensions.add("TIFF");
436: extensions.add("GEOTIFF");
437: }
438:
439: /**
440: * @return the String "*.*"
441: */
442: public String getDescription() {
443: return "*.*";
444: }
445:
446: /*
447: * (non-Javadoc)
448: *
449: * @see java.io.FilenameFilter#accept(java.io.File, java.lang.String)
450: */
451: public boolean accept(java.io.File file, String name) {
452: int pos = name.lastIndexOf(".");
453: String ext = name.substring(pos + 1).toUpperCase();
454: if (file.isDirectory()) {
455: String s = file.getAbsolutePath() + '/' + name;
456: File tmp = new File(s);
457: if (tmp.isDirectory()) {
458: return true;
459: }
460: }
461: return extensions.contains(ext);
462: }
463: }
464: }
|