1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2011-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
10 /// @file NBHeightMapper.h
11 /// @author Jakob Erdmann
12 /// @author Laura Bieker
13 /// @author Michael Behrisch
14 /// @date Sept 2011
15 /// @version $Id$
16 ///
17 // Set z-values for all network positions based on data from a height map
18 /****************************************************************************/
19 #ifndef NBHeightMapper_h
20 #define NBHeightMapper_h
21
22
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #include <config.h>
27
28 #ifdef _MSC_VER
29 typedef __int16 int16_t;
30 #else
31 #include <stdint.h>
32 #endif
33
34 #include <string>
35 #include <foreign/rtree/RTree.h>
36 #include <utils/geom/PositionVector.h>
37 #include <utils/geom/Boundary.h>
38 #include <utils/common/UtilExceptions.h>
39
40 #define TRIANGLE_RTREE_QUAL RTree<NBHeightMapper::Triangle*, NBHeightMapper::Triangle, float, 2, NBHeightMapper::QueryResult>
41
42 // ===========================================================================
43 // class declarations
44 // ===========================================================================
45 class OptionsCont;
46
47
48 // ===========================================================================
49 // class definitions
50 // ===========================================================================
51 /**
52 * @class NBHeightMapper
53 * @brief Set z-values for all network positions based on data from a height map
54 *
55 * Importing data from '.shp'-files works only if SUMO was compiled with GDAL-support.
56 * If not, an error message is generated.
57 */
58 class NBHeightMapper {
59
60 friend class NBHeightMapperTest;
61
62 public:
63 /** @brief loads heigh map data if any loading options are set
64 *
65 * @param[in] oc The options container to get further options from
66 * @exception ProcessError if something fails
67 */
68 static void loadIfSet(OptionsCont& oc);
69
70 /// @brief return the singleton instance (maybe 0)
71 static const NBHeightMapper& get();
72
73 /// @brief returns whether the NBHeightMapper has data
74 bool ready() const;
75
76 /// @brief returns the convex boundary of all known triangles
getBoundary()77 const Boundary& getBoundary() {
78 return Singleton.myBoundary;
79 }
80
81 /// @brief returns height for the given geo coordinate (WGS84)
82 double getZ(const Position& geo) const;
83
84 class QueryResult;
85 /* @brief content class for the rtree. Since we wish to be able to use the
86 * rtree for spatial querying we have to jump through some minor hoops:
87 * We let each found triangle callback the NBHeightMapper and add itself the
88 * the query result
89 * */
90 class Triangle {
91
92 public:
93 Triangle(const PositionVector& corners);
~Triangle()94 ~Triangle() {};
95
96 /// @brief callback for RTree search
97 void addSelf(const QueryResult& queryResult) const;
98
99 /// @brief checks whether pos lies within triangle (only checks x,y)
100 bool contains(const Position& pos) const;
101
102 /// @brief returns the projection of the give geoCoordinate (WGS84) onto triangle plane
103 double getZ(const Position& geo) const;
104
105 /// @brief returns the normal vector for this triangles plane
106 Position normalVector() const;
107
108 /// @brief the corners of the triangle
109 PositionVector myCorners;
110
111 };
112
113 typedef std::vector<const Triangle*> Triangles;
114
115 /// @brief class for cirumventing the const-restriction of RTree::Search-context
116 class QueryResult {
117 public:
QueryResult()118 QueryResult() {};
~QueryResult()119 ~QueryResult() {};
120 // @brief method not realy const
add(Triangle * triangle)121 void add(Triangle* triangle) const {
122 triangles.push_back(triangle);
123 };
124 mutable Triangles triangles;
125 };
126
127 private:
128 /// @brief the singleton instance
129 static NBHeightMapper Singleton;
130
131 Triangles myTriangles;
132
133 /// @brief The RTree for spatial queries
134 TRIANGLE_RTREE_QUAL myRTree;
135
136 /// @brief raster height information in m for all loaded files
137 std::vector<std::pair<Boundary, int16_t*> > myRasters;
138
139 /// @brief dimensions of one pixel in raster data
140 Position mySizeOfPixel;
141
142 /// @brief convex boundary of all known triangles;
143 Boundary myBoundary;
144
145 private:
146 /// @brief private constructor and destructor (Singleton)
147 NBHeightMapper();
148 ~NBHeightMapper();
149
150 /// @brief adds one triangles worth of height data
151 void addTriangle(PositionVector corners);
152
153 /** @brief load height data from Arcgis-shape file and returns the number of parsed features
154 * @return The number of parsed features
155 * @throws ProcessError
156 */
157 int loadShapeFile(const std::string& file);
158
159 /** @brief load height data from GeoTIFF file and returns the number of non void pixels
160 * @return The number of valid pixels
161 * @throws ProcessError
162 */
163 int loadTiff(const std::string& file);
164
165 /// @brief clears loaded data
166 void clearData();
167
168 /// @brief Invalidated copy constructor.
169 NBHeightMapper(const NBHeightMapper&);
170
171 /// @brief Invalidated assignment operator.
172 NBHeightMapper& operator=(const NBHeightMapper&);
173
174 };
175
176
177 // ===========================================================================
178 // RTree specialization for speedup and avoiding warnings (ripped from SUMORTree.h)
179 // ===========================================================================
180 template<>
RectSphericalVolume(Rect * a_rect)181 inline float TRIANGLE_RTREE_QUAL::RectSphericalVolume(Rect* a_rect) {
182 ASSERT(a_rect);
183 const float extent0 = a_rect->m_max[0] - a_rect->m_min[0];
184 const float extent1 = a_rect->m_max[1] - a_rect->m_min[1];
185 return .78539816f * (extent0 * extent0 + extent1 * extent1);
186 }
187
188 template<>
CombineRect(Rect * a_rectA,Rect * a_rectB)189 inline TRIANGLE_RTREE_QUAL::Rect TRIANGLE_RTREE_QUAL::CombineRect(Rect* a_rectA, Rect* a_rectB) {
190 ASSERT(a_rectA && a_rectB);
191 Rect newRect;
192 newRect.m_min[0] = rtree_min(a_rectA->m_min[0], a_rectB->m_min[0]);
193 newRect.m_max[0] = rtree_max(a_rectA->m_max[0], a_rectB->m_max[0]);
194 newRect.m_min[1] = rtree_min(a_rectA->m_min[1], a_rectB->m_min[1]);
195 newRect.m_max[1] = rtree_max(a_rectA->m_max[1], a_rectB->m_max[1]);
196 return newRect;
197 }
198
199
200 #endif
201
202 /****************************************************************************/
203
204