OpenCPN Partial API docs
Loading...
Searching...
No Matches
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) || \
41 (defined(__clang_major__) && (__clang_major__ < 15)))
42// MacOS 1.13
43#include <ghc/filesystem.hpp>
44namespace fs = ghc::filesystem;
45#else
46#include <filesystem>
47#include <utility>
48namespace fs = std::filesystem;
49#endif
50
52class LatLonKey {
53public:
54 LatLonKey(int lat, int lon) {
55 this->lat = lat;
56 this->lon = lon;
57 }
58 int lat;
59 int lon;
60
61 bool operator<(const LatLonKey &k) const {
62 if (this->lat < k.lat) {
63 return this->lon < k.lon;
64 }
65 return this->lat < k.lat;
66 }
67
68 bool operator==(const LatLonKey &other) const {
69 return (lat == other.lat && lon == other.lon);
70 }
71};
72
73template <>
74struct std::hash<LatLonKey> {
75 std::size_t operator()(const LatLonKey &k) const {
76 return 360 * k.lat + k.lon;
77 }
78};
79
81enum Quality {
83 crude,
85 low,
87 medium,
89 high,
92 full
93};
94
95typedef std::vector<wxRealPoint> contour;
96typedef std::vector<contour> contour_list;
97
104public:
105 ShapeBaseChart() = delete;
106 ShapeBaseChart(const std::string &filename, const size_t &min_scale,
107 const wxColor &color = *wxBLACK)
108 : _dmod(1),
109 _loading(false),
110 _is_usable(false),
111 _is_tiled(false),
112 _min_scale(min_scale),
113 _filename(filename),
114 _reader(nullptr),
115 _color(color) {
116 _is_usable = fs::exists(filename);
117 }
118
120 this->_filename = t._filename;
121 this->_is_usable = t._is_usable;
122 this->_is_tiled = t._is_tiled;
123 this->_min_scale = t._min_scale;
124 this->_reader = nullptr;
125 this->_color = t._color;
126 this->_dmod = t._dmod;
127 this->_loading = t._loading;
128 }
130 CancelLoading(); // Ensure async operation is done before cleanup.
131 delete _reader;
132 }
133
134 void SetColor(wxColor color) { _color = color; }
135
136 int _dmod;
137
138 bool LoadSHP();
139 bool IsUsable() { return _is_usable && !_loading; }
140 size_t MinScale() { return _min_scale; }
141 void RenderViewOnDC(ocpnDC &dc, ViewPort &vp) { DrawPolygonFilled(dc, vp); }
142 static const std::string ConstructPath(const std::string &dir,
143 const std::string &quality_suffix) {
144 return std::string(dir + fs::path::preferred_separator + "basemap_" +
145 quality_suffix + ".shp");
146 }
147
148 bool CrossesLand(double &lat1, double &lon1, double &lat2, double &lon2);
149
151 void CancelLoading();
152
153private:
154 std::future<bool> _loaded;
155 bool _loading;
156 bool _is_usable;
157 bool _is_tiled;
158 size_t _min_scale;
159 void DoDrawPolygonFilled(ocpnDC &pnt, ViewPort &vp,
160 const shp::Feature &feature);
161 void DoDrawPolygonFilledGL(ocpnDC &pnt, ViewPort &vp,
162 const shp::Feature &feature);
163 void DrawPolygonFilled(ocpnDC &pnt, ViewPort &vp);
164 void AddPointToTessList(shp::Point &point, ViewPort &vp, GLUtesselator *tobj,
165 bool idl);
166
167 std::string _filename;
168 shp::ShapefileReader *_reader;
169 std::unordered_map<LatLonKey, std::vector<size_t>> _tiles;
170 wxColor _color;
171
172 bool LineLineIntersect(const std::pair<double, double> &A,
173 const std::pair<double, double> &B,
174 const std::pair<double, double> &C,
175 const std::pair<double, double> &D);
176
177 bool PolygonLineIntersect(const shp::Feature &feature,
178 const std::pair<double, double> &A,
179 const std::pair<double, double> &B);
180};
181
188public:
190 ~ShapeBaseChartSet() { Cleanup(); }
191 static wxPoint2DDouble GetDoublePixFromLL(ViewPort &vp, double lat,
192 double lon);
193
194 void SetBasemapLandColor(wxColor color);
195 wxColor GetBasemapLandColor();
196
197 void RenderViewOnDC(ocpnDC &dc, ViewPort &vp);
198
199 ShapeBaseChart &SelectBaseMap(const size_t &scale);
200 bool IsUsable() {
201 return _basemap_map.size() > 0 && LowestQualityBaseMap().IsUsable();
202 }
203
204 bool CrossesLand(double lat1, double lon1, double lat2, double lon2) {
205 if (IsUsable()) {
206 return HighestQualityBaseMap().CrossesLand(lat1, lon1, lat2, lon2);
207 }
208 return false;
209 }
210
211 void Cleanup() {
212 for (auto &pair : _basemap_map) {
213 pair.second.CancelLoading();
214 }
215 _basemap_map.clear();
216 _loaded = false;
217 }
218 void Reset();
219
220private:
221 void LoadBasemaps(const std::string &dir);
222 void DrawPolygonFilled(ocpnDC &pnt, ViewPort &vp, wxColor const &color);
223 void DrawPolygonFilledGL(ocpnDC &pnt, int *pvc, ViewPort &vp,
224 wxColor const &color, bool idl);
225 ShapeBaseChart &LowestQualityBaseMap();
226 ShapeBaseChart &HighestQualityBaseMap();
227
228 bool _loaded;
229 wxColor land_color;
230
231 std::map<Quality, ShapeBaseChart> _basemap_map;
232};
233
234#endif
latitude/longitude key for 1 degree cells
Manages a set of ShapeBaseChart objects at different resolutions.
Represents a basemap chart based on shapefile data.
void CancelLoading()
Cancel the chart loading operation.
Represents the view port for chart display in OpenCPN.
Definition viewport.h:84
Device context class that can use either wxDC or OpenGL for drawing.
Definition ocpndc.h:64