001: /*---------------- FILE HEADER ------------------------------------------
002:
003: This file is part of deegree.
004: Copyright (C) 2001-2008 by:
005: EXSE, Department of Geography, University of Bonn
006: http://www.giub.uni-bonn.de/deegree/
007: lat/lon GmbH
008: http://www.lat-lon.de
009:
010: This library is free software; you can redistribute it and/or
011: modify it under the terms of the GNU Lesser General Public
012: License as published by the Free Software Foundation; either
013: version 2.1 of the License, or (at your option) any later version.
014:
015: This library is distributed in the hope that it will be useful,
016: but WITHOUT ANY WARRANTY; without even the implied warranty of
017: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
018: Lesser General Public License for more details.
019:
020: You should have received a copy of the GNU Lesser General Public
021: License along with this library; if not, write to the Free Software
022: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
023:
024: Contact:
025:
026: Andreas Poth
027: lat/lon GmbH
028: Aennchenstr. 19
029: 53177 Bonn
030: Germany
031: E-Mail: poth@lat-lon.de
032:
033: Prof. Dr. Klaus Greve
034: Department of Geography
035: University of Bonn
036: Meckenheimer Allee 166
037: 53115 Bonn
038: Germany
039: E-Mail: greve@giub.uni-bonn.de
040:
041:
042: ---------------------------------------------------------------------------*/
043: package org.deegree.ogcwebservices.wpvs.operation;
044:
045: import java.awt.Point;
046: import java.awt.Rectangle;
047: import java.util.ArrayList;
048: import java.util.List;
049: import java.util.Map;
050: import java.util.StringTokenizer;
051:
052: import org.deegree.framework.log.ILogger;
053: import org.deegree.framework.log.LoggerFactory;
054: import org.deegree.i18n.Messages;
055: import org.deegree.ogcbase.ExceptionCode;
056: import org.deegree.ogcwebservices.AbstractOGCWebServiceRequest;
057: import org.deegree.ogcwebservices.InconsistentRequestException;
058: import org.deegree.ogcwebservices.InvalidParameterValueException;
059: import org.deegree.ogcwebservices.OGCWebServiceException;
060: import org.deegree.ogcwebservices.wpvs.operation.GetView;
061:
062: /**
063: * This Class handles a kvp encoded Get3DFeatureInfo-request and stores it's values.
064: *
065: * @version $Revision: $
066: * @author <a href="mailto:cordes@lat-lon.de">Lyn Buesching</a>
067: * @author last edited by: $Author: $
068: *
069: * @version 1.0. $Revision: $, $Date: $
070: *
071: */
072: public class Get3DFeatureInfo extends AbstractOGCWebServiceRequest {
073:
074: /**
075: * the created serial id.
076: */
077: private static final long serialVersionUID = 4584807898848764192L;
078:
079: private static final ILogger LOGGER = LoggerFactory
080: .getLogger(Get3DFeatureInfo.class);
081:
082: private GetView getViewRequestCopy = null;
083:
084: private Point clickPoint = null;
085:
086: private Rectangle queryBox = null;
087:
088: private float apexAngle;
089:
090: private int radius;
091:
092: private float depth;
093:
094: private String exceptions = null;
095:
096: private String infoFormat;
097:
098: private List<String> queryDatasets = null;
099:
100: private int featureCount = 0;
101:
102: private boolean parent;
103:
104: /**
105: * creates a <tt>WPVSFeatureInfoRequest</tt> from a <tt>HashMap</tt> that contains the
106: * request parameters as key-value-pairs.
107: *
108: * @param param
109: * <tt>HashMap</tt> containing the request parameters
110: * @return an instance of <tt>WPVSFeatureInfoRequest</tt>
111: * @throws OGCWebServiceException
112: */
113: public static Get3DFeatureInfo create(Map<String, String> param)
114: throws OGCWebServiceException {
115:
116: // VERSION
117: String version = param.get("VERSION"); //$NON-NLS-1$
118: if (version == null) {
119: throw new InconsistentRequestException(Messages
120: .getMessage("WPVS_INVALID_VERSION")); //$NON-NLS-1$
121: }
122:
123: // ID
124: String id = param.get("ID"); //$NON-NLS-1$
125: if (id == null) {
126: throw new InconsistentRequestException(Messages
127: .getMessage("WPVS_MISSING_ID")); //$NON-NLS-1$
128: }
129:
130: // <view_request_copy>
131: GetView getViewRequestCopy = null;
132: try {
133: getViewRequestCopy = GetView.create(param);
134: } catch (Exception ex) {
135: throw new InconsistentRequestException(Messages
136: .getMessage("WPVS_EXCEPTION_GETVIEWREQUESTCOPY") //$NON-NLS-1$
137: + ex.getMessage());
138: }
139:
140: // APEXANGLE
141: float apexAngle;
142: if (param.get("AA") != null) {
143: try {
144: apexAngle = (float) Math.toRadians(Float
145: .parseFloat(param.remove("AA").trim()));
146: } catch (NumberFormatException nfe) {
147: throw new InvalidParameterValueException(Messages
148: .getMessage("WPVS_INVALID_APEXANGLE"));
149: }
150: if (apexAngle < 0) {
151: throw new InvalidParameterValueException(Messages
152: .getMessage("WPVS_INVALID_APEXANGLE_LESS_0"));
153: }
154: } else {
155: apexAngle = 0;
156: }
157:
158: // I, J
159: Point clickPoint = null;
160: if ((param.get("I") != null) && (param.get("J") != null)) { //$NON-NLS-1$ //$NON-NLS-2$
161: try {
162: int i = Integer.parseInt(param.remove("I")); //$NON-NLS-1$
163: int j = Integer.parseInt(param.remove("J")); //$NON-NLS-1$
164: clickPoint = new java.awt.Point(i, j);
165: } catch (NumberFormatException nfe) {
166: LOGGER.logError(nfe.getLocalizedMessage(), nfe);
167: throw new OGCWebServiceException(
168: "Get3DFeatureInfo", Messages.getMessage("WPVS_INVALID_POINT"), //$NON-NLS-1$ //$NON-NLS-2$
169: ExceptionCode.INVALID_POINT);
170: }
171: }
172:
173: // QUERYBOX
174: Rectangle queryBox = null;
175: if (param.get("QUERYBOX") != null) {
176: String[] tokens = param.remove("QUERYBOX").split(","); //$NON-NLS-1$
177: if (tokens.length != 4) {
178: throw new InconsistentRequestException(Messages
179: .getMessage("WPVS_INVALID_QUERYBOX")); //$NON-NLS-1$
180: }
181: int minx;
182: int maxx;
183: int miny;
184: int maxy;
185: try {
186: minx = Integer.parseInt(tokens[0]);
187: maxx = Integer.parseInt(tokens[1]);
188: miny = Integer.parseInt(tokens[2]);
189: maxy = Integer.parseInt(tokens[3]);
190: } catch (NumberFormatException e) {
191: throw new InconsistentRequestException(Messages
192: .getMessage("WPVS_ILLEGAL_QUERYBOX") //$NON-NLS-1$
193: + e.getMessage());
194: }
195: if (minx >= maxx) {
196: throw new InvalidParameterValueException(Messages
197: .getMessage("WPVS_INVALID_MINX_MAXX")); //$NON-NLS-1$
198: }
199: if (miny >= maxy) {
200: throw new InvalidParameterValueException(Messages
201: .getMessage("WPVS_INVALID_MINY_MAXY")); //$NON-NLS-1$
202: }
203: queryBox = new Rectangle(minx, maxx, miny, maxy);
204: }
205:
206: // RADIUS
207: int radius = 0;
208: if (param.get("RADIUS") != null) {
209: try {
210: radius = Integer
211: .parseInt(param.remove("RADIUS").trim());
212: } catch (NumberFormatException nfe) {
213: throw new InvalidParameterValueException(Messages
214: .getMessage("WPVS_INVALID_RADIUS"));
215: }
216: if (radius < 0) {
217: throw new InvalidParameterValueException(Messages
218: .getMessage("WPVS_INVALID_RADIUS_LESS_0"));
219: }
220: }
221:
222: // I,J or QUERYBOX?
223: if (clickPoint == null && queryBox == null) {
224: throw new InvalidParameterValueException(Messages
225: .getMessage("WPVS_INVALID_QUERYTYPE")); //$NON-NLS-1$
226: }
227:
228: // DEPTH
229: float depth = 0;
230: if (param.get("DEPTH") != null) {
231: try {
232: depth = Float.parseFloat(param.remove("DEPTH").trim());
233: } catch (NumberFormatException nfe) {
234: throw new InvalidParameterValueException(Messages
235: .getMessage("WPVS_INVALID_DEPTH"));
236: }
237: if (depth < 0) {
238: throw new InvalidParameterValueException(Messages
239: .getMessage("WPVS_INVALID_DEPTH_LESS_0"));
240: }
241: }
242:
243: // EXCEPTIONS (default=application/vnd.ogc.se_xml)
244: String exceptions = param.remove("EXCEPTIONS"); //$NON-NLS-1$
245: if (exceptions == null) {
246: exceptions = "application/vnd.ogc.se_xml"; //$NON-NLS-1$
247: }
248:
249: // INFO_FORMAT (mime-type)
250: String infoFormat = param.remove("INFO_FORMAT"); //$NON-NLS-1$
251: if (infoFormat == null) {
252: infoFormat = "application/vnd.ogc.gml"; //$NON-NLS-1$
253: }
254:
255: // QUERY_LAYERS
256: List<String> queryDatasets = null;
257: if (param.get("QUERY_DATASETS") != null) {
258: StringTokenizer st = new StringTokenizer(param
259: .remove("QUERY_DATASETS"), ","); //$NON-NLS-1$
260: queryDatasets = new ArrayList<String>(st.countTokens());
261: while (st.hasMoreTokens()) {
262: queryDatasets.add(st.nextToken());
263: }
264: } else {
265: throw new InconsistentRequestException(Messages
266: .getMessage("WPVS_INVALID_QUERYLAYERS")); //$NON-NLS-1$
267: }
268:
269: // FEATURE_COUNT
270: int featureCount = 1;
271: if (param.get("FEATURE_COUNT") != null) {
272: try {
273: featureCount = Integer.parseInt(param
274: .remove("FEATURE_COUNT"));
275: } catch (NumberFormatException nfe) {
276: throw new InvalidParameterValueException(Messages
277: .getMessage("WPVS_INVALID_FEATURE_COUNT"));
278: }
279: if (featureCount < 0) {
280: throw new InvalidParameterValueException(
281: Messages
282: .getMessage("WPVS_INVALID_FEATURE_COUNT_LESS_0"));
283: }
284: }
285:
286: // PARENT
287: boolean parent = true;
288: if (param.get("PARENT") != null) {
289: if (param.get("PARENT").toUpperCase().trim()
290: .equals("FALSE")) {
291: parent = false;
292: } else if (!param.remove("PARENT").toUpperCase().trim()
293: .equals("TRUE")) {
294: throw new InvalidParameterValueException(Messages
295: .getMessage("WPVS_INVALID_PARENT_NOT_BOOLEAN"));
296: }
297: }
298:
299: // VendorSpecificParameter; because all defined parameters has been
300: // removed from the model the vendorSpecificParameters are what left
301: Map<String, String> vendorSpecificParameter = param;
302:
303: return new Get3DFeatureInfo(version, id,
304: vendorSpecificParameter, getViewRequestCopy,
305: clickPoint, queryBox, apexAngle, radius, depth,
306: infoFormat, exceptions, queryDatasets, parent,
307: featureCount);
308:
309: }
310:
311: /**
312: * creates a new WPVSFeatureInfoRequest_Impl object
313: *
314: * @param version
315: * @param id
316: * @param vendorSpecificParameter
317: * @param getViewRequestCopy
318: * @param clickPoint
319: * @param queryBox
320: * @param radius
321: * @param depth
322: * @param infoFormat
323: * @param exceptions
324: * @param queryDatasets
325: * @param parent
326: * @param featureCount
327: */
328: private Get3DFeatureInfo(String version, String id,
329: Map<String, String> vendorSpecificParameter,
330: GetView getViewRequestCopy, Point clickPoint,
331: Rectangle queryBox, float apexAngle, int radius,
332: float depth, String infoFormat, String exceptions,
333: List<String> queryDatasets, boolean parent, int featureCount) {
334:
335: super (version, id, vendorSpecificParameter);
336: this .getViewRequestCopy = getViewRequestCopy;
337: this .clickPoint = clickPoint;
338: this .queryBox = queryBox;
339: this .apexAngle = apexAngle;
340: this .radius = radius;
341: this .depth = depth;
342: this .infoFormat = infoFormat;
343: this .exceptions = exceptions;
344: this .queryDatasets = queryDatasets;
345: this .parent = parent;
346: this .featureCount = featureCount;
347: }
348:
349: public String getServiceName() {
350: return "WPVS"; //$NON-NLS-1$
351: }
352:
353: /**
354: * The AA Parameter indicates the apex angle of a request with a cone
355: *
356: * @return the apex angle
357: */
358: public float getApexAngle() {
359: return apexAngle;
360: }
361:
362: /**
363: * The I and J parameters indicate a point of interest on the map. Used by the request with a
364: * line or cone. The origin is set to (0,0) centered in the pixel at the upper left corner; I
365: * increases to the right and J increases downward. I and J are returned as java.awt.Point
366: * class/datastructure.
367: *
368: * @return the point of interest
369: */
370: public Point getClickPoint() {
371: return clickPoint;
372: }
373:
374: /**
375: * This optional parameter indicates the depth of a query
376: *
377: * @return the depth
378: */
379: public float getDepth() {
380: return depth;
381: }
382:
383: /**
384: * The optional EXCEPTIONS parameter states the manner in which errors are to be reported to the
385: * client. The default value is application/vnd.ogc.se_xml if this parameter is absent from the
386: * request.
387: *
388: * @return the exception format
389: */
390: public String getExceptions() {
391: return exceptions;
392: }
393:
394: /**
395: * <view request copy> is not a name/value pair like the other parameters. Instead, most of the
396: * GetView request parameters that generated the original map are repeated. Two are omitted
397: * because Get3DFeatureInfo provides its own values: VERSION and REQUEST. The remainder of the
398: * GetView request shall be embedded contiguously in the Get3DFeatureInfo request.
399: *
400: * @return a copy of the original request
401: */
402: public GetView getGetViewRequestCopy() {
403: return getViewRequestCopy;
404: }
405:
406: /**
407: * The optional INFO_FORMAT indicates what format to use when returning the feature information.
408: * Supported values for a Get3DFeatureInfo request on a WPVS instance are listed as MIME types
409: * in one or more <Format>elements inside the <Request><FeatureInfo>element of its Capabilities
410: * XML. The entire MIME type string in <Format>is used as the value of the INFO_FORMAT
411: * parameter. In an HTTP environment, the MIME type shall be set on the returned object using
412: * the Content-type entity header.
413: * <p>
414: * </p>
415: * <b>EXAMPLE: </b> <tt> The parameter INFO_FORMAT=application/vnd.ogc.gml
416: * requests that the feature information be formatted in Geography Markup
417: * Language (GML).</tt>
418: *
419: * @return the format
420: */
421: public String getInfoFormat() {
422: return infoFormat;
423: }
424:
425: /**
426: * The required QUERY_LAYERS parameter states the map layer(s) from which feature information is
427: * desired to be retrieved. Its value is a comma- separated list of one or more map layers that
428: * are returned as an array. This parameter shall contain at least one layer name, but may
429: * contain fewer layers than the original GetView request.
430: * <p>
431: * </p>
432: * If any layer in this list is not contained in the Capabilities XML of the WPVS, the results
433: * are undefined and the WPVS shall produce an exception response.
434: *
435: * @return the layer names
436: */
437: public List<String> getQueryDatasets() {
438: return queryDatasets;
439: }
440:
441: /**
442: * @return true if a parent is available.
443: */
444: public boolean getParent() {
445: return parent;
446: }
447:
448: /**
449: * @return the number of features.
450: */
451: public int getFeatureCount() {
452: return featureCount;
453: }
454:
455: /**
456: * The parameter QueryBox indicates the rectangle for the Request with a pyramid
457: *
458: * @return the queryBox
459: */
460: public Rectangle getQueryBox() {
461: return queryBox;
462: }
463:
464: /**
465: * @return the radius of a feature info request.
466: */
467: public int getRadius() {
468: return radius;
469: }
470:
471: }
|