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

Fix ST_Centroid and ST_Buffer for tiny geometries #13323

Merged
merged 3 commits into from
Sep 4, 2019

Conversation

jagill
Copy link
Contributor

@jagill jagill commented Sep 2, 2019

Version 2.2.3 has two fixes of interest:

Fixes #13194 and #10629

== RELEASE NOTES ==

General Changes
-----------------
* Fix ST_Buffer for tiny geometries (#13194)
* Fix ST_Centroid for tiny geometries (#10629)

@jagill
Copy link
Contributor Author

jagill commented Sep 2, 2019

cc @mbasmanova

Copy link
Contributor

@mbasmanova mbasmanova left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jagill Thanks for fixing centroids and buffers for tiny polygons. I'd split this change into 3 commits:

  • upgrade ESRI
  • add tests for buffering tiny polygons
  • replace centroid logic with ESRI's

For better readability I'd update the commit message as follows (but this will change once the change is split into 3 commits).

Version 2.2.3 has two fixes of interest:

correct computation of centroids of very small polygons - Esri/geometry-api-java#227
correct computation of buffers around small polygons - Esri/geometry-api-java#243
Fixes #13194 and #10629

@@ -195,6 +199,20 @@ public void testSTBuffer()
assertInvalidFunction("ST_Buffer(ST_Point(0, 0), nan())", "distance is NaN");
}

@Test
public void testSTBufferTinyPolygons()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd fold this test into testSTBuffer


@Test
public void testSTCentroidInvalidGeometry()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd fold this test into testSTCentroid

}

@Test
public void testSTCentroidNumericStability()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd fold this test into testSTCentroid

@Test
public void testSTCentroidNumericStability()
{
String wkt1 = "MULTIPOLYGON (((153.492818 -28.13729, 153.492821 -28.137291, 153.492816 -28.137289, 153.492818 -28.13729)))";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't use a1, a2, a3... names for variables; here, I'd inline wkt1 and wkt2.

}

private void assertCentroid(String wkt, Point centroid)
{
assertFunction(format("ST_AsText(ST_Centroid(ST_GeometryFromText('%s')))", wkt), VARCHAR, new OGCPoint(centroid, null).asText());
}

private void assertApproximateCentroid(String wkt, Point centroid, double epsilon)
{
OGCGeometry geometry = OGCGeometry.fromText(wkt);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd inline geometry variable

private void assertApproximateCentroid(String wkt, Point centroid, double epsilon)
{
OGCGeometry geometry = OGCGeometry.fromText(wkt);
Slice inputSlice = GeometrySerde.serialize(geometry);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd inline inputSlice

OGCGeometry geometry = OGCGeometry.fromText(wkt);
Slice inputSlice = GeometrySerde.serialize(geometry);
OGCPoint calculatedCentroid = (OGCPoint) GeometrySerde.deserialize(stCentroid(inputSlice));
assertEquals(calculatedCentroid.X(), centroid.getX(), epsilon);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rename centroid to expectedCentroid and calculatedCentroid to centroid (or actualCentroid).

@mbasmanova mbasmanova requested a review from zhenxiao September 3, 2019 14:49
@mbasmanova mbasmanova self-assigned this Sep 3, 2019
Version 2.2.3 has two fixes of interest:

correct computation of centroids of very small polygons - Esri/geometry-api-java#227
correct computation of buffers around small polygons - Esri/geometry-api-java#243
@jagill jagill force-pushed the centroid-numerical-stability branch 2 times, most recently from bac0627 to 8e2777d Compare September 3, 2019 18:23
@jagill
Copy link
Contributor Author

jagill commented Sep 3, 2019

Addressed comments. cc @mbasmanova

@jagill jagill force-pushed the centroid-numerical-stability branch from 8e2777d to 0cd721d Compare September 3, 2019 19:52
Copy link
Contributor

@mbasmanova mbasmanova left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test for ST_Buffer NPE fix


// For small polygons, there was a bug in ESRI that throw an NPE. This
// was fixed (https://github.com/Esri/geometry-api-java/pull/243) to
// return an empty geometry instead. Ideally, these would return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you add a note in ST_Buffer's documentation about this behavior?

default:
throw new PrestoException(INVALID_FUNCTION_ARGUMENT, "Unexpected geometry type: " + geometryType);
}
return serialize(geometry.centroid());
}
catch (RuntimeException e) {
if (e instanceof PrestoException && ((PrestoException) e).getErrorCode() == INVALID_FUNCTION_ARGUMENT.toErrorCode()) {
throw e;
}
throw new PrestoException(INVALID_FUNCTION_ARGUMENT, format("Cannot compute centroid: %s Use ST_IsValid to confirm that input geometry is valid or compute centroid for a bounding box using ST_Envelope.", e.getMessage()), e);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jagill Is this logic still needed? I see that you removed the test that triggered it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose not!

Upgrading to Esri 2.2.3 included the fix in Esri/geometry-api-java#243
Fixes prestodb#13194
In Esri v2.2.3, the centroid calculate includes centroid fixes for
degenerate (near dimension 1) polygons (Esri/geometry-api-java#227).
This replaces our implemenation (which the original Esri implemenation
was based on) with the fixed Esri version.

Fixes prestodb#10629
@jagill jagill force-pushed the centroid-numerical-stability branch from 0cd721d to a0fead3 Compare September 3, 2019 23:08
@jagill
Copy link
Contributor Author

jagill commented Sep 3, 2019

Comments address. cc @mbasmanova

Copy link
Contributor

@mbasmanova mbasmanova left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jagill Looks good to me. Thank you for fixing these longstanding issues.

@mbasmanova mbasmanova changed the title Upgrade to ESRI geometry 2.2.3 Fix ST_Centroid and ST_Buffer for tiny geometries Sep 4, 2019
@mbasmanova mbasmanova merged commit 3cdf680 into prestodb:master Sep 4, 2019
@jagill jagill deleted the centroid-numerical-stability branch September 4, 2019 14:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

NullPointerException in ST_Buffer
3 participants