1 /******************************************************************************
2  *
3  * Project:  OpenGIS Simple Features Reference Implementation
4  * Purpose:  OGR Driver for DGNv8
5  * Author:   Even Rouault <even.rouault at spatialys.com>
6  *
7  ******************************************************************************
8  * Copyright (c) 2017, Even Rouault <even.rouault at spatialys.com>
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a
11  * copy of this software and associated documentation files (the "Software"),
12  * to deal in the Software without restriction, including without limitation
13  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  * and/or sell copies of the Software, and to permit persons to whom the
15  * Software is furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be included
18  * in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  * DEALINGS IN THE SOFTWARE.
27  ****************************************************************************/
28 
29 #ifndef OGR_DGNV8_H_INCLUDED
30 #define OGR_DGNV8_H_INCLUDED
31 
32 #include "ogrsf_frmts.h"
33 
34 #include <set>
35 #include <utility>
36 #include <vector>
37 
38 #include "dgnv8_headers.h"
39 
40 /************************************************************************/
41 /*                         OGRDGNV8Services                             */
42 /*                                                                      */
43 /*      Services implementation for OGR.  Eventually we should          */
44 /*      override the OdExDgnSystemServices IO to use VSI*L.             */
45 /************************************************************************/
46 
47 class OGRDGNV8Services: public OdExDgnSystemServices,
48                          public OdExDgnHostAppServices
49 {
50 protected:
51   ODRX_USING_HEAP_OPERATORS(OdExDgnSystemServices);
52 };
53 
54 /************************************************************************/
55 /*                           OGRDGNV8Layer                              */
56 /************************************************************************/
57 
58 class OGRDGNV8DataSource;
59 typedef std::pair<OGRFeature*, bool> tPairFeatureHoleFlag;
60 
61 class OGRDGNV8Layer final: public OGRLayer
62 {
63     friend class OGRDGNV8DataSource;
64 
65     OGRDGNV8DataSource         *m_poDS;
66     OGRFeatureDefn             *m_poFeatureDefn;
67     OdDgModelPtr                m_pModel;
68     OdDgElementIteratorPtr      m_pIterator;
69     std::vector<tPairFeatureHoleFlag>    m_aoPendingFeatures;
70     size_t                      m_nIdxInPendingFeatures;
71     std::set<CPLString>         m_aoSetIgnoredFeatureClasses;
72 
73     void                                 CleanPendingFeatures();
74     std::vector<tPairFeatureHoleFlag>    CollectSubElements( OdDgElementIteratorPtr iterator,
75                                                     int level );
76     std::vector<tPairFeatureHoleFlag>    ProcessElement(OdDgGraphicsElementPtr element,
77                                                int level = 0);
78     OGRFeature*                 GetNextUnfilteredFeature();
79 
80     void                        AddToComplexCurve( OGRFeature* poFeature,
81                                                    OGRCircularString* poCS,
82                                                    OdDgComplexCurvePtr complexCurve );
83     void                        AddToComplexCurve( OGRFeature* poFeature,
84                                                    OGRCompoundCurve* poCC,
85                                                    OdDgComplexCurvePtr complexCurve );
86     OdDgGraphicsElementPtr      CreateShape( OGRFeature* poFeature,
87                                              OGRCurve* poCurve,
88                                              bool bIsHole = false );
89     OdDgGraphicsElementPtr      CreateGraphicsElement( OGRFeature *poFeature,
90                                                        OGRGeometry *poGeom );
91     OdDgGraphicsElementPtr      TranslateLabel(
92                                     OGRFeature *poFeature, OGRPoint *poPoint );
93     void                        AttachFillLinkage( OGRFeature* poFeature,
94                                                    OdDgGraphicsElementPtr element);
95     void                        AttachCommonAttributes( OGRFeature *poFeature,
96                                                         OdDgGraphicsElementPtr element );
97     int                         GetColorFromString(const char* pszColor);
98     OdDgGraphicsElementPtr      GetFeatureInternal(GIntBig nFID, OdDg::OpenMode openMode);
99 
100   public:
101                         OGRDGNV8Layer( OGRDGNV8DataSource* poDS,
102                                        OdDgModelPtr pModel );
103                         virtual ~OGRDGNV8Layer();
104 
105     void                ResetReading() override;
106     OGRFeature *        GetNextFeature() override;
107     OGRFeature *        GetFeature(GIntBig nFID) override;
108     OGRErr              GetExtent( OGREnvelope *psExtent, int bForce ) override;
GetExtent(int iGeomField,OGREnvelope * psExtent,int bForce)109     virtual OGRErr      GetExtent( int iGeomField, OGREnvelope *psExtent,
110                                    int bForce ) override
111                 { return OGRLayer::GetExtent(iGeomField, psExtent, bForce); }
112 
GetLayerDefn()113     OGRFeatureDefn *    GetLayerDefn() override { return m_poFeatureDefn; }
114 
115     int                 TestCapability( const char * ) override;
116 
117     OGRErr              ICreateFeature( OGRFeature *poFeature ) override;
118     OGRErr              DeleteFeature(GIntBig nFID) override;
119 };
120 
121 
122 /************************************************************************/
123 /*                         OGRDGNV8DataSource                           */
124 /************************************************************************/
125 
126 class OGRDGNV8DataSource final: public GDALDataset
127 {
128     OGRDGNV8Services   *m_poServices;
129     OGRDGNV8Layer     **m_papoLayers;
130     int                 m_nLayers;
131     char              **m_papszOptions;
132     OdDgDatabasePtr     m_poDb;
133     bool                m_bUpdate;
134     bool                m_bModified;
135     CPLStringList       m_osDGNMD;
136 
137     void                InitWithSeed();
138 
139   public:
140                         explicit OGRDGNV8DataSource(OGRDGNV8Services* poServices);
141                         ~OGRDGNV8DataSource();
142 
143     int                 Open( const char *, bool bUpdate );
144     bool                PreCreate( const char *, char ** );
145 
146     OGRLayer           *ICreateLayer( const char *,
147                                      OGRSpatialReference * = nullptr,
148                                      OGRwkbGeometryType = wkbUnknown,
149                                      char ** = nullptr ) override;
150 
GetLayerCount()151     int                 GetLayerCount() override { return m_nLayers; }
152     OGRLayer            *GetLayer( int ) override;
153 
154     int                 TestCapability( const char * ) override;
155     virtual void        FlushCache() override;
156 
157     virtual char **     GetMetadataDomainList() override;
158     virtual char**      GetMetadata(const char* pszDomain = "") override;
159     virtual const char* GetMetadataItem(const char* pszName,
160                                         const char* pszDomain = "") override;
161 
GetDb()162     OdDgDatabasePtr     GetDb() const { return m_poDb; }
163 
GetUpdate()164     bool                GetUpdate() const { return m_bUpdate; }
SetModified()165     void                SetModified() { m_bModified = true; }
166 
167     static OdString     FromUTF8(const CPLString& str);
168     static CPLString    ToUTF8(const OdString& str);
169 };
170 
171 #endif /* ndef OGR_DGNV8_H_INCLUDED */
172