1 : /******************************************************************************
2 : * $Id: ogr_xplane_reader.cpp 14977 2008-07-19 13:17:25Z rouault $
3 : *
4 : * Project: X-Plane aeronautical data reader
5 : * Purpose: Definition of classes for OGR X-Plane aeronautical data driver.
6 : * Author: Even Rouault, even dot rouault at mines dash paris dot org
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2008, Even Rouault
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_xplane_reader.h"
31 :
32 : CPL_CVSID("$Id: ogr_xplane_reader.cpp 14977 2008-07-19 13:17:25Z rouault $");
33 :
34 : /***********************************************************************/
35 : /* OGRXPlaneReader() */
36 : /***********************************************************************/
37 :
38 4 : OGRXPlaneReader::OGRXPlaneReader()
39 : {
40 4 : papszTokens = NULL;
41 4 : fp = NULL;
42 4 : pszFilename = NULL;
43 4 : bEOF = FALSE;
44 4 : nLineNumber = 0;
45 4 : }
46 :
47 : /***********************************************************************/
48 : /* ~OGRXPlaneReader() */
49 : /***********************************************************************/
50 :
51 4 : OGRXPlaneReader::~OGRXPlaneReader()
52 : {
53 4 : CPLFree(pszFilename);
54 4 : pszFilename = NULL;
55 :
56 4 : CSLDestroy(papszTokens);
57 4 : papszTokens = NULL;
58 :
59 4 : if (fp != NULL)
60 4 : VSIFClose(fp);
61 4 : fp = NULL;
62 4 : }
63 :
64 : /************************************************************************/
65 : /* StartParsing() */
66 : /************************************************************************/
67 :
68 4 : int OGRXPlaneReader::StartParsing( const char * pszFilename )
69 : {
70 4 : fp = VSIFOpen( pszFilename, "rt" );
71 4 : if (fp == NULL)
72 0 : return FALSE;
73 :
74 4 : const char* pszLine = CPLReadLine(fp);
75 4 : if (!pszLine || (strcmp(pszLine, "I") != 0 &&
76 : strcmp(pszLine, "A") != 0))
77 : {
78 0 : VSIFClose(fp);
79 0 : fp = NULL;
80 0 : return FALSE;
81 : }
82 :
83 4 : pszLine = CPLReadLine(fp);
84 4 : if (!pszLine || IsRecognizedVersion(pszLine) == FALSE)
85 : {
86 0 : VSIFClose(fp);
87 0 : fp = NULL;
88 0 : return FALSE;
89 : }
90 :
91 4 : CPLFree(this->pszFilename);
92 4 : this->pszFilename = CPLStrdup(pszFilename);
93 :
94 4 : nLineNumber = 2;
95 4 : CPLDebug("XPlane", "Version/Copyright : %s", pszLine);
96 :
97 4 : Rewind();
98 :
99 4 : return TRUE;
100 : }
101 :
102 : /************************************************************************/
103 : /* Rewind() */
104 : /************************************************************************/
105 :
106 4 : void OGRXPlaneReader::Rewind()
107 : {
108 4 : if (fp != NULL)
109 : {
110 4 : VSIRewind(fp);
111 4 : CPLReadLine(fp);
112 4 : CPLReadLine(fp);
113 :
114 4 : nLineNumber = 2;
115 :
116 4 : CSLDestroy(papszTokens);
117 4 : papszTokens = NULL;
118 :
119 4 : bEOF = FALSE;
120 : }
121 4 : }
122 :
123 : /************************************************************************/
124 : /* GetNextFeature() */
125 : /************************************************************************/
126 :
127 0 : int OGRXPlaneReader::GetNextFeature()
128 : {
129 0 : if (fp == NULL || bEOF == TRUE || poInterestLayer == NULL)
130 0 : return FALSE;
131 :
132 0 : Read();
133 0 : return TRUE;
134 : }
135 :
136 : /************************************************************************/
137 : /* ReadWholeFile() */
138 : /************************************************************************/
139 :
140 4 : int OGRXPlaneReader::ReadWholeFile()
141 : {
142 4 : if (fp == NULL || bEOF == TRUE || nLineNumber != 2 || poInterestLayer != NULL)
143 0 : return FALSE;
144 :
145 4 : Read();
146 4 : return TRUE;
147 : }
148 :
149 :
150 : /***********************************************************************/
151 : /* assertMinCol() */
152 : /***********************************************************************/
153 :
154 2641 : int OGRXPlaneReader::assertMinCol(int nMinColNum)
155 : {
156 2641 : if (nTokens < nMinColNum)
157 : {
158 : CPLDebug("XPlane", "Line %d : not enough columns : %d. %d is the minimum required",
159 0 : nLineNumber, nTokens, nMinColNum);
160 0 : return FALSE;
161 : }
162 2641 : return TRUE;
163 : }
164 :
165 :
166 : /***********************************************************************/
167 : /* readDouble() */
168 : /***********************************************************************/
169 :
170 5306 : int OGRXPlaneReader::readDouble(double* pdfValue, int iToken, const char* pszTokenDesc)
171 : {
172 : char* pszNext;
173 5306 : *pdfValue = CPLStrtod(papszTokens[iToken], &pszNext);
174 5306 : if (*pszNext != '\0' )
175 : {
176 : CPLDebug("XPlane", "Line %d : invalid %s '%s'",
177 0 : nLineNumber, pszTokenDesc, papszTokens[iToken]);
178 0 : return FALSE;
179 : }
180 5306 : return TRUE;
181 : }
182 :
183 : /***********************************************************************/
184 : /* readDoubleWithBoundsAndConversion() */
185 : /***********************************************************************/
186 :
187 4243 : int OGRXPlaneReader::readDoubleWithBoundsAndConversion(
188 : double* pdfValue, int iToken, const char* pszTokenDesc,
189 : double dfFactor, double dfLowerBound, double dfUpperBound)
190 : {
191 4243 : int bRet = readDouble(pdfValue, iToken, pszTokenDesc);
192 4243 : if (bRet)
193 : {
194 4243 : *pdfValue *= dfFactor;
195 4243 : if (*pdfValue < dfLowerBound || *pdfValue > dfUpperBound)
196 : {
197 : CPLDebug("XPlane", "Line %d : %s '%s' out of bounds [%f, %f]",
198 : nLineNumber, pszTokenDesc, papszTokens[iToken],
199 1 : dfLowerBound / dfFactor, dfUpperBound / dfFactor);
200 1 : return FALSE;
201 : }
202 : }
203 4242 : return bRet;
204 : }
205 :
206 : /***********************************************************************/
207 : /* readDoubleWithBounds() */
208 : /***********************************************************************/
209 :
210 4207 : int OGRXPlaneReader::readDoubleWithBounds(
211 : double* pdfValue, int iToken, const char* pszTokenDesc,
212 : double dfLowerBound, double dfUpperBound)
213 : {
214 : return readDoubleWithBoundsAndConversion(pdfValue, iToken, pszTokenDesc,
215 4207 : 1., dfLowerBound, dfUpperBound);
216 : }
217 :
218 : /***********************************************************************/
219 : /* readStringUntilEnd() */
220 : /***********************************************************************/
221 :
222 280 : CPLString OGRXPlaneReader::readStringUntilEnd(int iFirstTokenIndice)
223 : {
224 280 : CPLString osResult;
225 280 : if (nTokens > iFirstTokenIndice)
226 : {
227 : int i;
228 280 : int nIDsToSum = nTokens - iFirstTokenIndice;
229 280 : const unsigned char* pszStr = (const unsigned char*)papszTokens[iFirstTokenIndice];
230 1592 : for(int j=0;pszStr[j];j++)
231 : {
232 2624 : if (pszStr[j] >= 32 && pszStr[j] <= 127)
233 1312 : osResult += pszStr[j];
234 : else
235 0 : CPLDebug("XPlane", "Line %d : string with non ASCII characters", nLineNumber);
236 : }
237 436 : for(i=1;i<nIDsToSum;i++)
238 : {
239 156 : osResult += " ";
240 156 : pszStr = (const unsigned char*)papszTokens[iFirstTokenIndice + i];
241 807 : for(int j=0;pszStr[j];j++)
242 : {
243 1302 : if (pszStr[j] >= 32 && pszStr[j] <= 127)
244 651 : osResult += pszStr[j];
245 : else
246 0 : CPLDebug("XPlane", "Line %d : string with non ASCII characters", nLineNumber);
247 : }
248 : }
249 : }
250 0 : return osResult;
251 : }
252 :
253 :
254 : /***********************************************************************/
255 : /* readLatLon() */
256 : /***********************************************************************/
257 :
258 1549 : int OGRXPlaneReader::readLatLon(double* pdfLat, double* pdfLon, int iToken)
259 : {
260 1549 : int bRet = readDoubleWithBounds(pdfLat, iToken, "latitude", -90., 90.);
261 1549 : bRet &= readDoubleWithBounds(pdfLon, iToken + 1, "longitude", -180., 180.);
262 1549 : return bRet;
263 : }
264 :
265 : /***********************************************************************/
266 : /* readTrueHeading() */
267 : /***********************************************************************/
268 :
269 604 : int OGRXPlaneReader::readTrueHeading(double* pdfTrueHeading, int iToken, const char* pszTokenDesc)
270 : {
271 604 : int bRet = readDoubleWithBounds(pdfTrueHeading, iToken, pszTokenDesc, -180., 360.);
272 604 : if (bRet)
273 : {
274 604 : if (*pdfTrueHeading < 0.)
275 0 : *pdfTrueHeading += 180.;
276 : }
277 604 : return bRet;
278 : }
279 :
280 :
281 :
282 : /***********************************************************************/
283 : /* OGRXPlaneEnumeration() */
284 : /***********************************************************************/
285 :
286 :
287 4180 : OGRXPlaneEnumeration::OGRXPlaneEnumeration(const char *pszEnumerationName,
288 : const sEnumerationElement* osElements,
289 : int nElements) :
290 : m_pszEnumerationName(pszEnumerationName),
291 : m_osElements(osElements),
292 4180 : m_nElements(nElements)
293 : {
294 4180 : }
295 :
296 : /***********************************************************************/
297 : /* GetText() */
298 : /***********************************************************************/
299 :
300 765 : const char* OGRXPlaneEnumeration::GetText(int eValue)
301 : {
302 : int i;
303 1605 : for(i=0;i<m_nElements;i++)
304 : {
305 1604 : if (m_osElements[i].eValue == eValue)
306 764 : return m_osElements[i].pszText;
307 : }
308 : CPLDebug("XPlane", "Unknown value (%d) for enumeration %s",
309 1 : eValue, m_pszEnumerationName);
310 1 : return NULL;
311 : }
312 :
313 : /***********************************************************************/
314 : /* GetValue() */
315 : /***********************************************************************/
316 :
317 0 : int OGRXPlaneEnumeration::GetValue(const char* pszText)
318 : {
319 : int i;
320 0 : if (pszText != NULL)
321 : {
322 0 : for(i=0;i<m_nElements;i++)
323 : {
324 0 : if (strcmp(m_osElements[i].pszText, pszText) == 0)
325 0 : return m_osElements[i].eValue;
326 : }
327 : }
328 : CPLDebug("XPlane", "Unknown text (%s) for enumeration %s",
329 0 : pszText, m_pszEnumerationName);
330 0 : return -1;
331 : }
|