1 : /******************************************************************************
2 : * $Id: s57featuredefns.cpp 19774 2010-05-27 15:12:33Z 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 19774 2010-05-27 15:12:33Z warmerdam $");
37 :
38 :
39 : /************************************************************************/
40 : /* S57GenerateGeomFeatureDefn() */
41 : /************************************************************************/
42 :
43 3 : OGRFeatureDefn *S57GenerateDSIDFeatureDefn()
44 :
45 : {
46 3 : OGRFeatureDefn *poFDefn = new OGRFeatureDefn( "DSID" );
47 3 : OGRFieldDefn oField( "", OFTInteger );
48 :
49 3 : poFDefn->SetGeomType( wkbNone );
50 3 : poFDefn->Reference();
51 :
52 : /* -------------------------------------------------------------------- */
53 : /* DSID fields. */
54 : /* -------------------------------------------------------------------- */
55 3 : oField.Set( "DSID_EXPP", OFTInteger, 3, 0 );
56 3 : poFDefn->AddFieldDefn( &oField );
57 :
58 3 : oField.Set( "DSID_INTU", OFTInteger, 3, 0 );
59 3 : poFDefn->AddFieldDefn( &oField );
60 :
61 3 : oField.Set( "DSID_DSNM", OFTString, 0, 0 );
62 3 : poFDefn->AddFieldDefn( &oField );
63 :
64 3 : oField.Set( "DSID_EDTN", OFTString, 0, 0 );
65 3 : poFDefn->AddFieldDefn( &oField );
66 :
67 3 : oField.Set( "DSID_UPDN", OFTString, 0, 0 );
68 3 : poFDefn->AddFieldDefn( &oField );
69 :
70 3 : oField.Set( "DSID_UADT", OFTString, 8, 0 );
71 3 : poFDefn->AddFieldDefn( &oField );
72 :
73 3 : oField.Set( "DSID_ISDT", OFTString, 8, 0 );
74 3 : poFDefn->AddFieldDefn( &oField );
75 :
76 3 : oField.Set( "DSID_STED", OFTReal, 11, 6 );
77 3 : poFDefn->AddFieldDefn( &oField );
78 :
79 3 : oField.Set( "DSID_PRSP", OFTInteger, 3, 0 );
80 3 : poFDefn->AddFieldDefn( &oField );
81 :
82 3 : oField.Set( "DSID_PSDN", OFTString, 0, 0 );
83 3 : poFDefn->AddFieldDefn( &oField );
84 :
85 3 : oField.Set( "DSID_PRED", OFTString, 0, 0 );
86 3 : poFDefn->AddFieldDefn( &oField );
87 :
88 3 : oField.Set( "DSID_PROF", OFTInteger, 3, 0 );
89 3 : poFDefn->AddFieldDefn( &oField );
90 :
91 3 : oField.Set( "DSID_AGEN", OFTInteger, 5, 0 );
92 3 : poFDefn->AddFieldDefn( &oField );
93 :
94 3 : oField.Set( "DSID_COMT", OFTString, 0, 0 );
95 3 : poFDefn->AddFieldDefn( &oField );
96 :
97 : /* -------------------------------------------------------------------- */
98 : /* DSSI fields. */
99 : /* -------------------------------------------------------------------- */
100 :
101 3 : oField.Set( "DSSI_DSTR", OFTInteger, 3, 0 );
102 3 : poFDefn->AddFieldDefn( &oField );
103 :
104 3 : oField.Set( "DSSI_AALL", OFTInteger, 3, 0 );
105 3 : poFDefn->AddFieldDefn( &oField );
106 :
107 3 : oField.Set( "DSSI_NALL", OFTInteger, 3, 0 );
108 3 : poFDefn->AddFieldDefn( &oField );
109 :
110 3 : oField.Set( "DSSI_NOMR", OFTInteger, 10, 0 );
111 3 : poFDefn->AddFieldDefn( &oField );
112 :
113 3 : oField.Set( "DSSI_NOCR", OFTInteger, 10, 0 );
114 3 : poFDefn->AddFieldDefn( &oField );
115 :
116 3 : oField.Set( "DSSI_NOGR", OFTInteger, 10, 0 );
117 3 : poFDefn->AddFieldDefn( &oField );
118 :
119 3 : oField.Set( "DSSI_NOLR", OFTInteger, 10, 0 );
120 3 : poFDefn->AddFieldDefn( &oField );
121 :
122 3 : oField.Set( "DSSI_NOIN", OFTInteger, 10, 0 );
123 3 : poFDefn->AddFieldDefn( &oField );
124 :
125 3 : oField.Set( "DSSI_NOCN", OFTInteger, 10, 0 );
126 3 : poFDefn->AddFieldDefn( &oField );
127 :
128 3 : oField.Set( "DSSI_NOED", OFTInteger, 10, 0 );
129 3 : poFDefn->AddFieldDefn( &oField );
130 :
131 3 : oField.Set( "DSSI_NOFA", OFTInteger, 10, 0 );
132 3 : poFDefn->AddFieldDefn( &oField );
133 :
134 : /* -------------------------------------------------------------------- */
135 : /* DSPM fields. */
136 : /* -------------------------------------------------------------------- */
137 :
138 3 : oField.Set( "DSPM_HDAT", OFTInteger, 3, 0 );
139 3 : poFDefn->AddFieldDefn( &oField );
140 :
141 3 : oField.Set( "DSPM_VDAT", OFTInteger, 3, 0 );
142 3 : poFDefn->AddFieldDefn( &oField );
143 :
144 3 : oField.Set( "DSPM_SDAT", OFTInteger, 3, 0 );
145 3 : poFDefn->AddFieldDefn( &oField );
146 :
147 3 : oField.Set( "DSPM_CSCL", OFTInteger, 10, 0 );
148 3 : poFDefn->AddFieldDefn( &oField );
149 :
150 3 : oField.Set( "DSPM_DUNI", OFTInteger, 3, 0 );
151 3 : poFDefn->AddFieldDefn( &oField );
152 :
153 3 : oField.Set( "DSPM_HUNI", OFTInteger, 3, 0 );
154 3 : poFDefn->AddFieldDefn( &oField );
155 :
156 3 : oField.Set( "DSPM_PUNI", OFTInteger, 3, 0 );
157 3 : poFDefn->AddFieldDefn( &oField );
158 :
159 3 : oField.Set( "DSPM_COUN", OFTInteger, 3, 0 );
160 3 : poFDefn->AddFieldDefn( &oField );
161 :
162 3 : oField.Set( "DSPM_COMF", OFTInteger, 10, 0 );
163 3 : poFDefn->AddFieldDefn( &oField );
164 :
165 3 : oField.Set( "DSPM_SOMF", OFTInteger, 10, 0 );
166 3 : poFDefn->AddFieldDefn( &oField );
167 :
168 3 : oField.Set( "DSPM_COMT", OFTString, 0, 0 );
169 3 : poFDefn->AddFieldDefn( &oField );
170 :
171 3 : return poFDefn;
172 : }
173 :
174 : /************************************************************************/
175 : /* S57GenerateGeomFeatureDefn() */
176 : /************************************************************************/
177 :
178 : OGRFeatureDefn *S57GenerateGeomFeatureDefn( OGRwkbGeometryType eGType,
179 1 : int nOptionFlags )
180 :
181 : {
182 1 : OGRFeatureDefn *poFDefn = NULL;
183 :
184 1 : if( eGType == wkbPoint )
185 : {
186 0 : poFDefn = new OGRFeatureDefn( "Point" );
187 0 : poFDefn->SetGeomType( eGType );
188 : }
189 1 : else if( eGType == wkbLineString )
190 : {
191 0 : poFDefn = new OGRFeatureDefn( "Line" );
192 0 : poFDefn->SetGeomType( eGType );
193 : }
194 1 : else if( eGType == wkbPolygon )
195 : {
196 0 : poFDefn = new OGRFeatureDefn( "Area" );
197 0 : poFDefn->SetGeomType( eGType );
198 : }
199 1 : else if( eGType == wkbNone )
200 : {
201 0 : poFDefn = new OGRFeatureDefn( "Meta" );
202 0 : poFDefn->SetGeomType( eGType );
203 : }
204 1 : else if( eGType == wkbUnknown )
205 : {
206 1 : poFDefn = new OGRFeatureDefn( "Generic" );
207 1 : poFDefn->SetGeomType( eGType );
208 : }
209 : else
210 0 : return NULL;
211 :
212 1 : poFDefn->Reference();
213 1 : S57GenerateStandardAttributes( poFDefn, nOptionFlags );
214 :
215 1 : 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( wkbUnknown );
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 : OGRFeatureDefn *S57GenerateObjectClassDefn( S57ClassRegistrar *poCR,
321 37 : int nOBJL, int nOptionFlags )
322 :
323 : {
324 37 : OGRFeatureDefn *poFDefn = NULL;
325 : char **papszGeomPrim;
326 :
327 37 : if( !poCR->SelectClass( nOBJL ) )
328 7 : return NULL;
329 :
330 : /* -------------------------------------------------------------------- */
331 : /* Create the feature definition based on the object class */
332 : /* acronym. */
333 : /* -------------------------------------------------------------------- */
334 30 : poFDefn = new OGRFeatureDefn( poCR->GetAcronym() );
335 30 : 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 30 : papszGeomPrim = poCR->GetPrimitives();
342 30 : if( CSLCount(papszGeomPrim) == 0 )
343 : {
344 0 : poFDefn->SetGeomType( wkbNone );
345 : }
346 30 : else if( CSLCount(papszGeomPrim) > 1 )
347 : {
348 : // leave as unknown geometry type.
349 : }
350 19 : else if( papszGeomPrim[0][0] == 'P' )
351 : {
352 8 : 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 6 : poFDefn->SetGeomType( wkbPoint );
361 : }
362 11 : else if( papszGeomPrim[0][0] == 'A' )
363 : {
364 8 : poFDefn->SetGeomType( wkbPolygon );
365 : }
366 3 : else if( papszGeomPrim[0][0] == 'L' )
367 : {
368 : // unfortunately this could be a multilinestring
369 3 : poFDefn->SetGeomType( wkbUnknown );
370 : }
371 :
372 : /* -------------------------------------------------------------------- */
373 : /* Add the standard attributes. */
374 : /* -------------------------------------------------------------------- */
375 30 : S57GenerateStandardAttributes( poFDefn, nOptionFlags );
376 :
377 : /* -------------------------------------------------------------------- */
378 : /* Add the attributes specific to this object class. */
379 : /* -------------------------------------------------------------------- */
380 30 : char **papszAttrList = poCR->GetAttributeList();
381 :
382 1136 : for( int iAttr = 0;
383 : papszAttrList != NULL && papszAttrList[iAttr] != NULL;
384 : iAttr++ )
385 : {
386 553 : int iAttrIndex = poCR->FindAttrByAcronym( papszAttrList[iAttr] );
387 :
388 553 : if( iAttrIndex == -1 )
389 : {
390 : CPLDebug( "S57", "Can't find attribute %s from class %s:%s.\n",
391 : papszAttrList[iAttr],
392 : poCR->GetAcronym(),
393 0 : poCR->GetDescription() );
394 0 : continue;
395 : }
396 :
397 553 : OGRFieldDefn oField( papszAttrList[iAttr], OFTInteger );
398 :
399 553 : switch( poCR->GetAttrType( iAttrIndex ) )
400 : {
401 : case SAT_ENUM:
402 : case SAT_INT:
403 123 : oField.SetType( OFTInteger );
404 123 : break;
405 :
406 : case SAT_FLOAT:
407 63 : oField.SetType( OFTReal );
408 63 : break;
409 :
410 : case SAT_CODE_STRING:
411 : case SAT_FREE_TEXT:
412 311 : oField.SetType( OFTString );
413 311 : break;
414 :
415 : case SAT_LIST:
416 56 : oField.SetType( OFTString );
417 : break;
418 : }
419 :
420 553 : poFDefn->AddFieldDefn( &oField );
421 : }
422 :
423 :
424 : /* -------------------------------------------------------------------- */
425 : /* Do we need to add DEPTH attributes to soundings? */
426 : /* -------------------------------------------------------------------- */
427 30 : if( EQUAL(poCR->GetAcronym(),"SOUNDG")
428 : && (nOptionFlags & S57M_ADD_SOUNDG_DEPTH) )
429 : {
430 0 : OGRFieldDefn oField( "DEPTH", OFTReal );
431 0 : poFDefn->AddFieldDefn( &oField );
432 : }
433 :
434 30 : return poFDefn;
435 : }
436 :
437 : /************************************************************************/
438 : /* S57GenerateStandardAttributes() */
439 : /* */
440 : /* Attach standard feature attributes to a feature definition. */
441 : /************************************************************************/
442 :
443 31 : void S57GenerateStandardAttributes( OGRFeatureDefn *poFDefn, int nOptionFlags )
444 :
445 : {
446 31 : OGRFieldDefn oField( "", OFTInteger );
447 :
448 : /* -------------------------------------------------------------------- */
449 : /* RCID */
450 : /* -------------------------------------------------------------------- */
451 31 : oField.Set( "RCID", OFTInteger, 10, 0 );
452 31 : poFDefn->AddFieldDefn( &oField );
453 :
454 : /* -------------------------------------------------------------------- */
455 : /* PRIM */
456 : /* -------------------------------------------------------------------- */
457 31 : oField.Set( "PRIM", OFTInteger, 3, 0 );
458 31 : poFDefn->AddFieldDefn( &oField );
459 :
460 : /* -------------------------------------------------------------------- */
461 : /* GRUP */
462 : /* -------------------------------------------------------------------- */
463 31 : oField.Set( "GRUP", OFTInteger, 3, 0 );
464 31 : poFDefn->AddFieldDefn( &oField );
465 :
466 : /* -------------------------------------------------------------------- */
467 : /* OBJL */
468 : /* -------------------------------------------------------------------- */
469 31 : oField.Set( "OBJL", OFTInteger, 5, 0 );
470 31 : poFDefn->AddFieldDefn( &oField );
471 :
472 : /* -------------------------------------------------------------------- */
473 : /* RVER */
474 : /* -------------------------------------------------------------------- */
475 31 : oField.Set( "RVER", OFTInteger, 3, 0 );
476 31 : poFDefn->AddFieldDefn( &oField );
477 :
478 : /* -------------------------------------------------------------------- */
479 : /* AGEN */
480 : /* -------------------------------------------------------------------- */
481 31 : oField.Set( "AGEN", OFTInteger, 5, 0 );
482 31 : poFDefn->AddFieldDefn( &oField );
483 :
484 : /* -------------------------------------------------------------------- */
485 : /* FIDN */
486 : /* -------------------------------------------------------------------- */
487 31 : oField.Set( "FIDN", OFTInteger, 10, 0 );
488 31 : poFDefn->AddFieldDefn( &oField );
489 :
490 : /* -------------------------------------------------------------------- */
491 : /* FIDS */
492 : /* -------------------------------------------------------------------- */
493 31 : oField.Set( "FIDS", OFTInteger, 5, 0 );
494 31 : poFDefn->AddFieldDefn( &oField );
495 :
496 : /* -------------------------------------------------------------------- */
497 : /* LNAM - only generated when LNAM strings are being used. */
498 : /* -------------------------------------------------------------------- */
499 31 : if( nOptionFlags & S57M_LNAM_REFS )
500 : {
501 31 : oField.Set( "LNAM", OFTString, 16, 0 );
502 31 : poFDefn->AddFieldDefn( &oField );
503 :
504 31 : oField.Set( "LNAM_REFS", OFTStringList, 16, 0 );
505 31 : poFDefn->AddFieldDefn( &oField );
506 :
507 31 : oField.Set( "FFPT_RIND", OFTIntegerList, 1, 0 );
508 31 : poFDefn->AddFieldDefn( &oField );
509 :
510 : // We should likely include FFPT_COMT here.
511 : }
512 :
513 : /* -------------------------------------------------------------------- */
514 : /* Values from FSPT field. */
515 : /* -------------------------------------------------------------------- */
516 31 : if( nOptionFlags & S57M_RETURN_LINKAGES )
517 : {
518 0 : oField.Set( "NAME_RCNM", OFTIntegerList, 3, 0 );
519 0 : poFDefn->AddFieldDefn( &oField );
520 :
521 0 : oField.Set( "NAME_RCID", OFTIntegerList, 10, 0 );
522 0 : poFDefn->AddFieldDefn( &oField );
523 :
524 0 : oField.Set( "ORNT", OFTIntegerList, 1, 0 );
525 0 : poFDefn->AddFieldDefn( &oField );
526 :
527 0 : oField.Set( "USAG", OFTIntegerList, 1, 0 );
528 0 : poFDefn->AddFieldDefn( &oField );
529 :
530 0 : oField.Set( "MASK", OFTIntegerList, 3, 0 );
531 0 : poFDefn->AddFieldDefn( &oField );
532 31 : }
533 31 : }
534 :
|