Source Code Cross Referenced for MathTransformTest.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:         *    (C) 2005-2006, Geotools Project Managment Committee (PMC)
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:        package org.geotools.referencing.operation.transform;
017:
018:        // J2SE dependencies
019:        import java.awt.geom.AffineTransform;
020:        import java.util.Arrays;
021:        import java.util.Random;
022:
023:        // JUnit dependencies
024:        import junit.framework.Test;
025:        import junit.framework.TestCase;
026:        import junit.framework.TestSuite;
027:
028:        // OpenGIS dependencies
029:        import org.opengis.parameter.ParameterValueGroup;
030:        import org.opengis.referencing.FactoryException;
031:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
032:        import org.opengis.referencing.operation.MathTransform;
033:        import org.opengis.referencing.operation.MathTransform1D;
034:        import org.opengis.referencing.operation.MathTransform2D;
035:        import org.opengis.referencing.operation.Matrix;
036:        import org.opengis.referencing.operation.NoninvertibleTransformException;
037:        import org.opengis.referencing.operation.TransformException;
038:        import org.opengis.geometry.DirectPosition;
039:
040:        // Geotools dependencies
041:        import org.geotools.geometry.DirectPosition1D;
042:        import org.geotools.geometry.GeneralDirectPosition;
043:        import org.geotools.referencing.ReferencingFactoryFinder;
044:        import org.geotools.referencing.crs.DefaultGeographicCRS;
045:        import org.geotools.referencing.operation.LinearTransform;
046:        import org.geotools.referencing.operation.DefaultMathTransformFactory;
047:        import org.geotools.referencing.operation.matrix.MatrixFactory;
048:        import org.geotools.referencing.operation.matrix.GeneralMatrix;
049:        import org.geotools.referencing.operation.matrix.XMatrix;
050:
051:        /**
052:         * Tests various classes of {@link MathTransform}, including {@link ConcatenatedTransform}.
053:         * Actually, there is many {@link ConcatenatedTransform}, each optimized for special cases.
054:         * This test tries to test a wide range of subclasses.
055:         *
056:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/test/java/org/geotools/referencing/operation/transform/MathTransformTest.java $
057:         * @version $Id: MathTransformTest.java 25262 2007-04-23 21:11:16Z desruisseaux $
058:         * @author Martin Desruisseaux
059:         */
060:        public final class MathTransformTest extends TestCase {
061:            /**
062:             * Runs the tests with the textual test runner.
063:             */
064:            public static void main(String args[]) {
065:                junit.textui.TestRunner.run(suite());
066:            }
067:
068:            /**
069:             * Returns the test suite.
070:             */
071:            public static Test suite() {
072:                return new TestSuite(MathTransformTest.class);
073:            }
074:
075:            /**
076:             * Constructs a test case with the given name.
077:             */
078:            public MathTransformTest(final String name) {
079:                super (name);
080:            }
081:
082:            /**
083:             * Random numbers generator.
084:             */
085:            private Random random;
086:
087:            /**
088:             * The default math transform factory.
089:             */
090:            private DefaultMathTransformFactory factory;
091:
092:            /**
093:             * Expected accuracy for tests on JTS objects.
094:             */
095:            private static final double ACCURACY = 0.03;
096:
097:            /**
098:             * Set up common objects used for all tests.
099:             */
100:            protected void setUp() throws Exception {
101:                super .setUp();
102:                random = new Random(-3531834320875149028L);
103:                factory = new DefaultMathTransformFactory();
104:            }
105:
106:            /**
107:             * Tests a transformation on a {@link DirectPosition} object.
108:             */
109:            public void testDirectPositionTransform() throws FactoryException,
110:                    TransformException {
111:                CoordinateReferenceSystem crs = ReferencingFactoryFinder
112:                        .getCRSFactory(null)
113:                        .createFromWKT(
114:                                "PROJCS[\"NAD_1983_UTM_Zone_10N\",\n"
115:                                        + "  GEOGCS[\"GCS_North_American_1983\",\n"
116:                                        + "    DATUM[\"D_North_American_1983\",\n"
117:                                        + "      TOWGS84[0,0,0,0,0,0,0]\n,"
118:                                        + "      SPHEROID[\"GRS_1980\", 6378137, 298.257222101]],\n"
119:                                        + "    PRIMEM[\"Greenwich\",0],\n"
120:                                        + "    UNIT[\"Degree\", 0.017453292519943295]],\n"
121:                                        + "  PROJECTION[\"Transverse_Mercator\"],\n"
122:                                        + "  PARAMETER[\"False_Easting\",500000],\n"
123:                                        + "  PARAMETER[\"False_Northing\",0],\n"
124:                                        + "  PARAMETER[\"Central_Meridian\",-123],\n"
125:                                        + "  PARAMETER[\"Scale_Factor\",0.9996],\n"
126:                                        + "  PARAMETER[\"Latitude_Of_Origin\",0],\n"
127:                                        + "  UNIT[\"Meter\",1]]");
128:
129:                MathTransform t = ReferencingFactoryFinder
130:                        .getCoordinateOperationFactory(null).createOperation(
131:                                DefaultGeographicCRS.WGS84, crs)
132:                        .getMathTransform();
133:                DirectPosition position = new GeneralDirectPosition(-123, 55);
134:                position = t.transform(position, position);
135:                position = t.inverse().transform(position, position);
136:                assertEquals(-123, position.getOrdinate(0), 1E-6);
137:                assertEquals(55, position.getOrdinate(1), 1E-6);
138:            }
139:
140:            /**
141:             * Tests the {@link ProjectiveTransform} implementation.
142:             */
143:            public void testAffineTransform() throws FactoryException,
144:                    TransformException {
145:                for (int pass = 0; pass < 10; pass++) {
146:                    final AffineTransform transform = new AffineTransform();
147:                    transform.rotate(Math.PI * random.nextDouble(),
148:                            100 * random.nextDouble(), 100 * random
149:                                    .nextDouble());
150:                    transform.scale(2 * random.nextDouble(), 2 * random
151:                            .nextDouble());
152:                    transform.shear(2 * random.nextDouble(), 2 * random
153:                            .nextDouble());
154:                    transform.translate(100 * random.nextDouble(), 100 * random
155:                            .nextDouble());
156:                    compareTransforms("AffineTransform", new MathTransform[] {
157:                            new ProjectiveTransform(
158:                                    new GeneralMatrix(transform)),
159:                            new AffineTransform2D(transform) });
160:                }
161:
162:                AffineTransform at = new AffineTransform(23.157082917424454,
163:                        0.0, 3220.1613428464952, 0.0, -23.157082917424457,
164:                        1394.4593259871676);
165:                MathTransform mt = factory
166:                        .createAffineTransform(new GeneralMatrix(at));
167:
168:                final double[] points = new double[] { -129.992589135802,
169:                        55.9226692948365, -129.987254340541, 55.9249676996729,
170:                        -129.982715772093, 55.9308988434656, -129.989772198265,
171:                        55.9289277997662, -129.992589135802, 55.9226692948365 };
172:                final double[] transformedPoints = new double[points.length];
173:                mt
174:                        .transform(points, 0, transformedPoints, 0,
175:                                points.length / 2);
176:                at.transform(points, 0, points, 0, points.length / 2);
177:                for (int i = 0; i < transformedPoints.length; i++) {
178:                    assertEquals(points[i], transformedPoints[i], ACCURACY);
179:                }
180:            }
181:
182:            /**
183:             * Test various linear transformations. We test for many differents dimensions.
184:             * The factory class should have created specialized classes for 1D and 2D cases.
185:             * This test is used in order to ensure that specialized case produces the same
186:             * results than general cases.
187:             */
188:            public void testSubAffineTransform() throws FactoryException,
189:                    TransformException {
190:                for (int pass = 0; pass < 5; pass++) {
191:                    /*
192:                     * Construct the reference matrix.
193:                     */
194:                    final int dimension = 10;
195:                    final GeneralMatrix matrix = new GeneralMatrix(
196:                            dimension + 1, dimension + 1);
197:                    for (int i = 0; i < dimension; i++) {
198:                        matrix.setElement(i, i, 400 * Math.random() - 200);
199:                        matrix.setElement(i, dimension,
200:                                400 * Math.random() - 200);
201:                    }
202:                    assertTrue(matrix.isAffine());
203:                    /*
204:                     * Construct all math transforms.
205:                     */
206:                    final MathTransform[] transforms = new MathTransform[dimension];
207:                    for (int i = 1; i <= dimension; i++) {
208:                        final GeneralMatrix sub = new GeneralMatrix(i + 1,
209:                                i + 1);
210:                        matrix.copySubMatrix(0, 0, i, i, 0, 0, sub); // Scale terms
211:                        matrix.copySubMatrix(0, dimension, i, 1, 0, i, sub); // Translation terms
212:                        final MathTransform transform = transforms[i - 1] = factory
213:                                .createAffineTransform(sub);
214:                        assertTrue(sub.isAffine());
215:                        assertEquals(sub, new GeneralMatrix(
216:                                ((LinearTransform) transform).getMatrix()));
217:                        assertInterfaced(transform);
218:                        assertTrue(i == transform.getSourceDimensions());
219:                    }
220:                    /*
221:                     * Check transformations and the inverse transformations.
222:                     */
223:                    assertTrue("MathTransform1D",
224:                            transforms[0] instanceof  MathTransform1D);
225:                    assertTrue("MathTransform2D",
226:                            transforms[1] instanceof  MathTransform2D);
227:                    assertEquals(matrix,
228:                            ((LinearTransform) transforms[dimension - 1])
229:                                    .getMatrix());
230:                    compareTransforms("SubAffineTransform", transforms);
231:                    for (int i = 0; i < transforms.length; i++) {
232:                        transforms[i] = transforms[i].inverse();
233:                    }
234:                    compareTransforms("SubAffineTransform.inverse", transforms);
235:                }
236:            }
237:
238:            /**
239:             * Test the concatenation of linear transformations. Concatenation of linear
240:             * transformations should involve only matrix multiplication.  However, this
241:             * test will also create {@link ConcatenatedTransform} objects in order to
242:             * compare their results.
243:             */
244:            public void testAffineTransformConcatenation()
245:                    throws FactoryException, TransformException {
246:                final MathTransform[] transforms = new MathTransform[2];
247:                final int numDim = 4;
248:                final int numPts = 200;
249:                for (int pass = 0; pass < 100; pass++) {
250:                    final int dimSource = random.nextInt(numDim) + 1;
251:                    final int dimTarget = random.nextInt(numDim) + 1;
252:                    final int dimInterm = random.nextInt(numDim) + 1;
253:                    final Matrix matrix1 = getRandomMatrix(dimSource, dimInterm);
254:                    final Matrix matrix2 = getRandomMatrix(dimInterm, dimTarget);
255:                    final MathTransform tr1 = factory
256:                            .createAffineTransform(matrix1);
257:                    final MathTransform tr2 = factory
258:                            .createAffineTransform(matrix2);
259:                    final double[] sourcePt = new double[dimSource * numPts];
260:                    final double[] intermPt = new double[dimInterm * numPts];
261:                    final double[] targetPt = new double[dimTarget * numPts];
262:                    final double[] compare = new double[dimTarget * numPts];
263:                    final double[] delta = new double[dimTarget];
264:                    for (int i = 0; i < numPts; i++) {
265:                        sourcePt[i] = 100 * random.nextDouble() - 50;
266:                    }
267:                    tr1.transform(sourcePt, 0, intermPt, 0, numPts);
268:                    tr2.transform(intermPt, 0, targetPt, 0, numPts);
269:                    Arrays.fill(delta, 1E-6);
270:                    /*
271:                     * Create two set of concatenated transform: the first one computed from matrix
272:                     * multiplication;   the second one is forced to a ConcatenatedTransform object
273:                     * for testing purpose.
274:                     */
275:                    transforms[0] = factory.createConcatenatedTransform(tr1,
276:                            tr2);
277:                    transforms[1] = ConcatenatedTransform
278:                            .createConcatenatedTransform(tr1, tr2);
279:                    assertTrue(transforms[0] instanceof  LinearTransform);
280:                    assertFalse(transforms[1] instanceof  LinearTransform);
281:                    for (int i = 0; i < transforms.length; i++) {
282:                        final MathTransform transform = transforms[i];
283:                        assertInterfaced(transform);
284:                        assertEquals("dimSource[" + i + ']', dimSource,
285:                                transform.getSourceDimensions());
286:                        assertEquals("dimTarget[" + i + ']', dimTarget,
287:                                transform.getTargetDimensions());
288:                        transform.transform(sourcePt, 0, compare, 0, numPts);
289:                        String name = "transform[" + i + "](" + dimSource
290:                                + " -> " + dimInterm + " -> " + dimTarget + ')';
291:                        assertPointsEqual(name, targetPt, compare, delta);
292:                    }
293:                }
294:            }
295:
296:            /**
297:             * Make sure that linear transformation preserve NaN values.
298:             * This is required for {@link org.geotools.coverage.Category}.
299:             */
300:            public void testNaN() throws FactoryException, TransformException {
301:                final XMatrix matrix = MatrixFactory.create(2);
302:                matrix.setElement(0, 0, 0);
303:                for (int i = 0; i < 200; i++) {
304:                    final int rawBits = 0x7FC00000 + random.nextInt(100);
305:                    final float value = Float.intBitsToFloat(rawBits);
306:                    assertTrue("isNaN", Float.isNaN(value));
307:                    matrix.setElement(0, 1, value);
308:                    final MathTransform1D tr = (MathTransform1D) factory
309:                            .createAffineTransform(matrix);
310:                    assertTrue("ConstantTransform1D",
311:                            tr instanceof  ConstantTransform1D);
312:                    final float compare = (float) tr.transform(0);
313:                    assertEquals("rawBits", rawBits, Float
314:                            .floatToRawIntBits(compare));
315:                }
316:            }
317:
318:            /**
319:             * Test the {@link ExponentialTransform1D} and {@link LogarithmicTransform1D} classes
320:             * using simple know values.
321:             */
322:            public void testLogarithmicTransform() throws FactoryException,
323:                    TransformException {
324:                final double[] POWER_2 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
325:                        11, 12, 13 };
326:                final double[] VALUE_2 = { 1, 2, 4, 8, 16, 32, 64, 128, 256,
327:                        512, 1024, 2048, 4096, 8192 };
328:                final double[] POWER_10 = { -5, -4, -3, -2, -1, 0, +1, +2, +3,
329:                        +4, +5 };
330:                final double[] VALUE_10 = { 1E-5, 1E-4, 1E-3, 1E-2, 1E-1, 1,
331:                        1E+1, 1E+2, 1E+3, 1E+4, 1E+5 };
332:                compareTransform1D("Exponential", 2, POWER_2, VALUE_2);
333:                compareTransform1D("Exponential", 10, POWER_10, VALUE_10);
334:                compareTransform1D("Logarithmic", 2, VALUE_2, POWER_2);
335:                compareTransform1D("Logarithmic", 10, VALUE_10, POWER_10);
336:            }
337:
338:            /**
339:             * Test the concatenation of {@link LinearTransform1D}, {@link ExponentialTransform1D}
340:             * and {@link LogarithmicTransform1D}.
341:             */
342:            public void testLogarithmicAndExponentialConcatenation()
343:                    throws FactoryException, TransformException {
344:                final int numPts = 200;
345:                final double[] sourcePt = new double[numPts];
346:                final double[] targetPt = new double[numPts];
347:                final double[] compare = new double[numPts];
348:                final double[] delta = new double[numPts];
349:                for (int pass = 0; pass < 100; pass++) {
350:                    for (int i = 0; i < numPts; i++) {
351:                        sourcePt[i] = 20 * random.nextDouble() + 0.1;
352:                    }
353:                    MathTransform ctr = getRandomTransform1D();
354:                    ctr.transform(sourcePt, 0, targetPt, 0, numPts);
355:                    for (int i = random.nextInt(2) + 1; --i >= 0;) {
356:                        final MathTransform1D step = getRandomTransform1D();
357:                        ctr = (MathTransform1D) factory
358:                                .createConcatenatedTransform(ctr, step);
359:                        step.transform(targetPt, 0, targetPt, 0, numPts);
360:                    }
361:                    ctr.transform(sourcePt, 0, compare, 0, numPts);
362:                    final double EPS = Math.pow(10, -5 + countNonlinear(ctr));
363:                    for (int i = 0; i < numPts; i++) {
364:                        delta[i] = Math.max(1E-9, Math.abs(targetPt[i] * EPS));
365:                        if (targetPt[i] >= +1E+300)
366:                            targetPt[i] = Double.POSITIVE_INFINITY;
367:                        if (targetPt[i] <= -1E+300)
368:                            targetPt[i] = Double.NEGATIVE_INFINITY;
369:                    }
370:                    assertPointsEqual("transform[" + ctr + ']', targetPt,
371:                            compare, delta);
372:                    /*
373:                     * Test the inverse transform. It is difficult to get back the exact original value,
374:                     * since expressions like  'pow(b1, pow(b2,x))'  tend to overflow or underflow very
375:                     * fast. We are very tolerant for this test because of this (exponential expression
376:                     * give exponential error). The 'testLogarithmicTransform' method tested the inverse
377:                     * transform in a more sever way.
378:                     */
379:                    try {
380:                        final MathTransform inv = ctr.inverse();
381:                        Arrays.fill(delta, Math.pow(10, countNonlinear(inv)));
382:                        inv.transform(targetPt, 0, compare, 0, numPts);
383:                        for (int i = 0; i < numPts; i++) {
384:                            if (!isReal(targetPt[i]) || !isReal(compare[i])) {
385:                                // Ignore all input points that produced NaN or infinity
386:                                // A succession of 2 "Exponentional" operation produces
387:                                // infinities pretty fast, so ignore it.
388:                                sourcePt[i] = Double.NaN;
389:                            }
390:                        }
391:                        assertPointsEqual("inverse[" + inv + ']', sourcePt,
392:                                compare, delta);
393:                    } catch (NoninvertibleTransformException exception) {
394:                        // Some transforms may not be invertible. Ignore...
395:                    }
396:                }
397:            }
398:
399:            ///////////////////////////////////////////////////////////////////////////////////
400:            ////////////                                                           ////////////
401:            ////////////               U T I L I T Y   M E T H O D S               ////////////
402:            ////////////                                                           ////////////
403:            ///////////////////////////////////////////////////////////////////////////////////
404:
405:            /**
406:             * Returns a random matrix.
407:             *
408:             * @param dimSource Number of dimension for input points.
409:             * @param dimTarget Number of dimension for outout points.
410:             */
411:            private Matrix getRandomMatrix(final int dimSource,
412:                    final int dimTarget) {
413:                final XMatrix matrix = MatrixFactory.create(dimTarget + 1,
414:                        dimSource + 1);
415:                for (int j = 0; j < dimTarget; j++) { // Don't touch to the last row!
416:                    for (int i = 0; i <= dimSource; i++) {
417:                        matrix.setElement(j, i, 10 * random.nextDouble() - 5);
418:                    }
419:                    if (j <= dimSource) {
420:                        matrix.setElement(j, j, 40 * random.nextDouble() + 10);
421:                    }
422:                    matrix.setElement(j, dimSource,
423:                            80 * random.nextDouble() - 40);
424:                }
425:                if (dimSource == dimTarget) {
426:                    assertTrue("Affine", matrix.isAffine());
427:                }
428:                return matrix;
429:            }
430:
431:            /**
432:             * Gets a random one-dimensional transform.
433:             */
434:            private MathTransform1D getRandomTransform1D()
435:                    throws FactoryException {
436:                final String[] candidates = { "Logarithmic", "Exponential",
437:                        "Affine" };
438:                final String classification = candidates[random
439:                        .nextInt(candidates.length)];
440:                final ParameterValueGroup parameters = factory
441:                        .getDefaultParameters(classification);
442:                if (classification.equalsIgnoreCase("Affine")) {
443:                    parameters.parameter("num_row").setValue(2);
444:                    parameters.parameter("num_col").setValue(2);
445:                    parameters.parameter("elt_0_0").setValue(
446:                            random.nextDouble() * 2 + 0.1); // scale
447:                    parameters.parameter("elt_0_1").setValue(
448:                            random.nextDouble() * 1 - 2); // offset
449:                } else {
450:                    parameters.parameter("base").setValue(
451:                            random.nextDouble() * 4 + 0.1);
452:                }
453:                return (MathTransform1D) factory
454:                        .createParameterizedTransform(parameters);
455:            }
456:
457:            /**
458:             * Compare the transformation performed by many math transforms. If some transforms
459:             * don't have the same number of input or output dimension, only the first input or
460:             * output dimensions will be taken in account.
461:             *
462:             * @throws TransformException if a transformation failed.
463:             */
464:            private void compareTransforms(final String name,
465:                    final MathTransform[] transforms) throws TransformException {
466:                /*
467:                 * Initialisation...
468:                 */
469:                final GeneralDirectPosition[] sources = new GeneralDirectPosition[transforms.length];
470:                final GeneralDirectPosition[] targets = new GeneralDirectPosition[transforms.length];
471:                int maxDimSource = 0;
472:                int maxDimTarget = 0;
473:                for (int i = 0; i < transforms.length; i++) {
474:                    final int dimSource = transforms[i].getSourceDimensions();
475:                    final int dimTarget = transforms[i].getTargetDimensions();
476:                    if (dimSource > maxDimSource)
477:                        maxDimSource = dimSource;
478:                    if (dimTarget > maxDimTarget)
479:                        maxDimTarget = dimTarget;
480:                    sources[i] = new GeneralDirectPosition(dimSource);
481:                    targets[i] = new GeneralDirectPosition(dimTarget);
482:                }
483:                /*
484:                 * Test with an arbitrary number of randoms points.
485:                 */
486:                for (int pass = 0; pass < 200; pass++) {
487:                    for (int j = 0; j < maxDimSource; j++) {
488:                        final double ord = 100 * random.nextDouble();
489:                        for (int i = 0; i < sources.length; i++) {
490:                            final GeneralDirectPosition source = sources[i];
491:                            if (j < source.ordinates.length) {
492:                                source.ordinates[j] = ord;
493:                            }
494:                        }
495:                    }
496:                    for (int j = 0; j < transforms.length; j++) {
497:                        assertSame(transforms[j].transform(sources[j],
498:                                targets[j]), targets[j]);
499:                    }
500:                    /*
501:                     * Compare all target points.
502:                     */
503:                    final StringBuffer buffer = new StringBuffer(name);
504:                    buffer.append(": Compare transform[");
505:                    final int lengthJ = buffer.length();
506:                    for (int j = 0; j < targets.length; j++) {
507:                        buffer.setLength(lengthJ);
508:                        buffer.append(j);
509:                        buffer.append("] with [");
510:                        final int lengthI = buffer.length();
511:                        final GeneralDirectPosition targetJ = targets[j];
512:                        for (int i = j + 1; i < targets.length; i++) {
513:                            buffer.setLength(lengthI);
514:                            buffer.append(i);
515:                            buffer.append(']');
516:                            final String label = buffer.toString();
517:                            final GeneralDirectPosition targetI = targets[i];
518:                            assertTrue(targetJ.ordinates != targetI.ordinates);
519:                            for (int k = Math.min(targetJ.ordinates.length,
520:                                    targetI.ordinates.length); --k >= 0;) {
521:                                assertEquals(label, targetJ.ordinates[k],
522:                                        targetI.ordinates[k], 1E-6);
523:                            }
524:                        }
525:                    }
526:                }
527:            }
528:
529:            /**
530:             * Compare the result of "Logarithmic" or "Exponential" transform with the expected results.
531:             *
532:             * @param classification The identifier name (e.g. "Exponential" or "Logarithmic").
533:             * @param base           The value for the "base" parameter.
534:             * @param input          Array of input values.
535:             * @param expected       Array of expected output values.
536:             */
537:            private void compareTransform1D(final String classification,
538:                    final double base, final double[] input,
539:                    final double[] expected) throws FactoryException,
540:                    TransformException {
541:                assertEquals(input.length, expected.length);
542:                final ParameterValueGroup parameters = factory
543:                        .getDefaultParameters(classification);
544:                parameters.parameter("base").setValue(base);
545:                final MathTransform1D direct = (MathTransform1D) factory
546:                        .createParameterizedTransform(parameters);
547:                final MathTransform1D inverse = (MathTransform1D) direct
548:                        .inverse();
549:                final DirectPosition1D point = new DirectPosition1D();
550:                for (int i = 0; i < expected.length; i++) {
551:                    final double x = input[i];
552:                    final double y = direct.transform(x);
553:                    assertEquals("transform[x=" + x + ']', expected[i], y, 1E-6);
554:                    assertEquals("inverse  [y=" + y + ']', x, inverse
555:                            .transform(y), 1E-6);
556:                    point.setOrdinate(0, x);
557:                    assertSame(direct.transform(point, point), point);
558:                    assertEquals(y, point.getOrdinate(0), 1E-9);
559:                }
560:            }
561:
562:            /**
563:             * Count the number of non-linear steps in a {@link MathTransform}.
564:             */
565:            private static int countNonlinear(final MathTransform transform) {
566:                if ((transform instanceof  ExponentialTransform1D)
567:                        || (transform instanceof  LogarithmicTransform1D)) {
568:                    return 1;
569:                }
570:                if (transform instanceof  ConcatenatedTransform) {
571:                    final ConcatenatedTransform ct = (ConcatenatedTransform) transform;
572:                    return countNonlinear(ct.transform1)
573:                            + countNonlinear(ct.transform2);
574:                }
575:                return 0;
576:            }
577:
578:            ///////////////////////////////////////////////////////////////////////////////////
579:            ////////////                                                           ////////////
580:            ////////////             A S S E R T I O N   M E T H O D S             ////////////
581:            ////////////                                                           ////////////
582:            ///////////////////////////////////////////////////////////////////////////////////
583:
584:            /**
585:             * Returns {@code true} if the specified number is real (neither NaN or infinite).
586:             */
587:            private static boolean isReal(final double value) {
588:                return !Double.isNaN(value) && !Double.isInfinite(value);
589:            }
590:
591:            /**
592:             * Verify that the specified transform implements {@link MathTransform1D}
593:             * or {@link MathTransform2D} as needed.
594:             *
595:             * @param transform The transform to test.
596:             */
597:            private static void assertInterfaced(final MathTransform transform) {
598:                if (transform instanceof  LinearTransform) {
599:                    final Matrix matrix = ((LinearTransform) transform)
600:                            .getMatrix();
601:                    if (!((XMatrix) matrix).isAffine()) {
602:                        // Special case: Non-affine transforms not yet declared as a 1D or 2D transform.
603:                        return;
604:                    }
605:                }
606:                int dim = transform.getSourceDimensions();
607:                if (transform.getTargetDimensions() != dim) {
608:                    dim = 0;
609:                }
610:                assertTrue("MathTransform1D",
611:                        (dim == 1) == (transform instanceof  MathTransform1D));
612:                assertTrue("MathTransform2D",
613:                        (dim == 2) == (transform instanceof  MathTransform2D));
614:            }
615:
616:            /**
617:             * Compare two arrays of points.
618:             *
619:             * @param name      The name of the comparaison to be performed.
620:             * @param expected  The expected array of points.
621:             * @param actual    The actual array of points.
622:             * @param delta     The maximal difference tolerated in comparaisons for each dimension.
623:             *                  This array length must be equal to coordinate dimension (usually 1, 2 or 3).
624:             */
625:            private static void assertPointsEqual(final String name,
626:                    final double[] expected, final double[] actual,
627:                    final double[] delta) {
628:                final int dimension = delta.length;
629:                final int stop = Math.min(expected.length, actual.length)
630:                        / dimension * dimension;
631:                assertEquals("Array length for expected points", stop,
632:                        expected.length);
633:                assertEquals("Array length for actual points", stop,
634:                        actual.length);
635:                final StringBuffer buffer = new StringBuffer(name);
636:                buffer.append(": point[");
637:                final int start = buffer.length();
638:                for (int i = 0; i < stop; i++) {
639:                    buffer.setLength(start);
640:                    buffer.append(i / dimension);
641:                    buffer.append(", dimension ");
642:                    buffer.append(i % dimension);
643:                    buffer.append(" of ");
644:                    buffer.append(dimension);
645:                    buffer.append(']');
646:                    if (isReal(expected[i])) {
647:                        // The "two steps" method in ConcatenatedTransformTest sometime produces
648:                        // random NaN numbers. This "two steps" is used only for comparaison purpose;
649:                        // the "real" (tested) method work better.
650:                        assertEquals(buffer.toString(), expected[i], actual[i],
651:                                delta[i % dimension]);
652:                    }
653:                }
654:            }
655:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.