libosmscout  1.1.1
ElevationService.h
Go to the documentation of this file.
1 #ifndef OSMSCOUT_ELEVATION_SERVICE_H
2 #define OSMSCOUT_ELEVATION_SERVICE_H
3 
4 /*
5  This source is part of the libosmscout library
6  Copyright (C) 2019 Lukas Karas
7 
8  This library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU Lesser General Public
10  License as published by the Free Software Foundation; either
11  version 2.1 of the License, or (at your option) any later version.
12 
13  This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public
19  License along with this library; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22 
23 #include <osmscout/TypeConfig.h>
24 #include <osmscout/Way.h>
26 #include <osmscout/FeatureReader.h>
27 
28 #include <osmscout/util/TileId.h>
29 
30 #include <vector>
31 
32 namespace osmscout {
33 
35 {
37  std::vector<WayRef> contours;
38 };
39 
41 {
42  Distance distance;
43  Distance elevation;
44  GeoCoord coord;
46 };
47 
48 template <typename DataLoader>
49 class ElevationService CLASS_FINAL
50 {
51 private:
52  DataLoader &dataLoader;
53  MagnificationLevel loadTileMag;
54 
55 public:
56  explicit ElevationService(DataLoader &dataLoader,
57  MagnificationLevel loadTileMag = Magnification::magSuburb):
58  dataLoader(dataLoader), loadTileMag(loadTileMag)
59  {}
60 
61  std::vector<ElevationPoint> ElevationProfile(const std::vector<GeoCoord> &way)
62  {
63  std::vector<ElevationPoint> result;
64  ElevationProfile(way, [&result](const Distance &, const std::vector<ElevationPoint> &points){
65  result.insert(result.end(), points.begin(), points.end());
66  });
67  return result;
68  }
69 
70  size_t ElevationProfile(const std::vector<GeoCoord> &way,
71  std::function<void(const Distance &distance, const std::vector<ElevationPoint> &points)> callback,
72  BreakerRef breaker=nullptr)
73  {
74  if (way.empty()){
75  return 0;
76  }
77 
78  Distance distance;
79  size_t pointCnt = 0;
80  GeoCoord intersection;
81 
82  std::vector<ContoursData> contours;
83  GeoBox loadBox;
84 
85  for (size_t i=0; i < way.size()-1; i+=1){
86  std::vector<ElevationPoint> result;
87  GeoCoord a1=way[i];
88  GeoCoord a2=way[i+1];
89  GeoBox lineBox(a1,a2);
90 
91  if (i%100==0 && breaker && breaker->IsAborted()){
92  break;
93  }
94 
95  if (!loadBox.Includes(a1) || !loadBox.Includes(a2)) {
96  TileId tile1=TileId::GetTile(loadTileMag, lineBox.GetMinCoord());
97  TileId tile2=TileId::GetTile(loadTileMag, lineBox.GetMaxCoord());
98  TileIdBox tileBox(tile1, tile2);
99  loadBox=tileBox.GetBoundingBox(Magnification(loadTileMag));
100  if (tileBox.GetCount() > 100){
101  osmscout::log.Warn() << "Too huge area for loading " << loadBox.GetDisplayText();
102  continue;
103  }
104  //osmscout::log.Debug() << "box " << lineBox.GetDisplayText() << " -> " << loadBox.GetDisplayText() << " size: " << tileBox.GetCount();
105  assert(loadBox.Includes(a1));
106  assert(loadBox.Includes(a2));
107  contours = dataLoader.LoadContours(loadBox);
108  }
109 
110  for (const ContoursData &contoursData:contours) {
111 
112  for (const auto &contour:contoursData.contours) {
113  if (!lineBox.Intersects(contour->GetBoundingBox())){
114  continue;
115  }
116 
117  EleFeatureValue *eleValue=contoursData.reader.GetValue(contour->GetFeatureValueBuffer());
118  if (eleValue==nullptr) {
119  continue;
120  }
121 
122  for (size_t bi=0; bi < contour->nodes.size()-1; bi+=1){
123  GeoCoord b1=contour->nodes[bi].GetCoord();
124  GeoCoord b2=contour->nodes[bi+1].GetCoord();
125  if (GetLineIntersection(a1,a2,
126  b1,b2,
127  intersection)) {
128 
129  result.push_back(ElevationPoint{
130  distance + GetEllipsoidalDistance(a1, intersection),
131  Meters(eleValue->GetEle()),
132  intersection,
133  contour
134  });
135 
136  //log.Debug() << " " << eleValue->GetEle() << " m, distance " << distance << " + " << GetEllipsoidalDistance(a1, intersection) << " : " << intersection.GetDisplayText();
137  }
138  }
139 
140  }
141  }
142 
143  //log.Debug() << "At distance " << distance << " adding " << GetEllipsoidalDistance(a1,a2) << " (" << a1.GetDisplayText() << " -> " << a2.GetDisplayText() << ")";
144  distance+=GetEllipsoidalDistance(a1,a2);
145  if (!result.empty()) {
146  std::sort(result.begin(), result.end(), [](const ElevationPoint &a, const ElevationPoint &b) {
147  if (a.distance != b.distance) {
148  return a.distance < b.distance;
149  }
150  if (a.elevation != b.elevation) {
151  return a.elevation < b.elevation;
152  }
153  return a.coord < b.coord;
154  });
155  pointCnt += result.size();
156  callback(distance, result);
157  }
158  }
159  return pointCnt;
160  }
161 };
162 
163 }
164 
165 #endif //OSMSCOUT_ELEVATION_SERVICE_H
OSMSCOUT_API Log log
GeoCoord coord
Definition: ElevationService.h:44
size_t ElevationProfile(const std::vector< GeoCoord > &way, std::function< void(const Distance &distance, const std::vector< ElevationPoint > &points)> callback, BreakerRef breaker=nullptr)
Definition: ElevationService.h:70
std::vector< ElevationPoint > ElevationProfile(const std::vector< GeoCoord > &way)
Definition: ElevationService.h:61
std::shared_ptr< Breaker > BreakerRef
Definition: Breaker.h:65
Definition: Area.h:86
Definition: ElevationService.h:40
EleFeatureValueReader reader
Definition: ElevationService.h:36
std::shared_ptr< Way > WayRef
Definition: Way.h:202
OSMSCOUT_API Distance GetEllipsoidalDistance(double aLon, double aLat, double bLon, double bLat)
bool GetLineIntersection(const N &a1, const N &a2, const N &b1, const N &b2, I &intersection)
Definition: Geometry.h:258
Distance elevation
Definition: ElevationService.h:43
Definition: Area.h:38
WayRef contour
Definition: ElevationService.h:45
Distance distance
Definition: ElevationService.h:42
ElevationService(DataLoader &dataLoader, MagnificationLevel loadTileMag=Magnification::magSuburb)
Definition: ElevationService.h:56
Distance Meters(double m)
Definition: Distance.h:358
Log & Warn(bool state)
Definition: Logger.h:462
Definition: ElevationService.h:34
std::vector< WayRef > contours
Definition: ElevationService.h:37
Definition: TypeFeatures.h:1297
uint32_t GetEle() const
Definition: TypeFeatures.h:1316
static TileId GetTile(const Magnification &magnification, const GeoCoord &coord)
Definition: TileId.h:45