OpenCPN Partial API docs
Loading...
Searching...
No Matches
s57obj.cpp
Go to the documentation of this file.
1/**************************************************************************
2 * Copyright (C) 2010 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
24#ifndef WX_PRECOMP
25#include "wx/wx.h"
26#endif // precompiled headers
27
28#include "wx/image.h" // for some reason, needed for msvc???
29#include "wx/tokenzr.h"
30#include <wx/textfile.h>
31
32#include "dychart.h"
33#include "ocpn_platform.h"
34
35#include "s52s57.h"
36#include "s52plib.h"
37
38#include "s57chart.h"
39
40#include "mygeom.h"
41#include "model/cutil.h"
42#include "model/georef.h"
43#include "navutil.h" // for LogMessageOnce
44#include "ocpn_pixel.h"
45#include "ocpndc.h"
46#include "s52utils.h"
47
48#include "gdal/cpl_csv.h"
49#include "setjmp.h"
50
51#include "ogr_s57.h"
52
53#include "pluginmanager.h" // for S57 lights overlay
54
55#include "o_senc.h"
56
57#ifdef __VISUALC__
58#include <wx/msw/msvcrt.h>
59#endif
60
61#ifdef ocpnUSE_GL
62#include "gl_chart_canvas.h"
63#endif
64
65#include <algorithm> // for std::sort
66#include <map>
67
68#ifdef __MSVC__
69#define strncasecmp(x, y, z) _strnicmp(x, y, z)
70#endif
71
72#ifdef __VISUALC__
73#include <wx/msw/msvcrt.h>
74#endif
75
76// For compilers that support precompilation, includes "wx.h".
77#include <wx/wxprec.h>
78
79#ifndef WX_PRECOMP
80#include <wx/wx.h>
81#endif
82
83#include <wx/image.h> // for some reason, needed for msvc???
84#include <wx/textfile.h>
85#include <wx/string.h>
86#include <wx/tokenzr.h>
87
88#include "gdal/cpl_csv.h"
89
90#include "model/cutil.h"
91#include "model/georef.h"
92#include "model/gui_vars.h"
93
94#include "dychart.h"
95#include "mygeom.h"
96#include "navutil.h" // for LogMessageOnce
97#include "ocpndc.h"
98#include "ocpn_pixel.h"
99#include "ocpn_platform.h"
100#include "ogr_s57.h"
101#include "o_senc.h"
102#include "pluginmanager.h" // for S57 lights overlay
103#include "s52plib.h"
104#include "s52s57.h"
105#include "s52utils.h"
106#include "s57chart.h"
107
108#ifdef ocpnUSE_GL
109#include "gl_chart_canvas.h"
110#endif
111
112//----------------------------------------------------------------------------------
113// S57Obj CTOR
114//----------------------------------------------------------------------------------
115
116S57Obj::S57Obj() { Init(); }
117
118//----------------------------------------------------------------------------------
119// S57Obj DTOR
120//----------------------------------------------------------------------------------
121
122S57Obj::~S57Obj() {
123 // Don't delete any allocated records of simple copy clones
124 if (!bIsClone) {
125 if (attVal) {
126 for (unsigned int iv = 0; iv < attVal->GetCount(); iv++) {
127 S57attVal *vv = attVal->Item(iv);
128 void *v2 = vv->value;
129 free(v2);
130 delete vv;
131 }
132 delete attVal;
133 }
134 free(att_array);
135
136 if (pPolyTessGeo) {
137#ifdef ocpnUSE_GL
138 bool b_useVBO = g_b_EnableVBO && !auxParm1; // VBO allowed?
139
140 PolyTriGroup *ppg_vbo = pPolyTessGeo->Get_PolyTriGroup_head();
141 if (b_useVBO && ppg_vbo && auxParm0 > 0 && ppg_vbo->single_buffer) {
142 glDeleteBuffers(1, (GLuint *)&auxParm0);
143 }
144#endif
145 delete pPolyTessGeo;
146 }
147
148 if (FText) delete FText;
149
150 if (geoPt) free(geoPt);
151 if (geoPtz) free(geoPtz);
152 if (geoPtMulti) free(geoPtMulti);
153
154 if (m_lsindex_array) free(m_lsindex_array);
155
156 if (m_ls_list) {
157 line_segment_element *element = m_ls_list;
158 while (element) {
159 line_segment_element *next = element->next;
160 delete element;
161 element = next;
162 }
163 }
164 }
165}
166
167void S57Obj::Init() {
168 att_array = NULL;
169 attVal = NULL;
170 n_attr = 0;
171
172 pPolyTessGeo = NULL;
173
174 bCS_Added = 0;
175 CSrules = NULL;
176 FText = NULL;
177 bFText_Added = 0;
178 geoPtMulti = NULL;
179 geoPtz = NULL;
180 geoPt = NULL;
181 bIsClone = false;
182 Scamin = 1e8 + 2; // Default is very large number, effectively unused.
183 SuperScamin = -1;
184 nRef = 0;
185
186 bIsAton = false;
187 bIsAssociable = false;
188 m_n_lsindex = 0;
189 m_lsindex_array = NULL;
190 m_n_edge_max_points = 0;
191 m_ls_list = 0;
192 m_ls_list_legacy = 0;
193
194 iOBJL = -1; // deferred, done by OBJL filtering in the PLIB as needed
195 bBBObj_valid = false;
196 bOK_to_Render = true;
197
198 // Set default (unity) auxiliary transform coefficients
199 x_rate = 1.0;
200 y_rate = 1.0;
201 x_origin = 0.0;
202 y_origin = 0.0;
203
204 auxParm0 = 0;
205 auxParm1 = 0;
206 auxParm2 = 0;
207 auxParm3 = 0;
208}
209
210//----------------------------------------------------------------------------------
211// S57Obj CTOR from FeatureName
212//----------------------------------------------------------------------------------
213S57Obj::S57Obj(const char *featureName) {
214 Init();
215
216 attVal = new wxArrayOfS57attVal();
217
218 strncpy(FeatureName, featureName, 6);
219 FeatureName[6] = 0;
220
221 if (!strncmp(FeatureName, "DEPARE", 6) || !strncmp(FeatureName, "DRGARE", 6))
222 bIsAssociable = true;
223}
224
225bool S57Obj::AddIntegerAttribute(const char *acronym, int val) {
226 S57attVal *pattValTmp = new S57attVal;
227
228 int *pAVI = (int *)malloc(sizeof(int)); // new int;
229 *pAVI = val;
230
231 pattValTmp->valType = OGR_INT;
232 pattValTmp->value = pAVI;
233
234 att_array = (char *)realloc(att_array, 6 * (n_attr + 1));
235 strncpy(att_array + (6 * sizeof(char) * n_attr), acronym, 6);
236 n_attr++;
237
238 attVal->Add(pattValTmp);
239
240 if (!strncmp(acronym, "SCAMIN", 6)) Scamin = val;
241
242 return true;
243}
244
245bool S57Obj::AddIntegerListAttribute(const char *acronym, int *pval,
246 int nValue) {
247 return true;
248}
249
250bool S57Obj::AddDoubleAttribute(const char *acronym, double val) {
251 S57attVal *pattValTmp = new S57attVal;
252
253 double *pAVI = (double *)malloc(sizeof(double)); // new double;
254 *pAVI = val;
255
256 pattValTmp->valType = OGR_REAL;
257 pattValTmp->value = pAVI;
258
259 att_array = (char *)realloc(att_array, 6 * (n_attr + 1));
260 strncpy(att_array + (6 * sizeof(char) * n_attr), acronym, 6);
261 n_attr++;
262
263 attVal->Add(pattValTmp);
264
265 return true;
266}
267
268bool S57Obj::AddDoubleListAttribute(const char *acronym, double *pval,
269 int nValue) {
270 return true;
271}
272
273bool S57Obj::AddStringAttribute(const char *acronym, char *val) {
274 S57attVal *pattValTmp = new S57attVal;
275
276 char *pAVS = (char *)malloc(strlen(val) + 1); // new string
277 strcpy(pAVS, val);
278
279 pattValTmp->valType = OGR_STR;
280 pattValTmp->value = pAVS;
281
282 att_array = (char *)realloc(att_array, 6 * (n_attr + 1));
283 strncpy(att_array + (6 * sizeof(char) * n_attr), acronym, 6);
284 n_attr++;
285
286 attVal->Add(pattValTmp);
287
288 return true;
289}
290
291bool S57Obj::SetPointGeometry(double lat, double lon, double ref_lat,
292 double ref_lon) {
293 Primitive_type = GEO_POINT;
294
295 m_lon = lon;
296 m_lat = lat;
297
298 // Set initial BoundingBox limits to 1 NM
299 double bound = 1. / 60.; // 1 NM, nominal
300 BBObj.Set(m_lat - bound, m_lon - bound, m_lat + bound, m_lon + bound);
301 bBBObj_valid = false;
302
303 // Calculate SM from chart common reference point
304 double easting, northing;
305 toSM(lat, lon, ref_lat, ref_lon, &easting, &northing);
306
307 x = easting;
308 y = northing;
309
310 npt = 1;
311
312 return true;
313}
314
315bool S57Obj::SetLineGeometry(LineGeometryDescriptor *pGeo, GeoPrim_t geoType,
316 double ref_lat, double ref_lon) {
317 Primitive_type = geoType;
318
319 // set s57obj bbox as lat/lon
320 BBObj.Set(pGeo->extent_s_lat, pGeo->extent_w_lon, pGeo->extent_n_lat,
321 pGeo->extent_e_lon);
322 bBBObj_valid = true;
323
324 // and declare x/y of the object to be average east/north of all points
325 double e1, e2, n1, n2;
326 toSM(pGeo->extent_n_lat, pGeo->extent_e_lon, ref_lat, ref_lon, &e1, &n1);
327 toSM(pGeo->extent_s_lat, pGeo->extent_w_lon, ref_lat, ref_lon, &e2, &n2);
328
329 x = (e1 + e2) / 2.;
330 y = (n1 + n2) / 2.;
331
332 // Set the object base point
333 double xll, yll;
334 fromSM(x, y, ref_lat, ref_lon, &yll, &xll);
335 m_lon = xll;
336 m_lat = yll;
337
338 // Set the edge and connected node table indices
339 m_n_lsindex = pGeo->indexCount;
340 m_lsindex_array = pGeo->indexTable;
341
342 m_n_edge_max_points =
343 0; // TODO this could be precalulated and added to next SENC format
344
345 return true;
346}
347
348bool S57Obj::SetAreaGeometry(PolyTessGeo *ppg, double ref_lat, double ref_lon) {
349 Primitive_type = GEO_AREA;
350 pPolyTessGeo = ppg;
351
352 // Set the s57obj bounding box as lat/lon
353 BBObj.Set(ppg->Get_ymin(), ppg->Get_xmin(), ppg->Get_ymax(), ppg->Get_xmax());
354 bBBObj_valid = true;
355
356 // and declare x/y of the object to be average east/north of all points
357 double e1, e2, n1, n2;
358 toSM(ppg->Get_ymax(), ppg->Get_xmax(), ref_lat, ref_lon, &e1, &n1);
359 toSM(ppg->Get_ymin(), ppg->Get_xmin(), ref_lat, ref_lon, &e2, &n2);
360
361 x = (e1 + e2) / 2.;
362 y = (n1 + n2) / 2.;
363
364 // Set the object base point
365 double xll, yll;
366 fromSM(x, y, ref_lat, ref_lon, &yll, &xll);
367 m_lon = xll;
368 m_lat = yll;
369
370 return true;
371}
372
373bool S57Obj::SetMultipointGeometry(MultipointGeometryDescriptor *pGeo,
374 double ref_lat, double ref_lon) {
375 Primitive_type = GEO_POINT;
376
377 npt = pGeo->pointCount;
378
379 geoPtz = (double *)malloc(npt * 3 * sizeof(double));
380 geoPtMulti = (double *)malloc(npt * 2 * sizeof(double));
381
382 double *pdd = geoPtz;
383 double *pdl = geoPtMulti;
384
385 float *pfs = (float *)(pGeo->pointTable); // start of point data
386 for (int ip = 0; ip < npt; ip++) {
387 float easting, northing;
388 easting = *pfs++;
389 northing = *pfs++;
390 float depth = *pfs++;
391
392 *pdd++ = easting;
393 *pdd++ = northing;
394 *pdd++ = depth;
395
396 // Convert point from SM to lat/lon for later use in decomposed bboxes
397 double xll, yll;
398 fromSM(easting, northing, ref_lat, ref_lon, &yll, &xll);
399
400 *pdl++ = xll;
401 *pdl++ = yll;
402 }
403
404 // set s57obj bbox as lat/lon
405 BBObj.Set(pGeo->extent_s_lat, pGeo->extent_w_lon, pGeo->extent_n_lat,
406 pGeo->extent_e_lon);
407 bBBObj_valid = true;
408
409 return true;
410}
411
412int S57Obj::GetAttributeIndex(const char *AttrSeek) {
413 char *patl = att_array;
414
415 for (int i = 0; i < n_attr; i++) {
416 if (!strncmp(patl, AttrSeek, 6)) {
417 return i;
418 break;
419 }
420
421 patl += 6;
422 }
423
424 return -1;
425}
426
427wxString S57Obj::GetAttrValueAsString(const char *AttrName) {
428 wxString str;
429
430 int idx = GetAttributeIndex(AttrName);
431
432 if (idx >= 0) {
433 // using idx to get the attribute value
434
435 S57attVal *v = attVal->Item(idx);
436
437 switch (v->valType) {
438 case OGR_STR: {
439 char *val = (char *)(v->value);
440 str.Append(wxString(val, wxConvUTF8));
441 break;
442 }
443 case OGR_REAL: {
444 double dval = *(double *)(v->value);
445 str.Printf("%g", dval);
446 break;
447 }
448 case OGR_INT: {
449 int ival = *((int *)v->value);
450 str.Printf("%d", ival);
451 break;
452 }
453 default: {
454 str.Printf("Unknown attribute type");
455 break;
456 }
457 }
458 }
459 return str;
460}
Extern C linked utilities.
OpenCPN Georef utility.
OpenGL chart rendering canvas.
Miscellaneous globals primarely used by gui layer, not persisted in configuration file.
Utility functions.
S57 SENC File Object.
Optimized wxBitmap Object.
OpenCPN Platform specific support utilities.
Layer to use wxDC or opengl.
PlugInManager and helper classes – Mostly gui parts (dialogs) and plugin API stuff.
S57 Chart Object.