Roofer reconstructs one building at a time. Efficient operation requires that the point cloud is cropped to the extent of the building polygon.
There are many parameters that configure the input, output and operation of roofer.
Configuration is passed to roofer in TOML files exclusively.
The TOML config path is passed with the -c, --config
command line arguments.
There are two command line applications:
- crop (
apps/crop.cpp
): Preprocess the point cloud by cropping with the building polygons. - reconstruct (
apps/reconstruct.cpp
): Reconstruct one building.
- tomlplusplus: TOML parser.
- Used in the CLI apps.
- argh: Argument handler.
- Used in the CLI apps.
- ptinpoly: Efficient point-in-polygon test.
- --> PointcloudRasteriser
- ::isMutated --> crop
- ::computeNoDataFraction --> crop
- ::computePointDensity --> crop
- ::gridthinPointcloud --> crop
- ::isMutated --> select_pointcloud::selectPointCloud --> crop
- StreamCropper
- ::PointsInPolygonsCollector --> ::PointCloudCropper --> crop
- --> PointcloudRasteriser
- fmt: CLI message formatting, path formatting.
- Only used in the CLI apps.
- spdlog: Logging. Uses fmt internally and depends on it.
- Used throughout the code.
- GEOS
- laslib
- CGAL::Core, v5.4
- GDAL
- PROJ v9.0.0
Parse configuration from the TOML file. Input data attributes that control the operation:
- low_lod_attribute
- year_of_construction_attribute
Read vector footprints with VectorReaderOGR::readPolygons (GDAL), including inner rings, attributes and CRS definition.
- Attributes: The
output_fid_
variable controls whether to get the OGR_FID from the data, and store it in theOGR_FID
attribute. - CRS: Get the CRS definition as WKT and init the internal projection of roofer from it, using the projHelperInterface.
- Geometry: Supports only Polygon and MultiPolygon. Polygons are extracted from a MultiPolygon and stored as a LinearRing. The exterior rings are ordered CCW, interiors are CW on reading. Coordinates are transformed to the internal CRS.
Simplify the polygons.
Buffer the polygons.
Crop each input point cloud with the buffered footprints. Uses PointCloudCropper process each point cloud:
- read
- reproject
- intersect with the polygons
- crop using lastools AOI indexed intersection test
- get the point cloud acquisition year
- compute point cloud quality with PointsInPolygonsCollector::do_post_process
Compute point cloud quality with PointcloudRasteriser methods. Assign the raster quality stats to the footprint attributes.
Select the suitable point cloud with PointcloudRasteriser::isMutated.
Apply thinning to the point cloud. The bool low_lod_attribute
applies extra thinning. Used for the kas_warenhuis
in the 3DBAG.
Compute the nodata radius of the pointcloud. If the low_lod_attribute
is set, do not compute.
Create the configuration for the reconstruction.
Write the cropped point cloud. Also write the quality raster if --rasters
is set.
Write the footprint.
Write the footprints ?again as the index file?
Write CityJSON Sequence paths to .txt.
Write CityJSON metadata.json.
init projection
Read the point cloud with createPointCloudReaderLASlib into a PointCollection and a vector of point classes. Split points to ground and building points. Why use a separate vec for the classes instead of the AttributeVecMap?
points --> plane detection (createPlaneDetector) --> planes points --> plane detection ground (createPlaneDetector) --> planes_ground
planes --> alpha shapes (createAlphaShaper) --> rings, roofplane_ids planes --> alpha shapes ground (createAlphaShaper) --> rings, roofplane_ids
rings, roofplane_ids, planes --> line detection (createLineDetector) --> edge_segments
planes --> plane intersection (createPlaneIntersector)
edge_segments --> regularize the edges (LineRegulariser) --> regularised_edges
alpha shape (+ground) triangles --> segment rasterizer computes heightfields
regularized_edges --> Arrangement --> arrangement
heightfield, planes (+ground), arrangement --> optimize arrangement --> arrangement
heightfield, arrangement --> dissolve arrangement --> snap edges --> arrangement
arrangement, FLOOR_ELEVATION --> extrusion
common::LinearRing : common::Geometry - Represents 3D polygons with inner rings.
- has inner rings
- coordinates are
std::array<float, 3>
- geometry is stored in the
interior_rings_
member get_data_ptr
returns a pointer to the outer ring- the complete geometry (incl. inner rings) are accessed with
interior_rings
common::PointCollection : common::GeometryCollection : common::Geometry - Stores the point cloud as a vector of std::array<float, 3>
.
- each point can have attributes, backed by an AttributeVecMap
get_data_ptr
returns a pointer to the first point- can compute its bounding box
common::AttributeVecMap - Stores the attributes of the input polygons as a vector of values per attribute.
- an
std::unordered_map
ofstd::string
+ vector, each member stores the complete set of values for all polygons for the attribute - possible attribute value types: bool, int, float, string, 3d array of float (3d point), Date, Time, DateTime
geometry::Vector2DOpsInterface - Operations on 2D vector geometry with GEOS.
- simplification
- buffer
crop::InputPointcloud - Stores quality information about one input point cloud.
StreamCropper::PointCloudCropper –
select_pointcloud::CandidatePointCloud
projHelper