Line data Source code
1 : /******************************************************************************
2 : *
3 : * Name: gdalmultidim_c_api_dimension.cpp
4 : * Project: GDAL Core
5 : * Purpose: C API for GDALGroup
6 : * Author: Even Rouault <even.rouault at spatialys.com>
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2019, Even Rouault <even.rouault at spatialys.com>
10 : *
11 : * SPDX-License-Identifier: MIT
12 : ****************************************************************************/
13 :
14 : #include "gdal_multidim.h"
15 : #include "gdalmultidim_priv.h"
16 : #include "gdal_fwd.h"
17 : #include "ogrsf_frmts.h"
18 :
19 : /************************************************************************/
20 : /* GDALGroupRelease() */
21 : /************************************************************************/
22 :
23 : /** Release the GDAL in-memory object associated with a GDALGroupH.
24 : *
25 : * Note: when applied on a object coming from a driver, this does not
26 : * destroy the object in the file, database, etc...
27 : */
28 2414 : void GDALGroupRelease(GDALGroupH hGroup)
29 : {
30 2414 : delete hGroup;
31 2414 : }
32 :
33 : /************************************************************************/
34 : /* GDALGroupGetName() */
35 : /************************************************************************/
36 :
37 : /** Return the name of the group.
38 : *
39 : * The returned pointer is valid until hGroup is released.
40 : *
41 : * This is the same as the C++ method GDALGroup::GetName().
42 : */
43 97 : const char *GDALGroupGetName(GDALGroupH hGroup)
44 : {
45 97 : VALIDATE_POINTER1(hGroup, __func__, nullptr);
46 97 : return hGroup->m_poImpl->GetName().c_str();
47 : }
48 :
49 : /************************************************************************/
50 : /* GDALGroupGetFullName() */
51 : /************************************************************************/
52 :
53 : /** Return the full name of the group.
54 : *
55 : * The returned pointer is valid until hGroup is released.
56 : *
57 : * This is the same as the C++ method GDALGroup::GetFullName().
58 : */
59 49 : const char *GDALGroupGetFullName(GDALGroupH hGroup)
60 : {
61 49 : VALIDATE_POINTER1(hGroup, __func__, nullptr);
62 49 : return hGroup->m_poImpl->GetFullName().c_str();
63 : }
64 :
65 : /************************************************************************/
66 : /* GDALGroupGetMDArrayNames() */
67 : /************************************************************************/
68 :
69 : /** Return the list of multidimensional array names contained in this group.
70 : *
71 : * This is the same as the C++ method GDALGroup::GetGroupNames().
72 : *
73 : * @return the array names, to be freed with CSLDestroy()
74 : */
75 414 : char **GDALGroupGetMDArrayNames(GDALGroupH hGroup, CSLConstList papszOptions)
76 : {
77 414 : VALIDATE_POINTER1(hGroup, __func__, nullptr);
78 828 : auto names = hGroup->m_poImpl->GetMDArrayNames(papszOptions);
79 828 : CPLStringList res;
80 1007 : for (const auto &name : names)
81 : {
82 593 : res.AddString(name.c_str());
83 : }
84 414 : return res.StealList();
85 : }
86 :
87 : /************************************************************************/
88 : /* GDALGroupGetMDArrayFullNamesRecursive() */
89 : /************************************************************************/
90 :
91 : /** Return the list of multidimensional array full names contained in this
92 : * group and its subgroups.
93 : *
94 : * This is the same as the C++ method GDALGroup::GetMDArrayFullNamesRecursive().
95 : *
96 : * @return the array names, to be freed with CSLDestroy()
97 : *
98 : * @since 3.11
99 : */
100 1 : char **GDALGroupGetMDArrayFullNamesRecursive(GDALGroupH hGroup,
101 : CSLConstList papszGroupOptions,
102 : CSLConstList papszArrayOptions)
103 : {
104 1 : VALIDATE_POINTER1(hGroup, __func__, nullptr);
105 1 : auto names = hGroup->m_poImpl->GetMDArrayFullNamesRecursive(
106 2 : papszGroupOptions, papszArrayOptions);
107 2 : CPLStringList res;
108 5 : for (const auto &name : names)
109 : {
110 4 : res.AddString(name.c_str());
111 : }
112 1 : return res.StealList();
113 : }
114 :
115 : /************************************************************************/
116 : /* GDALGroupOpenMDArray() */
117 : /************************************************************************/
118 :
119 : /** Open and return a multidimensional array.
120 : *
121 : * This is the same as the C++ method GDALGroup::OpenMDArray().
122 : *
123 : * @return the array, to be freed with GDALMDArrayRelease(), or nullptr.
124 : */
125 1645 : GDALMDArrayH GDALGroupOpenMDArray(GDALGroupH hGroup, const char *pszMDArrayName,
126 : CSLConstList papszOptions)
127 : {
128 1645 : VALIDATE_POINTER1(hGroup, __func__, nullptr);
129 1645 : VALIDATE_POINTER1(pszMDArrayName, __func__, nullptr);
130 4935 : auto array = hGroup->m_poImpl->OpenMDArray(std::string(pszMDArrayName),
131 4935 : papszOptions);
132 1645 : if (!array)
133 30 : return nullptr;
134 1615 : return new GDALMDArrayHS(array);
135 : }
136 :
137 : /************************************************************************/
138 : /* GDALGroupOpenMDArrayFromFullname() */
139 : /************************************************************************/
140 :
141 : /** Open and return a multidimensional array from its fully qualified name.
142 : *
143 : * This is the same as the C++ method GDALGroup::OpenMDArrayFromFullname().
144 : *
145 : * @return the array, to be freed with GDALMDArrayRelease(), or nullptr.
146 : *
147 : * @since GDAL 3.2
148 : */
149 19 : GDALMDArrayH GDALGroupOpenMDArrayFromFullname(GDALGroupH hGroup,
150 : const char *pszFullname,
151 : CSLConstList papszOptions)
152 : {
153 19 : VALIDATE_POINTER1(hGroup, __func__, nullptr);
154 19 : VALIDATE_POINTER1(pszFullname, __func__, nullptr);
155 19 : auto array = hGroup->m_poImpl->OpenMDArrayFromFullname(
156 57 : std::string(pszFullname), papszOptions);
157 19 : if (!array)
158 2 : return nullptr;
159 17 : return new GDALMDArrayHS(array);
160 : }
161 :
162 : /************************************************************************/
163 : /* GDALGroupResolveMDArray() */
164 : /************************************************************************/
165 :
166 : /** Locate an array in a group and its subgroups by name.
167 : *
168 : * See GDALGroup::ResolveMDArray() for description of the behavior.
169 : * @since GDAL 3.2
170 : */
171 19 : GDALMDArrayH GDALGroupResolveMDArray(GDALGroupH hGroup, const char *pszName,
172 : const char *pszStartingPoint,
173 : CSLConstList papszOptions)
174 : {
175 19 : VALIDATE_POINTER1(hGroup, __func__, nullptr);
176 19 : VALIDATE_POINTER1(pszName, __func__, nullptr);
177 19 : VALIDATE_POINTER1(pszStartingPoint, __func__, nullptr);
178 19 : auto array = hGroup->m_poImpl->ResolveMDArray(
179 57 : std::string(pszName), std::string(pszStartingPoint), papszOptions);
180 19 : if (!array)
181 2 : return nullptr;
182 17 : return new GDALMDArrayHS(array);
183 : }
184 :
185 : /************************************************************************/
186 : /* GDALGroupGetGroupNames() */
187 : /************************************************************************/
188 :
189 : /** Return the list of sub-groups contained in this group.
190 : *
191 : * This is the same as the C++ method GDALGroup::GetGroupNames().
192 : *
193 : * @return the group names, to be freed with CSLDestroy()
194 : */
195 109 : char **GDALGroupGetGroupNames(GDALGroupH hGroup, CSLConstList papszOptions)
196 : {
197 109 : VALIDATE_POINTER1(hGroup, __func__, nullptr);
198 218 : auto names = hGroup->m_poImpl->GetGroupNames(papszOptions);
199 218 : CPLStringList res;
200 247 : for (const auto &name : names)
201 : {
202 138 : res.AddString(name.c_str());
203 : }
204 109 : return res.StealList();
205 : }
206 :
207 : /************************************************************************/
208 : /* GDALGroupOpenGroup() */
209 : /************************************************************************/
210 :
211 : /** Open and return a sub-group.
212 : *
213 : * This is the same as the C++ method GDALGroup::OpenGroup().
214 : *
215 : * @return the sub-group, to be freed with GDALGroupRelease(), or nullptr.
216 : */
217 204 : GDALGroupH GDALGroupOpenGroup(GDALGroupH hGroup, const char *pszSubGroupName,
218 : CSLConstList papszOptions)
219 : {
220 204 : VALIDATE_POINTER1(hGroup, __func__, nullptr);
221 204 : VALIDATE_POINTER1(pszSubGroupName, __func__, nullptr);
222 : auto subGroup =
223 612 : hGroup->m_poImpl->OpenGroup(std::string(pszSubGroupName), papszOptions);
224 204 : if (!subGroup)
225 30 : return nullptr;
226 174 : return new GDALGroupHS(subGroup);
227 : }
228 :
229 : /************************************************************************/
230 : /* GDALGroupGetVectorLayerNames() */
231 : /************************************************************************/
232 :
233 : /** Return the list of layer names contained in this group.
234 : *
235 : * This is the same as the C++ method GDALGroup::GetVectorLayerNames().
236 : *
237 : * @return the group names, to be freed with CSLDestroy()
238 : * @since 3.4
239 : */
240 8 : char **GDALGroupGetVectorLayerNames(GDALGroupH hGroup,
241 : CSLConstList papszOptions)
242 : {
243 8 : VALIDATE_POINTER1(hGroup, __func__, nullptr);
244 16 : auto names = hGroup->m_poImpl->GetVectorLayerNames(papszOptions);
245 16 : CPLStringList res;
246 18 : for (const auto &name : names)
247 : {
248 10 : res.AddString(name.c_str());
249 : }
250 8 : return res.StealList();
251 : }
252 :
253 : /************************************************************************/
254 : /* GDALGroupOpenVectorLayer() */
255 : /************************************************************************/
256 :
257 : /** Open and return a vector layer.
258 : *
259 : * This is the same as the C++ method GDALGroup::OpenVectorLayer().
260 : *
261 : * Note that the vector layer is owned by its parent GDALDatasetH, and thus
262 : * the returned handled if only valid while the parent GDALDatasetH is kept
263 : * opened.
264 : *
265 : * @return the vector layer, or nullptr.
266 : * @since 3.4
267 : */
268 12 : OGRLayerH GDALGroupOpenVectorLayer(GDALGroupH hGroup,
269 : const char *pszVectorLayerName,
270 : CSLConstList papszOptions)
271 : {
272 12 : VALIDATE_POINTER1(hGroup, __func__, nullptr);
273 12 : VALIDATE_POINTER1(pszVectorLayerName, __func__, nullptr);
274 24 : return OGRLayer::ToHandle(hGroup->m_poImpl->OpenVectorLayer(
275 24 : std::string(pszVectorLayerName), papszOptions));
276 : }
277 :
278 : /************************************************************************/
279 : /* GDALGroupOpenMDArrayFromFullname() */
280 : /************************************************************************/
281 :
282 : /** Open and return a sub-group from its fully qualified name.
283 : *
284 : * This is the same as the C++ method GDALGroup::OpenGroupFromFullname().
285 : *
286 : * @return the sub-group, to be freed with GDALGroupRelease(), or nullptr.
287 : *
288 : * @since GDAL 3.2
289 : */
290 4 : GDALGroupH GDALGroupOpenGroupFromFullname(GDALGroupH hGroup,
291 : const char *pszFullname,
292 : CSLConstList papszOptions)
293 : {
294 4 : VALIDATE_POINTER1(hGroup, __func__, nullptr);
295 4 : VALIDATE_POINTER1(pszFullname, __func__, nullptr);
296 4 : auto subGroup = hGroup->m_poImpl->OpenGroupFromFullname(
297 12 : std::string(pszFullname), papszOptions);
298 4 : if (!subGroup)
299 2 : return nullptr;
300 2 : return new GDALGroupHS(subGroup);
301 : }
302 :
303 : /************************************************************************/
304 : /* GDALGroupGetDimensions() */
305 : /************************************************************************/
306 :
307 : /** Return the list of dimensions contained in this group and used by its
308 : * arrays.
309 : *
310 : * The returned array must be freed with GDALReleaseDimensions(). If only the
311 : * array itself needs to be freed, CPLFree() should be called (and
312 : * GDALDimensionRelease() on individual array members).
313 : *
314 : * This is the same as the C++ method GDALGroup::GetDimensions().
315 : *
316 : * @param hGroup Group.
317 : * @param pnCount Pointer to the number of values returned. Must NOT be NULL.
318 : * @param papszOptions Driver specific options determining how dimensions
319 : * should be retrieved. Pass nullptr for default behavior.
320 : *
321 : * @return an array of *pnCount dimensions.
322 : */
323 73 : GDALDimensionH *GDALGroupGetDimensions(GDALGroupH hGroup, size_t *pnCount,
324 : CSLConstList papszOptions)
325 : {
326 73 : VALIDATE_POINTER1(hGroup, __func__, nullptr);
327 73 : VALIDATE_POINTER1(pnCount, __func__, nullptr);
328 73 : auto dims = hGroup->m_poImpl->GetDimensions(papszOptions);
329 : auto ret = static_cast<GDALDimensionH *>(
330 73 : CPLMalloc(sizeof(GDALDimensionH) * dims.size()));
331 230 : for (size_t i = 0; i < dims.size(); i++)
332 : {
333 157 : ret[i] = new GDALDimensionHS(dims[i]);
334 : }
335 73 : *pnCount = dims.size();
336 73 : return ret;
337 : }
338 :
339 : /************************************************************************/
340 : /* GDALGroupGetAttribute() */
341 : /************************************************************************/
342 :
343 : /** Return an attribute by its name.
344 : *
345 : * This is the same as the C++ method GDALIHasAttribute::GetAttribute()
346 : *
347 : * The returned attribute must be freed with GDALAttributeRelease().
348 : */
349 143 : GDALAttributeH GDALGroupGetAttribute(GDALGroupH hGroup, const char *pszName)
350 : {
351 143 : VALIDATE_POINTER1(hGroup, __func__, nullptr);
352 143 : VALIDATE_POINTER1(pszName, __func__, nullptr);
353 429 : auto attr = hGroup->m_poImpl->GetAttribute(std::string(pszName));
354 143 : if (attr)
355 138 : return new GDALAttributeHS(attr);
356 5 : return nullptr;
357 : }
358 :
359 : /************************************************************************/
360 : /* GDALGroupGetAttributes() */
361 : /************************************************************************/
362 :
363 : /** Return the list of attributes contained in this group.
364 : *
365 : * The returned array must be freed with GDALReleaseAttributes(). If only the
366 : * array itself needs to be freed, CPLFree() should be called (and
367 : * GDALAttributeRelease() on individual array members).
368 : *
369 : * This is the same as the C++ method GDALGroup::GetAttributes().
370 : *
371 : * @param hGroup Group.
372 : * @param pnCount Pointer to the number of values returned. Must NOT be NULL.
373 : * @param papszOptions Driver specific options determining how attributes
374 : * should be retrieved. Pass nullptr for default behavior.
375 : *
376 : * @return an array of *pnCount attributes.
377 : */
378 74 : GDALAttributeH *GDALGroupGetAttributes(GDALGroupH hGroup, size_t *pnCount,
379 : CSLConstList papszOptions)
380 : {
381 74 : VALIDATE_POINTER1(hGroup, __func__, nullptr);
382 74 : VALIDATE_POINTER1(pnCount, __func__, nullptr);
383 74 : auto attrs = hGroup->m_poImpl->GetAttributes(papszOptions);
384 : auto ret = static_cast<GDALAttributeH *>(
385 74 : CPLMalloc(sizeof(GDALAttributeH) * attrs.size()));
386 256 : for (size_t i = 0; i < attrs.size(); i++)
387 : {
388 182 : ret[i] = new GDALAttributeHS(attrs[i]);
389 : }
390 74 : *pnCount = attrs.size();
391 74 : return ret;
392 : }
393 :
394 : /************************************************************************/
395 : /* GDALGroupGetStructuralInfo() */
396 : /************************************************************************/
397 :
398 : /** Return structural information on the group.
399 : *
400 : * This may be the compression, etc..
401 : *
402 : * The return value should not be freed and is valid until GDALGroup is
403 : * released or this function called again.
404 : *
405 : * This is the same as the C++ method GDALGroup::GetStructuralInfo().
406 : */
407 4 : CSLConstList GDALGroupGetStructuralInfo(GDALGroupH hGroup)
408 : {
409 4 : VALIDATE_POINTER1(hGroup, __func__, nullptr);
410 4 : return hGroup->m_poImpl->GetStructuralInfo();
411 : }
412 :
413 : /************************************************************************/
414 : /* GDALGroupGetDataTypeCount() */
415 : /************************************************************************/
416 :
417 : /** Return the number of data types associated with the group
418 : * (typically enumerations).
419 : *
420 : * This is the same as the C++ method GDALGroup::GetDataTypes().size().
421 : *
422 : * @since 3.12
423 : */
424 4 : size_t GDALGroupGetDataTypeCount(GDALGroupH hGroup)
425 : {
426 4 : VALIDATE_POINTER1(hGroup, __func__, 0);
427 4 : return hGroup->m_poImpl->GetDataTypes().size();
428 : }
429 :
430 : /************************************************************************/
431 : /* GDALGroupGetDataType() */
432 : /************************************************************************/
433 :
434 : /** Return one of the data types associated with the group.
435 : *
436 : * This is the same as the C++ method GDALGroup::GetDataTypes()[].
437 : *
438 : * @return a type to release with GDALExtendedDataTypeRelease() once done,
439 : * or nullptr in case of error.
440 : * @since 3.12
441 : */
442 1 : GDALExtendedDataTypeH GDALGroupGetDataType(GDALGroupH hGroup, size_t nIdx)
443 : {
444 1 : VALIDATE_POINTER1(hGroup, __func__, nullptr);
445 1 : if (nIdx >= hGroup->m_poImpl->GetDataTypes().size())
446 0 : return nullptr;
447 1 : return new GDALExtendedDataTypeHS(new GDALExtendedDataType(
448 1 : *(hGroup->m_poImpl->GetDataTypes()[nIdx].get())));
449 : }
450 :
451 : /************************************************************************/
452 : /* GDALGroupCreateGroup() */
453 : /************************************************************************/
454 :
455 : /** Create a sub-group within a group.
456 : *
457 : * This is the same as the C++ method GDALGroup::CreateGroup().
458 : *
459 : * @return the sub-group, to be freed with GDALGroupRelease(), or nullptr.
460 : */
461 185 : GDALGroupH GDALGroupCreateGroup(GDALGroupH hGroup, const char *pszSubGroupName,
462 : CSLConstList papszOptions)
463 : {
464 185 : VALIDATE_POINTER1(hGroup, __func__, nullptr);
465 185 : VALIDATE_POINTER1(pszSubGroupName, __func__, nullptr);
466 555 : auto ret = hGroup->m_poImpl->CreateGroup(std::string(pszSubGroupName),
467 555 : papszOptions);
468 185 : if (!ret)
469 52 : return nullptr;
470 133 : return new GDALGroupHS(ret);
471 : }
472 :
473 : /************************************************************************/
474 : /* GDALGroupDeleteGroup() */
475 : /************************************************************************/
476 :
477 : /** Delete a sub-group from a group.
478 : *
479 : * After this call, if a previously obtained instance of the deleted object
480 : * is still alive, no method other than for freeing it should be invoked.
481 : *
482 : * This is the same as the C++ method GDALGroup::DeleteGroup().
483 : *
484 : * @return true in case of success.
485 : * @since GDAL 3.8
486 : */
487 20 : bool GDALGroupDeleteGroup(GDALGroupH hGroup, const char *pszSubGroupName,
488 : CSLConstList papszOptions)
489 : {
490 20 : VALIDATE_POINTER1(hGroup, __func__, false);
491 20 : VALIDATE_POINTER1(pszSubGroupName, __func__, false);
492 40 : return hGroup->m_poImpl->DeleteGroup(std::string(pszSubGroupName),
493 20 : papszOptions);
494 : }
495 :
496 : /************************************************************************/
497 : /* GDALGroupCreateDimension() */
498 : /************************************************************************/
499 :
500 : /** Create a dimension within a group.
501 : *
502 : * This is the same as the C++ method GDALGroup::CreateDimension().
503 : *
504 : * @return the dimension, to be freed with GDALDimensionRelease(), or nullptr.
505 : */
506 840 : GDALDimensionH GDALGroupCreateDimension(GDALGroupH hGroup, const char *pszName,
507 : const char *pszType,
508 : const char *pszDirection, GUInt64 nSize,
509 : CSLConstList papszOptions)
510 : {
511 840 : VALIDATE_POINTER1(hGroup, __func__, nullptr);
512 840 : VALIDATE_POINTER1(pszName, __func__, nullptr);
513 840 : auto ret = hGroup->m_poImpl->CreateDimension(
514 1680 : std::string(pszName), std::string(pszType ? pszType : ""),
515 3360 : std::string(pszDirection ? pszDirection : ""), nSize, papszOptions);
516 840 : if (!ret)
517 9 : return nullptr;
518 831 : return new GDALDimensionHS(ret);
519 : }
520 :
521 : /************************************************************************/
522 : /* GDALGroupCreateMDArray() */
523 : /************************************************************************/
524 :
525 : /** Create a multidimensional array within a group.
526 : *
527 : * This is the same as the C++ method GDALGroup::CreateMDArray().
528 : *
529 : * @return the array, to be freed with GDALMDArrayRelease(), or nullptr.
530 : */
531 755 : GDALMDArrayH GDALGroupCreateMDArray(GDALGroupH hGroup, const char *pszName,
532 : size_t nDimensions,
533 : GDALDimensionH *pahDimensions,
534 : GDALExtendedDataTypeH hEDT,
535 : CSLConstList papszOptions)
536 : {
537 755 : VALIDATE_POINTER1(hGroup, __func__, nullptr);
538 755 : VALIDATE_POINTER1(pszName, __func__, nullptr);
539 755 : VALIDATE_POINTER1(hEDT, __func__, nullptr);
540 1510 : std::vector<std::shared_ptr<GDALDimension>> dims;
541 755 : dims.reserve(nDimensions);
542 1818 : for (size_t i = 0; i < nDimensions; i++)
543 1063 : dims.push_back(pahDimensions[i]->m_poImpl);
544 2265 : auto ret = hGroup->m_poImpl->CreateMDArray(std::string(pszName), dims,
545 2265 : *(hEDT->m_poImpl), papszOptions);
546 755 : if (!ret)
547 64 : return nullptr;
548 691 : return new GDALMDArrayHS(ret);
549 : }
550 :
551 : /************************************************************************/
552 : /* GDALGroupDeleteMDArray() */
553 : /************************************************************************/
554 :
555 : /** Delete an array from a group.
556 : *
557 : * After this call, if a previously obtained instance of the deleted object
558 : * is still alive, no method other than for freeing it should be invoked.
559 : *
560 : * This is the same as the C++ method GDALGroup::DeleteMDArray().
561 : *
562 : * @return true in case of success.
563 : * @since GDAL 3.8
564 : */
565 20 : bool GDALGroupDeleteMDArray(GDALGroupH hGroup, const char *pszName,
566 : CSLConstList papszOptions)
567 : {
568 20 : VALIDATE_POINTER1(hGroup, __func__, false);
569 20 : VALIDATE_POINTER1(pszName, __func__, false);
570 20 : return hGroup->m_poImpl->DeleteMDArray(std::string(pszName), papszOptions);
571 : }
572 :
573 : /************************************************************************/
574 : /* GDALGroupCreateAttribute() */
575 : /************************************************************************/
576 :
577 : /** Create a attribute within a group.
578 : *
579 : * This is the same as the C++ method GDALGroup::CreateAttribute().
580 : *
581 : * @return the attribute, to be freed with GDALAttributeRelease(), or nullptr.
582 : */
583 142 : GDALAttributeH GDALGroupCreateAttribute(GDALGroupH hGroup, const char *pszName,
584 : size_t nDimensions,
585 : const GUInt64 *panDimensions,
586 : GDALExtendedDataTypeH hEDT,
587 : CSLConstList papszOptions)
588 : {
589 142 : VALIDATE_POINTER1(hGroup, __func__, nullptr);
590 142 : VALIDATE_POINTER1(hEDT, __func__, nullptr);
591 284 : std::vector<GUInt64> dims;
592 142 : dims.reserve(nDimensions);
593 200 : for (size_t i = 0; i < nDimensions; i++)
594 58 : dims.push_back(panDimensions[i]);
595 142 : auto ret = hGroup->m_poImpl->CreateAttribute(
596 426 : std::string(pszName), dims, *(hEDT->m_poImpl), papszOptions);
597 142 : if (!ret)
598 18 : return nullptr;
599 124 : return new GDALAttributeHS(ret);
600 : }
601 :
602 : /************************************************************************/
603 : /* GDALGroupDeleteAttribute() */
604 : /************************************************************************/
605 :
606 : /** Delete an attribute from a group.
607 : *
608 : * After this call, if a previously obtained instance of the deleted object
609 : * is still alive, no method other than for freeing it should be invoked.
610 : *
611 : * This is the same as the C++ method GDALGroup::DeleteAttribute().
612 : *
613 : * @return true in case of success.
614 : * @since GDAL 3.8
615 : */
616 25 : bool GDALGroupDeleteAttribute(GDALGroupH hGroup, const char *pszName,
617 : CSLConstList papszOptions)
618 : {
619 25 : VALIDATE_POINTER1(hGroup, __func__, false);
620 25 : VALIDATE_POINTER1(pszName, __func__, false);
621 50 : return hGroup->m_poImpl->DeleteAttribute(std::string(pszName),
622 25 : papszOptions);
623 : }
624 :
625 : /************************************************************************/
626 : /* GDALGroupRename() */
627 : /************************************************************************/
628 :
629 : /** Rename the group.
630 : *
631 : * This is not implemented by all drivers.
632 : *
633 : * Drivers known to implement it: MEM, netCDF.
634 : *
635 : * This is the same as the C++ method GDALGroup::Rename()
636 : *
637 : * @return true in case of success
638 : * @since GDAL 3.8
639 : */
640 45 : bool GDALGroupRename(GDALGroupH hGroup, const char *pszNewName)
641 : {
642 45 : VALIDATE_POINTER1(hGroup, __func__, false);
643 45 : VALIDATE_POINTER1(pszNewName, __func__, false);
644 45 : return hGroup->m_poImpl->Rename(pszNewName);
645 : }
646 :
647 : /************************************************************************/
648 : /* GDALGroupSubsetDimensionFromSelection() */
649 : /************************************************************************/
650 :
651 : /** Return a virtual group whose one dimension has been subset according to a
652 : * selection.
653 : *
654 : * This is the same as the C++ method GDALGroup::SubsetDimensionFromSelection().
655 : *
656 : * @return a virtual group, to be freed with GDALGroupRelease(), or nullptr.
657 : */
658 : GDALGroupH
659 14 : GDALGroupSubsetDimensionFromSelection(GDALGroupH hGroup,
660 : const char *pszSelection,
661 : CPL_UNUSED CSLConstList papszOptions)
662 : {
663 14 : VALIDATE_POINTER1(hGroup, __func__, nullptr);
664 14 : VALIDATE_POINTER1(pszSelection, __func__, nullptr);
665 14 : auto hNewGroup = hGroup->m_poImpl->SubsetDimensionFromSelection(
666 42 : std::string(pszSelection));
667 14 : if (!hNewGroup)
668 8 : return nullptr;
669 6 : return new GDALGroupHS(hNewGroup);
670 : }
|