1 : /******************************************************************************
2 : * $Id: ogrs57layer.cpp 17953 2009-11-02 21:13:56Z rouault $
3 : *
4 : * Project: S-57 Translator
5 : * Purpose: Implements OGRS57Layer 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_s57.h"
31 : #include "cpl_conv.h"
32 : #include "cpl_string.h"
33 :
34 : CPL_CVSID("$Id: ogrs57layer.cpp 17953 2009-11-02 21:13:56Z rouault $");
35 :
36 : /************************************************************************/
37 : /* OGRS57Layer() */
38 : /* */
39 : /* Note that the OGRS57Layer assumes ownership of the passed */
40 : /* OGRFeatureDefn object. */
41 : /************************************************************************/
42 :
43 356 : OGRS57Layer::OGRS57Layer( OGRS57DataSource *poDSIn,
44 : OGRFeatureDefn * poDefnIn,
45 : int nFeatureCountIn,
46 356 : int nOBJLIn)
47 :
48 : {
49 356 : poDS = poDSIn;
50 :
51 356 : nFeatureCount = nFeatureCountIn;
52 :
53 356 : poFeatureDefn = poDefnIn;
54 :
55 356 : nOBJL = nOBJLIn;
56 :
57 356 : nNextFEIndex = 0;
58 356 : nCurrentModule = -1;
59 :
60 356 : if( EQUAL(poDefnIn->GetName(),OGRN_VI) )
61 0 : nRCNM = RCNM_VI;
62 356 : else if( EQUAL(poDefnIn->GetName(),OGRN_VC) )
63 0 : nRCNM = RCNM_VC;
64 356 : else if( EQUAL(poDefnIn->GetName(),OGRN_VE) )
65 0 : nRCNM = RCNM_VE;
66 356 : else if( EQUAL(poDefnIn->GetName(),OGRN_VF) )
67 0 : nRCNM = RCNM_VF;
68 356 : else if( EQUAL(poDefnIn->GetName(),"DSID") )
69 12 : nRCNM = RCNM_DSID;
70 : else
71 344 : nRCNM = 100; /* feature */
72 356 : }
73 :
74 : /************************************************************************/
75 : /* ~OGRS57Layer() */
76 : /************************************************************************/
77 :
78 356 : OGRS57Layer::~OGRS57Layer()
79 :
80 : {
81 356 : if( m_nFeaturesRead > 0 && poFeatureDefn != NULL )
82 : {
83 : CPLDebug( "S57", "%d features read on layer '%s'.",
84 : (int) m_nFeaturesRead,
85 14 : poFeatureDefn->GetName() );
86 : }
87 :
88 356 : poFeatureDefn->Release();
89 356 : }
90 :
91 : /************************************************************************/
92 : /* ResetReading() */
93 : /************************************************************************/
94 :
95 4 : void OGRS57Layer::ResetReading()
96 :
97 : {
98 4 : nNextFEIndex = 0;
99 4 : nCurrentModule = -1;
100 4 : }
101 :
102 : /************************************************************************/
103 : /* GetNextUnfilteredFeature() */
104 : /************************************************************************/
105 :
106 32 : OGRFeature *OGRS57Layer::GetNextUnfilteredFeature()
107 :
108 : {
109 32 : OGRFeature *poFeature = NULL;
110 :
111 : /* -------------------------------------------------------------------- */
112 : /* Are we out of modules to request features from? */
113 : /* -------------------------------------------------------------------- */
114 32 : if( nCurrentModule >= poDS->GetModuleCount() )
115 2 : return NULL;
116 :
117 : /* -------------------------------------------------------------------- */
118 : /* Set the current position on the current module and fetch a */
119 : /* feature. */
120 : /* -------------------------------------------------------------------- */
121 30 : S57Reader *poReader = poDS->GetModule(nCurrentModule);
122 :
123 30 : if( poReader != NULL )
124 : {
125 16 : poReader->SetNextFEIndex( nNextFEIndex, nRCNM );
126 16 : poFeature = poReader->ReadNextFeature( poFeatureDefn );
127 16 : nNextFEIndex = poReader->GetNextFEIndex( nRCNM );
128 : }
129 :
130 : /* -------------------------------------------------------------------- */
131 : /* If we didn't get a feature we need to move onto the next file. */
132 : /* -------------------------------------------------------------------- */
133 30 : if( poFeature == NULL )
134 : {
135 16 : nCurrentModule++;
136 16 : poReader = poDS->GetModule(nCurrentModule);
137 :
138 16 : if( poReader != NULL && poReader->GetModule() == NULL )
139 : {
140 0 : if( !poReader->Open( FALSE ) )
141 0 : return NULL;
142 : }
143 :
144 16 : return GetNextUnfilteredFeature();
145 : }
146 : else
147 : {
148 14 : m_nFeaturesRead++;
149 14 : if( poFeature->GetGeometryRef() != NULL )
150 : poFeature->GetGeometryRef()->assignSpatialReference(
151 10 : GetSpatialRef() );
152 : }
153 :
154 14 : return poFeature;
155 : }
156 :
157 : /************************************************************************/
158 : /* GetNextFeature() */
159 : /************************************************************************/
160 :
161 16 : OGRFeature *OGRS57Layer::GetNextFeature()
162 :
163 : {
164 16 : OGRFeature *poFeature = NULL;
165 :
166 : /* -------------------------------------------------------------------- */
167 : /* Read features till we find one that satisfies our current */
168 : /* spatial criteria. */
169 : /* -------------------------------------------------------------------- */
170 0 : while( TRUE )
171 : {
172 16 : poFeature = GetNextUnfilteredFeature();
173 16 : if( poFeature == NULL )
174 2 : break;
175 :
176 14 : if( (m_poFilterGeom == NULL
177 : || FilterGeometry(poFeature->GetGeometryRef()) )
178 : && (m_poAttrQuery == NULL
179 : || m_poAttrQuery->Evaluate( poFeature )) )
180 14 : break;
181 :
182 0 : delete poFeature;
183 : }
184 :
185 16 : return poFeature;
186 : }
187 :
188 : /************************************************************************/
189 : /* TestCapability() */
190 : /************************************************************************/
191 :
192 26 : int OGRS57Layer::TestCapability( const char * pszCap )
193 :
194 : {
195 26 : if( EQUAL(pszCap,OLCRandomRead) )
196 0 : return FALSE;
197 :
198 26 : else if( EQUAL(pszCap,OLCSequentialWrite) )
199 0 : return TRUE;
200 :
201 26 : else if( EQUAL(pszCap,OLCRandomWrite) )
202 0 : return FALSE;
203 :
204 26 : else if( EQUAL(pszCap,OLCFastFeatureCount) )
205 : return !(m_poFilterGeom != NULL || m_poAttrQuery != NULL
206 : || nFeatureCount == -1 ||
207 : ( EQUAL(poFeatureDefn->GetName(), "SOUNDG") &&
208 : poDS->GetModule(0) != NULL &&
209 26 : (poDS->GetModule(0)->GetOptionFlags() & S57M_SPLIT_MULTIPOINT)));
210 :
211 0 : else if( EQUAL(pszCap,OLCFastGetExtent) )
212 : {
213 0 : OGREnvelope oEnvelope;
214 :
215 0 : return GetExtent( &oEnvelope, FALSE ) == OGRERR_NONE;
216 : }
217 0 : else if( EQUAL(pszCap,OLCFastSpatialFilter) )
218 0 : return FALSE;
219 :
220 : else
221 0 : return FALSE;
222 : }
223 :
224 : /************************************************************************/
225 : /* GetSpatialRef() */
226 : /************************************************************************/
227 :
228 16 : OGRSpatialReference *OGRS57Layer::GetSpatialRef()
229 :
230 : {
231 16 : return poDS->GetSpatialRef();
232 : }
233 :
234 : /************************************************************************/
235 : /* GetExtent() */
236 : /************************************************************************/
237 :
238 0 : OGRErr OGRS57Layer::GetExtent( OGREnvelope *psExtent, int bForce )
239 :
240 : {
241 0 : return poDS->GetDSExtent( psExtent, bForce );
242 : }
243 :
244 : /************************************************************************/
245 : /* GetFeatureCount() */
246 : /************************************************************************/
247 26 : int OGRS57Layer::GetFeatureCount (int bForce)
248 : {
249 :
250 26 : if( !TestCapability(OLCFastFeatureCount) )
251 2 : return OGRLayer::GetFeatureCount( bForce );
252 : else
253 24 : return nFeatureCount;
254 : }
255 :
256 : /************************************************************************/
257 : /* GetFeature() */
258 : /************************************************************************/
259 :
260 8 : OGRFeature *OGRS57Layer::GetFeature( long nFeatureId )
261 :
262 : {
263 8 : S57Reader *poReader = poDS->GetModule(0); // not multi-reader aware
264 :
265 8 : if( poReader != NULL )
266 : {
267 : OGRFeature *poFeature;
268 :
269 8 : poFeature = poReader->ReadFeature( nFeatureId, poFeatureDefn );
270 8 : if( poFeature != NULL && poFeature->GetGeometryRef() != NULL )
271 : poFeature->GetGeometryRef()->assignSpatialReference(
272 6 : GetSpatialRef() );
273 8 : return poFeature;
274 : }
275 : else
276 0 : return NULL;
277 : }
278 :
279 : /************************************************************************/
280 : /* CreateFeature() */
281 : /************************************************************************/
282 :
283 0 : OGRErr OGRS57Layer::CreateFeature( OGRFeature *poFeature )
284 :
285 : {
286 : /* -------------------------------------------------------------------- */
287 : /* Set RCNM if not already set. */
288 : /* -------------------------------------------------------------------- */
289 0 : int iRCNMFld = poFeature->GetFieldIndex( "RCNM" );
290 :
291 0 : if( iRCNMFld != -1 )
292 : {
293 0 : if( !poFeature->IsFieldSet( iRCNMFld ) )
294 0 : poFeature->SetField( iRCNMFld, nRCNM );
295 : else
296 0 : CPLAssert( poFeature->GetFieldAsInteger( iRCNMFld ) == nRCNM );
297 : }
298 :
299 : /* -------------------------------------------------------------------- */
300 : /* Set OBJL if not already set. */
301 : /* -------------------------------------------------------------------- */
302 0 : if( nOBJL != -1 )
303 : {
304 0 : int iOBJLFld = poFeature->GetFieldIndex( "OBJL" );
305 :
306 0 : if( !poFeature->IsFieldSet( iOBJLFld ) )
307 0 : poFeature->SetField( iOBJLFld, nOBJL );
308 : else
309 0 : CPLAssert( poFeature->GetFieldAsInteger( iOBJLFld ) == nOBJL );
310 : }
311 :
312 : /* -------------------------------------------------------------------- */
313 : /* Create the isolated node feature. */
314 : /* -------------------------------------------------------------------- */
315 0 : if( poDS->GetWriter()->WriteCompleteFeature( poFeature ) )
316 0 : return OGRERR_NONE;
317 : else
318 0 : return OGRERR_FAILURE;
319 : }
|