001 /*
002 * GeoAPI - Java interfaces for OGC/ISO standards
003 * http://www.geoapi.org
004 *
005 * Copyright (C) 2005-2013 Open Geospatial Consortium, Inc.
006 * All Rights Reserved. http://www.opengeospatial.org/ogc/legal
007 *
008 * Permission to use, copy, and modify this software and its documentation, with
009 * or without modification, for any purpose and without fee or royalty is hereby
010 * granted, provided that you include the following on ALL copies of the software
011 * and documentation or portions thereof, including modifications, that you make:
012 *
013 * 1. The full text of this NOTICE in a location viewable to users of the
014 * redistributed or derivative work.
015 * 2. Notice of any changes or modifications to the OGC files, including the
016 * date changes were made.
017 *
018 * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE
019 * NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
020 * TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT
021 * THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY
022 * PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
023 *
024 * COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR
025 * CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION.
026 *
027 * The name and trademarks of copyright holders may NOT be used in advertising or
028 * publicity pertaining to the software without specific, written prior permission.
029 * Title to copyright in this software and any associated documentation will at all
030 * times remain with copyright holders.
031 */
032 package org.opengis.coverage.grid;
033
034 import java.util.List;
035 import java.util.ArrayList;
036
037 import org.opengis.util.CodeList;
038 import org.opengis.annotation.UML;
039
040 import static org.opengis.annotation.Obligation.*;
041 import static org.opengis.annotation.Specification.*;
042
043
044 /**
045 * Specifies the order in which attribute value records are assigned to {@linkplain GridPoint grid points}.
046 * There are several sequencing rules based on incrementing - or decrementing - grid coordinate values in
047 * a simple fashion. More complex space filling curves can also be used. Space filling curves are generated
048 * by progressively subdividing a space in a regular way and connecting the elements resulting from each
049 * subdivision according to some rule. They can be used to generate a grid, but they can also be used to
050 * assign an ordering to the grid points or grid cells in a separately defined grid. They lend themselves
051 * more readily than simple incrementing methods to sequencing in grids that have irregular shapes or cells
052 * of variable size.
053 * <p>
054 * In every case, ordering of the grid cells starts by incrementing coordinates along one grid axis.
055 * At some point in the process, it begins to increment coordinates along a second grid axis, then a
056 * third, and so on until it has progressed in the direction of each of the grid axes. The attribute
057 * {@linkplain SequenceRule#getScanDirection scan direction} provides a list of signed axis names
058 * that identifies the order in which scanning takes place. The list may include an additional element
059 * to support interleaving of feature attribute values.
060 * <p>
061 * Ordering is continuous if consecutive pairs of grid cells in the sequence are maximally connected.
062 * It is semicontinuous if consecutive pairs of grid cells are connected, but less than maximally
063 * connected, and discontinuous if consecutive pairs of cells are not connected.
064 * <p>
065 * <b>Example:</b> In the two dimensional case, a cell is connected to the 8 cells with which it
066 * shares at least one corner. It is maximally connected to the 4 cells with which it shares an
067 * edge and two corners. In the three dimensional case, a cell is maximally connected to those
068 * cells with which it shares a face.
069 *
070 * @version ISO 19123:2004
071 * @author Wim Koolhoven
072 * @author Martin Schouwenburg
073 * @author Martin Desruisseaux (IRD)
074 * @since GeoAPI 2.1
075 */
076 @UML(identifier="CV_SequenceType", specification=ISO_19123)
077 public class SequenceType extends CodeList<SequenceType> {
078 /**
079 * Serial number for compatibility with different versions.
080 */
081 private static final long serialVersionUID = -6231205465579495566L;
082
083 /**
084 * List of all enumerations of this type.
085 * Must be declared before any enum declaration.
086 */
087 private static final List<SequenceType> VALUES = new ArrayList<SequenceType>(6);
088
089 /**
090 * Feature attribute value records are assigned to consecutive grid points along a single grid line
091 * parallel to the first grid axis listed in {@linkplain SequenceRule#getScanDirection scan direction}.
092 * Once scanning of that row is complete, assignment of feature attribute value records steps to another
093 * grid line parallel to the first, and continues to step from grid line to grid line in a direction parallel
094 * to the second axis. If the grid is 3-dimensional, the sequencing process completes the assignment of feature
095 * attribute value records to all grid points in one plane, then steps to another plane, then continues stepping
096 * from plane to plane in a direction parallel to the third axis of the grid. The process can be extended to any
097 * number of axes. Linear scanning is continuous only along a single grid line.
098 *
099 * <center><img src="doc-files/LinearScanning.png"></center>
100 */
101 @UML(identifier="Linear scanning", obligation=CONDITIONAL, specification=ISO_19123)
102 public static final SequenceType LINEAR = new SequenceType("LINEAR");
103
104 /**
105 * A variant of {@linkplain #LINEAR linear} scanning, in which the direction of the scan is reversed
106 * on alternate grid lines. In the case of a 3-dimensional grid, it will also be reversed in alternate
107 * planes. Boustrophedonic scanning is continuous.
108 * <p>
109 * <b>NOTE:</b> Boustrophedonic scanning is also known as byte-offset scanning.
110 *
111 * <center><img src="doc-files/BoustrophedonicScanning.png"></center>
112 */
113 @UML(identifier="Boustrophedonic scanning", obligation=CONDITIONAL, specification=ISO_19123)
114 public static final SequenceType BOUSTROPHEDONIC = new SequenceType("BOUSTROPHEDONIC");
115
116 /**
117 * Cantor-diagonal scanning, also called zigzag scanning, orders the grid points in alternating
118 * directions along parallel diagonals of the grid. The scan pattern is affected by the direction
119 * of first step. Like linear scanning, Cantor-diagonal scanning can be extended to grids of three
120 * or more dimensions by repeating the scan pattern in consecutive planes. Cantor-diagonal scanning
121 * is semi-continuous within a single plane.
122 *
123 * <center><img src="doc-files/CantorDiagonalScanning.png"></center>
124 */
125 @UML(identifier="Cantor-diagonal scanning", obligation=CONDITIONAL, specification=ISO_19123)
126 public static final SequenceType CANTOR_DIAGONAL = new SequenceType("CANTOR_DIAGONAL");
127
128 /**
129 * Spiral scanning can begin either at the centre of the grid (outward spiral), or at a corner
130 * (inward spiral). Like {@linkplain #LINEAR linear} or {@linkplain #CANTOR_DIAGONAL Cantor-diagonal}
131 * scanning, spiral scanning can be extended to grids of three or more dimensions by repeating the
132 * scan pattern in consecutive planes. Spiral scanning is continuous in any one plane, but continuity
133 * in grids of more than two dimensions can only be maintained by reversing the inward/outward direction
134 * of the scan in alternate planes.
135 *
136 * <center><img src="doc-files/SpiralScanning.png"></center>
137 */
138 @UML(identifier="Spiral scanning", obligation=CONDITIONAL, specification=ISO_19123)
139 public static final SequenceType SPIRAL = new SequenceType("SPIRAL");
140
141 /**
142 * Ordering based on a space-filling curve generated by progressively subdividing a space into quadrants
143 * and ordering the quadrants in a Z pattern. The ordering index for each grid point is computed by converting
144 * the grid coordinates to binary numbers and interleaving the bits of the resulting values. Given the list
145 * of the grid axes specified by {@linkplain SequenceRule#getScanDirection scan direction}, the bits of the
146 * coordinate corresponding to an axis are less significant than those of the coordinate corresponding to the
147 * next axis in the list. Morton ordering can be extended to any number of dimensions. Morton ordering is
148 * discontinuous.
149 * <p>
150 * <b>NOTE:</b> Because of the shape of the curve formed by the initial ordering of quadrants,
151 * Morton ordering is also known as Z ordering.
152 * <p>
153 * <center><img src="doc-files/Morton.png"></center>
154 * <p>
155 * A grid generated with the Morton ordering technique will be square and its size in each direction
156 * will be a multiple of a power of 2. However, the bit interleaving technique for generating an index
157 * can be used to order the grid points in any grid, including grids that are irregular in shape or have
158 * grid cells of different sizes.
159 */
160 @UML(identifier="Morton order", obligation=CONDITIONAL, specification=ISO_19123)
161 public static final SequenceType MORTON = new SequenceType("MORTON");
162
163 /**
164 * Ordering based on a space-filling curve generated by progressively subdividing a space into quadrants.
165 * This is similar to {@linkplain #MORTON Morton} scanning, but the initial pattern of subdivision is different
166 * for Hilbert curves. Further subdivision involves replacement of parts of the curve by different patterns,
167 * unlike the simple replication of a single pattern as in Morton ordering. There are two sets of patterns.
168 * The left-hand column of the figure includes those for which the sense of the scan directions is the same
169 * - both are positive or both negative. The right-hand column of the figure includes those for which the
170 * sense of the scan directions is opposite - one is positive and one is negative. A Hilbert curve can only
171 * be constructed with patterns from the same set; it uses all the patterns in that set.
172 * <p>
173 * <b>NOTE:</b> Because of the shape of the curve formed by the initial ordering of quadrants, Hilbert
174 * ordering is also known as pi ordering.
175 *
176 * <center><img src="doc-files/Hilbert.png"></center>
177 */
178 @UML(identifier="Hilbert order", obligation=CONDITIONAL, specification=ISO_19123)
179 public static final SequenceType HILBERT = new SequenceType("HILBERT");
180
181 /**
182 * Constructs an element of the given name. The new element is
183 * automatically added to the list returned by {@link #values()}.
184 *
185 * @param name The name of the new element.
186 * This name must not be in use by an other element of this type.
187 */
188 private SequenceType(final String name) {
189 super(name, VALUES);
190 }
191
192 /**
193 * Returns the list of {@code SequenceType}s.
194 *
195 * @return The list of codes declared in the current JVM.
196 */
197 public static SequenceType[] values() {
198 synchronized (VALUES) {
199 return VALUES.toArray(new SequenceType[VALUES.size()]);
200 }
201 }
202
203 /**
204 * Returns the list of codes of the same kind than this code list element.
205 * Invoking this method is equivalent to invoking {@link #values()}, except that
206 * this method can be invoked on an instance of the parent {@code CodeList} class.
207 */
208 @Override
209 public SequenceType[] family() {
210 return values();
211 }
212
213 /**
214 * Returns the sequence type that matches the given string, or returns a
215 * new one if none match it. More specifically, this methods returns the first instance for
216 * which <code>{@linkplain #name() name()}.{@linkplain String#equals equals}(code)</code>
217 * returns {@code true}. If no existing instance is found, then a new one is created for
218 * the given name.
219 *
220 * @param code The name of the code to fetch or to create.
221 * @return A code matching the given name.
222 */
223 public static SequenceType valueOf(String code) {
224 return valueOf(SequenceType.class, code);
225 }
226 }