Source Code Cross Referenced for MosaicIndexBuilder.java in  » GIS » GeoTools-2.4.1 » it » geosolutions » utils » imagemosaic » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » GeoTools 2.4.1 » it.geosolutions.utils.imagemosaic 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        package it.geosolutions.utils.imagemosaic;
0002:
0003:        import it.geosolutions.utils.progress.ExceptionEvent;
0004:        import it.geosolutions.utils.progress.ProcessingEvent;
0005:        import it.geosolutions.utils.progress.ProcessingEventListener;
0006:        import it.geosolutions.utils.progress.ProgressManager;
0007:
0008:        import java.awt.Rectangle;
0009:        import java.awt.geom.Rectangle2D;
0010:        import java.awt.image.ColorModel;
0011:        import java.awt.image.ComponentColorModel;
0012:        import java.awt.image.IndexColorModel;
0013:        import java.awt.image.SampleModel;
0014:        import java.io.BufferedOutputStream;
0015:        import java.io.File;
0016:        import java.io.FileFilter;
0017:        import java.io.FileNotFoundException;
0018:        import java.io.FileOutputStream;
0019:        import java.io.IOException;
0020:        import java.net.MalformedURLException;
0021:        import java.util.ArrayList;
0022:        import java.util.Arrays;
0023:        import java.util.HashSet;
0024:        import java.util.Iterator;
0025:        import java.util.List;
0026:        import java.util.Properties;
0027:        import java.util.Set;
0028:        import java.util.logging.FileHandler;
0029:        import java.util.logging.Level;
0030:        import java.util.logging.Logger;
0031:
0032:        import javax.imageio.ImageIO;
0033:        import javax.imageio.ImageReader;
0034:        import javax.imageio.ImageTypeSpecifier;
0035:        import javax.imageio.stream.ImageInputStream;
0036:
0037:        import org.apache.commons.cli2.option.DefaultOption;
0038:        import org.apache.commons.cli2.option.GroupImpl;
0039:        import org.apache.commons.cli2.util.HelpFormatter;
0040:        import org.apache.commons.io.filefilter.DirectoryFileFilter;
0041:        import org.apache.commons.io.filefilter.WildcardFilter;
0042:        import org.geotools.coverage.grid.GridGeometry2D;
0043:        import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
0044:        import org.geotools.coverage.grid.io.AbstractGridFormat;
0045:        import org.geotools.coverage.grid.io.GridFormatFinder;
0046:        import org.geotools.data.DataSourceException;
0047:        import org.geotools.data.DefaultTransaction;
0048:        import org.geotools.data.FeatureWriter;
0049:        import org.geotools.data.Transaction;
0050:        import org.geotools.data.shapefile.ShapefileDataStore;
0051:        import org.geotools.feature.Feature;
0052:        import org.geotools.feature.FeatureType;
0053:        import org.geotools.feature.FeatureTypeBuilder;
0054:        import org.geotools.feature.IllegalAttributeException;
0055:        import org.geotools.feature.SchemaException;
0056:        import org.geotools.feature.type.GeometricAttributeType;
0057:        import org.geotools.feature.type.TextualAttributeType;
0058:        import org.geotools.geometry.GeneralEnvelope;
0059:        import org.geotools.geometry.jts.ReferencedEnvelope;
0060:        import org.geotools.referencing.CRS;
0061:        import org.geotools.resources.CRSUtilities;
0062:        import org.opengis.geometry.Envelope;
0063:        import org.opengis.referencing.FactoryException;
0064:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
0065:        import org.opengis.referencing.operation.MathTransform;
0066:        import org.opengis.referencing.operation.TransformException;
0067:
0068:        import com.vividsolutions.jts.geom.GeometryFactory;
0069:        import com.vividsolutions.jts.geom.Polygon;
0070:        import com.vividsolutions.jts.geom.PrecisionModel;
0071:
0072:        /**
0073:         * This classis in charge for creating the index for a mosaic of images that we
0074:         * want to tie together as a sigle bg coverage.
0075:         * 
0076:         * <p>
0077:         * To get instructions on how to run the toll just run it without any arguments
0078:         * and nice and clean help will be printed to the command line.
0079:         * 
0080:         * 
0081:         * <p>
0082:         * It is worth to point out that this tool comes as a command line tool but it
0083:         * has been built with in mind a GUI. It has the capapbility to register
0084:         * {@link ProcessingEventListener} object that receive notifications about what
0085:         * is going on. Moreover it delegates all the computations to an external
0086:         * thread, hence we can stop the tool in the middle of processig with no so many
0087:         * concerns (hopefully :-) ).
0088:         * <p>
0089:         * 
0090:         * <p>
0091:         * 
0092:         * @author Simone Giannecchini
0093:         * @author Alessio Fabiani
0094:         * @author Blaz Repnik
0095:         * @version 0.3
0096:         * 
0097:         */
0098:        public class MosaicIndexBuilder extends ProgressManager implements 
0099:                Runnable, ProcessingEventListener {
0100:
0101:            /**
0102:             * Number of resolution levels for the coverages.
0103:             */
0104:            private int numberOfLevels;
0105:
0106:            /**
0107:             * Resolutions levels.
0108:             */
0109:            private double[][] resolutionLevels;
0110:
0111:            /** Number of files to process. */
0112:            private int numFiles;
0113:
0114:            /** Default Logger * */
0115:            private final static Logger LOG = org.geotools.util.logging.Logging
0116:                    .getLogger("it.geosolutions.utils.imagemosaic");
0117:
0118:            /** Program Version */
0119:            private final static String versionNumber = "0.3";
0120:
0121:            private static final double EPS = 1E-2;
0122:
0123:            private final DefaultOption locationOpt;
0124:
0125:            private String locationPath;
0126:
0127:            private final DefaultOption wildcardOpt;
0128:
0129:            private String wildcardString = "*.*";
0130:
0131:            private DefaultOption nameOpt;
0132:
0133:            /**
0134:             * Index file name. Default is index.
0135:             */
0136:            private String indexName = "index";
0137:
0138:            /**
0139:             * This field will tell the plugin if it must do a conversion of color from
0140:             * the original index color model to an RGB color model. This happens f the
0141:             * original images uses different color maps between each other making for
0142:             * us impossible to reuse it for the mosaic.
0143:             */
0144:            private boolean mustConvertToRGB = false;
0145:
0146:            private ColorModel actualCM = null;
0147:
0148:            private ColorModel defaultCM = null;
0149:
0150:            private SampleModel defaultSM = null;
0151:
0152:            private SampleModel actualSM = null;
0153:
0154:            private GeneralEnvelope globEnvelope = null;
0155:
0156:            private GeneralEnvelope envelope = null;
0157:
0158:            private byte[][] defaultPalette = null;
0159:
0160:            private CoordinateReferenceSystem defaultCRS = null;
0161:
0162:            private CoordinateReferenceSystem actualCRS = null;
0163:
0164:            /**
0165:             * Recurses the directory tree and returns valid files.
0166:             */
0167:            private void recurse(List allFiles, String locationPath) {
0168:                File dir = new File(locationPath);
0169:                FileFilter fileFilter = new WildcardFilter(wildcardString);
0170:                File[] files = dir.listFiles(fileFilter);
0171:                File[] dirs = dir
0172:                        .listFiles((FileFilter) DirectoryFileFilter.INSTANCE);
0173:                for (int i = 0; i < files.length; i++) {
0174:                    allFiles.add(files[i]);
0175:                }
0176:                for (int i = 0; i < dirs.length; i++) {
0177:                    recurse(allFiles, locationPath + '/' + dirs[i].getName());
0178:                }
0179:            }
0180:
0181:            /**
0182:             * Main thread for the mosaic index builder.
0183:             */
0184:            public void run() {
0185:
0186:                // /////////////////////////////////////////////////////////////////////
0187:                //
0188:                // CREATING INDEX FILE
0189:                //
0190:                // /////////////////////////////////////////////////////////////////////
0191:
0192:                // /////////////////////////////////////////////////////////////////////
0193:                //
0194:                // Create a file handler that write log record to a file called
0195:                // my.log
0196:                //
0197:                // /////////////////////////////////////////////////////////////////////
0198:                FileHandler handler;
0199:                try {
0200:                    boolean append = true;
0201:                    handler = new FileHandler(new StringBuffer(locationPath)
0202:                            .append("/error.txt").toString(), append);
0203:                    handler.setLevel(Level.SEVERE);
0204:                    // Add to the desired logger
0205:                    LOG.addHandler(handler);
0206:                } catch (SecurityException el) {
0207:                    fireException(el);
0208:                    return;
0209:                } catch (IOException el) {
0210:                    fireException(el);
0211:                    return;
0212:                }
0213:
0214:                // /////////////////////////////////////////////////////////////////////
0215:                //
0216:                // Create a set of file names that have to be skipped since these are
0217:                // our metadata files
0218:                //
0219:                // /////////////////////////////////////////////////////////////////////
0220:                final Set skipFiles = new HashSet(Arrays.asList(new String[] {
0221:                        indexName + ".shp", indexName + ".dbf",
0222:                        indexName + ".shx", indexName + ".prj", "error.txt",
0223:                        "error.txt.lck", indexName + ".properties" }));
0224:
0225:                // /////////////////////////////////////////////////////////////////////
0226:                //
0227:                // Creating temp vars
0228:                //
0229:                // /////////////////////////////////////////////////////////////////////
0230:                ShapefileDataStore index = null;
0231:                Transaction t = new DefaultTransaction();
0232:                // declaring a preciosion model to adhere the java double type
0233:                // precision
0234:                PrecisionModel precMod = new PrecisionModel(
0235:                        PrecisionModel.FLOATING);
0236:                GeometryFactory geomFactory = new GeometryFactory(precMod);
0237:                try {
0238:                    index = new ShapefileDataStore(new File(locationPath + "/"
0239:                            + indexName + ".shp").toURL());
0240:                } catch (MalformedURLException ex) {
0241:                    if (LOG.isLoggable(Level.SEVERE))
0242:                        LOG.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
0243:                    fireException(ex);
0244:                    return;
0245:                }
0246:
0247:                // /** Fixed local variables * */
0248:                // AbstractGridCoverage2DReader reader;
0249:                // ImageInputStream inStream;
0250:                // ImageTypeSpecifier its;
0251:                // Iterator it;
0252:                // ImageReader r;
0253:                // double[] res;
0254:                // boolean skipFeature = false;
0255:                // double resX = 0, resY = 0;
0256:                // boolean doneSomething = false;
0257:
0258:                // final File dir = new File(locationPath);
0259:                final List files = new ArrayList(25);
0260:                recurse(files, locationPath);
0261:
0262:                // /////////////////////////////////////////////////////////////////////
0263:                //
0264:                // Cycling over the features
0265:                //
0266:                // /////////////////////////////////////////////////////////////////////
0267:                numFiles = files.size();
0268:                String validFileName = null;
0269:                final Iterator filesIt = files.iterator();
0270:                FeatureWriter fw = null;
0271:                boolean doneSomething = false;
0272:                for (int i = 0; i < numFiles; i++) {
0273:                    final File fileBeingProcessed = ((File) filesIt.next());
0274:                    StringBuffer message;
0275:                    // //
0276:                    //
0277:                    // Anyone has asked us to stop?
0278:                    //
0279:                    // //
0280:                    if (getStopThread()) {
0281:                        message = new StringBuffer(
0282:                                "Stopping requested at file  ").append(i)
0283:                                .append(" of ").append(numFiles).append(
0284:                                        " files");
0285:                        if (LOG.isLoggable(Level.FINE)) {
0286:                            LOG.fine(message.toString());
0287:                        }
0288:                        fireEvent(message.toString(), ((i * 100.0) / numFiles));
0289:                        return;
0290:                    } // replacing chars on input path
0291:                    try {
0292:                        validFileName = fileBeingProcessed.getCanonicalPath();
0293:                    } catch (IOException e1) {
0294:                        fireException(e1);
0295:                        return;
0296:                    }
0297:                    validFileName = validFileName.replace('\\', '/');
0298:                    validFileName = validFileName.substring(locationPath
0299:                            .length() + 1, fileBeingProcessed.getAbsolutePath()
0300:                            .length());
0301:                    if (skipFiles.contains(validFileName))
0302:                        continue;
0303:                    message = new StringBuffer("Now indexing file ")
0304:                            .append(validFileName);
0305:
0306:                    if (LOG.isLoggable(Level.FINE)) {
0307:                        LOG.fine(message.toString());
0308:                    }
0309:                    fireEvent(message.toString(), ((i * 100.0) / numFiles));
0310:                    try {
0311:                        // ////////////////////////////////////////////////////////
0312:                        //
0313:                        //
0314:                        // STEP 1
0315:                        // Getting an ImageIO reader for this coverage.
0316:                        //
0317:                        //
0318:                        // ////////////////////////////////////////////////////////
0319:                        final ImageInputStream inStream = ImageIO
0320:                                .createImageInputStream(fileBeingProcessed);
0321:                        inStream.mark();
0322:                        final Iterator it = ImageIO.getImageReaders(inStream);
0323:
0324:                        ImageReader r = null;
0325:                        if (it.hasNext()) {
0326:                            r = (ImageReader) it.next();
0327:                            r.setInput(inStream);
0328:                        } else {
0329:                            //release resources
0330:                            try {
0331:                                inStream.close();
0332:                            } catch (Exception e) {
0333:                                // ignore exception
0334:                            }
0335:                            try {
0336:                                r.dispose();
0337:                            } catch (Exception e) {
0338:                                // ignore exception
0339:                            }
0340:
0341:                            //send a message
0342:                            message = new StringBuffer("Skipped file ").append(
0343:                                    files.get(i)).append(
0344:                                    ":No ImageIO readeres avalaible.");
0345:                            if (LOG.isLoggable(Level.INFO))
0346:                                LOG.info(message.toString());
0347:                            fireEvent(message.toString(),
0348:                                    ((i * 99.0) / numFiles));
0349:                            continue;
0350:                        }
0351:
0352:                        // ////////////////////////////////////////////////////////
0353:                        //
0354:                        //
0355:                        // STEP 2
0356:                        // Getting a coverage reader for this coverage. Right now we can
0357:                        // index
0358:                        // Geotiff or WorldImage
0359:                        //
0360:                        //
0361:                        // ////////////////////////////////////////////////////////
0362:                        if (LOG.isLoggable(Level.FINE))
0363:                            LOG.fine(new StringBuffer("Getting a reader")
0364:                                    .toString());
0365:                        final AbstractGridFormat format = (AbstractGridFormat) GridFormatFinder
0366:                                .findFormat(files.get(i));
0367:                        if (format == null) {
0368:                            //release resources
0369:                            try {
0370:                                inStream.close();
0371:                            } catch (Exception e) {
0372:                                // ignore exception
0373:                            }
0374:                            try {
0375:                                r.dispose();
0376:                            } catch (Exception e) {
0377:                                // ignore exception
0378:                            }
0379:
0380:                            message = new StringBuffer("Skipped file ").append(
0381:                                    files.get(i)).append(
0382:                                    ": File format is not supported.");
0383:                            if (LOG.isLoggable(Level.INFO))
0384:                                LOG.info(message.toString());
0385:                            fireEvent(message.toString(),
0386:                                    ((i * 99.0) / numFiles));
0387:                            continue;
0388:                        }
0389:                        final AbstractGridCoverage2DReader reader = (AbstractGridCoverage2DReader) format
0390:                                .getReader(files.get(i));
0391:                        envelope = (GeneralEnvelope) reader
0392:                                .getOriginalEnvelope();
0393:                        actualCRS = reader.getCrs();
0394:
0395:                        // /////////////////////////////////////////////////////////////////////
0396:                        //
0397:                        // STEP 3
0398:                        // Get the type specifier for this image and the check that the
0399:                        // image has the correct sample model and color model.
0400:                        // If this is the first cycle of the loop we initialize
0401:                        // eveything.
0402:                        //
0403:                        // /////////////////////////////////////////////////////////////////////
0404:                        final ImageTypeSpecifier its = ((ImageTypeSpecifier) r
0405:                                .getImageTypes(0).next());
0406:                        boolean skipFeature = false;
0407:                        if (globEnvelope == null) {
0408:                            // /////////////////////////////////////////////////////////////////////
0409:                            //
0410:                            // at the first step we initialize everything that we will
0411:                            // reuse afterwards starting with color models, sample
0412:                            // models, crs, etc....
0413:                            //
0414:                            // /////////////////////////////////////////////////////////////////////
0415:                            defaultCM = its.getColorModel();
0416:                            if (defaultCM instanceof  IndexColorModel) {
0417:                                IndexColorModel icm = (IndexColorModel) defaultCM;
0418:                                int numBands = defaultCM
0419:                                        .getNumColorComponents();
0420:                                defaultPalette = new byte[3][icm.getMapSize()];
0421:                                icm.getReds(defaultPalette[0]);
0422:                                icm.getGreens(defaultPalette[0]);
0423:                                icm.getBlues(defaultPalette[0]);
0424:                                if (numBands == 4)
0425:                                    icm.getAlphas(defaultPalette[0]);
0426:
0427:                            }
0428:                            defaultSM = its.getSampleModel();
0429:                            defaultCRS = actualCRS;
0430:                            globEnvelope = new GeneralEnvelope(envelope);
0431:                            // /////////////////////////////////////////////////////////////////////
0432:                            //
0433:                            // getting information about resolution
0434:                            //
0435:                            // /////////////////////////////////////////////////////////////////////
0436:
0437:                            // //
0438:                            //
0439:                            // get the dimension of the hr image and build the model
0440:                            // as well as
0441:                            // computing the resolution
0442:                            // //
0443:                            // resetting reader and recreating stream, turnarounf for a
0444:                            // strange imageio bug
0445:                            r.reset();
0446:                            inStream.reset();
0447:                            r.setInput(inStream);
0448:                            numberOfLevels = r.getNumImages(true);
0449:                            resolutionLevels = new double[2][numberOfLevels];
0450:                            double[] res = getResolution(
0451:                                    envelope,
0452:                                    new Rectangle(r.getWidth(0), r.getHeight(0)),
0453:                                    defaultCRS);
0454:                            resolutionLevels[0][0] = res[0];
0455:                            resolutionLevels[1][0] = res[1];
0456:
0457:                            // resolutions levels
0458:                            if (numberOfLevels > 1) {
0459:
0460:                                for (int k = 0; k < numberOfLevels; k++) {
0461:                                    res = getResolution(envelope,
0462:                                            new Rectangle(r.getWidth(k), r
0463:                                                    .getHeight(k)), defaultCRS);
0464:                                    resolutionLevels[0][k] = res[0];
0465:                                    resolutionLevels[1][k] = res[1];
0466:                                }
0467:                            }
0468:
0469:                            // /////////////////////////////////////////////////////////////////////
0470:                            //
0471:                            // creating the schema
0472:                            //
0473:                            // /////////////////////////////////////////////////////////////////////
0474:                            final GeometricAttributeType refGeom = new GeometricAttributeType(
0475:                                    "the_geom", Polygon.class, true, null,
0476:                                    defaultCRS, null);
0477:                            final TextualAttributeType locationAttribute = new TextualAttributeType(
0478:                                    "location", true, 1, 1, "none", null);
0479:                            final FeatureTypeBuilder builder = FeatureTypeBuilder
0480:                                    .newInstance("index");
0481:                            builder.setDefaultGeometry(refGeom);
0482:                            builder.addType(locationAttribute);
0483:
0484:                            final FeatureType ftType;
0485:                            try {
0486:                                ftType = builder.getFeatureType();
0487:                            } catch (SchemaException e) {
0488:                                if (LOG.isLoggable(Level.SEVERE))
0489:                                    LOG.log(Level.SEVERE, e
0490:                                            .getLocalizedMessage(), e);
0491:                                fireEvent(e.getLocalizedMessage(), 0);
0492:                                return;
0493:                            }
0494:                            // create the schema for the new shape file
0495:                            index.createSchema(ftType);
0496:
0497:                            // get a feature writer
0498:                            fw = index.getFeatureWriter(
0499:                                    index.getTypeNames()[0], t);
0500:                        } else {
0501:                            // ////////////////////////////////////////////////////////
0502:                            // 
0503:                            // comparing ColorModel
0504:                            // comparing SampeModel
0505:                            // comparing CRSs
0506:                            // ////////////////////////////////////////////////////////
0507:                            globEnvelope.add(envelope);
0508:                            actualCM = its.getColorModel();
0509:                            actualSM = its.getSampleModel();
0510:                            skipFeature = (i > 0 ? !(CRS.equalsIgnoreMetadata(
0511:                                    defaultCRS, actualCRS)) : false);
0512:                            if (skipFeature)
0513:                                LOG.warning(new StringBuffer("Skipping image ")
0514:                                        .append(files.get(i)).append(
0515:                                                " because CRSs do not match.")
0516:                                        .toString());
0517:                            skipFeature = checkColorModels(defaultCM,
0518:                                    defaultPalette, actualCM);
0519:                            if (skipFeature)
0520:                                LOG
0521:                                        .warning(new StringBuffer(
0522:                                                "Skipping image ")
0523:                                                .append(files.get(i))
0524:                                                .append(
0525:                                                        " because color models do not match.")
0526:                                                .toString());
0527:                            // defaultCM.getNumComponents()==actualCM.getNumComponents()&&
0528:                            // defaultCM.getClass().equals(actualCM.getClass())
0529:                            // && defaultSM.getNumBands() == actualSM
0530:                            // .getNumBands()
0531:                            // && defaultSM.getDataType() == actualSM
0532:                            // .getDataType() &&
0533:                            //
0534:                            // if (skipFeature)
0535:                            // LOG
0536:                            // .warning(new StringBuffer("Skipping image ")
0537:                            // .append(files.get(i))
0538:                            // .append(
0539:                            // " because cm or sm does not match.")
0540:                            // .toString());
0541:                            // res = getResolution(envelope, new
0542:                            // Rectangle(r.getWidth(0),
0543:                            // r.getHeight(0)), defaultCRS);
0544:                            // if (Math.abs((resX - res[0]) / resX) > EPS
0545:                            // || Math.abs(resY - res[1]) > EPS) {
0546:                            // LOG.warning(new StringBuffer("Skipping image ").append(
0547:                            // files.get(i)).append(
0548:                            // " because resolutions does not match.")
0549:                            // .toString());
0550:                            // skipFeature = true;
0551:                            // }
0552:                        }
0553:
0554:                        // ////////////////////////////////////////////////////////
0555:                        //
0556:                        // STEP 4
0557:                        //
0558:                        // create and store features
0559:                        //
0560:                        // ////////////////////////////////////////////////////////
0561:                        if (!skipFeature) {
0562:
0563:                            final Feature feature = fw.next();
0564:                            feature.setAttribute(0, geomFactory
0565:                                    .toGeometry(new ReferencedEnvelope(
0566:                                            (Envelope) envelope)));
0567:
0568:                            feature.setAttribute(1, validFileName);
0569:                            fw.write();
0570:
0571:                            message = new StringBuffer("Done with file ")
0572:                                    .append(files.get(i));
0573:                            if (LOG.isLoggable(Level.FINE)) {
0574:                                LOG.fine(message.toString());
0575:                            }
0576:                            message.append('\n');
0577:                            fireEvent(message.toString(),
0578:                                    (((i + 1) * 99.0) / numFiles));
0579:                            doneSomething = true;
0580:                        } else
0581:                            skipFeature = false;
0582:
0583:                        // ////////////////////////////////////////////////////////
0584:                        //
0585:                        // STEP 5
0586:                        //
0587:                        // release resources
0588:                        //
0589:                        // ////////////////////////////////////////////////////////
0590:                        try {
0591:                            inStream.close();
0592:                        } catch (Exception e) {
0593:                            // ignore exception
0594:                        }
0595:                        try {
0596:                            r.dispose();
0597:                        } catch (Exception e) {
0598:                            // ignore exception
0599:                        }
0600:                        //release resources
0601:                        reader.dispose();
0602:
0603:                    } catch (IOException e) {
0604:                        fireException(e);
0605:                        break;
0606:                    } catch (ArrayIndexOutOfBoundsException e) {
0607:                        fireException(e);
0608:                        break;
0609:                    } catch (IllegalAttributeException e) {
0610:                        fireException(e);
0611:                        break;
0612:                    }
0613:
0614:                }
0615:                try {
0616:                    if (fw != null)
0617:                        fw.close();
0618:                    t.commit();
0619:                    t.close();
0620:                } catch (IOException e) {
0621:                    LOG.log(Level.SEVERE, e.getLocalizedMessage(), e);
0622:                }
0623:                createPropertiesFiles(globEnvelope, doneSomething);
0624:
0625:            }
0626:
0627:            /**
0628:             * @param globEnvelope
0629:             * @param doneSomething
0630:             */
0631:            private void createPropertiesFiles(GeneralEnvelope globEnvelope,
0632:                    boolean doneSomething) {
0633:                StringBuffer message;
0634:                if (numFiles > 0 && doneSomething) {
0635:                    // /////////////////////////////////////////////////////////////////////
0636:                    //
0637:                    // FINAL STEP
0638:                    //
0639:                    // CREATING GENERAL INFO FILE
0640:                    //
0641:                    // /////////////////////////////////////////////////////////////////////
0642:                    message = new StringBuffer(
0643:                            "Creating final properties file ");
0644:                    if (LOG.isLoggable(Level.FINE)) {
0645:                        LOG.fine(message.toString());
0646:                    }
0647:                    fireEvent(message.toString(), 99.9);
0648:
0649:                    // envelope
0650:                    final Properties properties = new Properties();
0651:                    properties.setProperty("NumFiles", Integer
0652:                            .toString(numFiles));
0653:                    properties
0654:                            .setProperty("Envelope2D", new StringBuffer(Double
0655:                                    .toString(globEnvelope.getMinimum(0)))
0656:                                    .append(",").append(
0657:                                            Double.toString(globEnvelope
0658:                                                    .getMinimum(1)))
0659:                                    .append(" ").append(
0660:                                            Double.toString(globEnvelope
0661:                                                    .getMaximum(0)))
0662:                                    .append(",").append(
0663:                                            Double.toString(globEnvelope
0664:                                                    .getMaximum(1))).toString());
0665:                    properties.setProperty("LevelsNum", Integer
0666:                            .toString(numberOfLevels));
0667:                    final StringBuffer levels = new StringBuffer();
0668:                    for (int k = 0; k < numberOfLevels; k++) {
0669:                        levels
0670:                                .append(Double.toString(resolutionLevels[0][k]))
0671:                                .append(",")
0672:                                .append(Double.toString(resolutionLevels[1][k]));
0673:                        if (k < numberOfLevels - 1)
0674:                            levels.append(" ");
0675:                    }
0676:                    properties.setProperty("Levels", levels.toString());
0677:                    properties.setProperty("Name", indexName);
0678:                    properties.setProperty("ExpandToRGB", Boolean
0679:                            .toString(mustConvertToRGB));
0680:                    try {
0681:                        properties.store(new BufferedOutputStream(
0682:                                new FileOutputStream(locationPath + "/"
0683:                                        + indexName + ".properties")), "");
0684:                    } catch (FileNotFoundException e) {
0685:                        if (LOG.isLoggable(Level.SEVERE))
0686:                            LOG.log(Level.SEVERE, e.getLocalizedMessage(), e);
0687:                        fireEvent(e.getLocalizedMessage(), 0);
0688:                    } catch (IOException e) {
0689:                        if (LOG.isLoggable(Level.SEVERE))
0690:                            LOG.log(Level.SEVERE, e.getLocalizedMessage(), e);
0691:                        fireEvent(e.getLocalizedMessage(), 0);
0692:                    }
0693:
0694:                    // processing information
0695:                    message = new StringBuffer("Done!!!");
0696:                    if (LOG.isLoggable(Level.FINE)) {
0697:                        LOG.fine(message.toString());
0698:                    }
0699:                    fireEvent(message.toString(), 100);
0700:                } else {
0701:                    // processing information
0702:                    message = new StringBuffer("No file to process!!!");
0703:                    if (LOG.isLoggable(Level.FINE)) {
0704:                        LOG.fine(message.toString());
0705:                    }
0706:                    fireEvent(message.toString(), 100);
0707:                }
0708:            }
0709:
0710:            /**
0711:             * This method checks the {@link ColorModel} of the current image with the
0712:             * one of the first image in order to check if they are compatible or not in
0713:             * order to perform a mosaic operation.
0714:             * 
0715:             * <p>
0716:             * It is worth to point out that we also check if, in case we have two index
0717:             * color model image, we also try to suggest whether or not we should do a
0718:             * color expansion.
0719:             * 
0720:             * @param defaultCM
0721:             * @param defaultPalette
0722:             * @param actualCM
0723:             * @return a boolean asking to skip this feature.
0724:             */
0725:            private boolean checkColorModels(ColorModel defaultCM,
0726:                    byte[][] defaultPalette, ColorModel actualCM) {
0727:
0728:                // /////////////////////////////////////////////////////////////////////
0729:                //
0730:                //
0731:                // ComponentColorModel
0732:                //
0733:                //
0734:                // /////////////////////////////////////////////////////////////////////
0735:                if (defaultCM instanceof  ComponentColorModel
0736:                        && actualCM instanceof  ComponentColorModel) {
0737:                    final ComponentColorModel defCCM = (ComponentColorModel) defaultCM, actualCCM = (ComponentColorModel) actualCM;
0738:                    return !(defCCM.getNumColorComponents() == actualCCM
0739:                            .getNumColorComponents()
0740:                            && defCCM.hasAlpha() == actualCCM.hasAlpha()
0741:                            && defCCM.getColorSpace().equals(
0742:                                    actualCCM.getColorSpace())
0743:                            && defCCM.getTransparency() == actualCCM
0744:                                    .getTransparency() && defCCM
0745:                            .getTransferType() == actualCCM.getTransferType());
0746:                }
0747:                // /////////////////////////////////////////////////////////////////////
0748:                //
0749:                //
0750:                // IndexColorModel
0751:                //
0752:                //
0753:                // /////////////////////////////////////////////////////////////////////
0754:                if (defaultCM instanceof  IndexColorModel
0755:                        && actualCM instanceof  IndexColorModel) {
0756:                    final IndexColorModel defICM = (IndexColorModel) defaultCM, actualICM = (IndexColorModel) actualCM;
0757:                    if (defICM.getNumColorComponents() != actualICM
0758:                            .getNumColorComponents()
0759:                            || defICM.hasAlpha() != actualICM.hasAlpha()
0760:                            || !defICM.getColorSpace().equals(
0761:                                    actualICM.getColorSpace())
0762:                            || defICM.getTransferType() != actualICM
0763:                                    .getTransferType())
0764:                        return true;
0765:                    // ///
0766:                    //
0767:                    // Suggesting expansion in the simplest case
0768:                    //
0769:                    // ///
0770:                    if (defICM.getMapSize() != actualICM.getMapSize()
0771:                            || defICM.getTransparency() != actualICM
0772:                                    .getTransparency()
0773:                            || defICM.getTransferType() != actualICM
0774:                                    .getTransferType()
0775:                            || defICM.getTransparentPixel() != actualICM
0776:                                    .getTransparentPixel()) {
0777:                        mustConvertToRGB = true;
0778:                        return false;
0779:                    }
0780:                    // //
0781:                    //
0782:                    // Now checking palettes to see if we need to do a color convert
0783:                    //
0784:                    // //
0785:                    // get the palette for this color model
0786:                    int numBands = actualICM.getNumColorComponents();
0787:                    byte[][] actualPalette = new byte[3][actualICM.getMapSize()];
0788:                    actualICM.getReds(actualPalette[0]);
0789:                    actualICM.getGreens(actualPalette[0]);
0790:                    actualICM.getBlues(actualPalette[0]);
0791:                    if (numBands == 4)
0792:                        actualICM.getAlphas(defaultPalette[0]);
0793:                    // compare them
0794:                    for (int i = 0; i < defICM.getMapSize(); i++)
0795:                        for (int j = 0; j < numBands; j++)
0796:                            if (actualPalette[j][i] != defaultPalette[j][i]) {
0797:                                mustConvertToRGB = true;
0798:                                break;
0799:                            }
0800:                    return false;
0801:
0802:                }
0803:                // //
0804:                //
0805:                // if we get here this means that the two color models where completely
0806:                // different, hence skip this feature.
0807:                //
0808:                // //
0809:                return true;
0810:            }
0811:
0812:            /**
0813:             * Default constructor
0814:             */
0815:            public MosaicIndexBuilder() {
0816:                // /////////////////////////////////////////////////////////////////////
0817:                // Options for the command line
0818:                // /////////////////////////////////////////////////////////////////////
0819:                helpOpt = optionBuilder.withShortName("h").withShortName("?")
0820:                        .withLongName("helpOpt").withDescription(
0821:                                "print this message.").create();
0822:                versionOpt = optionBuilder.withShortName("v").withLongName(
0823:                        "versionOpt").withDescription("print the versionOpt.")
0824:                        .create();
0825:                locationOpt = optionBuilder.withShortName("s").withLongName(
0826:                        "source_directory").withArgument(
0827:                        arguments.withName("source").withMinimum(1)
0828:                                .withMaximum(1).create()).withDescription(
0829:                        "path where files are located").withRequired(true)
0830:                        .create();
0831:                wildcardOpt = optionBuilder.withShortName("w").withLongName(
0832:                        "wildcardOpt").withArgument(
0833:                        arguments.withName("wildcardOpt").withMinimum(0)
0834:                                .withMaximum(1).create()).withDescription(
0835:                        "wildcardOpt to use for selecting files").withRequired(
0836:                        false).create();
0837:
0838:                nameOpt = optionBuilder.withShortName("name").withLongName(
0839:                        "index_name").withArgument(
0840:                        arguments.withName("name").withMinimum(0)
0841:                                .withMaximum(1).create()).withDescription(
0842:                        "name for the index file").withRequired(false).create();
0843:
0844:                priorityOpt = optionBuilder.withShortName("p").withLongName(
0845:                        "thread_priority").withArgument(
0846:                        arguments.withName("priority").withMinimum(0)
0847:                                .withMaximum(1).create()).withDescription(
0848:                        "priority for the underlying thread").withRequired(
0849:                        false).create();
0850:
0851:                cmdOpts.add(helpOpt);
0852:                cmdOpts.add(versionOpt);
0853:                cmdOpts.add(locationOpt);
0854:                cmdOpts.add(wildcardOpt);
0855:                cmdOpts.add(nameOpt);
0856:                cmdOpts.add(priorityOpt);
0857:
0858:                optionsGroup = new GroupImpl(cmdOpts, "Options",
0859:                        "All the options", 1, 10);
0860:
0861:                // /////////////////////////////////////////////////////////////////////
0862:                //
0863:                // Help Formatter
0864:                //
0865:                // /////////////////////////////////////////////////////////////////////
0866:                final HelpFormatter cmdHlp = new HelpFormatter("| ", "  ",
0867:                        " |", 75);
0868:                cmdHlp.setShellCommand("MosaicIndexBuilder");
0869:                cmdHlp.setHeader("Help");
0870:                cmdHlp
0871:                        .setFooter(new StringBuffer(
0872:                                "MosaicIndexBuilder - GeoSolutions S.a.s (C) 2006 - v ")
0873:                                .append(MosaicIndexBuilder.versionNumber)
0874:                                .toString());
0875:                cmdHlp
0876:                        .setDivider("|-------------------------------------------------------------------------|");
0877:
0878:                cmdParser.setGroup(optionsGroup);
0879:                cmdParser.setHelpOption(helpOpt);
0880:                cmdParser.setHelpFormatter(cmdHlp);
0881:            }
0882:
0883:            /**
0884:             * Entry point for the index builder.
0885:             * 
0886:             * @param args
0887:             */
0888:            public static void main(String[] args) {
0889:
0890:                final MosaicIndexBuilder mosaicIndexBuilder = new MosaicIndexBuilder();
0891:                mosaicIndexBuilder
0892:                        .addProcessingEventListener(mosaicIndexBuilder);
0893:                if (mosaicIndexBuilder.parseArgs(args)) {
0894:                    final Thread t = new Thread(mosaicIndexBuilder,
0895:                            "MosaicIndexBuilder");
0896:                    t.setPriority(mosaicIndexBuilder.priority);
0897:                    t.start();
0898:                    try {
0899:                        t.join();
0900:                    } catch (InterruptedException e) {
0901:                        LOG.log(Level.SEVERE, e.getLocalizedMessage(), e);
0902:                    }
0903:
0904:                } else
0905:                    LOG.fine("Exiting...");
0906:
0907:            }
0908:
0909:            private boolean parseArgs(String[] args) {
0910:                cmdLine = cmdParser.parseAndHelp(args);
0911:                if (cmdLine != null && cmdLine.hasOption(versionOpt)) {
0912:                    System.out
0913:                            .print(new StringBuffer(
0914:                                    "MosaicIndexBuilder - GeoSolutions S.a.s (C) 2006 - v")
0915:                                    .append(MosaicIndexBuilder.versionNumber)
0916:                                    .toString());
0917:                    System.exit(1);
0918:
0919:                } else if (cmdLine != null) {
0920:                    // ////////////////////////////////////////////////////////////////
0921:                    //
0922:                    // parsing command line parameters and setting up
0923:                    // Mosaic Index Builder options
0924:                    //
0925:                    // ////////////////////////////////////////////////////////////////
0926:                    locationPath = (String) cmdLine.getValue(locationOpt);
0927:                    final File inDir = new File(locationPath);
0928:                    if (!inDir.isDirectory()) {
0929:                        LOG
0930:                                .severe("Provided input dir does not exist or is not a dir!");
0931:                        return false;
0932:                    }
0933:                    try {
0934:                        locationPath = inDir.getCanonicalPath();
0935:                        locationPath = locationPath.replace('\\', '/');
0936:                    } catch (IOException e) {
0937:                        LOG.log(Level.SEVERE, e.getLocalizedMessage(), e);
0938:                        return false;
0939:                    }
0940:                    // wildcard
0941:                    if (cmdLine.hasOption(wildcardOpt))
0942:                        wildcardString = (String) cmdLine.getValue(wildcardOpt);
0943:
0944:                    // index name
0945:                    if (cmdLine.hasOption(nameOpt))
0946:                        indexName = (String) cmdLine.getValue(nameOpt);
0947:
0948:                    // //
0949:                    //
0950:                    // Thread priority
0951:                    //
0952:                    // //
0953:                    // index name
0954:                    if (cmdLine.hasOption(priorityOpt))
0955:                        priority = Integer.parseInt((String) cmdLine
0956:                                .getValue(priorityOpt));
0957:                    return true;
0958:
0959:                }
0960:                return false;
0961:
0962:            }
0963:
0964:            /**
0965:             * This method is responsible for computing the resolutions in for the
0966:             * provided grid geometry in the provided crs.
0967:             * 
0968:             * <P>
0969:             * It is worth to note that the returned resolution array is of length of 2
0970:             * and it always is lon, lat for the moment.<br>
0971:             * It might be worth to remove the axes reordering code when we are
0972:             * confident enough with the code to handle the north-up crs.
0973:             * <p>
0974:             * TODO use orthodromic distance?
0975:             * 
0976:             * @param envelope
0977:             *            the GeneralEnvelope
0978:             * @param dim
0979:             * @param crs
0980:             * @throws DataSourceException
0981:             */
0982:            protected final double[] getResolution(GeneralEnvelope envelope,
0983:                    Rectangle2D dim, CoordinateReferenceSystem crs)
0984:                    throws DataSourceException {
0985:                double[] requestedRes = null;
0986:                try {
0987:                    if (dim != null && envelope != null) {
0988:                        // do we need to transform the originalEnvelope?
0989:                        final CoordinateReferenceSystem crs2D = CRSUtilities
0990:                                .getCRS2D(envelope
0991:                                        .getCoordinateReferenceSystem());
0992:
0993:                        if (crs != null
0994:                                && !CRS.equalsIgnoreMetadata(crs, crs2D)) {
0995:                            final MathTransform tr = CRS.findMathTransform(
0996:                                    crs2D, crs);
0997:                            if (!tr.isIdentity())
0998:                                envelope = CRS.transform(tr, envelope);
0999:                        }
1000:                        requestedRes = new double[2];
1001:                        requestedRes[0] = envelope.getLength(0)
1002:                                / dim.getWidth();
1003:                        requestedRes[1] = envelope.getLength(1)
1004:                                / dim.getHeight();
1005:                    }
1006:                    return requestedRes;
1007:                } catch (TransformException e) {
1008:                    throw new DataSourceException(
1009:                            "Unable to get the resolution", e);
1010:                } catch (FactoryException e) {
1011:                    throw new DataSourceException(
1012:                            "Unable to get the resolution", e);
1013:                }
1014:            }
1015:
1016:            /**
1017:             * This method is repsonbile for sending the process progress events to the
1018:             * logger.
1019:             * 
1020:             * <p>
1021:             * It should be used to do normal logging when running this tools as command
1022:             * line tools but it should be disable when putting the tool behind a GUI.
1023:             * In such a case the GUI should register itself as a
1024:             * {@link ProcessingEventListener} and consume the processing events.
1025:             * 
1026:             * @param event
1027:             *            is a {@link ProcessingEvent} that informs the receiver on the
1028:             *            precetnage of the progress as well as on what is happening.
1029:             */
1030:            public void getNotification(ProcessingEvent event) {
1031:                LOG.info(new StringBuffer("Progress is at ").append(
1032:                        event.getPercentage()).append("\n").append(
1033:                        "attached message is: ").append(event.getMessage())
1034:                        .toString());
1035:
1036:            }
1037:
1038:            public void exceptionOccurred(ExceptionEvent event) {
1039:                LOG.log(Level.SEVERE, "An error occurred during processing",
1040:                        event.getException());
1041:            }
1042:
1043:            /**
1044:             * @param locationPath
1045:             *            the locationPath to set
1046:             */
1047:            public final void setLocationPath(String locationPath) {
1048:                this .locationPath = locationPath;
1049:                final File inDir = new File(locationPath);
1050:                if (!inDir.isDirectory()) {
1051:                    LOG
1052:                            .severe("Provided input dir does not exist or is not a dir!");
1053:                    throw new IllegalArgumentException(
1054:                            "Provided input dir does not exist or is not a dir!");
1055:                }
1056:                try {
1057:                    locationPath = inDir.getCanonicalPath();
1058:                    locationPath = locationPath.replace('\\', '/');
1059:                } catch (IOException e) {
1060:                    LOG.log(Level.SEVERE, e.getLocalizedMessage(), e);
1061:                    final IllegalArgumentException ex = new IllegalArgumentException();
1062:                    ex.initCause(e);
1063:                    throw ex;
1064:                }
1065:            }
1066:
1067:            /**
1068:             * @param wildcardString
1069:             *            the wildcardString to set
1070:             */
1071:            public final void setWildcardString(String wildcardString) {
1072:                this .wildcardString = wildcardString;
1073:            }
1074:
1075:            public String getIndexName() {
1076:                return indexName;
1077:            }
1078:
1079:            public void setIndexName(String indexName) {
1080:                this .indexName = indexName;
1081:            }
1082:
1083:            public double getResolutionX() {
1084:                return this .resolutionLevels[0][0];
1085:            }
1086:
1087:            public double getResolutionY() {
1088:                return this .resolutionLevels[1][0];
1089:            }
1090:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.