1 : /******************************************************************************
2 : * $Id: ogrnaslayer.cpp 24105 2012-03-10 12:08:04Z rouault $
3 : *
4 : * Project: OGR
5 : * Purpose: Implements OGRNASLayer class.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2002, Frank Warmerdam <warmerdam@pobox.com>
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_nas.h"
31 : #include "cpl_conv.h"
32 : #include "cpl_port.h"
33 : #include "cpl_string.h"
34 :
35 : CPL_CVSID("$Id: ogrnaslayer.cpp 24105 2012-03-10 12:08:04Z rouault $");
36 :
37 : /************************************************************************/
38 : /* OGRNASLayer() */
39 : /************************************************************************/
40 :
41 254 : OGRNASLayer::OGRNASLayer( const char * pszName,
42 : OGRSpatialReference *poSRSIn,
43 : OGRwkbGeometryType eReqType,
44 254 : OGRNASDataSource *poDSIn )
45 :
46 : {
47 254 : if( poSRSIn == NULL )
48 254 : poSRS = NULL;
49 : else
50 0 : poSRS = poSRSIn->Clone();
51 :
52 254 : iNextNASId = 0;
53 254 : nTotalNASCount = -1;
54 :
55 254 : poDS = poDSIn;
56 :
57 254 : if ( EQUALN(pszName, "ogr:", 4) )
58 0 : poFeatureDefn = new OGRFeatureDefn( pszName+4 );
59 : else
60 254 : poFeatureDefn = new OGRFeatureDefn( pszName );
61 254 : poFeatureDefn->Reference();
62 254 : poFeatureDefn->SetGeomType( eReqType );
63 :
64 : /* -------------------------------------------------------------------- */
65 : /* Reader's should get the corresponding NASFeatureClass and */
66 : /* cache it. */
67 : /* -------------------------------------------------------------------- */
68 254 : poFClass = poDS->GetReader()->GetClass( pszName );
69 254 : }
70 :
71 : /************************************************************************/
72 : /* ~OGRNASLayer() */
73 : /************************************************************************/
74 :
75 254 : OGRNASLayer::~OGRNASLayer()
76 :
77 : {
78 254 : if( poFeatureDefn )
79 254 : poFeatureDefn->Release();
80 :
81 254 : if( poSRS != NULL )
82 0 : poSRS->Release();
83 254 : }
84 :
85 : /************************************************************************/
86 : /* ResetReading() */
87 : /************************************************************************/
88 :
89 16 : void OGRNASLayer::ResetReading()
90 :
91 : {
92 16 : iNextNASId = 0;
93 16 : poDS->GetReader()->ResetReading();
94 16 : if (poFClass)
95 16 : poDS->GetReader()->SetFilteredClassName(poFClass->GetName());
96 16 : }
97 :
98 : /************************************************************************/
99 : /* GetNextFeature() */
100 : /************************************************************************/
101 :
102 674 : OGRFeature *OGRNASLayer::GetNextFeature()
103 :
104 : {
105 674 : GMLFeature *poNASFeature = NULL;
106 674 : OGRGeometry *poGeom = NULL;
107 :
108 674 : if( iNextNASId == 0 )
109 10 : ResetReading();
110 :
111 : /* ==================================================================== */
112 : /* Loop till we find and translate a feature meeting all our */
113 : /* requirements. */
114 : /* ==================================================================== */
115 0 : while( TRUE )
116 : {
117 : /* -------------------------------------------------------------------- */
118 : /* Cleanup last feature, and get a new raw nas feature. */
119 : /* -------------------------------------------------------------------- */
120 674 : delete poNASFeature;
121 674 : delete poGeom;
122 :
123 674 : poNASFeature = NULL;
124 674 : poGeom = NULL;
125 :
126 674 : poNASFeature = poDS->GetReader()->NextFeature();
127 674 : if( poNASFeature == NULL )
128 0 : return NULL;
129 :
130 : /* -------------------------------------------------------------------- */
131 : /* Is it of the proper feature class? */
132 : /* -------------------------------------------------------------------- */
133 :
134 : // We count reading low level NAS features as a feature read for
135 : // work checking purposes, though at least we didn't necessary
136 : // have to turn it into an OGRFeature.
137 674 : m_nFeaturesRead++;
138 :
139 674 : if( poNASFeature->GetClass() != poFClass )
140 0 : continue;
141 :
142 674 : iNextNASId++;
143 :
144 : /* -------------------------------------------------------------------- */
145 : /* Does it satisfy the spatial query, if there is one? */
146 : /* -------------------------------------------------------------------- */
147 674 : const CPLXMLNode* const * papsGeometry = poNASFeature->GetGeometryList();
148 674 : if (papsGeometry[0] != NULL)
149 : {
150 670 : poGeom = (OGRGeometry*) OGR_G_CreateFromGMLTree(papsGeometry[0]);
151 :
152 : // We assume the createFromNAS() function would have already
153 : // reported the error.
154 670 : if( poGeom == NULL )
155 : {
156 0 : delete poNASFeature;
157 0 : return NULL;
158 : }
159 :
160 670 : if( m_poFilterGeom != NULL && !FilterGeometry( poGeom ) )
161 0 : continue;
162 : }
163 :
164 : /* -------------------------------------------------------------------- */
165 : /* Convert the whole feature into an OGRFeature. */
166 : /* -------------------------------------------------------------------- */
167 : int iField;
168 674 : OGRFeature *poOGRFeature = new OGRFeature( GetLayerDefn() );
169 :
170 674 : poOGRFeature->SetFID( iNextNASId );
171 :
172 16732 : for( iField = 0; iField < poFClass->GetPropertyCount(); iField++ )
173 : {
174 16058 : const GMLProperty *psGMLProperty = poNASFeature->GetProperty( iField );
175 16058 : if( psGMLProperty == NULL || psGMLProperty->nSubProperties == 0 )
176 1990 : continue;
177 :
178 14068 : switch( poFClass->GetProperty(iField)->GetType() )
179 : {
180 : case GMLPT_Real:
181 : {
182 668 : poOGRFeature->SetField( iField, CPLAtof(psGMLProperty->papszSubProperties[0]) );
183 : }
184 668 : break;
185 :
186 : case GMLPT_IntegerList:
187 : {
188 0 : int nCount = psGMLProperty->nSubProperties;
189 0 : int *panIntList = (int *) CPLMalloc(sizeof(int) * nCount );
190 : int i;
191 :
192 0 : for( i = 0; i < nCount; i++ )
193 0 : panIntList[i] = atoi(psGMLProperty->papszSubProperties[i]);
194 :
195 0 : poOGRFeature->SetField( iField, nCount, panIntList );
196 0 : CPLFree( panIntList );
197 : }
198 0 : break;
199 :
200 : case GMLPT_RealList:
201 : {
202 0 : int nCount = psGMLProperty->nSubProperties;
203 0 : double *padfList = (double *)CPLMalloc(sizeof(double)*nCount);
204 : int i;
205 :
206 0 : for( i = 0; i < nCount; i++ )
207 0 : padfList[i] = CPLAtof(psGMLProperty->papszSubProperties[i]);
208 :
209 0 : poOGRFeature->SetField( iField, nCount, padfList );
210 0 : CPLFree( padfList );
211 : }
212 0 : break;
213 :
214 : case GMLPT_StringList:
215 : {
216 4 : poOGRFeature->SetField( iField, psGMLProperty->papszSubProperties );
217 : }
218 4 : break;
219 :
220 : default:
221 13396 : poOGRFeature->SetField( iField, psGMLProperty->papszSubProperties[0] );
222 : break;
223 : }
224 : }
225 :
226 : /* -------------------------------------------------------------------- */
227 : /* Test against the attribute query. */
228 : /* -------------------------------------------------------------------- */
229 674 : if( m_poAttrQuery != NULL
230 : && !m_poAttrQuery->Evaluate( poOGRFeature ) )
231 : {
232 0 : delete poOGRFeature;
233 0 : continue;
234 : }
235 :
236 : /* -------------------------------------------------------------------- */
237 : /* Wow, we got our desired feature. Return it. */
238 : /* -------------------------------------------------------------------- */
239 674 : delete poNASFeature;
240 :
241 674 : poOGRFeature->SetGeometryDirectly( poGeom );
242 :
243 674 : return poOGRFeature;
244 : }
245 :
246 : return NULL;
247 : }
248 :
249 : /************************************************************************/
250 : /* GetFeatureCount() */
251 : /************************************************************************/
252 :
253 6 : int OGRNASLayer::GetFeatureCount( int bForce )
254 :
255 : {
256 6 : if( poFClass == NULL )
257 0 : return 0;
258 :
259 6 : if( m_poFilterGeom != NULL || m_poAttrQuery != NULL )
260 0 : return OGRLayer::GetFeatureCount( bForce );
261 : else
262 6 : return poFClass->GetFeatureCount();
263 : }
264 :
265 : /************************************************************************/
266 : /* GetExtent() */
267 : /************************************************************************/
268 :
269 0 : OGRErr OGRNASLayer::GetExtent(OGREnvelope *psExtent, int bForce )
270 :
271 : {
272 : double dfXMin, dfXMax, dfYMin, dfYMax;
273 :
274 0 : if( poFClass != NULL &&
275 : poFClass->GetExtents( &dfXMin, &dfXMax, &dfYMin, &dfYMax ) )
276 : {
277 0 : psExtent->MinX = dfXMin;
278 0 : psExtent->MaxX = dfXMax;
279 0 : psExtent->MinY = dfYMin;
280 0 : psExtent->MaxY = dfYMax;
281 :
282 0 : return OGRERR_NONE;
283 : }
284 : else
285 0 : return OGRLayer::GetExtent( psExtent, bForce );
286 : }
287 :
288 : /************************************************************************/
289 : /* TestCapability() */
290 : /************************************************************************/
291 :
292 0 : int OGRNASLayer::TestCapability( const char * pszCap )
293 :
294 : {
295 0 : if( EQUAL(pszCap,OLCFastGetExtent) )
296 : {
297 : double dfXMin, dfXMax, dfYMin, dfYMax;
298 :
299 0 : if( poFClass == NULL )
300 0 : return FALSE;
301 :
302 0 : return poFClass->GetExtents( &dfXMin, &dfXMax, &dfYMin, &dfYMax );
303 : }
304 :
305 0 : else if( EQUAL(pszCap,OLCFastFeatureCount) )
306 : {
307 0 : if( poFClass == NULL
308 : || m_poFilterGeom != NULL
309 : || m_poAttrQuery != NULL )
310 0 : return FALSE;
311 :
312 0 : return poFClass->GetFeatureCount() != -1;
313 : }
314 :
315 0 : else if( EQUAL(pszCap,OLCStringsAsUTF8) )
316 0 : return TRUE;
317 :
318 : else
319 0 : return FALSE;
320 : }
321 :
322 : /************************************************************************/
323 : /* GetSpatialRef() */
324 : /************************************************************************/
325 :
326 0 : OGRSpatialReference *OGRNASLayer::GetSpatialRef()
327 :
328 : {
329 0 : return poSRS;
330 : }
331 :
|