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 17746 2009-10-03 21:32:37Z rouault $");
35 :
36 : /************************************************************************/
37 : /* OGRXPlaneLayer() */
38 : /************************************************************************/
39 :
40 28 : OGRXPlaneLayer::OGRXPlaneLayer( const char* pszLayerName )
41 :
42 : {
43 28 : nFID = 0;
44 28 : nFeatureArraySize = 0;
45 28 : nFeatureArrayMaxSize = 0;
46 28 : nFeatureArrayIndex = 0;
47 28 : papoFeatures = NULL;
48 :
49 28 : poFeatureDefn = new OGRFeatureDefn( pszLayerName );
50 28 : poFeatureDefn->Reference();
51 :
52 28 : poSRS = new OGRSpatialReference();
53 28 : poSRS->SetWellKnownGeogCS("WGS84");
54 :
55 28 : poReader = NULL;
56 28 : }
57 :
58 :
59 : /************************************************************************/
60 : /* ~OGRXPlaneLayer() */
61 : /************************************************************************/
62 :
63 28 : OGRXPlaneLayer::~OGRXPlaneLayer()
64 :
65 : {
66 28 : poFeatureDefn->Release();
67 :
68 28 : poSRS->Release();
69 :
70 883 : for(int i=0;i<nFeatureArraySize;i++)
71 : {
72 855 : if (papoFeatures[i])
73 855 : delete papoFeatures[i];
74 : }
75 28 : nFeatureArraySize = 0;
76 :
77 28 : CPLFree(papoFeatures);
78 28 : papoFeatures = NULL;
79 :
80 28 : if (poReader)
81 : {
82 0 : delete poReader;
83 0 : poReader = NULL;
84 : }
85 28 : }
86 :
87 :
88 : /************************************************************************/
89 : /* ResetReading() */
90 : /************************************************************************/
91 :
92 0 : void OGRXPlaneLayer::ResetReading()
93 :
94 : {
95 0 : if (poReader)
96 : {
97 0 : for(int i=0;i<nFeatureArraySize;i++)
98 : {
99 0 : if (papoFeatures[i])
100 0 : delete papoFeatures[i];
101 : }
102 0 : nFID = 0;
103 0 : nFeatureArraySize = 0;
104 0 : poReader->Rewind();
105 : }
106 0 : nFeatureArrayIndex = 0;
107 0 : }
108 :
109 : /************************************************************************/
110 : /* SetReader() */
111 : /************************************************************************/
112 :
113 0 : void OGRXPlaneLayer::SetReader(OGRXPlaneReader* poReader)
114 : {
115 0 : if (this->poReader)
116 : {
117 0 : delete this->poReader;
118 : }
119 0 : this->poReader = poReader;
120 0 : }
121 :
122 : /************************************************************************/
123 : /* AutoAdjustColumnsWidth() */
124 : /************************************************************************/
125 :
126 28 : void OGRXPlaneLayer::AutoAdjustColumnsWidth()
127 : {
128 28 : if (poReader != NULL)
129 : {
130 : CPLError(CE_Failure, CPLE_NotSupported,
131 0 : "AutoAdjustColumnsWidth() only supported when reading the whole file");
132 0 : return;
133 : }
134 :
135 195 : for(int col=0;col<poFeatureDefn->GetFieldCount();col++)
136 : {
137 167 : OGRFieldDefn* poFieldDefn = poFeatureDefn->GetFieldDefn(col);
138 167 : if (poFieldDefn->GetWidth() == 0)
139 : {
140 39 : if (poFieldDefn->GetType() == OFTString ||
141 : poFieldDefn->GetType() == OFTInteger)
142 : {
143 39 : int nMaxLen = 0;
144 1188 : for(int i=0;i<nFeatureArraySize;i++)
145 : {
146 1149 : int nLen = strlen(papoFeatures[i]->GetFieldAsString(col));
147 1149 : if (nLen > nMaxLen)
148 65 : nMaxLen = nLen;
149 : }
150 39 : poFieldDefn->SetWidth(nMaxLen);
151 : }
152 : else
153 : {
154 : CPLDebug("XPlane", "Field %s of layer %s is of unknown size",
155 0 : poFieldDefn->GetNameRef(), poFeatureDefn->GetName());
156 : }
157 : }
158 : }
159 : }
160 :
161 : /************************************************************************/
162 : /* GetNextFeature() */
163 : /************************************************************************/
164 :
165 28 : OGRFeature *OGRXPlaneLayer::GetNextFeature()
166 : {
167 : OGRFeature *poFeature;
168 :
169 28 : if (poReader)
170 : {
171 0 : while(TRUE)
172 : {
173 0 : if ( nFeatureArrayIndex == nFeatureArraySize)
174 : {
175 0 : nFeatureArrayIndex = nFeatureArraySize = 0;
176 :
177 0 : if (poReader->GetNextFeature() == FALSE)
178 0 : return NULL;
179 0 : if (nFeatureArraySize == 0)
180 0 : return NULL;
181 : }
182 :
183 0 : do
184 : {
185 0 : poFeature = papoFeatures[nFeatureArrayIndex];
186 0 : papoFeatures[nFeatureArrayIndex] = NULL;
187 0 : nFeatureArrayIndex++;
188 :
189 0 : if( (m_poFilterGeom == NULL
190 : || FilterGeometry( poFeature->GetGeometryRef() ) )
191 : && (m_poAttrQuery == NULL
192 : || m_poAttrQuery->Evaluate( poFeature )) )
193 : {
194 0 : return poFeature;
195 : }
196 :
197 0 : delete poFeature;
198 : } while(nFeatureArrayIndex < nFeatureArraySize);
199 : }
200 : }
201 :
202 56 : while(nFeatureArrayIndex < nFeatureArraySize)
203 : {
204 28 : poFeature = papoFeatures[nFeatureArrayIndex ++];
205 : CPLAssert (poFeature != NULL);
206 :
207 28 : if( (m_poFilterGeom == NULL
208 : || FilterGeometry( poFeature->GetGeometryRef() ) )
209 : && (m_poAttrQuery == NULL
210 : || m_poAttrQuery->Evaluate( poFeature )) )
211 : {
212 28 : return poFeature->Clone();
213 : }
214 : }
215 :
216 0 : return NULL;
217 : }
218 :
219 : /************************************************************************/
220 : /* GetFeature() */
221 : /************************************************************************/
222 :
223 0 : OGRFeature * OGRXPlaneLayer::GetFeature( long nFID )
224 : {
225 0 : if (poReader)
226 0 : return OGRLayer::GetFeature(nFID);
227 :
228 0 : if (nFID >= 0 && nFID < nFeatureArraySize)
229 : {
230 0 : return papoFeatures[nFID]->Clone();
231 : }
232 : else
233 : {
234 0 : return NULL;
235 : }
236 : }
237 :
238 : /************************************************************************/
239 : /* GetFeatureCount() */
240 : /************************************************************************/
241 :
242 28 : int OGRXPlaneLayer::GetFeatureCount( int bForce )
243 : {
244 28 : if (poReader == NULL && m_poFilterGeom == NULL && m_poAttrQuery == NULL)
245 28 : return nFeatureArraySize;
246 : else
247 0 : return OGRLayer::GetFeatureCount( bForce ) ;
248 : }
249 :
250 : /************************************************************************/
251 : /* TestCapability() */
252 : /************************************************************************/
253 :
254 0 : int OGRXPlaneLayer::TestCapability( const char * pszCap )
255 : {
256 0 : if (EQUAL(pszCap,OLCFastFeatureCount) ||
257 : EQUAL(pszCap,OLCRandomRead))
258 : {
259 0 : if (poReader == NULL && m_poFilterGeom == NULL && m_poAttrQuery == NULL)
260 0 : return TRUE;
261 : }
262 :
263 0 : return FALSE;
264 : }
265 :
266 :
267 : /************************************************************************/
268 : /* RegisterFeature() */
269 : /************************************************************************/
270 :
271 855 : void OGRXPlaneLayer::RegisterFeature( OGRFeature* poFeature )
272 : {
273 : CPLAssert (poFeature != NULL);
274 :
275 855 : OGRGeometry* poGeom = poFeature->GetGeometryRef();
276 855 : if (poGeom)
277 813 : poGeom->assignSpatialReference( poSRS );
278 :
279 855 : if (nFeatureArraySize == nFeatureArrayMaxSize)
280 : {
281 99 : nFeatureArrayMaxSize = 2 * nFeatureArrayMaxSize + 1;
282 : papoFeatures = (OGRFeature**)CPLRealloc(papoFeatures,
283 99 : nFeatureArrayMaxSize * sizeof(OGRFeature*));
284 : }
285 855 : papoFeatures[nFeatureArraySize] = poFeature;
286 855 : poFeature->SetFID( nFID );
287 855 : nFID ++;
288 855 : nFeatureArraySize ++;
289 855 : }
290 :
|