All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.geotoolkit.referencing.cs.PredefinedCS Maven / Gradle / Ivy

Go to download

Implementations of Coordinate Reference Systems (CRS), conversion and transformation services derived from ISO 19111.

There is a newer version: 3.20-geoapi-3.0
Show newest version
/*
 *    Geotoolkit.org - An Open Source Java GIS Toolkit
 *    http://www.geotoolkit.org
 *
 *    (C) 2005-2011, Open Source Geospatial Foundation (OSGeo)
 *    (C) 2009-2011, Geomatys
 *
 *    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.geotoolkit.referencing.cs;

import java.util.List;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Map;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;

import org.opengis.referencing.cs.*;

import org.geotoolkit.lang.Static;
import org.geotoolkit.resources.Errors;
import org.geotoolkit.referencing.IdentifiedObjects;


/**
 * Converts an arbitrary CS into one of the predefined constants provided in the
 * {@link org.geotoolkit.referencing.cs} package. The main usage for this class is
 * to reorder the axis in some "standard" order like (x, y,
 * z) or (longitude, latitude). What "standard"
 * order means is sometime an arbitrary choice, which explain why this class is
 * not public at this time.
 *
 * @author Martin Desruisseaux (IRD)
 * @version 3.00
 *
 * @since 2.2
 * @module
 */
final class PredefinedCS extends Static implements Comparator {
    /**
     * An instance of {@link PredefinedCS}. Will be created only when first needed.
     */
    private static Comparator csComparator;

    /**
     * Our ordering for coordinate system objects.
     */
    @SuppressWarnings({"unchecked","rawtypes"})
    private final Class[] types = new Class[] {
        CartesianCS  .class,
        AffineCS     .class,
        EllipsoidalCS.class,
        SphericalCS  .class,
        CylindricalCS.class,
        PolarCS      .class,
        VerticalCS   .class,
        TimeCS       .class,
        LinearCS     .class,
        UserDefinedCS.class
    };

    /**
     * Creates a comparator.
     */
    private PredefinedCS() {
    }

    /**
     * Compares the ordering between two coordinate systems. This comparator is used for sorting
     * the axis in an user-supplied compound CS in an order closes to some "standard" order.
     */
    @Override
    public int compare(final CoordinateSystem object1, final CoordinateSystem object2) {
        final Class type1 = object1.getClass();
        final Class type2 = object2.getClass();
        for (int i=0; i type = types[i];
            final boolean a1 = type.isAssignableFrom(type1);
            final boolean a2 = type.isAssignableFrom(type2);
            if (a1) return a2 ? 0 : -1;
            if (a2) return a1 ? 0 : +1;
        }
        return 0;
    }

    /**
     * Implementation of the {@link AbstractCS#standard} method.
     */
    static CoordinateSystem standard(final CoordinateSystem cs) throws IllegalArgumentException {
        final int dimension = cs.getDimension();
        if (cs instanceof CartesianCS) {
            switch (dimension) {
                case 2: {
                    if (DefaultCartesianCS.PROJECTED.axisColinearWith(cs)) {
                        return DefaultCartesianCS.PROJECTED;
                    }
                    if (DefaultCartesianCS.GRID.axisColinearWith(cs)) {
                        return DefaultCartesianCS.GRID;
                    }
                    if (DefaultCartesianCS.GENERIC_2D.directionColinearWith(cs)) {
                        return DefaultCartesianCS.GENERIC_2D;
                    }
                    return rightHanded((CartesianCS) cs);
                }
                case 3: {
                    if (DefaultCartesianCS.GEOCENTRIC.axisColinearWith(cs)) {
                        return DefaultCartesianCS.GEOCENTRIC;
                    }
                    if (DefaultCartesianCS.GENERIC_3D.directionColinearWith(cs)) {
                        return DefaultCartesianCS.GENERIC_3D;
                    }
                    return rightHanded((CartesianCS) cs);
                }
            }
        }
        if (cs instanceof AffineCS) {
            return rightHanded((AffineCS) cs);
        }
        if (cs instanceof EllipsoidalCS) {
            switch (dimension) {
                case 2: return DefaultEllipsoidalCS.GEODETIC_2D;
                case 3: return DefaultEllipsoidalCS.GEODETIC_3D;
            }
        }
        if (cs instanceof SphericalCS) {
            switch (dimension) {
                case 3: return DefaultSphericalCS.GEOCENTRIC;
            }
        }
        if (cs instanceof VerticalCS) {
            switch (dimension) {
                case 1: {
                    return DefaultVerticalCS.ELLIPSOIDAL_HEIGHT;
                }
            }
        }
        if (cs instanceof TimeCS) {
            switch (dimension) {
                case 1: return DefaultTimeCS.DAYS;
            }
        }
        if (cs instanceof DefaultCompoundCS) {
            final List components = ((DefaultCompoundCS) cs).getCoordinateSystems();
            final CoordinateSystem[] user = new CoordinateSystem[components.size()];
            final CoordinateSystem[] std  = new CoordinateSystem[user.length];
            for (int i=0; i unit = axe.getUnit();
            if (!Unit.ONE.equals(unit) && !SI.METRE.equals(unit)) {
                axe = DefaultCoordinateSystemAxis.castOrCopy(axe).usingUnit(SI.METRE);
            }
            changed |= (axe != axis[i]);
            axis[i] = axe;
        }
        /*
         * Sorts the axis in an attempt to create a right-handed system
         * and creates a new Coordinate System if at least one axis changed.
         */
        changed |= ComparableAxisWrapper.sort(axis);
        if (!changed) {
            return cs;
        }
        final Map properties = IdentifiedObjects.getProperties(cs, null);
        if (cs instanceof CartesianCS) {
            return new DefaultCartesianCS(properties, axis);
        }
        return new DefaultAffineCS(properties, axis);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy