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