Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: OpenGIS Simple Features Reference Implementation 4 : * Purpose: Implements OGRVFKDatasource class. 5 : * Author: Martin Landa, landa.martin gmail.com 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2009-2010, 2013-2018 Martin Landa <landa.martin gmail.com> 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #include "ogr_vfk.h" 14 : #include "cpl_conv.h" 15 : #include "cpl_string.h" 16 : 17 : /*! 18 : \brief OGRVFKDataSource constructor 19 : */ 20 17 : OGRVFKDataSource::OGRVFKDataSource() 21 17 : : papoLayers(nullptr), nLayers(0), poReader(nullptr) 22 : { 23 17 : } 24 : 25 : /*! 26 : \brief OGRVFKDataSource destructor 27 : */ 28 34 : OGRVFKDataSource::~OGRVFKDataSource() 29 : { 30 17 : if (poReader) 31 17 : delete poReader; 32 : 33 993 : for (int i = 0; i < nLayers; i++) 34 976 : delete papoLayers[i]; 35 : 36 17 : CPLFree(papoLayers); 37 34 : } 38 : 39 : /*! 40 : \brief Open VFK datasource 41 : 42 : \param poOpenInfo open info 43 : 44 : \return TRUE on success or FALSE on failure 45 : */ 46 17 : int OGRVFKDataSource::Open(GDALOpenInfo *poOpenInfo) 47 : { 48 : /* create VFK reader */ 49 17 : poReader = CreateVFKReader(poOpenInfo); 50 17 : if (poReader == nullptr || !poReader->IsValid()) 51 : { 52 : /* 53 : CPLError(CE_Failure, CPLE_AppDefined, 54 : "File %s appears to be VFK but the VFK reader can't" 55 : "be instantiated", 56 : pszFileName); 57 : */ 58 1 : return FALSE; 59 : } 60 : 61 : bool bSuppressGeometry = 62 16 : CPLFetchBool(poOpenInfo->papszOpenOptions, "SUPPRESS_GEOMETRY", false); 63 : /* read data blocks, i.e. &B */ 64 16 : poReader->ReadDataBlocks(bSuppressGeometry); 65 : 66 : /* get list of layers */ 67 32 : papoLayers = (OGRVFKLayer **)CPLCalloc(sizeof(OGRVFKLayer *), 68 16 : poReader->GetDataBlockCount()); 69 : 70 : /* create layers from VFK blocks */ 71 992 : for (int iLayer = 0; iLayer < poReader->GetDataBlockCount(); iLayer++) 72 : { 73 1952 : papoLayers[iLayer] = 74 976 : CreateLayerFromBlock(poReader->GetDataBlock(iLayer)); 75 976 : nLayers++; 76 : } 77 : 78 16 : if (CPLTestBool(CPLGetConfigOption("OGR_VFK_DB_READ_ALL_BLOCKS", "YES"))) 79 : { 80 : /* read data records if requested */ 81 16 : poReader->ReadDataRecords(); 82 : 83 16 : if (!bSuppressGeometry) 84 : { 85 930 : for (int iLayer = 0; iLayer < poReader->GetDataBlockCount(); 86 : iLayer++) 87 : { 88 : /* load geometry */ 89 915 : poReader->GetDataBlock(iLayer)->LoadGeometry(); 90 : } 91 : } 92 : } 93 : 94 16 : return TRUE; 95 : } 96 : 97 : /*! 98 : \brief Get VFK layer 99 : 100 : \param iLayer layer number 101 : 102 : \return pointer to OGRLayer instance or NULL on error 103 : */ 104 147 : OGRLayer *OGRVFKDataSource::GetLayer(int iLayer) 105 : { 106 147 : if (iLayer < 0 || iLayer >= nLayers) 107 0 : return nullptr; 108 : 109 147 : return papoLayers[iLayer]; 110 : } 111 : 112 : /*! 113 : \brief Test datasource capabilities 114 : 115 : \param pszCap capability 116 : 117 : \return TRUE if supported or FALSE if not supported 118 : */ 119 0 : int OGRVFKDataSource::TestCapability(const char *pszCap) 120 : { 121 0 : if (EQUAL(pszCap, "IsPreProcessed") && poReader) 122 : { 123 0 : if (poReader->IsPreProcessed()) 124 0 : return TRUE; 125 : } 126 : 127 0 : return FALSE; 128 : } 129 : 130 : /*! 131 : \brief Create OGR layer from VFKDataBlock 132 : 133 : \param poDataBlock pointer to VFKDataBlock instance 134 : 135 : \return pointer to OGRVFKLayer instance or NULL on error 136 : */ 137 : OGRVFKLayer * 138 976 : OGRVFKDataSource::CreateLayerFromBlock(const IVFKDataBlock *poDataBlock) 139 : { 140 : /* create an empty layer */ 141 : OGRVFKLayer *poLayer = new OGRVFKLayer( 142 976 : poDataBlock->GetName(), nullptr, poDataBlock->GetGeometryType(), this); 143 : 144 : /* define attributes (properties) */ 145 10208 : for (int iField = 0; iField < poDataBlock->GetPropertyCount(); iField++) 146 : { 147 9232 : VFKPropertyDefn *poProperty = poDataBlock->GetProperty(iField); 148 18464 : OGRFieldDefn oField(poProperty->GetName(), poProperty->GetType()); 149 : 150 9232 : if (poProperty->GetWidth() > 0) 151 9232 : oField.SetWidth(poProperty->GetWidth()); 152 9232 : if (poProperty->GetPrecision() > 0) 153 480 : oField.SetPrecision(poProperty->GetPrecision()); 154 : 155 9232 : poLayer->GetLayerDefn()->AddFieldDefn(&oField); 156 : } 157 : 158 976 : if (poDataBlock->GetReader()->HasFileField()) 159 : { 160 : /* open option FILE_FIELD=YES specified, append extra 161 : * attribute */ 162 122 : OGRFieldDefn oField(FILE_COLUMN, OFTString); 163 61 : oField.SetWidth(255); 164 61 : poLayer->GetLayerDefn()->AddFieldDefn(&oField); 165 : } 166 : 167 976 : return poLayer; 168 : }