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
51class ShapeBaseChartSet; // forward
52extern ShapeBaseChartSet gShapeBasemap;
53
66class LatLonKey {
67public:
75 LatLonKey(int lat, int lon) {
76 this->lat = lat;
77 this->lon = lon;
78 }
84 int lat;
90 int lon;
91
92 bool operator<(const LatLonKey &k) const {
93 if (this->lat < k.lat) {
94 return this->lon < k.lon;
95 }
96 return this->lat < k.lat;
97 }
98
99 bool operator==(const LatLonKey &other) const {
100 return (lat == other.lat && lon == other.lon);
101 }
102};
103
104template <>
105struct std::hash<LatLonKey> {
106 std::size_t operator()(const LatLonKey &k) const {
107 return 360 * k.lat + k.lon;
108 }
109};
110
112enum Quality {
114 crude,
116 low,
118 medium,
120 high,
123 full
124};
125
126typedef std::vector<wxRealPoint> contour;
127typedef std::vector<contour> contour_list;
128
138public:
139 ShapeBaseChart() = delete;
140 ShapeBaseChart(const std::string &filename, const size_t &min_scale,
141 const wxColor &color = *wxBLACK)
142 : _dmod(1),
143 _loading(false),
144 _is_usable(false),
145 _is_tiled(false),
146 _min_scale(min_scale),
147 _filename(filename),
148 _reader(nullptr),
149 _color(color) {
150 _is_usable = fs::exists(filename);
151 }
152
154 this->_filename = t._filename;
155 this->_is_usable = t._is_usable;
156 this->_is_tiled = t._is_tiled;
157 this->_min_scale = t._min_scale;
158 this->_reader = nullptr;
159 this->_color = t._color;
160 this->_dmod = t._dmod;
161 this->_loading = t._loading;
162 }
164 CancelLoading(); // Ensure async operation is done before cleanup.
165 delete _reader;
166 }
167
168 void SetColor(wxColor color) { _color = color; }
169
176 int _dmod;
177
188 bool LoadSHP();
195 bool IsUsable() { return _is_usable && !_loading; }
196 size_t MinScale() { return _min_scale; }
197 void RenderViewOnDC(ocpnDC &dc, ViewPort &vp) { DrawPolygonFilled(dc, vp); }
198 static const std::string ConstructPath(const std::string &dir,
199 const std::string &quality_suffix) {
200 return std::string(dir + fs::path::preferred_separator + "basemap_" +
201 quality_suffix + ".shp");
202 }
203
221 bool CrossesLand(double &lat1, double &lon1, double &lat2, double &lon2);
222
224 void CancelLoading();
225
226private:
227 std::future<bool> _loaded;
228 bool _loading;
229 bool _is_usable;
235 bool _is_tiled;
241 size_t _min_scale;
242 void DoDrawPolygonFilled(ocpnDC &pnt, ViewPort &vp,
243 const shp::Feature &feature);
244 void DoDrawPolygonFilledGL(ocpnDC &pnt, ViewPort &vp,
245 const shp::Feature &feature);
246 void DrawPolygonFilled(ocpnDC &pnt, ViewPort &vp);
247 void AddPointToTessList(shp::Point &point, ViewPort &vp, GLUtesselator *tobj,
248 bool idl);
249
254 std::string _filename;
261 shp::ShapefileReader *_reader;
268 std::unordered_map<LatLonKey, std::vector<size_t>> _tiles;
275 wxColor _color;
276
299 bool LineLineIntersect(const std::pair<double, double> &A,
300 const std::pair<double, double> &B,
301 const std::pair<double, double> &C,
302 const std::pair<double, double> &D);
303
322 bool PolygonLineIntersect(const shp::Feature &feature,
323 const std::pair<double, double> &A,
324 const std::pair<double, double> &B);
325};
326
333public:
335 ~ShapeBaseChartSet() { Cleanup(); }
336 static wxPoint2DDouble GetDoublePixFromLL(ViewPort &vp, double lat,
337 double lon);
338
339 void SetBasemapLandColor(wxColor color);
340 wxColor GetBasemapLandColor();
341
342 void RenderViewOnDC(ocpnDC &dc, ViewPort &vp);
343
344 ShapeBaseChart &SelectBaseMap(const size_t &scale);
350 bool IsUsable() {
351 return _basemap_map.size() > 0 && LowestQualityBaseMap().IsUsable();
352 }
353
365 bool CrossesLand(double lat1, double lon1, double lat2, double lon2) {
366 if (IsUsable()) {
367 return HighestQualityBaseMap().CrossesLand(lat1, lon1, lat2, lon2);
368 }
369 return false;
370 }
371
372 void Cleanup() {
373 for (auto &pair : _basemap_map) {
374 pair.second.CancelLoading();
375 }
376 _basemap_map.clear();
377 _loaded = false;
378 }
379 void Reset();
380
381private:
382 void LoadBasemaps(const std::string &dir);
383 void DrawPolygonFilled(ocpnDC &pnt, ViewPort &vp, wxColor const &color);
384 void DrawPolygonFilledGL(ocpnDC &pnt, int *pvc, ViewPort &vp,
385 wxColor const &color, bool idl);
393 ShapeBaseChart &LowestQualityBaseMap();
401 ShapeBaseChart &HighestQualityBaseMap();
402
403 bool _loaded;
409 wxColor land_color;
410
411 std::map<Quality, ShapeBaseChart> _basemap_map;
412};
413
414extern ShapeBaseChartSet gShapeBasemap;
415#endif
A latitude/longitude key for 1x1 or 10x10 degree grid tiles.
int lat
Integer latitude value representing the northern (top) boundary of a latitude band.
LatLonKey(int lat, int lon)
Constructor for creating a LatLonKey.
int lon
Integer longitude value representing the western (left) boundary of a longitude band.
Manages a set of ShapeBaseChart objects at different resolutions.
bool CrossesLand(double lat1, double lon1, double lat2, double lon2)
Determines if a line segment between two geographical points crosses any land mass.
bool IsUsable()
Checks if the chart set contains at least one usable chart.
Represents a basemap chart based on shapefile data.
bool CrossesLand(double &lat1, double &lon1, double &lat2, double &lon2)
Determines if a line segment between two geographical points intersects any land mass represented in ...
void CancelLoading()
Cancel the chart loading operation.
int _dmod
Tile size in degrees.
bool LoadSHP()
Loads the shapefile data into memory.
bool IsUsable()
Determines if the chart is ready to be used for rendering or spatial queries.
ViewPort - Core geographic projection and coordinate transformation engine.
Definition viewport.h:84
Device context class that can use either wxDC or OpenGL for drawing.
Definition ocpndc.h:60