Skip to content

Commit

Permalink
Add cheap ST_Intersection method for certain cases
Browse files Browse the repository at this point in the history
To find the intersection of an envelope that contains a geometry,
we can simple return the geometry.  This adds a check for that case,
short-circuiting the expensive intersection logic.

It reduces the benchmark cost for these types of intersections with small
polygons by 200x, and large polygons by 100,000x.

Original
Benchmark                                                          Mode  Cnt      Score     Error  Units
**BenchmarkSTIntersection.stIntersectionComplexPolygonLargeEnvelope  avgt   15  11572.428 ± 298.935  us/op**
BenchmarkSTIntersection.stIntersectionComplexPolygonSmallEnvelope  avgt   15   1405.820 ±  50.947  us/op
BenchmarkSTIntersection.stIntersectionComplexPolygons              avgt   15  18024.312 ±  93.407  us/op
BenchmarkSTIntersection.stIntersectionSimpleComplexPolygons        avgt   15   3624.582 ±  54.135  us/op
**BenchmarkSTIntersection.stIntersectionSimplePolygonLargeEnvelope   avgt   15     23.695 ±   0.296  us/op**
BenchmarkSTIntersection.stIntersectionSimplePolygonSmallEnvelope   avgt   15     47.711 ±   0.757  us/op
BenchmarkSTIntersection.stIntersectionSimplePolygons               avgt   15     17.121 ±   0.290  us/op

With Envelope Shortcut
Benchmark                                                          Mode  Cnt      Score     Error  Units
**BenchmarkSTIntersection.stIntersectionComplexPolygonLargeEnvelope  avgt   15      0.090 ±   0.007  us/op**
BenchmarkSTIntersection.stIntersectionComplexPolygonSmallEnvelope  avgt   15   1426.323 ±  52.648  us/op
BenchmarkSTIntersection.stIntersectionComplexPolygons              avgt   15  18471.559 ± 410.481  us/op
BenchmarkSTIntersection.stIntersectionSimpleComplexPolygons        avgt   15   3722.377 ±  67.931  us/op
**BenchmarkSTIntersection.stIntersectionSimplePolygonLargeEnvelope   avgt   15      0.087 ±   0.001  us/op**
BenchmarkSTIntersection.stIntersectionSimplePolygonSmallEnvelope   avgt   15     47.280 ±   0.524  us/op
BenchmarkSTIntersection.stIntersectionSimplePolygons               avgt   15     16.877 ±   0.364  us/op
  • Loading branch information
jagill authored and mbasmanova committed Feb 19, 2020
1 parent 3c674ca commit bfb18d6
Showing 1 changed file with 15 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -1040,7 +1040,10 @@ public static Slice stExteriorRing(@SqlType(GEOMETRY_TYPE_NAME) Slice input)
@SqlType(GEOMETRY_TYPE_NAME)
public static Slice stIntersection(@SqlType(GEOMETRY_TYPE_NAME) Slice left, @SqlType(GEOMETRY_TYPE_NAME) Slice right)
{
if (deserializeType(left) == GeometrySerializationType.ENVELOPE && deserializeType(right) == GeometrySerializationType.ENVELOPE) {
GeometrySerializationType leftType = deserializeType(left);
GeometrySerializationType rightType = deserializeType(right);

if (leftType == GeometrySerializationType.ENVELOPE && rightType == GeometrySerializationType.ENVELOPE) {
Envelope leftEnvelope = deserializeEnvelope(left);
Envelope rightEnvelope = deserializeEnvelope(right);

Expand All @@ -1064,6 +1067,17 @@ public static Slice stIntersection(@SqlType(GEOMETRY_TYPE_NAME) Slice left, @Sql
return EsriGeometrySerde.serialize(intersection);
}

// If one side is an envelope, then if it contains the other's envelope we can just return the other geometry.
if (leftType == GeometrySerializationType.ENVELOPE
&& deserializeEnvelope(left).contains(deserializeEnvelope(right))) {
return right;
}

if (rightType == GeometrySerializationType.ENVELOPE
&& deserializeEnvelope(right).contains(deserializeEnvelope(left))) {
return left;
}

OGCGeometry leftGeometry = EsriGeometrySerde.deserialize(left);
OGCGeometry rightGeometry = EsriGeometrySerde.deserialize(right);
verifySameSpatialReference(leftGeometry, rightGeometry);
Expand Down

0 comments on commit bfb18d6

Please sign in to comment.