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