1 : /******************************************************************************
2 : * $Id: ogrhtflayer.cpp 20766 2010-10-05 09:07:28Z rouault $
3 : *
4 : * Project: HTF Translator
5 : * Purpose: Implements OGRHTFLayer class.
6 : * Author: Even Rouault, <even dot rouault at mines dash paris dot org>
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2010, Even Rouault <even dot rouault at mines dash paris dot org>
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_htf.h"
31 : #include "cpl_conv.h"
32 : #include "cpl_string.h"
33 : #include "ogr_p.h"
34 : #include "ogr_srs_api.h"
35 :
36 : CPL_CVSID("$Id: ogrhtflayer.cpp 20766 2010-10-05 09:07:28Z rouault $");
37 :
38 : /************************************************************************/
39 : /* OGRHTFLayer() */
40 : /************************************************************************/
41 :
42 12 : OGRHTFLayer::OGRHTFLayer( const char* pszFilename, int nZone, int bIsNorth )
43 :
44 : {
45 12 : fpHTF = VSIFOpenL(pszFilename, "rb");
46 12 : nNextFID = 0;
47 12 : bEOF = FALSE;
48 :
49 12 : poSRS = new OGRSpatialReference(SRS_WKT_WGS84);
50 12 : poSRS->SetUTM( nZone, bIsNorth );
51 :
52 12 : bHasExtent = FALSE;
53 12 : dfMinX = 0;
54 12 : dfMinY = 0;
55 12 : dfMaxX = 0;
56 12 : dfMaxY = 0;
57 12 : }
58 :
59 : /************************************************************************/
60 : /* OGRHTFPolygonLayer() */
61 : /************************************************************************/
62 :
63 6 : OGRHTFPolygonLayer::OGRHTFPolygonLayer( const char* pszFilename, int nZone, int bIsNorth ) :
64 6 : OGRHTFLayer(pszFilename, nZone, bIsNorth)
65 :
66 : {
67 6 : poFeatureDefn = new OGRFeatureDefn( "polygon" );
68 6 : poFeatureDefn->Reference();
69 6 : poFeatureDefn->SetGeomType( wkbPolygon );
70 :
71 6 : OGRFieldDefn oField1( "DESCRIPTION", OFTString);
72 6 : poFeatureDefn->AddFieldDefn( &oField1 );
73 6 : OGRFieldDefn oField2( "IDENTIFIER", OFTInteger);
74 6 : poFeatureDefn->AddFieldDefn( &oField2 );
75 6 : OGRFieldDefn oField3( "SEAFLOOR_COVERAGE", OFTString);
76 6 : poFeatureDefn->AddFieldDefn( &oField3 );
77 6 : OGRFieldDefn oField4( "POSITION_ACCURACY", OFTReal);
78 6 : poFeatureDefn->AddFieldDefn( &oField4 );
79 6 : OGRFieldDefn oField5( "DEPTH_ACCURACY", OFTReal);
80 6 : poFeatureDefn->AddFieldDefn( &oField5 );
81 :
82 6 : ResetReading();
83 6 : }
84 :
85 : /************************************************************************/
86 : /* OGRHTFSoundingLayer() */
87 : /************************************************************************/
88 :
89 6 : OGRHTFSoundingLayer::OGRHTFSoundingLayer( const char* pszFilename, int nZone, int bIsNorth, int nTotalSoundings ) :
90 6 : OGRHTFLayer(pszFilename, nZone, bIsNorth)
91 :
92 : {
93 6 : poFeatureDefn = new OGRFeatureDefn( "sounding" );
94 6 : poFeatureDefn->Reference();
95 6 : poFeatureDefn->SetGeomType( wkbPoint );
96 :
97 6 : this->nTotalSoundings = nTotalSoundings;
98 6 : bHasFPK = FALSE;
99 6 : nFieldsPresent = 0;
100 6 : panFieldPresence = NULL;
101 6 : nEastingIndex = -1;
102 6 : nNorthingIndex = -1;
103 :
104 : const char* pszLine;
105 6 : int bSoundingHeader = FALSE;
106 762 : while( fpHTF != NULL &&
107 : (pszLine = CPLReadLine2L(fpHTF, 1024, NULL)) != NULL)
108 : {
109 756 : if (strncmp(pszLine, "SOUNDING HEADER", strlen("SOUNDING HEADER")) == 0)
110 6 : bSoundingHeader = TRUE;
111 1314 : else if (bSoundingHeader && strlen(pszLine) > 10 &&
112 288 : pszLine[0] == '[' && pszLine[3] == ']' &&
113 138 : pszLine[4] == ' ' &&
114 : strstr(pszLine + 5, " =") != NULL)
115 : {
116 138 : char* pszName = CPLStrdup(pszLine + 5);
117 138 : *strstr(pszName, " =") = 0;
118 138 : char* pszPtr = pszName;
119 1608 : for(;*pszPtr;pszPtr++)
120 : {
121 1470 : if (*pszPtr == ' ')
122 96 : *pszPtr = '_';
123 : }
124 : OGRFieldType eType;
125 168 : if (strcmp(pszName, "REJECTED_SOUNDING") == 0 ||
126 : strcmp(pszName, "FIX_NUMBER") == 0 ||
127 : strcmp(pszName, "NBA_FLAG") == 0 ||
128 : strcmp(pszName, "SOUND_VELOCITY") == 0 ||
129 : strcmp(pszName, "PLOTTED_SOUNDING") == 0)
130 30 : eType = OFTInteger;
131 168 : else if (strcmp(pszName, "LATITUDE") == 0 ||
132 : strcmp(pszName, "LONGITUDE") == 0 ||
133 : strcmp(pszName, "EASTING") == 0 ||
134 : strcmp(pszName, "NORTHING") == 0 ||
135 : strcmp(pszName, "DEPTH") == 0 ||
136 : strcmp(pszName, "TPE_POSITION") == 0 ||
137 : strcmp(pszName, "TPE_DEPTH") == 0 ||
138 : strcmp(pszName, "TIDE") == 0 ||
139 : strcmp(pszName, "DEEP_WATER_CORRECTION") == 0 ||
140 : strcmp(pszName, "VERTICAL_BIAS_CORRECTION") == 0)
141 60 : eType = OFTReal;
142 : else
143 48 : eType = OFTString;
144 138 : OGRFieldDefn oField( pszName, eType);
145 138 : poFeatureDefn->AddFieldDefn( &oField);
146 138 : CPLFree(pszName);
147 : }
148 612 : else if (strcmp(pszLine, "END OF SOUNDING HEADER") == 0)
149 : {
150 6 : bSoundingHeader = FALSE;
151 : }
152 606 : else if (strcmp(pszLine, "SOUNDING DATA") == 0)
153 : {
154 6 : pszLine = CPLReadLine2L(fpHTF, 1024, NULL);
155 6 : if (pszLine == NULL)
156 0 : break;
157 6 : if (pszLine[0] == '[' &&
158 : (int)strlen(pszLine) == 2 + poFeatureDefn->GetFieldCount())
159 : {
160 6 : bHasFPK = TRUE;
161 : panFieldPresence = (int*)CPLMalloc(sizeof(int) *
162 6 : poFeatureDefn->GetFieldCount());
163 : int i;
164 144 : for(i=0;i<poFeatureDefn->GetFieldCount();i++)
165 : {
166 138 : panFieldPresence[i] = pszLine[1 + i] != '0';
167 138 : nFieldsPresent += panFieldPresence[i];
168 : }
169 : }
170 6 : break;
171 : }
172 : }
173 :
174 6 : if (!bHasFPK)
175 : {
176 : panFieldPresence = (int*)CPLMalloc(sizeof(int) *
177 0 : poFeatureDefn->GetFieldCount());
178 : int i;
179 0 : for(i=0;i<poFeatureDefn->GetFieldCount();i++)
180 0 : panFieldPresence[i] = TRUE;
181 0 : nFieldsPresent = poFeatureDefn->GetFieldCount();
182 : }
183 :
184 : int nIndex;
185 6 : nIndex = poFeatureDefn->GetFieldIndex("EASTING");
186 6 : if (nIndex < 0 || !panFieldPresence[nIndex])
187 : {
188 0 : CPLError(CE_Failure, CPLE_NotSupported, "Cannot find EASTING field");
189 0 : VSIFCloseL( fpHTF );
190 0 : fpHTF = NULL;
191 0 : return;
192 : }
193 6 : nEastingIndex = nIndex;
194 6 : nIndex = poFeatureDefn->GetFieldIndex("NORTHING");
195 6 : if (nIndex < 0 || !panFieldPresence[nIndex])
196 : {
197 0 : CPLError(CE_Failure, CPLE_NotSupported, "Cannot find NORTHING field");
198 0 : VSIFCloseL( fpHTF );
199 0 : fpHTF = NULL;
200 0 : return;
201 : }
202 6 : nNorthingIndex = nIndex;
203 :
204 6 : ResetReading();
205 0 : }
206 :
207 : /************************************************************************/
208 : /* ~OGRHTFLayer() */
209 : /************************************************************************/
210 :
211 12 : OGRHTFLayer::~OGRHTFLayer()
212 :
213 : {
214 12 : if( poSRS != NULL )
215 12 : poSRS->Release();
216 :
217 12 : poFeatureDefn->Release();
218 :
219 12 : if (fpHTF)
220 12 : VSIFCloseL( fpHTF );
221 12 : }
222 :
223 :
224 : /************************************************************************/
225 : /* ~OGRHTFSoundingLayer() */
226 : /************************************************************************/
227 :
228 6 : OGRHTFSoundingLayer::~OGRHTFSoundingLayer()
229 :
230 : {
231 6 : CPLFree(panFieldPresence);
232 6 : }
233 :
234 : /************************************************************************/
235 : /* ResetReading() */
236 : /************************************************************************/
237 :
238 86 : void OGRHTFLayer::ResetReading()
239 :
240 : {
241 86 : nNextFID = 0;
242 86 : bEOF = FALSE;
243 86 : if (fpHTF)
244 : {
245 86 : VSIFSeekL( fpHTF, 0, SEEK_SET );
246 : }
247 86 : }
248 :
249 :
250 : /************************************************************************/
251 : /* ResetReading() */
252 : /************************************************************************/
253 :
254 48 : void OGRHTFPolygonLayer::ResetReading()
255 :
256 : {
257 48 : OGRHTFLayer::ResetReading();
258 48 : if (fpHTF)
259 : {
260 : const char* pszLine;
261 3216 : while( (pszLine = CPLReadLine2L(fpHTF, 1024, NULL)) != NULL)
262 : {
263 3168 : if (strcmp(pszLine, "POLYGON DATA") == 0)
264 : {
265 48 : break;
266 : }
267 : }
268 48 : if (pszLine == NULL)
269 0 : bEOF = TRUE;
270 : }
271 48 : }
272 :
273 :
274 : /************************************************************************/
275 : /* ResetReading() */
276 : /************************************************************************/
277 :
278 38 : void OGRHTFSoundingLayer::ResetReading()
279 :
280 : {
281 38 : OGRHTFLayer::ResetReading();
282 38 : if (fpHTF)
283 : {
284 : const char* pszLine;
285 4826 : while( (pszLine = CPLReadLine2L(fpHTF, 1024, NULL)) != NULL)
286 : {
287 4788 : if (strcmp(pszLine, "SOUNDING DATA") == 0)
288 : {
289 38 : if (bHasFPK)
290 38 : pszLine = CPLReadLine2L(fpHTF, 1024, NULL);
291 38 : break;
292 : }
293 : }
294 38 : if (pszLine == NULL)
295 0 : bEOF = TRUE;
296 : }
297 38 : }
298 :
299 : /************************************************************************/
300 : /* GetNextFeature() */
301 : /************************************************************************/
302 :
303 93 : OGRFeature *OGRHTFLayer::GetNextFeature()
304 : {
305 : OGRFeature *poFeature;
306 :
307 93 : if (fpHTF == NULL || bEOF)
308 13 : return NULL;
309 :
310 179 : while(!bEOF)
311 : {
312 94 : poFeature = GetNextRawFeature();
313 94 : if (poFeature == NULL)
314 13 : return NULL;
315 :
316 81 : if((m_poFilterGeom == NULL
317 : || FilterGeometry( poFeature->GetGeometryRef() ) )
318 : && (m_poAttrQuery == NULL
319 : || m_poAttrQuery->Evaluate( poFeature )) )
320 : {
321 62 : return poFeature;
322 : }
323 : else
324 19 : delete poFeature;
325 : }
326 :
327 5 : return NULL;
328 : }
329 :
330 : /************************************************************************/
331 : /* GetNextRawFeature() */
332 : /************************************************************************/
333 :
334 46 : OGRFeature *OGRHTFPolygonLayer::GetNextRawFeature()
335 : {
336 46 : OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
337 :
338 : const char* pszLine;
339 :
340 46 : OGRLinearRing oLR;
341 46 : int bHastFirstCoord = FALSE;
342 46 : double dfFirstEasting = 0, dfFirstNorthing = 0;
343 46 : double dfIslandEasting = 0, dfIslandNorthing = 0;
344 46 : int bInIsland = FALSE;
345 92 : OGRPolygon* poPoly = new OGRPolygon();
346 :
347 657 : while( (pszLine = CPLReadLine2L(fpHTF, 1024, NULL)) != NULL)
348 : {
349 611 : if (pszLine[0] == ';')
350 : {
351 : /* comment */ ;
352 : }
353 611 : else if (pszLine[0] == 0)
354 : {
355 : /* end of polygon is marked by a blank line */
356 25 : break;
357 : }
358 586 : else if (strncmp(pszLine, "POLYGON DESCRIPTION: ",
359 : strlen("POLYGON DESCRIPTION: ")) == 0)
360 : {
361 46 : poFeature->SetField(0, pszLine + strlen("POLYGON DESCRIPTION: "));
362 : }
363 540 : else if (strncmp(pszLine, "POLYGON IDENTIFIER: ",
364 : strlen("POLYGON IDENTIFIER: ")) == 0)
365 : {
366 46 : poFeature->SetField(1, pszLine + strlen("POLYGON IDENTIFIER: "));
367 : }
368 494 : else if (strncmp(pszLine, "SEAFLOOR COVERAGE: ",
369 : strlen("SEAFLOOR COVERAGE:")) == 0)
370 : {
371 46 : const char* pszVal = pszLine + strlen("SEAFLOOR COVERAGE: ");
372 46 : if (*pszVal != '*')
373 0 : poFeature->SetField(2, pszVal);
374 : }
375 448 : else if (strncmp(pszLine, "POSITION ACCURACY: ",
376 : strlen("POSITION ACCURACY:")) == 0)
377 : {
378 46 : const char* pszVal = pszLine + strlen("POSITION ACCURACY: ");
379 46 : if (*pszVal != '*')
380 0 : poFeature->SetField(3, pszVal);
381 : }
382 402 : else if (strncmp(pszLine, "DEPTH ACCURACY: ",
383 : strlen("DEPTH ACCURACY:")) == 0)
384 : {
385 46 : const char* pszVal = pszLine + strlen("DEPTH ACCURACY: ");
386 46 : if (*pszVal != '*')
387 0 : poFeature->SetField(4, pszVal);
388 : }
389 356 : else if (strcmp(pszLine, "END OF POLYGON DATA") == 0)
390 : {
391 21 : bEOF = TRUE;
392 21 : break;
393 : }
394 : else
395 : {
396 335 : char** papszTokens = CSLTokenizeString(pszLine);
397 335 : if (CSLCount(papszTokens) == 4)
398 : {
399 335 : double dfEasting = atof(papszTokens[2]);
400 335 : double dfNorthing = atof(papszTokens[3]);
401 335 : if (!bHastFirstCoord)
402 : {
403 46 : bHastFirstCoord = TRUE;
404 46 : dfFirstEasting = dfEasting;
405 46 : dfFirstNorthing = dfNorthing;
406 46 : oLR.addPoint(dfEasting, dfNorthing);
407 : }
408 356 : else if (dfFirstEasting == dfEasting &&
409 : dfFirstNorthing == dfNorthing)
410 : {
411 67 : if (!bInIsland)
412 : {
413 46 : oLR.addPoint(dfEasting, dfNorthing);
414 46 : poPoly->addRing(&oLR);
415 46 : oLR.empty();
416 46 : bInIsland = TRUE;
417 : }
418 : }
419 222 : else if (bInIsland && oLR.getNumPoints() == 0)
420 : {
421 21 : dfIslandEasting = dfEasting;
422 21 : dfIslandNorthing = dfNorthing;
423 21 : oLR.addPoint(dfEasting, dfNorthing);
424 : }
425 222 : else if (bInIsland && dfIslandEasting == dfEasting &&
426 : dfIslandNorthing == dfNorthing)
427 : {
428 21 : oLR.addPoint(dfEasting, dfNorthing);
429 21 : poPoly->addRing(&oLR);
430 21 : oLR.empty();
431 : }
432 : else
433 : {
434 180 : oLR.addPoint(dfEasting, dfNorthing);
435 : }
436 : }
437 335 : CSLDestroy(papszTokens);
438 : }
439 : }
440 :
441 46 : if (pszLine == NULL)
442 0 : bEOF = TRUE;
443 :
444 46 : if (oLR.getNumPoints() >= 3)
445 : {
446 0 : oLR.closeRings();
447 0 : poPoly->addRing(&oLR);
448 : }
449 46 : poPoly->assignSpatialReference(poSRS);
450 46 : poFeature->SetGeometryDirectly(poPoly);
451 46 : poFeature->SetFID(nNextFID++);
452 :
453 46 : return poFeature;
454 : }
455 :
456 :
457 : /************************************************************************/
458 : /* GetNextRawFeature() */
459 : /************************************************************************/
460 :
461 48 : OGRFeature *OGRHTFSoundingLayer::GetNextRawFeature()
462 : {
463 : const char* pszLine;
464 :
465 48 : OGRLinearRing oLR;
466 :
467 48 : while( (pszLine = CPLReadLine2L(fpHTF, 1024, NULL)) != NULL)
468 : {
469 48 : if (pszLine[0] == ';')
470 : {
471 : /* comment */ ;
472 : }
473 48 : else if (pszLine[0] == 0)
474 : {
475 0 : bEOF = TRUE;
476 0 : return NULL;
477 : }
478 48 : else if (strcmp(pszLine, "END OF SOUNDING DATA") == 0)
479 : {
480 13 : bEOF = TRUE;
481 13 : return NULL;
482 : }
483 : else
484 35 : break;
485 : }
486 35 : if (pszLine == NULL)
487 : {
488 0 : bEOF = TRUE;
489 0 : return NULL;
490 : }
491 :
492 : int i;
493 35 : double dfEasting = 0, dfNorthing = 0;
494 35 : OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
495 35 : char* pszStr = (char*)pszLine;
496 805 : for(i=0;i<poFeatureDefn->GetFieldCount();i++)
497 : {
498 805 : if (!panFieldPresence[i])
499 105 : continue;
500 :
501 700 : char* pszSpace = strchr(pszStr, ' ');
502 700 : if (pszSpace)
503 665 : *pszSpace = '\0';
504 :
505 700 : if (strcmp(pszStr, "*") != 0)
506 700 : poFeature->SetField(i, pszStr);
507 700 : if (i == nEastingIndex)
508 35 : dfEasting = poFeature->GetFieldAsDouble(i);
509 665 : else if (i == nNorthingIndex)
510 35 : dfNorthing = poFeature->GetFieldAsDouble(i);
511 :
512 700 : if (pszSpace == NULL)
513 35 : break;
514 665 : pszStr = pszSpace + 1;
515 : }
516 35 : OGRPoint* poPoint = new OGRPoint(dfEasting, dfNorthing);
517 35 : poPoint->assignSpatialReference(poSRS);
518 35 : poFeature->SetGeometryDirectly(poPoint);
519 35 : poFeature->SetFID(nNextFID++);
520 35 : return poFeature;
521 : }
522 :
523 : /************************************************************************/
524 : /* GetFeatureCount() */
525 : /************************************************************************/
526 :
527 10 : int OGRHTFSoundingLayer::GetFeatureCount(int bForce)
528 : {
529 10 : if (m_poFilterGeom != NULL || m_poAttrQuery != NULL)
530 4 : return OGRHTFLayer::GetFeatureCount(bForce);
531 :
532 6 : if (nTotalSoundings != 0)
533 6 : return nTotalSoundings;
534 :
535 0 : ResetReading();
536 0 : if (fpHTF == NULL)
537 0 : return 0;
538 :
539 0 : int nCount = 0;
540 : const char* pszLine;
541 0 : while( (pszLine = CPLReadLine2L(fpHTF, 1024, NULL)) != NULL)
542 : {
543 0 : if (pszLine[0] == ';')
544 : {
545 : /* comment */ ;
546 : }
547 0 : else if (pszLine[0] == 0)
548 0 : break;
549 0 : else if (strcmp(pszLine, "END OF SOUNDING DATA") == 0)
550 0 : break;
551 : else
552 0 : nCount ++;
553 : }
554 :
555 0 : ResetReading();
556 0 : return nCount;
557 : }
558 :
559 : /************************************************************************/
560 : /* TestCapability() */
561 : /************************************************************************/
562 :
563 16 : int OGRHTFLayer::TestCapability( const char * pszCap )
564 :
565 : {
566 16 : if (EQUAL(pszCap, OLCFastGetExtent))
567 0 : return bHasExtent;
568 :
569 16 : return FALSE;
570 : }
571 :
572 :
573 : /************************************************************************/
574 : /* TestCapability() */
575 : /************************************************************************/
576 :
577 8 : int OGRHTFSoundingLayer::TestCapability( const char * pszCap )
578 :
579 : {
580 8 : if (EQUAL(pszCap, OLCFastFeatureCount))
581 0 : return m_poFilterGeom == NULL && m_poAttrQuery == NULL && nTotalSoundings != 0;
582 :
583 8 : return OGRHTFLayer::TestCapability(pszCap);
584 : }
585 :
586 : /************************************************************************/
587 : /* GetExtent() */
588 : /************************************************************************/
589 :
590 2 : OGRErr OGRHTFLayer::GetExtent(OGREnvelope *psExtent, int bForce)
591 : {
592 2 : if (!bHasExtent)
593 0 : return OGRLayer::GetExtent(psExtent, bForce);
594 :
595 2 : psExtent->MinX = dfMinX;
596 2 : psExtent->MinY = dfMinY;
597 2 : psExtent->MaxX = dfMaxX;
598 2 : psExtent->MaxY = dfMaxY;
599 2 : return OGRERR_NONE;
600 : }
601 :
602 :
603 : /************************************************************************/
604 : /* SetExtent() */
605 : /************************************************************************/
606 :
607 12 : void OGRHTFLayer::SetExtent(double dfMinX, double dfMinY, double dfMaxX, double dfMaxY)
608 : {
609 12 : bHasExtent = TRUE;
610 12 : this->dfMinX = dfMinX;
611 12 : this->dfMinY = dfMinY;
612 12 : this->dfMaxX = dfMaxX;
613 12 : this->dfMaxY = dfMaxY;
614 12 : }
615 :
616 :
617 : /************************************************************************/
618 : /* OGRHTFMetadataLayer() */
619 : /************************************************************************/
620 :
621 6 : OGRHTFMetadataLayer::OGRHTFMetadataLayer(std::vector<CPLString> aosMD)
622 : {
623 6 : this->aosMD = aosMD;
624 6 : nNextFID = 0;
625 :
626 6 : poFeatureDefn = new OGRFeatureDefn( "metadata" );
627 6 : poFeatureDefn->Reference();
628 6 : poFeatureDefn->SetGeomType( wkbNone );
629 :
630 6 : std::vector<CPLString>::const_iterator iter = aosMD.begin();
631 6 : std::vector<CPLString>::const_iterator eiter = aosMD.end();
632 300 : while(iter != eiter)
633 : {
634 288 : const CPLString& osStr = *iter;
635 288 : char* pszStr = CPLStrdup(osStr.c_str());
636 288 : char* pszSep = strstr(pszStr, ": ");
637 288 : if (pszSep)
638 : {
639 282 : *pszSep = 0;
640 282 : int i = 0, j = 0;
641 5430 : for(;pszStr[i];i++)
642 : {
643 5694 : if (pszStr[i] == ' ' || pszStr[i] == '-' || pszStr[i] == '&')
644 : {
645 666 : if (j > 0 && pszStr[j-1] == '_')
646 120 : continue;
647 546 : pszStr[j++] = '_';
648 : }
649 4482 : else if (pszStr[i] == '(' || pszStr[i] == ')')
650 : ;
651 : else
652 4446 : pszStr[j++] = pszStr[i];
653 : }
654 282 : pszStr[j] = 0;
655 282 : OGRFieldDefn oField( pszStr, OFTString);
656 282 : poFeatureDefn->AddFieldDefn( &oField );
657 : }
658 288 : CPLFree(pszStr);
659 288 : ++iter;
660 : }
661 :
662 6 : poFeature = new OGRFeature(poFeatureDefn);
663 12 : iter = aosMD.begin();
664 6 : eiter = aosMD.end();
665 6 : int nField = 0;
666 300 : while(iter != eiter)
667 : {
668 288 : const CPLString& osStr = *iter;
669 288 : const char* pszStr = osStr.c_str();
670 288 : const char* pszSep = strstr(pszStr, ": ");
671 288 : if (pszSep)
672 : {
673 282 : if (pszSep[2] != '*')
674 258 : poFeature->SetField( nField, pszSep + 2 );
675 :
676 282 : nField ++;
677 : }
678 288 : ++iter;
679 : }
680 6 : }
681 :
682 : /************************************************************************/
683 : /* ~OGRHTFMetadataLayer() */
684 : /************************************************************************/
685 :
686 6 : OGRHTFMetadataLayer::~OGRHTFMetadataLayer()
687 : {
688 6 : delete poFeature;
689 6 : poFeatureDefn->Release();
690 6 : }
691 :
692 : /************************************************************************/
693 : /* GetNextFeature() */
694 : /************************************************************************/
695 :
696 26 : OGRFeature *OGRHTFMetadataLayer::GetNextFeature()
697 : {
698 26 : if (nNextFID == 1)
699 10 : return NULL;
700 :
701 16 : if((m_poFilterGeom == NULL
702 : || FilterGeometry( poFeature->GetGeometryRef() ) )
703 : && (m_poAttrQuery == NULL
704 : || m_poAttrQuery->Evaluate( poFeature )) )
705 : {
706 13 : nNextFID = 1;
707 13 : return poFeature->Clone();
708 : }
709 :
710 3 : return NULL;
711 : }
|