Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: TIGER/Line Translator 4 : * Purpose: Implements OGRTigerLayer class. 5 : * Author: Frank Warmerdam, warmerdam@pobox.com 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 1999, Frank Warmerdam 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_tiger.h" 30 : 31 : /************************************************************************/ 32 : /* OGRTigerLayer() */ 33 : /* */ 34 : /* Note that the OGRTigerLayer assumes ownership of the passed */ 35 : /* OGRFeatureDefn object. */ 36 : /************************************************************************/ 37 : 38 0 : OGRTigerLayer::OGRTigerLayer(OGRTigerDataSource *poDSIn, 39 0 : TigerFileBase *poReaderIn) 40 : : poReader(poReaderIn), poDS(poDSIn), nFeatureCount(0), 41 : panModuleFCount(nullptr), panModuleOffset(nullptr), iLastFeatureId(0), 42 0 : iLastModule(-1) 43 : { 44 : /* -------------------------------------------------------------------- */ 45 : /* Setup module feature counts. */ 46 : /* -------------------------------------------------------------------- */ 47 0 : panModuleFCount = (int *)CPLCalloc(poDS->GetModuleCount(), sizeof(int)); 48 0 : panModuleOffset = (int *)CPLCalloc(poDS->GetModuleCount() + 1, sizeof(int)); 49 : 50 0 : nFeatureCount = 0; 51 : 52 0 : for (int iModule = 0; iModule < poDS->GetModuleCount(); iModule++) 53 : { 54 0 : if (poReader->SetModule(poDS->GetModule(iModule))) 55 0 : panModuleFCount[iModule] = poReader->GetFeatureCount(); 56 : else 57 0 : panModuleFCount[iModule] = 0; 58 : 59 0 : panModuleOffset[iModule] = nFeatureCount; 60 0 : nFeatureCount += panModuleFCount[iModule]; 61 : } 62 : 63 : // this entry is just to make range comparisons easy without worrying 64 : // about falling off the end of the array. 65 0 : panModuleOffset[poDS->GetModuleCount()] = nFeatureCount; 66 : 67 0 : poReader->SetModule(nullptr); 68 0 : } 69 : 70 : /************************************************************************/ 71 : /* ~OGRTigerLayer() */ 72 : /************************************************************************/ 73 : 74 0 : OGRTigerLayer::~OGRTigerLayer() 75 : 76 : { 77 0 : if (m_nFeaturesRead > 0 && poReader->GetFeatureDefn() != nullptr) 78 : { 79 0 : CPLDebug("TIGER", "%d features read on layer '%s'.", 80 0 : (int)m_nFeaturesRead, poReader->GetFeatureDefn()->GetName()); 81 : } 82 : 83 0 : delete poReader; 84 : 85 0 : CPLFree(panModuleFCount); 86 0 : CPLFree(panModuleOffset); 87 0 : } 88 : 89 : /************************************************************************/ 90 : /* ResetReading() */ 91 : /************************************************************************/ 92 : 93 0 : void OGRTigerLayer::ResetReading() 94 : 95 : { 96 0 : iLastFeatureId = 0; 97 0 : iLastModule = -1; 98 0 : } 99 : 100 : /************************************************************************/ 101 : /* GetFeature() */ 102 : /************************************************************************/ 103 : 104 0 : OGRFeature *OGRTigerLayer::GetFeature(GIntBig nFeatureId) 105 : 106 : { 107 0 : if (nFeatureId < 1 || nFeatureId > nFeatureCount) 108 0 : return nullptr; 109 : 110 : /* -------------------------------------------------------------------- */ 111 : /* If we don't have the current module open for the requested */ 112 : /* data, then open it now. */ 113 : /* -------------------------------------------------------------------- */ 114 0 : if (iLastModule == -1 || nFeatureId <= panModuleOffset[iLastModule] || 115 0 : nFeatureId > panModuleOffset[iLastModule + 1]) 116 : { 117 0 : for (iLastModule = 0; iLastModule < poDS->GetModuleCount() && 118 0 : nFeatureId > panModuleOffset[iLastModule + 1]; 119 0 : iLastModule++) 120 : { 121 : } 122 : 123 0 : if (!poReader->SetModule(poDS->GetModule(iLastModule))) 124 : { 125 0 : return nullptr; 126 : } 127 : } 128 : 129 : /* -------------------------------------------------------------------- */ 130 : /* Fetch the feature associated with the record. */ 131 : /* -------------------------------------------------------------------- */ 132 0 : OGRFeature *poFeature = poReader->GetFeature( 133 0 : (int)nFeatureId - panModuleOffset[iLastModule] - 1); 134 : 135 0 : if (poFeature != nullptr) 136 : { 137 0 : poFeature->SetFID(nFeatureId); 138 : 139 0 : if (poFeature->GetGeometryRef() != nullptr) 140 0 : poFeature->GetGeometryRef()->assignSpatialReference( 141 0 : poDS->DSGetSpatialRef()); 142 : 143 0 : poFeature->SetField(0, poReader->GetShortModule()); 144 : 145 0 : m_nFeaturesRead++; 146 : } 147 : 148 0 : return poFeature; 149 : } 150 : 151 : /************************************************************************/ 152 : /* GetNextFeature() */ 153 : /************************************************************************/ 154 : 155 0 : OGRFeature *OGRTigerLayer::GetNextFeature() 156 : 157 : { 158 : /* -------------------------------------------------------------------- */ 159 : /* Read features till we find one that satisfies our current */ 160 : /* spatial criteria. */ 161 : /* -------------------------------------------------------------------- */ 162 0 : while (iLastFeatureId < nFeatureCount) 163 : { 164 0 : OGRFeature *poFeature = GetFeature(++iLastFeatureId); 165 : 166 0 : if (poFeature == nullptr) 167 0 : break; 168 : 169 0 : if ((m_poFilterGeom == nullptr || 170 0 : FilterGeometry(poFeature->GetGeometryRef())) && 171 0 : (m_poAttrQuery == nullptr || m_poAttrQuery->Evaluate(poFeature))) 172 0 : return poFeature; 173 : 174 0 : delete poFeature; 175 : } 176 : 177 0 : return nullptr; 178 : } 179 : 180 : /************************************************************************/ 181 : /* TestCapability() */ 182 : /************************************************************************/ 183 : 184 0 : int OGRTigerLayer::TestCapability(const char *pszCap) 185 : 186 : { 187 0 : if (EQUAL(pszCap, OLCRandomRead)) 188 0 : return TRUE; 189 : 190 0 : else if (EQUAL(pszCap, OLCFastFeatureCount)) 191 0 : return TRUE; 192 : 193 : else 194 0 : return FALSE; 195 : } 196 : 197 : /************************************************************************/ 198 : /* GetLayerDefn() */ 199 : /************************************************************************/ 200 : 201 0 : OGRFeatureDefn *OGRTigerLayer::GetLayerDefn() 202 : 203 : { 204 0 : OGRFeatureDefn *poFDefn = poReader->GetFeatureDefn(); 205 0 : if (poFDefn != nullptr) 206 : { 207 0 : if (poFDefn->GetGeomFieldCount() > 0) 208 0 : poFDefn->GetGeomFieldDefn(0)->SetSpatialRef( 209 0 : poDS->DSGetSpatialRef()); 210 : } 211 0 : return poFDefn; 212 : } 213 : 214 : /************************************************************************/ 215 : /* GetFeatureCount() */ 216 : /************************************************************************/ 217 : 218 0 : GIntBig OGRTigerLayer::GetFeatureCount(int bForce) 219 : 220 : { 221 0 : if (m_poFilterGeom == nullptr && m_poAttrQuery == nullptr) 222 0 : return nFeatureCount; 223 : else 224 0 : return OGRLayer::GetFeatureCount(bForce); 225 : }