/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2013, 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.data.mapinfo; import java.util.Collections; import org.apache.sis.referencing.datum.DefaultEllipsoid; import org.opengis.referencing.datum.DatumAuthorityFactory; import org.opengis.referencing.datum.Ellipsoid; import org.opengis.util.FactoryException; import java.util.HashMap; import java.util.Map; import org.apache.sis.measure.Units; import org.apache.sis.referencing.CRS; import org.apache.sis.referencing.IdentifiedObjects; import org.apache.sis.util.ArgumentChecks; import static org.geotoolkit.internal.InternalUtilities.epsilonEqual; import org.opengis.referencing.crs.CRSAuthorityFactory; /** * A class to identify mapInfo ellipsoïds defined by MapInfo. We give them an EPSG equivalent, or just register it's * data as specified in MapInfo. * * @author Alexis Manin (Geomatys) * Date : 21/03/13 */ public class EllipsoidIdentifier { /** A table to map MapInfo ellipsoïd codes with their EPSG equivalent. */ private static final Map<Integer, Integer> ELLIPSOID_TABLE = new HashMap<>(); /** A map to bind MapInfo ellipsoïd codes with built ellipsoïds. It only defines ellipsoïds which don't get EPSG codes */ private static final Map<Integer, Ellipsoid> CUSTOM_ELLIPSOIDS = new HashMap<>(); /** * Return the {@link Ellipsoid} pointed by given MapInfo code. * @param mapinfoCode The code of the datum to retrieve, as given by MapInfo. * @return The ellipsoid which the given MapInfo code represents, or null if we can't find any matching ellipsoid. * @throws FactoryException if we got a problem while building ellipsoid. */ public static Ellipsoid getEllipsoid(Integer mapinfoCode) throws FactoryException { Ellipsoid result = null; ArgumentChecks.ensureNonNull("MapInfo Ellipsoïd Code", mapinfoCode); Integer epsgCode = ELLIPSOID_TABLE.get(mapinfoCode); if(epsgCode != null) { final CRSAuthorityFactory datumFactory = CRS.getAuthorityFactory("EPSG"); if (datumFactory instanceof DatumAuthorityFactory) result = ((DatumAuthorityFactory)datumFactory).createEllipsoid(epsgCode.toString()); else throw new FactoryException("No datum factory available."); } else { result = CUSTOM_ELLIPSOIDS.get(mapinfoCode); } return result; } /** * Search a MIF code for the given EPSG ellipsoid code. * @param epsgCode The EPSG code which represents the wanted ellipsoid. * @return The MIF code for the found ellipsoid, or -1 if no equivalent can be found. */ public static int getMIFCodeFromEPSG(int epsgCode) { for(Map.Entry<Integer, Integer> pair : ELLIPSOID_TABLE.entrySet()) { if(pair.getValue().equals(epsgCode)) { return pair.getKey(); } } return -1; } /** * Search a MIF code for the given ellipsoid. * @param source the ellipsoid we want an equivalent for. * @return the MIF code which match the given ellipsoid. */ public static int getMIFCode(Ellipsoid source) throws FactoryException { int mifCode = getMIFCodeFromEPSG(IdentifiedObjects.lookupEPSG(source)); if (mifCode < 0) { for (Map.Entry<Integer, Ellipsoid> ellipsoid : CUSTOM_ELLIPSOIDS.entrySet()) { final double smAxis = ellipsoid.getValue().getSemiMajorAxis(); final double flat = ellipsoid.getValue().getInverseFlattening(); if (epsilonEqual(smAxis, source.getSemiMajorAxis()) && epsilonEqual(flat, source.getInverseFlattening())) { mifCode = ellipsoid.getKey(); break; } } } return mifCode; } static { ELLIPSOID_TABLE.put( 9, 7001); ELLIPSOID_TABLE.put(13, 7002); ELLIPSOID_TABLE.put(51, 7041); ELLIPSOID_TABLE.put( 2, 7003); ELLIPSOID_TABLE.put(10, 7004); // 35 // 14 ELLIPSOID_TABLE.put(36, 7007); ELLIPSOID_TABLE.put( 7, 7008); ELLIPSOID_TABLE.put( 8, 7009); ELLIPSOID_TABLE.put( 6, 7034); ELLIPSOID_TABLE.put(15, 7013); ELLIPSOID_TABLE.put(30, 7011); // 37 // 16 // 38 ELLIPSOID_TABLE.put(39, 7016); ELLIPSOID_TABLE.put(11, 7015); ELLIPSOID_TABLE.put(40, 7044); // 50 ELLIPSOID_TABLE.put(17, 7018); ELLIPSOID_TABLE.put(48, 7018); // 18 // 19 // 20 ELLIPSOID_TABLE.put(21, 7036); ELLIPSOID_TABLE.put( 0, 7019); ELLIPSOID_TABLE.put( 5, 7022); ELLIPSOID_TABLE.put(22, 7020); ELLIPSOID_TABLE.put(23, 7053); ELLIPSOID_TABLE.put(31, 7049); ELLIPSOID_TABLE.put(41, 7021); ELLIPSOID_TABLE.put( 4, 7022); // 49 // 3 // 32 // 33 ELLIPSOID_TABLE.put(42, 7025); ELLIPSOID_TABLE.put(43, 7043); ELLIPSOID_TABLE.put(43, 7043); ELLIPSOID_TABLE.put(44, 7032); ELLIPSOID_TABLE.put(45, 7033); ELLIPSOID_TABLE.put(46, 7027); // 52 ELLIPSOID_TABLE.put(24, 7003); ELLIPSOID_TABLE.put(12, 7052); ELLIPSOID_TABLE.put(47, 7028); // 34 ELLIPSOID_TABLE.put(25, 7029); // 26 ELLIPSOID_TABLE.put(27, 7025); ELLIPSOID_TABLE.put( 1, 7043); ELLIPSOID_TABLE.put(28, 7030); ELLIPSOID_TABLE.put(29, 7030); ELLIPSOID_TABLE.put(54, 7030); // Here we build ellipsoïds we did not found epsg equivalent for. CUSTOM_ELLIPSOIDS.put(35, DefaultEllipsoid.createFlattenedSphere( name("Bessel 1841 (modified for NGO 1948)"), 6377492.0176, 299.15281, Units.METRE)); CUSTOM_ELLIPSOIDS.put(14, DefaultEllipsoid.createFlattenedSphere( name("Bessel 1841 (modified for Schwarzeck)"), 6377483.865, 299.1528128, Units.METRE)); CUSTOM_ELLIPSOIDS.put(37, DefaultEllipsoid.createFlattenedSphere( name("Clarke 1880 (modified for Jamaica)"), 6378249.136, 293.46631, Units.METRE)); CUSTOM_ELLIPSOIDS.put(16, DefaultEllipsoid.createFlattenedSphere( name("Clarke 1880 (modified for Merchich)"), 6378249.2, 293.46598, Units.METRE)); CUSTOM_ELLIPSOIDS.put(38, DefaultEllipsoid.createFlattenedSphere( name("Clarke 1880 (modified for Palestine)"), 6378300.79, 293.46623, Units.METRE)); CUSTOM_ELLIPSOIDS.put(50, DefaultEllipsoid.createFlattenedSphere( name("Everest (Pakistan)"), 6377309.613, 300.8017, Units.METRE)); CUSTOM_ELLIPSOIDS.put(18, DefaultEllipsoid.createFlattenedSphere( name("Fischer 1960"), 6378166.0, 298.3, Units.METRE)); CUSTOM_ELLIPSOIDS.put(19, DefaultEllipsoid.createFlattenedSphere( name("Fischer 1960 (modified for South Asia)"), 6378155.0, 298.3, Units.METRE)); CUSTOM_ELLIPSOIDS.put(20, DefaultEllipsoid.createFlattenedSphere( name("Fischer 1968"), 6378150.0, 298.3, Units.METRE)); CUSTOM_ELLIPSOIDS.put(49, DefaultEllipsoid.createFlattenedSphere( name("Irish (WOFO)"), 6377542.178, 299.325, Units.METRE)); CUSTOM_ELLIPSOIDS.put( 3, DefaultEllipsoid.createFlattenedSphere( name("Krassovsky"), 6378245.0, 298.3, Units.METRE)); CUSTOM_ELLIPSOIDS.put(32, DefaultEllipsoid.createFlattenedSphere( name("MERIT 83"), 6378137.0, 298.257, Units.METRE)); CUSTOM_ELLIPSOIDS.put(33, DefaultEllipsoid.createFlattenedSphere( name("New International 1967"), 6378157.5, 298.25, Units.METRE)); CUSTOM_ELLIPSOIDS.put(52, DefaultEllipsoid.createFlattenedSphere( name("PZ90"), 6378136.0, 298.257839303, Units.METRE)); CUSTOM_ELLIPSOIDS.put(34, DefaultEllipsoid.createFlattenedSphere( name("Walbeck"), 6376896.0, 302.78, Units.METRE)); CUSTOM_ELLIPSOIDS.put(26, DefaultEllipsoid.createFlattenedSphere( name("WGS 60"), 6378165.0, 298.3, Units.METRE)); } private static Map<String,?> name(final String name) { return Collections.singletonMap(Ellipsoid.NAME_KEY, name); } }