/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2004-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.crs; // J2SE dependencies import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.URL; import java.util.Hashtable; import java.util.Properties; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; // OpenGIS dependencies import org.opengis.metadata.citation.Citation; import org.opengis.referencing.FactoryException; import org.opengis.referencing.IdentifiedObject; import org.opengis.referencing.NoSuchAuthorityCodeException; import org.opengis.referencing.ObjectFactory; import org.opengis.referencing.crs.CRSAuthorityFactory; import org.opengis.referencing.crs.CRSFactory; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.crs.GeographicCRS; import org.opengis.referencing.crs.ProjectedCRS; import org.opengis.util.InternationalString; // Geotools dependencies import org.geotools.util.logging.Logging; import org.geotools.factory.AbstractFactory; import org.geotools.metadata.iso.citation.Citations; import org.geotools.referencing.ReferencingFactoryFinder; /** * Default implementation for a coordinate reference system authority factory backed * by the EPSG property file. This gives most of the benifits of using the EPSG * database backed authority factory, in a nice, portable property file. * * @source $URL$ * @version $Id$ * @author Jody Garnett * @author Rueben Schulz * * @deprecated Uses one of the other EPSG factories backed by a database instead. */ //not quite sure how I am going to create a new factory (what should the geoapi method be) public class EPSGCRSAuthorityFactory extends AbstractFactory implements CRSAuthorityFactory { private static final Logger LOGGER = Logging.getLogger("org.geotools.referencing.crs.EPSGCRSAuthorityFactory"); public static final String AUTHORITY = "EPSG"; public static final String AUTHORITY_PREFIX = "EPSG:"; //would be nice to cache crs objects for codes that have already been requested /** * The default coordinate system authority factory. * Will be constructed only when first requested. */ protected static EPSGCRSAuthorityFactory DEFAULT; /** * The properties object for our properties file. Keys are the EPSG * code for a coordinate reference system and the associated value is a * WKT string for the CRS. */ protected Properties epsg = new Properties(); //object factory protected CRSFactory crsFactory; /** Cache of parsed CoordinateReferenceSystem WKT by EPSG_NUMBER */ private Hashtable cache = new Hashtable(); /** * Loads from epsg.properties if the file exists, defaults to internal defintions * exported from postgis and cubeworks. */ public EPSGCRSAuthorityFactory() { this(ReferencingFactoryFinder.getCRSFactory(null)); } /** * Loads from epsg.properties if the file exists, defaults to internal defintions * exported from postgis and cubeworks. */ protected EPSGCRSAuthorityFactory(final CRSFactory factory ) { super(MINIMUM_PRIORITY); // Select EPSG-HSQL factory first. this.crsFactory = factory; try { loadDefault(); } catch( IOException oops ){ System.err.println("Could not load epsg.properties"+ oops ); } } /** * */ protected EPSGCRSAuthorityFactory(final CRSFactory factory, URL definition) throws FactoryException { this( factory ); try { epsg.load( definition.openStream() ); } catch (IOException io ){ // could not load properties file throw new FactoryException("Could not load properties file: " + definition); } } /** * Loads from epsg.properties if the file exists, defaults to internal defintions * exported from postgis and cubeworks. * * @throws IOException */ protected void loadDefault() throws IOException { // Check the application directory first // File file = new File("epsg.properties"); if( file.exists() ){ epsg.load( new FileInputStream( file )); } // Use the built-in property defintions // URL url = EPSGCRSAuthorityFactory.class.getResource("epsg.properties"); epsg.load( url.openStream() ); } /** * Returns a default coordinate system factory backed by the EPSG property file. * * @return The default factory. * @throws SQLException if the connection to the database can't be etablished. */ public synchronized static CRSAuthorityFactory getDefault() { if (DEFAULT == null) { DEFAULT = new EPSGCRSAuthorityFactory(); } return DEFAULT; } public synchronized CoordinateReferenceSystem createCoordinateReferenceSystem(String code) throws FactoryException { if (code == null) { return null; } if( !code.startsWith( AUTHORITY_PREFIX )){ throw new NoSuchAuthorityCodeException( "This factory only understand EPSG codes", AUTHORITY, code ); } final String EPSG_NUMBER = code.substring( code.indexOf(':')+1 ).trim(); if( cache.containsKey( EPSG_NUMBER ) ){ Object value = cache.get( EPSG_NUMBER ); if( value instanceof Throwable ){ throw new FactoryException( "WKT for "+code+" could not be parsed", (Throwable) value ); } if( value instanceof CoordinateReferenceSystem){ return (CoordinateReferenceSystem) value; } } String wkt = epsg.getProperty( EPSG_NUMBER ); if( wkt == null ) { throw new NoSuchAuthorityCodeException( "Unknown EPSG_NUMBER", AUTHORITY, code ); } if( wkt.indexOf( EPSG_NUMBER ) == -1){ wkt = wkt.trim(); wkt = wkt.substring(0, wkt.length()-1 ); wkt += ",AUTHORITY[\"EPSG\",\""+EPSG_NUMBER+"\"]]"; LOGGER.log(Level.WARNING, "EPSG:"+EPSG_NUMBER+" lacks a proper identifying authority in its Well-Known Text. It is being added programmatically."); } try { CoordinateReferenceSystem crs = crsFactory.createFromWKT(wkt); cache.put(EPSG_NUMBER, crs); return crs; } catch (FactoryException fex) { cache.put(EPSG_NUMBER, fex); throw fex; } } public IdentifiedObject createObject(String code) throws FactoryException { return createCoordinateReferenceSystem(code); } public ProjectedCRS createProjectedCRS(String code) throws FactoryException { return (ProjectedCRS) createCoordinateReferenceSystem(code); } public GeographicCRS createGeographicCRS(String code) throws FactoryException { return (GeographicCRS) createCoordinateReferenceSystem(code); } public Citation getAuthority() { return Citations.EPSG; } /** * Returns the set of authority codes of the given type. The type * argument specify the base class. For example if this factory is * an instance of CRSAuthorityFactory, then: *