1 /******************************************************************************
2  * $Id: ogr_dwg.h db7b8a03d90637c2f6ba5cbdb087e2819d8ec8dd 2018-05-12 22:34:30 +0200 Even Rouault $
3  *
4  * Project:  DWG Translator
5  * Purpose:  Definition of classes for OGR .dwg driver.
6  * Author:   Frank Warmerdam, warmerdam@pobox.com
7  *
8  ******************************************************************************
9  * Copyright (c) 2011,  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 #ifndef OGR_DWG_H_INCLUDED
31 #define OGR_DWG_H_INCLUDED
32 
33 #include "ogrsf_frmts.h"
34 #include "cpl_conv.h"
35 #include <vector>
36 #include <map>
37 #include <set>
38 #include <queue>
39 
40 #include "ogr_autocad_services.h"
41 #include "dwg_headers.h"
42 
43 class OGRDWGDataSource;
44 class OGRDWGServices;
45 
46 /************************************************************************/
47 /*                          DWGBlockDefinition                          */
48 /*                                                                      */
49 /*      Container for info about a block.                               */
50 /************************************************************************/
51 
52 class DWGBlockDefinition
53 {
54 public:
DWGBlockDefinition()55     DWGBlockDefinition() : poGeometry(nullptr) {}
56     ~DWGBlockDefinition();
57 
58     OGRGeometry                *poGeometry;
59     std::vector<OGRFeature *>  apoFeatures;
60 };
61 
62 /************************************************************************/
63 /*                         OGRDWGBlocksLayer()                          */
64 /************************************************************************/
65 
66 class OGRDWGBlocksLayer final: public OGRLayer
67 {
68     OGRDWGDataSource   *poDS;
69 
70     OGRFeatureDefn     *poFeatureDefn;
71 
72     int                 iNextFID;
73     unsigned int        iNextSubFeature;
74 
75     std::map<CPLString,DWGBlockDefinition>::iterator oIt;
76 
77   public:
78     explicit OGRDWGBlocksLayer( OGRDWGDataSource *poDS );
79     ~OGRDWGBlocksLayer();
80 
81     void                ResetReading() override;
82     OGRFeature *        GetNextFeature() override;
83 
GetLayerDefn()84     OGRFeatureDefn *    GetLayerDefn() override { return poFeatureDefn; }
85 
86     int                 TestCapability( const char * ) override;
87 
88     OGRFeature *        GetNextUnfilteredFeature();
89 };
90 
91 /************************************************************************/
92 /*                             OGRDWGLayer                              */
93 /************************************************************************/
94 class OGRDWGLayer final: public OGRLayer
95 {
96     OGRDWGDataSource   *poDS;
97 
98     OGRFeatureDefn     *poFeatureDefn;
99     int                 iNextFID;
100 
101     std::set<CPLString> oIgnoredEntities;
102 
103     std::queue<OGRFeature*> apoPendingFeatures;
104     void                ClearPendingFeatures();
105 
106     std::map<CPLString,CPLString> oStyleProperties;
107 
108     void                TranslateGenericProperties( OGRFeature *poFeature,
109                                                     OdDbEntityPtr poEntity );
110     void                PrepareLineStyle( OGRFeature *poFeature );
111 //    void                ApplyOCSTransformer( OGRGeometry * );
112 
113     OGRFeature *        TranslatePOINT( OdDbEntityPtr poEntity );
114     OGRFeature *        TranslateLINE( OdDbEntityPtr poEntity );
115     OGRFeature *        TranslateLWPOLYLINE( OdDbEntityPtr poEntity );
116     OGRFeature *        Translate2DPOLYLINE( OdDbEntityPtr poEntity );
117     OGRFeature *        Translate3DPOLYLINE( OdDbEntityPtr poEntity );
118     OGRFeature *        TranslateELLIPSE( OdDbEntityPtr poEntity );
119     OGRFeature *        TranslateARC( OdDbEntityPtr poEntity );
120     OGRFeature *        TranslateMTEXT( OdDbEntityPtr poEntity );
121     OGRFeature *        TranslateDIMENSION( OdDbEntityPtr poEntity );
122     OGRFeature *        TranslateCIRCLE( OdDbEntityPtr poEntity );
123     OGRFeature *        TranslateSPLINE( OdDbEntityPtr poEntity );
124     OGRFeature *        TranslateHATCH( OdDbEntityPtr poEntity );
125     OGRFeature *        TranslateTEXT( OdDbEntityPtr poEntity );
126     OGRFeature *        TranslateINSERT( OdDbEntityPtr poEntity );
127 
128     void                FormatDimension( CPLString &osText, double dfValue );
129 
130     CPLString           TextUnescape( OdString oString, bool );
131 
132     OdDbBlockTableRecordPtr m_poBlock;
133     OdDbObjectIteratorPtr   poEntIter;
134 
135   public:
136     explicit OGRDWGLayer( OGRDWGDataSource *poDS );
137     ~OGRDWGLayer();
138 
139     void                ResetReading() override;
140     OGRFeature *        GetNextFeature() override;
141 
GetLayerDefn()142     OGRFeatureDefn *    GetLayerDefn() override { return poFeatureDefn; }
143 
144     int                 TestCapability( const char * ) override;
145 
146     OGRFeature *        GetNextUnfilteredFeature();
147 
148     // internal
149     void                SetBlockTable( OdDbBlockTableRecordPtr );
150     static double       AngleCorrect( double dfAngle, double dfRatio );
151 };
152 
153 /************************************************************************/
154 /*                           OGRDWGDataSource                           */
155 /************************************************************************/
156 
157 class OGRDWGDataSource final: public OGRDataSource
158 {
159     VSILFILE           *fp;
160 
161     CPLString           m_osName;
162     std::vector<OGRLayer*> apoLayers;
163 
164     int                 iEntitiesSectionOffset;
165 
166     std::map<CPLString,DWGBlockDefinition> oBlockMap;
167     std::map<CPLString,CPLString> oHeaderVariables;
168 
169     CPLString           osEncoding;
170 
171     // indexed by layer name, then by property name.
172     std::map< CPLString, std::map<CPLString,CPLString> >
173                         oLayerTable;
174 
175     std::map<CPLString,CPLString> oLineTypeTable;
176 
177     int                 bInlineBlocks;
178 
179     OGRDWGServices     *poServices;
180     OdDbDatabasePtr     poDb;
181 
182   public:
183                         OGRDWGDataSource();
184                         ~OGRDWGDataSource();
185 
GetDB()186     OdDbDatabasePtr     GetDB() { return poDb; }
187 
188     int                 Open( OGRDWGServices *poServices,
189                               const char * pszFilename, int bHeaderOnly=FALSE );
190 
GetName()191     const char          *GetName() override { return m_osName; }
192 
GetLayerCount()193     int                 GetLayerCount() override { return static_cast<int>(apoLayers.size()); }
194     OGRLayer            *GetLayer( int ) override;
195 
196     int                 TestCapability( const char * ) override;
197 
198     // The following is only used by OGRDWGLayer
199 
InlineBlocks()200     int                 InlineBlocks() { return bInlineBlocks; }
201     void                AddStandardFields( OGRFeatureDefn *poDef );
202 
203     // Implemented in ogrdxf_blockmap.cpp
204     void                ReadBlocksSection();
205     OGRGeometry        *SimplifyBlockGeometry( OGRGeometryCollection * );
206     DWGBlockDefinition *LookupBlock( const char *pszName );
GetBlockMap()207     std::map<CPLString,DWGBlockDefinition> &GetBlockMap() { return oBlockMap; }
208 
209     // Layer and other Table Handling (ogrdatasource.cpp)
210     void                ReadLayerDefinitions();
211     void                ReadLineTypeDefinitions();
212     const char         *LookupLayerProperty( const char *pszLayer,
213                                              const char *pszProperty );
214     const char         *LookupLineType( const char *pszName );
215 
216     // Header variables.
217     void                ReadHeaderSection();
218     const char         *GetVariable(const char *pszName,
219                                     const char *pszDefault=nullptr );
220 
GetEncoding()221     const char         *GetEncoding() { return osEncoding; }
222 };
223 
224 /************************************************************************/
225 /*                            OGRDWGServices                            */
226 /*                                                                      */
227 /*      Services implementation for OGR.  Eventually we should          */
228 /*      override the ExSystemServices IO to use VSI*L.                  */
229 /************************************************************************/
230 class OGRDWGServices : public ExSystemServices, public ExHostAppServices
231 {
232 protected:
233   ODRX_USING_HEAP_OPERATORS(ExSystemServices);
234 };
235 
236 /************************************************************************/
237 /*                             OGRDWGDriver                             */
238 /************************************************************************/
239 
240 class OGRDWGDriver final: public OGRSFDriver
241 {
242     OGRDWGServices *poServices;
243 
244   public:
245     OGRDWGDriver();
246     ~OGRDWGDriver();
247 
GetServices()248     OGRDWGServices *GetServices() { return poServices; }
249 
250     const char *GetName() override;
251     OGRDataSource *Open( const char *, int ) override;
252     int         TestCapability( const char * ) override;
253 };
254 
255 #endif /* ndef OGR_DWG_H_INCLUDED */
256