1 : /******************************************************************************
2 : * $Id: s57featuredefns.cpp 13460 2007-12-30 14:02:04Z warmerdam $
3 : *
4 : * Project: S-57 Translator
5 : * Purpose: Implements methods to create OGRFeatureDefns for various
6 : * object classes, and primitive features.
7 : * Author: Frank Warmerdam, warmerdam@pobox.com
8 : *
9 : ******************************************************************************
10 : * Copyright (c) 1999, 2001, 2003 Frank Warmerdam
11 : *
12 : * Permission is hereby granted, free of charge, to any person obtaining a
13 : * copy of this software and associated documentation files (the "Software"),
14 : * to deal in the Software without restriction, including without limitation
15 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 : * and/or sell copies of the Software, and to permit persons to whom the
17 : * Software is furnished to do so, subject to the following conditions:
18 : *
19 : * The above copyright notice and this permission notice shall be included
20 : * in all copies or substantial portions of the Software.
21 : *
22 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 : * DEALINGS IN THE SOFTWARE.
29 : ****************************************************************************/
30 :
31 : #include "s57.h"
32 : #include "ogr_api.h"
33 : #include "cpl_conv.h"
34 : #include "cpl_string.h"
35 :
36 : CPL_CVSID("$Id: s57featuredefns.cpp 13460 2007-12-30 14:02:04Z warmerdam $");
37 :
38 :
39 : /************************************************************************/
40 : /* S57GenerateGeomFeatureDefn() */
41 : /************************************************************************/
42 :
43 2 : OGRFeatureDefn *S57GenerateDSIDFeatureDefn()
44 :
45 : {
46 2 : OGRFeatureDefn *poFDefn = new OGRFeatureDefn( "DSID" );
47 2 : OGRFieldDefn oField( "", OFTInteger );
48 :
49 2 : poFDefn->SetGeomType( wkbNone );
50 2 : poFDefn->Reference();
51 :
52 : /* -------------------------------------------------------------------- */
53 : /* DSID fields. */
54 : /* -------------------------------------------------------------------- */
55 2 : oField.Set( "DSID_EXPP", OFTInteger, 3, 0 );
56 2 : poFDefn->AddFieldDefn( &oField );
57 :
58 2 : oField.Set( "DSID_INTU", OFTInteger, 3, 0 );
59 2 : poFDefn->AddFieldDefn( &oField );
60 :
61 2 : oField.Set( "DSID_DSNM", OFTString, 0, 0 );
62 2 : poFDefn->AddFieldDefn( &oField );
63 :
64 2 : oField.Set( "DSID_EDTN", OFTString, 0, 0 );
65 2 : poFDefn->AddFieldDefn( &oField );
66 :
67 2 : oField.Set( "DSID_UPDN", OFTString, 0, 0 );
68 2 : poFDefn->AddFieldDefn( &oField );
69 :
70 2 : oField.Set( "DSID_UADT", OFTString, 8, 0 );
71 2 : poFDefn->AddFieldDefn( &oField );
72 :
73 2 : oField.Set( "DSID_ISDT", OFTString, 8, 0 );
74 2 : poFDefn->AddFieldDefn( &oField );
75 :
76 2 : oField.Set( "DSID_STED", OFTReal, 11, 6 );
77 2 : poFDefn->AddFieldDefn( &oField );
78 :
79 2 : oField.Set( "DSID_PRSP", OFTInteger, 3, 0 );
80 2 : poFDefn->AddFieldDefn( &oField );
81 :
82 2 : oField.Set( "DSID_PSDN", OFTString, 0, 0 );
83 2 : poFDefn->AddFieldDefn( &oField );
84 :
85 2 : oField.Set( "DSID_PRED", OFTString, 0, 0 );
86 2 : poFDefn->AddFieldDefn( &oField );
87 :
88 2 : oField.Set( "DSID_PROF", OFTInteger, 3, 0 );
89 2 : poFDefn->AddFieldDefn( &oField );
90 :
91 2 : oField.Set( "DSID_AGEN", OFTInteger, 5, 0 );
92 2 : poFDefn->AddFieldDefn( &oField );
93 :
94 2 : oField.Set( "DSID_COMT", OFTString, 0, 0 );
95 2 : poFDefn->AddFieldDefn( &oField );
96 :
97 : /* -------------------------------------------------------------------- */
98 : /* DSSI fields. */
99 : /* -------------------------------------------------------------------- */
100 :
101 2 : oField.Set( "DSSI_DSTR", OFTInteger, 3, 0 );
102 2 : poFDefn->AddFieldDefn( &oField );
103 :
104 2 : oField.Set( "DSSI_AALL", OFTInteger, 3, 0 );
105 2 : poFDefn->AddFieldDefn( &oField );
106 :
107 2 : oField.Set( "DSSI_NALL", OFTInteger, 3, 0 );
108 2 : poFDefn->AddFieldDefn( &oField );
109 :
110 2 : oField.Set( "DSSI_NOMR", OFTInteger, 10, 0 );
111 2 : poFDefn->AddFieldDefn( &oField );
112 :
113 2 : oField.Set( "DSSI_NOCR", OFTInteger, 10, 0 );
114 2 : poFDefn->AddFieldDefn( &oField );
115 :
116 2 : oField.Set( "DSSI_NOGR", OFTInteger, 10, 0 );
117 2 : poFDefn->AddFieldDefn( &oField );
118 :
119 2 : oField.Set( "DSSI_NOLR", OFTInteger, 10, 0 );
120 2 : poFDefn->AddFieldDefn( &oField );
121 :
122 2 : oField.Set( "DSSI_NOIN", OFTInteger, 10, 0 );
123 2 : poFDefn->AddFieldDefn( &oField );
124 :
125 2 : oField.Set( "DSSI_NOCN", OFTInteger, 10, 0 );
126 2 : poFDefn->AddFieldDefn( &oField );
127 :
128 2 : oField.Set( "DSSI_NOED", OFTInteger, 10, 0 );
129 2 : poFDefn->AddFieldDefn( &oField );
130 :
131 2 : oField.Set( "DSSI_NOFA", OFTInteger, 10, 0 );
132 2 : poFDefn->AddFieldDefn( &oField );
133 :
134 : /* -------------------------------------------------------------------- */
135 : /* DSPM fields. */
136 : /* -------------------------------------------------------------------- */
137 :
138 2 : oField.Set( "DSPM_HDAT", OFTInteger, 3, 0 );
139 2 : poFDefn->AddFieldDefn( &oField );
140 :
141 2 : oField.Set( "DSPM_VDAT", OFTInteger, 3, 0 );
142 2 : poFDefn->AddFieldDefn( &oField );
143 :
144 2 : oField.Set( "DSPM_SDAT", OFTInteger, 3, 0 );
145 2 : poFDefn->AddFieldDefn( &oField );
146 :
147 2 : oField.Set( "DSPM_CSCL", OFTInteger, 10, 0 );
148 2 : poFDefn->AddFieldDefn( &oField );
149 :
150 2 : oField.Set( "DSPM_DUNI", OFTInteger, 3, 0 );
151 2 : poFDefn->AddFieldDefn( &oField );
152 :
153 2 : oField.Set( "DSPM_HUNI", OFTInteger, 3, 0 );
154 2 : poFDefn->AddFieldDefn( &oField );
155 :
156 2 : oField.Set( "DSPM_PUNI", OFTInteger, 3, 0 );
157 2 : poFDefn->AddFieldDefn( &oField );
158 :
159 2 : oField.Set( "DSPM_COUN", OFTInteger, 3, 0 );
160 2 : poFDefn->AddFieldDefn( &oField );
161 :
162 2 : oField.Set( "DSPM_COMF", OFTInteger, 10, 0 );
163 2 : poFDefn->AddFieldDefn( &oField );
164 :
165 2 : oField.Set( "DSPM_SOMF", OFTInteger, 10, 0 );
166 2 : poFDefn->AddFieldDefn( &oField );
167 :
168 2 : oField.Set( "DSPM_COMT", OFTString, 0, 0 );
169 2 : poFDefn->AddFieldDefn( &oField );
170 :
171 2 : return poFDefn;
172 : }
173 :
174 : /************************************************************************/
175 : /* S57GenerateGeomFeatureDefn() */
176 : /************************************************************************/
177 :
178 0 : OGRFeatureDefn *S57GenerateGeomFeatureDefn( OGRwkbGeometryType eGType,
179 : int nOptionFlags )
180 :
181 : {
182 0 : OGRFeatureDefn *poFDefn = NULL;
183 :
184 0 : if( eGType == wkbPoint )
185 : {
186 0 : poFDefn = new OGRFeatureDefn( "Point" );
187 0 : poFDefn->SetGeomType( eGType );
188 : }
189 0 : else if( eGType == wkbLineString )
190 : {
191 0 : poFDefn = new OGRFeatureDefn( "Line" );
192 0 : poFDefn->SetGeomType( eGType );
193 : }
194 0 : else if( eGType == wkbPolygon )
195 : {
196 0 : poFDefn = new OGRFeatureDefn( "Area" );
197 0 : poFDefn->SetGeomType( eGType );
198 : }
199 0 : else if( eGType == wkbNone )
200 : {
201 0 : poFDefn = new OGRFeatureDefn( "Meta" );
202 0 : poFDefn->SetGeomType( eGType );
203 : }
204 0 : else if( eGType == wkbUnknown )
205 : {
206 0 : poFDefn = new OGRFeatureDefn( "Generic" );
207 0 : poFDefn->SetGeomType( eGType );
208 : }
209 : else
210 0 : return NULL;
211 :
212 0 : poFDefn->Reference();
213 0 : S57GenerateStandardAttributes( poFDefn, nOptionFlags );
214 :
215 0 : return poFDefn;
216 : }
217 :
218 : /************************************************************************/
219 : /* S57GenerateVectorPrimitiveFeatureDefn() */
220 : /************************************************************************/
221 :
222 : OGRFeatureDefn *
223 0 : S57GenerateVectorPrimitiveFeatureDefn( int nRCNM, int nOptionFlags )
224 :
225 : {
226 0 : OGRFeatureDefn *poFDefn = NULL;
227 :
228 0 : if( nRCNM == RCNM_VI )
229 : {
230 0 : poFDefn = new OGRFeatureDefn( OGRN_VI );
231 0 : poFDefn->SetGeomType( wkbPoint );
232 : }
233 0 : else if( nRCNM == RCNM_VC )
234 : {
235 0 : poFDefn = new OGRFeatureDefn( OGRN_VC );
236 0 : poFDefn->SetGeomType( wkbPoint );
237 : }
238 0 : else if( nRCNM == RCNM_VE )
239 : {
240 0 : poFDefn = new OGRFeatureDefn( OGRN_VE );
241 0 : poFDefn->SetGeomType( wkbLineString );
242 : }
243 0 : else if( nRCNM == RCNM_VF )
244 : {
245 0 : poFDefn = new OGRFeatureDefn( OGRN_VF );
246 0 : poFDefn->SetGeomType( wkbPolygon );
247 : }
248 : else
249 0 : return NULL;
250 :
251 0 : poFDefn->Reference();
252 :
253 : /* -------------------------------------------------------------------- */
254 : /* Core vector primitive attributes */
255 : /* -------------------------------------------------------------------- */
256 0 : OGRFieldDefn oField("",OFTInteger);
257 :
258 0 : oField.Set( "RCNM", OFTInteger, 3, 0 );
259 0 : poFDefn->AddFieldDefn( &oField );
260 :
261 0 : oField.Set( "RCID", OFTInteger, 8, 0 );
262 0 : poFDefn->AddFieldDefn( &oField );
263 :
264 0 : oField.Set( "RVER", OFTInteger, 2, 0 );
265 0 : poFDefn->AddFieldDefn( &oField );
266 :
267 0 : oField.Set( "RUIN", OFTInteger, 2, 0 );
268 0 : poFDefn->AddFieldDefn( &oField );
269 :
270 : /* -------------------------------------------------------------------- */
271 : /* For lines we want to capture the point links for the first */
272 : /* and last nodes. */
273 : /* -------------------------------------------------------------------- */
274 0 : if( nRCNM == RCNM_VE )
275 : {
276 0 : oField.Set( "NAME_RCNM_0", OFTInteger, 3, 0 );
277 0 : poFDefn->AddFieldDefn( &oField );
278 :
279 0 : oField.Set( "NAME_RCID_0", OFTInteger, 8, 0 );
280 0 : poFDefn->AddFieldDefn( &oField );
281 :
282 0 : oField.Set( "ORNT_0", OFTInteger, 3, 0 );
283 0 : poFDefn->AddFieldDefn( &oField );
284 :
285 0 : oField.Set( "USAG_0", OFTInteger, 3, 0 );
286 0 : poFDefn->AddFieldDefn( &oField );
287 :
288 0 : oField.Set( "TOPI_0", OFTInteger, 1, 0 );
289 0 : poFDefn->AddFieldDefn( &oField );
290 :
291 0 : oField.Set( "MASK_0", OFTInteger, 3, 0 );
292 0 : poFDefn->AddFieldDefn( &oField );
293 :
294 0 : oField.Set( "NAME_RCNM_1", OFTInteger, 3, 0 );
295 0 : poFDefn->AddFieldDefn( &oField );
296 :
297 0 : oField.Set( "NAME_RCID_1", OFTInteger, 8, 0 );
298 0 : poFDefn->AddFieldDefn( &oField );
299 :
300 0 : oField.Set( "ORNT_1", OFTInteger, 3, 0 );
301 0 : poFDefn->AddFieldDefn( &oField );
302 :
303 0 : oField.Set( "USAG_1", OFTInteger, 3, 0 );
304 0 : poFDefn->AddFieldDefn( &oField );
305 :
306 0 : oField.Set( "TOPI_1", OFTInteger, 1, 0 );
307 0 : poFDefn->AddFieldDefn( &oField );
308 :
309 0 : oField.Set( "MASK_1", OFTInteger, 3, 0 );
310 0 : poFDefn->AddFieldDefn( &oField );
311 : }
312 :
313 0 : return poFDefn;
314 : }
315 :
316 : /************************************************************************/
317 : /* S57GenerateObjectClassDefn() */
318 : /************************************************************************/
319 :
320 21 : OGRFeatureDefn *S57GenerateObjectClassDefn( S57ClassRegistrar *poCR,
321 : int nOBJL, int nOptionFlags )
322 :
323 : {
324 21 : OGRFeatureDefn *poFDefn = NULL;
325 : char **papszGeomPrim;
326 :
327 21 : if( !poCR->SelectClass( nOBJL ) )
328 0 : return NULL;
329 :
330 : /* -------------------------------------------------------------------- */
331 : /* Create the feature definition based on the object class */
332 : /* acronym. */
333 : /* -------------------------------------------------------------------- */
334 21 : poFDefn = new OGRFeatureDefn( poCR->GetAcronym() );
335 21 : poFDefn->Reference();
336 :
337 : /* -------------------------------------------------------------------- */
338 : /* Try and establish the geometry type. If more than one */
339 : /* geometry type is allowed we just fall back to wkbUnknown. */
340 : /* -------------------------------------------------------------------- */
341 21 : papszGeomPrim = poCR->GetPrimitives();
342 21 : if( CSLCount(papszGeomPrim) == 0 )
343 : {
344 0 : poFDefn->SetGeomType( wkbNone );
345 : }
346 21 : else if( CSLCount(papszGeomPrim) > 1 )
347 : {
348 : // leave as unknown geometry type.
349 : }
350 15 : else if( papszGeomPrim[0][0] == 'P' )
351 : {
352 7 : if( EQUAL(poCR->GetAcronym(),"SOUNDG") )
353 : {
354 2 : if( nOptionFlags & S57M_SPLIT_MULTIPOINT )
355 0 : poFDefn->SetGeomType( wkbPoint25D );
356 : else
357 2 : poFDefn->SetGeomType( wkbMultiPoint25D );
358 : }
359 : else
360 5 : poFDefn->SetGeomType( wkbPoint );
361 : }
362 8 : else if( papszGeomPrim[0][0] == 'A' )
363 : {
364 5 : poFDefn->SetGeomType( wkbPolygon );
365 : }
366 3 : else if( papszGeomPrim[0][0] == 'L' )
367 : {
368 3 : poFDefn->SetGeomType( wkbLineString );
369 : }
370 :
371 : /* -------------------------------------------------------------------- */
372 : /* Add the standard attributes. */
373 : /* -------------------------------------------------------------------- */
374 21 : S57GenerateStandardAttributes( poFDefn, nOptionFlags );
375 :
376 : /* -------------------------------------------------------------------- */
377 : /* Add the attributes specific to this object class. */
378 : /* -------------------------------------------------------------------- */
379 21 : char **papszAttrList = poCR->GetAttributeList();
380 :
381 838 : for( int iAttr = 0;
382 419 : papszAttrList != NULL && papszAttrList[iAttr] != NULL;
383 : iAttr++ )
384 : {
385 398 : int iAttrIndex = poCR->FindAttrByAcronym( papszAttrList[iAttr] );
386 :
387 398 : if( iAttrIndex == -1 )
388 : {
389 : CPLDebug( "S57", "Can't find attribute %s from class %s:%s.\n",
390 : papszAttrList[iAttr],
391 : poCR->GetAcronym(),
392 0 : poCR->GetDescription() );
393 0 : continue;
394 : }
395 :
396 398 : OGRFieldDefn oField( papszAttrList[iAttr], OFTInteger );
397 :
398 398 : switch( poCR->GetAttrType( iAttrIndex ) )
399 : {
400 : case SAT_ENUM:
401 : case SAT_INT:
402 88 : oField.SetType( OFTInteger );
403 88 : break;
404 :
405 : case SAT_FLOAT:
406 46 : oField.SetType( OFTReal );
407 46 : break;
408 :
409 : case SAT_CODE_STRING:
410 : case SAT_FREE_TEXT:
411 219 : oField.SetType( OFTString );
412 219 : break;
413 :
414 : case SAT_LIST:
415 45 : oField.SetType( OFTString );
416 : break;
417 : }
418 :
419 398 : poFDefn->AddFieldDefn( &oField );
420 : }
421 :
422 :
423 : /* -------------------------------------------------------------------- */
424 : /* Do we need to add DEPTH attributes to soundings? */
425 : /* -------------------------------------------------------------------- */
426 21 : if( EQUAL(poCR->GetAcronym(),"SOUNDG")
427 : && (nOptionFlags & S57M_ADD_SOUNDG_DEPTH) )
428 : {
429 0 : OGRFieldDefn oField( "DEPTH", OFTReal );
430 0 : poFDefn->AddFieldDefn( &oField );
431 : }
432 :
433 21 : return poFDefn;
434 : }
435 :
436 : /************************************************************************/
437 : /* S57GenerateStandardAttributes() */
438 : /* */
439 : /* Attach standard feature attributes to a feature definition. */
440 : /************************************************************************/
441 :
442 21 : void S57GenerateStandardAttributes( OGRFeatureDefn *poFDefn, int nOptionFlags )
443 :
444 : {
445 21 : OGRFieldDefn oField( "", OFTInteger );
446 :
447 : /* -------------------------------------------------------------------- */
448 : /* RCID */
449 : /* -------------------------------------------------------------------- */
450 21 : oField.Set( "RCID", OFTInteger, 10, 0 );
451 21 : poFDefn->AddFieldDefn( &oField );
452 :
453 : /* -------------------------------------------------------------------- */
454 : /* PRIM */
455 : /* -------------------------------------------------------------------- */
456 21 : oField.Set( "PRIM", OFTInteger, 3, 0 );
457 21 : poFDefn->AddFieldDefn( &oField );
458 :
459 : /* -------------------------------------------------------------------- */
460 : /* GRUP */
461 : /* -------------------------------------------------------------------- */
462 21 : oField.Set( "GRUP", OFTInteger, 3, 0 );
463 21 : poFDefn->AddFieldDefn( &oField );
464 :
465 : /* -------------------------------------------------------------------- */
466 : /* OBJL */
467 : /* -------------------------------------------------------------------- */
468 21 : oField.Set( "OBJL", OFTInteger, 5, 0 );
469 21 : poFDefn->AddFieldDefn( &oField );
470 :
471 : /* -------------------------------------------------------------------- */
472 : /* RVER */
473 : /* -------------------------------------------------------------------- */
474 21 : oField.Set( "RVER", OFTInteger, 3, 0 );
475 21 : poFDefn->AddFieldDefn( &oField );
476 :
477 : /* -------------------------------------------------------------------- */
478 : /* AGEN */
479 : /* -------------------------------------------------------------------- */
480 21 : oField.Set( "AGEN", OFTInteger, 5, 0 );
481 21 : poFDefn->AddFieldDefn( &oField );
482 :
483 : /* -------------------------------------------------------------------- */
484 : /* FIDN */
485 : /* -------------------------------------------------------------------- */
486 21 : oField.Set( "FIDN", OFTInteger, 10, 0 );
487 21 : poFDefn->AddFieldDefn( &oField );
488 :
489 : /* -------------------------------------------------------------------- */
490 : /* FIDS */
491 : /* -------------------------------------------------------------------- */
492 21 : oField.Set( "FIDS", OFTInteger, 5, 0 );
493 21 : poFDefn->AddFieldDefn( &oField );
494 :
495 : /* -------------------------------------------------------------------- */
496 : /* LNAM - only generated when LNAM strings are being used. */
497 : /* -------------------------------------------------------------------- */
498 21 : if( nOptionFlags & S57M_LNAM_REFS )
499 : {
500 21 : oField.Set( "LNAM", OFTString, 16, 0 );
501 21 : poFDefn->AddFieldDefn( &oField );
502 :
503 21 : oField.Set( "LNAM_REFS", OFTStringList, 16, 0 );
504 21 : poFDefn->AddFieldDefn( &oField );
505 :
506 21 : oField.Set( "FFPT_RIND", OFTIntegerList, 1, 0 );
507 21 : poFDefn->AddFieldDefn( &oField );
508 :
509 : // We should likely include FFPT_COMT here.
510 : }
511 :
512 : /* -------------------------------------------------------------------- */
513 : /* Values from FSPT field. */
514 : /* -------------------------------------------------------------------- */
515 21 : if( nOptionFlags & S57M_RETURN_LINKAGES )
516 : {
517 0 : oField.Set( "NAME_RCNM", OFTIntegerList, 3, 0 );
518 0 : poFDefn->AddFieldDefn( &oField );
519 :
520 0 : oField.Set( "NAME_RCID", OFTIntegerList, 10, 0 );
521 0 : poFDefn->AddFieldDefn( &oField );
522 :
523 0 : oField.Set( "ORNT", OFTIntegerList, 1, 0 );
524 0 : poFDefn->AddFieldDefn( &oField );
525 :
526 0 : oField.Set( "USAG", OFTIntegerList, 1, 0 );
527 0 : poFDefn->AddFieldDefn( &oField );
528 :
529 0 : oField.Set( "MASK", OFTIntegerList, 3, 0 );
530 0 : poFDefn->AddFieldDefn( &oField );
531 21 : }
532 21 : }
533 :
|