1 : /******************************************************************************
2 : * $Id: sdtslinereader.cpp 19952 2010-07-02 05:44:18Z warmerdam $
3 : *
4 : * Project: SDTS Translator
5 : * Purpose: Implementation of SDTSLineReader and SDTSRawLine classes.
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 "sdts_al.h"
31 :
32 : CPL_CVSID("$Id: sdtslinereader.cpp 19952 2010-07-02 05:44:18Z warmerdam $");
33 :
34 : /************************************************************************/
35 : /* ==================================================================== */
36 : /* SDTSRawLine */
37 : /* */
38 : /* This is a simple class for holding the data related with a */
39 : /* line feature. */
40 : /* ==================================================================== */
41 : /************************************************************************/
42 :
43 : /************************************************************************/
44 : /* SDTSRawLine() */
45 : /************************************************************************/
46 :
47 110 : SDTSRawLine::SDTSRawLine()
48 :
49 : {
50 110 : nVertices = 0;
51 110 : padfX = padfY = padfZ = NULL;
52 110 : nAttributes = 0;
53 110 : }
54 :
55 : /************************************************************************/
56 : /* ~STDSRawLine() */
57 : /************************************************************************/
58 :
59 110 : SDTSRawLine::~SDTSRawLine()
60 :
61 : {
62 110 : CPLFree( padfX );
63 110 : }
64 :
65 : /************************************************************************/
66 : /* Read() */
67 : /* */
68 : /* Read a record from the passed SDTSLineReader, and assign the */
69 : /* values from that record to this line. This is the bulk of */
70 : /* the work in this whole file. */
71 : /************************************************************************/
72 :
73 110 : int SDTSRawLine::Read( SDTS_IREF * poIREF, DDFRecord * poRecord )
74 :
75 : {
76 110 : CPLAssert( poRecord->GetStringSubfield( "LINE", 0, "MODN", 0 ) != NULL );
77 :
78 : /* ==================================================================== */
79 : /* Loop over fields in this record, looking for those we */
80 : /* recognise, and need. I don't use the getSubfield() */
81 : /* interface on the record in order to retain some slight bit */
82 : /* of efficiency. */
83 : /* ==================================================================== */
84 904 : for( int iField = 0; iField < poRecord->GetFieldCount(); iField++ )
85 : {
86 794 : DDFField *poField = poRecord->GetField( iField );
87 : const char *pszFieldName;
88 :
89 794 : CPLAssert( poField != NULL );
90 794 : pszFieldName = poField->GetFieldDefn()->GetName();
91 :
92 794 : if( EQUAL(pszFieldName,"LINE") )
93 110 : oModId.Set( poField );
94 :
95 684 : else if( EQUAL(pszFieldName,"ATID") )
96 24 : ApplyATID( poField );
97 :
98 660 : else if( EQUAL(pszFieldName,"PIDL") )
99 110 : oLeftPoly.Set( poField );
100 :
101 550 : else if( EQUAL(pszFieldName,"PIDR") )
102 110 : oRightPoly.Set( poField );
103 :
104 440 : else if( EQUAL(pszFieldName,"SNID") )
105 110 : oStartNode.Set( poField );
106 :
107 330 : else if( EQUAL(pszFieldName,"ENID") )
108 110 : oEndNode.Set( poField );
109 :
110 220 : else if( EQUAL(pszFieldName,"SADR") )
111 : {
112 110 : nVertices = poIREF->GetSADRCount( poField );
113 :
114 110 : padfX = (double*) CPLRealloc(padfX,sizeof(double)*nVertices*3);
115 110 : padfY = padfX + nVertices;
116 110 : padfZ = padfX + 2*nVertices;
117 :
118 110 : poIREF->GetSADR( poField, nVertices, padfX, padfY, padfZ );
119 : }
120 : }
121 :
122 110 : return TRUE;
123 : }
124 :
125 : /************************************************************************/
126 : /* Dump() */
127 : /* */
128 : /* Write info about this object to a text file. */
129 : /************************************************************************/
130 :
131 0 : void SDTSRawLine::Dump( FILE * fp )
132 :
133 : {
134 : int i;
135 :
136 0 : fprintf( fp, "SDTSRawLine\n" );
137 : fprintf( fp, " Module=%s, Record#=%ld\n",
138 0 : oModId.szModule, oModId.nRecord );
139 0 : if( oLeftPoly.nRecord != -1 )
140 : fprintf( fp, " LeftPoly (Module=%s, Record=%ld)\n",
141 0 : oLeftPoly.szModule, oLeftPoly.nRecord );
142 0 : if( oRightPoly.nRecord != -1 )
143 : fprintf( fp, " RightPoly (Module=%s, Record=%ld)\n",
144 0 : oRightPoly.szModule, oRightPoly.nRecord );
145 0 : if( oStartNode.nRecord != -1 )
146 : fprintf( fp, " StartNode (Module=%s, Record=%ld)\n",
147 0 : oStartNode.szModule, oStartNode.nRecord );
148 0 : if( oEndNode.nRecord != -1 )
149 : fprintf( fp, " EndNode (Module=%s, Record=%ld)\n",
150 0 : oEndNode.szModule, oEndNode.nRecord );
151 0 : for( i = 0; i < nAttributes; i++ )
152 : fprintf( fp, " Attribute (Module=%s, Record=%ld)\n",
153 0 : paoATID[i].szModule, paoATID[i].nRecord );
154 :
155 0 : for( i = 0; i < nVertices; i++ )
156 : {
157 : fprintf( fp, " Vertex[%3d] = (%.2f,%.2f,%.2f)\n",
158 0 : i, padfX[i], padfY[i], padfZ[i] );
159 : }
160 0 : }
161 :
162 : /************************************************************************/
163 : /* ==================================================================== */
164 : /* SDTSLineReader */
165 : /* */
166 : /* This is the class used to read a line module. */
167 : /* ==================================================================== */
168 : /************************************************************************/
169 :
170 : /************************************************************************/
171 : /* SDTSLineReader() */
172 : /************************************************************************/
173 :
174 2 : SDTSLineReader::SDTSLineReader( SDTS_IREF * poIREFIn )
175 :
176 : {
177 2 : poIREF = poIREFIn;
178 2 : }
179 :
180 : /************************************************************************/
181 : /* ~SDTSLineReader() */
182 : /************************************************************************/
183 :
184 2 : SDTSLineReader::~SDTSLineReader()
185 : {
186 2 : Close();
187 2 : }
188 :
189 : /************************************************************************/
190 : /* Close() */
191 : /************************************************************************/
192 :
193 2 : void SDTSLineReader::Close()
194 :
195 : {
196 2 : oDDFModule.Close();
197 2 : }
198 :
199 : /************************************************************************/
200 : /* Open() */
201 : /* */
202 : /* Open the requested line file, and prepare to start reading */
203 : /* data records. */
204 : /************************************************************************/
205 :
206 2 : int SDTSLineReader::Open( const char * pszFilename )
207 :
208 : {
209 2 : return( oDDFModule.Open( pszFilename ) );
210 : }
211 :
212 : /************************************************************************/
213 : /* GetNextLine() */
214 : /* */
215 : /* Fetch the next line feature as an STDSRawLine. */
216 : /************************************************************************/
217 :
218 114 : SDTSRawLine * SDTSLineReader::GetNextLine()
219 :
220 : {
221 : /* -------------------------------------------------------------------- */
222 : /* Are we initialized? */
223 : /* -------------------------------------------------------------------- */
224 114 : if( oDDFModule.GetFP() == NULL )
225 0 : return NULL;
226 :
227 : /* -------------------------------------------------------------------- */
228 : /* Read the record. */
229 : /* -------------------------------------------------------------------- */
230 114 : DDFRecord *poRecord = oDDFModule.ReadRecord();
231 :
232 114 : if( poRecord == NULL )
233 4 : return NULL;
234 :
235 : /* -------------------------------------------------------------------- */
236 : /* Transform into a line feature. */
237 : /* -------------------------------------------------------------------- */
238 110 : SDTSRawLine *poRawLine = new SDTSRawLine();
239 :
240 110 : if( poRawLine->Read( poIREF, poRecord ) )
241 : {
242 110 : return( poRawLine );
243 : }
244 : else
245 : {
246 0 : delete poRawLine;
247 0 : return NULL;
248 : }
249 : }
250 :
251 : /************************************************************************/
252 : /* AttachToPolygons() */
253 : /* */
254 : /* Attach line features to all the polygon features they relate */
255 : /* to. */
256 : /************************************************************************/
257 :
258 : /**
259 : Attach lines in this module to their polygons as the first step in
260 : polygon formation.
261 :
262 : See also the SDTSRawPolygon::AssembleRings() method.
263 :
264 : @param poTransfer the SDTSTransfer of this SDTSLineReader, and from
265 : which the related SDTSPolygonReader will be instantiated.
266 : @param iTargetPolyLayer the polygon reader instance number, used to avoid
267 : processing lines for other layers.
268 :
269 : */
270 :
271 2 : void SDTSLineReader::AttachToPolygons( SDTSTransfer * poTransfer,
272 : int iTargetPolyLayer )
273 :
274 : {
275 : /* -------------------------------------------------------------------- */
276 : /* We force a filling of the index because when we attach the */
277 : /* lines we are just providing a pointer back to the line */
278 : /* features in this readers index. If they aren't cached in */
279 : /* the index then the pointer will be invalid. */
280 : /* -------------------------------------------------------------------- */
281 2 : FillIndex();
282 :
283 : /* ==================================================================== */
284 : /* Loop over all lines, attaching them to the polygons they */
285 : /* have as right and left faces. */
286 : /* ==================================================================== */
287 : SDTSRawLine *poLine;
288 2 : SDTSPolygonReader *poPolyReader = NULL;
289 :
290 2 : Rewind();
291 58 : while( (poLine = (SDTSRawLine *) GetNextFeature()) != NULL )
292 : {
293 : /* -------------------------------------------------------------------- */
294 : /* Skip lines with the same left and right polygon face. These */
295 : /* are dangles, and will not contribute in any useful fashion */
296 : /* to the resulting polygon. */
297 : /* -------------------------------------------------------------------- */
298 54 : if( poLine->oLeftPoly.nRecord == poLine->oRightPoly.nRecord )
299 4 : continue;
300 :
301 : /* -------------------------------------------------------------------- */
302 : /* If we don't have our indexed polygon reader yet, try to get */
303 : /* it now. */
304 : /* -------------------------------------------------------------------- */
305 50 : if( poPolyReader == NULL )
306 : {
307 2 : int iPolyLayer = -1;
308 :
309 2 : if( poLine->oLeftPoly.nRecord != -1 )
310 : {
311 2 : iPolyLayer = poTransfer->FindLayer(poLine->oLeftPoly.szModule);
312 : }
313 0 : else if( poLine->oRightPoly.nRecord != -1 )
314 : {
315 0 : iPolyLayer = poTransfer->FindLayer(poLine->oRightPoly.szModule);
316 : }
317 :
318 2 : if( iPolyLayer == -1 )
319 0 : continue;
320 :
321 2 : if( iPolyLayer != iTargetPolyLayer )
322 0 : continue;
323 :
324 : poPolyReader = (SDTSPolygonReader *)
325 2 : poTransfer->GetLayerIndexedReader(iPolyLayer);
326 :
327 2 : if( poPolyReader == NULL )
328 0 : return;
329 : }
330 :
331 : /* -------------------------------------------------------------------- */
332 : /* Attach line to right and/or left polygons. */
333 : /* -------------------------------------------------------------------- */
334 50 : if( poLine->oLeftPoly.nRecord != -1 )
335 : {
336 : SDTSRawPolygon *poPoly;
337 :
338 : poPoly = (SDTSRawPolygon *) poPolyReader->GetIndexedFeatureRef(
339 50 : poLine->oLeftPoly.nRecord );
340 50 : if( poPoly != NULL )
341 50 : poPoly->AddEdge( poLine );
342 : }
343 :
344 50 : if( poLine->oRightPoly.nRecord != -1 )
345 : {
346 : SDTSRawPolygon *poPoly;
347 :
348 : poPoly = (SDTSRawPolygon *) poPolyReader->GetIndexedFeatureRef(
349 50 : poLine->oRightPoly.nRecord );
350 :
351 50 : if( poPoly != NULL )
352 50 : poPoly->AddEdge( poLine );
353 : }
354 : }
355 : }
|