1 /******************************************************************************
2  *
3  * Project:  DWG Translator
4  * Purpose:  Implements OGRDWGBlocksLayer class.
5  * Author:   Frank Warmerdam, warmerdam@pobox.com
6  *
7  ******************************************************************************
8  * Copyright (c) 2010, Frank Warmerdam <warmerdam@pobox.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 #include "ogr_dwg.h"
30 #include "cpl_conv.h"
31 
32 CPL_CVSID("$Id: ogrdwgblockslayer.cpp b636987ee8a02c1292896e269d556699594ff0bc 2019-07-07 23:23:42 +0200 Even Rouault $")
33 
34 /************************************************************************/
35 /*                         OGRDWGBlocksLayer()                          */
36 /************************************************************************/
37 
OGRDWGBlocksLayer(OGRDWGDataSource * poDSIn)38 OGRDWGBlocksLayer::OGRDWGBlocksLayer( OGRDWGDataSource *poDSIn ) :
39     poDS(poDSIn),
40     poFeatureDefn(new OGRFeatureDefn( "blocks" ))
41 {
42     OGRDWGBlocksLayer::ResetReading();
43 
44     poFeatureDefn->Reference();
45 
46     poDS->AddStandardFields( poFeatureDefn );
47 }
48 
49 /************************************************************************/
50 /*                         ~OGRDWGBlocksLayer()                         */
51 /************************************************************************/
52 
~OGRDWGBlocksLayer()53 OGRDWGBlocksLayer::~OGRDWGBlocksLayer()
54 
55 {
56     if( m_nFeaturesRead > 0 && poFeatureDefn != nullptr )
57     {
58         CPLDebug( "DWG", "%d features read on layer '%s'.",
59                   (int) m_nFeaturesRead,
60                   poFeatureDefn->GetName() );
61     }
62 
63     if( poFeatureDefn )
64         poFeatureDefn->Release();
65 }
66 
67 /************************************************************************/
68 /*                            ResetReading()                            */
69 /************************************************************************/
70 
ResetReading()71 void OGRDWGBlocksLayer::ResetReading()
72 
73 {
74     iNextFID = 0;
75     iNextSubFeature = 0;
76     oIt = poDS->GetBlockMap().begin();
77 }
78 
79 /************************************************************************/
80 /*                      GetNextUnfilteredFeature()                      */
81 /************************************************************************/
82 
GetNextUnfilteredFeature()83 OGRFeature *OGRDWGBlocksLayer::GetNextUnfilteredFeature()
84 
85 {
86     OGRFeature *poFeature = nullptr;
87 
88 /* -------------------------------------------------------------------- */
89 /*      Are we out of features?                                         */
90 /* -------------------------------------------------------------------- */
91     if( oIt == poDS->GetBlockMap().end() )
92         return nullptr;
93 
94 /* -------------------------------------------------------------------- */
95 /*      Are we done reading the current blocks features?                */
96 /* -------------------------------------------------------------------- */
97     DWGBlockDefinition *psBlock = &(oIt->second);
98     unsigned int nSubFeatureCount = static_cast<unsigned int>(
99         psBlock->apoFeatures.size());
100 
101     if( psBlock->poGeometry != nullptr )
102         nSubFeatureCount++;
103 
104     if( iNextSubFeature >= nSubFeatureCount )
105     {
106         ++oIt;
107 
108         iNextSubFeature = 0;
109 
110         if( oIt == poDS->GetBlockMap().end() )
111             return nullptr;
112 
113         psBlock = &(oIt->second);
114     }
115 
116 /* -------------------------------------------------------------------- */
117 /*      Is this a geometry based block?                                 */
118 /* -------------------------------------------------------------------- */
119     if( psBlock->poGeometry != nullptr
120         && iNextSubFeature == psBlock->apoFeatures.size() )
121     {
122         poFeature = new OGRFeature( poFeatureDefn );
123         poFeature->SetGeometry( psBlock->poGeometry );
124         iNextSubFeature++;
125     }
126 
127 /* -------------------------------------------------------------------- */
128 /*      Otherwise duplicate the next sub-feature.                       */
129 /* -------------------------------------------------------------------- */
130     else
131     {
132         poFeature = new OGRFeature( poFeatureDefn );
133         poFeature->SetFrom( psBlock->apoFeatures[iNextSubFeature] );
134         iNextSubFeature++;
135     }
136 
137 /* -------------------------------------------------------------------- */
138 /*      Set FID and block name.                                         */
139 /* -------------------------------------------------------------------- */
140     poFeature->SetFID( iNextFID++ );
141 
142     poFeature->SetField( "BlockName", oIt->first.c_str() );
143 
144     m_nFeaturesRead++;
145 
146     return poFeature;
147 }
148 
149 /************************************************************************/
150 /*                           GetNextFeature()                           */
151 /************************************************************************/
152 
GetNextFeature()153 OGRFeature *OGRDWGBlocksLayer::GetNextFeature()
154 
155 {
156     while( true )
157     {
158         OGRFeature *poFeature = GetNextUnfilteredFeature();
159 
160         if( poFeature == nullptr )
161             return nullptr;
162 
163         if( (m_poFilterGeom == nullptr
164              || FilterGeometry( poFeature->GetGeometryRef() ) )
165             && (m_poAttrQuery == nullptr
166                 || m_poAttrQuery->Evaluate( poFeature ) ) )
167         {
168             return poFeature;
169         }
170 
171         delete poFeature;
172     }
173 }
174 
175 /************************************************************************/
176 /*                           TestCapability()                           */
177 /************************************************************************/
178 
TestCapability(const char * pszCap)179 int OGRDWGBlocksLayer::TestCapability( const char * pszCap )
180 
181 {
182     if( EQUAL(pszCap,OLCStringsAsUTF8) )
183         return TRUE;
184     else
185         return FALSE;
186 }
187