Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added calculation of the bounding box across multiple geometry columns for PostgreSQL (3.6) #1731

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

lgoltz
Copy link
Contributor

@lgoltz lgoltz commented Aug 13, 2024

Backport #1729

@lgoltz lgoltz changed the title Added calculation of the bounding box across multiple geometry columns for PostgreSQL (3.5) Added calculation of the bounding box across multiple geometry columns for PostgreSQL (3.6) Aug 13, 2024
@lgoltz lgoltz added enhancement enhancement or improvement WFS deegree Web Feature Service labels Aug 13, 2024
@lgoltz lgoltz added this to the 3.6 milestone Aug 13, 2024
@lgoltz
Copy link
Contributor Author

lgoltz commented Oct 24, 2024

From #1732 (comment):

We also discussed the use of ST_Union in the PostGIS dialect and we are very concerned that the proposed solution results in unexpected performance regressions. Calculating ST_Union can be very expensive on large complex geometries. There are many ways to preventing the use of this (potentially) expensive union, such as using ST_Collect instead, rewrite the query generator to compute extents for every column first and aggregate them later, etc.

Use of ST_Collect instead of ST_Union: 9118ed2

Before (with ST_Union):

inspire=# EXPLAIN ANALYZE SELECT ST_Extent( u.union )::BOX2D FROM (SELECT ST_Union( ARRAY[ ST_Extent(bu_core3d_geometry2d_bu_base_buildinggeometry2d_bu_base_geo_104)::BOX2D, ST_Extent(bu_core3d_geometry3dlod1_bu_core3d_buildinggeometry3dlod1_b_130)::BOX2D, ST_Extent(bu_core3d_geometry3dlod1_bu_core3d_buildinggeometry3dlod1_b_135)::BOX2D, ST_Extent(bu_core3d_geometry3dlod1_bu_core3d_buildinggeometry3dlod1_b_141)::BOX2D, ST_Extent(bu_core3d_geometry3dlod2_bu_core3d_buildinggeometry3dlod2_b_175)::BOX2D, ST_Extent(bu_core3d_geometry3dlod2_bu_core3d_buildinggeometry3dlod2_b_180)::BOX2D, ST_Extent(bu_core3d_geometry3dlod2_bu_core3d_buildinggeometry3dlod2_b_186)::BOX2D, ST_Extent(bu_core3d_geometry3dlod3_bu_core3d_buildinggeometry3dlod1_b_213)::BOX2D, ST_Extent(bu_core3d_geometry3dlod3_bu_core3d_buildinggeometry3dlod1_b_218)::BOX2D, ST_Extent(bu_core3d_geometry3dlod3_bu_core3d_buildinggeometry3dlod1_b_224)::BOX2D, ST_Extent(bu_core3d_geometry3dlod3_bu_core3d_buildinggeometry3dlod2_b_258)::BOX2D, ST_Extent(bu_core3d_geometry3dlod3_bu_core3d_buildinggeometry3dlod2_b_263)::BOX2D, ST_Extent(bu_core3d_geometry3dlod3_bu_core3d_buildinggeometry3dlod2_b_269)::BOX2D, ST_Extent(bu_core3d_geometry3dlod3_bu_core3d_buildinggeometry3dlod_bu_296)::BOX2D, ST_Extent(bu_core3d_geometry3dlod3_bu_core3d_buildinggeometry3dlod_bu_301)::BOX2D, ST_Extent(bu_core3d_geometry3dlod3_bu_core3d_buildinggeometry3dlod_bu_307)::BOX2D, ST_Extent(bu_core3d_geometry3dlod4_bu_core3d_buildinggeometry3dlod1_b_327)::BOX2D, ST_Extent(bu_core3d_geometry3dlod4_bu_core3d_buildinggeometry3dlod1_b_332)::BOX2D, ST_Extent(bu_core3d_geometry3dlod4_bu_core3d_buildinggeometry3dlod1_b_338)::BOX2D, ST_Extent(bu_core3d_geometry3dlod4_bu_core3d_buildinggeometry3dlod2_b_372)::BOX2D, ST_Extent(bu_core3d_geometry3dlod4_bu_core3d_buildinggeometry3dlod2_b_377)::BOX2D, ST_Extent(bu_core3d_geometry3dlod4_bu_core3d_buildinggeometry3dlod2_b_383)::BOX2D, ST_Extent(bu_core3d_geometry3dlod4_bu_core3d_buildinggeometry3dlod_bu_410)::BOX2D, ST_Extent(bu_core3d_geometry3dlod4_bu_core3d_buildinggeometry3dlod_bu_415)::BOX2D, ST_Extent(bu_core3d_geometry3dlod4_bu_core3d_buildinggeometry3dlod_bu_421)::BOX2D ] ) as union FROM citygml.bu_core3d_building) u;
                                                        QUERY PLAN                                                         
---------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=32.27..32.28 rows=1 width=65) (actual time=0.208..0.211 rows=1 loops=1)
   ->  Aggregate  (cost=16.25..32.01 rows=1 width=32) (actual time=0.194..0.197 rows=1 loops=1)
         ->  Seq Scan on bu_core3d_building  (cost=0.00..10.00 rows=1 width=800) (actual time=0.018..0.022 rows=1 loops=1)
 Planning Time: 1.316 ms
 Execution Time: 0.603 ms
(5 rows)

After (with ST_Collect):

inspire=# EXPLAIN ANALYZE SELECT ST_Extent( u.union )::BOX2D FROM (SELECT ST_Collect( ARRAY[ ST_Extent(bu_core3d_geometry2d_bu_base_buildinggeometry2d_bu_base_geo_104)::BOX2D, ST_Extent(bu_core3d_geometry3dlod1_bu_core3d_buildinggeometry3dlod1_b_130)::BOX2D, ST_Extent(bu_core3d_geometry3dlod1_bu_core3d_buildinggeometry3dlod1_b_135)::BOX2D, ST_Extent(bu_core3d_geometry3dlod1_bu_core3d_buildinggeometry3dlod1_b_141)::BOX2D, ST_Extent(bu_core3d_geometry3dlod2_bu_core3d_buildinggeometry3dlod2_b_175)::BOX2D, ST_Extent(bu_core3d_geometry3dlod2_bu_core3d_buildinggeometry3dlod2_b_180)::BOX2D, ST_Extent(bu_core3d_geometry3dlod2_bu_core3d_buildinggeometry3dlod2_b_186)::BOX2D, ST_Extent(bu_core3d_geometry3dlod3_bu_core3d_buildinggeometry3dlod1_b_213)::BOX2D, ST_Extent(bu_core3d_geometry3dlod3_bu_core3d_buildinggeometry3dlod1_b_218)::BOX2D, ST_Extent(bu_core3d_geometry3dlod3_bu_core3d_buildinggeometry3dlod1_b_224)::BOX2D, ST_Extent(bu_core3d_geometry3dlod3_bu_core3d_buildinggeometry3dlod2_b_258)::BOX2D, ST_Extent(bu_core3d_geometry3dlod3_bu_core3d_buildinggeometry3dlod2_b_263)::BOX2D, ST_Extent(bu_core3d_geometry3dlod3_bu_core3d_buildinggeometry3dlod2_b_269)::BOX2D, ST_Extent(bu_core3d_geometry3dlod3_bu_core3d_buildinggeometry3dlod_bu_296)::BOX2D, ST_Extent(bu_core3d_geometry3dlod3_bu_core3d_buildinggeometry3dlod_bu_301)::BOX2D, ST_Extent(bu_core3d_geometry3dlod3_bu_core3d_buildinggeometry3dlod_bu_307)::BOX2D, ST_Extent(bu_core3d_geometry3dlod4_bu_core3d_buildinggeometry3dlod1_b_327)::BOX2D, ST_Extent(bu_core3d_geometry3dlod4_bu_core3d_buildinggeometry3dlod1_b_332)::BOX2D, ST_Extent(bu_core3d_geometry3dlod4_bu_core3d_buildinggeometry3dlod1_b_338)::BOX2D, ST_Extent(bu_core3d_geometry3dlod4_bu_core3d_buildinggeometry3dlod2_b_372)::BOX2D, ST_Extent(bu_core3d_geometry3dlod4_bu_core3d_buildinggeometry3dlod2_b_377)::BOX2D, ST_Extent(bu_core3d_geometry3dlod4_bu_core3d_buildinggeometry3dlod2_b_383)::BOX2D, ST_Extent(bu_core3d_geometry3dlod4_bu_core3d_buildinggeometry3dlod_bu_410)::BOX2D, ST_Extent(bu_core3d_geometry3dlod4_bu_core3d_buildinggeometry3dlod_bu_415)::BOX2D, ST_Extent(bu_core3d_geometry3dlod4_bu_core3d_buildinggeometry3dlod_bu_421)::BOX2D ] ) as union FROM citygml.bu_core3d_building) u;
                                                        QUERY PLAN                                                         
---------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=19.90..19.91 rows=1 width=65) (actual time=0.088..0.090 rows=1 loops=1)
   ->  Aggregate  (cost=16.25..19.64 rows=1 width=32) (actual time=0.077..0.078 rows=1 loops=1)
         ->  Seq Scan on bu_core3d_building  (cost=0.00..10.00 rows=1 width=800) (actual time=0.016..0.018 rows=1 loops=1)
 Planning Time: 1.068 ms
 Execution Time: 0.361 ms
(5 rows)

bu_core3d_building contains only one row.

@julianzz98
Copy link
Contributor

julianzz98 commented Nov 5, 2024

The enhancement was successfully tested on a local infrastructure setup, using a PostgreSQL database containing data with multiple geometry columns. The test involved making the following deegree REST request to update the bounding box cache:

Upon completion, the following output was generated, filling the relevant feature type with information regarding the bounding box:

#Mon Aug 12 13:22:12 UTC 2024
{http://inspire.ec.europa.eu/schemas/bu-base/4.0}AbstractConstruction=
{http://inspire.ec.europa.eu/schemas/bu-base/4.0}BuildingPart=
{http://www.opengis.net/gml/3.2}MultiSolidCoverage=
{http://www.opengis.net/gml/3.2}Observation=
{http://www.opengis.net/gml/3.2}DirectedObservationAtDistance=
{http://www.opengis.net/gml/3.2}RectifiedGridCoverage=
{http://www.opengis.net/gml/3.2}GridCoverage=
{http://www.opengis.net/gml/3.2}FeatureCollection=
{http://www.opengis.net/gml/3.2}MultiSurfaceCoverage=
{http://www.opengis.net/gml/3.2}DirectedObservation=
{http://www.opengis.net/gml/3.2}AbstractFeature=
{http://www.opengis.net/gml/3.2}AbstractFeatureCollection=
{http://inspire.ec.europa.eu/schemas/bu-core3d/4.0}BuildingPart=
{http://www.opengis.net/gml/3.2}MultiPointCoverage=
{http://inspire.ec.europa.eu/schemas/gn/4.0}NamedPlace=
{http://inspire.ec.europa.eu/schemas/bu-base/4.0}Building=
{http://www.opengis.net/gml/3.2}AbstractContinuousCoverage=
{http://inspire.ec.europa.eu/schemas/base/3.3}SpatialDataSet=
{http://inspire.ec.europa.eu/schemas/bu-core3d/4.0}Building=epsg:7423,6.986686479893888,49.239796941834136,6.986799730542692,49.23987057120162
{http://www.opengis.net/gml/3.2}DynamicFeature=
{http://www.opengis.net/gml/3.2}AbstractDiscreteCoverage=
{http://inspire.ec.europa.eu/schemas/bu-base/4.0}AbstractBuilding=
{http://www.opengis.net/gml/3.2}AbstractCoverage=
{http://www.opengis.net/gml/3.2}DynamicFeatureCollection=
{http://www.opengis.net/gml/3.2}MultiCurveCoverage=

A secondary test was conducted using identical data but stored in an Oracle database. The same REST request was issued to update the bounding box cache. As expected the bounding box cache remained unchanged, since the enhancement was specifically designed for PostgreSQL.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement enhancement or improvement WFS deegree Web Feature Service
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants