1 /***************************************************************************
2                          qgsdwgimporter.h
3                          --------------
4     begin                : May 2016
5     copyright            : (C) 2016 by Juergen E. Fischer
6     email                : jef at norbit dot de
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #include "drw_interface.h"
19 
20 #include <QCoreApplication>
21 #include <QString>
22 #include <QElapsedTimer>
23 
24 #include <ogr_api.h>
25 
26 #include "qgsabstractgeometry.h"
27 #include "qgsogrutils.h"
28 
29 class QgsCompoundCurve;
30 class QgsLineString;
31 class QgsCircularString;
32 class QgsQgsCoordinateReferenceSystem;
33 class QLabel;
34 class QTextCodec;
35 
36 class QgsDwgImporter : public DRW_Interface
37 {
38     Q_DECLARE_TR_FUNCTIONS( QgsDwgImporter )
39 
40   public:
41     QgsDwgImporter( const QString &database, const QgsCoordinateReferenceSystem &crs );
42     ~QgsDwgImporter() override;
43 
44     bool import( const QString &drawing, QString &error, bool expandInserts, bool useCurves, QLabel *label );
45 
46     //! Called when header is parsed.
47     void addHeader( const DRW_Header *data ) override;
48 
49     //! Called for every line Type.
50     void addLType( const DRW_LType &data ) override;
51 
52     //! Called for every layer.
53     void addLayer( const DRW_Layer &data ) override;
54 
55     //! Called for every dim style.
56     void addDimStyle( const DRW_Dimstyle &data ) override;
57 
58     //! Called for every VPORT table.
59     void addVport( const DRW_Vport &data ) override;
60 
61     //! Called for every text style.
62     void addTextStyle( const DRW_Textstyle &data ) override;
63 
64     //! Called for every AppId entry.
65     void addAppId( const DRW_AppId &data ) override;
66 
67     void addBlock( const DRW_Block &data ) override;
68 
69     void setBlock( int handle ) override;
70 
71     //! Called to end the current block
72     void endBlock() override;
73 
74     //! Called for every point
75     void addPoint( const DRW_Point &data ) override;
76 
77     //! Called for every line
78     void addLine( const DRW_Line &data ) override;
79 
80     //! Called for every ray
81     void addRay( const DRW_Ray &data ) override;
82 
83     //! Called for every xline
84     void addXline( const DRW_Xline &data ) override;
85 
86     //! Called for every arc
87     void addArc( const DRW_Arc &data ) override;
88 
89     //! Called for every circle
90     void addCircle( const DRW_Circle &data ) override;
91 
92     //! Called for every ellipse
93     void addEllipse( const DRW_Ellipse &data ) override;
94 
95     //! Called for every lwpolyline
96     void addLWPolyline( const DRW_LWPolyline &data ) override;
97 
98     //! Called for every polyline start
99     void addPolyline( const DRW_Polyline &data ) override;
100 
101     //! Called for every spline
102     void addSpline( const DRW_Spline *data ) override;
103 
104     //! Called for every spline knot value
105     void addKnot( const DRW_Entity &data ) override;
106 
107     //! Called for every insert.
108     void addInsert( const DRW_Insert &data ) override;
109 
110     //! Called for every trace start
111     void addTrace( const DRW_Trace &data ) override;
112 
113     //! Called for every 3dface start
114     void add3dFace( const DRW_3Dface &data ) override;
115 
116     //! Called for every solid start
117     void addSolid( const DRW_Solid &data ) override;
118 
119     //! Called for every Multi Text entity.
120     void addMText( const DRW_MText &data ) override;
121 
122     //! Called for every Text entity.
123     void addText( const DRW_Text &data ) override;
124 
125     //! Called for every dimension entity.
126     void addDim( const DRW_Dimension *data );
127 
128     //! Called for every aligned dimension entity.
129     void addDimAlign( const DRW_DimAligned *data ) override;
130 
131     //! Called for every linear or rotated dimension entity.
132     void addDimLinear( const DRW_DimLinear *data ) override;
133 
134     //! Called for every radial dimension entity.
135     void addDimRadial( const DRW_DimRadial *data ) override;
136 
137     //! Called for every diametric dimension entity.
138     void addDimDiametric( const DRW_DimDiametric *data ) override;
139 
140     //! Called for every angular dimension (2 lines version) entity.
141     void addDimAngular( const DRW_DimAngular *data ) override;
142 
143     //! Called for every angular dimension (3 points version) entity.
144     void addDimAngular3P( const DRW_DimAngular3p *data ) override;
145 
146     //! Called for every ordinate dimension entity.
147     void addDimOrdinate( const DRW_DimOrdinate *data ) override;
148 
149     //! Called for every leader start.
150     void addLeader( const DRW_Leader *data ) override;
151 
152     //! Called for every hatch entity.
153     void addHatch( const DRW_Hatch *data ) override;
154 
155     //! Called for every viewport entity.
156     void addViewport( const DRW_Viewport &data ) override;
157 
158     //! Called for every image entity.
159     void addImage( const DRW_Image *data ) override;
160 
161     //! Called for every image definition.
162     void linkImage( const DRW_ImageDef *data ) override;
163 
164     //! Called for every comment in the DXF file (code 999).
165     void addComment( const char *comment ) override;
166 
167     void writeHeader( DRW_Header &data ) override;
168     void writeBlocks() override;
169     void writeBlockRecords() override;
170     void writeEntities() override;
171     void writeLTypes() override;
172     void writeLayers() override;
173     void writeTextstyles() override;
174     void writeVports() override;
175     void writeDimstyles() override;
176     void writeAppId() override;
177 
178   private:
179     void startTransaction();
180     void commitTransaction();
181     bool exec( const QString &sql, bool logError = true );
182     OGRLayerH query( const QString &sql );
183 
184     void progress( const QString &msg );
185     QString decode( const std::string &s ) const;
186     void cleanText( QString &s );
187 
188     void addEntity( OGRFeatureDefnH dfn, OGRFeatureH f, const DRW_Entity &data );
189     QString colorString( int color, int color24, int transparency, const QString &layer ) const;
190     double lineWidth( int lWeight, const QString &layer ) const;
191     QString linetypeString( const QString &linetype, const QString &layer ) const;
192     void setString( OGRFeatureDefnH dfn, OGRFeatureH f, const QString &field, const std::string &value ) const;
193     void setString( OGRFeatureDefnH dfn, OGRFeatureH f, const QString &field, const QString &value ) const;
194     void setString( OGRFeatureDefnH dfn, OGRFeatureH f, const QString &field, const char *value ) const;
195     void setDouble( OGRFeatureDefnH dfn, OGRFeatureH f, const QString &field, double value ) const;
196     void setInteger( OGRFeatureDefnH dfn, OGRFeatureH f, const QString &field, int value ) const;
197     void setPoint( OGRFeatureDefnH dfn, OGRFeatureH f, const QString &field, const DRW_Coord &value ) const;
198 
199     bool curveFromLWPolyline( const DRW_LWPolyline &data, QgsCompoundCurve &cc );
200     bool circularStringFromArc( const DRW_Arc &data, QgsCircularString &c );
201     bool lineFromSpline( const DRW_Spline &data, QgsLineString &l );
202 
203     bool expandInserts( QString &error );
204     bool expandInserts( QString &error, int block, QTransform base );
205 
206     bool createFeature( OGRLayerH layer, OGRFeatureH f, const QgsAbstractGeometry &g ) const;
207 
208     gdal::ogr_datasource_unique_ptr mDs;
209     QString mDatabase;
210     bool mInTransaction;
211     int mSplineSegs;
212     int mBlockHandle;
213     int mCrs;
214     OGRSpatialReferenceH mCrsH = nullptr;
215     bool mUseCurves;
216 
217     QHash<QString, QString> mLayerColor;
218     QHash<QString, double> mLayerLinewidth;
219     QHash<QString, QString> mLayerLinetype;
220     QHash<QString, QString> mLinetype;
221     QHash<QString, int> mBlockNames;
222     QHash<QString, QgsPointXY> mBlockBases;
223 
224     QLabel *mLabel = nullptr;
225     int mEntities = 0;
226     QTextCodec *mCodec = nullptr;
227     QElapsedTimer mTime;
228 };
229