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 180 : OGRTigerLayer::OGRTigerLayer( OGRTigerDataSource *poDSIn,
42 180 : TigerFileBase * poReaderIn )
43 :
44 : {
45 180 : poDS = poDSIn;
46 180 : poReader = poReaderIn;
47 :
48 180 : iLastFeatureId = 0;
49 180 : iLastModule = -1;
50 :
51 180 : nFeatureCount = 0;
52 180 : panModuleFCount = NULL;
53 180 : panModuleOffset = NULL;
54 :
55 : /* -------------------------------------------------------------------- */
56 : /* Setup module feature counts. */
57 : /* -------------------------------------------------------------------- */
58 180 : if( !poDS->GetWriteMode() )
59 : {
60 : panModuleFCount = (int *)
61 162 : CPLCalloc(poDS->GetModuleCount(),sizeof(int));
62 : panModuleOffset = (int *)
63 162 : CPLCalloc(poDS->GetModuleCount()+1,sizeof(int));
64 :
65 162 : nFeatureCount = 0;
66 :
67 324 : for( int iModule = 0; iModule < poDS->GetModuleCount(); iModule++ )
68 : {
69 162 : if( poReader->SetModule( poDS->GetModule(iModule) ) )
70 144 : panModuleFCount[iModule] = poReader->GetFeatureCount();
71 : else
72 18 : panModuleFCount[iModule] = 0;
73 :
74 162 : panModuleOffset[iModule] = nFeatureCount;
75 162 : 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 162 : panModuleOffset[poDS->GetModuleCount()] = nFeatureCount;
81 : }
82 :
83 180 : poReader->SetModule( NULL );
84 180 : }
85 :
86 : /************************************************************************/
87 : /* ~OGRTigerLayer() */
88 : /************************************************************************/
89 :
90 180 : OGRTigerLayer::~OGRTigerLayer()
91 :
92 : {
93 180 : if( m_nFeaturesRead > 0 && poReader->GetFeatureDefn() != NULL )
94 : {
95 : CPLDebug( "TIGER", "%d features read on layer '%s'.",
96 : (int) m_nFeaturesRead,
97 40 : poReader->GetFeatureDefn()->GetName() );
98 : }
99 :
100 180 : delete poReader;
101 :
102 180 : CPLFree( panModuleFCount );
103 180 : CPLFree( panModuleOffset );
104 180 : }
105 :
106 : /************************************************************************/
107 : /* ResetReading() */
108 : /************************************************************************/
109 :
110 400 : void OGRTigerLayer::ResetReading()
111 :
112 : {
113 400 : iLastFeatureId = 0;
114 400 : iLastModule = -1;
115 400 : }
116 :
117 : /************************************************************************/
118 : /* GetFeature() */
119 : /************************************************************************/
120 :
121 1118612 : OGRFeature *OGRTigerLayer::GetFeature( long nFeatureId )
122 :
123 : {
124 1118612 : if( nFeatureId < 1 || nFeatureId > nFeatureCount )
125 36 : 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 3355290 : if( iLastModule == -1
132 1118357 : || nFeatureId <= panModuleOffset[iLastModule]
133 1118357 : || nFeatureId > panModuleOffset[iLastModule+1] )
134 : {
135 438 : for( iLastModule = 0;
136 : iLastModule < poDS->GetModuleCount()
137 219 : && nFeatureId > panModuleOffset[iLastModule+1];
138 : iLastModule++ ) {}
139 :
140 219 : 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 1118576 : poReader->GetFeature( nFeatureId-panModuleOffset[iLastModule]-1 );
153 :
154 1118576 : if( poFeature != NULL )
155 : {
156 1118576 : poFeature->SetFID( nFeatureId );
157 :
158 1118576 : if( poFeature->GetGeometryRef() != NULL )
159 : poFeature->GetGeometryRef()->assignSpatialReference(
160 310430 : poDS->GetSpatialRef() );
161 :
162 1118576 : poFeature->SetField( 0, poReader->GetShortModule() );
163 :
164 1118576 : m_nFeaturesRead++;
165 : }
166 :
167 1118576 : return poFeature;
168 : }
169 :
170 :
171 : /************************************************************************/
172 : /* GetNextFeature() */
173 : /************************************************************************/
174 :
175 696592 : OGRFeature *OGRTigerLayer::GetNextFeature()
176 :
177 : {
178 : /* -------------------------------------------------------------------- */
179 : /* Read features till we find one that satisfies our current */
180 : /* spatial criteria. */
181 : /* -------------------------------------------------------------------- */
182 1815297 : while( iLastFeatureId < nFeatureCount )
183 : {
184 1118546 : OGRFeature *poFeature = GetFeature( ++iLastFeatureId );
185 :
186 1118546 : if( poFeature == NULL )
187 0 : break;
188 :
189 1118546 : if( (m_poFilterGeom == NULL
190 : || FilterGeometry( poFeature->GetGeometryRef() ) )
191 : && (m_poAttrQuery == NULL
192 : || m_poAttrQuery->Evaluate( poFeature )) )
193 696433 : return poFeature;
194 :
195 422113 : delete poFeature;
196 : }
197 :
198 159 : return NULL;
199 : }
200 :
201 : /************************************************************************/
202 : /* TestCapability() */
203 : /************************************************************************/
204 :
205 144 : int OGRTigerLayer::TestCapability( const char * pszCap )
206 :
207 : {
208 144 : if( EQUAL(pszCap,OLCRandomRead) )
209 18 : return TRUE;
210 :
211 126 : else if( EQUAL(pszCap,OLCSequentialWrite)
212 : || EQUAL(pszCap,OLCRandomWrite) )
213 36 : return FALSE;
214 :
215 90 : else if( EQUAL(pszCap,OLCFastFeatureCount) )
216 0 : return TRUE;
217 :
218 90 : else if( EQUAL(pszCap,OLCFastSpatialFilter) )
219 0 : return FALSE;
220 :
221 90 : else if( EQUAL(pszCap,OLCSequentialWrite) )
222 0 : return poDS->GetWriteMode();
223 :
224 : else
225 90 : return FALSE;
226 : }
227 :
228 : /************************************************************************/
229 : /* GetSpatialRef() */
230 : /************************************************************************/
231 :
232 54 : OGRSpatialReference *OGRTigerLayer::GetSpatialRef()
233 :
234 : {
235 54 : return poDS->GetSpatialRef();
236 : }
237 :
238 : /************************************************************************/
239 : /* GetLayerDefn() */
240 : /************************************************************************/
241 :
242 129023 : OGRFeatureDefn *OGRTigerLayer::GetLayerDefn()
243 :
244 : {
245 129023 : 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 124787 : OGRErr OGRTigerLayer::CreateFeature( OGRFeature *poFeature )
265 :
266 : {
267 124787 : return poReader->CreateFeature( poFeature );
268 : }
269 :
270 : /************************************************************************/
271 : /* GetFeatureCount() */
272 : /************************************************************************/
273 :
274 133 : int OGRTigerLayer::GetFeatureCount( int bForce )
275 :
276 : {
277 133 : if( m_poFilterGeom == NULL && m_poAttrQuery == NULL )
278 95 : return nFeatureCount;
279 : else
280 38 : return OGRLayer::GetFeatureCount( bForce );
281 : }
|