# filters.hag

Warning

The HAG filter has been eliminated was replaced by filters.hag_nn, filters.hag_dem and filters.hag_delaunay. Please use the new filter that matches your needs as this filter will be removed in a future release.

The Height Above Ground (HAG) filter takes as input a point cloud with `Classification` set to 2 for ground points (see ASPRS Standard LIDAR Point Classes). It creates a new dimension, `HeightAboveGround`, that contains the normalized height values. Ground points may be generated by filters.pmf or filters.smrf, but you can use any method you choose, as long as the ground returns are marked with the classification value of 2.

Normalized heights are a commonly used attribute of point cloud data. This can also be referred to as height above ground (HAG) or above ground level (AGL) heights. In the end, it is simply a measure of a point’s relative height as opposed to its raw elevation value.

There are two modes of operation:

## Weighted Nearest Point

This default method finds the count ground points nearest the non-ground point under consideration. It calculates an average ground height weighted by the distance of each ground point from the non-ground point. The `HeightAboveGround` is the difference between the `Z` value of the non-ground point and the interpolated ground height.

## Triangulated Interpolation

Used when the delaunay option is set to true. It requires a count of at least 3.

The filter creates a delaunay triangulation of the count ground points closest to the non-ground point in question. If the non-ground point is within the triangulated area, the assigned `HeightAboveGround` is the difference between its `Z` value and a ground height interpolated from the three vertices of the containing triangle. If the non-ground point is outside of the triangulated area, its `HeightAboveGround` is calculated as the difference between its `Z` value and the `Z` value of the nearest ground point.

Choosing a value for count is difficult, as placing the non-ground point in the triangulated area depends on the layout of the nearby points. If, for example, all the ground points near a non-ground point lay on one side of that non-ground point, finding a containing triangle will fail.

Default Embedded Stage

This stage is enabled by default

## Example #1

Using the autzen dataset (here shown colored by elevation)

we execute the following pipeline

    [
        "autzen.laz",
        {
            "type":"filters.hag"
        },
        {
            "type":"writers.bpf",
            "filename":"autzen-height.bpf",
            "output_dims":"X,Y,Z,HeightAboveGround"
        }
    ]

which is equivalent to the `pdal translate` command

    $ pdal translate autzen.laz autzen-height.bpf hag \
        --writers.bpf.output_dims="X,Y,Z,HeightAboveGround"

In either case, the result, when colored by the normalized height instead of elevation is

## Example #2

In the previous example, we chose a writer that could output custom dimensions. If you’d instead like to overwrite your Z values, then follow the height filter with filters.ferry as shown

    [
        "autzen.laz",
        {
            "type":"filters.hag",
            "count": 10,
            "delaunay": true
        },
        {
            "type":"filters.ferry",
            "dimensions":"HeightAboveGround=>Z"
        },
        "autzen-height-as-Z.laz"
    ]

## Example #3

If you don’t yet have points classified as ground, start with filters.pmf or filters.smrf to label ground returns, as shown

    [
        "autzen.laz",
        {
            "type":"filters.smrf"
        },
        {
            "type":"filters.hag",
            "count":4
        },
        {
            "type":"filters.ferry",
            "dimensions":"HeightAboveGround=>Z"
        },
        "autzen-height-as-Z-smrf.laz"
    ]

which is equivalent to the command

    $ pdal translate autzen.laz autzen-height-as-Z-smrf.bpf smrf hag ferry \
        --filters.ferry.dimensions="HeightAboveGround=Z" \
        --filters.hag.count=4

## Options

count

  The number of ground neighbors to consider when determining the height above ground for a non-ground point. Must be at least 3 when using the delaunay option. [Default: 1]

delaunay

  If true, create a delaunay triangulation of neighboring ground points to aid in interpolation of a ground height to use as a difference to a point’s non-ground height. [Default: false]

max_distance

  Use only ground points within max_distance of non-ground point when performing neighbor interpolation. Not used with the delaunay option. [Default: None]

allow_extrapolation

  If false and a non-ground point lies outside of the bounding box of all ground points, its `HeightAboveGround` is set to 0. If true and `delaunay` is set, the `HeightAboveGround` is set to the difference between the heights of the non-ground point and nearest ground point. If true and using neighbor interpolation (`delaunay` is false), extrapolation is used to assign the `HeightAboveGround` value. [Default: false]