ST_EliminateHoleByBuffer#

Table of Contents

  1. Setup BDT

  2. Generate Sample Data

  3. ST_EliminateHoleByBuffer

    1. Function Call

    2. Internal Steps Explained

Part 0: Setup BDT#

[ ]:
import bdt
bdt.auth("bdt.lic")
from bdt.processors import *
from bdt.functions import *
from pyspark.sql.functions import *
from pyspark.sql.types import StructType, StructField, StringType, IntegerType
BDT has been successfully authorized!

            Welcome to
             ___    _                ___         __             ______             __   __     _   __
            / _ )  (_)  ___ _       / _ \ ___ _ / /_ ___ _     /_  __/ ___  ___   / /  / /__  (_) / /_
           / _  | / /  / _ `/      / // // _ `// __// _ `/      / /   / _ \/ _ \ / /  /  '_/ / / / __/
          /____/ /_/   \_, /      /____/ \_,_/ \__/ \_,_/      /_/    \___/\___//_/  /_/\_\ /_/  \__/
                      /___/

BDT python version: v3.3.0-v3.3.0
BDT jar version: v3.3.0-v3.3.0

Part 1: Generate Sample Data#

  • The below code creates one square polygon with a square hole inside.

    • The diminsions of the polygon are 5x5, with a total area of 25 units.

    • The diminsions of its hole are 3x3, with a total area of 9.

    • The area of the hole is 36% of the total area of the polygon.

[ ]:
poly_wkt = "POLYGON((0 0, 5 0, 5 5, 0 5, 0 0), (1 1, 4 1, 4 4, 1 4, 1 1))"

poly_df = spark.createDataFrame([
            (poly_wkt,)
        ], schema="wkt string").select(st_fromText("wkt").alias("SHAPE"))

(
poly_df
    .select(st_asText("SHAPE").alias("wkt"))
    .show(truncate=False)
)
+---------------------------------------------------------------------+
|wkt                                                                  |
+---------------------------------------------------------------------+
|MULTIPOLYGON (((0 0, 5 0, 5 5, 0 5, 0 0), (1 1, 1 4, 4 4, 4 1, 1 1)))|
+---------------------------------------------------------------------+

The above code produces the following geometry:

Buffer

Part 2: ST_EliminateHoleByBuffer#

Part 2.1: Function Call#

  • ST_EliminateHoleByBuffer takes the following arguments:

    1. The polygon SHAPE.

    2. The distance to buffer (and un-buffer) the input polygon.

    3. The percentage threshold. A hole with an area less than this percentage of the total area of the polygon will be eliminated.

    4. The maximum number of vertices in a circle (or curve). The recommended default value is 96. Increase this value for polygon detail over performance and decrease for peformance over detail.

  • The output is converted to well-known text format to make the internal BDT shape readable.

  • The below code sets the buffer distance to 1.0 units, and the percentage threshold to 8.0%

[ ]:
result_df = poly_df.select(
    st_asText(
        st_eliminate_hole_by_buffer(
            "SHAPE", 1.0, 8.0, 96)
        .alias("SHAPE")
    ).alias("WKT")
)

result_df.show(truncate=False)
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|WKT                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|MULTIPOLYGON (((4.9836360778646815 3.560011134901632e-22, 4.999481281734015 5.187182659846673e-4, 5 0.01636392213531342, 5 4.983636077864691, 4.999481281734016 4.999481281734015, 4.983636077864686 5, 0.016363922135308462 5, 5.187182659843588e-4 4.999481281734016, 0 4.983636077864687, 0 0.016363922135318894, 5.187182659846685e-4 5.187182659843526e-4, 0.016363922135313347 1.0842021724855044e-19, 4.9836360778646815 3.560011134901632e-22)))|
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

  • The internal hole is removed because even though it is 36% of the polygon area before buffering, it is only about 2% of the polygon area after buffering. 2% is less than the threshold of 8%, so it is removed.

  • The below steps will show in detail why this happens.

Part 2.2: Internal Steps Explained#

  1. Step 1: Buffer and Simplify the polygon. The dimensions of the outer ring increase, and the dimensions of the inner ring (hole) decrease. The hole becomes only about 2% of the total area of the polygon.

Buffer

  1. Step 2: Remove Holes in the polygon. A buffered hole with an area that is less than the percentageThreshold of the total area of the buffered polygon will be eliminated. 2% is less than 8%, so the hole is removed.

Buffer

  1. Step 3: Simplify and Negative Buffer the polygon. Negative buffer the above result to effectively shrink the polygon back to its original size.

Buffer

  • Note: The input polygon for this example was already simple, so simplification did not do anything in this case. However, if the polygon is complex with a lot of verticies, it will be simplified too.