Coverage Report - org.geotoolkit.referencing.factory.web.AutoCRSFactory
 
Classes in this File Line Coverage Branch Coverage Complexity
AutoCRSFactory
94 %
36/38
75 %
9/12
2
 
 1  
 /*
 2  
  *    Geotoolkit.org - An Open Source Java GIS Toolkit
 3  
  *    http://www.geotoolkit.org
 4  
  *
 5  
  *    (C) 2004-2012, Open Source Geospatial Foundation (OSGeo)
 6  
  *    (C) 2009-2012, Geomatys
 7  
  *
 8  
  *    This library is free software; you can redistribute it and/or
 9  
  *    modify it under the terms of the GNU Lesser General Public
 10  
  *    License as published by the Free Software Foundation;
 11  
  *    version 2.1 of the License.
 12  
  *
 13  
  *    This library is distributed in the hope that it will be useful,
 14  
  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 15  
  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 16  
  *    Lesser General Public License for more details.
 17  
  */
 18  
 package org.geotoolkit.referencing.factory.web;
 19  
 
 20  
 import java.util.Set;
 21  
 import java.util.Map;
 22  
 import java.util.TreeMap;
 23  
 import java.util.Collections;
 24  
 import java.util.LinkedHashSet;
 25  
 import net.jcip.annotations.ThreadSafe;
 26  
 
 27  
 import org.opengis.util.FactoryException;
 28  
 import org.opengis.util.InternationalString;
 29  
 import org.opengis.metadata.citation.Citation;
 30  
 import org.opengis.referencing.IdentifiedObject;
 31  
 import org.opengis.referencing.NoSuchAuthorityCodeException;
 32  
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 33  
 import org.opengis.referencing.crs.CRSAuthorityFactory;
 34  
 import org.opengis.referencing.crs.ProjectedCRS;
 35  
 
 36  
 import org.geotoolkit.factory.Hints;
 37  
 import org.geotoolkit.util.SimpleInternationalString;
 38  
 import org.geotoolkit.metadata.iso.citation.Citations;
 39  
 import org.geotoolkit.metadata.iso.citation.DefaultCitation;
 40  
 import org.geotoolkit.referencing.factory.DirectAuthorityFactory;
 41  
 
 42  
 // Following are for Javadoc only.
 43  
 import org.geotoolkit.measure.Units;
 44  
 import org.geotoolkit.referencing.operation.projection.Orthographic;
 45  
 import org.geotoolkit.referencing.operation.projection.Equirectangular;
 46  
 import org.geotoolkit.referencing.operation.projection.TransverseMercator;
 47  
 
 48  
 
 49  
 /**
 50  
  * The factory for {@linkplain ProjectedCRS projected CRS} in the {@code AUTO} and {@code AUTO2}
 51  
  * space. The expected format is {@code AUTO:code,<unit>,lon0,lat0} where the {@code AUTO} prefix
 52  
  * is optional. The {@code <unit>} parameter is also optional, since it was not present in the WMS
 53  
  * 1.0 specification (it has been added later).
 54  
  * <p>
 55  
  * The parameters are as below:
 56  
  * <p>
 57  
  * <ul>
 58  
  *   <li>{@code code} - the projection code, as one of the following values:
 59  
  *     <ul>
 60  
  *       <li>42001 for the {@linkplain TransverseMercator Universal Transverse Mercator} projection.</li>
 61  
  *       <li>42002 for the {@linkplain TransverseMercator Transverse Mercator} projection.</li>
 62  
  *       <li>42003 for the {@linkplain Orthographic Orthographic} projection.</li>
 63  
  *       <li>42004 for the {@linkplain Equirectangular Equirectangular} projection.</li>
 64  
  *       <li>42005 for the Mollweide projection.</li>
 65  
  *     </ul>
 66  
  *   </li><li>
 67  
  *     {@code unit} - the unit of measurement code, as one of the codes documented
 68  
  *     in the {@link Units#valueOfEPSG(int)} method. This code is optional. If not
 69  
  *     provided, then the default value is 9001 (<cite>metre</cite>).
 70  
  *   </li><li>
 71  
  *     {@code long0} - the central meridian. For UTM projections (42001), it can be computed as
 72  
  *     (<var>zone</var>*6 - 183) where <var>zone</var> is the UTM zone in the range 1 to 60
 73  
  *     inclusive.
 74  
  *   </li><li>
 75  
  *     {@code lat0} - the latitude of origin.
 76  
  *   </li>
 77  
  * </ul>
 78  
  *
 79  
  * {@section Examples}
 80  
  * An orthographic CRS centered at 100 degrees West longitude and 45 degrees North latitude,
 81  
  * with ordinates in metres.
 82  
  *
 83  
  * {@preformat text
 84  
  *     AUTO2:42003,1,-100,45
 85  
  * }
 86  
  *
 87  
  * Same CRS as above, but with conversion factor allowing ordinate values in U.S. feet:
 88  
  *
 89  
  * {@preformat text
 90  
  *     AUTO2:42003,0.3048006096012192,-100,45
 91  
  * }
 92  
  *
 93  
  * @author Martin Desruisseaux (IRD, Geomatys)
 94  
  * @author Jody Garnett (Refractions)
 95  
  * @author Rueben Schulz (UBC)
 96  
  * @version 3.16
 97  
  *
 98  
  * @since 2.0
 99  
  * @module
 100  
  */
 101  
 @ThreadSafe
 102  
 public class AutoCRSFactory extends DirectAuthorityFactory implements CRSAuthorityFactory {
 103  
     /**
 104  
      * The authority code. We use the {@code AUTO2} title, but merge the identifiers from
 105  
      * {@code AUTO} and {@code AUTO2} in order to use the same factory for both authorities.
 106  
      */
 107  
     private static final Citation AUTHORITY;
 108  
     static {
 109  1
         final DefaultCitation c = new DefaultCitation(Citations.AUTO2);
 110  1
         c.getIdentifiers().addAll(Citations.AUTO.getIdentifiers());
 111  1
         c.freeze();
 112  1
         AUTHORITY = c;
 113  1
     }
 114  
 
 115  
     /**
 116  
      * Map of Factlets by integer code (from {@code AUTO:code}).
 117  
      *
 118  
      * @todo Replace this with full FactorySPI system.
 119  
      */
 120  10
     private final Map<Integer,Factlet> factlets = new TreeMap<Integer,Factlet>();
 121  
 
 122  
     /**
 123  
      * Constructs a default factory for the {@code AUTO} authority.
 124  
      */
 125  
     public AutoCRSFactory() {
 126  10
         this(EMPTY_HINTS);
 127  10
     }
 128  
 
 129  
     /**
 130  
      * Constructs a factory for the {@code AUTO} authority using the specified hints.
 131  
      *
 132  
      * @param userHints An optional set of hints, or {@code null} for the default ones.
 133  
      */
 134  
     public AutoCRSFactory(final Hints userHints) {
 135  10
         super(userHints);
 136  10
         add(Auto42001.DEFAULT);
 137  10
         add(Auto42002.DEFAULT);
 138  10
         add(Auto42003.DEFAULT);
 139  10
         add(Auto42004.DEFAULT);
 140  10
         add(Auto42005.DEFAULT);
 141  10
     }
 142  
 
 143  
     /**
 144  
      * Adds the specified factlet.
 145  
      */
 146  
     private void add(final Factlet f) {
 147  50
         final int code = f.code();
 148  50
         if (factlets.put(code, f) != null) {
 149  0
             throw new IllegalArgumentException(String.valueOf(code));
 150  
         }
 151  50
     }
 152  
 
 153  
     /**
 154  
      * Returns the {@link Factlet} for the given code.
 155  
      *
 156  
      * @param  code The code.
 157  
      * @return The fatclet for the specified code.
 158  
      * @throws NoSuchAuthorityCodeException if no factlet has been found for the specified code.
 159  
      */
 160  
     private Factlet findFactlet(final Code code) throws NoSuchAuthorityCodeException {
 161  25
         if (code.authority.equalsIgnoreCase("AUTO") ||
 162  
             code.authority.equalsIgnoreCase("AUTO2"))
 163  
         {
 164  25
             final Integer key = code.code;
 165  25
             final Factlet fac = factlets.get(key);
 166  25
             if (fac != null) {
 167  25
                 return fac;
 168  
             }
 169  
         }
 170  0
         throw noSuchAuthorityCode(code.type, code.toString());
 171  
     }
 172  
 
 173  
     /**
 174  
      * Returns the authority for this factory.
 175  
      */
 176  
     @Override
 177  
     public Citation getAuthority() {
 178  449
         return AUTHORITY;
 179  
     }
 180  
 
 181  
     /**
 182  
      * Provides a complete set of the known codes provided by this authority.
 183  
      * The returned set contains only numeric identifiers like {@code "42001"},
 184  
      * {@code "42002"}, <i>etc</i>. The authority name ({@code "AUTO"})
 185  
      * and the {@code lon0,lat0} part are not included. This is consistent with the
 186  
      * {@linkplain org.geotoolkit.referencing.factory.epsg.DirectEpsgFactory#getAuthorityCodes
 187  
      * codes returned by the EPSG factory} and avoid duplication, since the authority is the
 188  
      * same for every codes returned by this factory. It also make it easier for clients to
 189  
      * prepend whatever authority name they wish, as for example in the
 190  
      * {@linkplain org.geotoolkit.referencing.factory.AllAuthoritiesFactory#getAuthorityCodes
 191  
      * all authorities factory}.
 192  
      */
 193  
     @Override
 194  
     public Set<String> getAuthorityCodes(final Class<? extends IdentifiedObject> type)
 195  
             throws FactoryException
 196  
     {
 197  5
         if (type.isAssignableFrom(ProjectedCRS.class)) {
 198  4
             final Set<String> set = new LinkedHashSet<String>();
 199  4
             for (final Integer code : factlets.keySet()) {
 200  20
                 set.add(String.valueOf(code));
 201  
             }
 202  4
             return set;
 203  
         } else {
 204  1
             return Collections.emptySet();
 205  
         }
 206  
     }
 207  
 
 208  
     /**
 209  
      * Returns the CRS name for the given code.
 210  
      *
 211  
      * @throws FactoryException if an error occurred while fetching the description.
 212  
      */
 213  
     @Override
 214  
     public InternationalString getDescriptionText(final String code) throws FactoryException {
 215  2
         final Code c = new Code(code, ProjectedCRS.class, false);
 216  2
         return new SimpleInternationalString(findFactlet(c).getName());
 217  
     }
 218  
 
 219  
     /**
 220  
      * Creates an object from the specified code. The default implementation delegates to
 221  
      * <code>{@linkplain #createCoordinateReferenceSystem createCoordinateReferenceSystem}(code)</code>.
 222  
      *
 223  
      * @throws FactoryException if the object creation failed.
 224  
      */
 225  
     @Override
 226  
     public IdentifiedObject createObject(final String code) throws FactoryException {
 227  13
         return createCoordinateReferenceSystem(code);
 228  
     }
 229  
 
 230  
     /**
 231  
      * Creates a coordinate reference system from the specified code. The default implementation
 232  
      * delegates to <code>{@linkplain #createProjectedCRS createProjectedCRS}(code)</code>.
 233  
      *
 234  
      * @throws FactoryException if the object creation failed.
 235  
      */
 236  
     @Override
 237  
     public CoordinateReferenceSystem createCoordinateReferenceSystem(final String code)
 238  
             throws FactoryException
 239  
     {
 240  23
         return createProjectedCRS(code);
 241  
     }
 242  
 
 243  
     /**
 244  
      * Creates a projected coordinate reference system from the specified code.
 245  
      *
 246  
      * @throws FactoryException if the object creation failed.
 247  
      */
 248  
     @Override
 249  
     public ProjectedCRS createProjectedCRS(final String code) throws FactoryException {
 250  47
         final Code c = new Code(code, ProjectedCRS.class, true);
 251  23
         return findFactlet(c).create(c, factories);
 252  
     }
 253  
 }