<div dir="ltr">Found what I was looking for in the current PDAL python bindings source code.<div><br></div><div><br></div><div><br></div><div>Pipeline array -> pandas DataFrame:<br></div><div><br></div><div>Adapted from <a href="https://github.com/PDAL/python/blob/main/src/pdal/pipeline.py#L48">https://github.com/PDAL/python/blob/main/src/pdal/pipeline.py#L48</a></div><div><br></div><div><font face="monospace">pipeline = ...</font></div><div><font face="monospace"><br></font></div><div><font face="monospace">_ = pipeline.execute()</font></div><div><font face="monospace"><br></font></div><div><font face="monospace">idx = 0<br></font></div><div><font face="monospace"><br></font></div><div><font face="monospace">arr = pipeline.arrays[idx]</font></div><div><font face="monospace"><br></font></div><div><font face="monospace">df = pd.DataFrame(arr)</font></div><div><br></div><div><br></div><div><br></div><div>Pandas DataFrame / Geopandas GeoDataFrame -> pipeline:<br></div><div><br></div><div><font face="monospace">gdf = ...</font></div><div><font face="monospace"><br></font></div><div><font face="monospace">df = gdf.drop(columns=["geometry"])</font></div><div><font face="monospace"><br></font></div><div><font face="monospace">arr = df.to_records()<br></font></div><div><font face="monospace"><br></font></div><div><font face="monospace">pipeline = pdal.pipeline.Pipeline(arr)</font></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, 27 Jun 2024 at 09:29, James Ford <<a href="mailto:irvine.ford@gmail.com">irvine.ford@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Hello,<div><br></div><div>I am using the PDAL python bindings to read point clouds into geopandas GeoDataFrames and then write them back to disc.</div><div><br></div><div>The approach I have works, but is slow. Is there a faster way of doing this?</div><div><br></div><div>The slowest part is converting from a GeoDataFrame back to a structured numpy array.</div><div><br></div><div>Code below.</div><div><br></div><div>Thanks,</div><div><br></div><div>James</div><div><br></div><div><font face="monospace">import pdal<br>import numpy as np<br>import pandas as pd<br>import geopandas as gpd<br><br>input_point_cloud_filepath = "..."<br><br>output_point_cloud_filepath = "..."<br><br>crs = "..."<br><br>#################### Read PC into Memory and convert to GeoDataFrame ####################<br><br>pipeline_stages = [<br>    pdal.Reader.copc(input_point_cloud_filepath),<br>    pdal.Filter.hag_nn()<br>]<br><br>pipeline = pdal.Pipeline(pipeline_stages)<br><br>_ = pipeline.execute()<br><br>pointcloud_dtype = pipeline.arrays[0].dtype<br><br>pointcloud_df = pipeline.get_dataframe(0)<br><br>pointcloud_gdf = gpd.GeoDataFrame(<br>    pointcloud_df,<br>    geometry=gpd.points_from_xy(pointcloud_df["X"], pointcloud_df["Y"], pointcloud_df["Z"]),<br>    crs=</font>

<span style="font-family:monospace">crs</span> <font face="monospace">,<br>)<br><br>_ = pointcloud_gdf.sindex<br><br>########################## Manipulate PC via geopandas & numpy ##########################<br><br># Do stuff here<br><br><br>########################### GeoDataFrame -> numpy -> pipeline ###########################<br><br>pointcloud_arr = np.array(<br>    (<br>        pointcloud_gdf<br>        .drop(columns=["geometry"])<br>        .apply(tuple, axis=1)<br>    ),<br>    dtype=pointcloud_dtype<br>)<br><br>output_pipeline = pdal.Filter.stats().pipeline(pointcloud_arr)<br><br>output_pipeline |= pdal.Writer.copc(<br>    output_point_cloud_filepath,<br>    forward="all",<br>    a_srs=crs,<br>)<br><br>_ = output_pipeline.execute()</font><br><br></div></div>
</blockquote></div>