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