Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: GDAL TileDB Driver 4 : * Purpose: Implement GDAL TileDB multidimensional support based on https://www.tiledb.io 5 : * Author: TileDB, Inc 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2023, TileDB, Inc 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #include "tiledbmultidim.h" 14 : 15 : /************************************************************************/ 16 : /* TileDBSingleArrayGroup::SanitizeNameForPath() */ 17 : /************************************************************************/ 18 : 19 : /* static */ 20 34 : std::string TileDBSharedResource::SanitizeNameForPath(const std::string &osName) 21 : { 22 34 : return CPLLaunderForFilenameSafe(osName); 23 : } 24 : 25 : /************************************************************************/ 26 : /* TileDBArrayGroup::Create() */ 27 : /************************************************************************/ 28 : 29 1 : std::shared_ptr<GDALGroup> TileDBArrayGroup::Create( 30 : const std::shared_ptr<TileDBSharedResource> &poSharedResource, 31 : const std::string &osArrayPath) 32 : { 33 : auto poTileDBArray = std::make_unique<tiledb::Array>( 34 2 : poSharedResource->GetCtx(), osArrayPath, TILEDB_READ); 35 2 : auto schema = poTileDBArray->schema(); 36 1 : const auto nAttributes = schema.attribute_num(); 37 2 : const std::string osBaseName(CPLGetFilename(osArrayPath.c_str())); 38 2 : std::vector<std::shared_ptr<GDALMDArray>> apoArrays; 39 1 : if (nAttributes == 1) 40 : { 41 : auto poArray = TileDBArray::OpenFromDisk(poSharedResource, nullptr, "/", 42 0 : osBaseName, std::string(), 43 0 : osArrayPath, nullptr); 44 0 : if (!poArray) 45 0 : return nullptr; 46 0 : apoArrays.emplace_back(poArray); 47 : } 48 : else 49 : { 50 4 : for (uint32_t i = 0; i < nAttributes; ++i) 51 : { 52 : auto poArray = TileDBArray::OpenFromDisk( 53 : poSharedResource, nullptr, "/", 54 6 : osBaseName + "." + schema.attribute(i).name(), 55 12 : schema.attribute(i).name(), osArrayPath, nullptr); 56 3 : if (!poArray) 57 0 : return nullptr; 58 3 : apoArrays.emplace_back(poArray); 59 : } 60 : } 61 1 : return std::make_shared<TileDBArrayGroup>(apoArrays); 62 : } 63 : 64 : /************************************************************************/ 65 : /* TileDBArrayGroup::GetMDArrayNames() */ 66 : /************************************************************************/ 67 : 68 : std::vector<std::string> 69 2 : TileDBArrayGroup::GetMDArrayNames(CSLConstList /*papszOptions*/) const 70 : { 71 2 : std::vector<std::string> aosNames; 72 8 : for (const auto &poArray : m_apoArrays) 73 6 : aosNames.emplace_back(poArray->GetName()); 74 2 : return aosNames; 75 : } 76 : 77 : /************************************************************************/ 78 : /* TileDBArrayGroup::OpenMDArray() */ 79 : /************************************************************************/ 80 : 81 : std::shared_ptr<GDALMDArray> 82 1 : TileDBArrayGroup::OpenMDArray(const std::string &osName, 83 : CSLConstList /*papszOptions*/) const 84 : { 85 1 : for (const auto &poArray : m_apoArrays) 86 : { 87 1 : if (poArray->GetName() == osName) 88 1 : return poArray; 89 : } 90 0 : return nullptr; 91 : } 92 : 93 : /************************************************************************/ 94 : /* OpenMultiDimensional() */ 95 : /************************************************************************/ 96 : 97 30 : GDALDataset *TileDBDataset::OpenMultiDimensional(GDALOpenInfo *poOpenInfo) 98 : { 99 : const char *pszConfig = 100 30 : CSLFetchNameValue(poOpenInfo->papszOpenOptions, "TILEDB_CONFIG"); 101 : 102 30 : std::unique_ptr<tiledb::Context> pCtxt; 103 30 : if (pszConfig != nullptr) 104 : { 105 0 : tiledb::Config cfg(pszConfig); 106 0 : pCtxt.reset(new tiledb::Context(cfg)); 107 : } 108 : else 109 : { 110 30 : pCtxt.reset(new tiledb::Context()); 111 : } 112 : 113 : const std::string osPath = 114 60 : TileDBDataset::VSI_to_tiledb_uri(poOpenInfo->pszFilename); 115 : 116 30 : const auto eType = tiledb::Object::object(*(pCtxt.get()), osPath).type(); 117 : 118 : auto poSharedResource = std::make_shared<TileDBSharedResource>( 119 60 : std::move(pCtxt), poOpenInfo->eAccess == GA_Update); 120 : 121 60 : poSharedResource->SetDumpStats(CPLTestBool( 122 30 : CSLFetchNameValueDef(poOpenInfo->papszOpenOptions, "STATS", "FALSE"))); 123 : 124 : const char *pszTimestamp = 125 30 : CSLFetchNameValue(poOpenInfo->papszOpenOptions, "TILEDB_TIMESTAMP"); 126 30 : if (pszTimestamp) 127 0 : poSharedResource->SetTimestamp( 128 0 : std::strtoull(pszTimestamp, nullptr, 10)); 129 : 130 30 : std::shared_ptr<GDALGroup> poRG; 131 30 : if (eType == tiledb::Object::Type::Array) 132 : { 133 1 : poRG = TileDBArrayGroup::Create(poSharedResource, osPath); 134 : } 135 : else 136 : { 137 58 : poRG = TileDBGroup::OpenFromDisk(poSharedResource, std::string(), "/", 138 29 : osPath); 139 : } 140 30 : if (!poRG) 141 0 : return nullptr; 142 : 143 30 : auto poDS = new TileDBMultiDimDataset(poRG); 144 30 : poDS->SetDescription(poOpenInfo->pszFilename); 145 30 : return poDS; 146 : } 147 : 148 : /************************************************************************/ 149 : /* CreateMultiDimensional() */ 150 : /************************************************************************/ 151 : 152 : GDALDataset * 153 25 : TileDBDataset::CreateMultiDimensional(const char *pszFilename, 154 : CSLConstList /*papszRootGroupOptions*/, 155 : CSLConstList papszOptions) 156 : { 157 25 : const char *pszConfig = CSLFetchNameValue(papszOptions, "TILEDB_CONFIG"); 158 : 159 25 : std::unique_ptr<tiledb::Context> pCtxt; 160 25 : if (pszConfig != nullptr) 161 : { 162 0 : tiledb::Config cfg(pszConfig); 163 0 : pCtxt.reset(new tiledb::Context(cfg)); 164 : } 165 : else 166 : { 167 25 : pCtxt.reset(new tiledb::Context()); 168 : } 169 : 170 50 : const std::string osPath = TileDBDataset::VSI_to_tiledb_uri(pszFilename); 171 : 172 : auto poSharedResource = 173 50 : std::make_shared<TileDBSharedResource>(std::move(pCtxt), true); 174 : 175 25 : poSharedResource->SetDumpStats( 176 25 : CPLTestBool(CSLFetchNameValueDef(papszOptions, "STATS", "FALSE"))); 177 : 178 : const char *pszTimestamp = 179 25 : CSLFetchNameValue(papszOptions, "TILEDB_TIMESTAMP"); 180 25 : if (pszTimestamp) 181 0 : poSharedResource->SetTimestamp( 182 0 : std::strtoull(pszTimestamp, nullptr, 10)); 183 : 184 : auto poRG = 185 75 : TileDBGroup::CreateOnDisk(poSharedResource, std::string(), "/", osPath); 186 25 : if (!poRG) 187 0 : return nullptr; 188 : 189 25 : auto poDS = new TileDBMultiDimDataset(poRG); 190 25 : poDS->SetDescription(pszFilename); 191 25 : return poDS; 192 : } 193 : 194 : /************************************************************************/ 195 : /* TileDBDimension::GetIndexingVariable() */ 196 : /************************************************************************/ 197 : 198 29 : std::shared_ptr<GDALMDArray> TileDBDimension::GetIndexingVariable() const 199 : { 200 29 : return m_poIndexingVariable; 201 : } 202 : 203 : /************************************************************************/ 204 : /* TileDBMultiDimDataset::GetRootGroup() */ 205 : /************************************************************************/ 206 : 207 58 : std::shared_ptr<GDALGroup> TileDBMultiDimDataset::GetRootGroup() const 208 : { 209 58 : return m_poRG; 210 : }