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