Skip to content

Commit bd19b4c

Browse files
committed
read composite type data into a data.frame
r-spatial/stars#659
1 parent 1f1bdc6 commit bd19b4c

File tree

1 file changed

+39
-24
lines changed

1 file changed

+39
-24
lines changed

src/mdim.cpp

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -305,19 +305,18 @@ List CPL_read_mdim(CharacterVector file, CharacterVector array_names, CharacterV
305305
auto arr(get_array(curGroup, name));
306306
dims.attr("names") = dim_names;
307307
dimensions.attr("names") = dim_names;
308-
NumericVector vec;
309308
if (! proxy) { // read the arrays:
310309
auto data_type(arr->GetDataType());
311310
if (data_type.GetClass() == GEDTC_NUMERIC) {
312-
NumericVector vec_(nValues);
311+
NumericVector vec(nValues);
313312
if (debug)
314-
Rcout << "size of vec_: " << vec_.size() << "\n";
313+
Rcout << "size of vec: " << vec.size() << "\n";
315314
bool ok = arr->Read(offst.data(),
316315
anCount.data(),
317316
stp.data(), /* step: defaults to 1,1,1 */
318317
nullptr, /* stride: default to row-major convention */
319318
GDALExtendedDataType::Create(GDT_Float64),
320-
vec_.begin());
319+
vec.begin());
321320
if (!ok)
322321
stop("Cannot read array into a Float64 buffer");
323322
bool has_offset = false;
@@ -331,35 +330,51 @@ List CPL_read_mdim(CharacterVector file, CharacterVector array_names, CharacterV
331330
bool has_nodata = false;
332331
double nodata_value = arr->GetNoDataValueAsDouble(&has_nodata);
333332
if (has_offset || has_scale || has_nodata) {
334-
for (size_t i = 0; i < nValues; i++) {
335-
if (ISNAN(vec_[i]) || (has_nodata && vec_[i] == nodata_value))
336-
vec_[i] = NA_REAL;
333+
for (size_t j = 0; j < nValues; j++) {
334+
if (ISNAN(vec[j]) || (has_nodata && vec[j] == nodata_value))
335+
vec[j] = NA_REAL;
337336
else
338-
vec_[i] = vec_[i] * scale + offst;
337+
vec[j] = vec[j] * scale + offst;
339338
}
340339
}
341-
vec_.attr("dim") = dims;
342-
vec_.attr("units") = arr->GetUnit();
343-
vec = vec_;
340+
vec.attr("dim") = dims;
341+
vec.attr("units") = arr->GetUnit();
342+
vec_lst[i] = vec;
344343
} else if (data_type.GetClass() == GEDTC_COMPOUND) {
345-
std::vector<std::unique_ptr<GDALEDTComponent>> components;
346-
components = data_type.GetComponents();
347-
for (size_t i = 0; i < components.size(); i++) {
348-
auto t(components[i]->GetType());
349-
if (t.GetClass() == GEDTC_NUMERIC)
350-
Rcout << "numeric ";
351-
else if (t.GetClass() == GEDTC_STRING)
352-
Rcout << "string ";
353-
else
354-
Rcout << "other ";
355-
Rcout << std::endl;
344+
const auto &components = data_type.GetComponents();
345+
size_t sz = data_type.GetSize();
346+
std::vector<GByte> buf(sz * nValues);
347+
bool ok = arr->Read(offst.data(),
348+
anCount.data(),
349+
stp.data(), /* step: defaults to 1,1,1 */
350+
nullptr, /* stride: default to row-major convention */
351+
data_type,
352+
&buf[0]);
353+
DataFrame tbl;
354+
GByte *v = buf.data();
355+
for (const auto &co: components) {
356+
auto t(co->GetType());
357+
if (t.GetClass() == GEDTC_NUMERIC) {
358+
NumericVector vec(nValues);
359+
for (int j = 0; j < nValues; j++)
360+
memcpy(&(vec[j]), v + j * sz + co->GetOffset(), sizeof(double));
361+
tbl.push_back(vec, co->GetName());
362+
} else if (t.GetClass() == GEDTC_STRING) {
363+
CharacterVector vec(nValues);
364+
const char *str;
365+
for (int j = 0; j < nValues; j++) {
366+
memcpy(&str, v + j * sz + co->GetOffset(), sizeof(const char *));
367+
vec[j] = str; // deep copy
368+
}
369+
tbl.push_back(vec, co->GetName());
370+
} else
371+
stop("unsupported type");
356372
}
357-
stop("reading compound data not implemented");
373+
vec_lst[i] = tbl;
358374
} else { // GEDTC_STRING:
359375
stop("reading string data not implemented");
360376
}
361377
}
362-
vec_lst[i] = vec;
363378
}
364379
vec_lst.attr("names") = a_names;
365380
std::shared_ptr<OGRSpatialReference> srs = array->GetSpatialRef();

0 commit comments

Comments
 (0)