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 1263 : /* static */ void OGRS101Dataset::UnloadDriver(GDALDriver *) 22 : { 23 1263 : OGRS101FeatureCatalog::CleanupSingletonFeatureCatalog(); 24 1263 : } 25 : 26 : /************************************************************************/ 27 : /* Open() */ 28 : /************************************************************************/ 29 : 30 355 : /* static */ GDALDataset *OGRS101Dataset::Open(GDALOpenInfo *poOpenInfo) 31 : { 32 355 : if (!OGRS101DriverIdentify(poOpenInfo)) 33 0 : return nullptr; 34 : 35 355 : if (poOpenInfo->eAccess == GA_Update) 36 : { 37 0 : ReportUpdateNotSupportedByDriver("S101"); 38 0 : return nullptr; 39 : } 40 : 41 710 : auto poDS = std::make_unique<OGRS101Dataset>(); 42 : { 43 355 : auto poReader = std::make_unique<OGRS101Reader>(); 44 355 : if (!poReader->Load(poOpenInfo)) 45 113 : return nullptr; 46 242 : poDS->m_poReader = std::move(poReader); 47 : } 48 242 : auto &poReader = poDS->m_poReader; 49 242 : poDS->SetMetadata(poReader->GetMetadata().List()); 50 : 51 : { 52 484 : auto poFDefn = poReader->StealInformationTypeFeatureDefn(); 53 242 : if (poFDefn) 54 : { 55 312 : poDS->m_apoLayers.push_back( 56 468 : std::make_unique<OGRS101LayerInformationType>( 57 156 : *poDS, poReader->GetInformationTypeRecords(), 58 156 : std::move(poFDefn))); 59 : } 60 : } 61 : 62 392 : for (auto &[nCRSId, poFDefn] : poReader->StealPointFeatureDefns()) 63 : { 64 150 : const auto &oMap = poReader->GetMapCRSIdToRecordIdxForPoints(); 65 150 : const auto oIterIndices = oMap.find(nCRSId); 66 150 : CPLAssert(oIterIndices != oMap.end()); 67 150 : const auto &anRecordIndices = oIterIndices->second; 68 450 : poDS->m_apoLayers.push_back(std::make_unique<OGRS101LayerPoint>( 69 150 : *poDS, poReader->GetPointRecords(), anRecordIndices, 70 150 : std::move(poFDefn))); 71 : } 72 : 73 298 : for (auto &[nCRSId, poFDefn] : poReader->StealMultiPointFeatureDefns()) 74 : { 75 56 : const auto &oMap = poReader->GetMapCRSIdToRecordIdxForMultiPoints(); 76 56 : const auto oIterIndices = oMap.find(nCRSId); 77 56 : CPLAssert(oIterIndices != oMap.end()); 78 56 : const auto &anRecordIndices = oIterIndices->second; 79 168 : poDS->m_apoLayers.push_back(std::make_unique<OGRS101LayerMultiPoint>( 80 56 : *poDS, poReader->GetMultiPointRecords(), anRecordIndices, 81 56 : std::move(poFDefn))); 82 : } 83 : 84 : { 85 484 : auto poFDefn = poReader->StealCurveFeatureDefn(); 86 242 : if (poFDefn) 87 : { 88 318 : poDS->m_apoLayers.push_back(std::make_unique<OGRS101LayerCurve>( 89 212 : *poDS, poReader->GetCurveRecords(), std::move(poFDefn))); 90 : } 91 : } 92 : 93 : { 94 484 : auto poFDefn = poReader->StealCompositeCurveFeatureDefn(); 95 242 : if (poFDefn) 96 : { 97 162 : poDS->m_apoLayers.push_back( 98 243 : std::make_unique<OGRS101LayerCompositeCurve>( 99 81 : *poDS, poReader->GetCompositeCurveRecords(), 100 81 : std::move(poFDefn))); 101 : } 102 : } 103 : 104 : { 105 484 : auto poFDefn = poReader->StealSurfaceFeatureDefn(); 106 242 : if (poFDefn) 107 : { 108 189 : poDS->m_apoLayers.push_back(std::make_unique<OGRS101LayerSurface>( 109 126 : *poDS, poReader->GetSurfaceRecords(), std::move(poFDefn))); 110 : } 111 : } 112 : 113 564 : for (auto &[featureTypeKey, oLayerDef] : 114 806 : poReader->StealFeatureTypeLayerDefs()) 115 : { 116 : auto poLayer = std::make_unique<OGRS101LayerFeatureType>( 117 282 : *poDS, poReader->GetFeatureTypeRecords(), oLayerDef.anRecordIndices, 118 564 : std::move(oLayerDef.poFeatureDefn)); 119 282 : if (!oLayerDef.osName.empty()) 120 0 : poLayer->SetMetadataItem("NAME", oLayerDef.osName.c_str()); 121 282 : if (!oLayerDef.osDefinition.empty()) 122 0 : poLayer->SetMetadataItem("DEFINITION", 123 0 : oLayerDef.osDefinition.c_str()); 124 282 : if (!oLayerDef.osAlias.empty()) 125 0 : poLayer->SetMetadataItem("ALIAS", oLayerDef.osAlias.c_str()); 126 282 : poDS->m_apoLayers.push_back(std::move(poLayer)); 127 : } 128 : 129 242 : poDS->m_oMapFieldDomains = std::move(poReader->StealFieldDomains()); 130 : 131 242 : return poDS.release(); 132 : } 133 : 134 : /************************************************************************/ 135 : /* GetLayerCount() */ 136 : /************************************************************************/ 137 : 138 8922 : int OGRS101Dataset::GetLayerCount() const 139 : { 140 8922 : return static_cast<int>(m_apoLayers.size()); 141 : } 142 : 143 : /************************************************************************/ 144 : /* GetLayer() */ 145 : /************************************************************************/ 146 : 147 5055 : OGRLayer *OGRS101Dataset::GetLayer(int i) const 148 : { 149 5055 : if (i < 0 || i >= GetLayerCount()) 150 26 : return nullptr; 151 5029 : return m_apoLayers[i].get(); 152 : } 153 : 154 : /************************************************************************/ 155 : /* OGRS101Layer::TestCapability() */ 156 : /************************************************************************/ 157 : 158 172 : int OGRS101Dataset::TestCapability(const char *pszCap) const 159 : { 160 172 : if (EQUAL(pszCap, ODsCZGeometries)) 161 : { 162 354 : for (const auto &poLayer : m_apoLayers) 163 : { 164 321 : if (poLayer->TestCapability(OLCZGeometries)) 165 14 : return true; 166 : } 167 33 : return false; 168 : } 169 : 170 : // Totally custom, for autotest purposes 171 125 : if (EQUAL(pszCap, "HasFeatureCatalog")) 172 2 : return m_poReader->GetFeatureCatalog() != nullptr; 173 : 174 123 : return GDALDataset::TestCapability(pszCap); 175 : }