libosmscout  1.1.1
WaterIndexProcessor.h
Go to the documentation of this file.
1 #ifndef OSMSCOUT_IMPORT_WATERINDEXPROCESSOR_H
2 #define OSMSCOUT_IMPORT_WATERINDEXPROCESSOR_H
3 
4 /*
5  This source is part of the libosmscout library
6  Copyright (C) 2017 Tim Teulings
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 <fstream>
24 #include <list>
25 #include <map>
26 #include <set>
27 #include <memory>
28 #include <vector>
29 
30 #include <osmscout/GeoCoord.h>
31 #include <osmscout/Pixel.h>
32 
33 #include <osmscout/GroundTile.h>
34 
36 #include <osmscout/util/Geometry.h>
37 #include <osmscout/util/Progress.h>
40 
42 
44 
45 namespace osmscout {
46 
55  template<typename InputIterator>
56  void WriteGpx(InputIterator begin, InputIterator end, const std::string &name)
57  {
58  std::ofstream gpxFile;
59 
60  gpxFile.open(name.c_str());
61  gpxFile.imbue(std::locale("C"));
62  gpxFile.precision(100);
63 
64  gpxFile << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
65  gpxFile << "<gpx creator=\"osmscout\" version=\"1.1\" xmlns=\"http://www.topografix.com/GPX/1/1\"";
66  gpxFile << " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"";
67  gpxFile << " xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\">\n";
68 
69  gpxFile << " <trk><trkseg>\n";
70  for (InputIterator it=begin; it!=end;it++) {
71  gpxFile << "<trkpt lat=\"" << it->GetLat() << "\" lon=\"" << it->GetLon() << "\"></trkpt>\n";
72  }
73  gpxFile << " </trkseg></trk>\n</gpx>";
74 
75  gpxFile.close();
76  }
77 
78  extern void WriteGpx(const std::vector<Point> &path, const std::string& name);
79 
109  class OSMSCOUT_IMPORT_API WaterIndexProcessor CLASS_FINAL
110  {
111  public:
116  enum class CoastState : uint8_t
117  {
118  undefined = 0,
119  land = 1,
120  water = 2,
121  unknown = 3,
122  };
123 
133  {
135  bool isArea;
136  double sortCriteria;
139  std::vector<Point> coast;
142  };
143 
144  using CoastRef = std::shared_ptr<Coast>;
145 
149  enum State : uint8_t
150  {
151  unknown = 0,
152  land = 1,
153  water = 2,
154  coast = 3
155  };
156 
161  {
162  private:
163  double cellWidth;
164  double cellHeight;
165  uint32_t cellXStart;
166  uint32_t cellXEnd;
167  uint32_t cellYStart;
168  uint32_t cellYEnd;
169  uint32_t cellXCount;
170  uint32_t cellYCount;
171  std::vector<uint8_t> area;
172 
173  public:
174  void SetBox(const GeoBox& boundingBox,
175  double cellWidth,
176  double cellHeight);
177 
178  inline double GetCellWidth() const
179  {
180  return cellWidth;
181  }
182 
183  inline double GetCellHeight() const
184  {
185  return cellHeight;
186  }
187 
188  inline uint32_t GetXStart() const
189  {
190  return cellXStart;
191  }
192 
193  inline uint32_t GetYStart() const
194  {
195  return cellYStart;
196  }
197 
198  inline uint32_t GetXEnd() const
199  {
200  return cellXEnd;
201  }
202 
203  inline uint32_t GetYEnd() const
204  {
205  return cellYEnd;
206  }
207 
208  inline uint32_t GetXCount() const
209  {
210  return cellXCount;
211  }
212 
213  inline uint32_t GetYCount() const
214  {
215  return cellYCount;
216  }
217 
218  inline bool IsInAbsolute(uint32_t x, uint32_t y) const
219  {
220  return x>=cellXStart &&
221  x<=cellXEnd &&
222  y>=cellYStart &&
223  y<=cellYEnd;
224  }
225 
226  State GetState(uint32_t x, uint32_t y) const;
227  inline State GetStateAbsolute(uint32_t x, uint32_t y) const
228  {
229  return GetState(x-cellXStart,
230  y-cellYStart);
231  }
232 
233  void SetState(uint32_t x, uint32_t y, State state);
234  inline void SetStateAbsolute(uint32_t x, uint32_t y, State state)
235  {
236  SetState(x-cellXStart,
237  y-cellYStart,
238  state);
239  }
240  };
241 
246  {
247  // Transient
248  uint32_t level;
250 
251  // Persistent
252  bool hasCellData;
253  uint8_t dataOffsetBytes;
256 
258 
259  void SetBox(const GeoBox& boundingBox,
260  double cellWidth,
261  double cellHeight);
262  };
263 
267  enum Direction : int8_t
268  {
269  out = -1,
270  touch = 0,
271  in = 1
272  };
273 
278  {
279  size_t coastline;
281  GeoCoord prevPoint;
282  GeoCoord point;
283  double distanceSquare;
285  uint8_t borderIndex;
286  };
287 
288  using IntersectionRef = std::shared_ptr<Intersection>;
289 
295  {
296  Id id;
297  bool isArea;
299  GeoBox boundingBox;
300  Pixel cell;
301  std::vector<GeoCoord> points;
302  std::map<Pixel,std::list<IntersectionRef>> cellIntersections;
305  };
306 
307  using CoastlineDataRef = std::shared_ptr<CoastlineData>;
308 
313  {
314  std::vector<CoastlineDataRef> coastlines;
315  std::map<Pixel,std::list<size_t>> cellCoastlines;
316  std::map<Pixel,std::list<size_t>> cellCoveredCoastlines;
317  };
318 
319  private:
320 
324  struct IntersectionByPathComparator
325  {
326  inline bool operator()(const IntersectionRef& a, const IntersectionRef& b) const
327  {
328  if (a->prevWayPointIndex==b->prevWayPointIndex) {
329  return a->distanceSquare<b->distanceSquare;
330  }
331 
332  return a->prevWayPointIndex<b->prevWayPointIndex;
333  }
334  };
335 
339  struct IntersectionCWComparator
340  {
341  inline bool operator()(const IntersectionRef& a, const IntersectionRef& b) const
342  {
343  if (a->borderIndex==b->borderIndex) {
344  switch (a->borderIndex) {
345  case 0:
346  if (a->point.GetLon()==b->point.GetLon()){
347  return a->prevPoint.GetLon()<b->prevPoint.GetLon();
348  }
349  return a->point.GetLon()<b->point.GetLon();
350 
351  case 1:
352  if (a->point.GetLat()==b->point.GetLat()){
353  return a->prevPoint.GetLat()>b->prevPoint.GetLat();
354  }
355  return a->point.GetLat()>b->point.GetLat();
356 
357  case 2:
358  if (a->point.GetLon()==b->point.GetLon()){
359  return a->prevPoint.GetLon()>b->prevPoint.GetLon();
360  }
361  return a->point.GetLon()>b->point.GetLon();
362 
363  default: /* 3 */
364  if (a->point.GetLat()==b->point.GetLat()){
365  return a->prevPoint.GetLat()<b->prevPoint.GetLat();
366  }
367  return a->point.GetLat()<b->point.GetLat();
368  }
369  }
370  else {
371  return a->borderIndex<b->borderIndex;
372  }
373  }
374  };
375 
379  struct CellBoundaries
380  {
381  double lonMin;
382  double lonMax;
383  double latMin;
384  double latMax;
385 
386  using BorderCoords = std::array<GroundTile::Coord, 4>;
387  using BorderPoints = std::array<GeoCoord, 4>;
388  BorderCoords borderCoords;
389  BorderPoints borderPoints;
390 
391  inline CellBoundaries(const StateMap &stateMap, const Pixel &cell)
392  {
393  lonMin=(stateMap.GetXStart()+cell.x)*stateMap.GetCellWidth()-180.0;
394  lonMax=(stateMap.GetXStart()+cell.x+1)*stateMap.GetCellWidth()-180.0;
395  latMin=(stateMap.GetYStart()+cell.y)*stateMap.GetCellHeight()-90.0;
396  latMax=(stateMap.GetYStart()+cell.y+1)*stateMap.GetCellHeight()-90.0;
397 
398  borderPoints[0]=GeoCoord(latMax,lonMin); // top left
399  borderPoints[1]=GeoCoord(latMax,lonMax); // top right
400  borderPoints[2]=GeoCoord(latMin,lonMax); // bottom right
401  borderPoints[3]=GeoCoord(latMin,lonMin); // bottom left
402 
403  borderCoords[0].Set(0,GroundTile::Coord::CELL_MAX,false); // top left
404  borderCoords[1].Set(GroundTile::Coord::CELL_MAX,GroundTile::Coord::CELL_MAX,false); // top right
405  borderCoords[2].Set(GroundTile::Coord::CELL_MAX,0,false); // bottom right
406  borderCoords[3].Set(0,0,false); // bottom left
407  }
408  };
409 
410  private:
411  std::string StateToString(State state) const;
412  std::string TypeToString(GroundTile::Type type) const;
413 
429  GroundTile::Coord Transform(const GeoCoord& point,
430  const StateMap& stateMap,
431  double cellMinLat,
432  double cellMinLon,
433  bool coast);
434 
448  void GetCells(const StateMap& stateMap,
449  const GeoCoord& a,
450  const GeoCoord& b,
451  std::set<Pixel>& cellIntersections) const;
452 
462  void GetCellIntersections(const StateMap& stateMap,
463  const std::vector<GeoCoord>& points,
464  size_t coastline,
465  std::map<Pixel,std::list<IntersectionRef>>& cellIntersections);
466 
470  bool IsCellInBoundingPolygon(const CellBoundaries& cellBoundary,
471  const std::list<CoastRef>& boundingPolygons);
472 
476  bool ContainsCoord(const std::list<GroundTile> &tiles,
477  const GroundTile::Coord &coord,
478  GroundTile::Type type);
479 
483  bool ContainsCoord(const std::list<GroundTile> &tiles,
484  const GroundTile::Coord &coord);
485 
489  bool ContainsWater(const Pixel &coord,
490  const StateMap &stateMap,
491  const std::map<Pixel,std::list<GroundTile>>& cellGroundTileMap,
492  const GroundTile::Coord &testCoord1,
493  const GroundTile::Coord &testCoord2);
494 
500  void WalkBorderCW(GroundTile& groundTile,
501  const StateMap& stateMap,
502  double cellMinLat,
503  double cellMinLon,
504  const IntersectionRef& incoming,
505  const IntersectionRef& outgoing,
506  const CellBoundaries::BorderCoords &borderCoords);
507 
511  IntersectionRef GetNextCW(const std::list<IntersectionRef>& intersectionsCW,
512  const IntersectionRef& current) const;
513 
518  void WalkPathBack(GroundTile& groundTile,
519  const StateMap& stateMap,
520  double cellMinLat,
521  double cellMinLon,
522  const IntersectionRef& pathStart,
523  const IntersectionRef& pathEnd,
524  const std::vector<GeoCoord>& points,
525  bool isArea);
526 
531  void WalkPathForward(GroundTile& groundTile,
532  const StateMap& stateMap,
533  double cellMinLat,
534  double cellMinLon,
535  const IntersectionRef& pathStart,
536  const IntersectionRef& pathEnd,
537  const std::vector<GeoCoord>& points,
538  bool isArea);
539 
546  IntersectionRef FindSiblingIntersection(const IntersectionRef &intersection,
547  const std::list<IntersectionRef> &intersectionsCW,
548  bool isArea);
549 
560  bool WalkFromTripoint(GroundTile &groundTile,
561  const StateMap& stateMap,
562  const CellBoundaries &cellBoundaries,
563  IntersectionRef &pathStart,
564  IntersectionRef &pathEnd,
565  Data &data,
566  const std::list<IntersectionRef> &intersectionsCW,
567  const std::vector<size_t> &containingPaths);
568 
573  void WalkPath(GroundTile &groundTile,
574  const StateMap& stateMap,
575  const CellBoundaries &cellBoundaries,
576  const IntersectionRef pathStart,
577  const IntersectionRef pathEnd,
578  CoastlineDataRef coastline);
579 
585  bool WalkBoundaryCW(GroundTile &groundTile,
586  const StateMap &stateMap,
587  const IntersectionRef outIntersection,
588  const std::list<IntersectionRef> &intersectionsCW,
589  std::set<IntersectionRef> &visitedIntersections,
590  const CellBoundaries &cellBoundaries,
591  Data& data,
592  const std::vector<size_t> &containingPaths);
593 
605  void SynthesizeCoastlines2(Progress& progress,
606  const std::list<CoastRef>& boundingPolygons,
607  const std::list<CoastRef>& coastlines,
608  std::list<CoastRef>& synthesized);
609 
613  void HandleCoastlineCell(Progress& progress,
614  const Pixel &cell,
615  const std::list<size_t>& intersectCoastlines,
616  const StateMap& stateMap,
617  std::map<Pixel,std::list<GroundTile> >& cellGroundTileMap,
618  Data& data);
619 
620  void TransformCoastlines(Progress& progress,
621  TransPolygon::OptimizeMethod optimizationMethod,
622  double tolerance,
623  double minObjectDimension,
624  const Projection& projection,
625  const std::list<CoastRef>& coastlines,
626  std::vector<CoastlineDataRef> &transformedCoastlines);
627 
628  void FilterIntersectCoastlines(Progress& progress,
629  std::vector<CoastlineDataRef> &transformedCoastlines);
630 
631  void FilterEncapsulatedCoastlines(Progress& progress,
632  std::vector<CoastlineDataRef> &transformedCoastlines);
633 
634  void ComputeCoveredTiles(Progress& progress,
635  const StateMap& stateMap,
636  Data& data,
637  std::vector<CoastlineDataRef> &transformedCoastlines);
638 
642  static bool CoastlineGeoSizeSorter(const CoastlineDataRef &a, const CoastlineDataRef &b);
643 
644 public:
648  void MergeCoastlines(Progress& progress,
649  std::list<WaterIndexProcessor::CoastRef>& coastlines);
650 
661  void GetCells(const StateMap& stateMap,
662  const std::vector<GeoCoord>& points,
663  std::set<Pixel>& cellIntersections) const;
664 
675  void GetCells(const StateMap& stateMap,
676  const std::vector<Point>& points,
677  std::set<Pixel>& cellIntersections) const;
678 
687  void SynthesizeCoastlines(Progress& progress,
688  std::list<CoastRef>& coastlines,
689  std::list<CoastRef>& boundingPolygons);
690 
694  void CalculateCoastlineData(Progress& progress,
695  TransPolygon::OptimizeMethod optimizationMethod,
696  double tolerance,
697  double minObjectDimension,
698  const Projection& projection,
699  const StateMap& stateMap,
700  const std::list<CoastRef>& coastlines,
701  Data& data);
702 
706  void MarkCoastlineCells(Progress& progress,
707  StateMap& stateMap,
708  const Data& data);
709 
718  void HandleAreaCoastlinesCompletelyInACell(Progress& progress,
719  const StateMap& stateMap,
720  Data& data,
721  std::map<Pixel,std::list<GroundTile> >& cellGroundTileMap);
722 
726  void HandleCoastlinesPartiallyInACell(Progress& progress,
727  const StateMap& stateMap,
728  std::map<Pixel,std::list<GroundTile> >& cellGroundTileMap,
729  Data& data);
730 
738  void CalculateCoastEnvironment(Progress& progress,
739  StateMap& stateMap,
740  const std::map<Pixel,std::list<GroundTile> >& cellGroundTileMap);
741 
745  void FillWaterAroundIsland(Progress& progress,
746  StateMap& stateMap,
747  std::map<Pixel,std::list<GroundTile> >& cellGroundTileMap,
748  const std::list<CoastRef>& boundingPolygons);
749 
756  void FillWater(Progress& progress,
757  Level& level,
758  size_t tileCount,
759  const std::list<CoastRef>& boundingPolygons);
760 
767  void FillLand(Progress& progress,
768  StateMap& stateMap);
769 
773  void CalculateHasCellData(Level& level,
774  const std::map<Pixel,std::list<GroundTile> >& cellGroundTileMap) const;
775 
779  void DumpIndexHeader(FileWriter& writer,
780  std::vector<Level>& levels);
781 
785  void WriteTiles(Progress& progress,
786  const std::map<Pixel,std::list<GroundTile>>& cellGroundTileMap,
787  Level& level,
788  FileWriter& writer);
789  };
790 }
791 
792 #endif
Direction direction
The distance^2 between the path point and the intersectionPoint.
Definition: WaterIndexProcessor.h:284
uint32_t GetXStart() const
Definition: WaterIndexProcessor.h:188
State
Definition: WaterIndexProcessor.h:149
uint64_t Id
Definition: OSMScoutTypes.h:41
Definition: WaterIndexProcessor.h:245
std::map< Pixel, std::list< IntersectionRef > > cellIntersections
The points of the coastline.
Definition: WaterIndexProcessor.h:302
bool IsInAbsolute(uint32_t x, uint32_t y) const
Definition: WaterIndexProcessor.h:218
double GetCellHeight() const
Definition: WaterIndexProcessor.h:183
CoastState left
Definition: WaterIndexProcessor.h:140
int64_t OSMId
Definition: OSMScoutTypes.h:34
CoastState right
Definition: WaterIndexProcessor.h:304
uint8_t dataOffsetBytes
Number of bytes per entry in bitmap.
Definition: WaterIndexProcessor.h:253
uint32_t GetYStart() const
Definition: WaterIndexProcessor.h:193
State GetStateAbsolute(uint32_t x, uint32_t y) const
Definition: WaterIndexProcessor.h:227
double distanceSquare
The intersection point.
Definition: WaterIndexProcessor.h:283
Definition: WaterIndexProcessor.h:312
#define OSMSCOUT_IMPORT_API
Definition: ImportImportExport.h:45
Id backNodeId
Definition: WaterIndexProcessor.h:138
std::shared_ptr< CoastlineData > CoastlineDataRef
Definition: WaterIndexProcessor.h:307
uint32_t GetXCount() const
Definition: WaterIndexProcessor.h:208
StateMap stateMap
Index to handle state of cells.
Definition: WaterIndexProcessor.h:257
GeoBox boundingBox
true, if the complete coastline is within one cell
Definition: WaterIndexProcessor.h:299
CoastState
Definition: WaterIndexProcessor.h:116
std::map< Pixel, std::list< size_t > > cellCoastlines
data for each coastline
Definition: WaterIndexProcessor.h:315
OSMId id
Definition: WaterIndexProcessor.h:134
uint32_t level
The actual zoom level.
Definition: WaterIndexProcessor.h:248
std::vector< CoastlineDataRef > coastlines
Definition: WaterIndexProcessor.h:314
bool hasCellData
If true, we have cell data.
Definition: WaterIndexProcessor.h:252
CoastState right
Definition: WaterIndexProcessor.h:141
std::vector< GeoCoord > points
The cell that completely contains the coastline.
Definition: WaterIndexProcessor.h:301
Definition: WaterIndexProcessor.h:160
Definition: Area.h:38
GeoCoord point
just helper for sorting
Definition: WaterIndexProcessor.h:282
Definition: WaterIndexProcessor.h:132
std::vector< Point > coast
Definition: WaterIndexProcessor.h:139
Definition: WaterIndexProcessor.h:294
FileOffset indexDataOffset
File offset of start cell state data on disk.
Definition: WaterIndexProcessor.h:255
#define CLASS_FINAL
Definition: Compiler.h:26
bool isArea
Definition: WaterIndexProcessor.h:135
Id frontNodeId
Definition: WaterIndexProcessor.h:137
CoastState left
All intersections for each cell.
Definition: WaterIndexProcessor.h:303
Pixel cell
GeoBox from points (already transformed)
Definition: WaterIndexProcessor.h:300
std::map< Pixel, std::list< size_t > > cellCoveredCoastlines
Contains for each cell the list of intersecting coastlines.
Definition: WaterIndexProcessor.h:316
Id id
Definition: WaterIndexProcessor.h:296
uint32_t GetYEnd() const
Definition: WaterIndexProcessor.h:203
bool isArea
The id of the coastline.
Definition: WaterIndexProcessor.h:297
double GetCellWidth() const
Definition: WaterIndexProcessor.h:178
Definition: WaterIndexProcessor.h:277
uint8_t borderIndex
1 in, 0 touch, -1 out
Definition: WaterIndexProcessor.h:285
State defaultCellData
If hasCellData is false, this is the value to be returned for all cells.
Definition: WaterIndexProcessor.h:254
size_t coastline
Definition: WaterIndexProcessor.h:279
bool isCompletelyInCell
true,if the boundary forms an area
Definition: WaterIndexProcessor.h:298
uint64_t FileOffset
Definition: OSMScoutTypes.h:47
uint32_t GetXEnd() const
Definition: WaterIndexProcessor.h:198
std::shared_ptr< Intersection > IntersectionRef
Definition: WaterIndexProcessor.h:288
std::shared_ptr< Coast > CoastRef
Definition: WaterIndexProcessor.h:144
codepoint(*)(const character *, int context) Transform
functor implements desired transformation of the character It has 2 arguments:
Definition: utf8helper.h:49
uint32_t GetYCount() const
Definition: WaterIndexProcessor.h:213
void SetStateAbsolute(uint32_t x, uint32_t y, State state)
Definition: WaterIndexProcessor.h:234
size_t prevWayPointIndex
Running number of the intersecting coastline.
Definition: WaterIndexProcessor.h:280
void WriteGpx(InputIterator begin, InputIterator end, const std::string &name)
Definition: WaterIndexProcessor.h:56
GeoCoord prevPoint
The index of the path point before the intersection.
Definition: WaterIndexProcessor.h:281
Direction
Definition: WaterIndexProcessor.h:267
FileOffset indexEntryOffset
File offset of this entry on disk.
Definition: WaterIndexProcessor.h:249
double sortCriteria
Definition: WaterIndexProcessor.h:136