Skip to content

Commit a9c962b

Browse files
committed
Handle skips
1 parent 6c5271e commit a9c962b

File tree

2 files changed

+47
-25
lines changed

2 files changed

+47
-25
lines changed

pdal/StreamableExecutor.cpp

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,18 @@ void PythonPointTable::py_resizeArray(int np)
108108
PyArray_Dims dims{ sizes, 1 };
109109

110110
auto gil = PyGILState_Ensure();
111+
// copy the non-skipped elements to the beginning
112+
npy_intp dest_idx = 0;
113+
for (PointId src_idx = 0; src_idx < numPoints(); src_idx++)
114+
if (!skip(src_idx))
115+
{
116+
if (src_idx != dest_idx)
117+
{
118+
PyObject* src_item = PyArray_GETITEM(m_curArray, PyArray_GETPTR1(m_curArray, src_idx));
119+
PyArray_SETITEM(m_curArray, PyArray_GETPTR1(m_curArray, dest_idx), src_item);
120+
}
121+
dest_idx++;
122+
}
111123
PyArray_Resize(m_curArray, &dims, true, NPY_CORDER);
112124
PyGILState_Release(gil);
113125
}
@@ -124,30 +136,42 @@ PyObject *PythonPointTable::py_buildNumpyDescriptor() const
124136
// 'PointSourceId', 'GpsTime', 'Red', 'Green', 'Blue']}
125137
//
126138

127-
DimTypeList dims = layout()->dimTypes();
139+
auto dims = m_layout.dims();
140+
141+
// Need to sort the dimensions by offset
142+
// Is there a better way? Can they be sorted by offset already?
143+
auto sorter = [this](Dimension::Id id1, Dimension::Id id2) -> bool
144+
{
145+
return m_layout.dimOffset(id1) < m_layout.dimOffset(id2);
146+
};
147+
std::sort(dims.begin(), dims.end(), sorter);
148+
128149
PyObject* names = PyList_New(dims.size());
129150
PyObject* formats = PyList_New(dims.size());
130151
for (size_t i = 0; i < dims.size(); ++i)
131152
{
132-
DimType& dt = dims[i];
133-
std::string name = m_layout.dimName(dt.m_id);
134-
npy_intp stride = Dimension::size(dt.m_type);
135-
153+
auto id = dims[i];
136154
std::string kind;
137-
Dimension::BaseType b = Dimension::base(dt.m_type);
138-
if (b == Dimension::BaseType::Unsigned)
139-
kind = "u";
140-
else if (b == Dimension::BaseType::Signed)
141-
kind = "i";
142-
else if (b == Dimension::BaseType::Floating)
143-
kind = "f";
144-
else
145-
throw pdal_error("Unable to map kind '" + kind +
146-
"' to PDAL dimension type");
147-
148-
std::string type = kind + std::to_string(stride);
155+
switch (Dimension::base(m_layout.dimType(id)))
156+
{
157+
case Dimension::BaseType::Unsigned:
158+
kind = 'u';
159+
break;
160+
case Dimension::BaseType::Signed:
161+
kind = 'i';
162+
break;
163+
case Dimension::BaseType::Floating:
164+
kind = 'f';
165+
break;
166+
default:
167+
throw pdal_error("Unable to map kind '" + kind + "' to PDAL dimension type");
168+
}
169+
170+
auto name = m_layout.dimName(id);
149171
PyList_SetItem(names, i, PyUnicode_FromString(name.c_str()));
150-
PyList_SetItem(formats, i, PyUnicode_FromString(type.c_str()));
172+
173+
auto format = kind + std::to_string(m_layout.dimSize(id));
174+
PyList_SetItem(formats, i, PyUnicode_FromString(format.c_str()));
151175
}
152176

153177
PyObject* dict = PyDict_New();
@@ -158,12 +182,11 @@ PyObject *PythonPointTable::py_buildNumpyDescriptor() const
158182

159183
void PythonPointTable::reset()
160184
{
161-
point_count_t np = numPoints();
185+
point_count_t np = 0;
186+
for (PointId idx = 0; idx < numPoints(); idx++)
187+
if (!skip(idx))
188+
np++;
162189

163-
// If this is the last chunk, the size might be less than what's expected, so
164-
// resize the array to match its true size.
165-
// ABELL - This isn't quite right. We want to know if there are any skips and deal with those
166-
// but I'm leaving that for the moment.
167190
if (np && np != m_limit)
168191
py_resizeArray(np);
169192

@@ -179,7 +202,7 @@ void PythonPointTable::reset()
179202
m_curArray = nullptr;
180203
}
181204

182-
bool done = np < m_limit;
205+
bool done = numPoints() < m_limit;
183206

184207
// If we just pushed the last chunk, push a nullptr so that a reader knows.
185208
if (done)

test/test_pipeline.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,6 @@ def test_meshio(self, filename):
419419

420420
class TestPipelineIterator:
421421

422-
@pytest.mark.xfail
423422
def test_array(self):
424423
"""Can we fetch PDAL data as numpy arrays"""
425424
ri = get_pipeline("range.json", chunk_size=100)

0 commit comments

Comments
 (0)