Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: OpenGIS Simple Features Reference Implementation 4 : * Purpose: Implements OGRMemDataSource class. 5 : * Author: Frank Warmerdam, warmerdam@pobox.com 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2003, Frank Warmerdam <warmerdam@pobox.com> 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #include "cpl_port.h" 14 : #include "ogr_mem.h" 15 : 16 : #include "cpl_conv.h" 17 : #include "cpl_string.h" 18 : #include "ogr_core.h" 19 : #include "ogr_spatialref.h" 20 : #include "ogrsf_frmts.h" 21 : 22 : /************************************************************************/ 23 : /* OGRMemDataSource() */ 24 : /************************************************************************/ 25 : 26 758 : OGRMemDataSource::OGRMemDataSource(const char *pszFilename, 27 758 : char ** /* papszOptions */) 28 758 : : papoLayers(nullptr), nLayers(0) 29 : { 30 758 : SetDescription(pszFilename); 31 758 : } 32 : 33 : /************************************************************************/ 34 : /* ~OGRMemDataSource() */ 35 : /************************************************************************/ 36 : 37 1514 : OGRMemDataSource::~OGRMemDataSource() 38 : 39 : { 40 1626 : for (int i = 0; i < nLayers; i++) 41 869 : delete papoLayers[i]; 42 : 43 757 : CPLFree(papoLayers); 44 1514 : } 45 : 46 : /************************************************************************/ 47 : /* ICreateLayer() */ 48 : /************************************************************************/ 49 : 50 : OGRLayer * 51 877 : OGRMemDataSource::ICreateLayer(const char *pszLayerName, 52 : const OGRGeomFieldDefn *poGeomFieldDefn, 53 : CSLConstList papszOptions) 54 : { 55 : // Create the layer object. 56 : 57 877 : const auto eType = poGeomFieldDefn ? poGeomFieldDefn->GetType() : wkbNone; 58 : const auto poSRSIn = 59 877 : poGeomFieldDefn ? poGeomFieldDefn->GetSpatialRef() : nullptr; 60 : 61 877 : OGRSpatialReference *poSRS = nullptr; 62 877 : if (poSRSIn) 63 : { 64 175 : poSRS = poSRSIn->Clone(); 65 175 : poSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); 66 : } 67 877 : OGRMemLayer *poLayer = new OGRMemLayer(pszLayerName, poSRS, eType); 68 877 : if (poSRS) 69 : { 70 175 : poSRS->Release(); 71 : } 72 : 73 877 : if (CPLFetchBool(papszOptions, "ADVERTIZE_UTF8", false)) 74 31 : poLayer->SetAdvertizeUTF8(true); 75 : 76 877 : poLayer->SetDataset(this); 77 877 : poLayer->SetFIDColumn(CSLFetchNameValueDef(papszOptions, "FID", "")); 78 : 79 : // Add layer to data source layer list. 80 877 : papoLayers = static_cast<OGRMemLayer **>( 81 877 : CPLRealloc(papoLayers, sizeof(OGRMemLayer *) * (nLayers + 1))); 82 : 83 877 : papoLayers[nLayers++] = poLayer; 84 : 85 877 : return poLayer; 86 : } 87 : 88 : /************************************************************************/ 89 : /* DeleteLayer() */ 90 : /************************************************************************/ 91 : 92 9 : OGRErr OGRMemDataSource::DeleteLayer(int iLayer) 93 : 94 : { 95 9 : if (iLayer >= 0 && iLayer < nLayers) 96 : { 97 7 : delete papoLayers[iLayer]; 98 : 99 9 : for (int i = iLayer + 1; i < nLayers; ++i) 100 2 : papoLayers[i - 1] = papoLayers[i]; 101 : 102 7 : --nLayers; 103 : 104 7 : return OGRERR_NONE; 105 : } 106 : 107 2 : return OGRERR_FAILURE; 108 : } 109 : 110 : /************************************************************************/ 111 : /* TestCapability() */ 112 : /************************************************************************/ 113 : 114 691 : int OGRMemDataSource::TestCapability(const char *pszCap) 115 : 116 : { 117 691 : if (EQUAL(pszCap, ODsCCreateLayer)) 118 256 : return TRUE; 119 435 : else if (EQUAL(pszCap, ODsCDeleteLayer)) 120 1 : return TRUE; 121 434 : else if (EQUAL(pszCap, ODsCCreateGeomFieldAfterCreateLayer)) 122 169 : return TRUE; 123 265 : else if (EQUAL(pszCap, ODsCCurveGeometries)) 124 19 : return TRUE; 125 246 : else if (EQUAL(pszCap, ODsCMeasuredGeometries)) 126 0 : return TRUE; 127 246 : else if (EQUAL(pszCap, ODsCZGeometries)) 128 0 : return TRUE; 129 246 : else if (EQUAL(pszCap, ODsCRandomLayerWrite)) 130 8 : return TRUE; 131 238 : else if (EQUAL(pszCap, ODsCAddFieldDomain)) 132 10 : return TRUE; 133 228 : else if (EQUAL(pszCap, ODsCDeleteFieldDomain)) 134 0 : return TRUE; 135 228 : else if (EQUAL(pszCap, ODsCUpdateFieldDomain)) 136 0 : return TRUE; 137 : 138 228 : return FALSE; 139 : } 140 : 141 : /************************************************************************/ 142 : /* GetLayer() */ 143 : /************************************************************************/ 144 : 145 4366 : OGRLayer *OGRMemDataSource::GetLayer(int iLayer) 146 : 147 : { 148 4366 : if (iLayer < 0 || iLayer >= nLayers) 149 5 : return nullptr; 150 : 151 4361 : return papoLayers[iLayer]; 152 : } 153 : 154 : /************************************************************************/ 155 : /* AddFieldDomain() */ 156 : /************************************************************************/ 157 : 158 20 : bool OGRMemDataSource::AddFieldDomain(std::unique_ptr<OGRFieldDomain> &&domain, 159 : std::string &failureReason) 160 : { 161 20 : if (GetFieldDomain(domain->GetName()) != nullptr) 162 : { 163 1 : failureReason = "A domain of identical name already exists"; 164 1 : return false; 165 : } 166 19 : const std::string domainName(domain->GetName()); 167 19 : m_oMapFieldDomains[domainName] = std::move(domain); 168 19 : return true; 169 : } 170 : 171 : /************************************************************************/ 172 : /* DeleteFieldDomain() */ 173 : /************************************************************************/ 174 : 175 6 : bool OGRMemDataSource::DeleteFieldDomain(const std::string &name, 176 : std::string &failureReason) 177 : { 178 6 : const auto iter = m_oMapFieldDomains.find(name); 179 6 : if (iter == m_oMapFieldDomains.end()) 180 : { 181 2 : failureReason = "Domain does not exist"; 182 2 : return false; 183 : } 184 : 185 4 : m_oMapFieldDomains.erase(iter); 186 : 187 8 : for (int i = 0; i < nLayers; i++) 188 : { 189 4 : OGRMemLayer *poLayer = papoLayers[i]; 190 10 : for (int j = 0; j < poLayer->GetLayerDefn()->GetFieldCount(); ++j) 191 : { 192 : OGRFieldDefn *poFieldDefn = 193 6 : poLayer->GetLayerDefn()->GetFieldDefn(j); 194 6 : if (poFieldDefn->GetDomainName() == name) 195 : { 196 3 : auto oTemporaryUnsealer(poFieldDefn->GetTemporaryUnsealer()); 197 3 : poFieldDefn->SetDomainName(std::string()); 198 : } 199 : } 200 : } 201 : 202 4 : return true; 203 : } 204 : 205 : /************************************************************************/ 206 : /* UpdateFieldDomain() */ 207 : /************************************************************************/ 208 : 209 3 : bool OGRMemDataSource::UpdateFieldDomain( 210 : std::unique_ptr<OGRFieldDomain> &&domain, std::string &failureReason) 211 : { 212 6 : const std::string domainName(domain->GetName()); 213 3 : const auto iter = m_oMapFieldDomains.find(domainName); 214 3 : if (iter == m_oMapFieldDomains.end()) 215 : { 216 1 : failureReason = "No matching domain found"; 217 1 : return false; 218 : } 219 2 : m_oMapFieldDomains[domainName] = std::move(domain); 220 2 : return true; 221 : }