1 /******************************************************************************
2 *
3 * Project: UK NTF Reader
4 * Purpose: Implements OGRNTFLayer class.
5 * Author: Frank Warmerdam, warmerdam@pobox.com
6 *
7 ******************************************************************************
8 * Copyright (c) 1999, Frank Warmerdam
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included
18 * in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 ****************************************************************************/
28
29 #include "ntf.h"
30 #include "cpl_conv.h"
31
32 CPL_CVSID("$Id: ogrntflayer.cpp 7e07230bbff24eb333608de4dbd460b7312839d0 2017-12-11 19:08:47Z Even Rouault $")
33
34 /************************************************************************/
35 /* OGRNTFLayer() */
36 /* */
37 /* Note that the OGRNTFLayer assumes ownership of the passed */
38 /* OGRFeatureDefn object. */
39 /************************************************************************/
40
OGRNTFLayer(OGRNTFDataSource * poDSIn,OGRFeatureDefn * poFeatureDefine,NTFFeatureTranslator pfnTranslatorIn)41 OGRNTFLayer::OGRNTFLayer( OGRNTFDataSource *poDSIn,
42 OGRFeatureDefn * poFeatureDefine,
43 NTFFeatureTranslator pfnTranslatorIn ) :
44 poFeatureDefn(poFeatureDefine),
45 pfnTranslator(pfnTranslatorIn),
46 poDS(poDSIn),
47 iCurrentReader(-1),
48 nCurrentPos((vsi_l_offset)-1),
49 nCurrentFID(1)
50 {
51 SetDescription( poFeatureDefn->GetName() );
52 }
53
54 /************************************************************************/
55 /* ~OGRNTFLayer() */
56 /************************************************************************/
57
~OGRNTFLayer()58 OGRNTFLayer::~OGRNTFLayer()
59
60 {
61 if( m_nFeaturesRead > 0 && poFeatureDefn != nullptr )
62 {
63 CPLDebug( "Mem", "%d features read on layer '%s'.",
64 (int) m_nFeaturesRead,
65 poFeatureDefn->GetName() );
66 }
67
68 if( poFeatureDefn )
69 poFeatureDefn->Release();
70 }
71
72 /************************************************************************/
73 /* ResetReading() */
74 /************************************************************************/
75
ResetReading()76 void OGRNTFLayer::ResetReading()
77
78 {
79 iCurrentReader = -1;
80 nCurrentPos = (vsi_l_offset)-1;
81 nCurrentFID = 1;
82 }
83
84 /************************************************************************/
85 /* GetNextFeature() */
86 /************************************************************************/
87
GetNextFeature()88 OGRFeature *OGRNTFLayer::GetNextFeature()
89
90 {
91 OGRFeature *poFeature = nullptr;
92
93 /* -------------------------------------------------------------------- */
94 /* Have we processed all features already? */
95 /* -------------------------------------------------------------------- */
96 if( iCurrentReader == poDS->GetFileCount() )
97 return nullptr;
98
99 /* -------------------------------------------------------------------- */
100 /* Do we need to open a file? */
101 /* -------------------------------------------------------------------- */
102 if( iCurrentReader == -1 )
103 {
104 iCurrentReader++;
105 nCurrentPos = (vsi_l_offset)-1;
106 }
107
108 NTFFileReader *poCurrentReader = poDS->GetFileReader(iCurrentReader);
109 if( poCurrentReader->GetFP() == nullptr )
110 {
111 poCurrentReader->Open();
112 }
113
114 /* -------------------------------------------------------------------- */
115 /* Ensure we are reading on from the same point we were reading */
116 /* from for the last feature, even if some other access */
117 /* mechanism has moved the file pointer. */
118 /* -------------------------------------------------------------------- */
119 if( nCurrentPos != (vsi_l_offset)-1 )
120 poCurrentReader->SetFPPos( nCurrentPos, nCurrentFID );
121 else
122 poCurrentReader->Reset();
123
124 /* -------------------------------------------------------------------- */
125 /* Read features till we find one that satisfies our current */
126 /* spatial criteria. */
127 /* -------------------------------------------------------------------- */
128 while( true )
129 {
130 poFeature = poCurrentReader->ReadOGRFeature( this );
131 if( poFeature == nullptr )
132 break;
133
134 m_nFeaturesRead++;
135
136 if( (m_poFilterGeom == nullptr
137 || poFeature->GetGeometryRef() == nullptr
138 || FilterGeometry( poFeature->GetGeometryRef() ) )
139 && (m_poAttrQuery == nullptr
140 || m_poAttrQuery->Evaluate( poFeature )) )
141 break;
142
143 delete poFeature;
144 }
145
146 /* -------------------------------------------------------------------- */
147 /* If we get NULL the file must be all consumed, advance to the */
148 /* next file that contains features for this layer. */
149 /* -------------------------------------------------------------------- */
150 if( poFeature == nullptr )
151 {
152 poCurrentReader->Close();
153
154 if( poDS->GetOption("CACHING") != nullptr
155 && EQUAL(poDS->GetOption("CACHING"),"OFF") )
156 {
157 poCurrentReader->DestroyIndex();
158 }
159
160 do {
161 iCurrentReader++;
162 } while( iCurrentReader < poDS->GetFileCount()
163 && !poDS->GetFileReader(iCurrentReader)->TestForLayer(this) );
164
165 nCurrentPos = (vsi_l_offset)-1;
166 nCurrentFID = 1;
167
168 poFeature = GetNextFeature();
169 }
170 else
171 {
172 poCurrentReader->GetFPPos(&nCurrentPos, &nCurrentFID);
173 }
174
175 return poFeature;
176 }
177
178 /************************************************************************/
179 /* TestCapability() */
180 /************************************************************************/
181
TestCapability(const char *)182 int OGRNTFLayer::TestCapability( const char * /* pszCap */ )
183
184 {
185 return FALSE;
186 }
187
188 /************************************************************************/
189 /* FeatureTranslate() */
190 /************************************************************************/
191
FeatureTranslate(NTFFileReader * poReader,NTFRecord ** papoGroup)192 OGRFeature * OGRNTFLayer::FeatureTranslate( NTFFileReader *poReader,
193 NTFRecord ** papoGroup )
194
195 {
196 if( pfnTranslator == nullptr )
197 return nullptr;
198
199 return pfnTranslator( poReader, this, papoGroup );
200 }
201