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 74 : void OGRHTFLayer::ResetReading()
239 :
240 : {
241 74 : nNextFID = 0;
242 74 : bEOF = FALSE;
243 74 : if (fpHTF)
244 : {
245 74 : VSIFSeekL( fpHTF, 0, SEEK_SET );
246 : }
247 74 : }
248 :
249 :
250 : /************************************************************************/
251 : /* ResetReading() */
252 : /************************************************************************/
253 :
254 42 : void OGRHTFPolygonLayer::ResetReading()
255 :
256 : {
257 42 : OGRHTFLayer::ResetReading();
258 42 : if (fpHTF)
259 : {
260 : const char* pszLine;
261 2814 : while( (pszLine = CPLReadLine2L(fpHTF, 1024, NULL)) != NULL)
262 : {
263 2772 : if (strcmp(pszLine, "POLYGON DATA") == 0)
264 : {
265 42 : break;
266 : }
267 : }
268 42 : if (pszLine == NULL)
269 0 : bEOF = TRUE;
270 : }
271 42 : }
272 :
273 :
274 : /************************************************************************/
275 : /* ResetReading() */
276 : /************************************************************************/
277 :
278 32 : void OGRHTFSoundingLayer::ResetReading()
279 :
280 : {
281 32 : OGRHTFLayer::ResetReading();
282 32 : if (fpHTF)
283 : {
284 : const char* pszLine;
285 4064 : while( (pszLine = CPLReadLine2L(fpHTF, 1024, NULL)) != NULL)
286 : {
287 4032 : if (strcmp(pszLine, "SOUNDING DATA") == 0)
288 : {
289 32 : if (bHasFPK)
290 32 : pszLine = CPLReadLine2L(fpHTF, 1024, NULL);
291 32 : break;
292 : }
293 : }
294 32 : if (pszLine == NULL)
295 0 : bEOF = TRUE;
296 : }
297 32 : }
298 :
299 : /************************************************************************/
300 : /* GetNextFeature() */
301 : /************************************************************************/
302 :
303 73 : OGRFeature *OGRHTFLayer::GetNextFeature()
304 : {
305 : OGRFeature *poFeature;
306 :
307 73 : if (fpHTF == NULL || bEOF)
308 10 : return NULL;
309 :
310 141 : while(!bEOF)
311 : {
312 74 : poFeature = GetNextRawFeature();
313 74 : if (poFeature == NULL)
314 9 : return NULL;
315 :
316 65 : if((m_poFilterGeom == NULL
317 : || FilterGeometry( poFeature->GetGeometryRef() ) )
318 : && (m_poAttrQuery == NULL
319 : || m_poAttrQuery->Evaluate( poFeature )) )
320 : {
321 50 : return poFeature;
322 : }
323 : else
324 15 : delete poFeature;
325 : }
326 :
327 4 : return NULL;
328 : }
329 :
330 : /************************************************************************/
331 : /* GetNextRawFeature() */
332 : /************************************************************************/
333 :
334 38 : OGRFeature *OGRHTFPolygonLayer::GetNextRawFeature()
335 : {
336 38 : OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
337 :
338 : const char* pszLine;
339 :
340 38 : OGRLinearRing oLR;
341 38 : int bHastFirstCoord = FALSE;
342 38 : double dfFirstEasting = 0, dfFirstNorthing = 0;
343 38 : double dfIslandEasting = 0, dfIslandNorthing = 0;
344 38 : int bInIsland = FALSE;
345 76 : OGRPolygon* poPoly = new OGRPolygon();
346 :
347 541 : while( (pszLine = CPLReadLine2L(fpHTF, 1024, NULL)) != NULL)
348 : {
349 503 : if (pszLine[0] == ';')
350 : {
351 : /* comment */ ;
352 : }
353 503 : else if (pszLine[0] == 0)
354 : {
355 : /* end of polygon is marked by a blank line */
356 21 : break;
357 : }
358 482 : else if (strncmp(pszLine, "POLYGON DESCRIPTION: ",
359 : strlen("POLYGON DESCRIPTION: ")) == 0)
360 : {
361 38 : poFeature->SetField(0, pszLine + strlen("POLYGON DESCRIPTION: "));
362 : }
363 444 : else if (strncmp(pszLine, "POLYGON IDENTIFIER: ",
364 : strlen("POLYGON IDENTIFIER: ")) == 0)
365 : {
366 38 : poFeature->SetField(1, pszLine + strlen("POLYGON IDENTIFIER: "));
367 : }
368 406 : else if (strncmp(pszLine, "SEAFLOOR COVERAGE: ",
369 : strlen("SEAFLOOR COVERAGE:")) == 0)
370 : {
371 38 : const char* pszVal = pszLine + strlen("SEAFLOOR COVERAGE: ");
372 38 : if (*pszVal != '*')
373 0 : poFeature->SetField(2, pszVal);
374 : }
375 368 : else if (strncmp(pszLine, "POSITION ACCURACY: ",
376 : strlen("POSITION ACCURACY:")) == 0)
377 : {
378 38 : const char* pszVal = pszLine + strlen("POSITION ACCURACY: ");
379 38 : if (*pszVal != '*')
380 0 : poFeature->SetField(3, pszVal);
381 : }
382 330 : else if (strncmp(pszLine, "DEPTH ACCURACY: ",
383 : strlen("DEPTH ACCURACY:")) == 0)
384 : {
385 38 : const char* pszVal = pszLine + strlen("DEPTH ACCURACY: ");
386 38 : if (*pszVal != '*')
387 0 : poFeature->SetField(4, pszVal);
388 : }
389 292 : else if (strcmp(pszLine, "END OF POLYGON DATA") == 0)
390 : {
391 17 : bEOF = TRUE;
392 17 : break;
393 : }
394 : else
395 : {
396 275 : char** papszTokens = CSLTokenizeString(pszLine);
397 275 : if (CSLCount(papszTokens) == 4)
398 : {
399 275 : double dfEasting = atof(papszTokens[2]);
400 275 : double dfNorthing = atof(papszTokens[3]);
401 275 : if (!bHastFirstCoord)
402 : {
403 38 : bHastFirstCoord = TRUE;
404 38 : dfFirstEasting = dfEasting;
405 38 : dfFirstNorthing = dfNorthing;
406 38 : oLR.addPoint(dfEasting, dfNorthing);
407 : }
408 292 : else if (dfFirstEasting == dfEasting &&
409 : dfFirstNorthing == dfNorthing)
410 : {
411 55 : if (!bInIsland)
412 : {
413 38 : oLR.addPoint(dfEasting, dfNorthing);
414 38 : poPoly->addRing(&oLR);
415 38 : oLR.empty();
416 38 : bInIsland = TRUE;
417 : }
418 : }
419 182 : else if (bInIsland && oLR.getNumPoints() == 0)
420 : {
421 17 : dfIslandEasting = dfEasting;
422 17 : dfIslandNorthing = dfNorthing;
423 17 : oLR.addPoint(dfEasting, dfNorthing);
424 : }
425 182 : else if (bInIsland && dfIslandEasting == dfEasting &&
426 : dfIslandNorthing == dfNorthing)
427 : {
428 17 : oLR.addPoint(dfEasting, dfNorthing);
429 17 : poPoly->addRing(&oLR);
430 17 : oLR.empty();
431 : }
432 : else
433 : {
434 148 : oLR.addPoint(dfEasting, dfNorthing);
435 : }
436 : }
437 275 : CSLDestroy(papszTokens);
438 : }
439 : }
440 :
441 38 : if (pszLine == NULL)
442 0 : bEOF = TRUE;
443 :
444 38 : if (oLR.getNumPoints() >= 3)
445 : {
446 0 : oLR.closeRings();
447 0 : poPoly->addRing(&oLR);
448 : }
449 38 : poPoly->assignSpatialReference(poSRS);
450 38 : poFeature->SetGeometryDirectly(poPoly);
451 38 : poFeature->SetFID(nNextFID++);
452 :
453 38 : return poFeature;
454 : }
455 :
456 :
457 : /************************************************************************/
458 : /* GetNextRawFeature() */
459 : /************************************************************************/
460 :
461 36 : OGRFeature *OGRHTFSoundingLayer::GetNextRawFeature()
462 : {
463 : const char* pszLine;
464 :
465 36 : OGRLinearRing oLR;
466 :
467 36 : while( (pszLine = CPLReadLine2L(fpHTF, 1024, NULL)) != NULL)
468 : {
469 36 : if (pszLine[0] == ';')
470 : {
471 : /* comment */ ;
472 : }
473 36 : else if (pszLine[0] == 0)
474 : {
475 0 : bEOF = TRUE;
476 0 : return NULL;
477 : }
478 36 : else if (strcmp(pszLine, "END OF SOUNDING DATA") == 0)
479 : {
480 9 : bEOF = TRUE;
481 9 : return NULL;
482 : }
483 : else
484 27 : break;
485 : }
486 27 : if (pszLine == NULL)
487 : {
488 0 : bEOF = TRUE;
489 0 : return NULL;
490 : }
491 :
492 : int i;
493 27 : double dfEasting = 0, dfNorthing = 0;
494 27 : OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
495 27 : char* pszStr = (char*)pszLine;
496 621 : for(i=0;i<poFeatureDefn->GetFieldCount();i++)
497 : {
498 621 : if (!panFieldPresence[i])
499 81 : continue;
500 :
501 540 : char* pszSpace = strchr(pszStr, ' ');
502 540 : if (pszSpace)
503 513 : *pszSpace = '\0';
504 :
505 540 : if (strcmp(pszStr, "*") != 0)
506 540 : poFeature->SetField(i, pszStr);
507 540 : if (i == nEastingIndex)
508 27 : dfEasting = poFeature->GetFieldAsDouble(i);
509 513 : else if (i == nNorthingIndex)
510 27 : dfNorthing = poFeature->GetFieldAsDouble(i);
511 :
512 540 : if (pszSpace == NULL)
513 27 : break;
514 513 : pszStr = pszSpace + 1;
515 : }
516 27 : OGRPoint* poPoint = new OGRPoint(dfEasting, dfNorthing);
517 27 : poPoint->assignSpatialReference(poSRS);
518 27 : poFeature->SetGeometryDirectly(poPoint);
519 27 : poFeature->SetFID(nNextFID++);
520 27 : 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 8 : int OGRHTFLayer::TestCapability( const char * pszCap )
564 :
565 : {
566 8 : if (EQUAL(pszCap, OLCFastGetExtent))
567 0 : return bHasExtent;
568 :
569 8 : return FALSE;
570 : }
571 :
572 :
573 : /************************************************************************/
574 : /* TestCapability() */
575 : /************************************************************************/
576 :
577 4 : int OGRHTFSoundingLayer::TestCapability( const char * pszCap )
578 :
579 : {
580 4 : if (EQUAL(pszCap, OLCFastFeatureCount))
581 0 : return m_poFilterGeom == NULL && m_poAttrQuery == NULL && nTotalSoundings != 0;
582 :
583 4 : 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 19 : OGRFeature *OGRHTFMetadataLayer::GetNextFeature()
697 : {
698 19 : if (nNextFID == 1)
699 7 : return NULL;
700 :
701 12 : if((m_poFilterGeom == NULL
702 : || FilterGeometry( poFeature->GetGeometryRef() ) )
703 : && (m_poAttrQuery == NULL
704 : || m_poAttrQuery->Evaluate( poFeature )) )
705 : {
706 10 : nNextFID = 1;
707 10 : return poFeature->Clone();
708 : }
709 :
710 2 : return NULL;
711 : }
|