You can use formulas to create a variety of volumes around objects to analyse Point Cloud. These are commonly used to detect encroaching vegetation, or measure the distance to other classified objects, such as buildings.
You can use our example project to explore the volume and selection features directly in Neara.
Download and import the file attached at the bottom of this article to follow along.
Approach:
Create a volume around an object (e.g. a pole, or span)
Get/select the points within the volume
Label, visualize, colorize, and perform additional operations on the selected points
There are some special cases where you can get the points without needing a volume first
Creating volumes
Volumes are bounds in space, relative to an object β usually a span or pole.
A common reason to create an independent volume is that it can be easily visualised by turning on the eye in the column header of the field containing the volume. This is simpler than working solely with point selections that cannot be visualised unless there are relevant points in your test area.
There are a number of volumetric shapes you can create.
make_rectangular_volume
make_rectangular_volume(cables, width, height, start, end, [sample_multiplier])
Creates a rectangular clearance volume.
width
andheight
are the horizontal and vertical offsets to pad the sides of the volume from the cablesstart
andend
are within the interval [0..1] and determines what range of the span to cover
Example: On a span, make_rectangular_volume(Environments[].Cables, 5m, 2m, 0, 1)
make_clear_to_sky_volume
make_clear_to_sky_volume(catenaries, offset, height, [sample_multiplier])
Finds the clear to sky volume of a list of catenaries and space the left and right planes by a further offset away, and with the ceiling a given height above the sample points.
Example on a span: make_clear_to_sky_volume(Environments[].Cables, 5m, 10m)
make_canopy_volume
make_canopy_volume(cables, width, height, start, end, distance, [sample_multiplier])
Creates a rectangular clearance volume for the canopy region
hOff
is the horizontal offset to shift the sides of the volume away from the cablesvOff
is the vertical offset to shift the top of the volume down from the cablesstart
andend
are within the interval[0..1]
and determines what range of the span to coverdistance
is the minimum vertical distance that the canopy will cover
Example: On a span, make_canopy_volume(Environments[].Cables, 5m, 0m, 0, 1, 0m)
make_fall_in_risk_volume
make_fall_in_risk_volume(cables, offset, angle, distance, [sample_multiplier])
Creates a convex volume for the fall-in risk of a specific cable
cables
: either a single cable or a list of cablesangle
is between the sides of the volume and the vertical axisdistance
is length of the side of the volumeoffset
is the half-width of the plateau at the bottom of the volume
Example: On a span, make_fall_in_risk_volume(Environments[].Cables, 2m, unit_value(45, "degrees"), 10m)
wedge
make_wedges()
point_to_volume
point_to_volume(point, x_extent, y_extent, z_extent, [z_offset])
Creates a 3D volume from a GeoJSON point. The volume is constructed by specifying x, y, z
extents about the point.
Example: On a pole, point_to_volume(geo_point(location), 1m, 1m, 5m)
linestring_to_volume
linestring_to_volume(linestring, longitudinal_extent, transverse_extent, vertical_extent)
Creates a 3D volume from a GeoJSON linestring. The volume is constructed by specifying longitudinal, transverse, and vertical extents that are aligned with and measured from the linestring.
Example: On a span, linestring_to_volume(geo_linestring(list(pole1.location, pole2.location)), 1m, 1m, 1m)
polygon_to_volume
polygon_to_volume(polygon, keep_concave, distance below, distance above)
Creates a 3D volume from a 2D GeoJSON polygon.
keep_concave
: specify whether the resulting volume should remain concave if the polygon is also concave or calculated from the convex hull for performance.distance below
,distance above
: the distances below/above the smallest/largest terrain height at any of the vertices.
extrude_polygon()
affords more control over exact Z coordinates
extrude_polygon
extrude_polygon(polygon, min_z, max_z, [keep_concave: true])
Extrudes a 2D polygon, typically from GeoJSON, up into a 3D volume, between the given absolute z values.
keep_concave
: specify whether the resulting volume should remain concave if the polygon is also concave or calculated from the convex hull for performance.
combine_volume
combine_volume(list of volumes)
Combines all volumes present into a single one.
Example: On a span,
combine_volume( list( u_fall_in_risk_volume, u_canopy_volume ) )
Point Cloud selections
After creating a volume, you need to get/select the points from the Point Cloud within the volume. You can target all points, or only a specific class of points e.g. vegetation or ground.
This operation is called categorisation.
There are two special cases, where you can directly get the points within a radius around cables:
Around a static cable:
get_points()
Around a cable's full revolution (imagine a skipping rope):
get_cable_sweep_points()
Point cloud selections can then be manipulated using a number of functions.
categorize_volume_coarse
categorize_volume_coarse(level_of_detail, volume, label, [point_cloud_types])
Selects all lidar of the specified classification type within the given volume and classifies with the given classification label
level_of_detail
is used to determine the granularity of search for performance improvements.Returned points are guaranteed to be within
256.0 / 2^(level_of_detail)
metres of given volume
When only rough spatial accuracy is required, this function can be much faster than a fully correct classification using categorize_volume.
If no point cloud types are specified no filter is used. Valid point cloud types are:
ground, ground2, water, road, veg, building, fence, vehicle, smo_gnd, smo_rt, antenna_rt, overpass, electrical, railway, pipeline, infra, special, unclassified, noise, pole_p, pole_np, stays, tower, structure, cond
See Point Cloud classes for a list of Neara supported types, with examples
categorize_volume
categorize_volume(volume, label, [point_cloud_types])
Selects all lidar of the specified classification type within the given volume and classifies with the given classification label
If no point cloud types are specified no filter is used. Valid point cloud types are:
ground, ground2, water, road, veg, building, fence, vehicle, smo_gnd, smo_rt, antenna_rt, overpass, electrical, railway, pipeline, infra, special, unclassified, noise, pole_p, pole_np, stays, tower, structure, cond
See Point Cloud classes for a list of Neara supported types, with examples
combine_points
combine_points(list(points), [label])
Returns a new point grouping containing the union of all points. Sets up a new categorization if a new label is specified.
Example: On a pole, combine_points(list(get_points("points", self, 10m, "veg"), get_points("points", self, 10m, "ground")),"veg or ground")
intersect_points
intersect_points(points, points, [label])
Returns a new point grouping containing the intersection of points present in both arguments. Sets up a new categorization if a new label is specified.
Example: On a pole, intersect_points(get_points("points", self, 10m, "veg"), get_points("points", self, 10m, "ground"),"veg and ground")
exclude_points
exclude_points(points, pointsToRemove, [label])
Removes all points that appear in pointsToRemove
from points. Sets up a new categorization if a new label is specified.
Example: On a pole, exclude_points(get_points("points", self, 10m, "veg"), get_points("points", self, 10m, "ground"),"veg and not ground")
get_points
get_points(label, object, radius, [point_cloud_types])
Retrieves all points within a radial distance of the object (cables or poles). If no point cloud types are specified no filter is used.
Valid point cloud types are:
ground, ground2, water, road, veg, building, fence, vehicle, smo_gnd, smo_rt, antenna_rt, overpass, electrical, railway, pipeline, infra, special, unclassified, noise, pole_p, pole_np, stays, tower, structure, cond
See Point Cloud classes for a list of Neara supported types, with examples
Example 1
On a span:
get_points("points", Environments[].Cables, 10m, "veg")
returns all points within a 10m
radial distance of the span.
Example 2
On a pole:
get_points("veg_points", self, 10m. "veg")
returns all points classified as "veg
" within a 10m
radial distance of the pole.
get_highest_point
get_highest_point(point_selection)
Returns the highest point of the selection as a 3-dimensional coordinate. Returns null
if there are no points.
partition_points
partition_points(points, {by_timestamp: seconds, by_dataset: bool, by_point_type: bool, by_constituent_dataset: bool, by_classification: bool})
Partitions the points of the selection by the specified partition keys. At least one partition key needs to be specified.
The following keys are supported:
by_dataset
: Partitions by datasetsby_timestamp
: Partitions the points by grouping all points that lie within [time_duration] intervalby_point_type
: Partitions by point type. Respects reclassificationsby_constituent_dataset
: Partitions by breaking up combo datasets into their constituent datasets. Only needed when using combo datasetsby_classification
: Partitions by the original classification code. Does not account for reclassifications
Example: partition_points(get_points("points", self, 10m), by_constituent_dataset: true)
returns a list of constituent point selections.
Label, visualize, and colourize Point Cloud selections
The above functions create a new Point Cloud selection.
You can specify a label for the selection, which will be visible in the table cell, along with the number of points. Click on the label to reorient the camera to cover the point selection:
Additionally, this label can be given properties to modify the visualisation of the selected points, stored against the model object PointCloudVisibilityConfig
. To access, it follow these steps.
Create a new custom report and select PointCloudVisibilityConfig as the data source:
Each row in the table corresponds to a point selection:
Add new rows for each of the point selections you wish to visualise, being careful to use exactly the label
as typed in your formula.
Modify the colour for the point selection. Other options are to respect the settings of the View menu e.g. to colour points by map overlay, or to hide the points entirely. This is useful for simulating the appearance of vegetation trimming.
Each of these visualisation operations are executed in order. Where you have overlapping selections, consider this setting as altering the priority or layering of colouring options. A smaller number increases the chance the selection will be visible.
To see the point selection visualised, the eye button must be on in the column header of the corresponding field, as well as the eye button for the report containing it:
Next steps
Once you have set up point cloud selections you can perform additional operations, such as:
Create advanced visualisations by mixing selections with colour and hidden selections, as described above;
Measuring distances from point cloud selections to objects; and
Run analytics reports to perform the above on a wider area.