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


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2004-2006, GeoTools Project Managment Committee (PMC)
005:         *    (C) 2004, 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;
010:         *    version 2.1 of the License.
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:         *    This package contains documentation from OpenGIS specifications.
018:         *    OpenGIS consortium's work is fully acknowledged here.
019:         */
020:        package org.geotools.referencing.operation;
021:
022:        // J2SE dependencies
023:        import java.util.ArrayList;
024:        import java.util.Collection;
025:        import java.util.Collections;
026:        import java.util.HashMap;
027:        import java.util.Iterator;
028:        import java.util.LinkedHashSet;
029:        import java.util.List;
030:        import java.util.Map;
031:        import java.util.Set;
032:
033:        // OpenGIS dependencies
034:        import org.opengis.metadata.quality.PositionalAccuracy;
035:        import org.opengis.referencing.FactoryException;
036:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
037:        import org.opengis.referencing.operation.SingleOperation;
038:        import org.opengis.referencing.operation.CoordinateOperation;
039:        import org.opengis.referencing.operation.ConcatenatedOperation;
040:        import org.opengis.referencing.operation.Transformation;
041:        import org.opengis.referencing.operation.MathTransform;
042:        import org.opengis.referencing.operation.MathTransformFactory;
043:
044:        // Geotools dependencies
045:        import org.geotools.referencing.wkt.Formatter;
046:        import org.geotools.referencing.AbstractIdentifiedObject;
047:        import org.geotools.referencing.operation.transform.ConcatenatedTransform;
048:        import org.geotools.resources.Utilities;
049:        import org.geotools.resources.i18n.Errors;
050:        import org.geotools.resources.i18n.ErrorKeys;
051:
052:        /**
053:         * An ordered sequence of two or more single coordinate operations. The sequence of operations is
054:         * constrained by the requirement that the source coordinate reference system of step
055:         * (<var>n</var>+1) must be the same as the target coordinate reference system of step
056:         * (<var>n</var>). The source coordinate reference system of the first step and the target
057:         * coordinate reference system of the last step are the source and target coordinate reference
058:         * system associated with the concatenated operation.
059:         *  
060:         * @since 2.1
061:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/referencing/operation/DefaultConcatenatedOperation.java $
062:         * @version $Id: DefaultConcatenatedOperation.java 28264 2007-12-05 21:53:08Z desruisseaux $
063:         * @author Martin Desruisseaux
064:         */
065:        public class DefaultConcatenatedOperation extends
066:                AbstractCoordinateOperation implements  ConcatenatedOperation {
067:            /**
068:             * Serial number for interoperability with different versions.
069:             */
070:            private static final long serialVersionUID = 4199619838029045700L;
071:
072:            /**
073:             * The sequence of operations.
074:             */
075:            private final List/*<SingleOperation>*/operations;
076:
077:            /**
078:             * Constructs a concatenated operation from the specified name.
079:             *
080:             * @param name The operation name.
081:             * @param operations The sequence of operations.
082:             */
083:            public DefaultConcatenatedOperation(final String name,
084:                    final CoordinateOperation[] operations) {
085:                this (Collections.singletonMap(NAME_KEY, name), operations);
086:            }
087:
088:            /**
089:             * Constructs a concatenated operation from a set of properties.
090:             * The properties given in argument follow the same rules than for the
091:             * {@link AbstractCoordinateOperation} constructor.
092:             *
093:             * @param properties Set of properties. Should contains at least <code>"name"</code>.
094:             * @param operations The sequence of operations.
095:             */
096:            public DefaultConcatenatedOperation(final Map properties,
097:                    final CoordinateOperation[] operations) {
098:                this (properties, new ArrayList(
099:                        operations != null ? operations.length : 4), operations);
100:            }
101:
102:            /**
103:             * Constructs a concatenated operation from a set of properties and a
104:             * {@linkplain MathTransformFactory math transform factory}.
105:             * The properties given in argument follow the same rules than for the
106:             * {@link AbstractCoordinateOperation} constructor.
107:             *
108:             * @param  properties Set of properties. Should contains at least <code>"name"</code>.
109:             * @param  operations The sequence of operations.
110:             * @param  factory    The math transform factory to use for math transforms concatenation.
111:             * @throws FactoryException if the factory can't concatenate the math transforms.
112:             */
113:            public DefaultConcatenatedOperation(final Map properties,
114:                    final CoordinateOperation[] operations,
115:                    final MathTransformFactory factory) throws FactoryException {
116:                this (properties, new ArrayList(
117:                        operations != null ? operations.length : 4),
118:                        operations, factory);
119:            }
120:
121:            /**
122:             * Work around for RFE #4093999 in Sun's bug database
123:             * ("Relax constraint on placement of this()/super() call in constructors").
124:             */
125:            private DefaultConcatenatedOperation(final Map properties,
126:                    final ArrayList list, final CoordinateOperation[] operations) {
127:                this (properties, expand(operations, list), list);
128:            }
129:
130:            /**
131:             * Work around for RFE #4093999 in Sun's bug database
132:             * ("Relax constraint on placement of this()/super() call in constructors").
133:             */
134:            private DefaultConcatenatedOperation(final Map properties,
135:                    final ArrayList list,
136:                    final CoordinateOperation[] operations,
137:                    final MathTransformFactory factory) throws FactoryException {
138:                this (properties, expand(operations, list, factory, true), list);
139:            }
140:
141:            /**
142:             * Work around for RFE #4093999 in Sun's bug database
143:             * ("Relax constraint on placement of this()/super() call in constructors").
144:             */
145:            private DefaultConcatenatedOperation(final Map properties,
146:                    final MathTransform transform,
147:                    final ArrayList/*<SingleOperation>*/operations) {
148:                super (mergeAccuracy(properties, operations),
149:                        ((SingleOperation) operations.get(0)).getSourceCRS(),
150:                        ((SingleOperation) operations
151:                                .get(operations.size() - 1)).getTargetCRS(),
152:                        transform);
153:                operations.trimToSize();
154:                this .operations = Collections.unmodifiableList(operations); // No need to clone.
155:            }
156:
157:            /**
158:             * Work around for RFE #4093999 in Sun's bug database
159:             * ("Relax constraint on placement of this()/super() call in constructors").
160:             */
161:            private static MathTransform expand(
162:                    final CoordinateOperation[] operations, final List list) {
163:                try {
164:                    return expand(operations, list, null, true);
165:                } catch (FactoryException exception) {
166:                    // Should not happen, since we didn't used any MathTransformFactory.
167:                    throw new AssertionError(exception);
168:                }
169:            }
170:
171:            /**
172:             * Transforms the list of operations into a list of single operations. This method
173:             * also check against null value and make sure that all CRS dimension matches.
174:             *
175:             * @param  operations The array of operations to expand.
176:             * @param  list The list in which to add {@code SingleOperation}.
177:             * @param  factory The math transform factory to use, or {@code null}
178:             * @param  wantTransform {@code true} if the concatenated math transform should be computed.
179:             * @return The concatenated math transform.
180:             * @throws FactoryException if the factory can't concatenate the math transforms.
181:             */
182:            private static MathTransform expand(
183:                    final CoordinateOperation[] operations, final List list,
184:                    final MathTransformFactory factory,
185:                    final boolean wantTransform) throws FactoryException {
186:                MathTransform transform = null;
187:                ensureNonNull("operations", operations);
188:                for (int i = 0; i < operations.length; i++) {
189:                    ensureNonNull("operations", operations, i);
190:                    final CoordinateOperation op = operations[i];
191:                    if (op instanceof  SingleOperation) {
192:                        list.add(op);
193:                    } else if (op instanceof  ConcatenatedOperation) {
194:                        final ConcatenatedOperation cop = (ConcatenatedOperation) op;
195:                        final List cops = cop.getOperations();
196:                        expand((CoordinateOperation[]) cops
197:                                .toArray(new CoordinateOperation[cops.size()]),
198:                                list, factory, false);
199:                    } else {
200:                        throw new IllegalArgumentException(Errors.format(
201:                                ErrorKeys.ILLEGAL_CLASS_$2, Utilities
202:                                        .getShortClassName(op), Utilities
203:                                        .getShortName(SingleOperation.class)));
204:                    }
205:                    /*
206:                     * Check the CRS dimensions.
207:                     */
208:                    if (i != 0) {
209:                        final CoordinateReferenceSystem previous = operations[i - 1]
210:                                .getTargetCRS();
211:                        final CoordinateReferenceSystem next = op
212:                                .getSourceCRS();
213:                        if (previous != null && next != null) {
214:                            final int dim1 = previous.getCoordinateSystem()
215:                                    .getDimension();
216:                            final int dim2 = next.getCoordinateSystem()
217:                                    .getDimension();
218:                            if (dim1 != dim2) {
219:                                throw new IllegalArgumentException(
220:                                        Errors
221:                                                .format(
222:                                                        ErrorKeys.MISMATCHED_DIMENSION_$2,
223:                                                        new Integer(dim1),
224:                                                        new Integer(dim2)));
225:                            }
226:                        }
227:                    }
228:                    /*
229:                     * Concatenates the math transform.
230:                     */
231:                    if (wantTransform) {
232:                        final MathTransform step = op.getMathTransform();
233:                        if (transform == null) {
234:                            transform = step;
235:                        } else if (factory != null) {
236:                            transform = factory.createConcatenatedTransform(
237:                                    transform, step);
238:                        } else {
239:                            transform = ConcatenatedTransform.create(transform,
240:                                    step);
241:                        }
242:                    }
243:                }
244:                if (wantTransform) {
245:                    final int size = list.size();
246:                    if (size <= 1) {
247:                        throw new IllegalArgumentException(Errors.format(
248:                                ErrorKeys.MISSING_PARAMETER_$1, "operations["
249:                                        + size + ']'));
250:                    }
251:                }
252:                return transform;
253:            }
254:
255:            /**
256:             * If no accuracy were specified in the given properties map, add all accuracies found in the
257:             * operation to concatenate. This method considers only {@link Transformation} components and
258:             * ignores all conversions. According ISO 19111, the accuracy attribute is allowed only for
259:             * transformations. However, this restriction is not enforced everywhere. The EPSG database
260:             * declares an accuracy of 0 meters for conversions, which is conceptually exact. Ourself we
261:             * are departing from the specification, since we are adding accuracy informations to a
262:             * concatenated operation. This departure should be considered as a convenience feature
263:             * only; accuracies are really relevant in transformations only.
264:             * <p>
265:             * There is also a technical reasons for ignoring conversions. If a concatenated operation
266:             * contains a datum shift (i.e. a transformation) with unknow accuracy, and a projection
267:             * (i.e. a conversion) with a declared 0 meter error, we don't want to declare this 0 meter
268:             * error as the concatenated operation's accuracy; it would be a false information.
269:             * <p>
270:             * Note that a concatenated operation typically contains an arbitrary amount of conversions,
271:             * but only one transformation. So considering transformation only usually means to pickup
272:             * only one operation in the given {@code operations} list.
273:             *
274:             * @todo We should use a Map and merge only one accuracy for each specification.
275:             */
276:            private static Map mergeAccuracy(final Map properties,
277:                    final List/*<CoordinateOperation>*/operations) {
278:                if (!properties.containsKey(COORDINATE_OPERATION_ACCURACY_KEY)) {
279:                    Set accuracy = null;
280:                    for (final Iterator it = operations.iterator(); it
281:                            .hasNext();) {
282:                        final CoordinateOperation op = (CoordinateOperation) it
283:                                .next();
284:                        if (op instanceof  Transformation) {
285:                            // See javadoc for a rational why we take only transformations in account.
286:                            final Collection/*<PositionalAccuracy>*/candidates = op
287:                                    .getPositionalAccuracy();
288:                            if (candidates != null && !candidates.isEmpty()) {
289:                                if (accuracy == null) {
290:                                    accuracy = new LinkedHashSet();
291:                                }
292:                                accuracy.addAll(candidates);
293:                            }
294:                        }
295:                    }
296:                    if (accuracy != null) {
297:                        final Map merged = new HashMap(properties);
298:                        merged
299:                                .put(
300:                                        COORDINATE_OPERATION_ACCURACY_KEY,
301:                                        accuracy
302:                                                .toArray(new PositionalAccuracy[accuracy
303:                                                        .size()]));
304:                        return merged;
305:                    }
306:                }
307:                return properties;
308:            }
309:
310:            /**
311:             * Returns the sequence of operations.
312:             */
313:            public List/*<SingleOperation>*/getOperations() {
314:                return operations;
315:            }
316:
317:            /**
318:             * Compare this concatenated operation with the specified object for equality.
319:             * If {@code compareMetadata} is {@code true}, then all available properties are
320:             * compared including {@linkplain #getValidArea valid area} and {@linkplain #getScope scope}.
321:             *
322:             * @param  object The object to compare to {@code this}.
323:             * @param  compareMetadata {@code true} for performing a strict comparaison, or
324:             *         {@code false} for comparing only properties relevant to transformations.
325:             * @return {@code true} if both objects are equal.
326:             */
327:            public boolean equals(final AbstractIdentifiedObject object,
328:                    final boolean compareMetadata) {
329:                if (object == this ) {
330:                    return true; // Slight optimization.
331:                }
332:                if (super .equals(object, compareMetadata)) {
333:                    final DefaultConcatenatedOperation that = (DefaultConcatenatedOperation) object;
334:                    return equals(this .operations, that.operations,
335:                            compareMetadata);
336:                }
337:                return false;
338:            }
339:
340:            /**
341:             * Returns a hash code value for this concatenated operation.
342:             */
343:            public int hashCode() {
344:                return operations.hashCode() ^ (int) serialVersionUID;
345:            }
346:
347:            /**
348:             * {@inheritDoc}
349:             */
350:            protected String formatWKT(final Formatter formatter) {
351:                final String label = super .formatWKT(formatter);
352:                for (final Iterator it = operations.iterator(); it.hasNext();) {
353:                    formatter.append((CoordinateOperation) it.next());
354:                }
355:                return label;
356:            }
357:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.