<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Bradley,<br class=""><div><br class=""></div><div>Thanks for your example pipeline. Running it here with pdal 2.2.0, it prints “Parser error = !” when sent a pipeline with these statements. I’ve tracked the error messages to the blocks with "Classification = 6 WHERE …” and "Classification = 4 WHERE  …”.</div><div><br class=""></div><div>These blocks look valid based one the filters.assign description: <a href="https://pdal.io/stages/filters.assign.html" class="">https://pdal.io/stages/filters.assign.html</a></div><div><br class=""></div><div>For generating the surface height raster, I’d think to write the point with the highest Z value for the raster pixel. For surface type, perhaps label the raster pixel with the most common point classification. I’ll post a first cut.</div><div><br class=""></div><div>Cheers,</div><div><br class=""></div><div>Andreas</div><div><br class=""></div><div><br class=""><blockquote type="cite" class=""><div class="">On Apr 28, 2021, at 11:44, Bradley Chambers <<a href="mailto:brad.chambers@gmail.com" class="">brad.chambers@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div dir="ltr" class="">On Wed, Apr 28, 2021 at 9:34 AM Howard Butler <<a href="mailto:howard@hobu.co" target="_blank" class="">howard@hobu.co</a>> wrote:<br class=""></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br class="">
> On Apr 27, 2021, at 4:11 PM, Andreas Yankopolus <<a href="mailto:andreas@yank.to" target="_blank" class="">andreas@yank.to</a>> wrote:<br class=""><br class="">
> Is there previous work in these areas that I can build on with PDAL? I’m also looking at LAStools, which appears to have binaries that could be replicated with PDAL pipelines.<br class="">
<br class="">
I like to say that "PDAL is something you can use to build LAStools" about its scope in relation to that product. PDAL isn't pre-canned workflows for attacking a few kinds of LiDAR processing challenges. It's a bunch of building blocks for processing point cloud data in the context of ETL pipelines. <br class="">
<br class="">
That said, once constructed, those workflows can be quite valuable. Fancy classification pipelines haven't typically been shared freely, however.</blockquote><div class=""><br class=""></div><div class="">Your mileage will certainly vary, but one pipeline that was derived from this notebook (<a href="https://github.com/rockestate/point-cloud-processing/blob/master/notebooks/point-cloud-processing.ipynb" target="_blank" class="">https://github.com/rockestate/point-cloud-processing/blob/master/notebooks/point-cloud-processing.ipynb</a>) is shared below. It classifies noise, ground, vegetation, and building returns. In my experience, it does a reasonable job but can still require fine tuning of the parameters.</div><div class=""><br class=""></div><div class="">[<br class="">    {<br class="">        "type": "filters.assign",<br class="">        "assignment": "Classification[:]=0"<br class="">    },<br class="">    {<br class="">        "type": "filters.elm"<br class="">    },<br class="">    {<br class="">        "type": "filters.smrf",<br class="">        "where": "Classification != 7"<br class="">    },<br class="">    {<br class="">        "type": "filters.hag_delaunay"<br class="">    },<br class="">    {<br class="">        "type": "filters.outlier",<br class="">        "multiplier": 16,<br class="">        "class": 18,<br class="">        "where": "!(Classification==2 || Classification==7)"<br class="">    },<br class="">    {<br class="">        "type": "filters.approximatecoplanar",<br class="">        "where": "HeightAboveGround >= 2 && !(Classification==2 || Classification==7 || Classification==18)"<br class="">    },<br class="">    {<br class="">        "type": "filters.outlier",<br class="">        "class": 18,<br class="">        "where": "!(Classification==2 || Classification==7 || Classification==18) && Coplanar == 1"<br class="">    },<br class="">    {<br class="">        "type": "filters.assign",<br class="">        "value": "Classification=6 WHERE (Coplanar == 1 && !(Classification == 7 || Classification==18))"<br class="">    },<br class="">    {<br class="">        "type": "filters.covariancefeatures",<br class="">        "mode": "normalized",<br class="">        "feature_set": "Dimensionality",<br class="">        "knn": 45<br class="">    },<br class="">    {<br class="">        "type": "filters.assign",<br class="">        "value": "Classification=4 WHERE (!(Classification==2 || Classification==6) && HeightAboveGround >= 3.0 && Planarity < 0.8 && Scattering > 0.1 && Verticality > 0.1)"<br class="">    }<br class="">]<br class=""></div></div></div>
</div></blockquote></div><br class=""></body></html>