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