@@ -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
159183void 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)
0 commit comments