Giter Club home page Giter Club logo

building-boundary's Introduction

Building Boundary

Traces the boundary of a set of points belonging to an aerial LiDAR scan of a building (part). It attempts to optimize the boundary by exploiting the (most often) rectilinearity of buildings. It will look for the primary orientations of the building and regularize all boundary lines to these orientations (or the perpendicular).

The basic steps of the algorithm are as follows:

  1. Determine the boundary points
  2. Check if the shape matches a basic shape (rectangle or triangle), if so return this basic shape
  3. Segment the boundary points in to wall segments
  4. Fit a line to each segment
  5. Determine the primary orientations
  6. Regularize the lines to the primary orientations
  7. Merge subsequent parallel lines
  8. Compute the intersections of the lines

boundary points

boundary points

boundary points

boundary points

boundary points

Prerequisites

  • python >= 3.6
  • pip >= 19.1
  • concave-hull >= 1.0
  • pymintriangle >= 0.1
  • CGAL (with SWIG python bindings) >= 4.12 (optional, drastically improves computation time of alpha shapes)

Install

pip install .

Usage

import numpy as np
import building_boundary

points = np.array([
    [122336.637, 489292.815],
    [122336.233, 489291.98 ],
    [122336.258, 489292.865],
    [122335.234, 489293.104],
    [122336.448, 489293.46 ],
    [122334.992, 489293.68 ],
    [122335.987, 489292.778],
    [122335.383, 489292.746],
    [122336.509, 489293.173],
    [122335.794, 489293.425],
    [122335.562, 489293.121],
    [122335.469, 489293.406],
    [122335.944, 489293.734],
    [122335.3  , 489293.697],
    [122336.574, 489292.414],
    [122336.2  , 489292.31 ],
    [122335.907, 489292.296],
    [122335.599, 489292.281],
    [122335.686, 489292.762],
    [122336.842, 489293.192],
    [122335.886, 489293.139],
    [122335.094, 489292.733],
    [122336.146, 489293.444],
    [122336.193, 489293.157],
    [122335.154, 489293.389],
    [122335.643, 489293.717]
])
vertices = building_boundary.trace_boundary(
    points,
    0.3,
    max_error=0.4,
    alpha=0.5,
    k=5,
    num_points=10,
    merge_distance=0.6
)

Documentation

trace_boundary

Trace the boundary of a set of 2D points.

Parameters

points : (Mx2) array
The coordinates of the points.
ransac_threshold : float
Maximum distance for a data point to be classified as an inlier during the RANSAC line fitting.
max_error : float
The maximum error (distance) a point can have to a computed line.
alpha : float
Set to determine the boundary points using an alpha shape using this chosen alpha. If both alpha and k are set both methods will be used and the resulting shapes merged to find the boundary points.
k : int
Set to determine the boundary points using a knn based concave hull algorithm using this amount of nearest neighbors. If both alpha and k are set both methods will be used and the resulting shapes merged to find the boundary points.
num_points : int, optional
The number of points a segment needs to be supported by to be considered a primary orientation. Will be ignored if primary orientations are set manually.
angle_epsilon : float, optional
The angle (in radians) difference within two angles are considered the same. Used to merge segments.
merge_distance : float, optional
If the distance between two parallel sequential segments (based on the angle epsilon) is lower than this value the segments get merged.
primary_orientations : list of floats, optional
The desired primary orientations (in radians) of the boundary. If set manually here these orientations will not be computed.
perp_dist_weight : float, optional
Used during the computation of the intersections between the segments. If the distance between the intersection of two segments and the segments is more than perp_dist_weight times the distance between the intersection of the perpendicular line at the end of the line segment and the segments, the perpendicular intersection will be used instead.
inflate : bool, optional
If set to true the fit lines will be moved to the furthest outside point.

Returns

vertices : (Mx2) array
The vertices of the computed boundary line

building-boundary's People

Contributors

chrislcs avatar tomvantilburg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

building-boundary's Issues

max_intersect_distance is not always used as constraint

There are still situations where there are long spikes in the boundary output.
One approach might be to use a maximum_angle for a vertex? In that case vertices that have a very narrow angle from the edges can simply be discarded.

Defining optimal parameter values

Hi, can someone please define optimal value for the parameters:
a) alpha
b) k
c) max_error
d) merge_angle

I am trying to use this library and would like to understand these parameters.

Have footprint_geom accept (multi)linestrings

When preprocessing the footprint it can be useful to remove certain lines but that would invalidate or introduce new angles to the polygon. Simply giving a (multi)-linestring would avoid that.

index out of range error on some point configurations

Reproduce with:

import numpy as np
from buildingboundary import trace_boundary

points=[[111011.253, 488124.147],
       [111011.319, 488123.927],
       [111011.675, 488124.571],
       [111011.679, 488124.148],
       [111011.852, 488124.393],
       [111011.96 , 488124.708],
       [111012.09 , 488124.304],
       [111012.233, 488124.553],
       [111012.404, 488124.727]]
trace_boundary(points,
        max_error= 0.3,
        merge_angle= 0.2,
        k=5
) 

Loop in merge algorithm

Code loops forever.
Reproduces with:

points = [[122336.637, 489292.815],
       [122336.233, 489291.98 ],
       [122336.258, 489292.865],
       [122335.234, 489293.104],
       [122336.448, 489293.46 ],
       [122334.992, 489293.68 ],
       [122335.987, 489292.778],
       [122335.383, 489292.746],
       [122336.509, 489293.173],
       [122335.794, 489293.425],
       [122335.562, 489293.121],
       [122335.469, 489293.406],
       [122335.944, 489293.734],
       [122335.3  , 489293.697],
       [122336.574, 489292.414],
       [122336.2  , 489292.31 ],
       [122335.907, 489292.296],
       [122335.599, 489292.281],
       [122335.686, 489292.762],
       [122336.842, 489293.192],
       [122335.886, 489293.139],
       [122335.094, 489292.733],
       [122336.146, 489293.444],
       [122336.193, 489293.157],
       [122335.154, 489293.389],
       [122335.643, 489293.717]]
vertices = trace_boundary(points,
       max_error=0.26,
       merge_angle=0.4,
       k=5,
       alpha=0.5,
       min_area=2,
       max_merge_distance=0.6,
       max_error_invalid=0.35
)

Defining dependencies

Hi, in addition to the existing 4 dependencies, 'python-pcl' should also be added as a dependency. Even after cgal-bindings are installed successfully, the module needs pcl-bindings as well which has to be installed separately.

Self intersecting polygons returned

Consider the following output:

image

created by:

import numpy as np
from buildingboundary import trace_boundary
xarray=[125213.792,125213.511,125213.213,125212.895,125213.387,125212.801,125212.161,125209.805666667,125211.831,125210.097333333,125209.805666667,125211.341,125211.341,125211.216,125210.967,125210.92,125210.699,125210.542,125210.382,125210.331,125210.328,125210.178,125210.023,125210.021,125210.097333333,125214.458,125214.076,125213.474,125214.515,125214.684,125215.343,125215.057,125214.752,125214.442,125214.123,125215.237,125214.952,125214.654,125214.366,125213.725,125215.259,125214.954,125214.651,125214.366,125214.068,125213.436,125213.153,125214.535,125214.248,125213.35,125213.035,125214.089]
yarray=[480380.365,480380.343,480380.32,480380.296,480379.967,480379.922,480379.873,480378.319666667,480379.393,480378.027333333,480378.027333333,480379.941,480379.656,480379.347,480379.782,480379.324,480379.943,480380.726,480379.704,480379.992,480379.278,480380.774,480379.751,480379.255,480378.319666667,480383.325,480382.919,480382.872,480382.854,480382.387,480381.908,480381.885,480381.861,480381.838,480381.812,480381.506,480381.484,480381.46,480381.438,480381.389,480381.056,480381.032,480381.007,480380.986,480380.963,480380.914,480380.892,480380.679,480380.657,480380.587,480380.563,480380.388]
points = np.array((xarray, yarray)).T
trace_boundary(points,
 max_error=0.26,
 merge_angle=0.4,
 k=5,
 alpha=0.5,
 min_area=2,
 max_merge_distance=0.6,
 max_error_invalid=0.35,
 inflate=True)

Div by zero on some point configurations

Error message:
/usr/local/lib/python3.6/dist-packages/buildingboundary/components/segment.py:112: RuntimeWarning: divide by zero encountered in double_scalars

Reproduce with:

xarray=[125279.972,125280.391,125281.832,125281.923,125281.328,125281.787,125281.523,125280.928,125279.7315,125280.017625,125280.30375,125280.589875,125279.7315,125280.017625,125280.30375,125280.589875,125279.7315,125280.017625,125280.30375,125280.589875,125279.15925,125279.445375,125279.7315,125280.017625,125280.30375,125278.873125,125279.15925,125279.445375,125279.7315,125280.017625,125278.873125,125279.15925,125279.445375,125279.7315,125280.017625,125278.873125,125279.15925,125279.445375,125279.7315,125278.873125,125279.15925,125279.445375,125278.873125,125279.15925,125279.445375,125278.873125,125279.15925]
yarray=[480312.927,480312.589,480311.898,480311.623,480311.59,480311.228,480311.213,480311.181,480310.305272727,480310.305272727,480310.305272727,480310.305272727,480310.594545455,480310.594545455,480310.594545455,480310.594545455,480310.883818182,480310.883818182,480310.883818182,480310.883818182,480311.173090909,480311.173090909,480311.173090909,480311.173090909,480311.173090909,480311.462363636,480311.462363636,480311.462363636,480311.462363636,480311.462363636,480311.751636364,480311.751636364,480311.751636364,480311.751636364,480311.751636364,480312.040909091,480312.040909091,480312.040909091,480312.040909091,480312.330181818,480312.330181818,480312.330181818,480312.619454545,480312.619454545,480312.619454545,480312.908727273,480312.908727273]
points = np.array((xarray, yarray)).T
geom="POLYGON((125292.907 480314.521,125294.28 480315.277,125291.481 480320.326,125290.805 480319.947,125288.723 480318.781,125288.368 480319.414,125280.293 480314.951,125278.789 480317.714,125276.599 480321.735,125275.121 480324.45,125274.83 480324.984,125273.412 480327.589,125273 480328.345,125272.842 480328.258,125257.554 480319.811,125235.889 480325.954,125228.969 480338.56,125230.882 480337.944,125236.699 480327.315,125252.1 480322.994,125258.904 480326.894,125264.434 480325.343,125271.906 480329.476,125275.381 480341.398,125271.091 480349.188,125259.411 480352.548,125252.331 480348.648,125241.606 480351.716,125232.946 480346.953,125225.837 480348.985,125221.998 480355.922,125226.648 480358.405,125225.822 480359.879,125225.968 480359.971,125226.105 480360.076,125226.232 480360.193,125226.348 480360.322,125226.451 480360.46,125226.542 480360.608,125226.618 480360.763,125226.681 480360.924,125226.728 480361.09,125226.76 480361.26,125226.776 480361.432,125226.776 480361.605,125226.761 480361.777,125226.73 480361.947,125226.683 480362.114,125226.622 480362.276,125226.546 480362.431,125226.456 480362.579,125226.353 480362.718,125226.238 480362.847,125226.112 480362.964,125225.975 480363.07,125225.829 480363.163,125225.676 480363.243,125225.516 480363.308,125225.35 480363.358,125225.181 480363.392,125225.009 480363.411,125224.836 480363.415,125224.664 480363.402,125224.493 480363.374,125224.326 480363.331,125224.163 480363.272,125224.007 480363.199,125222.341 480366.209,125222.484 480366.304,125222.619 480366.413,125222.742 480366.533,125222.855 480366.664,125222.955 480366.804,125223.042 480366.953,125223.115 480367.11,125223.174 480367.272,125223.217 480367.439,125223.245 480367.609,125223.258 480367.781,125223.255 480367.954,125223.236 480368.125,125223.202 480368.294,125223.152 480368.46,125223.088 480368.62,125223.009 480368.773,125222.917 480368.919,125222.812 480369.056,125222.694 480369.183,125222.566 480369.298,125222.428 480369.402,125222.281 480369.492,125222.126 480369.569,125221.966 480369.631,125221.8 480369.678,125221.63 480369.711,125221.458 480369.727,125221.286 480369.728,125221.114 480369.713,125220.944 480369.683,125220.778 480369.637,125220.616 480369.577,125220.461 480369.502,125217.416 480375.06,125215.404 480374.07,125216.054 480376.423,125220.365 480378.798,125220.787 480380.263,125220.054 480381.585,125218.59 480381.999,125217.796 480381.557,125216.101 480384.612,125219.672 480386.614,125219.793 480386.396,125221.189 480387.179,125224.318 480398.078,125230.824 480401.72,125234.84 480403.981,125240.032 480406.81,125239.545 480407.683,125242.455 480409.304,125239.491 480414.368,125238.121 480413.617,125233.972 480421.182,125232.746 480420.525,125228.233 480428.936,125226.544 480427.99,125225.914 480428.169,125225.946 480428.337,125225.962 480428.508,125225.963 480428.68,125225.948 480428.851,125225.917 480429.02,125225.87 480429.185,125225.809 480429.345,125225.733 480429.499,125225.643 480429.645,125225.539 480429.782,125225.424 480429.909,125225.297 480430.025,125225.16 480430.129,125225.015 480430.219,125224.861 480430.296,125224.701 480430.358,125224.536 480430.405,125224.367 480430.436,125224.196 480430.452,125224.025 480430.452,125223.854 480430.436,125223.685 480430.404,125223.52 480430.357,125223.36 480430.294,125223.206 480430.218,125223.061 480430.127,125222.924 480430.023,125222.798 480429.907,125222.682 480429.78,125222.579 480429.642,125222.49 480429.496,125222.414 480429.342,125222.353 480429.182,125221.751 480429.381,125220.876 480430.963,125220.712 480430.872,125220.49 480431.267,125212.487 480426.835,125212.079 480427.57,125204.35 480423.365,125203.52 480424.698,125198.46 480421.928,125200.059 480419.006,125199.192 480418.532,125207.802 480402.798,125204.636 480391.864,125204.938 480391.323,125202.711 480390.082,125202.42 480390.603,125191.466 480393.744,125182.566 480410.008,125181.697 480409.532,125180.391 480411.918,125175.331 480409.117,125176.094 480407.736,125168.443 480403.513,125174.991 480391.651,125175.888 480391.399,125174.901 480387.885,125174.015 480388.134,125162.627 480381.832,125166.817 480374.264,125164.871 480373.188,125167.686 480368.129,125170.745 480369.83,125171.231 480368.957,125186.838 480377.639,125197.918 480374.358,125199.694 480371.166,125196.996 480361.848,125180.221 480352.515,125180.707 480351.64,125177.77 480350.007,125178.816 480348.13,125180.591 480344.948,125181.922 480345.683,125184.874 480340.34,125198.308 480336.485,125206.44 480321.782,125202.567 480308.355,125205.521 480303.011,125204.19 480302.277,125206.99 480297.218,125209.923 480298.841,125210.407 480297.966,125226.094 480306.65,125230.863 480305.285,125236.495 480295.107,125235.121 480290.34,125217.566 480280.623,125218.051 480279.748,125216.974 480279.152,125219.78 480274.084,125221.18 480274.859,125225.411 480267.218,125237.208 480273.747,125237.497 480274.625,125240.946 480273.502,125240.675 480272.699,125247.586 480260.874,125254.673 480264.693,125253.841 480266.258,125255.141 480266.988,125256.921 480263.748,125260.171 480265.508,125259.661 480266.488,125259.551 480266.578,125264.771 480269.238,125269.431 480267.898,125273.634 480260.314,125270.689 480250.114,125267.922 480248.578,125269.454 480245.818,125267.446 480238.84,125264.665 480237.276,125266.214 480234.527,125261.266 480217.296,125256.891 480214.86,125259.578 480210.05,125258.62 480209.515,125256.383 480208.266,125259.21 480203.203,125260.506 480203.927,125264.744 480196.338,125266.641 480197.401,125268.631 480193.838,125282.214 480189.879,125285.765 480191.843,125286.749 480190.06,125294.32 480194.239,125295.084 480192.855,125300.172 480195.659,125298.415 480198.839,125305.675 480202.854,125309.235 480204.823,125316.481 480208.83,125318.237 480205.652,125323.313 480208.466,125322.579 480209.793,125330.176 480213.97,125329.149 480215.836,125332.736 480217.82,125336.651 480231.468,125334.682 480235.028,125336.556 480236.064,125332.302 480243.756,125333.48 480244.408,125330.681 480249.458,125327.635 480247.774,125327.08 480248.778,125318.098 480265.02,125318.405 480265.189,125318.294 480265.39,125317.944 480266.022,125320.671 480267.547,125317.881 480272.607,125316.733 480271.963,125312.522 480279.568,125310.633 480278.522,125308.978 480281.517,125307.841 480283.572,125307.377 480284.413,125306.252 480286.447,125305.891 480287.097,125293.581 480280.155,125284.29 480296.752,125283.418 480297.003,125284.508 480300.577,125285.432 480300.305,125297.178 480306.813,125292.907 480314.521),(125274.551 480274.578,125278.006 480276.68,125280.174 480272.594,125276.595 480270.577,125275.367 480266.321,125273.281 480270.082,125274.551 480274.578),(125265.385 480289.654,125261.787 480290.764,125258.428 480296.855,125258.812 480298.235,125267.426 480295.761,125276.229 480279.174,125273.243 480277.522,125271.884 480277.913,125265.385 480289.654),(125250.924 480286.759,125253.333 480295.196,125254.704 480294.789,125258.078 480288.707,125257.22 480285.502,125263.869 480273.48,125263.48 480272.12,125260.067 480270.232,125250.924 480286.759))"
trace_boundary(points,
 max_error=0.26,
 merge_angle=0.4,
 k=5,
 alpha=0.5,
 min_area=2,
 max_merge_distance=0.6,
 max_error_invalid=0.35,
 inflate=True,
 footprint_geom=geom)

building simplify example

hello. Could you give me an example of how to regularize buildings? There are so many functions here that I can't use them very well.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.