1 : /******************************************************************************
2 : * $Id: ogrdxfdatasource.cpp 18778 2010-02-10 20:50:00Z warmerdam $
3 : *
4 : * Project: DXF Translator
5 : * Purpose: Implements OGRDXFDataSource class
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2009, Frank Warmerdam <warmerdam@pobox.com>
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_dxf.h"
31 : #include "cpl_conv.h"
32 : #include "cpl_string.h"
33 :
34 : CPL_CVSID("$Id: ogrdxfdatasource.cpp 18778 2010-02-10 20:50:00Z warmerdam $");
35 :
36 : /************************************************************************/
37 : /* OGRDXFDataSource() */
38 : /************************************************************************/
39 :
40 43 : OGRDXFDataSource::OGRDXFDataSource()
41 :
42 : {
43 43 : fp = NULL;
44 :
45 43 : iSrcBufferOffset = 0;
46 43 : nSrcBufferBytes = 0;
47 43 : iSrcBufferFileOffset = 0;
48 :
49 43 : nLastValueSize = 0;
50 43 : }
51 :
52 : /************************************************************************/
53 : /* ~OGRDXFDataSource() */
54 : /************************************************************************/
55 :
56 43 : OGRDXFDataSource::~OGRDXFDataSource()
57 :
58 : {
59 : /* -------------------------------------------------------------------- */
60 : /* Destroy layers. */
61 : /* -------------------------------------------------------------------- */
62 92 : while( apoLayers.size() > 0 )
63 : {
64 6 : delete apoLayers.back();
65 6 : apoLayers.pop_back();
66 : }
67 :
68 : /* -------------------------------------------------------------------- */
69 : /* Close file. */
70 : /* -------------------------------------------------------------------- */
71 43 : if( fp != NULL )
72 : {
73 6 : VSIFCloseL( fp );
74 6 : fp = NULL;
75 : }
76 43 : }
77 :
78 : /************************************************************************/
79 : /* TestCapability() */
80 : /************************************************************************/
81 :
82 0 : int OGRDXFDataSource::TestCapability( const char * pszCap )
83 :
84 : {
85 0 : return FALSE;
86 : }
87 :
88 : /************************************************************************/
89 : /* GetLayer() */
90 : /************************************************************************/
91 :
92 :
93 6 : OGRLayer *OGRDXFDataSource::GetLayer( int iLayer )
94 :
95 : {
96 6 : if( iLayer < 0 || iLayer >= (int) apoLayers.size() )
97 0 : return NULL;
98 : else
99 6 : return apoLayers[iLayer];
100 : }
101 :
102 : /************************************************************************/
103 : /* Open() */
104 : /************************************************************************/
105 :
106 43 : int OGRDXFDataSource::Open( const char * pszFilename )
107 :
108 : {
109 43 : if( !EQUAL(CPLGetExtension(pszFilename),"dxf") )
110 37 : return FALSE;
111 :
112 6 : osName = pszFilename;
113 :
114 : /* -------------------------------------------------------------------- */
115 : /* Open the file. */
116 : /* -------------------------------------------------------------------- */
117 6 : fp = VSIFOpenL( pszFilename, "r" );
118 6 : if( fp == NULL )
119 0 : return FALSE;
120 :
121 : /* -------------------------------------------------------------------- */
122 : /* Confirm we have a header section. */
123 : /* -------------------------------------------------------------------- */
124 : char szLineBuf[257];
125 : int nCode;
126 6 : int bEntitiesOnly = FALSE;
127 :
128 6 : if( ReadValue( szLineBuf ) != 0 || !EQUAL(szLineBuf,"SECTION") )
129 0 : return FALSE;
130 :
131 6 : if( ReadValue( szLineBuf ) != 2
132 : || (!EQUAL(szLineBuf,"HEADER") && !EQUAL(szLineBuf,"ENTITIES")) )
133 0 : return FALSE;
134 :
135 6 : if( EQUAL(szLineBuf,"ENTITIES") )
136 3 : bEntitiesOnly = TRUE;
137 :
138 : /* -------------------------------------------------------------------- */
139 : /* Process the header, picking up a few useful pieces of */
140 : /* information. */
141 : /* -------------------------------------------------------------------- */
142 6 : if( !bEntitiesOnly )
143 : {
144 3 : ReadHeaderSection();
145 3 : ReadValue(szLineBuf);
146 :
147 : /* -------------------------------------------------------------------- */
148 : /* Process the CLASSES section, if present. */
149 : /* -------------------------------------------------------------------- */
150 3 : if( EQUAL(szLineBuf,"ENDSEC") )
151 0 : ReadValue(szLineBuf);
152 :
153 3 : if( EQUAL(szLineBuf,"SECTION") )
154 3 : ReadValue(szLineBuf);
155 :
156 3 : if( EQUAL(szLineBuf,"CLASSES") )
157 : {
158 17 : while( (nCode = ReadValue( szLineBuf,sizeof(szLineBuf) )) > -1
159 : && !EQUAL(szLineBuf,"ENDSEC") )
160 : {
161 : //printf("C:%d/%s\n", nCode, szLineBuf );
162 : }
163 : }
164 :
165 : /* -------------------------------------------------------------------- */
166 : /* Process the TABLES section, if present. */
167 : /* -------------------------------------------------------------------- */
168 3 : if( EQUAL(szLineBuf,"ENDSEC") )
169 1 : ReadValue(szLineBuf);
170 :
171 3 : if( EQUAL(szLineBuf,"SECTION") )
172 1 : ReadValue(szLineBuf);
173 :
174 3 : if( EQUAL(szLineBuf,"TABLES") )
175 : {
176 2 : ReadTablesSection();
177 2 : ReadValue(szLineBuf);
178 : }
179 : }
180 :
181 : /* -------------------------------------------------------------------- */
182 : /* Create out layer object - we will need it when interpreting */
183 : /* blocks. */
184 : /* -------------------------------------------------------------------- */
185 6 : apoLayers.push_back( new OGRDXFLayer( this ) );
186 :
187 : /* -------------------------------------------------------------------- */
188 : /* Process the BLOCKS section if present. */
189 : /* -------------------------------------------------------------------- */
190 6 : if( !bEntitiesOnly )
191 : {
192 3 : if( EQUAL(szLineBuf,"ENDSEC") )
193 0 : ReadValue(szLineBuf);
194 :
195 3 : if( EQUAL(szLineBuf,"SECTION") )
196 2 : ReadValue(szLineBuf);
197 :
198 3 : if( EQUAL(szLineBuf,"BLOCKS") )
199 : {
200 3 : ReadBlocksSection();
201 3 : ReadValue(szLineBuf);
202 : }
203 : }
204 :
205 : /* -------------------------------------------------------------------- */
206 : /* Now we are at the entities section, hopefully. Confirm. */
207 : /* -------------------------------------------------------------------- */
208 6 : if( EQUAL(szLineBuf,"SECTION") )
209 3 : ReadValue(szLineBuf);
210 :
211 6 : if( !EQUAL(szLineBuf,"ENTITIES") )
212 0 : return FALSE;
213 :
214 6 : iEntitiesSectionOffset = iSrcBufferFileOffset + iSrcBufferOffset;
215 6 : apoLayers[0]->ResetReading();
216 :
217 6 : return TRUE;
218 : }
219 :
220 : /************************************************************************/
221 : /* ReadTablesSection() */
222 : /************************************************************************/
223 :
224 2 : void OGRDXFDataSource::ReadTablesSection()
225 :
226 : {
227 : char szLineBuf[257];
228 : int nCode;
229 :
230 703 : while( (nCode = ReadValue( szLineBuf, sizeof(szLineBuf) )) > -1
231 : && !EQUAL(szLineBuf,"ENDSEC") )
232 : {
233 : // We are only interested in extracting tables.
234 699 : if( nCode != 0 || !EQUAL(szLineBuf,"TABLE") )
235 681 : continue;
236 :
237 : // Currently we are only interested in the LAYER table.
238 18 : nCode = ReadValue( szLineBuf, sizeof(szLineBuf) );
239 :
240 18 : if( nCode != 2 || !EQUAL(szLineBuf,"LAYER") )
241 16 : continue;
242 :
243 13 : while( (nCode = ReadValue( szLineBuf, sizeof(szLineBuf) )) > -1
244 : && !EQUAL(szLineBuf,"ENDTAB") )
245 : {
246 9 : if( nCode == 0 && EQUAL(szLineBuf,"LAYER") )
247 2 : ReadLayerDefinition();
248 : }
249 : }
250 :
251 2 : CPLDebug( "DXF", "Read %d layer definitions.", (int) oLayerTable.size() );
252 2 : }
253 :
254 : /************************************************************************/
255 : /* ReadLayerDefinition() */
256 : /************************************************************************/
257 :
258 2 : void OGRDXFDataSource::ReadLayerDefinition()
259 :
260 : {
261 : char szLineBuf[257];
262 : int nCode;
263 2 : std::map<CPLString,CPLString> oLayerProperties;
264 2 : CPLString osLayerName = "";
265 :
266 23 : while( (nCode = ReadValue( szLineBuf, sizeof(szLineBuf) )) > 0 )
267 : {
268 19 : switch( nCode )
269 : {
270 : case 2:
271 2 : osLayerName = szLineBuf;
272 2 : break;
273 :
274 : case 6:
275 2 : oLayerProperties["Linetype"] = szLineBuf;
276 2 : break;
277 :
278 : case 62:
279 2 : oLayerProperties["Color"] = szLineBuf;
280 2 : break;
281 :
282 : case 70:
283 2 : oLayerProperties["Flags"] = szLineBuf;
284 2 : break;
285 :
286 : case 370:
287 : case 39:
288 2 : oLayerProperties["LineWeight"] = szLineBuf;
289 : break;
290 :
291 : default:
292 : break;
293 : }
294 : }
295 :
296 2 : if( oLayerProperties.size() > 0 )
297 2 : oLayerTable[osLayerName] = oLayerProperties;
298 :
299 2 : UnreadValue();
300 2 : }
301 :
302 : /************************************************************************/
303 : /* LookupLayerProperty() */
304 : /************************************************************************/
305 :
306 : const char *OGRDXFDataSource::LookupLayerProperty( const char *pszLayer,
307 37 : const char *pszProperty )
308 :
309 : {
310 37 : if( pszLayer == NULL )
311 0 : return NULL;
312 :
313 : try {
314 37 : return (oLayerTable[pszLayer])[pszProperty];
315 0 : } catch( ... ) {
316 0 : return NULL;
317 : }
318 : }
319 :
320 : /************************************************************************/
321 : /* ReadHeaderSection() */
322 : /************************************************************************/
323 :
324 3 : void OGRDXFDataSource::ReadHeaderSection()
325 :
326 : {
327 : char szLineBuf[257];
328 : int nCode;
329 :
330 1058 : while( (nCode = ReadValue( szLineBuf, sizeof(szLineBuf) )) > -1
331 : && !EQUAL(szLineBuf,"ENDSEC") )
332 : {
333 579 : if( nCode != 9 )
334 106 : continue;
335 :
336 473 : CPLString osName = szLineBuf;
337 :
338 473 : ReadValue( szLineBuf, sizeof(szLineBuf) );
339 :
340 473 : CPLString osValue = szLineBuf;
341 :
342 473 : oHeaderVariables[osName] = osValue;
343 : }
344 :
345 : CPLDebug( "DXF", "Read %d header variables.",
346 3 : (int) oHeaderVariables.size() );
347 3 : }
348 :
349 : /************************************************************************/
350 : /* GetVariable() */
351 : /* */
352 : /* Fetch a variable that came from the HEADER section. */
353 : /************************************************************************/
354 :
355 : const char *OGRDXFDataSource::GetVariable( const char *pszName,
356 8 : const char *pszDefault )
357 :
358 : {
359 8 : if( oHeaderVariables.count(pszName) == 0 )
360 4 : return pszDefault;
361 : else
362 4 : return oHeaderVariables[pszName];
363 : }
364 :
|