Source Code Cross Referenced for DefaultProcessor.java in  » GIS » GeoTools-2.4.1 » org » geotools » coverage » processing » 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 » org.geotools.coverage.processing 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Geotools 2 - OpenSource mapping toolkit
003:         * (C) 2003, Geotools Project Management Committee (PMC)
004:         * (C) 2001, Institut de Recherche pour le Développement
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; either
009:         *    version 2.1 of the License, or (at your option) any later version.
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:         *    You should have received a copy of the GNU Lesser General Public
017:         *    License along with this library; if not, write to the Free Software
018:         *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
019:         */
020:        package org.geotools.coverage.processing;
021:
022:        // J2SE dependencies
023:        import java.awt.RenderingHints;
024:        import java.util.Arrays;
025:        import java.util.Collections;
026:        import java.util.Collection;
027:        import java.util.Comparator;
028:        import java.util.Iterator;
029:        import java.util.List;
030:        import java.util.Map;
031:        import java.util.TreeMap;
032:        import java.util.logging.Level;
033:
034:        // JAI dependencies
035:        import javax.media.jai.Interpolation;
036:        import javax.media.jai.JAI;
037:        import javax.media.jai.TileCache;
038:
039:        // OpenGIS dependencies
040:        import org.opengis.coverage.Coverage;
041:        import org.opengis.coverage.processing.Operation;
042:        import org.opengis.coverage.processing.OperationNotFoundException;
043:        import org.opengis.parameter.GeneralParameterValue;
044:        import org.opengis.parameter.ParameterValue;
045:        import org.opengis.parameter.ParameterValueGroup;
046:
047:        // Geotools dependencies
048:        import org.geotools.coverage.grid.GridCoverage2D;
049:        import org.geotools.coverage.grid.Interpolator2D;
050:        import org.geotools.factory.FactoryRegistry;
051:        import org.geotools.factory.Hints;
052:        import org.geotools.resources.i18n.Errors;
053:        import org.geotools.resources.i18n.ErrorKeys;
054:        import org.geotools.resources.i18n.Logging;
055:        import org.geotools.resources.i18n.LoggingKeys;
056:
057:        /**
058:         * Default implementation of a {@linkplain Coverage coverage} processor.
059:         * This default implementation makes the following assumptions:
060:         * <p>
061:         * <ul>
062:         *   <li>Operations are declared in the
063:         *       {@code META-INF/services/org.opengis.coverage.processing.Operation} file.</li>
064:         *   <li>Operations are actually instances of {@link AbstractOperation} (note: this constraint
065:         *       may be relaxed in a future version after GeoAPI interfaces for grid coverage will be
066:         *       redesigned).</li>
067:         *   <li>Most operations are backed by <cite>Java Advanced Imaging</cite>.</li>
068:         * </ul>
069:         * <p>
070:         * <strong>Note:</strong> This implementation do not caches produced coverages. Since coverages
071:         * may be big, consider wrapping {@code DefaultProcessor} instances in {@link BufferedProcessor}.
072:         *
073:         * @since 2.2
074:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/coverage/src/main/java/org/geotools/coverage/processing/DefaultProcessor.java $
075:         * @version $Id: DefaultProcessor.java 22482 2006-10-31 02:58:00Z desruisseaux $
076:         * @author Martin Desruisseaux
077:         */
078:        public class DefaultProcessor extends AbstractProcessor {
079:            /**
080:             * Augments the amout of memory allocated for the JAI tile cache.
081:             */
082:            static {
083:                final long targetCapacity = 0x4000000; // 64 Mo.
084:                final long maxMemory = Runtime.getRuntime().maxMemory();
085:                final TileCache cache = JAI.getDefaultInstance().getTileCache();
086:                if (maxMemory >= 2 * targetCapacity) {
087:                    if (cache.getMemoryCapacity() < targetCapacity) {
088:                        cache.setMemoryCapacity(targetCapacity);
089:                    }
090:                }
091:                LOGGER.config("Java Advanced Imaging: " + JAI.getBuildVersion()
092:                        + ", TileCache capacity="
093:                        + (float) (cache.getMemoryCapacity() / (1024 * 1024))
094:                        + " Mb");
095:                /*
096:                 * Verifies that the tile cache has some reasonable value. A lot of users seem to
097:                 * misunderstand the memory setting in Java and set wrong values. If the user set
098:                 * a tile cache greater than the maximum heap size, tell him that he is looking
099:                 * for serious trouble.
100:                 */
101:                if (cache.getMemoryCapacity() + (4 * 1024 * 1024) >= maxMemory) {
102:                    LOGGER.log(Logging.format(Level.SEVERE,
103:                            LoggingKeys.EXCESSIVE_TILE_CACHE_$1, new Double(
104:                                    maxMemory / (1024 * 1024.0))));
105:                }
106:            }
107:
108:            /**
109:             * The comparator for ordering operation names.
110:             */
111:            private static final Comparator COMPARATOR = new Comparator() {
112:                public int compare(final Object name1, final Object name2) {
113:                    return ((String) name1).toLowerCase().compareTo(
114:                            ((String) name2).toLowerCase());
115:                }
116:            };
117:
118:            /**
119:             * The set of operations for this coverage processor. Keys are operation's name.
120:             * Values are operations and should not contains duplicated values. Note that while
121:             * keys are {@link String} objects, the operation name are actually case-insensitive
122:             * because of the comparator used in the sorted map.
123:             */
124:            private final Map/*<String,Operation>*/operations = new TreeMap(
125:                    COMPARATOR);
126:
127:            /**
128:             * The rendering hints for JAI operations (never {@code null}).
129:             * This field is usually given as argument to {@link OperationJAI} methods.
130:             */
131:            private final Hints hints;
132:
133:            /**
134:             * The service registry for finding {@link Operation} implementations.
135:             */
136:            private final FactoryRegistry registry;
137:
138:            /**
139:             * Constructs a default coverage processor. The {@link #scanForPlugins} method will be
140:             * automatically invoked the first time an operation is required. Additional operations
141:             * can be added by subclasses with the {@link #addOperation} method. Rendering hints will
142:             * be initialized with the following hints:
143:             * <p>
144:             * <ul>
145:             *   <li>{@link JAI#KEY_REPLACE_INDEX_COLOR_MODEL} set to {@link Boolean#FALSE}.</li>
146:             *   <li>{@link JAI#KEY_TRANSFORM_ON_COLORMAP} set to {@link Boolean#FALSE}.</li>
147:             * </ul>
148:             *
149:             * @param hints A set of additional rendering hints, or {@code null} if none.
150:             */
151:            public DefaultProcessor(final RenderingHints hints) {
152:                registry = new FactoryRegistry(Collections
153:                        .singleton(Operation.class));
154:                this .hints = new Hints(hints);
155:                this .hints
156:                        .put(JAI.KEY_REPLACE_INDEX_COLOR_MODEL, Boolean.FALSE);
157:                this .hints.put(JAI.KEY_TRANSFORM_ON_COLORMAP, Boolean.FALSE);
158:                this .hints.put(Hints.GRID_COVERAGE_PROCESSOR, this ); // Must overwrites user setting.
159:            }
160:
161:            /**
162:             * Sets the GRID_COVERAGE_PROCESSOR hint to the specified value.
163:             * This is used by {@link BufferedProcessor} only.
164:             */
165:            final void setProcessor(final AbstractProcessor processor) {
166:                hints.put(Hints.GRID_COVERAGE_PROCESSOR, processor);
167:            }
168:
169:            /**
170:             * Removes the GRID_COVERAGE_PROCESSOR hint. The {@link AbstractOperation#getProcessor} method
171:             * will automatically returns the default instance when this hint is not defined. Removing this
172:             * hint provides three advantages for the common case when the default processor is used:
173:             *
174:             * <ul>
175:             *   <li>Avoid a strong reference to this processor in {@link RenderedImage} properties.</li>
176:             *   <li>Avoid serialization of this processor when a {@link RenderedImage} is serialized.</li>
177:             *   <li>Allows {@link AbstractOperation#getProcessor} to returns the {@link BufferedProcessor}
178:             *       instance instead of this instance.</li>
179:             * </ul>
180:             */
181:            void setAsDefault() {
182:                hints.remove(Hints.GRID_COVERAGE_PROCESSOR);
183:            }
184:
185:            /**
186:             * Add the specified operation to this processor. This method is usually invoked
187:             * at construction time before this processor is made accessible.
188:             *
189:             * @param  operation The operation to add.
190:             * @throws IllegalStateException if an operation already exists with the same name.
191:             */
192:            protected synchronized void addOperation(final Operation operation)
193:                    throws IllegalStateException {
194:                ensureNonNull("operation", operation);
195:                if (operations.isEmpty()) {
196:                    scanForPlugins();
197:                }
198:                addOperation0(operation);
199:            }
200:
201:            /**
202:             * Implementation of {@link #addOperation} method. Also used by {@link #scanForPlugins}
203:             * instead of the public method in order to avoid never-ending loop.
204:             */
205:            private void addOperation0(final Operation operation)
206:                    throws IllegalStateException {
207:                final String name = operation.getName().trim();
208:                final Operation old = (Operation) operations.put(name,
209:                        operation);
210:                if (old != null && !old.equals(operation)) {
211:                    operations.put(old.getName().trim(), old);
212:                    throw new IllegalStateException(Errors.getResources(
213:                            getLocale()).getString(
214:                            ErrorKeys.OPERATION_ALREADY_BOUND_$1,
215:                            operation.getName()));
216:                }
217:            }
218:
219:            /**
220:             * Retrieves grid processing operations information. Each operation information contains
221:             * the name of the operation as well as a list of its parameters.
222:             */
223:            public synchronized Collection/*<Operation>*/getOperations() {
224:                if (operations.isEmpty()) {
225:                    scanForPlugins();
226:                }
227:                return operations.values();
228:            }
229:
230:            /**
231:             * Returns the operation for the specified name.
232:             *
233:             * @param  name Name of the operation (case insensitive).
234:             * @return The operation for the given name.
235:             * @throws OperationNotFoundException if there is no operation for the specified name.
236:             */
237:            public synchronized Operation getOperation(String name)
238:                    throws OperationNotFoundException {
239:                ensureNonNull("name", name);
240:                name = name.trim();
241:                if (operations.isEmpty()) {
242:                    scanForPlugins();
243:                }
244:                final Operation operation = (Operation) operations.get(name);
245:                if (operation != null) {
246:                    return operation;
247:                }
248:                throw new OperationNotFoundException(Errors.getResources(
249:                        getLocale()).getString(
250:                        ErrorKeys.OPERATION_NOT_FOUND_$1, name));
251:            }
252:
253:            /**
254:             * Returns a rendering hint.
255:             *
256:             * @param  key The hint key (e.g. {@link Hints#JAI_INSTANCE}).
257:             * @return The hint value for the specified key, or {@code null} if there is no hint for the
258:             *         specified key.
259:             */
260:            public final Object getRenderingHint(final RenderingHints.Key key) {
261:                return hints.get(key);
262:            }
263:
264:            /**
265:             * Applies a process operation to a coverage. The default implementation checks if source
266:             * coverages use an interpolation, and then invokes {@link AbstractOperation#doOperation}.
267:             * If all source coverages used the same interpolation, then this interpolation is applied
268:             * to the resulting coverage (except if the resulting coverage has already an interpolation).
269:             *
270:             * @param  parameters Parameters required for the operation. The easiest way to construct them
271:             *         is to invoke <code>operation.{@link Operation#getParameters getParameters}()</code>
272:             *         and to modify the returned group.
273:             * @return The result as a coverage.
274:             * @throws OperationNotFoundException if there is no operation for the parameter group name.
275:             */
276:            public synchronized Coverage doOperation(
277:                    final ParameterValueGroup parameters)
278:                    throws OperationNotFoundException {
279:                Coverage source = getPrimarySource(parameters);
280:                final String operationName = getOperationName(parameters);
281:                final Operation operation = getOperation(operationName);
282:                /*
283:                 * Detects the interpolation type for the source grid coverage.
284:                 * The same interpolation will be applied on the result.
285:                 */
286:                Interpolation[] interpolations = null;
287:                if (!operationName.equalsIgnoreCase("Interpolate")) {
288:                    for (final Iterator it = parameters.values().iterator(); it
289:                            .hasNext();) {
290:                        final GeneralParameterValue param = (GeneralParameterValue) it
291:                                .next();
292:                        if (param instanceof  ParameterValue) {
293:                            final Object value = ((ParameterValue) param)
294:                                    .getValue();
295:                            if (value instanceof  Interpolator2D) {
296:                                // If all sources use the same interpolation, preserves the
297:                                // interpolation for the resulting coverage. Otherwise, uses
298:                                // the default interpolation (nearest neighbor).
299:                                final Interpolation[] interp = ((Interpolator2D) value)
300:                                        .getInterpolations();
301:                                if (interpolations == null) {
302:                                    interpolations = interp;
303:                                } else if (!Arrays.equals(interpolations,
304:                                        interp)) {
305:                                    // Set to no interpolation.
306:                                    interpolations = null;
307:                                    break;
308:                                }
309:                            }
310:                        }
311:                    }
312:                }
313:                /*
314:                 * Applies the operation, applies the same interpolation and log a message.
315:                 * Note: we don't use "if (operation instanceof AbstractOperation)" below
316:                 *       because if it is not, we want the ClassCastException as the cause
317:                 *       for the failure.
318:                 */
319:                final AbstractOperation op;
320:                try {
321:                    op = (AbstractOperation) operation;
322:                } catch (ClassCastException cause) {
323:                    final OperationNotFoundException exception = new OperationNotFoundException(
324:                            Errors.getResources(getLocale()).getString(
325:                                    ErrorKeys.OPERATION_NOT_FOUND_$1,
326:                                    operationName));
327:                    exception.initCause(cause);
328:                    throw exception;
329:                }
330:                Coverage coverage = op.doOperation(parameters, hints);
331:                if (interpolations != null
332:                        && (coverage instanceof  GridCoverage2D)
333:                        && !(coverage instanceof  Interpolator2D)) {
334:                    coverage = Interpolator2D.create((GridCoverage2D) coverage,
335:                            interpolations);
336:                }
337:                log(source, coverage, operationName, false);
338:                return coverage;
339:            }
340:
341:            /**
342:             * Scans for factory plug-ins on the application class path. This method is needed because the
343:             * application class path can theoretically change, or additional plug-ins may become available.
344:             * Rather than re-scanning the classpath on every invocation of the API, the class path is
345:             * scanned automatically only on the first invocation. Clients can call this method to prompt
346:             * a re-scan. Thus this method need only be invoked by sophisticated applications which
347:             * dynamically make new plug-ins available at runtime.
348:             */
349:            public synchronized void scanForPlugins() {
350:                for (final Iterator it = registry
351:                        .getServiceProviders(Operation.class); it.hasNext();) {
352:                    final Operation operation = (Operation) it.next();
353:                    final String name = operation.getName().trim();
354:                    if (!operations.containsKey(name)) {
355:                        addOperation0(operation);
356:                    }
357:                }
358:            }
359:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.