001/* 002 * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences. 003 * Copyright (C) 2006 - JScience (http://jscience.org/) 004 * All rights reserved. 005 * 006 * Permission to use, copy, modify, and distribute this software is 007 * freely granted, provided that this notice is preserved. 008 */ 009package org.jscience.geography.coordinates.crs; 010 011import java.util.Collection; 012import java.util.Set; 013 014import javax.measure.quantity.Angle; 015import javax.measure.quantity.Duration; 016import javax.measure.quantity.Length; 017import javax.measure.Measurable; 018import javax.measure.unit.Unit; 019 020import javolution.util.FastSet; 021 022import org.jscience.geography.coordinates.Coordinates; 023import org.opengis.metadata.Identifier; 024import org.opengis.metadata.citation.Citation; 025import org.opengis.metadata.extent.Extent; 026import org.opengis.referencing.cs.AxisDirection; 027import org.opengis.referencing.cs.CoordinateSystem; 028import org.opengis.util.InternationalString; 029import org.opengis.referencing.cs.CoordinateSystemAxis; 030 031/** 032 * This class represents an arbitrary system of reference for which 033 * {@link Coordinates coordinates} of same significance can be stated. 034 * 035 * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a> 036 * @version 3.0, February 13, 2006 037 */ 038public abstract class CoordinateReferenceSystem<C extends Coordinates<?>> 039 implements org.opengis.referencing.crs.CoordinateReferenceSystem { 040 041 042 /** 043 * This class represents an absolute position (can be be extended) 044 */ 045 protected static class AbsolutePosition { 046 047 /** 048 * Holds the Geodetic Latitude (WGS84 Ellipsoid). 049 */ 050 public Measurable<Angle> latitudeWGS84; 051 052 /** 053 * Holds the Geodetic Longitude (WGS84 Ellipsoid). 054 */ 055 public Measurable<Angle> longitudeWGS84; 056 057 /** 058 * Holds the WGS84 Ellipsoidal Height. 059 */ 060 public Measurable<Length> heightWGS84; 061 062 /** 063 * Holds the Time since midnight, January 1, 1970 UTC. 064 */ 065 public Measurable<Duration> timeUTC; 066 } 067 068 /** 069 * Returns the converter between this coordinate reference system 070 * and the one specified. 071 * 072 * @param that the coordinate reference system to convert to. 073 * @return the corresponding coordinates converter. 074 * @throws ConversionException if the conversion is not possible 075 * (e.g. geographic to temporal). 076 */ 077 public <T extends Coordinates<?>> CoordinatesConverter<C, T> getConverterTo( 078 CoordinateReferenceSystem<T> that) { 079 return new GeneralConverter<T>(that); 080 } 081 082 // General implementation using absolute position as intermediary. 083 private class GeneralConverter<T extends Coordinates<?>> implements 084 CoordinatesConverter<C, T> { 085 private final CoordinateReferenceSystem<T> _toCRS; 086 087 private GeneralConverter(CoordinateReferenceSystem<T> toCRS) { 088 _toCRS = toCRS; 089 } 090 091 public T convert(C source) { 092 AbsolutePosition position = positionOf(source, 093 new AbsolutePosition()); 094 return _toCRS.coordinatesOf(position); 095 } 096 } 097 098 /** 099 * Returns the coordinates in this reference system of the specified 100 * absolute position. 101 * 102 * @param position the absolute position for which the coordinates 103 * in this reference system is returned. 104 * @return the coordinates for the specified absolute position. 105 * @throws ConversionException if a conversion error occurs. 106 */ 107 protected abstract C coordinatesOf(AbsolutePosition position); 108 109 /** 110 * Returns the absolute position from the coordinates in 111 * this reference system. This update may require information already 112 * supplied by the position. For example, the height for a pressure 113 * altitude might depends upon the latitude/longitude and the time. 114 * 115 * @param coordinates the coordinates for which the absolute position 116 * is adjusted. 117 * @param position the position object to update. 118 * @return the corresponding absolute position. 119 * @throws ConversionException if a conversion error occurs. 120 */ 121 protected abstract AbsolutePosition positionOf(C coordinates, 122 AbsolutePosition position); 123 124 /** 125 * Returns the OpenGIS coordinate system associated to this 126 * coordinate reference system. 127 * 128 * @return the corresponding coordinate system. 129 */ 130 public abstract CoordinateSystem getCoordinateSystem(); 131 132 ///////////// 133 // OpenGIS // 134 ///////////// 135 136 /** 137 * OpenGIS® - Area for which the (coordinate) reference system is valid. 138 * 139 * @return coordinate reference system valid area, 140 * or {@code null} (default) if not available. 141 */ 142 public Extent getValidArea() { 143 return null; 144 } 145 146 /** 147 * OpenGIS® - Description of domain of usage, or limitations of usage, 148 * for which this (coordinate) reference system object is valid. 149 */ 150 public InternationalString getScope() { 151 throw new UnsupportedOperationException(); 152 } 153 154 /** 155 * OpenGIS® - The primary name by which this object is identified. 156 * 157 * @return an identifier holding the class name. 158 */ 159 public Identifier getName() { 160 return new Name(CoordinateReferenceSystem.this.getClass().getName()); 161 } 162 163 /** 164 * OpenGIS® - An alternative name by which this object is identified. 165 * 166 * @return The aliases, or an empty collection if there is none. 167 */ 168 public Collection<String> getAlias() { 169 return EMPTY_SET; 170 } 171 172 /** 173 * OpenGIS® - An identifier which references elsewhere the object's defining information. 174 * Alternatively an identifier by which this object can be referenced. 175 * 176 * @return This object identifiers, or an empty set if there is none. 177 */ 178 public Set<String> getIdentifiers() { 179 return EMPTY_SET; 180 } 181 182 /** 183 * OpenGIS® - Comments on or information about this object, including 184 * data source information. 185 * 186 * @return <code>null</code> (default). 187 */ 188 public InternationalString getRemarks() { 189 return null; 190 } 191 192 /** 193 * OpenGIS® - Returns a <cite>Well Known Text</cite> (WKT)</A> for 194 * this object. This operation may fails if an object is too complex for 195 * the WKT format capability (for example an engineering CRS} with different 196 * unit for each axis). 197 * 198 * @return The Well Know Text for this object. 199 * @throws UnsupportedOperationException If this object can't be formatted 200 * as WKT (default). 201 */ 202 public String toWKT() throws UnsupportedOperationException { 203 throw new UnsupportedOperationException(); 204 } 205 206 // Default coordinates axis. 207 static class Axis implements CoordinateSystemAxis { 208 209 private final Name _name; 210 211 private final String _abbreviation; 212 213 private final Unit<?> _unit; 214 215 private final AxisDirection _direction; 216 217 public Axis(final String name, String abbreviation, Unit<?> unit, 218 AxisDirection direction) { 219 _name = new Name(name); 220 _abbreviation = abbreviation; 221 _unit = unit; 222 _direction = direction; 223 } 224 225 public final Identifier getName() { 226 return _name; 227 } 228 229 public final String getAbbreviation() { 230 return _abbreviation; 231 } 232 233 public final Unit<?> getUnit() { 234 return _unit; 235 } 236 237 public final AxisDirection getDirection() { 238 return _direction; 239 } 240 241 public Collection<String> getAlias() { 242 return EMPTY_SET; 243 } 244 245 public Set<String> getIdentifiers() { 246 return EMPTY_SET; 247 } 248 249 public InternationalString getRemarks() { 250 throw new UnsupportedOperationException(); 251 } 252 253 public String toWKT() throws UnsupportedOperationException { 254 throw new UnsupportedOperationException(); 255 } 256 257 } 258 259 // Default coordinates axis. 260 static class Name implements Identifier { 261 final String _value; 262 263 public Name(String value) { 264 _value = value; 265 } 266 267 public String getCode() { 268 return _value; 269 } 270 271 public Citation getAuthority() { 272 throw new UnsupportedOperationException(); 273 } 274 275 public String getVersion() { 276 throw new UnsupportedOperationException(); 277 } 278 } 279 280 static final FastSet<String> EMPTY_SET = new FastSet<String>(); 281}