1 : /******************************************************************************
2 : * $Id: ogrfeaturedefn.cpp 17587 2009-08-27 17:56:01Z warmerdam $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: The OGRFeatureDefn class implementation.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 1999, Les Technologies SoftMap Inc.
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 : #include "ogr_feature.h"
31 : #include "ogr_api.h"
32 : #include "ogr_p.h"
33 :
34 : CPL_CVSID("$Id: ogrfeaturedefn.cpp 17587 2009-08-27 17:56:01Z warmerdam $");
35 :
36 : /************************************************************************/
37 : /* OGRFeatureDefn() */
38 : /************************************************************************/
39 :
40 : /**
41 : * \brief Constructor.
42 : *
43 : * The OGRFeatureDefn maintains a reference count, but this starts at
44 : * zero. It is mainly intended to represent a count of OGRFeature's
45 : * based on this definition.
46 : *
47 : * This method is the same as the C function OGR_FD_Create().
48 : *
49 : * @param pszName the name to be assigned to this layer/class. It does not
50 : * need to be unique.
51 : */
52 :
53 4003 : OGRFeatureDefn::OGRFeatureDefn( const char * pszName )
54 :
55 : {
56 4003 : pszFeatureClassName = CPLStrdup( pszName );
57 4003 : nRefCount = 0;
58 4003 : nFieldCount = 0;
59 4003 : papoFieldDefn = NULL;
60 4003 : eGeomType = wkbUnknown;
61 4003 : }
62 :
63 : /************************************************************************/
64 : /* OGR_FD_Create() */
65 : /************************************************************************/
66 : /**
67 : * \brief Create a new feature definition object to hold the field definitions.
68 : *
69 : * The OGRFeatureDefn maintains a reference count, but this starts at
70 : * zero, and should normally be incremented by the owner.
71 : *
72 : * This function is the same as the C++ method
73 : * OGRFeatureDefn::OGRFeatureDefn().
74 : *
75 : * @param pszName the name to be assigned to this layer/class. It does not
76 : * need to be unique.
77 : * @return handle to the newly created feature definition.
78 : */
79 :
80 5 : OGRFeatureDefnH OGR_FD_Create( const char *pszName )
81 :
82 : {
83 5 : return (OGRFeatureDefnH) new OGRFeatureDefn( pszName );
84 : }
85 :
86 :
87 : /************************************************************************/
88 : /* ~OGRFeatureDefn() */
89 : /************************************************************************/
90 :
91 4003 : OGRFeatureDefn::~OGRFeatureDefn()
92 :
93 : {
94 4003 : if( nRefCount != 0 )
95 : {
96 : CPLDebug( "OGRFeatureDefn",
97 : "OGRFeatureDefn %s with a ref count of %d deleted!\n",
98 0 : pszFeatureClassName, nRefCount );
99 : }
100 :
101 4003 : CPLFree( pszFeatureClassName );
102 :
103 25027 : for( int i = 0; i < nFieldCount; i++ )
104 : {
105 21024 : delete papoFieldDefn[i];
106 : }
107 :
108 4003 : CPLFree( papoFieldDefn );
109 4003 : }
110 :
111 : /************************************************************************/
112 : /* OGR_FD_Destroy() */
113 : /************************************************************************/
114 : /**
115 : * \brief Destroy a feature definition object and release all memory associated with it.
116 : *
117 : * This function is the same as the C++ method
118 : * OGRFeatureDefn::~OGRFeatureDefn().
119 : *
120 : * @param hDefn handle to the feature definition to be destroyed.
121 : */
122 :
123 0 : void OGR_FD_Destroy( OGRFeatureDefnH hDefn )
124 :
125 : {
126 0 : delete (OGRFeatureDefn *) hDefn;
127 0 : }
128 :
129 : /************************************************************************/
130 : /* Release() */
131 : /************************************************************************/
132 :
133 : /**
134 : * \fn void OGRFeatureDefn::Release();
135 : *
136 : * \brief Drop a reference to this object, and destroy if no longer referenced.
137 : */
138 :
139 77672 : void OGRFeatureDefn::Release()
140 :
141 : {
142 77672 : CPLAssert( NULL != this );
143 :
144 77672 : if( Dereference() <= 0 )
145 3985 : delete this;
146 77672 : }
147 :
148 : /************************************************************************/
149 : /* OGR_FD_Release() */
150 : /************************************************************************/
151 :
152 : /**
153 : * \brief Drop a reference, and destroy if unreferenced.
154 : *
155 : * This function is the same as the C++ method OGRFeatureDefn::Release().
156 : *
157 : * @param hDefn handle to the feature definition to be released.
158 : */
159 :
160 6 : void OGR_FD_Release( OGRFeatureDefnH hDefn )
161 :
162 : {
163 6 : ((OGRFeatureDefn *) hDefn)->Release();
164 6 : }
165 :
166 : /************************************************************************/
167 : /* Clone() */
168 : /************************************************************************/
169 :
170 : /**
171 : * \fn OGRFeatureDefn *OGRFeatureDefn::Clone();
172 : *
173 : * \brief Create a copy of this feature definition.
174 : *
175 : * Creates a deep copy of the feature definition.
176 : *
177 : * @return the copy.
178 : */
179 :
180 2 : OGRFeatureDefn *OGRFeatureDefn::Clone()
181 :
182 : {
183 : OGRFeatureDefn *poCopy;
184 :
185 2 : poCopy = new OGRFeatureDefn( GetName() );
186 :
187 2 : poCopy->SetGeomType( GetGeomType() );
188 :
189 4 : for( int i = 0; i < GetFieldCount(); i++ )
190 2 : poCopy->AddFieldDefn( GetFieldDefn( i ) );
191 :
192 2 : return poCopy;
193 : }
194 :
195 : /************************************************************************/
196 : /* GetName() */
197 : /************************************************************************/
198 :
199 : /**
200 : * \fn const char *OGRFeatureDefn::GetName();
201 : *
202 : * \brief Get name of this OGRFeatureDefn.
203 : *
204 : * This method is the same as the C function OGR_FD_GetName().
205 : *
206 : * @return the name. This name is internal and should not be modified, or
207 : * freed.
208 : */
209 :
210 : /************************************************************************/
211 : /* OGR_FD_GetName() */
212 : /************************************************************************/
213 : /**
214 : * \brief Get name of the OGRFeatureDefn passed as an argument.
215 : *
216 : * This function is the same as the C++ method OGRFeatureDefn::GetName().
217 : *
218 : * @param hDefn handle to the feature definition to get the name from.
219 : * @return the name. This name is internal and should not be modified, or
220 : * freed.
221 : */
222 :
223 1191 : const char *OGR_FD_GetName( OGRFeatureDefnH hDefn )
224 :
225 : {
226 1191 : return ((OGRFeatureDefn *) hDefn)->GetName();
227 : }
228 :
229 : /************************************************************************/
230 : /* GetFieldCount() */
231 : /************************************************************************/
232 :
233 : /**
234 : * \fn int OGRFeatureDefn::GetFieldCount();
235 : *
236 : * \brief Fetch number of fields on this feature.
237 : *
238 : * This method is the same as the C function OGR_FD_GetFieldCount().
239 : * @return count of fields.
240 : */
241 :
242 : /************************************************************************/
243 : /* OGR_FD_GetFieldCount() */
244 : /************************************************************************/
245 :
246 : /**
247 : * \brief Fetch number of fields on the passed feature definition.
248 : *
249 : * This function is the same as the C++ OGRFeatureDefn::GetFieldCount().
250 : *
251 : * @param hDefn handle to the feature definition to get the fields count from.
252 : * @return count of fields.
253 : */
254 :
255 162 : int OGR_FD_GetFieldCount( OGRFeatureDefnH hDefn )
256 :
257 : {
258 162 : return ((OGRFeatureDefn *) hDefn)->GetFieldCount();
259 : }
260 :
261 : /************************************************************************/
262 : /* GetFieldDefn() */
263 : /************************************************************************/
264 :
265 : /**
266 : * \brief Fetch field definition.
267 : *
268 : * This method is the same as the C function OGR_FD_GetFieldDefn().
269 : *
270 : * Starting with GDAL 1.7.0, this method will also issue an error if the index
271 : * is not valid.
272 : *
273 : * @param iField the field to fetch, between 0 and GetFieldCount()-1.
274 : *
275 : * @return a pointer to an internal field definition object or NULL if invalid index.
276 : * This object should not be modified or freed by the application.
277 : */
278 :
279 971868 : OGRFieldDefn *OGRFeatureDefn::GetFieldDefn( int iField )
280 :
281 : {
282 971868 : if( iField < 0 || iField >= nFieldCount )
283 : {
284 0 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid index : %d", iField);
285 0 : return NULL;
286 : }
287 :
288 971868 : return papoFieldDefn[iField];
289 : }
290 :
291 : /************************************************************************/
292 : /* OGR_FD_GetFieldDefn() */
293 : /************************************************************************/
294 :
295 : /**
296 : * \brief Fetch field definition of the passed feature definition.
297 : *
298 : * This function is the same as the C++ method
299 : * OGRFeatureDefn::GetFieldDefn().
300 : *
301 : * Starting with GDAL 1.7.0, this method will also issue an error if the index
302 : * is not valid.
303 : *
304 : * @param hDefn handle to the feature definition to get the field definition
305 : * from.
306 : * @param iField the field to fetch, between 0 and GetFieldCount()-1.
307 : *
308 : * @return an handle to an internal field definition object or NULL if invalid index.
309 : * This object should not be modified or freed by the application.
310 : */
311 :
312 584 : OGRFieldDefnH OGR_FD_GetFieldDefn( OGRFeatureDefnH hDefn, int iField )
313 :
314 : {
315 584 : return (OGRFieldDefnH) ((OGRFeatureDefn *) hDefn)->GetFieldDefn( iField );
316 : }
317 :
318 : /************************************************************************/
319 : /* AddFieldDefn() */
320 : /************************************************************************/
321 :
322 : /**
323 : * \brief Add a new field definition.
324 : *
325 : * This method should only be called while there are no OGRFeature
326 : * objects in existance based on this OGRFeatureDefn. The OGRFieldDefn
327 : * passed in is copied, and remains the responsibility of the caller.
328 : *
329 : * This method is the same as the C function OGR_FD_AddFieldDefn().
330 : *
331 : * @param poNewDefn the definition of the new field.
332 : */
333 :
334 21024 : void OGRFeatureDefn::AddFieldDefn( OGRFieldDefn * poNewDefn )
335 :
336 : {
337 : papoFieldDefn = (OGRFieldDefn **)
338 21024 : CPLRealloc( papoFieldDefn, sizeof(void*)*(nFieldCount+1) );
339 :
340 21024 : papoFieldDefn[nFieldCount] = new OGRFieldDefn( poNewDefn );
341 21024 : nFieldCount++;
342 21024 : }
343 :
344 : /************************************************************************/
345 : /* OGR_FD_AddFieldDefn() */
346 : /************************************************************************/
347 :
348 : /**
349 : * \brief Add a new field definition to the passed feature definition.
350 : *
351 : * This function should only be called while there are no OGRFeature
352 : * objects in existance based on this OGRFeatureDefn. The OGRFieldDefn
353 : * passed in is copied, and remains the responsibility of the caller.
354 : *
355 : * This function is the same as the C++ method OGRFeatureDefn::AddFieldDefn.
356 : *
357 : * @param hDefn handle to the feature definition to add the field definition
358 : * to.
359 : * @param hNewField handle to the new field definition.
360 : */
361 :
362 21 : void OGR_FD_AddFieldDefn( OGRFeatureDefnH hDefn, OGRFieldDefnH hNewField )
363 :
364 : {
365 21 : ((OGRFeatureDefn *) hDefn)->AddFieldDefn( (OGRFieldDefn *) hNewField );
366 21 : }
367 :
368 : /************************************************************************/
369 : /* GetGeomType() */
370 : /************************************************************************/
371 :
372 : /**
373 : * \fn OGRwkbGeometryType OGRFeatureDefn::GetGeomType();
374 : *
375 : * \brief Fetch the geometry base type.
376 : *
377 : * Note that some drivers are unable to determine a specific geometry
378 : * type for a layer, in which case wkbUnknown is returned. A value of
379 : * wkbNone indicates no geometry is available for the layer at all.
380 : * Many drivers do not properly mark the geometry
381 : * type as 25D even if some or all geometries are in fact 25D. A few (broken)
382 : * drivers return wkbPolygon for layers that also include wkbMultiPolygon.
383 : *
384 : * This method is the same as the C function OGR_FD_GetGeomType().
385 : *
386 : * @return the base type for all geometry related to this definition.
387 : */
388 :
389 : /************************************************************************/
390 : /* OGR_FD_GetGeomType() */
391 : /************************************************************************/
392 : /**
393 : * \brief Fetch the geometry base type of the passed feature definition.
394 : *
395 : * This function is the same as the C++ method OGRFeatureDefn::GetGeomType().
396 : *
397 : * @param hDefn handle to the feature definition to get the geometry type from.
398 : * @return the base type for all geometry related to this definition.
399 : */
400 :
401 102 : OGRwkbGeometryType OGR_FD_GetGeomType( OGRFeatureDefnH hDefn )
402 :
403 : {
404 102 : return ((OGRFeatureDefn *) hDefn)->GetGeomType();
405 : }
406 :
407 : /************************************************************************/
408 : /* SetGeomType() */
409 : /************************************************************************/
410 :
411 : /**
412 : * \brief Assign the base geometry type for this layer.
413 : *
414 : * All geometry objects using this type must be of the defined type or
415 : * a derived type. The default upon creation is wkbUnknown which allows for
416 : * any geometry type. The geometry type should generally not be changed
417 : * after any OGRFeatures have been created against this definition.
418 : *
419 : * This method is the same as the C function OGR_FD_SetGeomType().
420 : *
421 : * @param eNewType the new type to assign.
422 : */
423 :
424 6712 : void OGRFeatureDefn::SetGeomType( OGRwkbGeometryType eNewType )
425 :
426 : {
427 6712 : eGeomType = eNewType;
428 6712 : }
429 :
430 : /************************************************************************/
431 : /* OGR_FD_SetGeomType() */
432 : /************************************************************************/
433 :
434 : /**
435 : * \brief Assign the base geometry type for the passed layer (the same as the feature definition).
436 : *
437 : * All geometry objects using this type must be of the defined type or
438 : * a derived type. The default upon creation is wkbUnknown which allows for
439 : * any geometry type. The geometry type should generally not be changed
440 : * after any OGRFeatures have been created against this definition.
441 : *
442 : * This function is the same as the C++ method OGRFeatureDefn::SetGeomType().
443 : *
444 : * @param hDefn handle to the layer or feature definition to set the geometry
445 : * type to.
446 : * @param eType the new type to assign.
447 : */
448 :
449 4 : void OGR_FD_SetGeomType( OGRFeatureDefnH hDefn, OGRwkbGeometryType eType )
450 :
451 : {
452 4 : ((OGRFeatureDefn *) hDefn)->SetGeomType( eType );
453 4 : }
454 :
455 :
456 : /************************************************************************/
457 : /* Reference() */
458 : /************************************************************************/
459 :
460 : /**
461 : * \fn int OGRFeatureDefn::Reference();
462 : *
463 : * \brief Increments the reference count by one.
464 : *
465 : * The reference count is used keep track of the number of OGRFeature
466 : * objects referencing this definition.
467 : *
468 : * This method is the same as the C function OGR_FD_Reference().
469 : *
470 : * @return the updated reference count.
471 : */
472 :
473 : /************************************************************************/
474 : /* OGR_FD_Reference() */
475 : /************************************************************************/
476 : /**
477 : * \brief Increments the reference count by one.
478 : *
479 : * The reference count is used keep track of the number of OGRFeature
480 : * objects referencing this definition.
481 : *
482 : * This function is the same as the C++ method OGRFeatureDefn::Reference().
483 : *
484 : * @param hDefn handle to the feature definition on witch OGRFeature are
485 : * based on.
486 : * @return the updated reference count.
487 : */
488 :
489 5 : int OGR_FD_Reference( OGRFeatureDefnH hDefn )
490 :
491 : {
492 5 : return ((OGRFeatureDefn *) hDefn)->Reference();
493 : }
494 :
495 : /************************************************************************/
496 : /* Dereference() */
497 : /************************************************************************/
498 :
499 : /**
500 : * \fn int OGRFeatureDefn::Dereference();
501 : *
502 : * \brief Decrements the reference count by one.
503 : *
504 : * This method is the same as the C function OGR_FD_Dereference().
505 : *
506 : * @return the updated reference count.
507 : */
508 :
509 : /************************************************************************/
510 : /* OGR_FD_Dereference() */
511 : /************************************************************************/
512 :
513 : /**
514 : * \brief Decrements the reference count by one.
515 : *
516 : * This function is the same as the C++ method OGRFeatureDefn::Dereference().
517 : *
518 : * @param hDefn handle to the feature definition on witch OGRFeature are
519 : * based on.
520 : * @return the updated reference count.
521 : */
522 :
523 0 : int OGR_FD_Dereference( OGRFeatureDefnH hDefn )
524 :
525 : {
526 0 : return ((OGRFeatureDefn *) hDefn)->Dereference();
527 : }
528 :
529 : /************************************************************************/
530 : /* GetReferenceCount() */
531 : /************************************************************************/
532 :
533 : /**
534 : * \fn int OGRFeatureDefn::GetReferenceCount();
535 : *
536 : * \brief Fetch current reference count.
537 : *
538 : * This method is the same as the C function OGR_FD_GetReferenceCount().
539 : *
540 : * @return the current reference count.
541 : */
542 :
543 : /************************************************************************/
544 : /* OGR_FD_GetReferenceCount() */
545 : /************************************************************************/
546 :
547 : /**
548 : * \brief Fetch current reference count.
549 : *
550 : * This function is the same as the C++ method
551 : * OGRFeatureDefn::GetReferenceCount().
552 : *
553 : * @param hDefn hanlde to the feature definition on witch OGRFeature are
554 : * based on.
555 : * @return the current reference count.
556 : */
557 :
558 0 : int OGR_FD_GetReferenceCount( OGRFeatureDefnH hDefn )
559 :
560 : {
561 0 : return ((OGRFeatureDefn *) hDefn)->GetReferenceCount();
562 : }
563 :
564 : /************************************************************************/
565 : /* GetFieldIndex() */
566 : /************************************************************************/
567 :
568 : /**
569 : * \brief Find field by name.
570 : *
571 : * The field index of the first field matching the passed field name (case
572 : * insensitively) is returned.
573 : *
574 : * This method is the same as the C function OGR_FD_GetFieldIndex().
575 : *
576 : * @param pszFieldName the field name to search for.
577 : *
578 : * @return the field index, or -1 if no match found.
579 : */
580 :
581 :
582 15832 : int OGRFeatureDefn::GetFieldIndex( const char * pszFieldName )
583 :
584 : {
585 89258 : for( int i = 0; i < nFieldCount; i++ )
586 : {
587 81750 : if( EQUAL(pszFieldName, papoFieldDefn[i]->GetNameRef() ) )
588 8324 : return i;
589 : }
590 :
591 7508 : return -1;
592 : }
593 :
594 : /************************************************************************/
595 : /* OGR_FD_GetFieldIndex() */
596 : /************************************************************************/
597 : /**
598 : * \brief Find field by name.
599 : *
600 : * The field index of the first field matching the passed field name (case
601 : * insensitively) is returned.
602 : *
603 : * This function is the same as the C++ method OGRFeatureDefn::GetFieldIndex.
604 : *
605 : * @param hDefn handle to the feature definition to get field index from.
606 : * @param pszFieldName the field name to search for.
607 : *
608 : * @return the field index, or -1 if no match found.
609 : */
610 :
611 256 : int OGR_FD_GetFieldIndex( OGRFeatureDefnH hDefn, const char *pszFieldName )
612 :
613 : {
614 256 : return ((OGRFeatureDefn *)hDefn)->GetFieldIndex( pszFieldName );
615 : }
616 :
617 : /************************************************************************/
618 : /* CreateFeatureDefn() */
619 : /************************************************************************/
620 :
621 0 : OGRFeatureDefn *OGRFeatureDefn::CreateFeatureDefn( const char *pszName )
622 :
623 : {
624 0 : return new OGRFeatureDefn( pszName );
625 : }
626 :
627 : /************************************************************************/
628 : /* DestroyFeatureDefn() */
629 : /************************************************************************/
630 :
631 2 : void OGRFeatureDefn::DestroyFeatureDefn( OGRFeatureDefn *poDefn )
632 :
633 : {
634 2 : delete poDefn;
635 2 : }
|