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