OpenCPN Partial API docs
Loading...
Searching...
No Matches
shapefile_basemap.h
Go to the documentation of this file.
1/**************************************************************************
2 * Copyright (C) 2012-2023 by David S. Register *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, see <https://www.gnu.org/licenses/>. *
16 **************************************************************************/
17
23
24#ifndef SHAPEFILE_BASEMAP_H
25#define SHAPEFILE_BASEMAP_H
26
27#include <functional>
28#include <future>
29#include <map>
30#include <thread>
31#include <vector>
32
33#include "gl_headers.h"
34
35#include <wx/gdicmn.h>
36
37#include "ShapefileReader.hpp"
38#include "poly_math.h"
39#include "ocpndc.h"
40#include "std_filesystem.h"
41
42typedef std::vector<wxRealPoint> contour;
43typedef std::vector<contour> contour_list;
44
45class ShapeBaseChartSet; // forward
47
60class LatLonKey {
61public:
69 LatLonKey(int lat, int lon) {
70 this->lat = lat;
71 this->lon = lon;
72 }
73
78 int lat;
84 int lon;
85
86 bool operator<(const LatLonKey &k) const {
87 if (this->lat < k.lat) {
88 return this->lon < k.lon;
89 }
90 return this->lat < k.lat;
91 }
92
93 bool operator==(const LatLonKey &other) const {
94 return (lat == other.lat && lon == other.lon);
95 }
96};
97
98template <>
99struct std::hash<LatLonKey> {
100 std::size_t operator()(const LatLonKey &k) const {
101 return 360 * k.lat + k.lon;
102 }
103};
104
119
128class ShapeBaseChart {
129public:
130 ShapeBaseChart() = delete;
131 ShapeBaseChart(const std::string &filename, const size_t &min_scale,
132 const wxColor &color = *wxBLACK)
133 : _dmod(1),
134 _loading(false),
135 _is_usable(false),
136 _is_tiled(false),
137 _min_scale(min_scale),
138 _filename(filename),
139 _reader(nullptr),
140 _color(color) {
141 _is_usable = fs::exists(filename);
142 }
143
144 ShapeBaseChart(const ShapeBaseChart &t) {
145 this->_filename = t._filename;
146 this->_is_usable = t._is_usable;
147 this->_is_tiled = t._is_tiled;
148 this->_min_scale = t._min_scale;
149 this->_reader = nullptr;
150 this->_color = t._color;
151 this->_dmod = t._dmod;
152 this->_loading = t._loading;
153 }
154 ~ShapeBaseChart() {
155 CancelLoading(); // Ensure async operation is done before cleanup.
156 delete _reader;
157 }
158
159 void SetColor(wxColor color) { _color = color; }
160
167 int _dmod;
168
179 bool LoadSHP();
186 bool IsUsable() { return _is_usable && !_loading; }
187 size_t MinScale() { return _min_scale; }
188 void RenderViewOnDC(ocpnDC &dc, ViewPort &vp) { DrawPolygonFilled(dc, vp); }
189 static const std::string ConstructPath(const std::string &dir,
190 const std::string &quality_suffix) {
191 return std::string(dir +
192 static_cast<const char>(fs::path::preferred_separator) +
193 "basemap_" + quality_suffix + ".shp");
194 }
195
213 bool CrossesLand(double &lat1, double &lon1, double &lat2, double &lon2);
214
216 void CancelLoading();
217
218private:
219 std::future<bool> _loaded;
220 bool _loading;
221 bool _is_usable;
227 bool _is_tiled;
233 size_t _min_scale;
234 void DoDrawPolygonFilled(ocpnDC &pnt, ViewPort &vp,
235 const shp::Feature &feature);
236 void DoDrawPolygonFilledGL(ocpnDC &pnt, ViewPort &vp,
237 const shp::Feature &feature);
238 void DrawPolygonFilled(ocpnDC &pnt, ViewPort &vp);
239#ifdef ocpnUSE_GL
240 void AddPointToTessList(shp::Point &point, ViewPort &vp, GLUtesselator *tobj,
241 bool idl);
242#endif
243
248 std::string _filename;
255 shp::ShapefileReader *_reader;
262 std::unordered_map<LatLonKey, std::vector<size_t>> _tiles;
269 wxColor _color;
270
293 bool LineLineIntersect(const std::pair<double, double> &A,
294 const std::pair<double, double> &B,
295 const std::pair<double, double> &C,
296 const std::pair<double, double> &D);
297
316 bool PolygonLineIntersect(const shp::Feature &feature,
317 const std::pair<double, double> &A,
318 const std::pair<double, double> &B);
319};
320
326class ShapeBaseChartSet {
327public:
328 ShapeBaseChartSet();
329 ~ShapeBaseChartSet() { Cleanup(); }
330 static wxPoint2DDouble GetDoublePixFromLL(ViewPort &vp, double lat,
331 double lon);
332
333 void SetBasemapLandColor(wxColor color);
334 wxColor GetBasemapLandColor();
335
336 void RenderViewOnDC(ocpnDC &dc, ViewPort &vp);
337
338 ShapeBaseChart &SelectBaseMap(const size_t &scale);
344 bool IsUsable() {
345 return _basemap_map.size() > 0 && LowestQualityBaseMap().IsUsable();
346 }
347
359 bool CrossesLand(double lat1, double lon1, double lat2, double lon2) {
360 if (IsUsable()) {
361 return HighestQualityBaseMap().CrossesLand(lat1, lon1, lat2, lon2);
362 }
363 return false;
364 }
365
366 void Cleanup() {
367 for (auto &pair : _basemap_map) {
368 pair.second.CancelLoading();
369 }
370 _basemap_map.clear();
371 _loaded = false;
372 }
373 void Reset();
374
375private:
376 void LoadBasemaps(const std::string &dir);
377 void DrawPolygonFilled(ocpnDC &pnt, ViewPort &vp, wxColor const &color);
378 void DrawPolygonFilledGL(ocpnDC &pnt, int *pvc, ViewPort &vp,
379 wxColor const &color, bool idl);
387 ShapeBaseChart &LowestQualityBaseMap();
395 ShapeBaseChart &HighestQualityBaseMap();
396
397 bool _loaded;
403 wxColor land_color;
404
405 std::map<Quality, ShapeBaseChart> _basemap_map;
406};
407
409#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:56
Device context class that can use either wxDC or OpenGL for drawing.
Definition ocpndc.h:60
Platform independent GL includes.
Layer to use wxDC or opengl.
ShapeBaseChartSet gShapeBasemap
global instance
Quality
Basemap quality.
@ full
Full resolution of the OSM dataset.
@ low
Low resolution.
@ crude
Planetary scale dataset.
@ high
High resolution.
@ medium
Medium resolution.