-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
point cloud to mesh grid cell averaging #15
Comments
The question is how to do this in a sufficiently performant way. The first thing I'll try is pdal's colorization filter which allows us to attribute from a gdal supported raster to any attribute in our point cloud: In this way, we can use grid ID's to attribute to the point cloud, and then use that attribution as our tie-in to extract statistics from the point cloud based on those IDs. |
Then we can use filter.stats to extract whichever statistic we are interested in using a where clause to isolate the grid cell in question. |
https://github.com/localdevices/ORProfile/blob/optimizer/orprofile%2Fapi%2Fdepth_sample.py does a similar resampling approach for the sonar samples. Perhaps components can be reused? |
A bit of progress. I've got stuff I might want to do differently, but keeping it simple and proof of concept first. As such, I'm just sub-sampling the dry bed point cloud first and writing to a csv, and then feeding that in. Once everything is working, I'll likely integrate this further as with PDAL's python API and/or skip writing of an intermediate file. But in the meantime, we have a json file to tell pdal what to do:
And can invoke that as so: Now we have a csv that we can pull in. @hcwinsemius -- can you show me how you generate the grid for Bamboi? I need to generate that directly to fully test (rather than a geojson) so that it has all the appropriate properties. Here's my attempt in importing: import geopandas as gpd
import pandas as pd
import numpy as np
import orprofile.api.mesh
import numpy as np
def regrid_dry(mesh, gdf, nodata=-9999, column="Depth"):
"""
regrid a set of depth samples to the provided mesh object
Parameters
----------
mesh : orprofile.Mesh
Returns
-------
"""
# get the index numbers of each mesh cell
da_index = mesh._get_index_da()
# get index number of each sample
points = da_index.ugrid.sel_points(
x=gdf.geometry.x,
y=gdf.geometry.y
)
face_index = np.ones(len(gdf), dtype=np.int64) * nodata # -9999 is the nodata value
face_index[points.mesh2d_index] = points.values
gdf["face_index"] = face_index
depth_mean = gdf[gdf["face_index"] != nodata][[column, "face_index"]].groupby("face_index").mean()
depth_grid = np.zeros(da_index.shape) * np.nan
depth_grid[depth_mean.index] = depth_mean[column]
ds = mesh._get_empty_ds()
ds["samples"] = ("mesh2d_nFaces", depth_grid)
return ds
df = pd.read_csv('filtered.csv')
gdf = gpd.GeoDataFrame(
df, geometry=gpd.points_from_xy(df.X, df.Y), crs="EPSG:32630"
)
print(gdf.head())
mesh = gpd.read_file("mesh_example_v2.geojson")
print(mesh.head())
regrid_dry(mesh, gdf) Which errors on out
|
Linking into original python documenting point cloud reading, though the below might be a bit more pythonistic: Existing averaging should work fine, so I checked off the above. Feel free to uncheck if my assumptions are wrong. Probably the simplest way to get a point cloud into a numpy array is as follows:
This has the added bonus of operating on controllable windowed subsets of the data. Access to the full dataset is also possible with something like the following: This is pretty minor changes to the documented API here on streamable pipelines: As before, the file can be local or remote. I have it pointed to crankyserver for this example, but a local file usually makes more sense. |
The following writes a geojson file from a sampled point cloud such that it can be parsed into the appropriate cells: import pdal
pipeline = pdal.Reader("https://crankyserver.com/api/projects/243/tasks/d6bb6fd8-902d-41fc-b969-87b6732a30ef/download/georeferenced_model.laz") | pdal.Filter.sample(radius="4")
print(pipeline.execute())
full_array = pipeline.arrays[0]
pipeline = pdal.Writer.text(
filename="filtered.geojson",
format="geojson",
order="X,Y,Z",
).pipeline(full_array)
print(pipeline.execute()) Although there is a bug in pdal which isn't writing valid json. It's missing comma delimiters between objects. |
Submitted the bug report upstream in PDAL: And a pull request now adds the dry bed data to tests: |
The text was updated successfully, but these errors were encountered: