SpatialQueryDescriptor.hpp
1 #ifndef OPALS_SPATIAL_QUERY_DESCRIPTOR_HPP_INCLUDED
2 #define OPALS_SPATIAL_QUERY_DESCRIPTOR_HPP_INCLUDED
3 
4 #pragma once
5 
6 #include "opals/Vector.hpp"
7 #include "opals/String.hpp"
8 #include "opals/CustomOptionType.hpp"
9 
10 //forward declaration
11 namespace DM {
12  class IGeometry;
13 }
14 
15 namespace opals
16 {
17  /// Describes a spatial selection.
18  /** OPALS supports two types of spatial queries:
19  - k nearest neighbour queries (kNN) and
20  - region queries based on 2D or 3D geometry objects (see RegionType::Type).
21  SpatialQueryDescriptor describes one of those query types, or a combination thereof, which returns up to k objects that are inside the given region.
22  kNN queries return the results ordered in ascending distance from the queried position, where distance is defined according to the kNN-Dimension (2d or 3d).
23  Region queries return objects in unspecified order.
24  A certain order of results for kNN, region, and combined queries can be forced via SortOrder::Type.
25 
26  Syntax for constructor represented as railroad diagrams:
27 
28  \htmlinclude spatial_query_descriptor_diag.xht
29 
30  Syntax for constructor in EBNF:
31  \code
32  SpatialQuery ::=
33  ( GeometryQuery ( NnQuery )?
34  | NnQuery ( GeometryQuery )?
35  )
36  ( ( "ORDER" "=" )? ( "UNSORTED" | "ASC2D" | "ASC3D" ) )?
37 
38  RegionQuery ::=
39  RegionQuery2D
40  | RegionQuery3D
41 
42  RegionQuery2D ::=
43  "WINDOW" "(" Length Width? ")"
44  | "CIRCLE" "(" Radius ")"
45 
46  RegionQuery3D ::=
47  "CYLINDER" "(" Radius ( Height | MinMax ) ")"
48  | "BOX" "(" Length Width? ( Height | MinMax )? ")"
49  | "SPHERE" "(" Radius ")"
50 
51  NnQuery ::=
52  NnQuery2D
53  | NnQuery3D
54 
55  NnQuery2D ::=
56  "NN2D" "(" Count ( ( "MODE" "=" )? ( "ORDINARY" | "QUADRANT" ) )? ")"
57 
58  NnQuery3D ::=
59  "NN3D" "(" Count ( ( "MODE" "=" )? ( "ORDINARY" | "OCTANT" ) )? ")"
60 
61  Count ::= ( "COUNT" "=" )? Integer
62 
63 
64  Length ::= ( "LENGTH" "=" )? Real
65  Width ::= ( "WIDTH" "=" )? Real
66  Height ::= ( "HEIGHT" "=" )? Real
67  Radius ::= ( "RADIUS" "=" )? Real
68  MinMax ::= ( "MIN" "=" )? Real ( "MAX" "=" )? Real
69  \endcode
70 
71  \author JO, WK
72  \date 24.05.2013
73  */
74  class OPALS_API SpatialQueryDescriptor : public CustomOptionType<SpatialQueryDescriptor>
75  {
76  public:
77  /// Dimensionality of nearest neighbor selection
78  struct KNNDim {
79  enum Type {
80  d2 = 2,
81  d3 = 3,
82 
83  Count
84  };
85  };
86 
87  /// k-Nearest neighbor mode
88  struct KNNSelection {
89  enum Type {
90  ordinary, ///< selects k nearest neighbors according to distance, irrespective of direction
91  quadrant, ///< selects kNN equally distributed across all quadrants
92  octant, ///< selects kNN equally distributed across all octants
93 
94  Count
95  };
96  };
97 
98  /// Types supported by region queries
99  struct RegionType {
100  enum Type {
101  // 2D
102  window = 4, ///< axis-aligned rectangle defined by 4 values (xmin, ymin, xmax, ymax)
103  circle = 6, ///< circle defined by 1 value (radius)
104 
105  // 3D
106  box = 5, ///< axis-aligned rectangular cuboid defined by 6 values (xmin, ymin, zmin, xmax, ymax, zmax)
107  sphere = 7, ///< sphere defined by 1 value (radius)
108  cylinder = 8, ///< cylinder defined by 3 values (radius, zmin, zmax)
109 
110  Count
111  };
112  static int getDim( Type type ); ///< dimensionality of regionType: 2-D, 3-D, or undefined==0
113  };
114 
115  /// Sort order of results
116  struct SortOrder {
117  enum Type {
118  unsorted, ///< results are in unspecified order
119  asc2d, ///< results are sorted ascending by 2d distance from query position
120  asc3d, ///< results are sorted ascending by 3d distance from query position
121 
122  Count
123  };
124  };
125 
126  /// Construct from the given string that must adhere to the <a href="#SpatialQuery">syntax</a>, if not empty.
127  SpatialQueryDescriptor( const String &definition = String() );
128 
129 #ifdef __GNUC__
130  typedef bool (SpatialQueryDescriptor::*unspecified_bool_type) ();
131 #else
132  typedef bool (SpatialQueryDescriptor::*unspecified_bool_type) () const;
133 #endif
134 
135 #ifdef __GNUC__
136  operator unspecified_bool_type();
137 #else
138  operator unspecified_bool_type() const;
139 #endif
140 
141 #ifdef __GNUC__
142  bool isEmpty(); // const removed (gcc error: forming reference to qualified function type)
143 #else
144  bool isEmpty() const;
145 #endif
146 
147  /// \name kNN query
148  ///@{
149 #ifdef __GNUC__
150  bool isKNNQuery(); // const removed (gcc error: forming reference to qualified function type)
151 #else
152  bool isKNNQuery() const;
153 #endif
154 
155  unsigned getKNNCount() const;
156  KNNDim::Type getKNNDim() const;
157  KNNSelection::Type getKNNSelection() const;
158 
159  void setKNN( unsigned k, KNNDim::Type knnDim, KNNSelection::Type knnSelection = KNNSelection::ordinary );
160  void resetKNN();
161  ///}@
162 
163 
164  /// \name region query
165  ///@{
166 #ifdef __GNUC__
167  bool isRegionQuery(); // const removed (gcc error: forming reference to qualified function type)
168 #else
169  bool isRegionQuery() const;
170 #endif
171 
172 
173  RegionType::Type getRegionType() const;
174  const Vector<double>& getRegionCoords() const;
175 
176  void setRegion( RegionType::Type type, const Vector<double> &coords );
177  void resetRegion();
178 
179  /// create geometry from regionType and regionCoords
180  DM::IGeometry* createRegion() const;
181  /// set regionType and regionCoords from geometry
182  void setRegion( const DM::IGeometry& geometry );
183  ///}@
184 
185 
186  /// \name sort order
187  ///@{
188  SortOrder::Type getSortOrder() const;
189  void setSortOrder( SortOrder::Type type );
190  ///}@
191 
192  /// \name CustomOptionType interface
193  ///@{
194  static const char * help();
195  static const char * syntax();
196  static bool exportsPythonType();
197  ///}@
198 
199  private:
200  unsigned knnCount; ///< Number of nearest neighbors to be selected (0 -> no kNN query)
201  KNNDim::Type knnDim; ///< Dimensionality of nearest neighbor selection
202  KNNSelection::Type knnSelection; ///< Nearest neighbor selection mode
203 
204  RegionType::Type regionType; ///< Region query object (RegionType::none -> no region query)
205  Vector<double> regionCoords; ///< Coordinates of the query region
206 
207  SortOrder::Type sortOrder; ///< Sort order of region query results
208  };
209 }
210 
211 #endif //OPALS_SPATIAL_QUERY_DESCRIPTOR_HPP_INCLUDED