From 7107f1a420d576ccc44f626266be6d89eeeebfe8 Mon Sep 17 00:00:00 2001 From: Daniel Baston Date: Wed, 20 Jan 2016 11:57:21 +0000 Subject: [PATCH] #3433, ST_ClusterIntersecting gives incorrect result for MultiPoints git-svn-id: http://svn.osgeo.org/postgis/trunk@14611 b70326c6-7e19-0410-871a-916f4a2858ee --- liblwgeom/cunit/cu_geos_cluster.c | 18 ++++++++++++++++++ liblwgeom/lwgeom_geos_cluster.c | 22 ++++++++++++++++++---- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/liblwgeom/cunit/cu_geos_cluster.c b/liblwgeom/cunit/cu_geos_cluster.c index 39450f002..80215e935 100644 --- a/liblwgeom/cunit/cu_geos_cluster.c +++ b/liblwgeom/cunit/cu_geos_cluster.c @@ -238,6 +238,23 @@ static void empty_inputs_test(void) perform_cluster_within_distance_test(1, wkt_inputs, 2, expected_outputs, 2); } +static void multipoint_test(void) +{ + /* See #3433 */ + char* wkt_inputs_mp[] = { "MULTIPOINT ((0 0), (0 1))", "POINT (0 0)"}; + char* expected_outputs_mp[] = { "GEOMETRYCOLLECTION(MULTIPOINT ((0 0), (0 1)), POINT (0 0))"}; + + char* wkt_inputs_gc[] = { "GEOMETRYCOLLECTION (POINT (0 0), POINT (0 1))", "POINT (0 0)"}; + char* expected_outputs_gc[] = { "GEOMETRYCOLLECTION(GEOMETRYCOLLECTION (POINT (0 0), POINT (0 1)), POINT (0 0))"}; + + char* wkt_inputs_pt[] = { "POINT (3 3)", "POINT (3 3)"}; + char* expected_outputs_pt[] = { "GEOMETRYCOLLECTION(POINT (3 3), POINT (3 3))"}; + + perform_cluster_intersecting_test(wkt_inputs_mp, 2, expected_outputs_mp, 1); + perform_cluster_intersecting_test(wkt_inputs_gc, 2, expected_outputs_gc, 1); + perform_cluster_intersecting_test(wkt_inputs_pt, 2, expected_outputs_pt, 1); +} + void geos_cluster_suite_setup(void); void geos_cluster_suite_setup(void) { @@ -247,4 +264,5 @@ void geos_cluster_suite_setup(void) PG_ADD_TEST(suite, basic_distance_test); PG_ADD_TEST(suite, single_input_test); PG_ADD_TEST(suite, empty_inputs_test); + PG_ADD_TEST(suite, multipoint_test); } diff --git a/liblwgeom/lwgeom_geos_cluster.c b/liblwgeom/lwgeom_geos_cluster.c index 97a6fdb85..a9421afaf 100644 --- a/liblwgeom/lwgeom_geos_cluster.c +++ b/liblwgeom/lwgeom_geos_cluster.c @@ -136,12 +136,26 @@ union_if_intersecting(void* item, void* userdata) if (p != q && UF_find(cxt->uf, p) != UF_find(cxt->uf, q)) { - /* Lazy initialize prepared geometry */ - if (cxt->prep == NULL) + int geos_type = GEOSGeomTypeId(cxt->geoms[p]); + int geos_result; + + /* Don't build prepared a geometry around a Point or MultiPoint - + * there are some problems in the implementation, and it's not clear + * there would be a performance benefit in any case. (See #3433) + */ + if (geos_type != GEOS_POINT && geos_type != GEOS_MULTIPOINT) { - cxt->prep = GEOSPrepare(cxt->geoms[p]); + /* Lazy initialize prepared geometry */ + if (cxt->prep == NULL) + { + cxt->prep = GEOSPrepare(cxt->geoms[p]); + } + geos_result = GEOSPreparedIntersects(cxt->prep, cxt->geoms[q]); + } + else + { + geos_result = GEOSIntersects(cxt->geoms[p], cxt->geoms[q]); } - int geos_result = GEOSPreparedIntersects(cxt->prep, cxt->geoms[q]); if (geos_result > 1) { cxt->error = geos_result; -- 2.50.0