001/* 002 * GeoAPI - Java interfaces for OGC/ISO standards 003 * Copyright © 2004-2024 Open Geospatial Consortium, Inc. 004 * http://www.geoapi.org 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.opengis.referencing.cs; 019 020import java.util.Optional; 021import org.opengis.util.CodeList; 022import org.opengis.annotation.UML; 023import org.opengis.geoapi.internal.Vocabulary; 024 025import static org.opengis.annotation.Obligation.*; 026import static org.opengis.annotation.Specification.*; 027 028 029/** 030 * The direction of positive increase in the coordinate value for a coordinate system axis. 031 * This direction is exact in some cases, and is approximate in other cases. 032 * 033 * <p>Some coordinate systems use non-standard orientations. 034 * For example, the first axis in South African grids usually points West, instead of East. 035 * This information is relevant for algorithms converting South African grid coordinates into Lat/Long.</p> 036 * 037 * @author OGC Topic 2 (for abstract model and documentation) 038 * @author Martin Desruisseaux (IRD, Geomatys) 039 * @version 3.1 040 * @since 1.0 041 * 042 * @see CoordinateSystemAxis#getDirection() 043 */ 044@Vocabulary(capacity=41) 045@UML(identifier="AxisDirection", specification=ISO_19111) 046public final class AxisDirection extends CodeList<AxisDirection> { 047 /** 048 * Serial number for compatibility with different versions. 049 */ 050 private static final long serialVersionUID = -4405275475770755714L; 051 052 /** 053 * Unknown or unspecified axis orientation. 054 * 055 * @category Other 056 * 057 * @deprecated Replaced by {@link #UNSPECIFIED} in ISO 19111:2019. 058 */ 059 @Deprecated(since = "3.1") 060 @UML(identifier="CS_AxisOrientationEnum.CS_AO_Other", obligation=CONDITIONAL, specification=OGC_01009) 061 public static final AxisDirection OTHER = new AxisDirection("OTHER"); 062 063 /** 064 * Axis positive direction is north. 065 * In a geographic or projected <abbr>CRS</abbr>, north is defined through the geodetic reference frame. 066 * In an engineering <abbr>CRS</abbr>, north may be defined with respect to an engineering object 067 * rather than a geographical direction. 068 * 069 * @category Rose 070 */ 071 @UML(identifier="north", obligation=CONDITIONAL, specification=ISO_19111) 072 public static final AxisDirection NORTH = new AxisDirection("NORTH"); 073 074 /** 075 * Axis positive direction is approximately north-north-east. 076 * 077 * @category Rose 078 */ 079 @UML(identifier="northNorthEast", obligation=CONDITIONAL, specification=ISO_19111) 080 public static final AxisDirection NORTH_NORTH_EAST = new AxisDirection("NORTH_NORTH_EAST"); 081 082 /** 083 * Axis positive direction is approximately north-east. 084 * 085 * @category Rose 086 */ 087 @UML(identifier="northEast", obligation=CONDITIONAL, specification=ISO_19111) 088 public static final AxisDirection NORTH_EAST = new AxisDirection("NORTH_EAST"); 089 090 /** 091 * Axis positive direction is approximately east-north-east. 092 * 093 * @category Rose 094 */ 095 @UML(identifier="eastNorthEast", obligation=CONDITIONAL, specification=ISO_19111) 096 public static final AxisDirection EAST_NORTH_EAST = new AxisDirection("EAST_NORTH_EAST"); 097 098 /** 099 * Axis positive direction is π/2 radians clockwise from north. 100 * This is usually used for grid <var>X</var> coordinates and for longitude. 101 * 102 * @category Rose 103 */ 104 @UML(identifier="east", obligation=CONDITIONAL, specification=ISO_19111) 105 public static final AxisDirection EAST = new AxisDirection("EAST"); 106 107 /** 108 * Axis positive direction is approximately east-south-east. 109 * 110 * @category Rose 111 */ 112 @UML(identifier="eastSouthEast", obligation=CONDITIONAL, specification=ISO_19111) 113 public static final AxisDirection EAST_SOUTH_EAST = new AxisDirection("EAST_SOUTH_EAST"); 114 115 /** 116 * Axis positive direction is approximately south-east. 117 * 118 * @category Rose 119 */ 120 @UML(identifier="southEast", obligation=CONDITIONAL, specification=ISO_19111) 121 public static final AxisDirection SOUTH_EAST = new AxisDirection("SOUTH_EAST"); 122 123 /** 124 * Axis positive direction is approximately south-south-east. 125 * 126 * @category Rose 127 */ 128 @UML(identifier="southSouthEast", obligation=CONDITIONAL, specification=ISO_19111) 129 public static final AxisDirection SOUTH_SOUTH_EAST = new AxisDirection("SOUTH_SOUTH_EAST"); 130 131 /** 132 * Axis positive direction is π radians clockwise from north. 133 * 134 * @category Rose 135 */ 136 @UML(identifier="south", obligation=CONDITIONAL, specification=ISO_19111) 137 public static final AxisDirection SOUTH = new AxisDirection("SOUTH", NORTH); 138 139 /** 140 * Axis positive direction is approximately south-south-west. 141 * 142 * @category Rose 143 */ 144 @UML(identifier="southSouthWest", obligation=CONDITIONAL, specification=ISO_19111) 145 public static final AxisDirection SOUTH_SOUTH_WEST = new AxisDirection("SOUTH_SOUTH_WEST", NORTH_NORTH_EAST); 146 147 /** 148 * Axis positive direction is approximately south-west. 149 * 150 * @category Rose 151 */ 152 @UML(identifier="southWest", obligation=CONDITIONAL, specification=ISO_19111) 153 public static final AxisDirection SOUTH_WEST = new AxisDirection("SOUTH_WEST", NORTH_EAST); 154 155 /** 156 * Axis positive direction is approximately west-south-west. 157 * 158 * @category Rose 159 */ 160 @UML(identifier="westSouthWest", obligation=CONDITIONAL, specification=ISO_19111) 161 public static final AxisDirection WEST_SOUTH_WEST = new AxisDirection("WEST_SOUTH_WEST", EAST_NORTH_EAST); 162 163 /** 164 * Axis positive direction is 3π/2 radians clockwise from north. 165 * This is usually used for Grid X coordinates and Longitude. 166 * 167 * @category Rose 168 */ 169 @UML(identifier="west", obligation=CONDITIONAL, specification=ISO_19111) 170 public static final AxisDirection WEST = new AxisDirection("WEST", EAST); 171 172 /** 173 * Axis positive direction is approximately west-north-west. 174 * 175 * @category Rose 176 */ 177 @UML(identifier="westNorthWest", obligation=CONDITIONAL, specification=ISO_19111) 178 public static final AxisDirection WEST_NORTH_WEST = new AxisDirection("WEST_NORTH_WEST", EAST_SOUTH_EAST); 179 180 /** 181 * Axis positive direction is approximately north-west. 182 * 183 * @category Rose 184 */ 185 @UML(identifier="northWest", obligation=CONDITIONAL, specification=ISO_19111) 186 public static final AxisDirection NORTH_WEST = new AxisDirection("NORTH_WEST", SOUTH_EAST); 187 188 /** 189 * Axis positive direction is approximately north-north-west. 190 * 191 * @category Rose 192 */ 193 @UML(identifier="northNorthWest", obligation=CONDITIONAL, specification=ISO_19111) 194 public static final AxisDirection NORTH_NORTH_WEST = new AxisDirection("NORTH_NORTH_WEST", SOUTH_SOUTH_EAST); 195 196 /** 197 * Axis positive direction is up relative to gravity. 198 * This is used for {@linkplain VerticalCS vertical coordinate systems}. 199 * 200 * @category Vertical 201 */ 202 @UML(identifier="up", obligation=CONDITIONAL, specification=ISO_19111) 203 public static final AxisDirection UP = new AxisDirection("UP"); 204 205 /** 206 * Axis positive direction is down relative to gravity. 207 * This is used for {@linkplain VerticalCS vertical coordinate systems}. 208 * 209 * @category Vertical 210 */ 211 @UML(identifier="down", obligation=CONDITIONAL, specification=ISO_19111) 212 public static final AxisDirection DOWN = new AxisDirection("DOWN", UP); 213 214 /** 215 * Axis positive direction is toward geocentric <var>X</var>. 216 * This is the direction in the equatorial plane from the center of the modeled planet 217 * towards the intersection of the equator with the prime meridian. 218 * 219 * @category Geocentric 220 */ 221 @UML(identifier="geocentricX", obligation=CONDITIONAL, specification=ISO_19111) 222 public static final AxisDirection GEOCENTRIC_X = new AxisDirection("GEOCENTRIC_X"); 223 224 /** 225 * Axis positive direction is toward geocentric <var>Y</var>. 226 * This is the direction in the equatorial plane from the center of the modeled planet 227 * towards the intersection of the equator and the meridian π/2 radians eastwards from the prime meridian. 228 * 229 * @category Geocentric 230 */ 231 @UML(identifier="geocentricY", obligation=CONDITIONAL, specification=ISO_19111) 232 public static final AxisDirection GEOCENTRIC_Y = new AxisDirection("GEOCENTRIC_Y"); 233 234 /** 235 * Axis positive direction is toward geocentric <var>Z</var>. 236 * This is the direction from the center of the modeled planet 237 * parallel to its rotation axis and towards its north pole. 238 * 239 * @category Geocentric 240 */ 241 @UML(identifier="geocentricZ", obligation=CONDITIONAL, specification=ISO_19111) 242 public static final AxisDirection GEOCENTRIC_Z = new AxisDirection("GEOCENTRIC_Z"); 243 244 /** 245 * Axis positive direction is towards higher pixel column. 246 * 247 * @category Image 248 */ 249 @UML(identifier="columnPositive", obligation=CONDITIONAL, specification=ISO_19111) 250 public static final AxisDirection COLUMN_POSITIVE = new AxisDirection("COLUMN_POSITIVE"); 251 252 /** 253 * Axis positive direction is towards lower pixel column. 254 * 255 * @category Image 256 */ 257 @UML(identifier="columnNegative", obligation=CONDITIONAL, specification=ISO_19111) 258 public static final AxisDirection COLUMN_NEGATIVE = new AxisDirection("COLUMN_NEGATIVE", COLUMN_POSITIVE); 259 260 /** 261 * Axis positive direction is towards higher pixel row. 262 * 263 * @category Image 264 */ 265 @UML(identifier="rowPositive", obligation=CONDITIONAL, specification=ISO_19111) 266 public static final AxisDirection ROW_POSITIVE = new AxisDirection("ROW_POSITIVE"); 267 268 /** 269 * Axis positive direction is towards lower pixel row. 270 * 271 * @category Image 272 */ 273 @UML(identifier="rowNegative", obligation=CONDITIONAL, specification=ISO_19111) 274 public static final AxisDirection ROW_NEGATIVE = new AxisDirection("ROW_NEGATIVE", ROW_POSITIVE); 275 276 /** 277 * Axis positive direction is right in display. 278 * 279 * @category Display 280 */ 281 @UML(identifier="displayRight", obligation=CONDITIONAL, specification=ISO_19111) 282 public static final AxisDirection DISPLAY_RIGHT = new AxisDirection("DISPLAY_RIGHT"); 283 284 /** 285 * Axis positive direction is left in display. 286 * 287 * @category Display 288 */ 289 @UML(identifier="displayLeft", obligation=CONDITIONAL, specification=ISO_19111) 290 public static final AxisDirection DISPLAY_LEFT = new AxisDirection("DISPLAY_LEFT", DISPLAY_RIGHT); 291 292 /** 293 * Axis positive direction is towards top of approximately vertical display surface. 294 * 295 * @category Display 296 */ 297 @UML(identifier="displayUp", obligation=CONDITIONAL, specification=ISO_19111) 298 public static final AxisDirection DISPLAY_UP = new AxisDirection("DISPLAY_UP"); 299 300 /** 301 * Axis positive direction is towards bottom of approximately vertical display surface. 302 * 303 * @category Display 304 */ 305 @UML(identifier="displayDown", obligation=CONDITIONAL, specification=ISO_19111) 306 public static final AxisDirection DISPLAY_DOWN = new AxisDirection("DISPLAY_DOWN", DISPLAY_UP); 307 308 /** 309 * Axis positive direction is forward. 310 * For an observer at the center of the object this will be towards its front, bow or nose. 311 * 312 * @category Engineering 313 * @since 3.1 314 */ 315 @UML(identifier="forward", obligation=CONDITIONAL, specification=ISO_19111) 316 public static final AxisDirection FORWARD = new AxisDirection("FORWARD"); 317 318 /** 319 * Axis positive direction is aft. 320 * For an observer at the center of the object this will be towards its back, stern or tail. 321 * 322 * @category Engineering 323 * @since 3.1 324 */ 325 @UML(identifier="aft", obligation=CONDITIONAL, specification=ISO_19111) 326 public static final AxisDirection AFT = new AxisDirection("AFT", FORWARD); 327 328 /** 329 * Axis positive direction is port. 330 * For an observer looking forward from the center of the object this will be towards its left. 331 * 332 * @category Engineering 333 * @since 3.1 334 */ 335 @UML(identifier="port", obligation=CONDITIONAL, specification=ISO_19111) 336 public static final AxisDirection PORT = new AxisDirection("PORT"); 337 338 /** 339 * Axis positive direction is starboard. 340 * For an observer looking forward from the center of the object this will be towards its right. 341 * 342 * @category Engineering 343 * @since 3.1 344 */ 345 @UML(identifier="starboard", obligation=CONDITIONAL, specification=ISO_19111) 346 public static final AxisDirection STARBOARD = new AxisDirection("STARBOARD", PORT); 347 348 /** 349 * Axis positive direction is clockwise from a specified direction. 350 * 351 * @category Engineering 352 * @since 3.1 353 */ 354 @UML(identifier="clockwise", obligation=CONDITIONAL, specification=ISO_19111) 355 public static final AxisDirection CLOCKWISE = new AxisDirection("CLOCKWISE"); 356 357 /** 358 * Axis positive direction is counter clockwise from a specified direction. 359 * 360 * @category Engineering 361 * @since 3.1 362 */ 363 @UML(identifier="counterClockwise", obligation=CONDITIONAL, specification=ISO_19111) 364 public static final AxisDirection COUNTER_CLOCKWISE = new AxisDirection("COUNTER_CLOCKWISE", CLOCKWISE); 365 366 /** 367 * Axis positive direction is towards the object. 368 * 369 * @category Engineering 370 * @since 3.1 371 */ 372 @UML(identifier="towards", obligation=CONDITIONAL, specification=ISO_19111) 373 public static final AxisDirection TOWARDS = new AxisDirection("TOWARDS"); 374 375 /** 376 * Axis positive direction is away from the object. 377 * 378 * @category Engineering 379 * @since 3.1 380 */ 381 @UML(identifier="awayFrom", obligation=CONDITIONAL, specification=ISO_19111) 382 public static final AxisDirection AWAY_FROM = new AxisDirection("AWAY_FROM", TOWARDS); 383 384 /** 385 * Axis positive direction is towards the future. 386 * This is used for {@linkplain TimeCS temporal coordinate systems}. 387 * 388 * @category Temporal 389 */ 390 @UML(identifier="future", obligation=CONDITIONAL, specification=ISO_19111) 391 public static final AxisDirection FUTURE = new AxisDirection("FUTURE"); 392 393 /** 394 * Axis positive direction is towards the past. 395 * This is used for {@linkplain TimeCS temporal coordinate systems}. 396 * 397 * @category Temporal 398 */ 399 @UML(identifier="past", obligation=CONDITIONAL, specification=ISO_19111) 400 public static final AxisDirection PAST = new AxisDirection("PAST", FUTURE); 401 402 /** 403 * Axis positive direction is unspecified. 404 * 405 * @category Other 406 * @since 3.1 407 */ 408 @UML(identifier="unspecified", obligation=CONDITIONAL, specification=ISO_19111) 409 public static final AxisDirection UNSPECIFIED = new AxisDirection("UNSPECIFIED"); 410 static { 411 UNSPECIFIED.opposite = UNSPECIFIED; 412 } 413 414 /** 415 * The direction of negative coordinate values, or {@code null} if unknown. 416 */ 417 private AxisDirection opposite; 418 419 /** 420 * Constructs an element of the given name. 421 * 422 * @param name the name of the new element. This name shall not be in use by another element of this type. 423 */ 424 private AxisDirection(final String name) { 425 super(name); 426 } 427 428 /** 429 * Constructs an element of the given name. 430 * 431 * @param name the name of the new element. This name shall not be in use by another element of this type. 432 * @param opposite the direction of negative coordinate values. 433 */ 434 private AxisDirection(final String name, final AxisDirection opposite) { 435 super(name); 436 this.opposite = opposite; 437 opposite.opposite = this; 438 } 439 440 /** 441 * Returns the direction of negative coordinate values. 442 * For example, the opposite of {@link #NORTH} is {@link #SOUTH} and the opposite of {@link #FUTURE} is {@link #PAST}. 443 * The opposite of the opposite (if present) is always {@code this}. 444 * 445 * @return direction of negative coordinate values. 446 * 447 * @since 3.1 448 */ 449 public Optional<AxisDirection> opposite() { 450 return Optional.ofNullable(opposite); 451 } 452 453 /** 454 * Returns the list of {@code AxisDirection}s. 455 * 456 * @return the list of codes declared in the current JVM. 457 */ 458 public static AxisDirection[] values() { 459 return values(AxisDirection.class); 460 } 461 462 /** 463 * Returns the list of codes of the same kind as this code list element. 464 * Invoking this method is equivalent to invoking {@link #values()}, except that 465 * this method can be invoked on an instance of the parent {@code CodeList} class. 466 * 467 * @return all code {@linkplain #values() values} for this code list. 468 */ 469 @Override 470 public AxisDirection[] family() { 471 return values(); 472 } 473 474 /** 475 * Returns the axis direction that matches the given string, or returns a new one if none match it. 476 * This methods returns the first instance (in declaration order) for which the {@linkplain #name() name} 477 * is {@linkplain String#equalsIgnoreCase(String) equals, ignoring case}, to the given name. 478 * If no existing instance is found, then a new one is created for the given name. 479 * 480 * @param code the name of the code to fetch or to create. 481 * @return a code matching the given name. 482 */ 483 public static AxisDirection valueOf(String code) { 484 return valueOf(AxisDirection.class, code, AxisDirection::new).get(); 485 } 486}