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 360 : ~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 256 : ~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 : }