001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2005-2006, GeoTools Project Managment Committee (PMC)
005: * (C) 2005, Institut de Recherche pour le Développement
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation;
010: * version 2.1 of the License.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * This package contains documentation from OpenGIS specifications.
018: * OpenGIS consortium's work is fully acknowledged here.
019: */
020: package org.geotools.referencing.factory;
021:
022: // J2SE dependencies
023: import java.util.Set;
024: import java.util.Collections;
025: import javax.units.Unit;
026:
027: // OpenGIS dependencies
028: import org.opengis.referencing.*;
029: import org.opengis.referencing.cs.*;
030: import org.opengis.referencing.crs.*;
031: import org.opengis.referencing.datum.*;
032: import org.opengis.referencing.operation.*;
033: import org.opengis.util.InternationalString;
034: import org.opengis.metadata.extent.Extent;
035: import org.opengis.metadata.citation.Citation;
036: import org.opengis.parameter.ParameterDescriptor;
037: import org.opengis.util.GenericName;
038:
039: // Geotools dependencies
040: import org.geotools.referencing.AbstractIdentifiedObject;
041: import org.geotools.metadata.iso.citation.Citations;
042: import org.geotools.resources.i18n.ErrorKeys;
043: import org.geotools.resources.i18n.Errors;
044: import org.geotools.resources.Utilities;
045: import org.geotools.util.NameFactory;
046:
047: /**
048: * Base class for authority factories. An <cite>authority</cite> is an organization that maintains
049: * definitions of authority codes. An <cite>authority code</cite> is a compact string defined by
050: * an authority to reference a particular spatial reference object. For example the
051: * <A HREF="http://www.epsg.org">European Petroleum Survey Group (EPSG)</A> maintains
052: * a database of coordinate systems, and other spatial referencing objects, where each
053: * object has a code number ID. For example, the EPSG code for a WGS84 Lat/Lon coordinate
054: * system is {@code "4326"}.
055: * <p>
056: * This class defines a default implementation for most methods defined in the
057: * {@link DatumAuthorityFactory}, {@link CSAuthorityFactory} and {@link CRSAuthorityFactory}
058: * interfaces. However, those interfaces do not appear in the {@code implements} clause of
059: * this class declaration. This is up to subclasses to decide which interfaces they declare
060: * to implement.
061: * <p>
062: * The default implementation for all {@code createFoo} methods ultimately invokes
063: * {@link #createObject}, which may be the only method that a subclass need to override.
064: * However, other methods may be overridden as well for better performances.
065: *
066: * @since 2.1
067: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/referencing/factory/AbstractAuthorityFactory.java $
068: * @version $Id: AbstractAuthorityFactory.java 26212 2007-07-12 02:34:18Z jgarnett $
069: * @author Martin Desruisseaux
070: */
071: public abstract class AbstractAuthorityFactory extends
072: ReferencingFactory implements AuthorityFactory {
073: /**
074: * Constructs an instance using the specified priority level.
075: *
076: * @param priority The priority for this factory, as a number between
077: * {@link #MINIMUM_PRIORITY MINIMUM_PRIORITY} and
078: * {@link #MAXIMUM_PRIORITY MAXIMUM_PRIORITY} inclusive.
079: */
080: protected AbstractAuthorityFactory(final int priority) {
081: super (priority);
082: }
083:
084: /**
085: * Returns {@code true} if this factory is available. This method may returns {@code false}
086: * for example if a connection to the EPSG database failed. This method is defined here for
087: * implementation convenience, but not yet public because not yet applicable. It will be made
088: * public in {@link DeferredAuthorityFactory} and {@link AuthorityFactoryAdapter} subclasses,
089: * which implement the {@link org.geotools.factory.OptionalFactory} interface.
090: */
091: boolean isAvailable() {
092: return true;
093: }
094:
095: /**
096: * If this factory is a wrapper for the specified factory that do not add any additional
097: * {@linkplain #getAuthorityCodes authority codes}, returns {@code true}. Example of such
098: * wrappers are {@link BufferedAuthorityFactory} and {@link TransformedAuthorityFactory}.
099: * <p>
100: * This method should perform a cheap test. It is for {@link FallbackAuthorityFactory}
101: * internal use only and should not be public.
102: */
103: boolean sameAuthorityCodes(final AuthorityFactory factory) {
104: return factory == this ;
105: }
106:
107: /**
108: * Returns the organization or party responsible for definition and maintenance of the
109: * database.
110: */
111: public abstract Citation getAuthority();
112:
113: /**
114: * Returns a description of the underlying backing store, or {@code null} if unknown.
115: * This is for example the database software used for storing the data.
116: * The default implementation returns always {@code null}.
117: *
118: * @throws FactoryException if a failure occurs while fetching the engine description.
119: */
120: public String getBackingStoreDescription() throws FactoryException {
121: return null;
122: }
123:
124: /**
125: * Returns an arbitrary object from a code. The returned object will typically be an instance
126: * of {@link Datum}, {@link CoordinateSystem}, {@link CoordinateReferenceSystem} or
127: * {@link CoordinateOperation}. The default implementation always throw an exception.
128: * Subclasses should override this method if they are capable to automatically detect
129: * the object type from its code.
130: *
131: * @param code Value allocated by authority.
132: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
133: * @throws FactoryException if the object creation failed for some other reason.
134: *
135: * @see #createCoordinateReferenceSystem
136: * @see #createDatum
137: * @see #createEllipsoid
138: * @see #createUnit
139: */
140: public IdentifiedObject createObject(final String code)
141: throws FactoryException {
142: ensureNonNull("code", code);
143: throw noSuchAuthorityCode(IdentifiedObject.class, code);
144: }
145:
146: /**
147: * Returns an arbitrary {@linkplain Datum datum} from a code.
148: * The default implementation invokes <code>{@linkplain #createObject createObject}(code)</code>.
149: *
150: * @param code Value allocated by authority.
151: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
152: * @throws FactoryException if the object creation failed for some other reason.
153: *
154: * @see #createGeodeticDatum
155: * @see #createVerticalDatum
156: * @see #createTemporalDatum
157: */
158: public Datum createDatum(final String code) throws FactoryException {
159: final IdentifiedObject object = createObject(code);
160: try {
161: return (Datum) object;
162: } catch (ClassCastException exception) {
163: throw noSuchAuthorityCode(Datum.class, code, exception);
164: }
165: }
166:
167: /**
168: * Creates a {@linkplain EngineeringDatum engineering datum} from a code.
169: * The default implementation invokes <code>{@linkplain #createDatum createDatum}(code)</code>.
170: *
171: * @param code Value allocated by authority.
172: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
173: * @throws FactoryException if the object creation failed for some other reason.
174: *
175: * @see #createEngineeringCRS
176: */
177: public EngineeringDatum createEngineeringDatum(final String code)
178: throws FactoryException {
179: final Datum datum = createDatum(code);
180: try {
181: return (EngineeringDatum) datum;
182: } catch (ClassCastException exception) {
183: throw noSuchAuthorityCode(EngineeringDatum.class, code,
184: exception);
185: }
186: }
187:
188: /**
189: * Creates a {@linkplain ImageDatum image datum} from a code.
190: * The default implementation invokes <code>{@linkplain #createDatum createDatum}(code)</code>.
191: *
192: * @param code Value allocated by authority.
193: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
194: * @throws FactoryException if the object creation failed for some other reason.
195: *
196: * @see #createImageCRS
197: */
198: public ImageDatum createImageDatum(final String code)
199: throws FactoryException {
200: final Datum datum = createDatum(code);
201: try {
202: return (ImageDatum) datum;
203: } catch (ClassCastException exception) {
204: throw noSuchAuthorityCode(ImageDatum.class, code, exception);
205: }
206: }
207:
208: /**
209: * Creates a {@linkplain VerticalDatum vertical datum} from a code.
210: * The default implementation invokes <code>{@linkplain #createDatum createDatum}(code)</code>.
211: *
212: * @param code Value allocated by authority.
213: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
214: * @throws FactoryException if the object creation failed for some other reason.
215: *
216: * @see #createVerticalCRS
217: */
218: public VerticalDatum createVerticalDatum(final String code)
219: throws FactoryException {
220: final Datum datum = createDatum(code);
221: try {
222: return (VerticalDatum) datum;
223: } catch (ClassCastException exception) {
224: throw noSuchAuthorityCode(VerticalDatum.class, code,
225: exception);
226: }
227: }
228:
229: /**
230: * Creates a {@linkplain TemporalDatum temporal datum} from a code.
231: * The default implementation invokes <code>{@linkplain #createDatum createDatum}(code)</code>.
232: *
233: * @param code Value allocated by authority.
234: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
235: * @throws FactoryException if the object creation failed for some other reason.
236: *
237: * @see #createTemporalCRS
238: */
239: public TemporalDatum createTemporalDatum(final String code)
240: throws FactoryException {
241: final Datum datum = createDatum(code);
242: try {
243: return (TemporalDatum) datum;
244: } catch (ClassCastException exception) {
245: throw noSuchAuthorityCode(TemporalDatum.class, code,
246: exception);
247: }
248: }
249:
250: /**
251: * Returns a {@linkplain GeodeticDatum geodetic datum} from a code.
252: * The default implementation invokes <code>{@linkplain #createDatum createDatum}(code)</code>.
253: *
254: * @param code Value allocated by authority.
255: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
256: * @throws FactoryException if the object creation failed for some other reason.
257: *
258: * @see #createEllipsoid
259: * @see #createPrimeMeridian
260: * @see #createGeographicCRS
261: * @see #createProjectedCRS
262: */
263: public GeodeticDatum createGeodeticDatum(final String code)
264: throws FactoryException {
265: final Datum datum = createDatum(code);
266: try {
267: return (GeodeticDatum) datum;
268: } catch (ClassCastException exception) {
269: throw noSuchAuthorityCode(GeodeticDatum.class, code,
270: exception);
271: }
272: }
273:
274: /**
275: * Returns an {@linkplain Ellipsoid ellipsoid} from a code.
276: * The default implementation invokes <code>{@linkplain #createObject createObject}(code)</code>.
277: *
278: * @param code Value allocated by authority.
279: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
280: * @throws FactoryException if the object creation failed for some other reason.
281: *
282: * @see #createGeodeticDatum
283: */
284: public Ellipsoid createEllipsoid(final String code)
285: throws FactoryException {
286: final IdentifiedObject object = createObject(code);
287: try {
288: return (Ellipsoid) object;
289: } catch (ClassCastException exception) {
290: throw noSuchAuthorityCode(Ellipsoid.class, code, exception);
291: }
292: }
293:
294: /**
295: * Returns a {@linkplain PrimeMeridian prime meridian} from a code.
296: * The default implementation invokes <code>{@linkplain #createObject createObject}(code)</code>.
297: *
298: * @param code Value allocated by authority.
299: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
300: * @throws FactoryException if the object creation failed for some other reason.
301: *
302: * @see #createGeodeticDatum
303: */
304: public PrimeMeridian createPrimeMeridian(final String code)
305: throws FactoryException {
306: final IdentifiedObject object = createObject(code);
307: try {
308: return (PrimeMeridian) object;
309: } catch (ClassCastException exception) {
310: throw noSuchAuthorityCode(PrimeMeridian.class, code,
311: exception);
312: }
313: }
314:
315: /**
316: * Returns a {@linkplain Extent extent} (usually an area of validity) from a code.
317: * The default implementation invokes <code>{@linkplain #createObject createObject}(code)</code>.
318: *
319: * @param code Value allocated by authority.
320: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
321: * @throws FactoryException if the object creation failed for some other reason.
322: */
323: public Extent createExtent(final String code)
324: throws FactoryException {
325: final IdentifiedObject object = createObject(code);
326: try {
327: return (Extent) object;
328: } catch (ClassCastException exception) {
329: throw noSuchAuthorityCode(Extent.class, code, exception);
330: }
331: }
332:
333: /**
334: * Returns an arbitrary {@linkplain CoordinateSystem coordinate system} from a code.
335: * The default implementation invokes <code>{@linkplain #createObject createObject}(code)</code>.
336: *
337: * @param code Value allocated by authority.
338: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
339: * @throws FactoryException if the object creation failed for some other reason.
340: */
341: public CoordinateSystem createCoordinateSystem(final String code)
342: throws FactoryException {
343: final IdentifiedObject object = createObject(code);
344: try {
345: return (CoordinateSystem) object;
346: } catch (ClassCastException exception) {
347: throw noSuchAuthorityCode(CoordinateSystem.class, code,
348: exception);
349: }
350: }
351:
352: /**
353: * Creates a cartesian coordinate system from a code.
354: * The default implementation invokes
355: * <code>{@linkplain #createCoordinateSystem createCoordinateSystem}(code)</code>.
356: *
357: * @param code Value allocated by authority.
358: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
359: * @throws FactoryException if the object creation failed for some other reason.
360: */
361: public CartesianCS createCartesianCS(final String code)
362: throws FactoryException {
363: final CoordinateSystem cs = createCoordinateSystem(code);
364: try {
365: return (CartesianCS) cs;
366: } catch (ClassCastException exception) {
367: throw noSuchAuthorityCode(CartesianCS.class, code,
368: exception);
369: }
370: }
371:
372: /**
373: * Creates a polar coordinate system from a code.
374: * The default implementation invokes
375: * <code>{@linkplain #createCoordinateSystem createCoordinateSystem}(code)</code>.
376: *
377: * @param code Value allocated by authority.
378: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
379: * @throws FactoryException if the object creation failed for some other reason.
380: */
381: public PolarCS createPolarCS(final String code)
382: throws FactoryException {
383: final CoordinateSystem cs = createCoordinateSystem(code);
384: try {
385: return (PolarCS) cs;
386: } catch (ClassCastException exception) {
387: throw noSuchAuthorityCode(PolarCS.class, code, exception);
388: }
389: }
390:
391: /**
392: * Creates a cylindrical coordinate system from a code.
393: * The default implementation invokes
394: * <code>{@linkplain #createCoordinateSystem createCoordinateSystem}(code)</code>.
395: *
396: * @param code Value allocated by authority.
397: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
398: * @throws FactoryException if the object creation failed for some other reason.
399: */
400: public CylindricalCS createCylindricalCS(final String code)
401: throws FactoryException {
402: final CoordinateSystem cs = createCoordinateSystem(code);
403: try {
404: return (CylindricalCS) cs;
405: } catch (ClassCastException exception) {
406: throw noSuchAuthorityCode(CylindricalCS.class, code,
407: exception);
408: }
409: }
410:
411: /**
412: * Creates a spherical coordinate system from a code.
413: * The default implementation invokes
414: * <code>{@linkplain #createCoordinateSystem createCoordinateSystem}(code)</code>.
415: *
416: * @param code Value allocated by authority.
417: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
418: * @throws FactoryException if the object creation failed for some other reason.
419: */
420: public SphericalCS createSphericalCS(final String code)
421: throws FactoryException {
422: final CoordinateSystem cs = createCoordinateSystem(code);
423: try {
424: return (SphericalCS) cs;
425: } catch (ClassCastException exception) {
426: throw noSuchAuthorityCode(SphericalCS.class, code,
427: exception);
428: }
429: }
430:
431: /**
432: * Creates an ellipsoidal coordinate system from a code.
433: * The default implementation invokes
434: * <code>{@linkplain #createCoordinateSystem createCoordinateSystem}(code)</code>.
435: *
436: * @param code Value allocated by authority.
437: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
438: * @throws FactoryException if the object creation failed for some other reason.
439: */
440: public EllipsoidalCS createEllipsoidalCS(final String code)
441: throws FactoryException {
442: final CoordinateSystem cs = createCoordinateSystem(code);
443: try {
444: return (EllipsoidalCS) cs;
445: } catch (ClassCastException exception) {
446: throw noSuchAuthorityCode(EllipsoidalCS.class, code,
447: exception);
448: }
449: }
450:
451: /**
452: * Creates a vertical coordinate system from a code.
453: * The default implementation invokes
454: * <code>{@linkplain #createCoordinateSystem createCoordinateSystem}(code)</code>.
455: *
456: * @param code Value allocated by authority.
457: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
458: * @throws FactoryException if the object creation failed for some other reason.
459: */
460: public VerticalCS createVerticalCS(final String code)
461: throws FactoryException {
462: final CoordinateSystem cs = createCoordinateSystem(code);
463: try {
464: return (VerticalCS) cs;
465: } catch (ClassCastException exception) {
466: throw noSuchAuthorityCode(VerticalCS.class, code, exception);
467: }
468: }
469:
470: /**
471: * Creates a temporal coordinate system from a code.
472: * The default implementation invokes
473: * <code>{@linkplain #createCoordinateSystem createCoordinateSystem}(code)</code>.
474: *
475: * @param code Value allocated by authority.
476: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
477: * @throws FactoryException if the object creation failed for some other reason.
478: */
479: public TimeCS createTimeCS(final String code)
480: throws FactoryException {
481: final CoordinateSystem cs = createCoordinateSystem(code);
482: try {
483: return (TimeCS) cs;
484: } catch (ClassCastException exception) {
485: throw noSuchAuthorityCode(TimeCS.class, code, exception);
486: }
487: }
488:
489: /**
490: * Returns a {@linkplain CoordinateSystemAxis coordinate system axis} from a code.
491: * The default implementation invokes <code>{@linkplain #createObject createObject}(code)</code>.
492: *
493: * @param code Value allocated by authority.
494: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
495: * @throws FactoryException if the object creation failed for some other reason.
496: */
497: public CoordinateSystemAxis createCoordinateSystemAxis(
498: final String code) throws FactoryException {
499: final IdentifiedObject object = createObject(code);
500: try {
501: return (CoordinateSystemAxis) object;
502: } catch (ClassCastException exception) {
503: throw noSuchAuthorityCode(CoordinateSystemAxis.class, code,
504: exception);
505: }
506: }
507:
508: /**
509: * Returns an {@linkplain Unit unit} from a code.
510: * The default implementation invokes <code>{@linkplain #createObject createObject}(code)</code>.
511: *
512: * @param code Value allocated by authority.
513: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
514: * @throws FactoryException if the object creation failed for some other reason.
515: */
516: public Unit createUnit(final String code) throws FactoryException {
517: final IdentifiedObject object = createObject(code);
518: try {
519: return (Unit) object;
520: } catch (ClassCastException exception) {
521: throw noSuchAuthorityCode(Unit.class, code, exception);
522: }
523: }
524:
525: /**
526: * Returns an arbitrary {@linkplain CoordinateReferenceSystem coordinate reference system}
527: * from a code. If the coordinate reference system type is know at compile time, it is
528: * recommended to invoke the most precise method instead of this one (for example
529: * <code> {@linkplain #createGeographicCRS createGeographicCRS}(code) </code>
530: * instead of <code> createCoordinateReferenceSystem(code) </code> if the caller
531: * know he is asking for a {@linkplain GeographicCRS geographic coordinate reference system}).
532: *
533: * @param code Value allocated by authority.
534: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
535: * @throws FactoryException if the object creation failed for some other reason.
536: *
537: * @see #createGeographicCRS
538: * @see #createProjectedCRS
539: * @see #createVerticalCRS
540: * @see #createTemporalCRS
541: * @see #createCompoundCRS
542: */
543: public CoordinateReferenceSystem createCoordinateReferenceSystem(
544: final String code) throws FactoryException {
545: final IdentifiedObject object = createObject(code);
546: try {
547: return (CoordinateReferenceSystem) object;
548: } catch (ClassCastException exception) {
549: throw noSuchAuthorityCode(CoordinateReferenceSystem.class,
550: code, exception);
551: }
552: }
553:
554: /**
555: * Creates a 3D coordinate reference system from a code.
556: *
557: * @param code Value allocated by authority.
558: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
559: * @throws FactoryException if the object creation failed for some other reason.
560: */
561: public CompoundCRS createCompoundCRS(final String code)
562: throws FactoryException {
563: final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
564: try {
565: return (CompoundCRS) crs;
566: } catch (ClassCastException exception) {
567: throw noSuchAuthorityCode(CompoundCRS.class, code,
568: exception);
569: }
570: }
571:
572: /**
573: * Creates a derived coordinate reference system from a code.
574: *
575: * @param code Value allocated by authority.
576: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
577: * @throws FactoryException if the object creation failed for some other reason.
578: */
579: public DerivedCRS createDerivedCRS(final String code)
580: throws FactoryException {
581: final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
582: try {
583: return (DerivedCRS) crs;
584: } catch (ClassCastException exception) {
585: throw noSuchAuthorityCode(DerivedCRS.class, code, exception);
586: }
587: }
588:
589: /**
590: * Creates a {@linkplain EngineeringCRS engineering coordinate reference system} from a code.
591: *
592: * @param code Value allocated by authority.
593: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
594: * @throws FactoryException if the object creation failed for some other reason.
595: */
596: public EngineeringCRS createEngineeringCRS(final String code)
597: throws FactoryException {
598: final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
599: try {
600: return (EngineeringCRS) crs;
601: } catch (ClassCastException exception) {
602: throw noSuchAuthorityCode(EngineeringCRS.class, code,
603: exception);
604: }
605: }
606:
607: /**
608: * Returns a {@linkplain GeographicCRS geographic coordinate reference system} from a code.
609: *
610: * @param code Value allocated by authority.
611: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
612: * @throws FactoryException if the object creation failed for some other reason.
613: *
614: * @see #createGeodeticDatum
615: */
616: public GeographicCRS createGeographicCRS(final String code)
617: throws FactoryException {
618: final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
619: try {
620: return (GeographicCRS) crs;
621: } catch (ClassCastException exception) {
622: throw noSuchAuthorityCode(GeographicCRS.class, code,
623: exception);
624: }
625: }
626:
627: /**
628: * Returns a {@linkplain GeocentricCRS geocentric coordinate reference system} from a code.
629: *
630: * @param code Value allocated by authority.
631: * @throws FactoryException if the object creation failed.
632: *
633: * @see #createGeodeticDatum
634: */
635: public GeocentricCRS createGeocentricCRS(final String code)
636: throws FactoryException {
637: final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
638: try {
639: return (GeocentricCRS) crs;
640: } catch (ClassCastException exception) {
641: throw noSuchAuthorityCode(GeocentricCRS.class, code,
642: exception);
643: }
644: }
645:
646: /**
647: * Creates a {@linkplain ImageCRS image coordinate reference system} from a code.
648: *
649: * @param code Value allocated by authority.
650: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
651: * @throws FactoryException if the object creation failed for some other reason.
652: */
653: public ImageCRS createImageCRS(final String code)
654: throws FactoryException {
655: final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
656: try {
657: return (ImageCRS) crs;
658: } catch (ClassCastException exception) {
659: throw noSuchAuthorityCode(ImageCRS.class, code, exception);
660: }
661: }
662:
663: /**
664: * Returns a {@linkplain ProjectedCRS projected coordinate reference system} from a code.
665: *
666: * @param code Value allocated by authority.
667: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
668: * @throws FactoryException if the object creation failed for some other reason.
669: *
670: * @see #createGeodeticDatum
671: */
672: public ProjectedCRS createProjectedCRS(final String code)
673: throws FactoryException {
674: final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
675: try {
676: return (ProjectedCRS) crs;
677: } catch (ClassCastException exception) {
678: throw noSuchAuthorityCode(ProjectedCRS.class, code,
679: exception);
680: }
681: }
682:
683: /**
684: * Creates a {@linkplain TemporalCRS temporal coordinate reference system} from a code.
685: *
686: * @param code Value allocated by authority.
687: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
688: * @throws FactoryException if the object creation failed for some other reason.
689: *
690: * @see #createTemporalDatum
691: */
692: public TemporalCRS createTemporalCRS(final String code)
693: throws FactoryException {
694: final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
695: try {
696: return (TemporalCRS) crs;
697: } catch (ClassCastException exception) {
698: throw noSuchAuthorityCode(TemporalCRS.class, code,
699: exception);
700: }
701: }
702:
703: /**
704: * Creates a {@linkplain VerticalCRS vertical coordinate reference system} from a code.
705: *
706: * @param code Value allocated by authority.
707: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
708: * @throws FactoryException if the object creation failed for some other reason.
709: *
710: * @see #createVerticalDatum
711: */
712: public VerticalCRS createVerticalCRS(final String code)
713: throws FactoryException {
714: final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
715: try {
716: return (VerticalCRS) crs;
717: } catch (ClassCastException exception) {
718: throw noSuchAuthorityCode(VerticalCRS.class, code,
719: exception);
720: }
721: }
722:
723: /**
724: * Creates a parameter descriptor from a code.
725: *
726: * @param code Value allocated by authority.
727: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
728: * @throws FactoryException if the object creation failed for some other reason.
729: *
730: * @since 2.2
731: */
732: public ParameterDescriptor createParameterDescriptor(
733: final String code) throws FactoryException {
734: final IdentifiedObject operation = createObject(code);
735: try {
736: return (ParameterDescriptor) operation;
737: } catch (ClassCastException exception) {
738: throw noSuchAuthorityCode(ParameterDescriptor.class, code,
739: exception);
740: }
741: }
742:
743: /**
744: * Creates an operation method from a code.
745: *
746: * @param code Value allocated by authority.
747: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
748: * @throws FactoryException if the object creation failed for some other reason.
749: *
750: * @since 2.2
751: */
752: public OperationMethod createOperationMethod(final String code)
753: throws FactoryException {
754: final IdentifiedObject operation = createObject(code);
755: try {
756: return (OperationMethod) operation;
757: } catch (ClassCastException exception) {
758: throw noSuchAuthorityCode(OperationMethod.class, code,
759: exception);
760: }
761: }
762:
763: /**
764: * Creates an operation from a single operation code.
765: *
766: * @param code Value allocated by authority.
767: * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
768: * @throws FactoryException if the object creation failed for some other reason.
769: *
770: * @since 2.2
771: */
772: public CoordinateOperation createCoordinateOperation(
773: final String code) throws FactoryException {
774: final IdentifiedObject operation = createObject(code);
775: try {
776: return (CoordinateOperation) operation;
777: } catch (ClassCastException exception) {
778: throw noSuchAuthorityCode(CoordinateOperation.class, code,
779: exception);
780: }
781: }
782:
783: /**
784: * Creates an operation from coordinate reference system codes. The default implementation
785: * returns an {@linkplain Collections#EMPTY_SET empty set}. We do not delegate to some kind
786: * of {@linkplain CoordinateOperationFactory#createOperation(CoordinateReferenceSystem,
787: * CoordinateReferenceSystem) coordinate operation factory method} because the usual contract
788: * for this method is to extract the information from an authority database like
789: * <A HREF="http://www.epsg.org">EPSG</A>, not to compute operations on-the-fly.
790: * <p>
791: * <strong>Rational:</strong> Coordinate operation factory
792: * {@linkplain org.geotools.referencing.operation.AuthorityBackedFactory backed by an authority}
793: * will invoke this method. If this method invoked the coordinate operation factory in turn, the
794: * application could be trapped in infinite recursive calls.
795: *
796: * @param sourceCode Coded value of source coordinate reference system.
797: * @param targetCode Coded value of target coordinate reference system.
798: *
799: * @throws NoSuchAuthorityCodeException if a specified code was not found.
800: * @throws FactoryException if the object creation failed for some other reason.
801: *
802: * @since 2.2
803: */
804: public Set/*<CoordinateOperation>*/createFromCoordinateReferenceSystemCodes(
805: final String sourceCode, final String targetCode)
806: throws FactoryException {
807: return Collections.EMPTY_SET;
808: }
809:
810: /**
811: * Returns a finder which can be used for looking up unidentified objects. The finder
812: * fetchs a fully {@linkplain IdentifiedObject identified object} from an incomplete one,
813: * for example from an object without identifier or "{@code AUTHORITY[...]}" element in
814: * <cite>Well Known Text</cite> terminology.
815: *
816: * @param type The type of objects to look for. Should be a GeoAPI interface like
817: * {@code GeographicCRS.class}, but this method accepts also implementation
818: * class. If the type is unknown, use {@code IdentifiedObject.class}. A more
819: * accurate type may help to speed up the search, since it reduces the amount
820: * of tables to scan in some implementations like the factories backed by
821: * EPSG database.
822: * @return A finder to use for looking up unidentified objects.
823: * @throws FactoryException if the finder can not be created.
824: *
825: * @since 2.4
826: */
827: public IdentifiedObjectFinder getIdentifiedObjectFinder(
828: final Class/*<? extends IdentifiedObject>*/type)
829: throws FactoryException {
830: return new IdentifiedObjectFinder(this , type);
831: }
832:
833: /**
834: * Releases resources immediately instead of waiting for the garbage collector.
835: * Once a factory has been disposed, further {@code create(...)} invocations
836: * may throw a {@link FactoryException}. Disposing a previously-disposed factory,
837: * however, has no effect.
838: *
839: * @throws FactoryException if an error occured while disposing the factory.
840: */
841: public void dispose() throws FactoryException {
842: // To be overridden by subclasses.
843: }
844:
845: /**
846: * Creates an exception for an unknow authority code. This convenience method is provided
847: * for implementation of {@code createXXX} methods.
848: *
849: * @param type The GeoAPI interface that was to be created
850: * (e.g. {@code CoordinateReferenceSystem.class}).
851: * @param code The unknow authority code.
852: * @param cause The cause of this error, or {@code null}.
853: * @return An exception initialized with an error message built
854: * from the specified informations.
855: */
856: private NoSuchAuthorityCodeException noSuchAuthorityCode(
857: final Class type, final String code,
858: final ClassCastException cause) {
859: final NoSuchAuthorityCodeException exception = noSuchAuthorityCode(
860: type, code);
861: exception.initCause(cause);
862: return exception;
863: }
864:
865: /**
866: * Trims the authority scope, if present. For example if this factory is an EPSG authority
867: * factory and the specified code start with the "EPSG:" prefix, then the prefix is removed.
868: * Otherwise, the string is returned unchanged (except for leading and trailing spaces).
869: *
870: * @param code The code to trim.
871: * @return The code without the authority scope.
872: */
873: protected String trimAuthority(String code) {
874: /*
875: * IMPLEMENTATION NOTE: This method is overrided in PropertyAuthorityFactory. If
876: * implementation below is modified, it is probably worth to revisit the overrided
877: * method as well.
878: */
879: code = code.trim();
880: final GenericName name = NameFactory.create(code);
881: final GenericName scope = name.getScope();
882: if (scope == null) {
883: return code;
884: }
885: if (Citations.identifierMatches(getAuthority(), scope
886: .toString())) {
887: return name.asLocalName().toString().trim();
888: }
889: return code;
890: }
891:
892: /**
893: * Creates an exception for an unknow authority code. This convenience method is provided
894: * for implementation of {@code createXXX} methods.
895: *
896: * @param type The GeoAPI interface that was to be created
897: * (e.g. {@code CoordinateReferenceSystem.class}).
898: * @param code The unknow authority code.
899: * @return An exception initialized with an error message built
900: * from the specified informations.
901: */
902: protected final NoSuchAuthorityCodeException noSuchAuthorityCode(
903: final Class type, final String code) {
904: final InternationalString authority = getAuthority().getTitle();
905: return new NoSuchAuthorityCodeException(Errors.format(
906: ErrorKeys.NO_SUCH_AUTHORITY_CODE_$3, code, authority,
907: Utilities.getShortName(type)), authority.toString(),
908: code);
909: }
910: }
|