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 : OGRS57Layer::OGRS57Layer( OGRS57DataSource *poDSIn,
44 : OGRFeatureDefn * poDefnIn,
45 : int nFeatureCountIn,
46 34 : int nOBJLIn)
47 :
48 : {
49 34 : poDS = poDSIn;
50 :
51 34 : nFeatureCount = nFeatureCountIn;
52 :
53 34 : poFeatureDefn = poDefnIn;
54 :
55 34 : nOBJL = nOBJLIn;
56 :
57 34 : nNextFEIndex = 0;
58 34 : nCurrentModule = -1;
59 :
60 34 : if( EQUAL(poDefnIn->GetName(),OGRN_VI) )
61 0 : nRCNM = RCNM_VI;
62 34 : else if( EQUAL(poDefnIn->GetName(),OGRN_VC) )
63 0 : nRCNM = RCNM_VC;
64 34 : else if( EQUAL(poDefnIn->GetName(),OGRN_VE) )
65 0 : nRCNM = RCNM_VE;
66 34 : else if( EQUAL(poDefnIn->GetName(),OGRN_VF) )
67 0 : nRCNM = RCNM_VF;
68 34 : else if( EQUAL(poDefnIn->GetName(),"DSID") )
69 3 : nRCNM = RCNM_DSID;
70 : else
71 31 : nRCNM = 100; /* feature */
72 34 : }
73 :
74 : /************************************************************************/
75 : /* ~OGRS57Layer() */
76 : /************************************************************************/
77 :
78 34 : OGRS57Layer::~OGRS57Layer()
79 :
80 : {
81 34 : if( m_nFeaturesRead > 0 && poFeatureDefn != NULL )
82 : {
83 : CPLDebug( "S57", "%d features read on layer '%s'.",
84 : (int) m_nFeaturesRead,
85 6 : poFeatureDefn->GetName() );
86 : }
87 :
88 34 : poFeatureDefn->Release();
89 34 : }
90 :
91 : /************************************************************************/
92 : /* ResetReading() */
93 : /************************************************************************/
94 :
95 2 : void OGRS57Layer::ResetReading()
96 :
97 : {
98 2 : nNextFEIndex = 0;
99 2 : nCurrentModule = -1;
100 2 : }
101 :
102 : /************************************************************************/
103 : /* GetNextUnfilteredFeature() */
104 : /************************************************************************/
105 :
106 14 : OGRFeature *OGRS57Layer::GetNextUnfilteredFeature()
107 :
108 : {
109 14 : OGRFeature *poFeature = NULL;
110 :
111 : /* -------------------------------------------------------------------- */
112 : /* Are we out of modules to request features from? */
113 : /* -------------------------------------------------------------------- */
114 14 : if( nCurrentModule >= poDS->GetModuleCount() )
115 1 : return NULL;
116 :
117 : /* -------------------------------------------------------------------- */
118 : /* Set the current position on the current module and fetch a */
119 : /* feature. */
120 : /* -------------------------------------------------------------------- */
121 13 : S57Reader *poReader = poDS->GetModule(nCurrentModule);
122 :
123 13 : if( poReader != NULL )
124 : {
125 7 : poReader->SetNextFEIndex( nNextFEIndex, nRCNM );
126 7 : poFeature = poReader->ReadNextFeature( poFeatureDefn );
127 7 : 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 13 : if( poFeature == NULL )
134 : {
135 7 : nCurrentModule++;
136 7 : poReader = poDS->GetModule(nCurrentModule);
137 :
138 7 : if( poReader != NULL && poReader->GetModule() == NULL )
139 : {
140 0 : if( !poReader->Open( FALSE ) )
141 0 : return NULL;
142 : }
143 :
144 7 : return GetNextUnfilteredFeature();
145 : }
146 : else
147 : {
148 6 : m_nFeaturesRead++;
149 6 : if( poFeature->GetGeometryRef() != NULL )
150 : poFeature->GetGeometryRef()->assignSpatialReference(
151 4 : GetSpatialRef() );
152 : }
153 :
154 6 : return poFeature;
155 : }
156 :
157 : /************************************************************************/
158 : /* GetNextFeature() */
159 : /************************************************************************/
160 :
161 7 : OGRFeature *OGRS57Layer::GetNextFeature()
162 :
163 : {
164 7 : 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 7 : poFeature = GetNextUnfilteredFeature();
173 7 : if( poFeature == NULL )
174 1 : break;
175 :
176 6 : if( (m_poFilterGeom == NULL
177 : || FilterGeometry(poFeature->GetGeometryRef()) )
178 : && (m_poAttrQuery == NULL
179 : || m_poAttrQuery->Evaluate( poFeature )) )
180 6 : break;
181 :
182 0 : delete poFeature;
183 : }
184 :
185 7 : return poFeature;
186 : }
187 :
188 : /************************************************************************/
189 : /* TestCapability() */
190 : /************************************************************************/
191 :
192 13 : int OGRS57Layer::TestCapability( const char * pszCap )
193 :
194 : {
195 13 : if( EQUAL(pszCap,OLCRandomRead) )
196 0 : return FALSE;
197 :
198 13 : else if( EQUAL(pszCap,OLCSequentialWrite) )
199 0 : return TRUE;
200 :
201 13 : else if( EQUAL(pszCap,OLCRandomWrite) )
202 0 : return FALSE;
203 :
204 13 : 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 13 : (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 4 : OGRSpatialReference *OGRS57Layer::GetSpatialRef()
229 :
230 : {
231 4 : 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 13 : int OGRS57Layer::GetFeatureCount (int bForce)
248 : {
249 :
250 13 : if( !TestCapability(OLCFastFeatureCount) )
251 1 : return OGRLayer::GetFeatureCount( bForce );
252 : else
253 12 : return nFeatureCount;
254 : }
255 :
256 : /************************************************************************/
257 : /* GetFeature() */
258 : /************************************************************************/
259 :
260 0 : OGRFeature *OGRS57Layer::GetFeature( long nFeatureId )
261 :
262 : {
263 0 : S57Reader *poReader = poDS->GetModule(0); // not multi-reader aware
264 :
265 0 : if( poReader != NULL )
266 : {
267 : OGRFeature *poFeature;
268 :
269 0 : poFeature = poReader->ReadFeature( nFeatureId, poFeatureDefn );
270 0 : if( poFeature != NULL && poFeature->GetGeometryRef() != NULL )
271 : poFeature->GetGeometryRef()->assignSpatialReference(
272 0 : GetSpatialRef() );
273 0 : 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 : }
|