/*
* 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.factory.wms;
// OpenGIS dependencies
import org.opengis.referencing.NoSuchAuthorityCodeException;
// Geotools dependencies
import org.geotools.measure.Latitude;
import org.geotools.measure.Longitude;
import org.geotools.resources.i18n.Errors;
import org.geotools.resources.i18n.ErrorKeys;
/**
* A code parsed by the {@link AutoCRSFactory} methods.
* The expected format is {@code AUTO:code,unit,lon0,lat0} where {@code AUTO} is optional.
*
* @source $URL$
* @version $Id$
* @author Jody Garnett
* @author Martin Desruisseaux
*/
final class Code {
/**
* The authority name. Should usually be {@code AUTO}.
*/
public final String authority;
/**
* The code number.
*/
public final int code;
/**
* The central longitude.
*/
public final double longitude;
/**
* The central latitude.
*/
public final double latitude;
/**
* The type of the CRS to be constructed (e.g. {@code GeographicCRS.class}).
* Used only in case of failure for constructing an error message.
*/
final Class type;
/**
* Parse the code string to retrive the code number and central longitude / latitude.
* Assumed format is {@code AUTO:code,lon0,lat0} where {@code AUTO} is optional.
*
* @param text The code in the {@code AUTO:code,lon0,lat0} format.
* @param The type of the CRS to be constructed (e.g. {@code GeographicCRS.class}).
* Used only in case of failure for constructing an error message.
* @throws NoSuchAuthorityCodeException if the specified code can't be parsed.
*/
public Code(final String text, final Class type) throws NoSuchAuthorityCodeException {
String authority = "AUTO";
int code = 0;
int unit = 9001;
double longitude = Double.NaN;
double latitude = Double.NaN;
// there are two syntaxes for the AUTO factory:
// AUTO:code,unit,longitude,latitude (from WMS 1.1 spec)
// AUTO:code,longitude,latitude (from early WMS specs)
// here we try to support both of them
// the AUTO prefix is optional, remove it if necessary (and support also AUTO2)
String[] parts;
if(text.startsWith("AUTO"))
parts = text.replaceAll("AUTO(2)?\\s*:", "").split("\\s*,\\s*");
else
parts = text.split("\\s*,\\s*");
// do we have enough components?
if(parts.length < 3) {
throw noSuchAuthorityCode(type, text);
}
try {
if(parts.length < 4) {
// code,lon,lat
code = Integer.parseInt (parts[0]);
longitude = Double.parseDouble(parts[1]);
latitude = Double.parseDouble(parts[2]);
} else {
// code,unit,lon,lat
code = Integer.parseInt (parts[0]);
unit = Integer.parseInt (parts[1]);
longitude = Double.parseDouble(parts[2]);
latitude = Double.parseDouble(parts[3]);
}
} catch(NumberFormatException exception) {
// If a number can't be parsed, then this is an invalid authority code.
NoSuchAuthorityCodeException e = noSuchAuthorityCode(type, text);
e.initCause(exception);
throw e;
}
if (!(longitude>=Longitude.MIN_VALUE && longitude<=Longitude.MAX_VALUE &&
latitude >= Latitude.MIN_VALUE && latitude <= Latitude.MAX_VALUE))
{
// A longitude or latitude is out of range, or was not present
// (i.e. the field still has a NaN value).
throw noSuchAuthorityCode(type, text);
}
this.authority = authority;
this.code = code;
this.longitude = longitude;
this.latitude = latitude;
this.type = type;
}
/**
* Creates an exception for an unknow authority code.
*
* @param type The GeoAPI interface that was to be created.
* @param code The unknow authority code.
* @return An exception initialized with an error message built from the specified informations.
*/
private static NoSuchAuthorityCodeException noSuchAuthorityCode(final Class type,
final String code)
{
final String authority = "AUTO";
return new NoSuchAuthorityCodeException(Errors.format(ErrorKeys.NO_SUCH_AUTHORITY_CODE_$3,
code, authority, type), authority, code);
}
/**
* Returns a string representation of this code.
*/
public String toString(){
return authority + ':' + code + ',' + longitude + ',' + latitude;
}
}