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


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2003-2006, Geotools Project Managment Committee (PMC)
005:         *    (C) 2001, Institut de Recherche pour le Développement
006:         *
007:         *    This library is free software; you can redistribute it and/or
008:         *    modify it under the terms of the GNU Lesser General Public
009:         *    License as published by the Free Software Foundation; either
010:         *    version 2.1 of the License, or (at your option) any later version.
011:         *
012:         *    This library is distributed in the hope that it will be useful,
013:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015:         *    Lesser General Public License for more details.
016:         */
017:        package org.geotools.resources.coverage;
018:
019:        import java.awt.RenderingHints;
020:        import java.awt.image.ColorModel;
021:        import java.awt.image.IndexColorModel;
022:        import java.awt.image.RenderedImage;
023:        import java.util.Collection;
024:        import java.util.Iterator;
025:        import java.util.List;
026:
027:        import javax.media.jai.Interpolation;
028:        import javax.media.jai.InterpolationBilinear;
029:        import javax.media.jai.InterpolationNearest;
030:        import javax.media.jai.PropertySource;
031:
032:        import org.opengis.coverage.SampleDimension;
033:        import org.opengis.coverage.grid.GridCoverage;
034:        import org.opengis.referencing.operation.MathTransform1D;
035:        import org.opengis.referencing.operation.TransformException;
036:
037:        import org.geotools.coverage.Category;
038:        import org.geotools.coverage.GridSampleDimension;
039:        import org.geotools.coverage.grid.GridCoverage2D;
040:        import org.geotools.coverage.grid.RenderedCoverage;
041:        import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
042:        import org.geotools.factory.Hints;
043:        import org.geotools.feature.FeatureCollection;
044:        import org.geotools.feature.IllegalAttributeException;
045:        import org.geotools.feature.SchemaException;
046:        import org.geotools.util.NumberRange;
047:
048:        /**
049:         * A set of utilities methods for the Grid Coverage package. Those methods are not really
050:         * rigorous; must of them should be seen as temporary implementations.
051:         *
052:         * @since 2.4
053:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/coverage/src/main/java/org/geotools/resources/coverage/CoverageUtilities.java $
054:         * @version $Id: CoverageUtilities.java 25447 2007-05-06 16:56:19Z desruisseaux $
055:         * @author Martin Desruisseaux
056:         * @author Simone Giannecchini
057:         */
058:        public class CoverageUtilities {
059:            /**
060:             * Controlling datum shift process.
061:             *
062:             * @deprecated Will be deleted.
063:             */
064:            public final static Hints LENIENT_HINT = new Hints(
065:                    Hints.LENIENT_DATUM_SHIFT, Boolean.TRUE);
066:
067:            /**
068:             * Do not allows instantiation of this class.
069:             *
070:             * @deprecated We will make this constructor private after we deleted
071:             *             the deprecated subclass, and make this class final.
072:             */
073:            protected CoverageUtilities() {
074:            }
075:
076:            /**
077:             * Retrieves a best guess for the sample value to use for background,
078:             * inspecting the categories of the provided {@link GridCoverage2D}.
079:             * 
080:             * @param coverage to use for guessing background values.
081:             * @return an array of double values to use as a background.
082:             */
083:            public static double[] getBackgroundValues(GridCoverage2D coverage) {
084:                /*
085:                 * Get the sample value to use for background. We will try to fetch this
086:                 * value from one of "no data" categories. For geophysics images, it is
087:                 * usually NaN. For non-geophysics images, it is usually 0.
088:                 */
089:                final GridSampleDimension[] sampleDimensions = coverage
090:                        .getSampleDimensions();
091:                final double[] background = new double[sampleDimensions.length];
092:                for (int i = 0; i < background.length; i++) {
093:                    final NumberRange range = sampleDimensions[i]
094:                            .getBackground().getRange();
095:                    final double min = range.getMinimum();
096:                    final double max = range.getMaximum();
097:                    if (range.isMinIncluded()) {
098:                        background[i] = min;
099:                    } else if (range.isMaxIncluded()) {
100:                        background[i] = max;
101:                    } else {
102:                        background[i] = 0.5 * (min + max);
103:                    }
104:                }
105:                return background;
106:            }
107:
108:            /**
109:             * Returns {@code true} if at least one of the specified sample dimensions has a
110:             * {@linkplain SampleDimension#getSampleToGeophysics sample to geophysics} transform
111:             * which is not the identity transform.
112:             */
113:            public static boolean hasTransform(
114:                    final SampleDimension[] sampleDimensions) {
115:                for (int i = sampleDimensions.length; --i >= 0;) {
116:                    SampleDimension sd = sampleDimensions[i];
117:                    if (sd instanceof  GridSampleDimension) {
118:                        sd = ((GridSampleDimension) sd).geophysics(false);
119:                    }
120:                    MathTransform1D tr = sd.getSampleToGeophysics();
121:                    return tr != null && !tr.isIdentity();
122:                }
123:                return false;
124:            }
125:
126:            /**
127:             * Returns {@code true} if the specified grid coverage or any of its source
128:             * uses the following image.
129:             */
130:            public static boolean uses(final GridCoverage coverage,
131:                    final RenderedImage image) {
132:                if (coverage != null) {
133:                    if (coverage instanceof  RenderedCoverage) {
134:                        if (((RenderedCoverage) coverage).getRenderedImage() == image) {
135:                            return true;
136:                        }
137:                    }
138:                    final Collection sources = coverage.getSources();
139:                    if (sources != null) {
140:                        for (final Iterator it = sources.iterator(); it
141:                                .hasNext();) {
142:                            if (uses((GridCoverage) it.next(), image)) {
143:                                return true;
144:                            }
145:                        }
146:                    }
147:                }
148:                return false;
149:            }
150:
151:            /**
152:             * Returns the visible band in the specified {@link RenderedImage} or {@link PropertySource}.
153:             * This method fetch the {@code "GC_VisibleBand"} property. If this property is undefined,
154:             * then the visible band default to the first one.
155:             *
156:             * @param  image The image for which to fetch the visible band, or {@code null}.
157:             * @return The visible band.
158:             */
159:            public static int getVisibleBand(final Object image) {
160:                Object candidate = null;
161:                if (image instanceof  RenderedImage) {
162:                    candidate = ((RenderedImage) image)
163:                            .getProperty("GC_VisibleBand");
164:                } else if (image instanceof  PropertySource) {
165:                    candidate = ((PropertySource) image)
166:                            .getProperty("GC_VisibleBand");
167:                }
168:                if (candidate instanceof  Integer) {
169:                    return ((Integer) candidate).intValue();
170:                }
171:                return 0;
172:            }
173:
174:            /**
175:             * General purpose method used in various operations for {@link GridCoverage2D} to help
176:             * with taking decisions on how to treat coverages with respect to their {@link ColorModel}.
177:             *
178:             * <p>
179:             * The need for this method arose in consideration of the fact that applying most operations
180:             * on coverage whose {@link ColorModel} is an instance of {@link IndexColorModel} may lead to
181:             * unpredictable results depending on the applied {@link Interpolation} (think about applying
182:             * "Scale" with {@link InterpolationBilinear} on a non-geophysics {@link GridCoverage2D} with an
183:             * {@link IndexColorModel}) or more simply on the operation itself ("SubsampleAverage" cannot
184:             * be applied at all on a {@link GridCoverage2D} backed by an {@link IndexColorModel}).
185:             *
186:             * <p>
187:             * This method suggests the actions to take depending on the structure of the provided
188:             * {@link GridCoverage2D}, the provided {@link Interpolation} and if the operation uses
189:             * a filter or not (this is useful for operations like SubsampleAverage or FilteredSubsample).
190:             *
191:             * <p>
192:             * In general the idea is as follows: If the original coverage is backed by a
193:             * {@link RenderedImage} with an {@link IndexColorModel}, we have the following cases:
194:             *
195:             * <ul>
196:             *  <li>if the interpolation is {@link InterpolationNearest} and there is no filter involved
197:             *      we can apply the operation on the {@link IndexColorModel}-backed coverage with nor
198:             *      probs.</li>
199:             *  <li>If the interpolations in of higher order or there is a filter to apply we have to
200:             *      options:
201:             *      <ul>
202:             *        <li>If the coverage has a twin geophysics view we need to go back to it and apply
203:             *            the operation there.</li>
204:             *        <li>If the coverage has no geophysics view (an orthophoto with an intrisic
205:             *            {@link IndexColorModel} view) we need to perform an RGB(A) color expansion
206:             *            before applying the operation.</li>
207:             *      </ul>
208:             *  </li>
209:             * </ul>
210:             *
211:             * <p>
212:             * A special case is when we want to apply an operation on the geophysics view of a coverage that
213:             * does not involve high order interpolation of filters. In this case we suggest to apply the
214:             * operation on the non-geophysics view, which is usually much faster. Users may ignore this
215:             * advice.
216:             *
217:             * @param coverage to check for the action to take.
218:             * @param interpolation to use for the action to take.
219:             * @param hasFilter if the operation we will apply is going to use a filter.
220:             * @param hints to use when applying a certain operation.
221:             * @return 0 if nothing has to be done on the provided coverage, 1 if a color expansion has to be
222:             *         provided, 2 if we need to employ the geophysics vew of the provided coverage,
223:             *         3 if we suggest to  employ the non-geophysics vew of the provided coverage.
224:             *
225:             * @since 2.3.1
226:             *
227:             * @todo Consider refactoring this method into {@link org.geotools.coverage.grid.ViewType},
228:             *       or in some utility class related to it.
229:             */
230:            public static int prepareSourcesForGCOperation(
231:                    final GridCoverage2D coverage,
232:                    final Interpolation interpolation, final boolean hasFilter,
233:                    final RenderingHints hints) {
234:                final RenderedImage sourceImage = coverage.getRenderedImage();
235:                boolean useNonGeoView = false;
236:                if (hints != null) {
237:                    // REPLACE_NON_GEOPHYSICS_VIEW default value is 'true'.
238:                    // useNonGeoView value is the opposite of REPLACE_NON_GEOPHYSICS_VIEW.
239:                    useNonGeoView = Boolean.FALSE.equals(hints
240:                            .get(Hints.REPLACE_NON_GEOPHYSICS_VIEW));
241:                }
242:                // the color model is indexed?
243:                final boolean isIndexColorModel = sourceImage.getColorModel() instanceof  IndexColorModel;
244:                if (!isIndexColorModel) {
245:                    return 0;// optimization
246:                }
247:                final boolean isNearestNeigborInterpolation = interpolation instanceof  InterpolationNearest;
248:                // /////////////////////////////////////////////////////////////////////
249:                //
250:                // The projection are usually applied on floating-point values, in order
251:                // to gets maximal precision and to handle correctly the special case of
252:                // NaN values. However, we can apply the projection on integer values if
253:                // the interpolation type is "nearest neighbor", since this is not
254:                // really an interpolation.
255:                //
256:                // If this condition is met, then we verify if an "integer version" of
257:                // the image is available as a source of the source coverage (i.e. the
258:                // floating-point image is derived from the integer image, not the
259:                // converse).
260:                //
261:                // /////////////////////////////////////////////////////////////////////
262:                if (isNearestNeigborInterpolation && !hasFilter) {
263:                    final GridCoverage2D candidate = coverage.geophysics(false);
264:                    if (candidate != coverage) {
265:                        final List sources = coverage.getRenderedImage()
266:                                .getSources();
267:                        if (sources != null) {
268:                            if (sources.contains(candidate.getRenderedImage())) {
269:                                return 3;
270:                            }
271:                        }
272:                    }
273:                }
274:
275:                // /////////////////////////////////////////////////////////////////////
276:                //
277:                // Do we need to explode the Palette to RGB(A)? This is needed only when
278:                // we have a coverage that has a geoophysiscs view which has itself
279:                // an IndexColorModel and we want to perform an operation that involves
280:                // an higher order interpolation or a filter (like with
281:                // SubsampleAverage).
282:                //
283:                // /////////////////////////////////////////////////////////////////////
284:                // do we have transforms?
285:                final boolean hasRenderingCategories = hasRenderingCategories(coverage);
286:                final boolean preprocessIndexed = isIndexColorModel
287:                        && (!isNearestNeigborInterpolation || hasFilter);
288:                final boolean getGeophysics = !useNonGeoView
289:                        && (hasRenderingCategories && preprocessIndexed);
290:                // this coverage is a real image with index color model, hence we need
291:                // to apply this operation on the expanded model.
292:                if (preprocessIndexed) {
293:                    if (!getGeophysics) {
294:                        return 1;
295:                    } else if (getGeophysics) {
296:                        // in this case we need to go back the geophysics view of the
297:                        // source coverage
298:                        return 2;
299:                    }
300:                }
301:                return 0;
302:            }
303:
304:            /**
305:             * Returns {@code true} if the provided {@link GridCoverage}
306:             * has {@link Category} objects twith a real transformation.
307:             *
308:             * <p>
309:             * Common use case for this method is understanding if a
310:             * {@link GridCoverage} has an accompanying Gephysiscs or non-Geophysics
311:             * view, which means a dicotomy between the coverage with the "real" data
312:             * and the coverage with the rendered version of the original data exists.
313:             * An example is when you have raw data whose data type is float and you
314:             * want to render them using a palette. You usually do this by specifying a
315:             * set of {@link Category} object which will map some intervals of the raw
316:             * data to some specific colors. The rendered version that we will create
317:             * using the method {@link GridCoverage2D#geophysics(false)} will be backed
318:             * by a RenderedImage with an IndexColorModel representing the colors
319:             * provided in the Categories.
320:             *
321:             * @param gridCoverage
322:             *            to check for the existence of categories with tranformations
323:             *            between original data and their rendered counterpart.
324:             * @return {@code false} if this coverage has only a single view associated with it,
325:             *         {@code true} otherwise.
326:             */
327:            public static boolean hasRenderingCategories(
328:                    final GridCoverage gridCoverage) {
329:                // getting all the SampleDimensions of this coverage, if any exist
330:                final int numSampleDimensions = gridCoverage
331:                        .getNumSampleDimensions();
332:                if (numSampleDimensions == 0) {
333:                    return false;
334:                }
335:                final SampleDimension[] sampleDimensions = new SampleDimension[numSampleDimensions];
336:                for (int i = 0; i < numSampleDimensions; i++) {
337:                    sampleDimensions[i] = gridCoverage.getSampleDimension(i);
338:                }
339:                // do they have any transformation that is not the identity?
340:                return hasTransform(sampleDimensions);
341:            }
342:
343:            /**
344:             * Wraps a grid coverage into a Feature. Code lifted from ArcGridDataSource
345:             * (temporary).
346:             *
347:             * @deprecated Moved to {@link FeatureUtilities#wrapGridCoverage}.
348:             */
349:            public static FeatureCollection wrapGc(final GridCoverage coverage)
350:                    throws TransformException, SchemaException,
351:                    IllegalAttributeException {
352:                return FeatureUtilities
353:                        .wrapGridCoverage((GridCoverage2D) coverage);
354:            }
355:
356:            /**
357:             * Wraps a grid coverage into a Feature. Code lifted from ArcGridDataSource
358:             * (temporary).
359:             * 
360:             * @param gridCoverageReader the grid coverage 
361:             * @return a feature with the grid coverage envelope as the geometry and the
362:             *         grid coverage itself in the "grid" attribute
363:             *
364:             * @deprecated Moved to {@link FeatureUtilities#wrapGridCoverageReader}.
365:             */
366:            public static FeatureCollection wrapGcReader(
367:                    AbstractGridCoverage2DReader reader)
368:                    throws TransformException, SchemaException,
369:                    IllegalAttributeException {
370:                return FeatureUtilities.wrapGridCoverageReader(reader);
371:            }
372:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.