001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002-2006, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.data;
017:
018: import java.net.URI;
019: import org.opengis.filter.Filter;
020: import org.opengis.filter.sort.SortBy;
021: import org.opengis.referencing.crs.CoordinateReferenceSystem;
022: import org.geotools.factory.Hints;
023:
024: /**
025: * Encapsulates a data request.
026: *
027: * <p>
028: * The query object is used by the FeatureSource.getFeatures(Query) to
029: * encapsulate a request. For this use it the
030: * FeatureSource.getSchema().getTypeName() should match the one provided by
031: * the Query, or the Query should not provide one.
032: * </p>
033: *
034: * <p>
035: * Suggested Extensions (Jody):
036: * </p>
037: *
038: * <ul>
039: * <li>
040: * Transient CoordianteSystem override done getCoordianteSystem()
041: * </li>
042: * <li>
043: * Transient Geometry reproject to an alternate CoordinateSystem - done
044: * getCoordinateSystemReproject()
045: * </li>
046: * <li>
047: * Consider Namespace, FeatueType name override - not done considered evil
048: * </li>
049: * <li>
050: * DataStore.getFeatureReader( Query, Transaction )
051: * </li>
052: * <li>
053: * DataStore.getView( Query ) - prototype in AbstractDataStore (not really
054: * ready for primetime, see Expr)
055: * </li>
056: * </ul>
057: *
058: *
059: * @author Chris Holmes
060: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/api/src/main/java/org/geotools/data/Query.java $
061: * @version $Id: Query.java 26489 2007-08-08 15:36:02Z aaime $
062: */
063: public interface Query {
064: /** TODO: should this be ANY_URI */
065: static final URI NO_NAMESPACE = null;
066:
067: /** So getMaxFeatures does not return null we use a very large number. */
068: static final int DEFAULT_MAX = Integer.MAX_VALUE;
069:
070: /**
071: * Implements a query that will fetch all features from a datasource. This
072: * query should retrieve all properties, with no maxFeatures, no
073: * filtering, and the default featureType.
074: */
075: final Query ALL = new ALLQuery();
076:
077: /**
078: * Implements a query that will fetch all the FeatureIDs from a datasource.
079: * This query should retrive no properties, with no maxFeatures, no
080: * filtering, and the a featureType with no attribtues.
081: */
082: final Query FIDS = new FIDSQuery();
083:
084: /**
085: * Ask for no properties when used with setPropertyNames.
086: *
087: * <p>
088: * Note the query will still return a result - limited to FeatureIDs.
089: * </p>
090: */
091: final String[] NO_NAMES = new String[0];
092:
093: /** Ask for all properties when used with setPropertyNames. */
094: final String[] ALL_NAMES = null;
095:
096: /**
097: * The properties array is used to specify the attributes that should be
098: * selected for the return feature collection.
099: *
100: * <ul>
101: * <li>
102: * ALL_NAMES: <code>null</code><br>
103: * If no properties are specified (getProperties returns ALL_NAMES or
104: * null) then the full schema should be used (all attributes).
105: * </li>
106: * <li>
107: * NO_NAMES: <code>new String[0]</code><br>
108: * If getProperties returns an array of size 0, then the datasource should
109: * return features with no attributes, only their ids.
110: * </li>
111: * </ul>
112: *
113: * <p>
114: * The available properties can be determined with a getSchema call from
115: * the DataSource interface. A datasource can use {@link
116: * #retrieveAllProperties()} as a shortcut to determine if all its
117: * available properties should be returned (same as checking to see if
118: * getProperties is ALL_NAMES, but clearer)
119: * </p>
120: *
121: * <p>
122: * If properties that are not part of the datasource's schema are requested
123: * then the datasource shall throw an exception.
124: * </p>
125: *
126: * <p>
127: * This replaces our funky setSchema method of retrieving select
128: * properties. It makes it easier to understand how to get certain
129: * properties out of the datasource, instead of having users get the
130: * schema and then compose a new schema using the attributes that they
131: * want. The old way had problems because one couldn't have multiple
132: * object reuse the same datasource object, since some other object could
133: * come along and change its schema, and would then return the wrong
134: * properties.
135: * </p>
136: *
137: * @return the attributes to be used in the returned FeatureCollection.
138: *
139: * @task REVISIT: make a FidProperties object, instead of an array size 0.
140: * I think Query.FIDS fills this role to some degree.
141: * Query.FIDS.equals( filter ) would meet this need?
142: */
143: String[] getPropertyNames();
144:
145: /**
146: * Convenience method to determine if the query should use the full schema
147: * (all properties) of the data source for the features returned. This
148: * method is equivalent to if (query.getProperties() == null), but allows
149: * for more clarity on the part of datasource implementors, so they do not
150: * need to examine and use null values. All Query implementations should
151: * return true for this function if getProperties returns null.
152: *
153: * @return if all datasource attributes should be included in the schema of
154: * the returned FeatureCollection.
155: */
156: boolean retrieveAllProperties();
157:
158: /**
159: * The optional maxFeatures can be used to limit the number of features
160: * that a query request retrieves. If no maxFeatures is specified then
161: * all features should be returned.
162: *
163: * <p>
164: * This is the only method that is not directly out of the Query element in
165: * the WFS spec. It is instead a part of a GetFeature request, which can
166: * hold one or more queries. But each of those in turn will need a
167: * maxFeatures, so it is needed here.
168: * </p>
169: *
170: * @return the max features the getFeature call should return.
171: */
172: int getMaxFeatures();
173:
174: /**
175: * The Filter can be used to define constraints on a query. If no Filter
176: * is present then the query is unconstrained and all feature instances
177: * should be retrieved.
178: *
179: * @return The filter that defines constraints on the query.
180: */
181: Filter getFilter();
182:
183: /**
184: * The typeName attribute is used to indicate the name of the feature type
185: * to be queried. If no typename is specified, then the default typeName
186: * should be returned from the dataStore. If the datasstore only supports
187: * one feature type then this part of the query may be ignored.
188: *
189: * @return the name of the feature type to be returned with this query.
190: */
191: String getTypeName();
192:
193: /**
194: * The namespace attribute is used to indicate the namespace of the schema
195: * being represented.
196: *
197: * @return the gml namespace of the feature type to be returned with this
198: * query
199: */
200: URI getNamespace();
201:
202: /**
203: * The handle attribute is included to allow a client to associate a
204: * mnemonic name to the Query request. The purpose of the handle attribute
205: * is to provide an error handling mechanism for locating a statement
206: * that might fail.
207: *
208: * @return the mnemonic name of the query request.
209: */
210: String getHandle();
211:
212: /**
213: * From WFS Spec: The version attribute is included in order to
214: * accommodate systems that support feature versioning. A value of ALL
215: * indicates that all versions of a feature should be fetched. Otherwise
216: * an integer, n, can be specified to return the n th version of a
217: * feature. The version numbers start at '1' which is the oldest version.
218: * If a version value larger than the largest version is specified then
219: * the latest version is return. The default action shall be for the query
220: * to return the latest version. Systems that do not support versioning
221: * can ignore the parameter and return the only version that they have.
222: *
223: * @return the version of the feature to return, or null for latest.
224: */
225: String getVersion();
226:
227: /**
228: * Specifies the coordinate system that the features being queried are in.
229: *
230: * <p>
231: * This denotes a request to Temporarily to override the coordinate system
232: * contained in the FeatureSource being queried. The same coordinate
233: * values will be used, but the features created will appear in this
234: * Coordinate System.
235: * </p>
236: *
237: * <p>
238: * This change is not persistant at all, indeed it is only for the Features
239: * returned by this Query. If used in conjunction with {@link #getCoordinateSystemReproject()}
240: * the reprojection will occur from {@link #getCoordinateSystem()} to
241: * {@link #getCoordinateSystemReproject()}.
242: * </p>
243: *
244: * @return The coordinate system to be returned for Features from this
245: * Query (override the set coordinate system).
246: */
247: CoordinateReferenceSystem getCoordinateSystem();
248:
249: /**
250: * Request data reprojection.
251: *
252: * <p>
253: * Gets the coordinate System to reproject the data contained in the
254: * backend datastore to.
255: * </p>
256: *
257: * <p>
258: * If the DataStore can optimize the reprojection it should, if not then a
259: * decorator on the reader should perform the reprojection on the fly.
260: * </p>
261: *
262: * <p>
263: * If the datastore has the wrong CS then {@link #getCoordinateSystem()} should be set to
264: * the CS to be used, this will perform the reprojection on that.
265: * </p>
266: *
267: * @return The coordinate system that Features from the datasource should
268: * be reprojected to.
269: */
270: CoordinateReferenceSystem getCoordinateSystemReproject();
271:
272: /**
273: * SortBy results according to indicated property and order.
274: * <p>
275: * SortBy is part of the Filter 1.1 specification, it is referenced
276: * by WFS1.1 and Catalog 2.0.x specifications and is used to organize
277: * results.
278: * </p>
279: * The SortBy's are ment to be applied in order:
280: * <ul>
281: * <li>SortBy( year, ascending )
282: * <li>SortBy( month, decsending )
283: * </ul>
284: * Would produce something like: <pre><code>
285: * [year=2002 month=4],[year=2002 month=3],[year=2002 month=2],
286: * [year=2002 month=1],[year=2003 month=12],[year=2002 month=4],
287: * </code></pre>
288: * </p>
289: * <p>
290: *
291: * SortBy should be considered at the same level of abstraction as Filter,
292: * and like Filter you may sort using properties not listed in
293: * getPropertyNames.
294: * </p>
295: *
296: * <p>
297: * At a technical level the interface SortBy2 is used to indicate the
298: * additional requirements of a GeoTools implementation. The pure
299: * WFS 1.1 specification itself is limited to SortBy.
300: * </p>
301: *
302: * @return SortBy array or order of application
303: */
304: SortBy[] getSortBy();
305:
306: /**
307: * Specifies some hints to drive the query execution and results build-up.
308: * Hints examples can be the GeometryFactory to be used, a generalization
309: * distance to be applied right in the data store, to data store specific
310: * things such as the fetch size to be used in JDBC queries.
311: * The set of hints supported can be fetched by calling
312: * {@links FeatureSource#getSupportedHints()}.
313: * Depending on the actual values of the hints, the data store is free to ignore them.
314: * No mechanism is in place, at the moment, to figure out which hints where
315: * actually used during the query execution.
316: * @return the Hints the data store should try to use when executing the query
317: * (eventually empty but never null).
318: */
319: Hints getHints();
320: }
|