/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2007-2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.referencing.operation.builder; import java.io.File; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Random; import junit.framework.Assert; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.coverage.grid.GridCoverageFactory; import org.geotools.gce.image.WorldImageWriter; import org.geotools.geometry.DirectPosition2D; import org.geotools.geometry.Envelope2D; import org.geotools.referencing.crs.DefaultEngineeringCRS; import org.geotools.referencing.crs.DefaultGeographicCRS; import org.geotools.referencing.operation.DefaultMathTransformFactory; import org.geotools.referencing.operation.matrix.GeneralMatrix; import org.geotools.referencing.operation.transform.ProjectiveTransform; import org.geotools.referencing.operation.transform.WarpGridTransform2D; import org.geotools.referencing.operation.transform.WarpGridTransform2D.ProviderFile; import org.opengis.geometry.Envelope; import org.opengis.parameter.ParameterValueGroup; import org.opengis.referencing.FactoryException; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.NoninvertibleTransformException; import org.opengis.referencing.operation.TransformException; /** * @author jezekjan * */ public class WarpGridBuilderTest extends TestCase { private double tolerance = 0.03; //cm DefaultEngineeringCRS l; private CoordinateReferenceSystem crs = DefaultEngineeringCRS.GENERIC_2D; private boolean show = false; private boolean write = true; private String path="/home/jezekjan/tmp/"; /** * Run the suite from the command line. * * @param args */ public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } /** * Returns the test suite. * * @return */ public static Test suite() { return new TestSuite(WarpGridBuilderTest.class); } /** * Generates Mapped positions inside specified envelope. * @param env Envelope * @param number Number of points to be generated * @param deltas approximately the deltas between source and target point. * @return */ private List<MappedPosition> generateMappedPositions(Envelope env, int number, double deltas, CoordinateReferenceSystem crs) { List<MappedPosition> vectors = new ArrayList<MappedPosition>(); double minx = env.getLowerCorner().getCoordinates()[0]; double miny = env.getLowerCorner().getCoordinates()[1]; double maxx = env.getUpperCorner().getCoordinates()[0]; double maxy = env.getUpperCorner().getCoordinates()[1]; final Random random = new Random(8578348921369L); for (int i = 0; i < number; i++) { double x = minx + (random.nextDouble() * (maxx - minx)); double y = miny + (random.nextDouble() * (maxy - miny)); vectors.add(new MappedPosition(new DirectPosition2D(crs, x, y), new DirectPosition2D(crs, (x + (random.nextDouble() * deltas)) - (random.nextDouble() * deltas), (y + (random.nextDouble() * deltas)) - (random.nextDouble() * deltas)))); } return vectors; } /** * Test of TPDWarpGridBuilder * */ public void testIDWWarpGridBuilder() { try { // Envelope 20*20 km 00 Envelope env = new Envelope2D(crs, -50, -50, 400000, 200000); // Generates 15 MappedPositions of approximately 2 m differences List<MappedPosition> mp = generateMappedPositions(env, 6, 2, crs); WarpGridBuilder builder = new IDWGridBuilder(mp, 5000, 5000, env); //gridTest(mp, builder.getMathTransform()); GridCoverage2D dx = (new GridCoverageFactory()).create("idw - dx", builder.getDxGrid(), env); GridCoverage2D dy = (new GridCoverageFactory()).create("idw - dy", builder.getDyGrid(), env); if (show == true) { dx.show(); dy.show(); } if (write == true) { WorldImageWriter writerx = new WorldImageWriter((Object) (new File( path+"idwdx.png"))); writerx.write(dx, null); WorldImageWriter writery = new WorldImageWriter((Object) (new File( path+"idwdy.png"))); writery.write(dy, null); } assertBuilder(builder); assertInverse(builder); } catch (Exception e) { e.printStackTrace(); } } /** * Test of IDWDWarpGridBuilder * */ public void testTPSWarpGridBuilder() { try { Envelope env = new Envelope2D(crs, 0, 0, 2000, 3000 ); // Generates 15 MappedPositions of approximately 2 m differences List<MappedPosition> mp = generateMappedPositions(env, 10, 1, crs); GeneralMatrix M = new GeneralMatrix(3, 3); double[] m0 = { 1, 0, 0 }; double[] m1 = { 0, 1, 0 }; double[] m2 = { 0, 0, 1 }; M.setRow(0, m0); M.setRow(1, m1); M.setRow(2, m2); WarpGridBuilder builder = new TPSGridBuilder(mp, 10, 10, env,ProjectiveTransform.create(M)); //builder.getDeltaFile(0, "/home/jezekjan/gridfile.txt"); GridCoverage2D dx = (new GridCoverageFactory()).create("tps - dx", builder.getDxGrid(), env); GridCoverage2D dy = (new GridCoverageFactory()).create("tps - dy", builder.getDyGrid(), env); if (show == true) { dx.show(); dy.show(); } if (write == true) { WorldImageWriter writerx = new WorldImageWriter((Object) (new File( path+"tpsdx.png"))); writerx.write(dx, null); WorldImageWriter writery = new WorldImageWriter((Object) (new File( path+"tpsdy.png"))); writery.write(dy, null); } assertBuilder(builder); assertInverse(builder); } catch (Exception e) { e.printStackTrace(); } } public void testRSGridBuilder() { try { Envelope env = new Envelope2D(crs, 0, 0, 1000, 1000); // Generates 15 MappedPositions of approximately 2 m differences List<MappedPosition> mp = generateMappedPositions(env, 15, 1, crs); GeneralMatrix M = new GeneralMatrix(3, 3); double[] m0 = { 1, 0, 0 }; double[] m1 = { 0, 1, 0 }; double[] m2 = { 0, 0, 1 }; M.setRow(0, m0); M.setRow(1, m1); M.setRow(2, m2); WarpGridBuilder builder = new RSGridBuilder(mp, 3, 3, env, ProjectiveTransform.create(M)); GridCoverage2D rubberdx = (new GridCoverageFactory()).create("RubberSheet - dx", builder.getDxGrid(), env); GridCoverage2D rubberdy = (new GridCoverageFactory()).create("RubberSheet - dy", builder.getDyGrid(), env); if (show == true) { rubberdx.show(); rubberdy.show(); } if (write == true) { WorldImageWriter writerx = new WorldImageWriter((Object) (new File( path+"/rubberdx.png"))); writerx.write(rubberdx, null); WorldImageWriter writery = new WorldImageWriter((Object) (new File( path+"/rubberdy.png"))); writery.write(rubberdy, null); } assertBuilder(builder); } catch (Exception e) { e.printStackTrace(); } } public void testFileProvider(){ try { // Envelope 20*20 km Envelope env = new Envelope2D(crs, 10, 10, 500, 500); GeneralMatrix M = new GeneralMatrix(3, 3); // WarpGridBuilder builder = new RSGridBuilder(mp, 3, 3, env, // ProjectiveTransform.create(M)); // Generates 15 MappedPositions of approximately 2 m differences List<MappedPosition> mp = generateMappedPositions(env, 15, 0.01, crs); WarpGridBuilder builder = new IDWGridBuilder(mp, 20, 20, env, ProjectiveTransform.create(M)); final DefaultMathTransformFactory factory = new DefaultMathTransformFactory(); ParameterValueGroup gridParams = factory.getDefaultParameters("Warp Grid (from file)"); String pathx = path+"dx"; String pathy = path+"dy"; builder.writeDeltaFile(0, pathx); builder.writeDeltaFile(1, pathy); gridParams.parameter("X_difference_file").setValue(pathx); gridParams.parameter("Y_difference_file").setValue(pathy); MathTransform mt = (new ProviderFile()).createMathTransform(gridParams); MathTransform mtOriginal = builder.getMathTransform(); float[] wp = ( float[] )(((WarpGridTransform2D)mt).getParameterValues().parameter("warpPositions").getValue()); float[] wpOrig = ( float[] )(((WarpGridTransform2D)mtOriginal).getParameterValues().parameter("warpPositions").getValue()); for (int i = 0; i < wp.length; i++){ Assert.assertEquals(wp[i], wpOrig[i], 0.0001); } } catch (Exception e) { e.printStackTrace(); } } /** * Tests that transformed source point fits to target point (considering tolerance). * @param builder */ private void assertBuilder(MathTransformBuilder builder) { List<MappedPosition> mp = builder.getMappedPositions(); try { for (int i = 0; i < mp.size(); i++) { Assert.assertEquals(0, ((MappedPosition) mp.get(i)).getError(builder.getMathTransform(), null), tolerance); } } catch (Exception e) { e.printStackTrace(); } } private void assertInverse(MathTransformBuilder builder) { try { List<MappedPosition> mp = builder.getMappedPositions(); for (int i = 0; i < mp.size(); i++) { MappedPosition p = (MappedPosition) mp.get(i); MappedPosition inversMp = new MappedPosition(p.getTarget(), p.getSource()); //inversMp.add(new MappedPosition(p.getTarget(),p.getSource())); // System.out.println(inversMp.getError(builder.getMathTransform().inverse(), null)); Assert.assertEquals(0, inversMp.getError(builder.getMathTransform().inverse(), null), tolerance); } } catch (NoninvertibleTransformException e) { e.printStackTrace(); } catch (TransformException e) { e.printStackTrace(); } catch (FactoryException e) { e.printStackTrace(); } //builder.getMathTransform().inverse(); } public static void gridTest(List<MappedPosition> mps, MathTransform trans) throws TransformException{ double sum = 0; int j = 0; for(Iterator<MappedPosition> i = mps.iterator(); i.hasNext();){ MappedPosition mp = i.next(); DirectPosition2D test = new DirectPosition2D(0,0); trans.transform(mp.getSource(),test); Assert.assertEquals(mp.getTarget().getOrdinate(0), test.getOrdinate(0), 0.04); Assert.assertEquals(mp.getTarget().getOrdinate(1), test.getOrdinate(1), 0.04); double dx = Math.pow((mp.getTarget().getOrdinate(0)-test.getOrdinate(0)),2); double dy = Math.pow((mp.getTarget().getOrdinate(1)-test.getOrdinate(1)),2); sum = sum + Math.pow((dx+dy),0.5); j++; } } }