Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: DXF Translator 4 : * Purpose: Implements OGRDXFBlocksLayer class. 5 : * Author: Frank Warmerdam, warmerdam@pobox.com 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2010, Frank Warmerdam <warmerdam@pobox.com> 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #include "ogr_dxf.h" 14 : #include "cpl_conv.h" 15 : 16 : /************************************************************************/ 17 : /* OGRDXFBlocksLayer() */ 18 : /************************************************************************/ 19 : 20 4 : OGRDXFBlocksLayer::OGRDXFBlocksLayer(OGRDXFDataSource *poDSIn) 21 4 : : poDS(poDSIn), poFeatureDefn(new OGRFeatureDefn("blocks")), iNextFID(0) 22 : { 23 4 : OGRDXFBlocksLayer::ResetReading(); 24 : 25 4 : poFeatureDefn->Reference(); 26 : 27 4 : int nModes = ODFM_None; 28 4 : if (!poDS->InlineBlocks()) 29 4 : nModes |= ODFM_IncludeBlockFields; 30 4 : if (poDS->ShouldIncludeRawCodeValues()) 31 0 : nModes |= ODFM_IncludeRawCodeValues; 32 4 : if (poDS->In3DExtensibleMode()) 33 0 : nModes |= ODFM_Include3DModeFields; 34 4 : OGRDXFDataSource::AddStandardFields(poFeatureDefn, nModes); 35 4 : } 36 : 37 : /************************************************************************/ 38 : /* ~OGRDXFBlocksLayer() */ 39 : /************************************************************************/ 40 : 41 8 : OGRDXFBlocksLayer::~OGRDXFBlocksLayer() 42 : 43 : { 44 4 : if (m_nFeaturesRead > 0 && poFeatureDefn != nullptr) 45 : { 46 4 : CPLDebug("DXF", "%d features read on layer '%s'.", (int)m_nFeaturesRead, 47 4 : poFeatureDefn->GetName()); 48 : } 49 : 50 4 : if (poFeatureDefn) 51 4 : poFeatureDefn->Release(); 52 : 53 4 : while (!apoPendingFeatures.empty()) 54 : { 55 0 : delete apoPendingFeatures.front(); 56 0 : apoPendingFeatures.pop(); 57 : } 58 8 : } 59 : 60 : /************************************************************************/ 61 : /* ResetReading() */ 62 : /************************************************************************/ 63 : 64 19 : void OGRDXFBlocksLayer::ResetReading() 65 : 66 : { 67 19 : iNextFID = 0; 68 23 : while (!apoPendingFeatures.empty()) 69 : { 70 4 : OGRDXFFeature *poFeature = apoPendingFeatures.front(); 71 4 : apoPendingFeatures.pop(); 72 4 : delete poFeature; 73 : } 74 19 : oIt = poDS->GetBlockMap().begin(); 75 19 : } 76 : 77 : /************************************************************************/ 78 : /* GetNextUnfilteredFeature() */ 79 : /************************************************************************/ 80 : 81 41 : OGRDXFFeature *OGRDXFBlocksLayer::GetNextUnfilteredFeature() 82 : 83 : { 84 41 : OGRDXFFeature *poFeature = nullptr; 85 : 86 : /* -------------------------------------------------------------------- */ 87 : /* If we have pending features, return one of them. */ 88 : /* -------------------------------------------------------------------- */ 89 41 : if (!apoPendingFeatures.empty()) 90 : { 91 18 : poFeature = apoPendingFeatures.front(); 92 18 : apoPendingFeatures.pop(); 93 : 94 18 : poFeature->SetFID(iNextFID++); 95 18 : poFeature->SetField("Block", osBlockName.c_str()); 96 18 : if (poFeature->GetAttributeTag() != "") 97 : { 98 6 : poFeature->SetField("AttributeTag", poFeature->GetAttributeTag()); 99 : } 100 : 101 18 : m_nFeaturesRead++; 102 18 : return poFeature; 103 : } 104 : 105 : /* -------------------------------------------------------------------- */ 106 : /* Are we out of features? */ 107 : /* -------------------------------------------------------------------- */ 108 23 : while (oIt != poDS->GetBlockMap().end()) 109 : { 110 20 : poFeature = new OGRDXFFeature(poFeatureDefn); 111 : 112 : // Let's insert this block at the origin with no rotation and scale. 113 20 : OGRDXFLayer oTempLayer(poDS); 114 20 : poFeature = oTempLayer.InsertBlockInline( 115 40 : CPLGetErrorCounter(), oIt->first, OGRDXFInsertTransformer(), 116 20 : poFeature, apoPendingFeatures, false, 117 20 : poDS->ShouldMergeBlockGeometries()); 118 : 119 20 : osBlockName = oIt->first; 120 20 : ++oIt; 121 : 122 20 : if (!poFeature) 123 : { 124 9 : if (apoPendingFeatures.empty()) 125 : { 126 : // This block must have been empty. Move onto the next block 127 0 : continue; 128 : } 129 : else 130 : { 131 9 : poFeature = apoPendingFeatures.front(); 132 9 : apoPendingFeatures.pop(); 133 : } 134 : } 135 : 136 20 : poFeature->SetFID(iNextFID++); 137 20 : poFeature->SetField("Block", osBlockName.c_str()); 138 20 : if (poFeature->GetAttributeTag() != "") 139 : { 140 0 : poFeature->SetField("AttributeTag", poFeature->GetAttributeTag()); 141 : } 142 : 143 20 : m_nFeaturesRead++; 144 20 : return poFeature; 145 : } 146 : 147 : // No more blocks left. 148 3 : return nullptr; 149 : } 150 : 151 : /************************************************************************/ 152 : /* GetNextFeature() */ 153 : /************************************************************************/ 154 : 155 41 : OGRFeature *OGRDXFBlocksLayer::GetNextFeature() 156 : 157 : { 158 : while (true) 159 : { 160 41 : OGRFeature *poFeature = GetNextUnfilteredFeature(); 161 : 162 41 : if (poFeature == nullptr) 163 3 : return nullptr; 164 : 165 76 : if ((m_poFilterGeom == nullptr || 166 76 : FilterGeometry(poFeature->GetGeometryRef())) && 167 38 : (m_poAttrQuery == nullptr || m_poAttrQuery->Evaluate(poFeature))) 168 : { 169 38 : return poFeature; 170 : } 171 : 172 0 : delete poFeature; 173 0 : } 174 : } 175 : 176 : /************************************************************************/ 177 : /* TestCapability() */ 178 : /************************************************************************/ 179 : 180 0 : int OGRDXFBlocksLayer::TestCapability(const char *pszCap) 181 : 182 : { 183 0 : return EQUAL(pszCap, OLCStringsAsUTF8); 184 : }