1 : /******************************************************************************
2 : * $Id: ogravclayer.cpp 15014 2008-07-23 21:05:23Z dmorissette $
3 : *
4 : * Project: OGR
5 : * Purpose: Implements OGRAVCLayer class. This is the base class for E00
6 : * and binary coverage layer implementations. It provides some base
7 : * layer operations, and methods for transforming between OGR
8 : * features, and the in memory structures of the AVC library.
9 : * Author: Frank Warmerdam, warmerdam@pobox.com
10 : *
11 : ******************************************************************************
12 : * Copyright (c) 2002, Frank Warmerdam <warmerdam@pobox.com>
13 : *
14 : * Permission is hereby granted, free of charge, to any person obtaining a
15 : * copy of this software and associated documentation files (the "Software"),
16 : * to deal in the Software without restriction, including without limitation
17 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 : * and/or sell copies of the Software, and to permit persons to whom the
19 : * Software is furnished to do so, subject to the following conditions:
20 : *
21 : * The above copyright notice and this permission notice shall be included
22 : * in all copies or substantial portions of the Software.
23 : *
24 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 : * DEALINGS IN THE SOFTWARE.
31 : ****************************************************************************/
32 :
33 : #include "ogr_avc.h"
34 : #include "cpl_conv.h"
35 : #include "cpl_string.h"
36 :
37 : CPL_CVSID("$Id: ogravclayer.cpp 15014 2008-07-23 21:05:23Z dmorissette $");
38 :
39 : /************************************************************************/
40 : /* OGRAVCLayer() */
41 : /************************************************************************/
42 :
43 4 : OGRAVCLayer::OGRAVCLayer( AVCFileType eSectionTypeIn,
44 4 : OGRAVCDataSource *poDSIn )
45 :
46 : {
47 4 : eSectionType = eSectionTypeIn;
48 :
49 4 : poFeatureDefn = NULL;
50 4 : poDS = poDSIn;
51 4 : }
52 :
53 : /************************************************************************/
54 : /* ~OGRAVCLayer() */
55 : /************************************************************************/
56 :
57 4 : OGRAVCLayer::~OGRAVCLayer()
58 :
59 : {
60 4 : if( m_nFeaturesRead > 0 && poFeatureDefn != NULL )
61 : {
62 : CPLDebug( "AVC", "%d features read on layer '%s'.",
63 : (int) m_nFeaturesRead,
64 2 : poFeatureDefn->GetName() );
65 : }
66 :
67 4 : if( poFeatureDefn != NULL )
68 4 : poFeatureDefn->Release();
69 4 : }
70 :
71 : /************************************************************************/
72 : /* TestCapability() */
73 : /************************************************************************/
74 :
75 0 : int OGRAVCLayer::TestCapability( const char * pszCap )
76 :
77 : {
78 0 : return FALSE;
79 : }
80 :
81 : /************************************************************************/
82 : /* GetSpatialRef() */
83 : /************************************************************************/
84 :
85 0 : OGRSpatialReference *OGRAVCLayer::GetSpatialRef()
86 :
87 : {
88 0 : return poDS->GetSpatialRef();
89 : }
90 :
91 : /************************************************************************/
92 : /* SetupFeatureDefinition() */
93 : /************************************************************************/
94 :
95 4 : int OGRAVCLayer::SetupFeatureDefinition( const char *pszName )
96 :
97 : {
98 4 : switch( eSectionType )
99 : {
100 : case AVCFileARC:
101 : {
102 2 : poFeatureDefn = new OGRFeatureDefn( pszName );
103 2 : poFeatureDefn->Reference();
104 2 : poFeatureDefn->SetGeomType( wkbLineString );
105 :
106 2 : OGRFieldDefn oUserId( "UserId", OFTInteger );
107 2 : OGRFieldDefn oFNode( "FNODE_", OFTInteger );
108 2 : OGRFieldDefn oTNode( "TNODE_", OFTInteger );
109 2 : OGRFieldDefn oLPoly( "LPOLY_", OFTInteger );
110 2 : OGRFieldDefn oRPoly( "RPOLY_", OFTInteger );
111 :
112 2 : poFeatureDefn->AddFieldDefn( &oUserId );
113 2 : poFeatureDefn->AddFieldDefn( &oFNode );
114 2 : poFeatureDefn->AddFieldDefn( &oTNode );
115 2 : poFeatureDefn->AddFieldDefn( &oLPoly );
116 2 : poFeatureDefn->AddFieldDefn( &oRPoly );
117 : }
118 2 : return TRUE;
119 :
120 : case AVCFilePAL:
121 : case AVCFileRPL:
122 : {
123 0 : poFeatureDefn = new OGRFeatureDefn( pszName );
124 0 : poFeatureDefn->Reference();
125 0 : poFeatureDefn->SetGeomType( wkbPolygon );
126 :
127 0 : OGRFieldDefn oArcIds( "ArcIds", OFTIntegerList );
128 0 : poFeatureDefn->AddFieldDefn( &oArcIds );
129 : }
130 0 : return TRUE;
131 :
132 : case AVCFileCNT:
133 : {
134 0 : poFeatureDefn = new OGRFeatureDefn( pszName );
135 0 : poFeatureDefn->Reference();
136 0 : poFeatureDefn->SetGeomType( wkbPoint );
137 :
138 0 : OGRFieldDefn oLabelIds( "LabelIds", OFTIntegerList );
139 0 : poFeatureDefn->AddFieldDefn( &oLabelIds );
140 : }
141 0 : return TRUE;
142 :
143 : case AVCFileLAB:
144 : {
145 2 : poFeatureDefn = new OGRFeatureDefn( pszName );
146 2 : poFeatureDefn->Reference();
147 2 : poFeatureDefn->SetGeomType( wkbPoint );
148 :
149 2 : OGRFieldDefn oValueId( "ValueId", OFTInteger );
150 2 : poFeatureDefn->AddFieldDefn( &oValueId );
151 :
152 2 : OGRFieldDefn oPolyId( "PolyId", OFTInteger );
153 2 : poFeatureDefn->AddFieldDefn( &oPolyId );
154 : }
155 2 : return TRUE;
156 :
157 : case AVCFileTXT:
158 : case AVCFileTX6:
159 : {
160 0 : poFeatureDefn = new OGRFeatureDefn( pszName );
161 0 : poFeatureDefn->Reference();
162 0 : poFeatureDefn->SetGeomType( wkbPoint );
163 :
164 0 : OGRFieldDefn oUserId( "UserId", OFTInteger );
165 0 : poFeatureDefn->AddFieldDefn( &oUserId );
166 :
167 0 : OGRFieldDefn oText( "Text", OFTString );
168 0 : poFeatureDefn->AddFieldDefn( &oText );
169 :
170 0 : OGRFieldDefn oHeight( "Height", OFTReal );
171 0 : poFeatureDefn->AddFieldDefn( &oHeight );
172 :
173 0 : OGRFieldDefn oLevel( "Level", OFTInteger );
174 0 : poFeatureDefn->AddFieldDefn( &oLevel );
175 : }
176 0 : return TRUE;
177 :
178 : default:
179 0 : poFeatureDefn = NULL;
180 0 : return FALSE;
181 : }
182 : }
183 :
184 : /************************************************************************/
185 : /* TranslateFeature() */
186 : /* */
187 : /* Translate the AVC structure for a feature to the the */
188 : /* corresponding OGR definition. It is assumed that the passed */
189 : /* in feature is of a type matching the section type */
190 : /* established by SetupFeatureDefinition(). */
191 : /************************************************************************/
192 :
193 16 : OGRFeature *OGRAVCLayer::TranslateFeature( void *pAVCFeature )
194 :
195 : {
196 16 : m_nFeaturesRead++;
197 :
198 16 : switch( eSectionType )
199 : {
200 : /* ==================================================================== */
201 : /* ARC */
202 : /* ==================================================================== */
203 : case AVCFileARC:
204 : {
205 16 : AVCArc *psArc = (AVCArc *) pAVCFeature;
206 :
207 : /* -------------------------------------------------------------------- */
208 : /* Create feature. */
209 : /* -------------------------------------------------------------------- */
210 16 : OGRFeature *poOGRFeature = new OGRFeature( GetLayerDefn() );
211 16 : poOGRFeature->SetFID( psArc->nArcId );
212 :
213 : /* -------------------------------------------------------------------- */
214 : /* Apply the line geometry. */
215 : /* -------------------------------------------------------------------- */
216 32 : OGRLineString *poLine = new OGRLineString();
217 :
218 16 : poLine->setNumPoints( psArc->numVertices );
219 60 : for( int iVert = 0; iVert < psArc->numVertices; iVert++ )
220 : poLine->setPoint( iVert,
221 44 : psArc->pasVertices[iVert].x,
222 88 : psArc->pasVertices[iVert].y );
223 :
224 16 : poOGRFeature->SetGeometryDirectly( poLine );
225 :
226 : /* -------------------------------------------------------------------- */
227 : /* Apply attributes. */
228 : /* -------------------------------------------------------------------- */
229 16 : poOGRFeature->SetField( 0, psArc->nUserId );
230 16 : poOGRFeature->SetField( 1, psArc->nFNode );
231 16 : poOGRFeature->SetField( 2, psArc->nTNode );
232 16 : poOGRFeature->SetField( 3, psArc->nLPoly );
233 16 : poOGRFeature->SetField( 4, psArc->nRPoly );
234 16 : return poOGRFeature;
235 : }
236 :
237 : /* ==================================================================== */
238 : /* PAL (Polygon) */
239 : /* RPL (Region) */
240 : /* ==================================================================== */
241 : case AVCFilePAL:
242 : case AVCFileRPL:
243 : {
244 0 : AVCPal *psPAL = (AVCPal *) pAVCFeature;
245 :
246 : /* -------------------------------------------------------------------- */
247 : /* Create feature. */
248 : /* -------------------------------------------------------------------- */
249 0 : OGRFeature *poOGRFeature = new OGRFeature( GetLayerDefn() );
250 0 : poOGRFeature->SetFID( psPAL->nPolyId );
251 :
252 : /* -------------------------------------------------------------------- */
253 : /* Apply attributes. */
254 : /* -------------------------------------------------------------------- */
255 : // Setup ArcId list.
256 : int *panArcs, i;
257 :
258 0 : panArcs = (int *) CPLMalloc(sizeof(int) * psPAL->numArcs );
259 0 : for( i = 0; i < psPAL->numArcs; i++ )
260 0 : panArcs[i] = psPAL->pasArcs[i].nArcId;
261 0 : poOGRFeature->SetField( 0, psPAL->numArcs, panArcs );
262 0 : CPLFree( panArcs );
263 :
264 0 : return poOGRFeature;
265 : }
266 :
267 : /* ==================================================================== */
268 : /* CNT (Centroid) */
269 : /* ==================================================================== */
270 : case AVCFileCNT:
271 : {
272 0 : AVCCnt *psCNT = (AVCCnt *) pAVCFeature;
273 :
274 : /* -------------------------------------------------------------------- */
275 : /* Create feature. */
276 : /* -------------------------------------------------------------------- */
277 0 : OGRFeature *poOGRFeature = new OGRFeature( GetLayerDefn() );
278 0 : poOGRFeature->SetFID( psCNT->nPolyId );
279 :
280 : /* -------------------------------------------------------------------- */
281 : /* Apply Geometry */
282 : /* -------------------------------------------------------------------- */
283 : poOGRFeature->SetGeometryDirectly(
284 0 : new OGRPoint( psCNT->sCoord.x, psCNT->sCoord.y ) );
285 :
286 : /* -------------------------------------------------------------------- */
287 : /* Apply attributes. */
288 : /* -------------------------------------------------------------------- */
289 0 : poOGRFeature->SetField( 0, psCNT->numLabels, psCNT->panLabelIds );
290 :
291 0 : return poOGRFeature;
292 : }
293 :
294 : /* ==================================================================== */
295 : /* LAB (Label) */
296 : /* ==================================================================== */
297 : case AVCFileLAB:
298 : {
299 0 : AVCLab *psLAB = (AVCLab *) pAVCFeature;
300 :
301 : /* -------------------------------------------------------------------- */
302 : /* Create feature. */
303 : /* -------------------------------------------------------------------- */
304 0 : OGRFeature *poOGRFeature = new OGRFeature( GetLayerDefn() );
305 0 : poOGRFeature->SetFID( psLAB->nValue );
306 :
307 : /* -------------------------------------------------------------------- */
308 : /* Apply Geometry */
309 : /* -------------------------------------------------------------------- */
310 : poOGRFeature->SetGeometryDirectly(
311 0 : new OGRPoint( psLAB->sCoord1.x, psLAB->sCoord1.y ) );
312 :
313 : /* -------------------------------------------------------------------- */
314 : /* Apply attributes. */
315 : /* -------------------------------------------------------------------- */
316 0 : poOGRFeature->SetField( 0, psLAB->nValue );
317 0 : poOGRFeature->SetField( 1, psLAB->nPolyId );
318 :
319 0 : return poOGRFeature;
320 : }
321 :
322 : /* ==================================================================== */
323 : /* TXT/TX6 (Text) */
324 : /* ==================================================================== */
325 : case AVCFileTXT:
326 : case AVCFileTX6:
327 : {
328 0 : AVCTxt *psTXT = (AVCTxt *) pAVCFeature;
329 :
330 : /* -------------------------------------------------------------------- */
331 : /* Create feature. */
332 : /* -------------------------------------------------------------------- */
333 0 : OGRFeature *poOGRFeature = new OGRFeature( GetLayerDefn() );
334 0 : poOGRFeature->SetFID( psTXT->nTxtId );
335 :
336 : /* -------------------------------------------------------------------- */
337 : /* Apply Geometry */
338 : /* -------------------------------------------------------------------- */
339 0 : if( psTXT->numVerticesLine > 0 )
340 : poOGRFeature->SetGeometryDirectly(
341 0 : new OGRPoint( psTXT->pasVertices[0].x,
342 0 : psTXT->pasVertices[0].y ) );
343 :
344 : /* -------------------------------------------------------------------- */
345 : /* Apply attributes. */
346 : /* -------------------------------------------------------------------- */
347 0 : poOGRFeature->SetField( 0, psTXT->nUserId );
348 0 : poOGRFeature->SetField( 1, (const char *)psTXT->pszText );
349 0 : poOGRFeature->SetField( 2, psTXT->dHeight );
350 0 : poOGRFeature->SetField( 3, psTXT->nLevel );
351 :
352 0 : return poOGRFeature;
353 : }
354 :
355 : default:
356 0 : return NULL;
357 : }
358 : }
359 :
360 : /************************************************************************/
361 : /* MatchesSpatialFilter() */
362 : /************************************************************************/
363 :
364 16 : int OGRAVCLayer::MatchesSpatialFilter( void *pFeature )
365 :
366 : {
367 16 : if( m_poFilterGeom == NULL )
368 16 : return TRUE;
369 :
370 0 : switch( eSectionType )
371 : {
372 : /* ==================================================================== */
373 : /* ARC */
374 : /* */
375 : /* Check each line segment for possible intersection. */
376 : /* ==================================================================== */
377 : case AVCFileARC:
378 : {
379 0 : AVCArc *psArc = (AVCArc *) pFeature;
380 :
381 0 : for( int iVert = 0; iVert < psArc->numVertices-1; iVert++ )
382 : {
383 0 : AVCVertex *psV1 = psArc->pasVertices + iVert;
384 0 : AVCVertex *psV2 = psArc->pasVertices + iVert + 1;
385 :
386 0 : if( (psV1->x < m_sFilterEnvelope.MinX
387 : && psV2->x < m_sFilterEnvelope.MinX)
388 : || (psV1->x > m_sFilterEnvelope.MaxX
389 : && psV2->x > m_sFilterEnvelope.MaxX)
390 : || (psV1->y < m_sFilterEnvelope.MinY
391 : && psV2->y < m_sFilterEnvelope.MinY)
392 : || (psV1->y > m_sFilterEnvelope.MaxY
393 : && psV2->y > m_sFilterEnvelope.MaxY) )
394 : /* This segment is completely outside extents */;
395 : else
396 0 : return TRUE;
397 : }
398 :
399 0 : return FALSE;
400 : }
401 :
402 : /* ==================================================================== */
403 : /* PAL (Polygon) */
404 : /* RPL (Region) */
405 : /* */
406 : /* Check against the polygon bounds stored in the PAL. */
407 : /* ==================================================================== */
408 : case AVCFilePAL:
409 : case AVCFileRPL:
410 : {
411 0 : AVCPal *psPAL = (AVCPal *) pFeature;
412 :
413 0 : if( psPAL->sMin.x > m_sFilterEnvelope.MaxX
414 : || psPAL->sMax.x < m_sFilterEnvelope.MinX
415 : || psPAL->sMin.y > m_sFilterEnvelope.MaxY
416 : || psPAL->sMax.y < m_sFilterEnvelope.MinY )
417 0 : return FALSE;
418 : else
419 0 : return TRUE;
420 : }
421 :
422 : /* ==================================================================== */
423 : /* CNT (Centroid) */
424 : /* ==================================================================== */
425 : case AVCFileCNT:
426 : {
427 0 : AVCCnt *psCNT = (AVCCnt *) pFeature;
428 :
429 0 : if( psCNT->sCoord.x < m_sFilterEnvelope.MinX
430 : || psCNT->sCoord.x > m_sFilterEnvelope.MaxX
431 : || psCNT->sCoord.y < m_sFilterEnvelope.MinY
432 : || psCNT->sCoord.y > m_sFilterEnvelope.MaxY )
433 0 : return FALSE;
434 : else
435 0 : return TRUE;
436 : }
437 :
438 : /* ==================================================================== */
439 : /* LAB (Label) */
440 : /* ==================================================================== */
441 : case AVCFileLAB:
442 : {
443 0 : AVCLab *psLAB = (AVCLab *) pFeature;
444 :
445 0 : if( psLAB->sCoord1.x < m_sFilterEnvelope.MinX
446 : || psLAB->sCoord1.x > m_sFilterEnvelope.MaxX
447 : || psLAB->sCoord1.y < m_sFilterEnvelope.MinY
448 : || psLAB->sCoord1.y > m_sFilterEnvelope.MaxY )
449 0 : return FALSE;
450 : else
451 0 : return TRUE;
452 : }
453 :
454 : /* ==================================================================== */
455 : /* TXT/TX6 (Text) */
456 : /* ==================================================================== */
457 : case AVCFileTXT:
458 : case AVCFileTX6:
459 : {
460 0 : AVCTxt *psTXT = (AVCTxt *) pFeature;
461 :
462 0 : if( psTXT->numVerticesLine == 0 )
463 0 : return TRUE;
464 :
465 0 : if( psTXT->pasVertices[0].x < m_sFilterEnvelope.MinX
466 0 : || psTXT->pasVertices[0].x > m_sFilterEnvelope.MaxX
467 0 : || psTXT->pasVertices[0].y < m_sFilterEnvelope.MinY
468 0 : || psTXT->pasVertices[0].y > m_sFilterEnvelope.MaxY )
469 0 : return FALSE;
470 : else
471 0 : return TRUE;
472 : }
473 :
474 : default:
475 0 : return TRUE;
476 : }
477 : }
478 :
479 : /************************************************************************/
480 : /* AppendTableDefinition() */
481 : /* */
482 : /* Add fields to this layers feature definition based on the */
483 : /* definition from the coverage. */
484 : /************************************************************************/
485 :
486 0 : int OGRAVCLayer::AppendTableDefinition( AVCTableDef *psTableDef )
487 :
488 : {
489 0 : for( int iField = 0; iField < psTableDef->numFields; iField++ )
490 : {
491 0 : AVCFieldInfo *psFInfo = psTableDef->pasFieldDef + iField;
492 : char szFieldName[128];
493 :
494 : /* Strip off white space */
495 0 : strcpy( szFieldName, psFInfo->szName );
496 0 : if( strstr(szFieldName," ") != NULL )
497 0 : *(strstr(szFieldName," ")) = '\0';
498 :
499 0 : OGRFieldDefn oFDefn( szFieldName, OFTInteger );
500 :
501 0 : if( psFInfo->nIndex < 0 )
502 0 : continue;
503 :
504 : // Skip FNODE#, TNODE#, LPOLY# and RPOLY# from AAT table.
505 0 : if( eSectionType == AVCFileARC && iField < 4 )
506 0 : continue;
507 :
508 0 : oFDefn.SetWidth( psFInfo->nFmtWidth );
509 :
510 0 : if( psFInfo->nType1 * 10 == AVC_FT_DATE
511 : || psFInfo->nType1 * 10 == AVC_FT_CHAR )
512 0 : oFDefn.SetType( OFTString );
513 :
514 0 : else if( psFInfo->nType1 * 10 == AVC_FT_FIXINT
515 : || psFInfo->nType1 * 10 == AVC_FT_BININT )
516 0 : oFDefn.SetType( OFTInteger );
517 :
518 0 : else if( psFInfo->nType1 * 10 == AVC_FT_FIXNUM
519 : || psFInfo->nType1 * 10 == AVC_FT_BINFLOAT )
520 : {
521 0 : oFDefn.SetType( OFTReal );
522 0 : if( psFInfo->nFmtPrec > 0 )
523 0 : oFDefn.SetPrecision( psFInfo->nFmtPrec );
524 : }
525 :
526 0 : poFeatureDefn->AddFieldDefn( &oFDefn );
527 : }
528 0 : return TRUE;
529 : }
530 :
531 : /************************************************************************/
532 : /* TranslateTableFields() */
533 : /************************************************************************/
534 :
535 0 : int OGRAVCLayer::TranslateTableFields( OGRFeature *poFeature,
536 : int nFieldBase,
537 : AVCTableDef *psTableDef,
538 : AVCField *pasFields )
539 :
540 : {
541 0 : int iOutField = nFieldBase;
542 :
543 0 : for( int iField=0; iField < psTableDef->numFields; iField++ )
544 : {
545 0 : AVCFieldInfo *psFInfo = psTableDef->pasFieldDef + iField;
546 0 : int nType = psFInfo->nType1 * 10;
547 :
548 0 : if( psFInfo->nIndex < 0 )
549 0 : continue;
550 :
551 : // Skip FNODE#, TNODE#, LPOLY# and RPOLY# from AAT table.
552 0 : if( eSectionType == AVCFileARC && iField < 4 )
553 0 : continue;
554 :
555 0 : if (nType == AVC_FT_DATE || nType == AVC_FT_CHAR ||
556 : nType == AVC_FT_FIXINT || nType == AVC_FT_FIXNUM)
557 : {
558 0 : if (nType == AVC_FT_CHAR)
559 : {
560 : /* Remove trailing spaces in char fields */
561 0 : int nLen = strlen((const char*)pasFields[iField].pszStr);
562 0 : while (nLen > 0 && pasFields[iField].pszStr[nLen-1] == ' ')
563 0 : nLen--;
564 0 : pasFields[iField].pszStr[nLen] = '\0';
565 : }
566 : poFeature->SetField( iOutField++,
567 0 : (const char *)pasFields[iField].pszStr );
568 : }
569 0 : else if (nType == AVC_FT_BININT && psFInfo->nSize == 4)
570 : {
571 0 : poFeature->SetField( iOutField++, pasFields[iField].nInt32 );
572 : }
573 0 : else if (nType == AVC_FT_BININT && psFInfo->nSize == 2)
574 : {
575 0 : poFeature->SetField( iOutField++, pasFields[iField].nInt16 );
576 : }
577 0 : else if (nType == AVC_FT_BINFLOAT && psFInfo->nSize == 4)
578 : {
579 0 : poFeature->SetField( iOutField++, pasFields[iField].fFloat );
580 : }
581 0 : else if (nType == AVC_FT_BINFLOAT && psFInfo->nSize == 8)
582 : {
583 0 : poFeature->SetField( iOutField++, pasFields[iField].dDouble );
584 : }
585 : else
586 : {
587 : CPLAssert( FALSE );
588 0 : return FALSE;
589 : }
590 : }
591 :
592 0 : return TRUE;
593 : }
594 :
595 :
596 :
597 :
598 :
599 :
|