1 : /******************************************************************************
2 : * $Id: ograeronavfaalayer.cpp 21376 2011-01-02 18:28:40Z rouault $
3 : *
4 : * Project: AeronavFAA Translator
5 : * Purpose: Implements OGRAeronavFAALayer 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_aeronavfaa.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: ograeronavfaalayer.cpp 21376 2011-01-02 18:28:40Z rouault $");
37 :
38 : /************************************************************************/
39 : /* OGRAeronavFAALayer() */
40 : /************************************************************************/
41 :
42 0 : OGRAeronavFAALayer::OGRAeronavFAALayer( VSILFILE* fp, const char* pszLayerName )
43 :
44 : {
45 0 : fpAeronavFAA = fp;
46 0 : nNextFID = 0;
47 0 : bEOF = FALSE;
48 :
49 0 : psRecordDesc = NULL;
50 :
51 0 : poSRS = new OGRSpatialReference(SRS_WKT_WGS84);
52 :
53 0 : poFeatureDefn = new OGRFeatureDefn( pszLayerName );
54 0 : poFeatureDefn->Reference();
55 0 : }
56 :
57 : /************************************************************************/
58 : /* ~OGRAeronavFAALayer() */
59 : /************************************************************************/
60 :
61 0 : OGRAeronavFAALayer::~OGRAeronavFAALayer()
62 :
63 : {
64 0 : if( poSRS != NULL )
65 0 : poSRS->Release();
66 :
67 0 : poFeatureDefn->Release();
68 :
69 0 : VSIFCloseL( fpAeronavFAA );
70 0 : }
71 :
72 :
73 : /************************************************************************/
74 : /* ResetReading() */
75 : /************************************************************************/
76 :
77 0 : void OGRAeronavFAALayer::ResetReading()
78 :
79 : {
80 0 : nNextFID = 0;
81 0 : bEOF = FALSE;
82 0 : VSIFSeekL( fpAeronavFAA, 0, SEEK_SET );
83 0 : }
84 :
85 :
86 : /************************************************************************/
87 : /* GetNextFeature() */
88 : /************************************************************************/
89 :
90 0 : OGRFeature *OGRAeronavFAALayer::GetNextFeature()
91 : {
92 : OGRFeature *poFeature;
93 :
94 0 : while(TRUE)
95 : {
96 0 : if (bEOF)
97 0 : return NULL;
98 :
99 0 : poFeature = GetNextRawFeature();
100 0 : if (poFeature == NULL)
101 0 : return NULL;
102 :
103 0 : if((m_poFilterGeom == NULL
104 : || FilterGeometry( poFeature->GetGeometryRef() ) )
105 : && (m_poAttrQuery == NULL
106 : || m_poAttrQuery->Evaluate( poFeature )) )
107 : {
108 0 : return poFeature;
109 : }
110 : else
111 0 : delete poFeature;
112 : }
113 : }
114 :
115 : /************************************************************************/
116 : /* TestCapability() */
117 : /************************************************************************/
118 :
119 0 : int OGRAeronavFAALayer::TestCapability( const char * pszCap )
120 :
121 : {
122 0 : return FALSE;
123 : }
124 :
125 :
126 :
127 : static const RecordFieldDesc DOFFields [] =
128 : {
129 : { "ORS_CODE", 1, 2, OFTString },
130 : { "NUMBER" , 4, 9, OFTInteger, },
131 : { "VERIF_STATUS", 11, 11, OFTString },
132 : { "COUNTRY", 13, 14, OFTString },
133 : { "STATE", 16, 17, OFTString },
134 : { "CITY", 19, 34, OFTString },
135 : { "TYPE", 63, 74, OFTString },
136 : { "QUANTITY", 76, 76, OFTInteger },
137 : { "AGL_HT", 78, 82, OFTInteger },
138 : { "AMSL_HT", 84, 88, OFTInteger },
139 : { "LIGHTING", 90, 90, OFTString },
140 : { "HOR_ACC", 92, 92, OFTString },
141 : { "VER_ACC", 94, 94, OFTString },
142 : { "MARK_INDIC", 96, 96, OFTString },
143 : { "FAA_STUDY_NUMBER", 98, 111, OFTString },
144 : { "ACTION", 113, 113, OFTString },
145 : { "DATE", 115, 121, OFTString }
146 : };
147 :
148 : static const RecordDesc DOF = { sizeof(DOFFields)/sizeof(DOFFields[0]), DOFFields, 36, 49 };
149 :
150 :
151 : /************************************************************************/
152 : /* OGRAeronavFAADOFLayer() */
153 : /************************************************************************/
154 :
155 0 : OGRAeronavFAADOFLayer::OGRAeronavFAADOFLayer( VSILFILE* fp, const char* pszLayerName ) :
156 0 : OGRAeronavFAALayer(fp, pszLayerName)
157 : {
158 0 : poFeatureDefn->SetGeomType( wkbPoint );
159 :
160 0 : psRecordDesc = &DOF;
161 :
162 : int i;
163 0 : for(i=0;i<psRecordDesc->nFields;i++)
164 : {
165 0 : OGRFieldDefn oField( psRecordDesc->pasFields[i].pszFieldName, psRecordDesc->pasFields[i].eType );
166 0 : oField.SetWidth(psRecordDesc->pasFields[i].nLastCol - psRecordDesc->pasFields[i].nStartCol + 1);
167 0 : poFeatureDefn->AddFieldDefn( &oField );
168 : }
169 0 : }
170 :
171 : /************************************************************************/
172 : /* GetLatLon() */
173 : /************************************************************************/
174 :
175 0 : static int GetLatLon(const char* pszLat,
176 : char chLatHemisphere,
177 : const char* pszLon,
178 : char chLonHemisphere,
179 : int nSecLen,
180 : double& dfLat, double& dfLon)
181 : {
182 : char szDeg[4], szMin[3], szSec[10];
183 0 : szDeg[0] = pszLat[0];
184 0 : szDeg[1] = pszLat[1];
185 0 : szDeg[2] = 0;
186 0 : szMin[0] = pszLat[3];
187 0 : szMin[1] = pszLat[4];
188 0 : szMin[2] = 0;
189 0 : memcpy(szSec, pszLat + 6, MAX((int)sizeof(szSec) - 1, nSecLen));
190 0 : szSec[MAX((int)sizeof(szSec) - 1, nSecLen)] = 0;
191 :
192 0 : dfLat = atoi(szDeg) + atoi(szMin) / 60. + atof(szSec) / 3600.;
193 0 : if (chLatHemisphere == 'S')
194 0 : dfLat = -dfLat;
195 :
196 0 : szDeg[0] = pszLon[0];
197 0 : szDeg[1] = pszLon[1];
198 0 : szDeg[2] = pszLon[2];
199 0 : szDeg[3] = 0;
200 0 : szMin[0] = pszLon[4];
201 0 : szMin[1] = pszLon[5];
202 0 : szMin[2] = 0;
203 0 : memcpy(szSec, pszLon + 7, MAX((int)sizeof(szSec) - 1, nSecLen));
204 0 : szSec[MAX((int)sizeof(szSec) - 1, nSecLen)] = 0;
205 :
206 0 : dfLon = atoi(szDeg) + atoi(szMin) / 60. + atof(szSec) / 3600.;
207 0 : if (chLonHemisphere == ' ' || chLonHemisphere == 'W')
208 0 : dfLon = -dfLon;
209 :
210 0 : return TRUE;
211 : }
212 :
213 :
214 : /************************************************************************/
215 : /* GetLatLon() */
216 : /************************************************************************/
217 :
218 0 : int OGRAeronavFAADOFLayer::GetLatLon(const char* pszLat, const char* pszLon, double& dfLat, double& dfLon)
219 : {
220 0 : return ::GetLatLon(pszLat, pszLat[11], pszLon, pszLon[12], 5, dfLat, dfLon);
221 : }
222 :
223 : /************************************************************************/
224 : /* GetNextRawFeature() */
225 : /************************************************************************/
226 :
227 0 : OGRFeature *OGRAeronavFAADOFLayer::GetNextRawFeature()
228 : {
229 : const char* pszLine;
230 : char szBuffer[130];
231 :
232 0 : while(TRUE)
233 : {
234 0 : pszLine = CPLReadLine2L(fpAeronavFAA, 130, NULL);
235 0 : if (pszLine == NULL)
236 : {
237 0 : bEOF = TRUE;
238 0 : return NULL;
239 : }
240 0 : if (strlen(pszLine) != 128)
241 0 : continue;
242 0 : if ( ! (pszLine[psRecordDesc->nLatStartCol-1] >= '0' &&
243 0 : pszLine[psRecordDesc->nLatStartCol-1] <= '9') )
244 0 : continue;
245 :
246 0 : OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
247 0 : poFeature->SetFID(nNextFID ++);
248 :
249 : int i;
250 0 : for(i=0;i<psRecordDesc->nFields;i++)
251 : {
252 0 : int nWidth = psRecordDesc->pasFields[i].nLastCol - psRecordDesc->pasFields[i].nStartCol + 1;
253 0 : strncpy(szBuffer, pszLine + psRecordDesc->pasFields[i].nStartCol - 1, nWidth);
254 0 : szBuffer[nWidth] = 0;
255 0 : while(nWidth > 0 && szBuffer[nWidth - 1] == ' ')
256 : {
257 0 : szBuffer[nWidth - 1] = 0;
258 0 : nWidth --;
259 : }
260 0 : if (nWidth != 0)
261 0 : poFeature->SetField(i, szBuffer);
262 : }
263 :
264 : double dfLat, dfLon;
265 : GetLatLon(pszLine + psRecordDesc->nLatStartCol - 1,
266 : pszLine + psRecordDesc->nLonStartCol - 1,
267 : dfLat,
268 0 : dfLon);
269 :
270 0 : OGRGeometry* poGeom = new OGRPoint(dfLon, dfLat);
271 0 : poGeom->assignSpatialReference(poSRS);
272 0 : poFeature->SetGeometryDirectly( poGeom );
273 0 : return poFeature;
274 : }
275 : }
276 :
277 :
278 :
279 : static const RecordFieldDesc NAVAIDFields [] =
280 : {
281 : { "ID", 2, 6, OFTString },
282 : { "NAVAID_TYPE", 8, 9, OFTString },
283 : { "STATUS" , 11, 11, OFTString },
284 : { "NAME" , 44, 68, OFTString },
285 : { "CAN_ARTCC" , 69, 69, OFTString },
286 : { "SERVICE" , 76, 76, OFTString },
287 : { "FREQUENCY" , 78, 84, OFTString },
288 : { "CHANNEL" , 86, 89, OFTString },
289 : { "ELEVATION" , 92, 96, OFTString },
290 : { "MAG_VAR" , 98, 100, OFTString },
291 : { "ARTCC" , 102, 104, OFTString },
292 : { "STATE" , 106, 107, OFTString },
293 : };
294 :
295 : static const RecordDesc NAVAID = { sizeof(NAVAIDFields)/sizeof(NAVAIDFields[0]), NAVAIDFields, 17, 30 };
296 :
297 :
298 : /************************************************************************/
299 : /* OGRAeronavFAANAVAIDLayer() */
300 : /************************************************************************/
301 :
302 0 : OGRAeronavFAANAVAIDLayer::OGRAeronavFAANAVAIDLayer( VSILFILE* fp, const char* pszLayerName ) :
303 0 : OGRAeronavFAALayer(fp, pszLayerName)
304 : {
305 0 : poFeatureDefn->SetGeomType( wkbPoint );
306 :
307 0 : psRecordDesc = &NAVAID;
308 :
309 : int i;
310 0 : for(i=0;i<psRecordDesc->nFields;i++)
311 : {
312 0 : OGRFieldDefn oField( psRecordDesc->pasFields[i].pszFieldName, psRecordDesc->pasFields[i].eType );
313 0 : oField.SetWidth(psRecordDesc->pasFields[i].nLastCol - psRecordDesc->pasFields[i].nStartCol + 1);
314 0 : poFeatureDefn->AddFieldDefn( &oField );
315 : }
316 0 : }
317 :
318 :
319 : /************************************************************************/
320 : /* GetLatLon() */
321 : /************************************************************************/
322 :
323 0 : int OGRAeronavFAANAVAIDLayer::GetLatLon(const char* pszLat, const char* pszLon, double& dfLat, double& dfLon)
324 : {
325 0 : return ::GetLatLon(pszLat + 2, pszLat[0], pszLon + 2, pszLon[0], 4, dfLat, dfLon);
326 : }
327 :
328 : /************************************************************************/
329 : /* GetNextRawFeature() */
330 : /************************************************************************/
331 :
332 0 : OGRFeature *OGRAeronavFAANAVAIDLayer::GetNextRawFeature()
333 : {
334 : const char* pszLine;
335 : char szBuffer[134];
336 :
337 0 : while(TRUE)
338 : {
339 0 : pszLine = CPLReadLine2L(fpAeronavFAA, 134, NULL);
340 0 : if (pszLine == NULL)
341 : {
342 0 : bEOF = TRUE;
343 0 : return NULL;
344 : }
345 0 : if (strlen(pszLine) != 132)
346 0 : continue;
347 0 : if ( !(pszLine[psRecordDesc->nLatStartCol-1] == 'N' ||
348 0 : pszLine[psRecordDesc->nLatStartCol-1] == 'S') )
349 0 : continue;
350 0 : if ( !(pszLine[psRecordDesc->nLonStartCol-1] == 'E' ||
351 0 : pszLine[psRecordDesc->nLonStartCol-1] == 'W') )
352 0 : continue;
353 :
354 0 : OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
355 0 : poFeature->SetFID(nNextFID ++);
356 :
357 : int i;
358 0 : for(i=0;i<psRecordDesc->nFields;i++)
359 : {
360 0 : int nWidth = psRecordDesc->pasFields[i].nLastCol - psRecordDesc->pasFields[i].nStartCol + 1;
361 0 : strncpy(szBuffer, pszLine + psRecordDesc->pasFields[i].nStartCol - 1, nWidth);
362 0 : szBuffer[nWidth] = 0;
363 0 : while(nWidth > 0 && szBuffer[nWidth - 1] == ' ')
364 : {
365 0 : szBuffer[nWidth - 1] = 0;
366 0 : nWidth --;
367 : }
368 0 : if (nWidth != 0)
369 0 : poFeature->SetField(i, szBuffer);
370 : }
371 :
372 : double dfLat, dfLon;
373 : GetLatLon(pszLine + psRecordDesc->nLatStartCol - 1,
374 : pszLine + psRecordDesc->nLonStartCol - 1,
375 : dfLat,
376 0 : dfLon);
377 :
378 0 : OGRGeometry* poGeom = new OGRPoint(dfLon, dfLat);
379 0 : poGeom->assignSpatialReference(poSRS);
380 0 : poFeature->SetGeometryDirectly( poGeom );
381 0 : return poFeature;
382 : }
383 : }
384 :
385 :
386 :
387 : /************************************************************************/
388 : /* OGRAeronavFAARouteLayer() */
389 : /************************************************************************/
390 :
391 0 : OGRAeronavFAARouteLayer::OGRAeronavFAARouteLayer( VSILFILE* fp, const char* pszLayerName, int bIsDPOrSTARS ) :
392 0 : OGRAeronavFAALayer(fp, pszLayerName)
393 : {
394 0 : this->bIsDPOrSTARS = bIsDPOrSTARS;
395 :
396 0 : poFeatureDefn->SetGeomType( wkbLineString );
397 :
398 0 : if (bIsDPOrSTARS)
399 : {
400 : {
401 0 : OGRFieldDefn oField( "APT_NAME", OFTString );
402 0 : poFeatureDefn->AddFieldDefn( &oField );
403 : }
404 :
405 : {
406 0 : OGRFieldDefn oField( "STATE", OFTString );
407 0 : poFeatureDefn->AddFieldDefn( &oField );
408 : }
409 : }
410 :
411 : {
412 0 : OGRFieldDefn oField( "NAME", OFTString );
413 0 : poFeatureDefn->AddFieldDefn( &oField );
414 : }
415 :
416 0 : }
417 :
418 :
419 : /************************************************************************/
420 : /* GetLatLon() */
421 : /************************************************************************/
422 :
423 0 : int OGRAeronavFAARouteLayer::GetLatLon(const char* pszLat, const char* pszLon, double& dfLat, double& dfLon)
424 : {
425 0 : return ::GetLatLon(pszLat, pszLat[10], pszLon, pszLon[11], 4, dfLat, dfLon);
426 : }
427 :
428 : /************************************************************************/
429 : /* GetNextRawFeature() */
430 : /************************************************************************/
431 :
432 0 : OGRFeature *OGRAeronavFAARouteLayer::GetNextRawFeature()
433 : {
434 : const char* pszLine;
435 0 : OGRFeature* poFeature = NULL;
436 0 : OGRLineString* poLS = NULL;
437 :
438 0 : while(TRUE)
439 : {
440 0 : if (osLastReadLine.size() != 0)
441 0 : pszLine = osLastReadLine.c_str();
442 : else
443 0 : pszLine = CPLReadLine2L(fpAeronavFAA, 87, NULL);
444 0 : osLastReadLine = "";
445 :
446 0 : if (pszLine == NULL)
447 : {
448 0 : bEOF = TRUE;
449 0 : return poFeature;
450 : }
451 0 : if (strlen(pszLine) != 85)
452 0 : continue;
453 :
454 0 : if (bIsDPOrSTARS && strncmp(pszLine, "===", 3) == 0 && pszLine[3] != '=')
455 : {
456 0 : osAPTName = pszLine + 3;
457 0 : const char* pszComma = strchr(pszLine + 3, ',');
458 0 : if (pszComma)
459 : {
460 0 : osAPTName.resize(pszComma - (pszLine + 3));
461 0 : osStateName = pszComma + 2;
462 0 : const char* pszEqual = strchr(pszComma + 2, '=');
463 0 : if (pszEqual)
464 0 : osStateName.resize(pszEqual - (pszComma + 2));
465 : }
466 : else
467 : {
468 0 : const char* pszEqual = strchr(pszLine + 3, '=');
469 0 : if (pszEqual)
470 0 : osAPTName.resize(pszEqual - (pszLine + 3));
471 0 : osStateName = "";
472 : }
473 : }
474 :
475 0 : if (strncmp(pszLine + 2, "FACILITY OR", strlen("FACILITY OR")) == 0)
476 0 : continue;
477 0 : if (strncmp(pszLine + 2, "INTERSECTION", strlen("INTERSECTION")) == 0)
478 0 : continue;
479 :
480 0 : if (strcmp(pszLine, "================================DELETIONS LIST=================================198326") == 0)
481 : {
482 0 : bEOF = TRUE;
483 0 : return poFeature;
484 : }
485 :
486 0 : if (poFeature == NULL)
487 : {
488 0 : if (pszLine[2] == ' ' || pszLine[2] == '-' )
489 : {
490 0 : continue;
491 : }
492 :
493 0 : if (strncmp(pszLine + 29, " ", 20) == 0 ||
494 : strchr(pszLine, '(') != NULL)
495 : {
496 0 : CPLString osName = pszLine + 2;
497 0 : osName.resize(60);
498 0 : while(osName.size() > 0 && osName[osName.size()-1] == ' ')
499 : {
500 0 : osName.resize(osName.size()-1);
501 : }
502 :
503 0 : if (strcmp(osName.c_str(), "(DELETIONS LIST)") == 0)
504 : {
505 0 : bEOF = TRUE;
506 0 : return NULL;
507 : }
508 :
509 0 : poFeature = new OGRFeature(poFeatureDefn);
510 0 : poFeature->SetFID(nNextFID ++);
511 0 : if (bIsDPOrSTARS)
512 : {
513 0 : poFeature->SetField(0, osAPTName);
514 0 : poFeature->SetField(1, osStateName);
515 0 : poFeature->SetField(2, osName);
516 : }
517 : else
518 0 : poFeature->SetField(0, osName);
519 0 : poLS = new OGRLineString();
520 0 : poFeature->SetGeometryDirectly(poLS);
521 : }
522 0 : continue;
523 : }
524 :
525 0 : if (strncmp(pszLine, " 0", 85) == 0)
526 : {
527 0 : if (poLS->getNumPoints() == 0)
528 0 : continue;
529 : else
530 0 : return poFeature;
531 : }
532 :
533 0 : if (pszLine[29 - 1] == ' ' && pszLine[42 - 1] == ' ')
534 0 : continue;
535 0 : if (strstr(pszLine, "RWY") || strchr(pszLine, '('))
536 : {
537 0 : osLastReadLine = pszLine;
538 0 : return poFeature;
539 : }
540 :
541 : double dfLat, dfLon;
542 : GetLatLon(pszLine + 29 - 1,
543 : pszLine + 42 - 1,
544 : dfLat,
545 0 : dfLon);
546 0 : poLS->addPoint(dfLon, dfLat);
547 : }
548 : }
549 :
550 : /************************************************************************/
551 : /* ResetReading() */
552 : /************************************************************************/
553 :
554 0 : void OGRAeronavFAARouteLayer::ResetReading()
555 :
556 : {
557 0 : OGRAeronavFAALayer::ResetReading();
558 0 : osLastReadLine = "";
559 0 : osAPTName = "";
560 0 : osStateName = "";
561 0 : }
562 :
563 :
564 : static const RecordFieldDesc IAPFields [] =
565 : {
566 : { "LOC_ID", 4, 8, OFTString },
567 : { "MAG_VAR" , 52, 54, OFTInteger, },
568 : { "ELEVATION", 62, 67, OFTInteger },
569 : { "TYPE", 71, 77, OFTString },
570 :
571 : };
572 :
573 : static const RecordDesc IAP = { sizeof(IAPFields)/sizeof(IAPFields[0]), IAPFields, -1, -1 };
574 :
575 :
576 : /************************************************************************/
577 : /* OGRAeronavFAAIAPLayer() */
578 : /************************************************************************/
579 :
580 0 : OGRAeronavFAAIAPLayer::OGRAeronavFAAIAPLayer( VSILFILE* fp, const char* pszLayerName ) :
581 0 : OGRAeronavFAALayer(fp, pszLayerName)
582 : {
583 0 : poFeatureDefn->SetGeomType( wkbPoint );
584 :
585 : {
586 0 : OGRFieldDefn oField( "CITY", OFTString );
587 0 : poFeatureDefn->AddFieldDefn( &oField );
588 : }
589 : {
590 0 : OGRFieldDefn oField( "STATE", OFTString );
591 0 : poFeatureDefn->AddFieldDefn( &oField );
592 : }
593 : {
594 0 : OGRFieldDefn oField( "APT_NAME", OFTString );
595 0 : poFeatureDefn->AddFieldDefn( &oField );
596 : }
597 : {
598 0 : OGRFieldDefn oField( "APT_CODE", OFTString );
599 0 : poFeatureDefn->AddFieldDefn( &oField );
600 : }
601 :
602 :
603 0 : psRecordDesc = &IAP;
604 :
605 : int i;
606 0 : for(i=0;i<psRecordDesc->nFields;i++)
607 : {
608 0 : OGRFieldDefn oField( psRecordDesc->pasFields[i].pszFieldName, psRecordDesc->pasFields[i].eType );
609 0 : oField.SetWidth(psRecordDesc->pasFields[i].nLastCol - psRecordDesc->pasFields[i].nStartCol + 1);
610 0 : poFeatureDefn->AddFieldDefn( &oField );
611 : }
612 :
613 0 : }
614 :
615 :
616 : /************************************************************************/
617 : /* GetLatLon() */
618 : /************************************************************************/
619 :
620 0 : int OGRAeronavFAAIAPLayer::GetLatLon(const char* pszLat, const char* pszLon, double& dfLat, double& dfLon)
621 : {
622 0 : return ::GetLatLon(pszLat, pszLat[11], pszLon, pszLon[12], 4, dfLat, dfLon);
623 : }
624 :
625 : /************************************************************************/
626 : /* GetNextRawFeature() */
627 : /************************************************************************/
628 :
629 0 : OGRFeature *OGRAeronavFAAIAPLayer::GetNextRawFeature()
630 : {
631 : const char* pszLine;
632 : char szBuffer[87];
633 0 : int nCountUnderscoreLines = 0;
634 :
635 0 : while(TRUE)
636 : {
637 0 : pszLine = CPLReadLine2L(fpAeronavFAA, 87, NULL);
638 0 : if (pszLine == NULL)
639 : {
640 0 : bEOF = TRUE;
641 0 : return NULL;
642 : }
643 0 : if (strlen(pszLine) != 85)
644 0 : continue;
645 :
646 0 : if (strncmp(pszLine, "DELETIONS", strlen("DELETIONS")) == 0)
647 : {
648 0 : bEOF = TRUE;
649 0 : return NULL;
650 : }
651 :
652 0 : if (nNextFID == 0 && nCountUnderscoreLines < 2)
653 : {
654 0 : if (strcmp(pszLine, "_____________________________________________________________________________ 285285") == 0)
655 0 : nCountUnderscoreLines ++;
656 0 : continue;
657 : }
658 :
659 0 : if (pszLine[1] != ' ')
660 0 : continue;
661 0 : if (strncmp(pszLine, " ", 79) == 0)
662 0 : continue;
663 0 : if (strstr(pszLine, "NAVIGATIONAL AIDS") != NULL)
664 0 : continue;
665 0 : if (strstr(pszLine, "TERMINAL INSTRUMENT FIXES") != NULL)
666 0 : continue;
667 :
668 0 : const char* pszComma = strchr(pszLine, ',');
669 0 : if (pszComma)
670 : {
671 0 : const char* pszBegin = pszLine;
672 0 : while( *pszBegin == ' ')
673 0 : pszBegin ++;
674 0 : osCityName = pszBegin;
675 0 : osCityName.resize(pszComma - pszBegin);
676 0 : osStateName = pszComma + 2;
677 0 : osStateName.resize(78 - (pszComma + 2 - pszLine));
678 0 : while(osStateName.size() > 0 && osStateName[osStateName.size()-1] == ' ')
679 : {
680 0 : osStateName.resize(osStateName.size()-1);
681 : }
682 0 : osAPTName = "";
683 0 : osAPTId = "";
684 0 : continue;
685 : }
686 :
687 0 : const char* pszLeftParenthesis = strstr(pszLine, " (");
688 0 : if (pszLeftParenthesis)
689 : {
690 0 : const char* pszRightParenthesis = strchr(pszLeftParenthesis, ')');
691 0 : if (pszRightParenthesis)
692 : {
693 0 : const char* pszBegin = pszLine;
694 0 : while( *pszBegin == ' ')
695 0 : pszBegin ++;
696 0 : osAPTName = pszBegin;
697 0 : osAPTName.resize(pszLeftParenthesis - pszBegin);
698 0 : osAPTId = pszLeftParenthesis + 2;
699 0 : osAPTId.resize(pszRightParenthesis - (pszLeftParenthesis + 2));
700 : }
701 0 : continue;
702 : }
703 :
704 0 : OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
705 0 : poFeature->SetFID(nNextFID ++);
706 :
707 0 : poFeature->SetField(0, osCityName);
708 0 : poFeature->SetField(1, osStateName);
709 0 : poFeature->SetField(2, osAPTName);
710 0 : poFeature->SetField(3, osAPTId);
711 :
712 : int i;
713 0 : for(i=0;i<psRecordDesc->nFields;i++)
714 : {
715 0 : int nWidth = psRecordDesc->pasFields[i].nLastCol - psRecordDesc->pasFields[i].nStartCol + 1;
716 0 : strncpy(szBuffer, pszLine + psRecordDesc->pasFields[i].nStartCol - 1, nWidth);
717 0 : szBuffer[nWidth] = 0;
718 0 : while(nWidth > 0 && szBuffer[nWidth - 1] == ' ')
719 : {
720 0 : szBuffer[nWidth - 1] = 0;
721 0 : nWidth --;
722 : }
723 0 : if (nWidth != 0)
724 0 : poFeature->SetField(i + 4, szBuffer);
725 : }
726 :
727 : double dfLat, dfLon;
728 : GetLatLon(pszLine + 16 - 1,
729 0 : (pszLine[34 - 1] != ' ') ? pszLine + 34 - 1 : pszLine + 35 - 1,
730 : dfLat,
731 0 : dfLon);
732 :
733 0 : OGRGeometry* poGeom = new OGRPoint(dfLon, dfLat);
734 0 : poGeom->assignSpatialReference(poSRS);
735 0 : poFeature->SetGeometryDirectly( poGeom );
736 0 : return poFeature;
737 : }
738 : }
739 :
740 : /************************************************************************/
741 : /* ResetReading() */
742 : /************************************************************************/
743 :
744 0 : void OGRAeronavFAAIAPLayer::ResetReading()
745 :
746 : {
747 0 : OGRAeronavFAALayer::ResetReading();
748 0 : osCityName = "";
749 0 : osStateName = "";
750 0 : osAPTName = "";
751 0 : osAPTId = "";
752 0 : }
753 :
|