OpenCPN Partial API docs
Loading...
Searching...
No Matches
s57featuredefns.cpp
1/******************************************************************************
2 *
3 * Project: S-57 Translator
4 * Purpose: Implements methods to create OGRFeatureDefns for various
5 * object classes, and primitive features.
6 * Author: Frank Warmerdam, warmerdam@pobox.com
7 *
8 ******************************************************************************
9 * Copyright (c) 1999, 2001, 2003 Frank Warmerdam
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included
19 * in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 * DEALINGS IN THE SOFTWARE.
28 ******************************************************************************
29 *
30 * $Log: s57featuredefns.cpp,v $
31 * Cleanup/optimize
32 *
33 * Revision 1.1.1.1 2006/08/21 05:52:20 dsr
34 * Initial import as opencpn, GNU Automake compliant.
35 *
36 * Revision 1.1.1.1 2006/04/19 03:23:28 dsr
37 * Rename/Import to OpenCPN
38 *
39 * Revision 1.2 2003/11/17 20:10:46 warmerda
40 * added support for writing FFPT linkages
41 *
42 * Revision 1.1 2003/11/12 21:24:41 warmerda
43 * New
44 *
45 */
46
47#include "s57.h"
48#include "gdal/ogr_api.h"
49#include "gdal/cpl_conv.h"
50#include "gdal/cpl_string.h"
51
52/************************************************************************/
53/* S57GenerateGeomFeatureDefn() */
54/************************************************************************/
55
56OGRFeatureDefn *S57GenerateGeomFeatureDefn(OGRwkbGeometryType eGType,
57 int nOptionFlags)
58
59{
60 OGRFeatureDefn *poFDefn = NULL;
61
62 if (eGType == wkbPoint) {
63 poFDefn = new OGRFeatureDefn("Point");
64 poFDefn->SetGeomType(eGType);
65 } else if (eGType == wkbLineString) {
66 poFDefn = new OGRFeatureDefn("Line");
67 poFDefn->SetGeomType(eGType);
68 } else if (eGType == wkbPolygon) {
69 poFDefn = new OGRFeatureDefn("Area");
70 poFDefn->SetGeomType(eGType);
71 } else if (eGType == wkbNone) {
72 poFDefn = new OGRFeatureDefn("Meta");
73 poFDefn->SetGeomType(eGType);
74 } else if (eGType == wkbUnknown) {
75 poFDefn = new OGRFeatureDefn("Generic");
76 poFDefn->SetGeomType(eGType);
77 } else
78 return NULL;
79
80 S57GenerateStandardAttributes(poFDefn, nOptionFlags);
81
82 return poFDefn;
83}
84
85/************************************************************************/
86/* S57GenerateVectorPrimitiveFeatureDefn() */
87/************************************************************************/
88
89OGRFeatureDefn *S57GenerateVectorPrimitiveFeatureDefn(int nRCNM,
90 int nOptionFlags)
91
92{
93 OGRFeatureDefn *poFDefn = NULL;
94
95 if (nRCNM == RCNM_VI) {
96 poFDefn = new OGRFeatureDefn(OGRN_VI);
97 poFDefn->SetGeomType(wkbPoint);
98 } else if (nRCNM == RCNM_VC) {
99 poFDefn = new OGRFeatureDefn(OGRN_VC);
100 poFDefn->SetGeomType(wkbPoint);
101 } else if (nRCNM == RCNM_VE) {
102 poFDefn = new OGRFeatureDefn(OGRN_VE);
103 poFDefn->SetGeomType(wkbLineString);
104 } else if (nRCNM == RCNM_VF) {
105 poFDefn = new OGRFeatureDefn(OGRN_VF);
106 poFDefn->SetGeomType(wkbPolygon);
107 } else
108 return NULL;
109
110 /* -------------------------------------------------------------------- */
111 /* Core vector primitive attributes */
112 /* -------------------------------------------------------------------- */
113 OGRFieldDefn oField("", OFTInteger);
114
115 oField.Set("RCNM", OFTInteger, 3, 0);
116 poFDefn->AddFieldDefn(&oField);
117
118 oField.Set("RCID", OFTInteger, 8, 0);
119 poFDefn->AddFieldDefn(&oField);
120
121 oField.Set("RVER", OFTInteger, 2, 0);
122 poFDefn->AddFieldDefn(&oField);
123
124 oField.Set("RUIN", OFTInteger, 2, 0);
125 poFDefn->AddFieldDefn(&oField);
126
127 /* -------------------------------------------------------------------- */
128 /* For lines we want to capture the point links for the first */
129 /* and last nodes. */
130 /* -------------------------------------------------------------------- */
131 if (nRCNM == RCNM_VE) {
132 oField.Set("NAME_RCNM_0", OFTInteger, 3, 0);
133 poFDefn->AddFieldDefn(&oField);
134
135 oField.Set("NAME_RCID_0", OFTInteger, 8, 0);
136 poFDefn->AddFieldDefn(&oField);
137
138 oField.Set("ORNT_0", OFTInteger, 3, 0);
139 poFDefn->AddFieldDefn(&oField);
140
141 oField.Set("USAG_0", OFTInteger, 3, 0);
142 poFDefn->AddFieldDefn(&oField);
143
144 oField.Set("TOPI_0", OFTInteger, 1, 0);
145 poFDefn->AddFieldDefn(&oField);
146
147 oField.Set("MASK_0", OFTInteger, 3, 0);
148 poFDefn->AddFieldDefn(&oField);
149
150 oField.Set("NAME_RCNM_1", OFTInteger, 3, 0);
151 poFDefn->AddFieldDefn(&oField);
152
153 oField.Set("NAME_RCID_1", OFTInteger, 8, 0);
154 poFDefn->AddFieldDefn(&oField);
155
156 oField.Set("ORNT_1", OFTInteger, 3, 0);
157 poFDefn->AddFieldDefn(&oField);
158
159 oField.Set("USAG_1", OFTInteger, 3, 0);
160 poFDefn->AddFieldDefn(&oField);
161
162 oField.Set("TOPI_1", OFTInteger, 1, 0);
163 poFDefn->AddFieldDefn(&oField);
164
165 oField.Set("MASK_1", OFTInteger, 3, 0);
166 poFDefn->AddFieldDefn(&oField);
167 }
168
169 return poFDefn;
170}
171
172/************************************************************************/
173/* S57GenerateObjectClassDefn() */
174/************************************************************************/
175
176OGRFeatureDefn *S57GenerateObjectClassDefn(S57ClassRegistrar *poCR, int nOBJL,
177 int nOptionFlags)
178
179{
180 OGRFeatureDefn *poFDefn = NULL;
181 char **papszGeomPrim;
182
183 if (!poCR->SelectClass(nOBJL)) return NULL;
184
185 /* -------------------------------------------------------------------- */
186 /* Create the feature definition based on the object class */
187 /* acronym. */
188 /* -------------------------------------------------------------------- */
189 poFDefn = new OGRFeatureDefn(poCR->GetAcronym());
190
191 /* -------------------------------------------------------------------- */
192 /* Set the nOBJL Class Code as a convenience */
193 /* -------------------------------------------------------------------- */
194 poFDefn->SetOBJL(nOBJL);
195
196 /* -------------------------------------------------------------------- */
197 /* Try and establish the geometry type. If more than one */
198 /* geometry type is allowed we just fall back to wkbUnknown. */
199 /* -------------------------------------------------------------------- */
200 papszGeomPrim = poCR->GetPrimitives();
201 if (CSLCount(papszGeomPrim) == 0) {
202 poFDefn->SetGeomType(wkbNone);
203 } else if (CSLCount(papszGeomPrim) > 1) {
204 // leave as unknown geometry type.
205 } else if (EQUAL(papszGeomPrim[0], "Point")) {
206 if (EQUAL(poCR->GetAcronym(), "SOUNDG")) {
207 if (nOptionFlags & S57M_SPLIT_MULTIPOINT)
208 poFDefn->SetGeomType(wkbPoint25D);
209 else
210 poFDefn->SetGeomType(wkbMultiPoint);
211 } else
212 poFDefn->SetGeomType(wkbPoint);
213 } else if (EQUAL(papszGeomPrim[0], "Area")) {
214 poFDefn->SetGeomType(wkbPolygon);
215 } else if (EQUAL(papszGeomPrim[0], "Line")) {
216 poFDefn->SetGeomType(wkbLineString);
217 }
218
219 /* -------------------------------------------------------------------- */
220 /* Add the standard attributes. */
221 /* -------------------------------------------------------------------- */
222 S57GenerateStandardAttributes(poFDefn, nOptionFlags);
223
224 /* -------------------------------------------------------------------- */
225 /* Add the attributes specific to this object class. */
226 /* -------------------------------------------------------------------- */
227 char **papszAttrList = poCR->GetAttributeList();
228
229 for (int iAttr = 0; papszAttrList != NULL && papszAttrList[iAttr] != NULL;
230 iAttr++) {
231 int iAttrIndex = poCR->FindAttrByAcronym(papszAttrList[iAttr]);
232
233 if (iAttrIndex == -1) {
234 CPLDebug("S57", "Can't find attribute %s from class %s:%s.\n",
235 papszAttrList[iAttr], poCR->GetAcronym(),
236 poCR->GetDescription());
237 continue;
238 }
239
240 OGRFieldDefn oField(papszAttrList[iAttr], OFTInteger);
241
242 switch (poCR->GetAttrType(iAttrIndex)) {
243 case SAT_ENUM:
244 case SAT_INT:
245 oField.SetType(OFTInteger);
246 break;
247
248 case SAT_FLOAT:
249 oField.SetType(OFTReal);
250 break;
251
252 case SAT_CODE_STRING:
253 case SAT_FREE_TEXT:
254 oField.SetType(OFTString);
255 break;
256
257 case SAT_LIST:
258 oField.SetType(OFTString);
259 break;
260 }
261
262 poFDefn->AddFieldDefn(&oField);
263 }
264
265 /* -------------------------------------------------------------------- */
266 /* Do we need to add DEPTH attributes to soundings? */
267 /* -------------------------------------------------------------------- */
268 if (EQUAL(poCR->GetAcronym(), "SOUNDG") &&
269 (nOptionFlags & S57M_ADD_SOUNDG_DEPTH)) {
270 OGRFieldDefn oField("DEPTH", OFTReal);
271 poFDefn->AddFieldDefn(&oField);
272 }
273
274 return poFDefn;
275}
276
277/************************************************************************/
278/* S57GenerateStandardAttributes() */
279/* */
280/* Attach standard feature attributes to a feature definition. */
281/************************************************************************/
282
283void S57GenerateStandardAttributes(OGRFeatureDefn *poFDefn, int nOptionFlags)
284
285{
286 OGRFieldDefn oField("", OFTInteger);
287
288 /* -------------------------------------------------------------------- */
289 /* RCID */
290 /* -------------------------------------------------------------------- */
291 oField.Set("RCID", OFTInteger, 10, 0);
292 poFDefn->AddFieldDefn(&oField);
293
294 /* -------------------------------------------------------------------- */
295 /* PRIM */
296 /* -------------------------------------------------------------------- */
297 oField.Set("PRIM", OFTInteger, 3, 0);
298 poFDefn->AddFieldDefn(&oField);
299
300 /* -------------------------------------------------------------------- */
301 /* GRUP */
302 /* -------------------------------------------------------------------- */
303 oField.Set("GRUP", OFTInteger, 3, 0);
304 poFDefn->AddFieldDefn(&oField);
305
306 /* -------------------------------------------------------------------- */
307 /* OBJL */
308 /* -------------------------------------------------------------------- */
309 oField.Set("OBJL", OFTInteger, 5, 0);
310 poFDefn->AddFieldDefn(&oField);
311
312 /* -------------------------------------------------------------------- */
313 /* RVER */
314 /* -------------------------------------------------------------------- */
315 oField.Set("RVER", OFTInteger, 3, 0);
316 poFDefn->AddFieldDefn(&oField);
317
318 /* -------------------------------------------------------------------- */
319 /* AGEN */
320 /* -------------------------------------------------------------------- */
321 oField.Set("AGEN", OFTInteger, 5, 0);
322 poFDefn->AddFieldDefn(&oField);
323
324 /* -------------------------------------------------------------------- */
325 /* FIDN */
326 /* -------------------------------------------------------------------- */
327 oField.Set("FIDN", OFTInteger, 10, 0);
328 poFDefn->AddFieldDefn(&oField);
329
330 /* -------------------------------------------------------------------- */
331 /* FIDS */
332 /* -------------------------------------------------------------------- */
333 oField.Set("FIDS", OFTInteger, 5, 0);
334 poFDefn->AddFieldDefn(&oField);
335
336 /* -------------------------------------------------------------------- */
337 /* LNAM - only generated when LNAM strings are being used. */
338 /* -------------------------------------------------------------------- */
339 if (nOptionFlags & S57M_LNAM_REFS) {
340 oField.Set("LNAM", OFTString, 16, 0);
341 poFDefn->AddFieldDefn(&oField);
342
343 oField.Set("LNAM_REFS", OFTStringList, 16, 0);
344 poFDefn->AddFieldDefn(&oField);
345
346 oField.Set("FFPT_RIND", OFTIntegerList, 1, 0);
347 poFDefn->AddFieldDefn(&oField);
348
349 // We should likely include FFPT_COMT here.
350 }
351
352 /* -------------------------------------------------------------------- */
353 /* Values from FSPT field. */
354 /* -------------------------------------------------------------------- */
355 if (nOptionFlags & S57M_RETURN_LINKAGES) {
356 oField.Set("NAME_RCNM", OFTIntegerList, 3, 0);
357 poFDefn->AddFieldDefn(&oField);
358
359 oField.Set("NAME_RCID", OFTIntegerList, 10, 0);
360 poFDefn->AddFieldDefn(&oField);
361
362 oField.Set("ORNT", OFTIntegerList, 1, 0);
363 poFDefn->AddFieldDefn(&oField);
364
365 oField.Set("USAG", OFTIntegerList, 1, 0);
366 poFDefn->AddFieldDefn(&oField);
367
368 oField.Set("MASK", OFTIntegerList, 3, 0);
369 poFDefn->AddFieldDefn(&oField);
370 }
371}