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


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *   
005:         *   (C) 2003-2006, Geotools Project Managment Committee (PMC)
006:         *   (C) 2001, Institut de Recherche pour le Développement
007:         *
008:         *    This library is free software; you can redistribute it and/or
009:         *    modify it under the terms of the GNU Lesser General Public
010:         *    License as published by the Free Software Foundation; either
011:         *    version 2.1 of the License, or (at your option) any later version.
012:         *
013:         *    This library is distributed in the hope that it will be useful,
014:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
015:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
016:         *    Lesser General Public License for more details.
017:         */
018:        package org.geotools.referencing.operation.transform;
019:
020:        // J2SE dependencies
021:        import java.io.Serializable;
022:
023:        // OpenGIS dependencies
024:        import org.opengis.referencing.operation.MathTransform;
025:        import org.opengis.referencing.operation.Matrix;
026:        import org.opengis.referencing.operation.NoninvertibleTransformException;
027:        import org.opengis.referencing.operation.TransformException;
028:        import org.opengis.geometry.DirectPosition;
029:        import org.opengis.geometry.MismatchedDimensionException;
030:
031:        // Geotools dependencies
032:        import org.geotools.geometry.GeneralDirectPosition;
033:        import org.geotools.referencing.operation.LinearTransform;
034:        import org.geotools.referencing.operation.matrix.GeneralMatrix;
035:        import org.geotools.referencing.wkt.Formatter;
036:        import org.geotools.resources.Utilities;
037:        import org.geotools.resources.i18n.ErrorKeys;
038:        import org.geotools.resources.i18n.Errors;
039:
040:        /**
041:         * Transform which passes through a subset of ordinates to another transform.
042:         * This allows transforms to operate on a subset of ordinates.  For example,
043:         * if you have (<var>latitude</var>,<var>longitude</var>,<var>height</var>)
044:         * coordinates, then you may wish to convert the height values from feet to
045:         * meters without affecting the latitude and longitude values.
046:         *
047:         * @since 2.0
048:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/PassThroughTransform.java $
049:         * @version $Id: PassThroughTransform.java 24925 2007-03-27 20:12:08Z jgarnett $
050:         * @author Martin Desruisseaux
051:         *
052:         * @see DimensionFilter
053:         */
054:        public class PassThroughTransform extends AbstractMathTransform
055:                implements  Serializable {
056:            /**
057:             * Serial number for interoperability with different versions.
058:             */
059:            private static final long serialVersionUID = -1673997634240223449L;
060:
061:            /**
062:             * Index of the first affected ordinate.
063:             */
064:            protected final int firstAffectedOrdinate;
065:
066:            /**
067:             * Number of unaffected ordinates after the affected ones.
068:             * Always 0 when used through the strict OpenGIS API.
069:             */
070:            protected final int numTrailingOrdinates;
071:
072:            /**
073:             * The sub transform.
074:             *
075:             * @see #getSubTransform
076:             */
077:            protected final MathTransform subTransform;
078:
079:            /**
080:             * The inverse transform. This field will be computed only when needed.
081:             * But it is serialized in order to avoid rounding error.
082:             */
083:            private PassThroughTransform inverse;
084:
085:            /**
086:             * Create a pass through transform.
087:             *
088:             * @param firstAffectedOrdinate Index of the first affected ordinate.
089:             * @param subTransform The sub transform.
090:             * @param numTrailingOrdinates Number of trailing ordinates to pass through.
091:             *        Affected ordinates will range from {@code firstAffectedOrdinate}
092:             *        inclusive to {@code dimTarget-numTrailingOrdinates} exclusive.
093:             */
094:            protected PassThroughTransform(final int firstAffectedOrdinate,
095:                    final MathTransform subTransform,
096:                    final int numTrailingOrdinates) {
097:                if (firstAffectedOrdinate < 0) {
098:                    throw new IllegalArgumentException(Errors.format(
099:                            ErrorKeys.ILLEGAL_ARGUMENT_$2,
100:                            "firstAffectedOrdinate", new Integer(
101:                                    firstAffectedOrdinate)));
102:                }
103:                if (numTrailingOrdinates < 0) {
104:                    throw new IllegalArgumentException(Errors.format(
105:                            ErrorKeys.ILLEGAL_ARGUMENT_$2,
106:                            "numTrailingOrdinates", new Integer(
107:                                    numTrailingOrdinates)));
108:                }
109:                if (subTransform instanceof  PassThroughTransform) {
110:                    final PassThroughTransform passThrough = (PassThroughTransform) subTransform;
111:                    this .firstAffectedOrdinate = passThrough.firstAffectedOrdinate
112:                            + firstAffectedOrdinate;
113:                    this .numTrailingOrdinates = passThrough.numTrailingOrdinates
114:                            + numTrailingOrdinates;
115:                    this .subTransform = passThrough.subTransform;
116:                } else {
117:                    this .firstAffectedOrdinate = firstAffectedOrdinate;
118:                    this .numTrailingOrdinates = numTrailingOrdinates;
119:                    this .subTransform = subTransform;
120:                }
121:            }
122:
123:            /**
124:             * Creates a transform which passes through a subset of ordinates to another transform.
125:             * This allows transforms to operate on a subset of ordinates. For example, if you have
126:             * (<var>latitidue</var>,<var>longitude</var>,<var>height</var>) coordinates, then you
127:             * may wish to convert the height values from feet to meters without affecting the
128:             * latitude and longitude values.
129:             *
130:             * @param  firstAffectedOrdinate Index of the first affected ordinate.
131:             * @param  subTransform The sub transform.
132:             * @param  numTrailingOrdinates Number of trailing ordinates to pass through.
133:             *         Affected ordinates will range from {@code firstAffectedOrdinate}
134:             *         inclusive to {@code dimTarget-numTrailingOrdinates} exclusive.
135:             * @return A pass through transform with the following dimensions:<br>
136:             *         <pre>
137:             * Source: firstAffectedOrdinate + subTransform.getSourceDimensions() + numTrailingOrdinates
138:             * Target: firstAffectedOrdinate + subTransform.getTargetDimensions() + numTrailingOrdinates</pre>
139:             */
140:            public static MathTransform create(final int firstAffectedOrdinate,
141:                    final MathTransform subTransform,
142:                    final int numTrailingOrdinates) {
143:                if (firstAffectedOrdinate < 0) {
144:                    throw new IllegalArgumentException(Errors.format(
145:                            ErrorKeys.ILLEGAL_ARGUMENT_$2,
146:                            "firstAffectedOrdinate", new Integer(
147:                                    firstAffectedOrdinate)));
148:                }
149:                if (numTrailingOrdinates < 0) {
150:                    throw new IllegalArgumentException(Errors.format(
151:                            ErrorKeys.ILLEGAL_ARGUMENT_$2,
152:                            "numTrailingOrdinates", new Integer(
153:                                    numTrailingOrdinates)));
154:                }
155:                if (firstAffectedOrdinate == 0 && numTrailingOrdinates == 0) {
156:                    return subTransform;
157:                }
158:                /*
159:                 * Optimize the "Identity transform" case.
160:                 */
161:                if (subTransform.isIdentity()) {
162:                    final int dimension = subTransform.getSourceDimensions();
163:                    if (dimension == subTransform.getTargetDimensions()) {
164:                        return IdentityTransform.create(firstAffectedOrdinate
165:                                + dimension + numTrailingOrdinates);
166:                    }
167:                }
168:                /*
169:                 * Special case for transformation backed by a matrix. Is is possible to use a
170:                 * new matrix for such transform, instead of wrapping the sub-transform into a
171:                 * PassThroughTransform object. It is faster and easier to concatenate.
172:                 */
173:                if (subTransform instanceof  LinearTransform) {
174:                    GeneralMatrix matrix = toGMatrix(((LinearTransform) subTransform)
175:                            .getMatrix());
176:                    matrix = PassThroughTransform.expand(matrix,
177:                            firstAffectedOrdinate, numTrailingOrdinates, 1);
178:                    return ProjectiveTransform.create(matrix);
179:                }
180:                /*
181:                 * Constructs the general PassThroughTransform object. An optimisation
182:                 * for the "Pass through case" is done right in the  constructor.
183:                 */
184:                return new PassThroughTransform(firstAffectedOrdinate,
185:                        subTransform, numTrailingOrdinates);
186:            }
187:
188:            /**
189:             * Returns the sub transform.
190:             *
191:             * @since 2.2
192:             */
193:            public MathTransform getSubTransform() {
194:                return subTransform;
195:            }
196:
197:            /**
198:             * Ordered sequence of positive integers defining the positions in a coordinate
199:             * tuple of the coordinates affected by this pass-through transform. The returned
200:             * index are for source coordinates.
201:             *
202:             * @return The modified coordinates.
203:             */
204:            public int[] getModifiedCoordinates() {
205:                final int[] index = new int[subTransform.getSourceDimensions()];
206:                for (int i = 0; i < index.length; i++) {
207:                    index[i] = i + firstAffectedOrdinate;
208:                }
209:                return index;
210:            }
211:
212:            /**
213:             * Gets the dimension of input points.
214:             */
215:            public int getSourceDimensions() {
216:                return firstAffectedOrdinate
217:                        + subTransform.getSourceDimensions()
218:                        + numTrailingOrdinates;
219:            }
220:
221:            /**
222:             * Gets the dimension of output points.
223:             */
224:            public int getTargetDimensions() {
225:                return firstAffectedOrdinate
226:                        + subTransform.getTargetDimensions()
227:                        + numTrailingOrdinates;
228:            }
229:
230:            /**
231:             * Tests whether this transform does not move any points.
232:             */
233:            public boolean isIdentity() {
234:                return subTransform.isIdentity();
235:            }
236:
237:            /**
238:             * Transforms a list of coordinate point ordinal values.
239:             */
240:            public void transform(final float[] srcPts, int srcOff,
241:                    final float[] dstPts, int dstOff, int numPts)
242:                    throws TransformException {
243:                final int subDimSource = subTransform.getSourceDimensions();
244:                final int subDimTarget = subTransform.getTargetDimensions();
245:                int srcStep = numTrailingOrdinates;
246:                int dstStep = numTrailingOrdinates;
247:                if (srcPts == dstPts && srcOff < dstOff) {
248:                    final int dimSource = getSourceDimensions();
249:                    final int dimTarget = getTargetDimensions();
250:                    srcOff += numPts * dimSource;
251:                    dstOff += numPts * dimTarget;
252:                    srcStep -= 2 * dimSource;
253:                    dstStep -= 2 * dimTarget;
254:                }
255:                while (--numPts >= 0) {
256:                    System.arraycopy(srcPts, srcOff, dstPts, dstOff,
257:                            firstAffectedOrdinate);
258:                    subTransform.transform(srcPts,
259:                            srcOff += firstAffectedOrdinate, dstPts,
260:                            dstOff += firstAffectedOrdinate, 1);
261:                    System.arraycopy(srcPts, srcOff += subDimSource, dstPts,
262:                            dstOff += subDimTarget, numTrailingOrdinates);
263:                    srcOff += srcStep;
264:                    dstOff += dstStep;
265:                }
266:            }
267:
268:            /**
269:             * Transforms a list of coordinate point ordinal values.
270:             */
271:            public void transform(final double[] srcPts, int srcOff,
272:                    final double[] dstPts, int dstOff, int numPts)
273:                    throws TransformException {
274:                final int subDimSource = subTransform.getSourceDimensions();
275:                final int subDimTarget = subTransform.getTargetDimensions();
276:                int srcStep = numTrailingOrdinates;
277:                int dstStep = numTrailingOrdinates;
278:                if (srcPts == dstPts && srcOff < dstOff) {
279:                    final int dimSource = getSourceDimensions();
280:                    final int dimTarget = getTargetDimensions();
281:                    srcOff += numPts * dimSource;
282:                    dstOff += numPts * dimTarget;
283:                    srcStep -= 2 * dimSource;
284:                    dstStep -= 2 * dimTarget;
285:                }
286:                while (--numPts >= 0) {
287:                    System.arraycopy(srcPts, srcOff, dstPts, dstOff,
288:                            firstAffectedOrdinate);
289:                    subTransform.transform(srcPts,
290:                            srcOff += firstAffectedOrdinate, dstPts,
291:                            dstOff += firstAffectedOrdinate, 1);
292:                    System.arraycopy(srcPts, srcOff += subDimSource, dstPts,
293:                            dstOff += subDimTarget, numTrailingOrdinates);
294:                    srcOff += srcStep;
295:                    dstOff += dstStep;
296:                }
297:            }
298:
299:            /**
300:             * Gets the derivative of this transform at a point.
301:             */
302:            public Matrix derivative(final DirectPosition point)
303:                    throws TransformException {
304:                final int nSkipped = firstAffectedOrdinate
305:                        + numTrailingOrdinates;
306:                final int transDim = subTransform.getSourceDimensions();
307:                final int pointDim = point.getDimension();
308:                if (pointDim != transDim + nSkipped) {
309:                    throw new MismatchedDimensionException(Errors.format(
310:                            ErrorKeys.MISMATCHED_DIMENSION_$3, "point",
311:                            new Integer(pointDim), new Integer(transDim
312:                                    + nSkipped)));
313:                }
314:                final GeneralDirectPosition subPoint = new GeneralDirectPosition(
315:                        transDim);
316:                for (int i = 0; i < transDim; i++) {
317:                    subPoint.ordinates[i] = point.getOrdinate(i
318:                            + firstAffectedOrdinate);
319:                }
320:                return expand(toGMatrix(subTransform.derivative(subPoint)),
321:                        firstAffectedOrdinate, numTrailingOrdinates, 0);
322:            }
323:
324:            /**
325:             * Creates a pass through transform from a matrix. This method is invoked when the
326:             * sub-transform can be express as a matrix. It is also invoked for computing the
327:             * matrix returned by {@link #derivative}.
328:             *
329:             * @param subMatrix The sub-transform as a matrix.
330:             * @param firstAffectedOrdinate Index of the first affected ordinate.
331:             * @param numTrailingOrdinates Number of trailing ordinates to pass through.
332:             * @param affine 0 if the matrix do not contains translation terms, or 1 if
333:             *        the matrix is an affine transform with translation terms.
334:             */
335:            private static GeneralMatrix expand(final GeneralMatrix subMatrix,
336:                    final int firstAffectedOrdinate,
337:                    final int numTrailingOrdinates, final int affine) {
338:                final int nSkipped = firstAffectedOrdinate
339:                        + numTrailingOrdinates;
340:                final int numRow = subMatrix.getNumRow() - affine;
341:                final int numCol = subMatrix.getNumCol() - affine;
342:                final GeneralMatrix matrix = new GeneralMatrix(numRow
343:                        + nSkipped + affine, numCol + nSkipped + affine);
344:                matrix.setZero();
345:
346:                //  Set UL part to 1:   [ 1  0             ]
347:                //                      [ 0  1             ]
348:                //                      [                  ]
349:                //                      [                  ]
350:                //                      [                  ]
351:                for (int j = 0; j < firstAffectedOrdinate; j++) {
352:                    matrix.setElement(j, j, 1);
353:                }
354:                //  Set central part:   [ 1  0  0  0  0  0 ]
355:                //                      [ 0  1  0  0  0  0 ]
356:                //                      [ 0  0  ?  ?  ?  0 ]
357:                //                      [ 0  0  ?  ?  ?  0 ]
358:                //                      [                  ]
359:                subMatrix.copySubMatrix(0, 0, numRow, numCol,
360:                        firstAffectedOrdinate, firstAffectedOrdinate, matrix);
361:
362:                //  Set LR part to 1:   [ 1  0  0  0  0  0 ]
363:                //                      [ 0  1  0  0  0  0 ]
364:                //                      [ 0  0  ?  ?  ?  0 ]
365:                //                      [ 0  0  ?  ?  ?  0 ]
366:                //                      [ 0  0  0  0  0  1 ]
367:                final int offset = numCol - numRow;
368:                final int numRowOut = numRow + nSkipped;
369:                for (int j = numRowOut - numTrailingOrdinates; j < numRowOut; j++) {
370:                    matrix.setElement(j, j + offset, 1);
371:                }
372:                if (affine != 0) {
373:                    // Copy the translation terms in the last column.
374:                    subMatrix.copySubMatrix(0, numCol, numRow, affine,
375:                            firstAffectedOrdinate, numCol + nSkipped, matrix);
376:                    // Copy the last row as a safety, but it should contains only 0.
377:                    subMatrix.copySubMatrix(numRow, 0, affine, numCol, numRow
378:                            + nSkipped, firstAffectedOrdinate, matrix);
379:                    // Copy the lower right corner, which should contains only 1.
380:                    subMatrix.copySubMatrix(numRow, numCol, affine, affine,
381:                            numRow + nSkipped, numCol + nSkipped, matrix);
382:                }
383:                return matrix;
384:            }
385:
386:            /**
387:             * Creates the inverse transform of this object.
388:             */
389:            public MathTransform inverse()
390:                    throws NoninvertibleTransformException {
391:                // No need to synchronize. Not a big deal if two objects are created.
392:                if (inverse == null) {
393:                    inverse = new PassThroughTransform(firstAffectedOrdinate,
394:                            subTransform.inverse(), numTrailingOrdinates);
395:                    inverse.inverse = this ;
396:                }
397:                return inverse;
398:            }
399:
400:            /**
401:             * Returns a hash value for this transform.
402:             * This value need not remain consistent between
403:             * different implementations of the same class.
404:             */
405:            public int hashCode() {
406:                int code = (int) serialVersionUID + firstAffectedOrdinate + 37
407:                        * numTrailingOrdinates;
408:                if (subTransform != null) {
409:                    code ^= subTransform.hashCode();
410:                }
411:                return code;
412:            }
413:
414:            /**
415:             * Compares the specified object with this math transform for equality.
416:             */
417:            public boolean equals(final Object object) {
418:                if (object == this ) {
419:                    return true;
420:                }
421:                if (super .equals(object)) {
422:                    final PassThroughTransform that = (PassThroughTransform) object;
423:                    return this .firstAffectedOrdinate == that.firstAffectedOrdinate
424:                            && this .numTrailingOrdinates == that.numTrailingOrdinates
425:                            && Utilities.equals(this .subTransform,
426:                                    that.subTransform);
427:                }
428:                return false;
429:            }
430:
431:            /**
432:             * Format the inner part of a
433:             * <A HREF="http://geoapi.sourceforge.net/snapshot/javadoc/org/opengis/referencing/doc-files/WKT.html"><cite>Well
434:             * Known Text</cite> (WKT)</A> element.
435:             *
436:             * @param  formatter The formatter to use.
437:             * @return The WKT element name.
438:             *
439:             * @todo The {@link #numTrailingOrdinates} parameter is not part of OpenGIS specification.
440:             *       We should returns a more complex WKT when {@code numTrailingOrdinates != 0},
441:             *       using an affine transform to change the coordinates order.
442:             */
443:            protected String formatWKT(final Formatter formatter) {
444:                formatter.append(firstAffectedOrdinate);
445:                if (numTrailingOrdinates != 0) {
446:                    formatter.append(numTrailingOrdinates);
447:                }
448:                formatter.append(subTransform);
449:                return "PASSTHROUGH_MT";
450:            }
451:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.