1 : /******************************************************************************
2 : * $Id: ogropenairdatasource.cpp 20003 2010-07-10 19:46:28Z rouault $
3 : *
4 : * Project: OpenAir Translator
5 : * Purpose: Implements OGROpenAirDataSource 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_openair.h"
31 : #include "cpl_conv.h"
32 : #include "cpl_string.h"
33 :
34 : CPL_CVSID("$Id: ogropenairdatasource.cpp 20003 2010-07-10 19:46:28Z rouault $");
35 :
36 : /************************************************************************/
37 : /* OGROpenAirDataSource() */
38 : /************************************************************************/
39 :
40 11 : OGROpenAirDataSource::OGROpenAirDataSource()
41 :
42 : {
43 11 : papoLayers = NULL;
44 11 : nLayers = 0;
45 :
46 11 : pszName = NULL;
47 11 : }
48 :
49 : /************************************************************************/
50 : /* ~OGROpenAirDataSource() */
51 : /************************************************************************/
52 :
53 11 : OGROpenAirDataSource::~OGROpenAirDataSource()
54 :
55 : {
56 13 : for( int i = 0; i < nLayers; i++ )
57 2 : delete papoLayers[i];
58 11 : CPLFree( papoLayers );
59 :
60 11 : CPLFree( pszName );
61 11 : }
62 :
63 : /************************************************************************/
64 : /* TestCapability() */
65 : /************************************************************************/
66 :
67 0 : int OGROpenAirDataSource::TestCapability( const char * pszCap )
68 :
69 : {
70 0 : return FALSE;
71 : }
72 :
73 : /************************************************************************/
74 : /* GetLayer() */
75 : /************************************************************************/
76 :
77 3 : OGRLayer *OGROpenAirDataSource::GetLayer( int iLayer )
78 :
79 : {
80 3 : if( iLayer < 0 || iLayer >= nLayers )
81 0 : return NULL;
82 : else
83 3 : return papoLayers[iLayer];
84 : }
85 :
86 : /************************************************************************/
87 : /* Open() */
88 : /************************************************************************/
89 :
90 11 : int OGROpenAirDataSource::Open( const char * pszFilename, int bUpdateIn)
91 :
92 : {
93 11 : if (bUpdateIn)
94 : {
95 3 : return FALSE;
96 : }
97 :
98 8 : pszName = CPLStrdup( pszFilename );
99 :
100 : /* -------------------------------------------------------------------- */
101 : /* Determine what sort of object this is. */
102 : /* -------------------------------------------------------------------- */
103 : VSIStatBufL sStatBuf;
104 :
105 8 : if( VSIStatL( pszFilename, &sStatBuf ) != 0 &&
106 : VSI_ISREG(sStatBuf.st_mode) )
107 0 : return FALSE;
108 :
109 : // --------------------------------------------------------------------
110 : // Does this appear to be an openair file?
111 : // --------------------------------------------------------------------
112 :
113 8 : FILE* fp = VSIFOpenL(pszFilename, "rb");
114 8 : if (fp == NULL)
115 2 : return FALSE;
116 :
117 : char szBuffer[10000];
118 6 : int nbRead = (int)VSIFReadL(szBuffer, 1, sizeof(szBuffer) - 1, fp);
119 6 : szBuffer[nbRead] = '\0';
120 :
121 : int bIsOpenAir = (strstr(szBuffer, "\nAC ") != NULL &&
122 : strstr(szBuffer, "\nAN ") != NULL &&
123 : strstr(szBuffer, "\nAL ") != NULL &&
124 6 : strstr(szBuffer, "\nAH") != NULL);
125 :
126 6 : if (bIsOpenAir)
127 : {
128 1 : VSIFSeekL( fp, 0, SEEK_SET );
129 :
130 1 : FILE* fp2 = VSIFOpenL(pszFilename, "rb");
131 1 : if (fp2)
132 : {
133 1 : nLayers = 2;
134 1 : papoLayers = (OGRLayer**) CPLMalloc(2 * sizeof(OGRLayer*));
135 1 : papoLayers[0] = new OGROpenAirLayer(fp);
136 2 : papoLayers[1] = new OGROpenAirLabelLayer(fp2);
137 : }
138 : }
139 : else
140 5 : VSIFCloseL(fp);
141 :
142 6 : return bIsOpenAir;
143 : }
144 :
145 :
146 : /************************************************************************/
147 : /* GetLatLon() */
148 : /************************************************************************/
149 :
150 : enum { DEGREE, MINUTE, SECOND };
151 :
152 8 : int OGROpenAirGetLatLon(const char* pszStr, double& dfLat, double& dfLon)
153 : {
154 8 : dfLat = 0;
155 8 : dfLon = 0;
156 :
157 8 : int nCurInt = 0;
158 8 : double dfExp = 1.;
159 8 : int bHasExp = FALSE;
160 8 : int nCurPart = DEGREE;
161 8 : double dfDegree = 0, dfMinute = 0, dfSecond = 0;
162 : char c;
163 8 : int bHasLat = FALSE, bHasLon = FALSE;
164 126 : while((c = *pszStr) != 0)
165 : {
166 178 : if (c >= '0' && c <= '9')
167 : {
168 60 : nCurInt = nCurInt * 10 + c - '0';
169 60 : if (bHasExp)
170 8 : dfExp *= 10;
171 : }
172 58 : else if (c == '.')
173 : {
174 4 : bHasExp = TRUE;
175 : }
176 54 : else if (c == ':')
177 : {
178 14 : double dfVal = nCurInt / dfExp;
179 14 : if (nCurPart == DEGREE)
180 12 : dfDegree = dfVal;
181 2 : else if (nCurPart == MINUTE)
182 2 : dfMinute = dfVal;
183 0 : else if (nCurPart == SECOND)
184 0 : dfSecond = dfVal;
185 14 : nCurPart ++;
186 14 : nCurInt = 0;
187 14 : dfExp = 1.;
188 14 : bHasExp = FALSE;
189 : }
190 40 : else if (c == ' ')
191 : {
192 :
193 : }
194 24 : else if (c == 'N' || c == 'S')
195 : {
196 8 : double dfVal = nCurInt / dfExp;
197 8 : if (nCurPart == DEGREE)
198 2 : dfDegree = dfVal;
199 6 : else if (nCurPart == MINUTE)
200 4 : dfMinute = dfVal;
201 2 : else if (nCurPart == SECOND)
202 2 : dfSecond = dfVal;
203 :
204 8 : dfLat = dfDegree + dfMinute / 60 + dfSecond / 3600;
205 8 : if (c == 'S')
206 0 : dfLat = -dfLat;
207 8 : nCurInt = 0;
208 8 : dfExp = 1.;
209 8 : bHasExp = FALSE;
210 8 : nCurPart = DEGREE;
211 8 : bHasLat = TRUE;
212 : }
213 8 : else if (c == 'E' || c == 'W')
214 : {
215 8 : double dfVal = nCurInt / dfExp;
216 8 : if (nCurPart == DEGREE)
217 2 : dfDegree = dfVal;
218 6 : else if (nCurPart == MINUTE)
219 6 : dfMinute = dfVal;
220 0 : else if (nCurPart == SECOND)
221 0 : dfSecond = dfVal;
222 :
223 8 : dfLon = dfDegree + dfMinute / 60 + dfSecond / 3600;
224 8 : if (c == 'W')
225 0 : dfLon = -dfLon;
226 8 : bHasLon = TRUE;
227 8 : break;
228 : }
229 :
230 110 : pszStr++;
231 : }
232 :
233 8 : return bHasLat && bHasLon;
234 : }
|