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