1 : /******************************************************************************
2 : * $Id: ogrtigerlayer.cpp 10645 2007-01-18 02:22:39Z warmerdam $
3 : *
4 : * Project: TIGER/Line Translator
5 : * Purpose: Implements OGRTigerLayer class.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 1999, Frank Warmerdam
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_tiger.h"
31 :
32 : CPL_CVSID("$Id: ogrtigerlayer.cpp 10645 2007-01-18 02:22:39Z warmerdam $");
33 :
34 : /************************************************************************/
35 : /* OGRTigerLayer() */
36 : /* */
37 : /* Note that the OGRTigerLayer assumes ownership of the passed */
38 : /* OGRFeatureDefn object. */
39 : /************************************************************************/
40 :
41 : OGRTigerLayer::OGRTigerLayer( OGRTigerDataSource *poDSIn,
42 0 : TigerFileBase * poReaderIn )
43 :
44 : {
45 0 : poDS = poDSIn;
46 0 : poReader = poReaderIn;
47 :
48 0 : iLastFeatureId = 0;
49 0 : iLastModule = -1;
50 :
51 0 : nFeatureCount = 0;
52 0 : panModuleFCount = NULL;
53 0 : panModuleOffset = NULL;
54 :
55 : /* -------------------------------------------------------------------- */
56 : /* Setup module feature counts. */
57 : /* -------------------------------------------------------------------- */
58 0 : if( !poDS->GetWriteMode() )
59 : {
60 : panModuleFCount = (int *)
61 0 : CPLCalloc(poDS->GetModuleCount(),sizeof(int));
62 : panModuleOffset = (int *)
63 0 : CPLCalloc(poDS->GetModuleCount()+1,sizeof(int));
64 :
65 0 : nFeatureCount = 0;
66 :
67 0 : for( int iModule = 0; iModule < poDS->GetModuleCount(); iModule++ )
68 : {
69 0 : if( poReader->SetModule( poDS->GetModule(iModule) ) )
70 0 : panModuleFCount[iModule] = poReader->GetFeatureCount();
71 : else
72 0 : panModuleFCount[iModule] = 0;
73 :
74 0 : panModuleOffset[iModule] = nFeatureCount;
75 0 : nFeatureCount += panModuleFCount[iModule];
76 : }
77 :
78 : // this entry is just to make range comparisons easy without worrying
79 : // about falling off the end of the array.
80 0 : panModuleOffset[poDS->GetModuleCount()] = nFeatureCount;
81 : }
82 :
83 0 : poReader->SetModule( NULL );
84 0 : }
85 :
86 : /************************************************************************/
87 : /* ~OGRTigerLayer() */
88 : /************************************************************************/
89 :
90 0 : OGRTigerLayer::~OGRTigerLayer()
91 :
92 : {
93 0 : if( m_nFeaturesRead > 0 && poReader->GetFeatureDefn() != NULL )
94 : {
95 : CPLDebug( "TIGER", "%d features read on layer '%s'.",
96 : (int) m_nFeaturesRead,
97 0 : poReader->GetFeatureDefn()->GetName() );
98 : }
99 :
100 0 : delete poReader;
101 :
102 0 : CPLFree( panModuleFCount );
103 0 : CPLFree( panModuleOffset );
104 0 : }
105 :
106 : /************************************************************************/
107 : /* ResetReading() */
108 : /************************************************************************/
109 :
110 0 : void OGRTigerLayer::ResetReading()
111 :
112 : {
113 0 : iLastFeatureId = 0;
114 0 : iLastModule = -1;
115 0 : }
116 :
117 : /************************************************************************/
118 : /* GetFeature() */
119 : /************************************************************************/
120 :
121 0 : OGRFeature *OGRTigerLayer::GetFeature( long nFeatureId )
122 :
123 : {
124 0 : if( nFeatureId < 1 || nFeatureId > nFeatureCount )
125 0 : return NULL;
126 :
127 : /* -------------------------------------------------------------------- */
128 : /* If we don't have the current module open for the requested */
129 : /* data, then open it now. */
130 : /* -------------------------------------------------------------------- */
131 0 : if( iLastModule == -1
132 : || nFeatureId <= panModuleOffset[iLastModule]
133 : || nFeatureId > panModuleOffset[iLastModule+1] )
134 : {
135 0 : for( iLastModule = 0;
136 : iLastModule < poDS->GetModuleCount()
137 : && nFeatureId > panModuleOffset[iLastModule+1];
138 : iLastModule++ ) {}
139 :
140 0 : if( !poReader->SetModule( poDS->GetModule(iLastModule) ) )
141 : {
142 0 : return NULL;
143 : }
144 : }
145 :
146 : /* -------------------------------------------------------------------- */
147 : /* Fetch the feature associated with the record. */
148 : /* -------------------------------------------------------------------- */
149 : OGRFeature *poFeature;
150 :
151 : poFeature =
152 0 : poReader->GetFeature( nFeatureId-panModuleOffset[iLastModule]-1 );
153 :
154 0 : if( poFeature != NULL )
155 : {
156 0 : poFeature->SetFID( nFeatureId );
157 :
158 0 : if( poFeature->GetGeometryRef() != NULL )
159 : poFeature->GetGeometryRef()->assignSpatialReference(
160 0 : poDS->GetSpatialRef() );
161 :
162 0 : poFeature->SetField( 0, poReader->GetShortModule() );
163 :
164 0 : m_nFeaturesRead++;
165 : }
166 :
167 0 : return poFeature;
168 : }
169 :
170 :
171 : /************************************************************************/
172 : /* GetNextFeature() */
173 : /************************************************************************/
174 :
175 0 : OGRFeature *OGRTigerLayer::GetNextFeature()
176 :
177 : {
178 : /* -------------------------------------------------------------------- */
179 : /* Read features till we find one that satisfies our current */
180 : /* spatial criteria. */
181 : /* -------------------------------------------------------------------- */
182 0 : while( iLastFeatureId < nFeatureCount )
183 : {
184 0 : OGRFeature *poFeature = GetFeature( ++iLastFeatureId );
185 :
186 0 : if( poFeature == NULL )
187 0 : break;
188 :
189 0 : if( (m_poFilterGeom == NULL
190 : || FilterGeometry( poFeature->GetGeometryRef() ) )
191 : && (m_poAttrQuery == NULL
192 : || m_poAttrQuery->Evaluate( poFeature )) )
193 0 : return poFeature;
194 :
195 0 : delete poFeature;
196 : }
197 :
198 0 : return NULL;
199 : }
200 :
201 : /************************************************************************/
202 : /* TestCapability() */
203 : /************************************************************************/
204 :
205 0 : int OGRTigerLayer::TestCapability( const char * pszCap )
206 :
207 : {
208 0 : if( EQUAL(pszCap,OLCRandomRead) )
209 0 : return TRUE;
210 :
211 0 : else if( EQUAL(pszCap,OLCSequentialWrite)
212 : || EQUAL(pszCap,OLCRandomWrite) )
213 0 : return FALSE;
214 :
215 0 : else if( EQUAL(pszCap,OLCFastFeatureCount) )
216 0 : return TRUE;
217 :
218 0 : else if( EQUAL(pszCap,OLCFastSpatialFilter) )
219 0 : return FALSE;
220 :
221 0 : else if( EQUAL(pszCap,OLCSequentialWrite) )
222 0 : return poDS->GetWriteMode();
223 :
224 : else
225 0 : return FALSE;
226 : }
227 :
228 : /************************************************************************/
229 : /* GetSpatialRef() */
230 : /************************************************************************/
231 :
232 0 : OGRSpatialReference *OGRTigerLayer::GetSpatialRef()
233 :
234 : {
235 0 : return poDS->GetSpatialRef();
236 : }
237 :
238 : /************************************************************************/
239 : /* GetLayerDefn() */
240 : /************************************************************************/
241 :
242 0 : OGRFeatureDefn *OGRTigerLayer::GetLayerDefn()
243 :
244 : {
245 0 : return poReader->GetFeatureDefn();
246 : }
247 :
248 : /************************************************************************/
249 : /* CreateField() */
250 : /************************************************************************/
251 :
252 0 : OGRErr OGRTigerLayer::CreateField( OGRFieldDefn *poField, int bApproxOK )
253 :
254 : {
255 : /* notdef/TODO: I should add some checking here eventually. */
256 :
257 0 : return OGRERR_NONE;
258 : }
259 :
260 : /************************************************************************/
261 : /* CreateFeature() */
262 : /************************************************************************/
263 :
264 0 : OGRErr OGRTigerLayer::CreateFeature( OGRFeature *poFeature )
265 :
266 : {
267 0 : return poReader->CreateFeature( poFeature );
268 : }
269 :
270 : /************************************************************************/
271 : /* GetFeatureCount() */
272 : /************************************************************************/
273 :
274 0 : int OGRTigerLayer::GetFeatureCount( int bForce )
275 :
276 : {
277 0 : if( m_poFilterGeom == NULL && m_poAttrQuery == NULL )
278 0 : return nFeatureCount;
279 : else
280 0 : return OGRLayer::GetFeatureCount( bForce );
281 : }
|