Package org.geotools.referencing.wkt

Source Code of org.geotools.referencing.wkt.ParserTest

/*
*    GeoTools - The Open Source Java GIS Toolkit
*    http://geotools.org
*
*    (C) 2002-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.wkt;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.ParseException;
import java.util.Collection;
import java.util.HashSet;

import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.crs.GeographicCRS;
import org.opengis.referencing.cs.CartesianCS;
import org.opengis.referencing.operation.MathTransform;

import org.geotools.referencing.crs.DefaultProjectedCRS;
import org.geotools.referencing.ScriptRunner;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.referencing.cs.DefaultCartesianCS;
import org.geotools.referencing.operation.DefaultMathTransformFactory;
import org.geotools.test.TestData;

import org.junit.*;
import static org.junit.Assert.*;


/**
* Tests the WKT {@link Parser} implementation.
*
*
*
* @source $URL$
* @version $Id$
* @author Yann Cézard
* @author Remi Eve
* @author Martin Desruisseaux (IRD)
*/
public final class ParserTest {
    /**
     * Test a hard coded version of a WKT. This is more convenient for debugging.
     */
    @Test
    public void testHardCoded() throws ParseException {
        final Parser parser = new Parser();
        String              wkt1, wkt2;
        DefaultProjectedCRS crs1, crs2;
        ParameterValueGroup param;
        /*
         * First, rather simple Mercator projection.
         * Uses standard units and axis order.
         */
        wkt1 = "PROJCS[\"Mercator test\",\n"                             +
               "  GEOGCS[\"WGS84\",\n"                                   +
               "    DATUM[\"WGS84\",\n"                                  +
               "      SPHEROID[\"WGS84\", 6378137.0, 298.257223563]],\n" +
               "    PRIMEM[\"Greenwich\", 0.0],\n"                       +
               "    UNIT[\"degree\", 0.017453292519943295],\n"           +
               "    AXIS[\"Longitude\", EAST],\n"                        +
               "    AXIS[\"Latitude\", NORTH]],\n"                       +
               "  PROJECTION[\"Mercator_1SP\"],\n"                       +
               "  PARAMETER[\"central_meridian\", -20.0],\n"             +
               "  PARAMETER[\"scale_factor\", 1.0],\n"                   +
               "  PARAMETER[\"false_easting\", 500000.0],\n"             +
               "  PARAMETER[\"false_northing\", 0.0],\n"                 +
               "  UNIT[\"m\", 1.0],\n"                                   +
               "  AXIS[\"x\", EAST],\n"                                  +
               "  AXIS[\"y\", NORTH]]\n";
        assertTrue(Symbols.DEFAULT.containsAxis(wkt1));
        crs1  = (DefaultProjectedCRS) parser.parseObject(wkt1);
        wkt2  = parser.format(crs1);
        crs2  = (DefaultProjectedCRS) parser.parseObject(wkt2);
        param = crs1.getConversionFromBase().getParameterValues();
        assertEquals(crs1, crs2);
        assertEquals("Mercator_1SP", crs1.getConversionFromBase().getMethod().getName().getCode());
        assertTrue(crs1.getConversionFromBase().getMathTransform().toWKT().startsWith("PARAM_MT[\"Mercator_1SP\""));
        assertFalse (wkt2.contains("semi_major"));
        assertFalse (wkt2.contains("semi_minor"));
        assertEquals("semi_major",   6378137.0, param.parameter("semi_major"      ).doubleValue(), 1E-4);
        assertEquals("semi_minor",   6356752.3, param.parameter("semi_minor"      ).doubleValue(), 1E-1);
        assertEquals("central_meridian", -20.0, param.parameter("central_meridian").doubleValue(), 1E-8);
        assertEquals("scale_factor",       1.0, param.parameter("scale_factor"    ).doubleValue(), 1E-8);
        assertEquals("false_easting", 500000.0, param.parameter("false_easting"   ).doubleValue(), 1E-4);
        assertEquals("false_northing",     0.0, param.parameter("false_northing"  ).doubleValue(), 1E-4);
        /*
         * Same Mercator projection as above, but
         * switch longitude and latitude axis.
         */
        wkt1 = "PROJCS[\"Mercator test\",\n"                             +
               "  GEOGCS[\"WGS84\",\n"                                   +
               "    DATUM[\"WGS84\",\n"                                  +
               "      SPHEROID[\"WGS84\", 6378137.0, 298.257223563]],\n" +
               "    PRIMEM[\"Greenwich\", 0.0],\n"                       +
               "    UNIT[\"degree\", 0.017453292519943295],\n"           +
               "    AXIS[\"Latitude\", NORTH],\n"                        +
               "    AXIS[\"Longitude\", EAST]],\n"                       +
               "  PROJECTION[\"Mercator_1SP\"],\n"                       +
               "  PARAMETER[\"central_meridian\", -20.0],\n"             +
               "  PARAMETER[\"scale_factor\", 1.0],\n"                   +
               "  PARAMETER[\"false_easting\", 500000.0],\n"             +
               "  PARAMETER[\"false_northing\", 0.0],\n"                 +
               "  UNIT[\"m\", 1.0],\n"                                   +
               "  AXIS[\"x\", EAST],\n"                                  +
               "  AXIS[\"y\", NORTH]]\n";
        assertTrue(Symbols.DEFAULT.containsAxis(wkt1));
        crs1  = (DefaultProjectedCRS) parser.parseObject(wkt1);
        wkt2  = parser.format(crs1);
        crs2  = (DefaultProjectedCRS) parser.parseObject(wkt2);
        param = crs1.getConversionFromBase().getParameterValues();
        assertEquals(crs1, crs2);
        assertEquals("Mercator_1SP", crs1.getConversionFromBase().getMethod().getName().getCode());
        assertTrue(crs1.getConversionFromBase().getMathTransform().toWKT().startsWith("CONCAT_MT[PARAM_MT["));
        assertFalse (wkt2.contains("semi_major"));
        assertFalse (wkt2.contains("semi_minor"));
        assertEquals("semi_major",   6378137.0, param.parameter("semi_major"      ).doubleValue(), 1E-4);
        assertEquals("semi_minor",   6356752.3, param.parameter("semi_minor"      ).doubleValue(), 1E-1);
        assertEquals("central_meridian", -20.0, param.parameter("central_meridian").doubleValue(), 1E-8);
        assertEquals("scale_factor",       1.0, param.parameter("scale_factor"    ).doubleValue(), 1E-8);
        assertEquals("false_easting", 500000.0, param.parameter("false_easting"   ).doubleValue(), 1E-4);
        assertEquals("false_northing",     0.0, param.parameter("false_northing"  ).doubleValue(), 1E-4);
        /*
         * Try an other projection (Transverse Mercator).
         */
        wkt1 = "PROJCS[\"OSGB 1936 / British National Grid\",\n"                                          +
               "  GEOGCS[\"OSGB 1936\",\n"                                                                +
               "    DATUM[\"OSGB_1936\",\n"                                                               +
               "      SPHEROID[\"Airy 1830\", 6377563.396, 299.3249646, AUTHORITY[\"EPSG\",\"7001\"]],\n" +
               "      TOWGS84[375.0, -111.0, 431.0, 0.0, 0.0, 0.0, 0.0],\n"                               +
               "      AUTHORITY[\"EPSG\",\"6277\"]],\n"                                                   +
               "    PRIMEM[\"Greenwich\",0.0, AUTHORITY[\"EPSG\",\"8901\"]],\n"                           +
               "    UNIT[\"DMSH\",0.0174532925199433, AUTHORITY[\"EPSG\",\"9108\"]],\n"                   +
               "    AXIS[\"Lat\",NORTH],AXIS[\"Long\",EAST], AUTHORITY[\"EPSG\",\"4277\"]],\n"            +
               "  PROJECTION[\"Transverse_Mercator\"],\n"                                                 +
               "  PARAMETER[\"latitude_of_origin\", 49.0],\n"                                             +
               "  PARAMETER[\"central_meridian\", -2.0],\n"                                               +
               "  PARAMETER[\"scale_factor\", 0.999601272],\n"                                            +
               "  PARAMETER[\"false_easting\", 400000.0],\n"                                              +
               "  PARAMETER[\"false_northing\", -100000.0],\n"                                            +
               "  UNIT[\"metre\", 1.0, AUTHORITY[\"EPSG\",\"9001\"]],\n"                                  +
               "  AXIS[\"E\",EAST],\n"                                                                    +
               "  AXIS[\"N\",NORTH],\n"                                                                   +
               "  AUTHORITY[\"EPSG\",\"27700\"]]\n";
        assertTrue(Symbols.DEFAULT.containsAxis(wkt1));
        crs1  = (DefaultProjectedCRS) parser.parseObject(wkt1);
        wkt2  = parser.format(crs1);
        crs2  = (DefaultProjectedCRS) parser.parseObject(wkt2);
        param = crs1.getConversionFromBase().getParameterValues();
        assertEquals(crs1, crs2);
        assertFalse (wkt2.contains("semi_major"));
        assertFalse (wkt2.contains("semi_minor"));
        assertEquals("Transverse_Mercator", crs1.getConversionFromBase().getMethod().getName().getCode());
        assertEquals("semi_major",   6377563.396, param.parameter("semi_major"        ).doubleValue(), 1E-4);
        assertEquals("semi_minor",   6356256.909, param.parameter("semi_minor"        ).doubleValue(), 1E-3);
        assertEquals("latitude_of_origin"49.0, param.parameter("latitude_of_origin").doubleValue(), 1E-8);
        assertEquals("central_meridian",    -2.0, param.parameter("central_meridian"  ).doubleValue(), 1E-8);
        assertEquals("scale_factor",      0.9996, param.parameter("scale_factor"      ).doubleValue(), 1E-5);
        assertEquals("false_easting",   400000.0, param.parameter("false_easting"     ).doubleValue(), 1E-4);
        assertEquals("false_northing", -100000.0, param.parameter("false_northing"    ).doubleValue(), 1E-4);
        /*
         * Try a projection with feet units.
         */
        wkt1 = "PROJCS[\"TransverseMercator\",\n"                     +
               "  GEOGCS[\"Sphere\",\n"                               +
               "    DATUM[\"Sphere\",\n"                              +
               "      SPHEROID[\"Sphere\", 6370997.0, 0.0],\n"        +
               "      TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]],\n" +
               "    PRIMEM[\"Greenwich\", 0.0],\n"                    +
               "    UNIT[\"degree\", 0.017453292519943295],\n"        +
               "    AXIS[\"Longitude\", EAST],\n"                     +
               "    AXIS[\"Latitude\", NORTH]],\n"                    +
               "  PROJECTION[\"Transverse_Mercator\",\n"              +
               "    AUTHORITY[\"OGC\",\"Transverse_Mercator\"]],\n"   +
               "  PARAMETER[\"central_meridian\", 170.0],\n"          +
               "  PARAMETER[\"latitude_of_origin\", 50.0],\n"         +
               "  PARAMETER[\"scale_factor\", 0.95],\n"               +
               "  PARAMETER[\"false_easting\", 0.0],\n"               +
               "  PARAMETER[\"false_northing\", 0.0],\n"              +
               "  UNIT[\"feet\", 0.304800609601219],\n"               +
               "  AXIS[\"x\", EAST],\n"                               +
               "  AXIS[\"y\", NORTH]]\n";
        assertTrue(Symbols.DEFAULT.containsAxis(wkt1));
        crs1  = (DefaultProjectedCRS) parser.parseObject(wkt1);
        wkt2  = parser.format(crs1);
        crs2  = (DefaultProjectedCRS) parser.parseObject(wkt2);
        param = crs1.getConversionFromBase().getParameterValues();
        assertEquals(crs1, crs2);
        assertFalse (wkt2.contains("semi_major"));
        assertFalse (wkt2.contains("semi_minor"));
        assertEquals("Transverse_Mercator", crs1.getConversionFromBase().getMethod().getName().getCode());
        assertEquals("semi_major",     6370997.0, param.parameter("semi_major"        ).doubleValue(), 1E-5);
        assertEquals("semi_minor",     6370997.0, param.parameter("semi_minor"        ).doubleValue(), 1E-5);
        assertEquals("latitude_of_origin"50.0, param.parameter("latitude_of_origin").doubleValue(), 1E-8);
        assertEquals("central_meridian",   170.0, param.parameter("central_meridian"  ).doubleValue(), 1E-8);
        assertEquals("scale_factor",        0.95, param.parameter("scale_factor"      ).doubleValue(), 1E-8);
        assertEquals("false_easting",        0.0, param.parameter("false_easting"     ).doubleValue(), 1E-8);
        assertEquals("false_northing",       0.0, param.parameter("false_northing"    ).doubleValue(), 1E-8);
        /*
         * Try with a number using scientific notation.
         */
        wkt1 = "GEOGCS[\"NAD83 / NFIS Seconds\",DATUM[\"North_American_Datum_1983\",\n" +
               "  SPHEROID[\"GRS 1980\", 6378137, 298.257222101]],\n"                   +
               "  PRIMEM[\"Greenwich\", 0],\n"                                          +
               "  UNIT[\"Decimal_Second\", 4.84813681109536e-06],\n"                    +
               "  AUTHORITY[\"EPSG\", \"100001\"]]";
        assertFalse(Symbols.DEFAULT.containsAxis(wkt1));
        wkt2 = parser.format(parser.parseObject(wkt1));
        assertFalse(wkt2.contains("semi_major"));
        assertFalse(wkt2.contains("semi_minor"));
    }

    /**
     * Tests the Oracle variant of WKT.
     */
    @Test
    public void testOracleWKT() throws ParseException {
        final String wkt =
                "PROJCS[\"Datum 73 / Modified Portuguese Grid\"," +
                 " GEOGCS [ \"Datum 73\"," +
                   " DATUM[\"Datum 73 (EPSG ID 6274)\"," +
                     " SPHEROID [\"International 1924 (EPSG ID 7022)\", 6378388, 297]," +
                     " -231, 102.6, 29.8, .6149999999999993660366746131394108039579," +
                     " -.1979999999999997958947342656936639661522," +
                      " .8809999999999990918346509498793836069706, .99999821]," +
                   " PRIMEM [ \"Greenwich\", 0.000000 ]," +
                   " UNIT [\"Decimal Degree\", 0.01745329251994328]]," +
                 " PROJECTION[\"Transverse_Mercator\"]," +
//               " PROJECTION[\"Modified Portuguese Grid (EPSG OP 19974)\"]," +
// TODO: The real projection is "Modified Portugues", but it is not yet implemented in Geotools.
                 " PARAMETER[\"Latitude_Of_Origin\", 39.66666666666666666666666666666666666667]," +
                 " PARAMETER[\"Central_Meridian\", -8.13190611111111111111111111111111111111]," +
                 " PARAMETER[\"Scale_Factor\", 1]," +
                 " PARAMETER [\"False_Easting\", 180.598]," +
                 " PARAMETER[\"False_Northing\", -86.99]," +
                 " UNIT [\"Meter\", 1]]";
        assertFalse(Symbols.DEFAULT.containsAxis(wkt));
        final Parser parser = new Parser();
        CoordinateReferenceSystem crs1 = parser.parseCoordinateReferenceSystem(wkt);
        final String check = parser.format(crs1);
        assertTrue(check.indexOf("TOWGS84[-231") >= 0);
        CoordinateReferenceSystem crs2 = parser.parseCoordinateReferenceSystem(check);
        assertEquals(crs1, crs2);
        assertFalse(check.contains("semi_major"));
        assertFalse(check.contains("semi_minor"));
    }

    /**
     * Tests parsing with custom axis length. At the difference of the previous test,
     * the WKT formatting in this test should include the axis length as parameter values.
     */
    @Test
    public void testCustomAxisLength() throws FactoryException, ParseException {
        DefaultMathTransformFactory factory = new DefaultMathTransformFactory();
        ParameterValueGroup parameters = factory.getDefaultParameters("Lambert_Conformal_Conic_2SP");

        final double majorAxis = 6.3712e+6;
        final double minorAxis = 6.3712e+6;
        parameters.parameter("semi_major").setValue(majorAxis);
        parameters.parameter("semi_minor").setValue(minorAxis);
        parameters.parameter("latitude_of_origin").setValue(25.0);
        parameters.parameter("standard_parallel_1").setValue(25.0);
        parameters.parameter("standard_parallel_2").setValue(25.0);
        parameters.parameter("longitude_of_origin").setValue(-95.0);
        parameters.parameter("false_easting").setValue(0.0);
        parameters.parameter("false_northing").setValue(0.0);

        GeographicCRS base = DefaultGeographicCRS.WGS84;
        MathTransform mt   = factory.createParameterizedTransform(parameters);
        CartesianCS cs = DefaultCartesianCS.PROJECTED;
        CoordinateReferenceSystem crs = new DefaultProjectedCRS("Lambert", base, mt, cs);

        final String wkt = crs.toWKT();
        assertTrue(wkt.contains("semi_major"));
        assertTrue(wkt.contains("semi_minor"));
        final Parser parser = new Parser();
        CoordinateReferenceSystem check = parser.parseCoordinateReferenceSystem(wkt);
        assertEquals(wkt, check.toWKT());
    }

    /**
     * Tests parsing of math transforms.
     */
    @Test
    public void testMathTransform() throws IOException, ParseException {
        testParsing(new MathTransformParser(), "wkt/MathTransform.txt");
    }

    /**
     * Tests parsing of coordinate reference systems.
     */
    @Test
    public void testCoordinateReferenceSystem() throws IOException, ParseException {
        testParsing(new Parser(), "wkt/CoordinateReferenceSystem.txt");
    }

    /**
     * Parses all elements from the specified file. Parsing creates a set of
     * geographic objects. No special processing are done with them; we just
     * check if the parsing work without error and produces distincts objects.
     */
    private void testParsing(final AbstractParser parser, final String filename)
            throws IOException, ParseException
    {
        final BufferedReader reader = TestData.openReader(ScriptRunner.class, filename);
        if (reader == null) {
            throw new FileNotFoundException(filename);
        }
        final Collection<Object> pool = new HashSet<Object>();
        String line;
        while ((line=reader.readLine()) != null) {
            line = line.trim();
            if (line.length()==0 || line.startsWith("#")) {
                continue;
            }
            /*
             * Parses a line. If the parse fails, then dump the WKT and rethrow the exception.
             */
            final Object parsed;
            try {
                parsed = parser.parseObject(line);
            } catch (ParseException exception) {
                System.err.println();
                System.err.println("-----------------------------");
                System.err.println("Parse failed. Dump WKT below.");
                System.err.println("-----------------------------");
                System.err.println(line);
                System.err.println();
                throw exception;
            }
            assertNotNull("Parsing returns null.",                 parsed);
            assertEquals("Inconsistent equals method",             parsed, parsed);
            assertSame("Parsing twice returns different objects.", parsed, parser.parseObject(line));
            assertTrue("An identical object already exists.",      pool.add(parsed));
            assertTrue("Inconsistent hashCode or equals method.",  pool.contains(parsed));
            /*
             * Formats the object and parse it again.
             * Ensures that the result is consistent.
             */
            String formatted = parser.format(parsed);
            final Object again;
            try {
                again = parser.parseObject(formatted);
            } catch (ParseException exception) {
                System.err.println();
                System.err.println("------------------------------------");
                System.err.println("Second parse failed. Dump WKT below.");
                System.err.println("------------------------------------");
                System.err.println(line);
                System.err.println();
                System.err.println("------ Reformatted WKT below -------");
                System.err.println();
                System.err.println(formatted);
                System.err.println();
                throw exception;
            }
            assertEquals("Second parsing produced different objects", parsed, again);
            assertTrue("Inconsistent hashCode or equals method.",  pool.contains(again));
        }
        reader.close();
    }
   
    /**
     * Test if the parser handles string and number coded Authority code-values.
     * @throws IOException
     * @throws ParseException
     */
    @Test
    public void testAuthorityCodeParsing() throws IOException, ParseException {
        testParsing(new Parser(), "wkt/AuthorityCode.txt");
    }   
}
TOP

Related Classes of org.geotools.referencing.wkt.ParserTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.