Skip to content

Commit 2c1ff3c

Browse files
committed
Merge buildNumpyDescription function and PythonPointTable::py_buildNumpyDescriptor
1 parent f0a7b65 commit 2c1ff3c

File tree

4 files changed

+36
-80
lines changed

4 files changed

+36
-80
lines changed

pdal/PyPipeline.cpp

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ void addArrayReaders(PipelineExecutor* executor, std::vector<std::shared_ptr<Arr
105105
}
106106

107107

108-
inline PyObject* buildNumpyDescription(PointViewPtr view)
108+
PyObject* buildNumpyDescriptor(PointLayoutPtr layout)
109109
{
110110
// Build up a numpy dtype dictionary
111111
//
@@ -116,31 +116,42 @@ inline PyObject* buildNumpyDescription(PointViewPtr view)
116116
// 'Classification', 'ScanAngleRank', 'UserData',
117117
// 'PointSourceId', 'GpsTime', 'Red', 'Green', 'Blue']}
118118
//
119-
Dimension::IdList dims = view->dims();
119+
120+
// Ensure that the dimensions are sorted by offset
121+
// Is there a better way? Can they be sorted by offset already?
122+
auto sortByOffset = [layout](Dimension::Id id1, Dimension::Id id2) -> bool
123+
{
124+
return layout->dimOffset(id1) < layout->dimOffset(id2);
125+
};
126+
auto dims = layout->dims();
127+
std::sort(dims.begin(), dims.end(), sortByOffset);
128+
120129
PyObject* names = PyList_New(dims.size());
121130
PyObject* formats = PyList_New(dims.size());
122131
for (size_t i = 0; i < dims.size(); ++i)
123132
{
124133
Dimension::Id id = dims[i];
125-
std::string name = view->dimName(id);
126-
npy_intp stride = view->dimSize(id);
127-
128-
std::string kind;
129-
Dimension::BaseType b = Dimension::base(view->dimType(id));
130-
if (b == Dimension::BaseType::Unsigned)
131-
kind = "u";
132-
else if (b == Dimension::BaseType::Signed)
133-
kind = "i";
134-
else if (b == Dimension::BaseType::Floating)
135-
kind = "f";
136-
else
137-
throw pdal_error("Unable to map kind '" + kind +
138-
"' to PDAL dimension type");
139-
140-
std::stringstream oss;
141-
oss << kind << stride;
134+
auto name = layout->dimName(id);
142135
PyList_SetItem(names, i, PyUnicode_FromString(name.c_str()));
143-
PyList_SetItem(formats, i, PyUnicode_FromString(oss.str().c_str()));
136+
137+
std::stringstream format;
138+
switch (Dimension::base(layout->dimType(id)))
139+
{
140+
case Dimension::BaseType::Unsigned:
141+
format << 'u';
142+
break;
143+
case Dimension::BaseType::Signed:
144+
format << 'i';
145+
break;
146+
case Dimension::BaseType::Floating:
147+
format << 'f';
148+
break;
149+
default:
150+
throw pdal_error("Unable to map dimension '" + name + "' to Numpy");
151+
}
152+
format << layout->dimSize(id);
153+
PyList_SetItem(formats, i, PyUnicode_FromString(format.str().c_str()));
154+
144155
}
145156
PyObject* dtype_dict = PyDict_New();
146157
PyDict_SetItemString(dtype_dict, "names", names);
@@ -154,7 +165,7 @@ PyArrayObject* viewToNumpyArray(PointViewPtr view)
154165
if (_import_array() < 0)
155166
throw pdal_error("Could not import numpy.core.multiarray.");
156167

157-
PyObject* dtype_dict = buildNumpyDescription(view);
168+
PyObject* dtype_dict = buildNumpyDescriptor(view->layout());
158169
PyArray_Descr *dtype = nullptr;
159170
if (PyArray_DescrConverter(dtype_dict, &dtype) == NPY_FAIL)
160171
throw pdal_error("Unable to build numpy dtype");

pdal/PyPipeline.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ namespace python
4545

4646
class Array;
4747

48+
PyObject* buildNumpyDescriptor(PointLayoutPtr layout);
4849
void addArrayReaders(PipelineExecutor* executor, std::vector<std::shared_ptr<Array>> arrays);
4950
PyArrayObject* viewToNumpyArray(PointViewPtr view);
5051
PyArrayObject* meshToNumpyArray(const TriangularMesh* mesh);

pdal/StreamableExecutor.cpp

Lines changed: 3 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
* OF SUCH DAMAGE.
3333
****************************************************************************/
3434

35+
#include "PyPipeline.hpp"
3536
#include "StreamableExecutor.hpp"
3637

3738
#include <Python.h>
@@ -68,7 +69,7 @@ void PythonPointTable::finalize()
6869
auto gil = PyGILState_Ensure();
6970
if (_import_array() < 0)
7071
std::cerr << "Could not import array!\n";
71-
PyObject *dtype_dict = py_buildNumpyDescriptor();
72+
PyObject *dtype_dict = buildNumpyDescriptor(&m_layout);
7273
if (PyArray_DescrConverter(dtype_dict, &m_dtype) == NPY_FAIL)
7374
throw pdal_error("Unable to create numpy dtype");
7475
Py_XDECREF(dtype_dict);
@@ -110,62 +111,6 @@ void PythonPointTable::py_resizeArray(point_count_t np)
110111
PyGILState_Release(gil);
111112
}
112113

113-
PyObject *PythonPointTable::py_buildNumpyDescriptor() const
114-
{
115-
// Build up a numpy dtype dictionary
116-
//
117-
// {'formats': ['f8', 'f8', 'f8', 'u2', 'u1', 'u1', 'u1', 'u1', 'u1',
118-
// 'f4', 'u1', 'u2', 'f8', 'u2', 'u2', 'u2'],
119-
// 'names': ['X', 'Y', 'Z', 'Intensity', 'ReturnNumber',
120-
// 'NumberOfReturns', 'ScanDirectionFlag', 'EdgeOfFlightLine',
121-
// 'Classification', 'ScanAngleRank', 'UserData',
122-
// 'PointSourceId', 'GpsTime', 'Red', 'Green', 'Blue']}
123-
//
124-
125-
auto dims = m_layout.dims();
126-
127-
// Need to sort the dimensions by offset
128-
// Is there a better way? Can they be sorted by offset already?
129-
auto sorter = [this](Dimension::Id id1, Dimension::Id id2) -> bool
130-
{
131-
return m_layout.dimOffset(id1) < m_layout.dimOffset(id2);
132-
};
133-
std::sort(dims.begin(), dims.end(), sorter);
134-
135-
PyObject* names = PyList_New(dims.size());
136-
PyObject* formats = PyList_New(dims.size());
137-
for (size_t i = 0; i < dims.size(); ++i)
138-
{
139-
auto id = dims[i];
140-
std::string kind;
141-
switch (Dimension::base(m_layout.dimType(id)))
142-
{
143-
case Dimension::BaseType::Unsigned:
144-
kind = 'u';
145-
break;
146-
case Dimension::BaseType::Signed:
147-
kind = 'i';
148-
break;
149-
case Dimension::BaseType::Floating:
150-
kind = 'f';
151-
break;
152-
default:
153-
throw pdal_error("Unable to map kind '" + kind + "' to PDAL dimension type");
154-
}
155-
156-
auto name = m_layout.dimName(id);
157-
PyList_SetItem(names, i, PyUnicode_FromString(name.c_str()));
158-
159-
auto format = kind + std::to_string(m_layout.dimSize(id));
160-
PyList_SetItem(formats, i, PyUnicode_FromString(format.c_str()));
161-
}
162-
163-
PyObject* dict = PyDict_New();
164-
PyDict_SetItemString(dict, "names", names);
165-
PyDict_SetItemString(dict, "formats", formats);
166-
return dict;
167-
}
168-
169114
void PythonPointTable::reset()
170115
{
171116
point_count_t np = 0;
@@ -231,7 +176,7 @@ char *PythonPointTable::getPoint(PointId idx)
231176
StreamableExecutor::StreamableExecutor(std::string const& json, point_count_t chunkSize, int prefetch) :
232177
PipelineExecutor(json), m_table(chunkSize, prefetch)
233178
{}
234-
179+
235180
StreamableExecutor::~StreamableExecutor()
236181
{
237182
//ABELL - Hmmm.

pdal/StreamableExecutor.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ class PythonPointTable : public StreamPointTable
7070
// All functions starting with py_ call Python things that need the GIL locked.
7171
void py_createArray();
7272
void py_resizeArray(point_count_t np);
73-
PyObject *py_buildNumpyDescriptor() const;
7473

7574
int m_prefetch;
7675
PointLayout m_layout;

0 commit comments

Comments
 (0)