Regularize Adjacent Building Footprint (3D Analyst)

Summary

Regularizes building footprints that have common boundaries.

Usage

  • This tool uses a polyline compression algorithm to correct distortions in building footprint polygons created through feature extraction workflows that may produce undesirable artifacts.

  • When regularizing building footprints that are derived from raster data, the regularization tolerance should be larger than the resolution of the source raster.

  • Features with adjacent boundaries must have a common attribute value in order to create a regularized boundary that does not overlap another feature. If no common attribute is available, consider the following steps:

    1. Use the Buffer tool with a buffer distance that matches the desired regularization tolerance.
    2. Process the buffered polygon features with the Union tool to create a single feature for the overlapping polygons.
    3. Use the Spatial Join tool to add the unique ID from the unioned polygons to the original input features that will be regularized.
    4. Run the Regularize Adjacent Building Footprint tool with the field containing the unique ID specified in the Grouping Field (group parameter in Python).
  • Consider using the Any Angles method for input features comprised of acute or reflex interior angles, or when the angular bend between two segments does not fall on a 45° interval between 90° and 180°.

  • When the specified parameters cannot produce a regularized solution for a given input, the original feature is copied to the output. The value specified in the STATUS field will indicate whether the feature was regularized as follows:

    • 0—Regularized feature
    • 1—Original feature

Syntax

RegularizeAdjacentBuildingFootprint(in_features, group, out_feature_class, method, tolerance, precision, angular_limit)
ParameterExplanationData Type
in_features

The input features to process.

Feature Layer
group

The field that will be used to determine which features share coincident, non-overlapping boundaries.

Field
out_feature_class

The feature class that will be produced by this tool.

Feature Class
method

The method that will be used to regularize the input features.

  • RIGHT_ANGLESIdentifies the best line segments that fit the input feature vertices along 90° and 180° angles.
  • RIGHT_ANGLES_AND_DIAGONALSIdentifies the best line segments that fit the input feature vertices along 90°, 135°, and 180° interior angles.
  • ANY_ANGLESIdentifies the best fit line that falls along any angle while reducing the overall vertex count of the input features.
String
tolerance

The maximum distance that the regularized footprint can deviate from the boundary of its originating feature.

Linear Unit
precision

The precision of the spatial grid used in the regularization process. Valid values range from 0.05 to 0.25.

Double
angular_limit

The maximum deviation of the best fit line's interior angles that will be tolerated when using the Right Angles and Diagonals (RIGHT_ANGLES_AND_DIAGONALS) method. This value should generally be kept to less than 5° to obtain best results. This parameter is disabled for other regularization methods.

Double

Code sample

RegularizeAdjacentBuildingFootprint example 1 (Python window)

The following sample demonstrates the use of this tool in the Python window.

arcpy.env.workspace = 'c:/data'
arcpy.ddd.RegularizeAdjacentBuildingFootprint('rough_footprints.shp', 'Block_ID',
                                              'regularized_footprints.shp', 
                                              'RIGHT_ANGLES_AND_DIAGONALS', 
                                              '2 Meters', 0.10)
RegularizeAdjacentBuildingFootprint example 2 (stand-alone script)

The following sample demonstrates the use of this tool in a stand-alone Python script.

'''****************************************************************************
       Name: Classify Lidar & Extract Building Footprints
Description: Extract footprint from lidar points classified as buildings, 
             regularize its geometry, and calculate the building height.

****************************************************************************'''
import arcpy

lasd = arcpy.GetParameterAsText(0)
dem = arcpy.GetParameterAsText(1)
footprint = arcpy.GetParameterAsText(2)

try:
    desc = arcpy.Describe(lasd)
    if desc.spatialReference.linearUnitName in ['Foot_US', 'Foot']:
        unit = 'Feet'
    else:
        unit = 'Meters'
    ptSpacing = desc.pointSpacing * 2.25
    sampling = '{0} {1}'.format(ptSpacing, unit)
    # Classify overlap points
    arcpy.ddd.ClassifyLASOverlap(lasd, sampling)
    # Classify ground points
    arcpy.ddd.ClassifyLasGround(lasd)
    # Filter for ground points
    arcpy.management.MakeLasDatasetLayer(lasd, 'ground', class_code=[2])
    # Generate DEM
    arcpy.conversion.LasDatasetToRaster('ground', dem, 'ELEVATION', 
                                        'BINNING NEAREST NATURAL_NEIGHBOR', 
                                        sampling_type='CELLSIZE', 
                                        sampling_value=desc.pointSpacing)
    # Classify noise points
    arcpy.ddd.ClassifyLasNoise(lasd, method='ISOLATION', edit_las='CLASSIFY', 
                               withheld='WITHHELD', ground=dem, 
                               low_z='-2 feet', high_z='300 feet', 
                               max_neighbors=ptSpacing, step_width=ptSpacing, 
                               step_height='10 feet')
    # Classify buildings
    arcpy.ddd.ClassifyLasBuilding(lasd, '7.5 feet', '80 Square Feet')
    #Classify vegetation
    arcpy.ddd.ClassifyLasByHeight(lasd, 'GROUND', [8, 20, 55], 
                                  compute_stats='COMPUTE_STATS')
    # Filter LAS dataset for building points
    lasd_layer = 'building points'
    arcpy.management.MakeLasDatasetLayer(lasd, lasd_layer, class_code=[6])
    # Export raster from lidar using only building points
    temp_raster = 'in_memory/bldg_raster'
    arcpy.management.LasPointStatsAsRaster(lasd_layer, temp_raster,
                                           'PREDOMINANT_CLASS', 'CELLSIZE', 2.5)
    # Convert building raster to polygon
    temp_footprint = 'in_memory/footprint'
    arcpy.conversion.RasterToPolygon(temp_raster, temp_footprint)
    # Regularize building footprints
    arcpy.ddd.RegularizeBuildingFootprint(temp_footprint, footprint, 
                                          method='RIGHT_ANGLES')

except arcpy.ExecuteError:
    print(arcpy.GetMessages())

Licensing information

  • Basic: Requires 3D Analyst
  • Standard: Requires 3D Analyst
  • Advanced: Requires 3D Analyst

Related topics