001    //$HeadURL: http://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/model/crs/CRSFactory.java $
002    /*----------------------------------------------------------------------------
003     This file is part of deegree, http://deegree.org/
004     Copyright (C) 2001-2009 by:
005     Department of Geography, University of Bonn
006     and
007     lat/lon GmbH
008    
009     This library is free software; you can redistribute it and/or modify it under
010     the terms of the GNU Lesser General Public License as published by the Free
011     Software Foundation; either version 2.1 of the License, or (at your option)
012     any later version.
013     This library is distributed in the hope that it will be useful, but WITHOUT
014     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016     details.
017     You should have received a copy of the GNU Lesser General Public License
018     along with this library; if not, write to the Free Software Foundation, Inc.,
019     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020    
021     Contact information:
022    
023     lat/lon GmbH
024     Aennchenstr. 19, 53177 Bonn
025     Germany
026     http://lat-lon.de/
027    
028     Department of Geography, University of Bonn
029     Prof. Dr. Klaus Greve
030     Postfach 1147, 53001 Bonn
031     Germany
032     http://www.geographie.uni-bonn.de/deegree/
033    
034     e-mail: info@deegree.org
035     ----------------------------------------------------------------------------*/
036    package org.deegree.model.crs;
037    
038    import javax.vecmath.Point2d;
039    
040    import org.deegree.crs.Identifiable;
041    import org.deegree.crs.components.Axis;
042    import org.deegree.crs.components.Ellipsoid;
043    import org.deegree.crs.components.GeodeticDatum;
044    import org.deegree.crs.components.Unit;
045    import org.deegree.crs.configuration.CRSConfiguration;
046    import org.deegree.crs.configuration.CRSProvider;
047    import org.deegree.crs.coordinatesystems.GeographicCRS;
048    import org.deegree.crs.coordinatesystems.ProjectedCRS;
049    import org.deegree.crs.exceptions.CRSConfigurationException;
050    import org.deegree.crs.projections.cylindric.TransverseMercator;
051    import org.deegree.crs.transformations.Transformation;
052    import org.deegree.crs.transformations.helmert.Helmert;
053    import org.deegree.framework.log.ILogger;
054    import org.deegree.framework.log.LoggerFactory;
055    import org.deegree.framework.util.BootLogger;
056    
057    /**
058     * 
059     * The <code>CRSFactory</code> class wraps the access to the CRSProvider in the org.deegree.crs package by supplying a
060     * static create method, thus encapsulating the access to the CoordinateSystems.
061     * 
062     * @author <a href="mailto:bezema@lat-lon.de">Rutger Bezema</a>
063     * 
064     * @author last edited by: $Author: apoth $
065     * 
066     * @version $Revision: 31743 $, $Date: 2011-09-05 11:24:03 +0200 (Mo, 05 Sep 2011) $
067     * 
068     */
069    public class CRSFactory {
070    
071        private static ILogger LOG = LoggerFactory.getLogger( CRSFactory.class );
072    
073        public static CoordinateSystem EPSG_4326;
074        static {
075            if ( EPSG_4326 == null ) {
076                try {
077                    EPSG_4326 = CRSFactory.create( "EPSG:4326" );
078                } catch ( UnknownCRSException e ) {
079                    BootLogger.logError( e.getMessage(), e );
080                }
081            }
082        }
083    
084        private synchronized static CRSProvider getProvider( String providerName ) {
085            CRSConfiguration crsConfig = CRSConfiguration.getCRSConfiguration( providerName );
086            return crsConfig.getProvider();
087        }
088    
089        /**
090         * Creates a CRS from the given name using the given provider, if no CRS was found an UnkownCRSException will be
091         * thrown.
092         * 
093         * @param providerName
094         *            to be used for the creation of the crs.
095         * @param name
096         *            of the crs, e.g. EPSG:31466
097         * @return a CoordinateSystem corresponding to the given name
098         * @throws UnknownCRSException
099         *             if the crs-name is not known
100         */
101        public synchronized static CoordinateSystem create( String providerName, String name )
102                                throws UnknownCRSException {
103            CRSProvider crsProvider = getProvider( providerName );
104            org.deegree.crs.coordinatesystems.CoordinateSystem realCRS = null;
105            try {
106                realCRS = crsProvider.getCRSByID( name );
107            } catch ( CRSConfigurationException e ) {
108                LOG.logError( e.getMessage(), e );
109            }
110            if ( realCRS == null ) {
111                throw new UnknownCRSException( name );
112            }
113            LOG.logDebug( "Successfully created the crs with id: " + name );
114            return new CoordinateSystem( realCRS, name );
115        }
116    
117        /**
118         * Get a {@link Transformation} with given id, or <code>null</code> if it does not exist.
119         * 
120         * @param providerName
121         *            to use.
122         * @param id
123         *            of the Transformation.
124         * @return the identified transformation or <code>null<code> if no such transformation is found.
125         */
126        public synchronized static Transformation getTransformation( String providerName, String id ) {
127            CRSProvider crsProvider = getProvider( providerName );
128            Identifiable t = crsProvider.getIdentifiable( id );
129            if ( t instanceof Transformation ) {
130                return (Transformation) t;
131            }
132            LOG.logDebug( "The given id: " + id + " is not of type transformation return null." );
133            return null;
134        }
135    
136        /**
137         * Retrieve a {@link Transformation} (chain) which transforms coordinates from the given source into the given
138         * target crs. If no such {@link Transformation} could be found or the implementation does not support inverse
139         * lookup of transformations <code>null<code> will be returned.
140         * 
141         * @param providerName
142         *            to use.
143         * @param sourceCRS
144         *            start of the transformation (chain)
145         * @param targetCRS
146         *            end point of the transformation (chain).
147         * @return the given {@link Transformation} or <code>null<code> if no such transformation was found.
148         */
149        public synchronized static Transformation getTransformation( String providerName, CoordinateSystem sourceCRS,
150                                                                     CoordinateSystem targetCRS ) {
151            CRSProvider crsProvider = getProvider( providerName );
152            return crsProvider.getTransformation( sourceCRS.getCRS(), targetCRS.getCRS() );
153        }
154    
155        /**
156         * Creates a CRS from the given name, if no CRS was found an UnkownCRSException will be thrown.
157         * 
158         * @param name
159         *            of the crs, e.g. EPSG:4326
160         * @return a CoordinateSystem corresponding to the given name, using the configured provider.
161         * @throws UnknownCRSException
162         *             if the crs-name is not known
163         */
164        public synchronized static CoordinateSystem create( String name )
165                                throws UnknownCRSException {
166            return create( null, name );
167        }
168    
169        /**
170         * Wrapper for the private constructor of the org.deegree.model.crs.CoordinateSystem class.
171         * 
172         * @param realCRS
173         *            to wrap
174         * 
175         * @return a CoordinateSystem corresponding to the given crs.
176         */
177        public static CoordinateSystem create( org.deegree.crs.coordinatesystems.CoordinateSystem realCRS ) {
178            return new CoordinateSystem( realCRS, realCRS.getIdentifier() );
179        }
180    
181        /**
182         * Wrapper for the private constructor to create a dummy projected crs with no projection parameters set, the
183         * standard wgs84 datum and the given optional name as the identifier. X-Y axis are in metres.
184         * 
185         * @param name
186         *            optional identifier, if missing, the word 'dummy' will be used.
187         * 
188         * @return a dummy CoordinateSystem having filled out all the essential values.
189         */
190        public static CoordinateSystem createDummyCRS( String name ) {
191            if ( name == null || "".equals( name.trim() ) ) {
192                name = "dummy";
193            }
194            /**
195             * Standard axis of a geographic crs
196             */
197            final Axis[] axis_degree = new Axis[] { new Axis( Unit.DEGREE, "lon", Axis.AO_EAST ),
198                                                   new Axis( Unit.DEGREE, "lat", Axis.AO_NORTH ) };
199            final Axis[] axis_projection = new Axis[] { new Axis( "x", Axis.AO_EAST ), new Axis( "y", Axis.AO_NORTH ) };
200    
201            final Helmert wgs_info = new Helmert( GeographicCRS.WGS84, GeographicCRS.WGS84, name + "_wgs" );
202            final GeodeticDatum datum = new GeodeticDatum( Ellipsoid.WGS84, wgs_info, new String[] { name + "_datum" } );
203            final GeographicCRS geographicCRS = new GeographicCRS( datum, axis_degree, new String[] { name
204                                                                                                      + "geographic_crs" } );
205            final TransverseMercator projection = new TransverseMercator( true, geographicCRS, 0, 0, new Point2d( 0, 0 ),
206                                                                          Unit.METRE, 1 );
207    
208            return new CoordinateSystem(
209                                         new ProjectedCRS( projection, axis_projection, new String[] { name
210                                                                                                       + "projected_crs" } ),
211                                         name );
212    
213        }
214    }