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
197 // Set default (unity) auxiliary transform coefficients
198 x_rate = 1.0;
199 y_rate = 1.0;
200 x_origin = 0.0;
201 y_origin = 0.0;
202
203 auxParm0 = 0;
204 auxParm1 = 0;
205 auxParm2 = 0;
206 auxParm3 = 0;
207}
208
209//----------------------------------------------------------------------------------
210// S57Obj CTOR from FeatureName
211//----------------------------------------------------------------------------------
212S57Obj::S57Obj(const char *featureName) {
213 Init();
214
215 attVal = new wxArrayOfS57attVal();
216
217 strncpy(FeatureName, featureName, 6);
218 FeatureName[6] = 0;
219
220 if (!strncmp(FeatureName, "DEPARE", 6) || !strncmp(FeatureName, "DRGARE", 6))
221 bIsAssociable = true;
222}
223
224bool S57Obj::AddIntegerAttribute(const char *acronym, int val) {
225 S57attVal *pattValTmp = new S57attVal;
226
227 int *pAVI = (int *)malloc(sizeof(int)); // new int;
228 *pAVI = val;
229
230 pattValTmp->valType = OGR_INT;
231 pattValTmp->value = pAVI;
232
233 att_array = (char *)realloc(att_array, 6 * (n_attr + 1));
234 strncpy(att_array + (6 * sizeof(char) * n_attr), acronym, 6);
235 n_attr++;
236
237 attVal->Add(pattValTmp);
238
239 if (!strncmp(acronym, "SCAMIN", 6)) Scamin = val;
240
241 return true;
242}
243
244bool S57Obj::AddIntegerListAttribute(const char *acronym, int *pval,
245 int nValue) {
246 return true;
247}
248
249bool S57Obj::AddDoubleAttribute(const char *acronym, double val) {
250 S57attVal *pattValTmp = new S57attVal;
251
252 double *pAVI = (double *)malloc(sizeof(double)); // new double;
253 *pAVI = val;
254
255 pattValTmp->valType = OGR_REAL;
256 pattValTmp->value = pAVI;
257
258 att_array = (char *)realloc(att_array, 6 * (n_attr + 1));
259 strncpy(att_array + (6 * sizeof(char) * n_attr), acronym, 6);
260 n_attr++;
261
262 attVal->Add(pattValTmp);
263
264 return true;
265}
266
267bool S57Obj::AddDoubleListAttribute(const char *acronym, double *pval,
268 int nValue) {
269 return true;
270}
271
272bool S57Obj::AddStringAttribute(const char *acronym, char *val) {
273 S57attVal *pattValTmp = new S57attVal;
274
275 char *pAVS = (char *)malloc(strlen(val) + 1); // new string
276 strcpy(pAVS, val);
277
278 pattValTmp->valType = OGR_STR;
279 pattValTmp->value = pAVS;
280
281 att_array = (char *)realloc(att_array, 6 * (n_attr + 1));
282 strncpy(att_array + (6 * sizeof(char) * n_attr), acronym, 6);
283 n_attr++;
284
285 attVal->Add(pattValTmp);
286
287 return true;
288}
289
290bool S57Obj::SetPointGeometry(double lat, double lon, double ref_lat,
291 double ref_lon) {
292 Primitive_type = GEO_POINT;
293
294 m_lon = lon;
295 m_lat = lat;
296
297 // Set initial BoundingBox limits to 1 NM
298 double bound = 1. / 60.; // 1 NM, nominal
299 BBObj.Set(m_lat - bound, m_lon - bound, m_lat + bound, m_lon + bound);
300 bBBObj_valid = false;
301
302 // Calculate SM from chart common reference point
303 double easting, northing;
304 toSM(lat, lon, ref_lat, ref_lon, &easting, &northing);
305
306 x = easting;
307 y = northing;
308
309 npt = 1;
310
311 return true;
312}
313
314bool S57Obj::SetLineGeometry(LineGeometryDescriptor *pGeo, GeoPrim_t geoType,
315 double ref_lat, double ref_lon) {
316 Primitive_type = geoType;
317
318 // set s57obj bbox as lat/lon
319 BBObj.Set(pGeo->extent_s_lat, pGeo->extent_w_lon, pGeo->extent_n_lat,
320 pGeo->extent_e_lon);
321 bBBObj_valid = true;
322
323 // and declare x/y of the object to be average east/north of all points
324 double e1, e2, n1, n2;
325 toSM(pGeo->extent_n_lat, pGeo->extent_e_lon, ref_lat, ref_lon, &e1, &n1);
326 toSM(pGeo->extent_s_lat, pGeo->extent_w_lon, ref_lat, ref_lon, &e2, &n2);
327
328 x = (e1 + e2) / 2.;
329 y = (n1 + n2) / 2.;
330
331 // Set the object base point
332 double xll, yll;
333 fromSM(x, y, ref_lat, ref_lon, &yll, &xll);
334 m_lon = xll;
335 m_lat = yll;
336
337 // Set the edge and connected node table indices
338 m_n_lsindex = pGeo->indexCount;
339 m_lsindex_array = pGeo->indexTable;
340
341 m_n_edge_max_points =
342 0; // TODO this could be precalulated and added to next SENC format
343
344 return true;
345}
346
347bool S57Obj::SetAreaGeometry(PolyTessGeo *ppg, double ref_lat, double ref_lon) {
348 Primitive_type = GEO_AREA;
349 pPolyTessGeo = ppg;
350
351 // Set the s57obj bounding box as lat/lon
352 BBObj.Set(ppg->Get_ymin(), ppg->Get_xmin(), ppg->Get_ymax(), ppg->Get_xmax());
353 bBBObj_valid = true;
354
355 // and declare x/y of the object to be average east/north of all points
356 double e1, e2, n1, n2;
357 toSM(ppg->Get_ymax(), ppg->Get_xmax(), ref_lat, ref_lon, &e1, &n1);
358 toSM(ppg->Get_ymin(), ppg->Get_xmin(), ref_lat, ref_lon, &e2, &n2);
359
360 x = (e1 + e2) / 2.;
361 y = (n1 + n2) / 2.;
362
363 // Set the object base point
364 double xll, yll;
365 fromSM(x, y, ref_lat, ref_lon, &yll, &xll);
366 m_lon = xll;
367 m_lat = yll;
368
369 return true;
370}
371
372bool S57Obj::SetMultipointGeometry(MultipointGeometryDescriptor *pGeo,
373 double ref_lat, double ref_lon) {
374 Primitive_type = GEO_POINT;
375
376 npt = pGeo->pointCount;
377
378 geoPtz = (double *)malloc(npt * 3 * sizeof(double));
379 geoPtMulti = (double *)malloc(npt * 2 * sizeof(double));
380
381 double *pdd = geoPtz;
382 double *pdl = geoPtMulti;
383
384 float *pfs = (float *)(pGeo->pointTable); // start of point data
385 for (int ip = 0; ip < npt; ip++) {
386 float easting, northing;
387 easting = *pfs++;
388 northing = *pfs++;
389 float depth = *pfs++;
390
391 *pdd++ = easting;
392 *pdd++ = northing;
393 *pdd++ = depth;
394
395 // Convert point from SM to lat/lon for later use in decomposed bboxes
396 double xll, yll;
397 fromSM(easting, northing, ref_lat, ref_lon, &yll, &xll);
398
399 *pdl++ = xll;
400 *pdl++ = yll;
401 }
402
403 // set s57obj bbox as lat/lon
404 BBObj.Set(pGeo->extent_s_lat, pGeo->extent_w_lon, pGeo->extent_n_lat,
405 pGeo->extent_e_lon);
406 bBBObj_valid = true;
407
408 return true;
409}
410
411int S57Obj::GetAttributeIndex(const char *AttrSeek) {
412 char *patl = att_array;
413
414 for (int i = 0; i < n_attr; i++) {
415 if (!strncmp(patl, AttrSeek, 6)) {
416 return i;
417 break;
418 }
419
420 patl += 6;
421 }
422
423 return -1;
424}
425
426wxString S57Obj::GetAttrValueAsString(const char *AttrName) {
427 wxString str;
428
429 int idx = GetAttributeIndex(AttrName);
430
431 if (idx >= 0) {
432 // using idx to get the attribute value
433
434 S57attVal *v = attVal->Item(idx);
435
436 switch (v->valType) {
437 case OGR_STR: {
438 char *val = (char *)(v->value);
439 str.Append(wxString(val, wxConvUTF8));
440 break;
441 }
442 case OGR_REAL: {
443 double dval = *(double *)(v->value);
444 str.Printf("%g", dval);
445 break;
446 }
447 case OGR_INT: {
448 int ival = *((int *)v->value);
449 str.Printf("%d", ival);
450 break;
451 }
452 default: {
453 str.Printf("Unknown attribute type");
454 break;
455 }
456 }
457 }
458 return str;
459}
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.