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