1 : /******************************************************************************
2 : * $Id: ogrxplanelayer.cpp
3 : *
4 : * Project: XPlane Translator
5 : * Purpose: Implements OGRXPlaneLayer class.
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.h"
31 : #include "ogr_xplane_geo_utils.h"
32 : #include "ogr_xplane_reader.h"
33 :
34 : CPL_CVSID("$Id: ogrxplanelayer.cpp 18548 2010-01-14 22:01:35Z rouault $");
35 :
36 : /************************************************************************/
37 : /* OGRXPlaneLayer() */
38 : /************************************************************************/
39 :
40 46 : OGRXPlaneLayer::OGRXPlaneLayer( const char* pszLayerName )
41 :
42 : {
43 46 : nFID = 0;
44 46 : nFeatureArraySize = 0;
45 46 : nFeatureArrayMaxSize = 0;
46 46 : nFeatureArrayIndex = 0;
47 46 : papoFeatures = NULL;
48 46 : poDS = NULL;
49 :
50 46 : poFeatureDefn = new OGRFeatureDefn( pszLayerName );
51 46 : poFeatureDefn->Reference();
52 :
53 46 : poSRS = new OGRSpatialReference();
54 46 : poSRS->SetWellKnownGeogCS("WGS84");
55 :
56 46 : poReader = NULL;
57 46 : }
58 :
59 :
60 : /************************************************************************/
61 : /* ~OGRXPlaneLayer() */
62 : /************************************************************************/
63 :
64 46 : OGRXPlaneLayer::~OGRXPlaneLayer()
65 :
66 : {
67 46 : poFeatureDefn->Release();
68 :
69 46 : poSRS->Release();
70 :
71 1025 : for(int i=0;i<nFeatureArraySize;i++)
72 : {
73 979 : if (papoFeatures[i])
74 979 : delete papoFeatures[i];
75 : }
76 46 : nFeatureArraySize = 0;
77 :
78 46 : CPLFree(papoFeatures);
79 46 : papoFeatures = NULL;
80 :
81 46 : if (poReader)
82 : {
83 0 : delete poReader;
84 0 : poReader = NULL;
85 : }
86 46 : }
87 :
88 :
89 : /************************************************************************/
90 : /* ResetReading() */
91 : /************************************************************************/
92 :
93 0 : void OGRXPlaneLayer::ResetReading()
94 :
95 : {
96 0 : if (poReader)
97 : {
98 0 : for(int i=0;i<nFeatureArraySize;i++)
99 : {
100 0 : if (papoFeatures[i])
101 0 : delete papoFeatures[i];
102 : }
103 0 : nFID = 0;
104 0 : nFeatureArraySize = 0;
105 0 : poReader->Rewind();
106 : }
107 0 : nFeatureArrayIndex = 0;
108 0 : }
109 :
110 : /************************************************************************/
111 : /* SetReader() */
112 : /************************************************************************/
113 :
114 0 : void OGRXPlaneLayer::SetReader(OGRXPlaneReader* poReader)
115 : {
116 0 : if (this->poReader)
117 : {
118 0 : delete this->poReader;
119 : }
120 0 : this->poReader = poReader;
121 0 : }
122 :
123 : /************************************************************************/
124 : /* AutoAdjustColumnsWidth() */
125 : /************************************************************************/
126 :
127 46 : void OGRXPlaneLayer::AutoAdjustColumnsWidth()
128 : {
129 46 : if (poReader != NULL)
130 : {
131 : CPLError(CE_Failure, CPLE_NotSupported,
132 0 : "AutoAdjustColumnsWidth() only supported when reading the whole file");
133 0 : return;
134 : }
135 :
136 326 : for(int col=0;col<poFeatureDefn->GetFieldCount();col++)
137 : {
138 280 : OGRFieldDefn* poFieldDefn = poFeatureDefn->GetFieldDefn(col);
139 280 : if (poFieldDefn->GetWidth() == 0)
140 : {
141 70 : if (poFieldDefn->GetType() == OFTString ||
142 : poFieldDefn->GetType() == OFTInteger)
143 : {
144 70 : int nMaxLen = 0;
145 1424 : for(int i=0;i<nFeatureArraySize;i++)
146 : {
147 1354 : int nLen = strlen(papoFeatures[i]->GetFieldAsString(col));
148 1354 : if (nLen > nMaxLen)
149 101 : nMaxLen = nLen;
150 : }
151 70 : poFieldDefn->SetWidth(nMaxLen);
152 : }
153 : else
154 : {
155 : CPLDebug("XPlane", "Field %s of layer %s is of unknown size",
156 0 : poFieldDefn->GetNameRef(), poFeatureDefn->GetName());
157 : }
158 : }
159 : }
160 : }
161 :
162 : /************************************************************************/
163 : /* GetNextFeature() */
164 : /************************************************************************/
165 :
166 46 : OGRFeature *OGRXPlaneLayer::GetNextFeature()
167 : {
168 : OGRFeature *poFeature;
169 :
170 46 : if (poReader)
171 : {
172 0 : while(TRUE)
173 : {
174 0 : if ( nFeatureArrayIndex == nFeatureArraySize)
175 : {
176 0 : nFeatureArrayIndex = nFeatureArraySize = 0;
177 :
178 0 : if (poReader->GetNextFeature() == FALSE)
179 0 : return NULL;
180 0 : if (nFeatureArraySize == 0)
181 0 : return NULL;
182 : }
183 :
184 0 : do
185 : {
186 0 : poFeature = papoFeatures[nFeatureArrayIndex];
187 0 : papoFeatures[nFeatureArrayIndex] = NULL;
188 0 : nFeatureArrayIndex++;
189 :
190 0 : if( (m_poFilterGeom == NULL
191 : || FilterGeometry( poFeature->GetGeometryRef() ) )
192 : && (m_poAttrQuery == NULL
193 : || m_poAttrQuery->Evaluate( poFeature )) )
194 : {
195 0 : return poFeature;
196 : }
197 :
198 0 : delete poFeature;
199 : } while(nFeatureArrayIndex < nFeatureArraySize);
200 : }
201 : }
202 : else
203 46 : poDS->ReadWholeFileIfNecessary();
204 :
205 46 : while(nFeatureArrayIndex < nFeatureArraySize)
206 : {
207 41 : poFeature = papoFeatures[nFeatureArrayIndex ++];
208 41 : CPLAssert (poFeature != NULL);
209 :
210 41 : if( (m_poFilterGeom == NULL
211 : || FilterGeometry( poFeature->GetGeometryRef() ) )
212 : && (m_poAttrQuery == NULL
213 : || m_poAttrQuery->Evaluate( poFeature )) )
214 : {
215 41 : return poFeature->Clone();
216 : }
217 : }
218 :
219 5 : return NULL;
220 : }
221 :
222 : /************************************************************************/
223 : /* GetFeature() */
224 : /************************************************************************/
225 :
226 0 : OGRFeature * OGRXPlaneLayer::GetFeature( long nFID )
227 : {
228 0 : if (poReader)
229 0 : return OGRLayer::GetFeature(nFID);
230 : else
231 0 : poDS->ReadWholeFileIfNecessary();
232 :
233 0 : if (nFID >= 0 && nFID < nFeatureArraySize)
234 : {
235 0 : return papoFeatures[nFID]->Clone();
236 : }
237 : else
238 : {
239 0 : return NULL;
240 : }
241 : }
242 :
243 : /************************************************************************/
244 : /* GetFeatureCount() */
245 : /************************************************************************/
246 :
247 46 : int OGRXPlaneLayer::GetFeatureCount( int bForce )
248 : {
249 46 : if (poReader == NULL && m_poFilterGeom == NULL && m_poAttrQuery == NULL)
250 : {
251 46 : poDS->ReadWholeFileIfNecessary();
252 46 : return nFeatureArraySize;
253 : }
254 : else
255 0 : return OGRLayer::GetFeatureCount( bForce ) ;
256 : }
257 :
258 :
259 : /************************************************************************/
260 : /* SetNextByIndex() */
261 : /************************************************************************/
262 :
263 0 : OGRErr OGRXPlaneLayer::SetNextByIndex( long nIndex )
264 : {
265 0 : if (poReader == NULL && m_poFilterGeom == NULL && m_poAttrQuery == NULL)
266 : {
267 0 : poDS->ReadWholeFileIfNecessary();
268 0 : if (nIndex < 0 || nIndex >= nFeatureArraySize)
269 0 : return OGRERR_FAILURE;
270 :
271 0 : nFeatureArrayIndex = (int)nIndex;
272 0 : return OGRERR_NONE;
273 : }
274 : else
275 0 : return OGRLayer::SetNextByIndex(nIndex);
276 : }
277 :
278 : /************************************************************************/
279 : /* TestCapability() */
280 : /************************************************************************/
281 :
282 0 : int OGRXPlaneLayer::TestCapability( const char * pszCap )
283 : {
284 0 : if (EQUAL(pszCap,OLCFastFeatureCount) ||
285 : EQUAL(pszCap,OLCRandomRead) ||
286 : EQUAL(pszCap,OLCFastSetNextByIndex))
287 : {
288 0 : if (poReader == NULL && m_poFilterGeom == NULL && m_poAttrQuery == NULL)
289 0 : return TRUE;
290 : }
291 :
292 0 : return FALSE;
293 : }
294 :
295 :
296 : /************************************************************************/
297 : /* RegisterFeature() */
298 : /************************************************************************/
299 :
300 979 : void OGRXPlaneLayer::RegisterFeature( OGRFeature* poFeature )
301 : {
302 979 : CPLAssert (poFeature != NULL);
303 :
304 979 : OGRGeometry* poGeom = poFeature->GetGeometryRef();
305 979 : if (poGeom)
306 927 : poGeom->assignSpatialReference( poSRS );
307 :
308 979 : if (nFeatureArraySize == nFeatureArrayMaxSize)
309 : {
310 139 : nFeatureArrayMaxSize = 2 * nFeatureArrayMaxSize + 1;
311 : papoFeatures = (OGRFeature**)CPLRealloc(papoFeatures,
312 139 : nFeatureArrayMaxSize * sizeof(OGRFeature*));
313 : }
314 979 : papoFeatures[nFeatureArraySize] = poFeature;
315 979 : poFeature->SetFID( nFID );
316 979 : nFID ++;
317 979 : nFeatureArraySize ++;
318 979 : }
319 :
320 : /************************************************************************/
321 : /* GetLayerDefn() */
322 : /************************************************************************/
323 :
324 374 : OGRFeatureDefn * OGRXPlaneLayer::GetLayerDefn()
325 : {
326 374 : poDS->ReadWholeFileIfNecessary();
327 374 : return poFeatureDefn;
328 : }
329 :
330 : /************************************************************************/
331 : /* SetDataSource() */
332 : /************************************************************************/
333 :
334 46 : void OGRXPlaneLayer::SetDataSource(OGRXPlaneDataSource* poDS)
335 : {
336 46 : this->poDS = poDS;
337 46 : }
|