Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: S-101 driver 4 : * Purpose: Implements OGRS101Dataset 5 : * Author: Even Rouault <even dot rouault at spatialys.com> 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2026, Even Rouault <even dot rouault at spatialys.com> 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #include "ogr_s101.h" 14 : #include "ogrs101drivercore.h" 15 : #include "ogrs101featurecatalog.h" 16 : 17 : /************************************************************************/ 18 : /* UnloadDriver() */ 19 : /************************************************************************/ 20 : 21 1294 : /* static */ void OGRS101Dataset::UnloadDriver(GDALDriver *) 22 : { 23 1294 : OGRS101FeatureCatalog::CleanupSingletonFeatureCatalog(); 24 1294 : } 25 : 26 : /************************************************************************/ 27 : /* Open() */ 28 : /************************************************************************/ 29 : 30 501 : /* static */ GDALDataset *OGRS101Dataset::Open(GDALOpenInfo *poOpenInfo) 31 : { 32 501 : if (!OGRS101DriverIdentify(poOpenInfo)) 33 0 : return nullptr; 34 : 35 501 : if (poOpenInfo->eAccess == GA_Update) 36 : { 37 0 : ReportUpdateNotSupportedByDriver("S101"); 38 0 : return nullptr; 39 : } 40 : 41 1002 : auto poDS = std::make_unique<OGRS101Dataset>(); 42 : { 43 501 : auto poReader = std::make_unique<OGRS101Reader>(); 44 501 : if (!poReader->Load(poOpenInfo)) 45 163 : return nullptr; 46 338 : poDS->m_poReader = std::move(poReader); 47 : } 48 338 : auto &poReader = poDS->m_poReader; 49 338 : poDS->SetMetadata(poReader->GetMetadata().List()); 50 : 51 338 : if (poReader->IsCancelled()) 52 5 : return poDS.release(); 53 : 54 : { 55 666 : auto poFDefn = poReader->StealInformationTypeFeatureDefn(); 56 333 : if (poFDefn) 57 : { 58 396 : poDS->m_apoLayers.push_back( 59 594 : std::make_unique<OGRS101LayerInformationType>( 60 198 : *poDS, poReader->GetInformationTypeRecords(), 61 198 : std::move(poFDefn))); 62 : } 63 : } 64 : 65 537 : for (auto &[nCRSId, poFDefn] : poReader->StealPointFeatureDefns()) 66 : { 67 204 : const auto &oMap = poReader->GetMapCRSIdToRecordIdxForPoints(); 68 204 : const auto oIterIndices = oMap.find(nCRSId); 69 204 : CPLAssert(oIterIndices != oMap.end()); 70 204 : const auto &anRecordIndices = oIterIndices->second; 71 612 : poDS->m_apoLayers.push_back(std::make_unique<OGRS101LayerPoint>( 72 204 : *poDS, poReader->GetPointRecords(), anRecordIndices, 73 204 : std::move(poFDefn))); 74 : } 75 : 76 410 : for (auto &[nCRSId, poFDefn] : poReader->StealMultiPointFeatureDefns()) 77 : { 78 77 : const auto &oMap = poReader->GetMapCRSIdToRecordIdxForMultiPoints(); 79 77 : const auto oIterIndices = oMap.find(nCRSId); 80 77 : CPLAssert(oIterIndices != oMap.end()); 81 77 : const auto &anRecordIndices = oIterIndices->second; 82 231 : poDS->m_apoLayers.push_back(std::make_unique<OGRS101LayerMultiPoint>( 83 77 : *poDS, poReader->GetMultiPointRecords(), anRecordIndices, 84 77 : std::move(poFDefn))); 85 : } 86 : 87 : { 88 666 : auto poFDefn = poReader->StealCurveFeatureDefn(); 89 333 : if (poFDefn) 90 : { 91 432 : poDS->m_apoLayers.push_back(std::make_unique<OGRS101LayerCurve>( 92 288 : *poDS, poReader->GetCurveRecords(), std::move(poFDefn))); 93 : } 94 : } 95 : 96 : { 97 666 : auto poFDefn = poReader->StealCompositeCurveFeatureDefn(); 98 333 : if (poFDefn) 99 : { 100 218 : poDS->m_apoLayers.push_back( 101 327 : std::make_unique<OGRS101LayerCompositeCurve>( 102 109 : *poDS, poReader->GetCompositeCurveRecords(), 103 109 : std::move(poFDefn))); 104 : } 105 : } 106 : 107 : { 108 666 : auto poFDefn = poReader->StealSurfaceFeatureDefn(); 109 333 : if (poFDefn) 110 : { 111 234 : poDS->m_apoLayers.push_back(std::make_unique<OGRS101LayerSurface>( 112 156 : *poDS, poReader->GetSurfaceRecords(), std::move(poFDefn))); 113 : } 114 : } 115 : 116 598 : for (auto &[featureTypeKey, oLayerDef] : 117 931 : poReader->StealFeatureTypeLayerDefs()) 118 : { 119 : auto poLayer = std::make_unique<OGRS101LayerFeatureType>( 120 299 : *poDS, poReader->GetFeatureTypeRecords(), oLayerDef.anRecordIndices, 121 598 : std::move(oLayerDef.poFeatureDefn)); 122 299 : if (!oLayerDef.osName.empty()) 123 0 : poLayer->SetMetadataItem("NAME", oLayerDef.osName.c_str()); 124 299 : if (!oLayerDef.osDefinition.empty()) 125 0 : poLayer->SetMetadataItem("DEFINITION", 126 0 : oLayerDef.osDefinition.c_str()); 127 299 : if (!oLayerDef.osAlias.empty()) 128 0 : poLayer->SetMetadataItem("ALIAS", oLayerDef.osAlias.c_str()); 129 299 : poDS->m_apoLayers.push_back(std::move(poLayer)); 130 : } 131 : 132 333 : poDS->m_oMapFieldDomains = std::move(poReader->StealFieldDomains()); 133 : 134 333 : return poDS.release(); 135 : } 136 : 137 : /************************************************************************/ 138 : /* GetLayerCount() */ 139 : /************************************************************************/ 140 : 141 11545 : int OGRS101Dataset::GetLayerCount() const 142 : { 143 11545 : return static_cast<int>(m_apoLayers.size()); 144 : } 145 : 146 : /************************************************************************/ 147 : /* GetLayer() */ 148 : /************************************************************************/ 149 : 150 6455 : OGRLayer *OGRS101Dataset::GetLayer(int i) const 151 : { 152 6455 : if (i < 0 || i >= GetLayerCount()) 153 52 : return nullptr; 154 6403 : return m_apoLayers[i].get(); 155 : } 156 : 157 : /************************************************************************/ 158 : /* OGRS101Layer::TestCapability() */ 159 : /************************************************************************/ 160 : 161 291 : int OGRS101Dataset::TestCapability(const char *pszCap) const 162 : { 163 291 : if (EQUAL(pszCap, ODsCZGeometries)) 164 : { 165 478 : for (const auto &poLayer : m_apoLayers) 166 : { 167 421 : if (poLayer->TestCapability(OLCZGeometries)) 168 18 : return true; 169 : } 170 57 : return false; 171 : } 172 : 173 : // Totally custom, for autotest purposes 174 216 : if (EQUAL(pszCap, "HasFeatureCatalog")) 175 2 : return m_poReader->GetFeatureCatalog() != nullptr; 176 : 177 214 : return GDALDataset::TestCapability(pszCap); 178 : }