OpenCPN Partial API docs
shapefile_basemap.h
1 /******************************************************************************
2  *
3  * Project: OpenCPN
4  * Purpose: Shapefile basemap
5  *
6  ***************************************************************************
7  * Copyright (C) 2012-2023 by David S. Register *
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  * This program is distributed in the hope that it will be useful, *
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17  * GNU General Public License for more details. *
18  * *
19  * You should have received a copy of the GNU General Public License *
20  * along with this program; if not, write to the *
21  * Free Software Foundation, Inc., *
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
23  ***************************************************************************
24  *
25  *
26  */
27 
28 #ifndef SHAPEFILE_BASEMAP_H
29 #define SHAPEFILE_BASEMAP_H
30 
31 #include <functional>
32 #include <vector>
33 #include <map>
34 #include <thread>
35 #include <future>
36 #include "ShapefileReader.hpp"
37 #include "poly_math.h"
38 #include "ocpndc.h"
39 
40 #if (defined(OCPN_GHC_FILESYSTEM) || (defined(__clang_major__) && (__clang_major__ < 15)))
41 // MacOS 1.13
42 #include <ghc/filesystem.hpp>
43 namespace fs = ghc::filesystem;
44 #else
45 #include <filesystem>
46 #include <utility>
47 namespace fs = std::filesystem;
48 #endif
49 
51 class LatLonKey {
52 public:
53  LatLonKey(int lat, int lon) {
54  this->lat = lat;
55  this->lon = lon;
56  }
57  int lat;
58  int lon;
59 
60  bool operator<(const LatLonKey &k) const {
61  if (this->lat < k.lat) {
62  return this->lon < k.lon;
63  }
64  return this->lat < k.lat;
65  }
66 
67  bool operator==(const LatLonKey &other) const {
68  return (lat == other.lat && lon == other.lon);
69  }
70 };
71 
72 template <>
73 struct std::hash<LatLonKey> {
74  std::size_t operator()(const LatLonKey &k) const {
75  return 360 * k.lat + k.lon;
76  }
77 };
78 
80 enum Quality {
82  crude,
84  low,
86  medium,
88  high,
91  full
92 };
93 
94 typedef std::vector<wxRealPoint> contour;
95 typedef std::vector<contour> contour_list;
96 
99 public:
100  ShapeBaseChart() = delete;
101  ShapeBaseChart(const std::string &filename, const size_t &min_scale,
102  const wxColor &color = *wxBLACK)
103  : _dmod(1),
104  _loading(false),
105  _is_usable(false),
106  _is_tiled(false),
107  _min_scale(min_scale),
108  _filename(filename),
109  _reader(nullptr),
110  _color(color){
111  _is_usable = fs::exists(filename);
112  }
113 
114  ShapeBaseChart(const ShapeBaseChart &t) {
115  this->_filename = t._filename;
116  this->_is_usable = t._is_usable;
117  this->_is_tiled = t._is_tiled;
118  this->_min_scale = t._min_scale;
119  this->_reader = nullptr;
120  this->_color = t._color;
121  this->_dmod = t._dmod;
122  this->_loading = t._loading;
123  }
124  ~ShapeBaseChart() { delete _reader; }
125 
126  int _dmod;
127 
128  bool LoadSHP();
129  bool IsUsable() { return _is_usable && !_loading; }
130  size_t MinScale() { return _min_scale; }
131  void RenderViewOnDC(ocpnDC &dc, ViewPort &vp) { DrawPolygonFilled(dc, vp); }
132  static const std::string ConstructPath(const std::string &dir,
133  const std::string &quality_suffix) {
134  return std::string(dir + fs::path::preferred_separator + "basemap_" +
135  quality_suffix + ".shp");
136  }
137 
138  bool CrossesLand(double &lat1, double &lon1, double &lat2, double &lon2);
139 
140 private:
141  std::future<bool> _loaded;
142  bool _loading;
143  bool _is_usable;
144  bool _is_tiled;
145  size_t _min_scale;
146  void DoDrawPolygonFilled(ocpnDC &pnt, ViewPort &vp,
147  const shp::Feature &feature);
148  void DoDrawPolygonFilledGL(ocpnDC &pnt, ViewPort &vp,
149  const shp::Feature &feature);
150  void DrawPolygonFilled(ocpnDC &pnt, ViewPort &vp);
151  void AddPointToTessList(shp::Point &point, ViewPort &vp, GLUtesselator *tobj, bool idl);
152 
153  std::string _filename;
154  shp::ShapefileReader *_reader;
155  std::unordered_map<LatLonKey, std::vector<size_t>> _tiles;
156  wxColor _color;
157 
158  bool LineLineIntersect(const std::pair<double, double> &A,
159  const std::pair<double, double> &B,
160  const std::pair<double, double> &C,
161  const std::pair<double, double> &D);
162 
163  bool PolygonLineIntersect(const shp::Feature &feature,
164  const std::pair<double, double> &A,
165  const std::pair<double, double> &B);
166 };
167 
170 public:
172  ~ShapeBaseChartSet() {}
173  static wxPoint2DDouble GetDoublePixFromLL(ViewPort &vp, double lat,
174  double lon);
175 
176  void RenderViewOnDC(ocpnDC &dc, ViewPort &vp);
177 
178  ShapeBaseChart &SelectBaseMap(const size_t &scale);
179  bool IsUsable() { return _basemap_map.size() > 0 && LowestQualityBaseMap().IsUsable(); }
180 
181  bool CrossesLand(double lat1, double lon1, double lat2, double lon2) {
182  if(IsUsable()) {
183  return HighestQualityBaseMap().CrossesLand(lat1, lon1, lat2, lon2);
184  }
185  return false;
186  }
187 
188  void Reset();
189 
190 private:
191  void LoadBasemaps(const std::string &dir);
192  void DrawPolygonFilled(ocpnDC &pnt, ViewPort &vp, wxColor const &color);
193  void DrawPolygonFilledGL(ocpnDC &pnt, int *pvc, ViewPort &vp,
194  wxColor const &color, bool idl);
195  ShapeBaseChart &LowestQualityBaseMap();
196  ShapeBaseChart &HighestQualityBaseMap();
197 
198  bool _loaded;
199 
200  std::map<Quality, ShapeBaseChart> _basemap_map;
201 };
202 
203 #endif
latitude/longitude key for 1 degree cells
Set of basemaps at different resolutions.
Definition: ocpndc.h:58
Definition: Quilt.cpp:867