1 : /******************************************************************************
2 : * $Id: sdtslinereader.cpp 10645 2007-01-18 02:22:39Z 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 10645 2007-01-18 02:22:39Z 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 55 : SDTSRawLine::SDTSRawLine()
48 :
49 : {
50 55 : nVertices = 0;
51 55 : padfX = padfY = padfZ = NULL;
52 55 : nAttributes = 0;
53 55 : }
54 :
55 : /************************************************************************/
56 : /* ~STDSRawLine() */
57 : /************************************************************************/
58 :
59 110 : SDTSRawLine::~SDTSRawLine()
60 :
61 : {
62 55 : 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 55 : int SDTSRawLine::Read( SDTS_IREF * poIREF, DDFRecord * poRecord )
74 :
75 : {
76 : 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 452 : for( int iField = 0; iField < poRecord->GetFieldCount(); iField++ )
85 : {
86 397 : DDFField *poField = poRecord->GetField( iField );
87 : const char *pszFieldName;
88 :
89 : CPLAssert( poField != NULL );
90 397 : pszFieldName = poField->GetFieldDefn()->GetName();
91 :
92 397 : if( EQUAL(pszFieldName,"LINE") )
93 55 : oModId.Set( poField );
94 :
95 342 : else if( EQUAL(pszFieldName,"ATID") )
96 12 : ApplyATID( poField );
97 :
98 330 : else if( EQUAL(pszFieldName,"PIDL") )
99 55 : oLeftPoly.Set( poField );
100 :
101 275 : else if( EQUAL(pszFieldName,"PIDR") )
102 55 : oRightPoly.Set( poField );
103 :
104 220 : else if( EQUAL(pszFieldName,"SNID") )
105 55 : oStartNode.Set( poField );
106 :
107 165 : else if( EQUAL(pszFieldName,"ENID") )
108 55 : oEndNode.Set( poField );
109 :
110 110 : else if( EQUAL(pszFieldName,"SADR") )
111 : {
112 55 : nVertices = poIREF->GetSADRCount( poField );
113 :
114 55 : padfX = (double*) CPLRealloc(padfX,sizeof(double)*nVertices*3);
115 55 : padfY = padfX + nVertices;
116 55 : padfZ = padfX + 2*nVertices;
117 :
118 55 : poIREF->GetSADR( poField, nVertices, padfX, padfY, padfZ );
119 : }
120 : }
121 :
122 55 : 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 1 : SDTSLineReader::SDTSLineReader( SDTS_IREF * poIREFIn )
175 :
176 : {
177 1 : poIREF = poIREFIn;
178 1 : }
179 :
180 : /************************************************************************/
181 : /* ~SDTSLineReader() */
182 : /************************************************************************/
183 :
184 2 : SDTSLineReader::~SDTSLineReader()
185 : {
186 1 : Close();
187 2 : }
188 :
189 : /************************************************************************/
190 : /* Close() */
191 : /************************************************************************/
192 :
193 1 : void SDTSLineReader::Close()
194 :
195 : {
196 1 : oDDFModule.Close();
197 1 : }
198 :
199 : /************************************************************************/
200 : /* Open() */
201 : /* */
202 : /* Open the requested line file, and prepare to start reading */
203 : /* data records. */
204 : /************************************************************************/
205 :
206 1 : int SDTSLineReader::Open( const char * pszFilename )
207 :
208 : {
209 1 : return( oDDFModule.Open( pszFilename ) );
210 : }
211 :
212 : /************************************************************************/
213 : /* GetNextLine() */
214 : /* */
215 : /* Fetch the next line feature as an STDSRawLine. */
216 : /************************************************************************/
217 :
218 57 : SDTSRawLine * SDTSLineReader::GetNextLine()
219 :
220 : {
221 : /* -------------------------------------------------------------------- */
222 : /* Are we initialized? */
223 : /* -------------------------------------------------------------------- */
224 57 : if( oDDFModule.GetFP() == NULL )
225 0 : return NULL;
226 :
227 : /* -------------------------------------------------------------------- */
228 : /* Read the record. */
229 : /* -------------------------------------------------------------------- */
230 57 : DDFRecord *poRecord = oDDFModule.ReadRecord();
231 :
232 57 : if( poRecord == NULL )
233 2 : return NULL;
234 :
235 : /* -------------------------------------------------------------------- */
236 : /* Transform into a line feature. */
237 : /* -------------------------------------------------------------------- */
238 55 : SDTSRawLine *poRawLine = new SDTSRawLine();
239 :
240 55 : if( poRawLine->Read( poIREF, poRecord ) )
241 : {
242 55 : 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 :
267 : */
268 :
269 1 : void SDTSLineReader::AttachToPolygons( SDTSTransfer * poTransfer )
270 :
271 : {
272 : /* -------------------------------------------------------------------- */
273 : /* We force a filling of the index because when we attach the */
274 : /* lines we are just providing a pointer back to the line */
275 : /* features in this readers index. If they aren't cached in */
276 : /* the index then the pointer will be invalid. */
277 : /* -------------------------------------------------------------------- */
278 1 : FillIndex();
279 :
280 : /* ==================================================================== */
281 : /* Loop over all lines, attaching them to the polygons they */
282 : /* have as right and left faces. */
283 : /* ==================================================================== */
284 : SDTSRawLine *poLine;
285 1 : SDTSPolygonReader *poPolyReader = NULL;
286 :
287 1 : Rewind();
288 29 : while( (poLine = (SDTSRawLine *) GetNextFeature()) != NULL )
289 : {
290 : /* -------------------------------------------------------------------- */
291 : /* Skip lines with the same left and right polygon face. These */
292 : /* are dangles, and will not contribute in any useful fashion */
293 : /* to the resulting polygon. */
294 : /* -------------------------------------------------------------------- */
295 27 : if( poLine->oLeftPoly.nRecord == poLine->oRightPoly.nRecord )
296 2 : continue;
297 :
298 : /* -------------------------------------------------------------------- */
299 : /* If we don't have our indexed polygon reader yet, try to get */
300 : /* it now. */
301 : /* -------------------------------------------------------------------- */
302 25 : if( poPolyReader == NULL )
303 : {
304 1 : int iPolyLayer = -1;
305 :
306 1 : if( poLine->oLeftPoly.nRecord != -1 )
307 : {
308 1 : iPolyLayer = poTransfer->FindLayer(poLine->oLeftPoly.szModule);
309 : }
310 0 : else if( poLine->oRightPoly.nRecord != -1 )
311 : {
312 0 : iPolyLayer = poTransfer->FindLayer(poLine->oRightPoly.szModule);
313 : }
314 :
315 1 : if( iPolyLayer == -1 )
316 0 : continue;
317 :
318 : poPolyReader = (SDTSPolygonReader *)
319 1 : poTransfer->GetLayerIndexedReader(iPolyLayer);
320 :
321 1 : if( poPolyReader == NULL )
322 0 : return;
323 : }
324 :
325 : /* -------------------------------------------------------------------- */
326 : /* Attach line to right and/or left polygons. */
327 : /* -------------------------------------------------------------------- */
328 25 : if( poLine->oLeftPoly.nRecord != -1 )
329 : {
330 : SDTSRawPolygon *poPoly;
331 :
332 : poPoly = (SDTSRawPolygon *) poPolyReader->GetIndexedFeatureRef(
333 25 : poLine->oLeftPoly.nRecord );
334 25 : if( poPoly != NULL )
335 25 : poPoly->AddEdge( poLine );
336 : }
337 :
338 25 : if( poLine->oRightPoly.nRecord != -1 )
339 : {
340 : SDTSRawPolygon *poPoly;
341 :
342 : poPoly = (SDTSRawPolygon *) poPolyReader->GetIndexedFeatureRef(
343 25 : poLine->oRightPoly.nRecord );
344 :
345 25 : if( poPoly != NULL )
346 25 : poPoly->AddEdge( poLine );
347 : }
348 : }
349 : }
|