1 /******************************************************************************
2 *
3 * Project: UK NTF Reader
4 * Purpose: Implements OGRNTFFeatureClassLayer 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: ogrntffeatureclasslayer.cpp 7e07230bbff24eb333608de4dbd460b7312839d0 2017-12-11 19:08:47Z Even Rouault $")
33
34 /************************************************************************/
35 /* OGRNTFFeatureClassLayer() */
36 /* */
37 /* Note that the OGRNTFLayer assumes ownership of the passed */
38 /* OGRFeatureDefn object. */
39 /************************************************************************/
40
OGRNTFFeatureClassLayer(OGRNTFDataSource * poDSIn)41 OGRNTFFeatureClassLayer::OGRNTFFeatureClassLayer( OGRNTFDataSource *poDSIn ) :
42 poFeatureDefn(new OGRFeatureDefn("FEATURE_CLASSES")),
43 poFilterGeom(nullptr),
44 poDS(poDSIn),
45 iCurrentFC(0)
46 {
47 /* -------------------------------------------------------------------- */
48 /* Establish the schema. */
49 /* -------------------------------------------------------------------- */
50 SetDescription( poFeatureDefn->GetName() );
51 poFeatureDefn->SetGeomType( wkbNone );
52 poFeatureDefn->Reference();
53
54 OGRFieldDefn oFCNum( "FEAT_CODE", OFTString );
55
56 oFCNum.SetWidth( 4 );
57 poFeatureDefn->AddFieldDefn( &oFCNum );
58
59 OGRFieldDefn oFCName( "FC_NAME", OFTString );
60
61 oFCNum.SetWidth( 80 );
62 poFeatureDefn->AddFieldDefn( &oFCName );
63 }
64
65 /************************************************************************/
66 /* ~OGRNTFFeatureClassLayer() */
67 /************************************************************************/
68
~OGRNTFFeatureClassLayer()69 OGRNTFFeatureClassLayer::~OGRNTFFeatureClassLayer()
70
71 {
72 if( poFeatureDefn )
73 poFeatureDefn->Release();
74
75 if( poFilterGeom != nullptr )
76 delete poFilterGeom;
77 }
78
79 /************************************************************************/
80 /* SetSpatialFilter() */
81 /************************************************************************/
82
SetSpatialFilter(OGRGeometry * poGeomIn)83 void OGRNTFFeatureClassLayer::SetSpatialFilter( OGRGeometry * poGeomIn )
84
85 {
86 if( poFilterGeom != nullptr )
87 {
88 delete poFilterGeom;
89 poFilterGeom = nullptr;
90 }
91
92 if( poGeomIn != nullptr )
93 poFilterGeom = poGeomIn->clone();
94 }
95
96 /************************************************************************/
97 /* ResetReading() */
98 /************************************************************************/
99
ResetReading()100 void OGRNTFFeatureClassLayer::ResetReading()
101
102 {
103 iCurrentFC = 0;
104 }
105
106 /************************************************************************/
107 /* GetNextFeature() */
108 /************************************************************************/
109
GetNextFeature()110 OGRFeature *OGRNTFFeatureClassLayer::GetNextFeature()
111
112 {
113 if( iCurrentFC >= GetFeatureCount() )
114 return nullptr;
115
116 return GetFeature( (long) iCurrentFC++ );
117 }
118
119 /************************************************************************/
120 /* GetFeature() */
121 /************************************************************************/
122
GetFeature(GIntBig nFeatureId)123 OGRFeature *OGRNTFFeatureClassLayer::GetFeature( GIntBig nFeatureId )
124
125 {
126 char *pszFCName, *pszFCId;
127
128 if( nFeatureId < 0 || nFeatureId >= poDS->GetFCCount() )
129 return nullptr;
130
131 poDS->GetFeatureClass( (int)nFeatureId, &pszFCId, &pszFCName );
132
133 /* -------------------------------------------------------------------- */
134 /* Create a corresponding feature. */
135 /* -------------------------------------------------------------------- */
136 OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
137
138 poFeature->SetField( 0, pszFCId );
139 poFeature->SetField( 1, pszFCName );
140 poFeature->SetFID( nFeatureId );
141
142 return poFeature;
143 }
144
145 /************************************************************************/
146 /* GetFeatureCount() */
147 /* */
148 /* If a spatial filter is in effect, we turn control over to */
149 /* the generic counter. Otherwise we return the total count. */
150 /* Eventually we should consider implementing a more efficient */
151 /* way of counting features matching a spatial query. */
152 /************************************************************************/
153
GetFeatureCount(CPL_UNUSED int bForce)154 GIntBig OGRNTFFeatureClassLayer::GetFeatureCount( CPL_UNUSED int bForce )
155 {
156 return poDS->GetFCCount();
157 }
158
159 /************************************************************************/
160 /* TestCapability() */
161 /************************************************************************/
162
TestCapability(const char * pszCap)163 int OGRNTFFeatureClassLayer::TestCapability( const char * pszCap )
164
165 {
166 if( EQUAL(pszCap,OLCRandomRead) )
167 return TRUE;
168
169 else if( EQUAL(pszCap,OLCSequentialWrite)
170 || EQUAL(pszCap,OLCRandomWrite) )
171 return FALSE;
172
173 else if( EQUAL(pszCap,OLCFastFeatureCount) )
174 return TRUE;
175
176 else if( EQUAL(pszCap,OLCFastSpatialFilter) )
177 return TRUE;
178
179 else
180 return FALSE;
181 }
182