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

geo/geomfn: implement ST_LineInterpolatePoint(s) #49742

Merged
merged 1 commit into from
Jun 2, 2020

Conversation

abhishek20123g
Copy link
Contributor

@abhishek20123g abhishek20123g commented May 31, 2020

Fixes #48971
Fixes #48972

This PR adds following builtin functions

  • ST_LineInterpolatePoint{{geometry, float8}}
  • ST_LineInterpolatePoints{{geometry, float8, bool}}

which works for LineString only, allows us to determine one or more
interpolated points in the LineString which at an integral multiple
of given fraction of LineString's total length.

Release note (sql change): This PR implement adds the following built-in functions.

  • ST_LineInterpolatePoint{{geometry, float8}}
  • ST_LineInterpolatePoints{{geometry, float8, bool}}

@blathers-crl
Copy link

blathers-crl bot commented May 31, 2020

Thank you for contributing to CockroachDB. Please ensure you have followed the guidelines for creating a PR.

My owl senses detect your PR is good for review. Please keep an eye out for any test failures in CI.

I have added a few people who may be able to assist in reviewing:

🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is otan.

@cockroach-teamcity
Copy link
Member

This change is Reviewable

@blathers-crl blathers-crl bot added O-community Originated from the community X-blathers-triaged blathers was able to find an owner labels May 31, 2020
@blathers-crl blathers-crl bot requested a review from otan May 31, 2020 19:51
@abhishek20123g
Copy link
Contributor Author

Small Overview:

  1. Thought these functions can't be completely called as unary functions, but I had kept them in unary_operators.go file, as it may be appropriate place for them and, I am not completely sure of creating a new file for them is a good idea. In Geos they are kept under separate location named Linear referencing functions
    https://github.com/libgeos/geos/blob/master/capi/geos_c.h.in#L359.
  2. logictest can be added without creating table geom_linear but I think geom_linear table may be helpful for other linear built-in functions.
  3. Error messages are not same as they are in PostGIS I had changed them a little If they are not appropriate I can make them same as PostGIS
    the error message is postGIS are :
gis=# select st_lineinterpolatepoint('linestring(0 0, 1 1)'::geometry, -1);
ERROR:  line_interpolate_point: 2nd arg isn't within [0,1]
gis=# select st_lineinterpolatepoint('multilinestring((0 0, 1 1))'::geometry, 0.2);
ERROR:  line_interpolate_point: 1st arg isn't a line
  1. doc statements are also slightly deviated from PostGIS doc.
    In PostGIS they are as:
Returns a point interpolated along a line. First argument must be a LINESTRING. Second argument is a float8 between 0 and 1 representing fraction of total linestring length the point has to be located.
Returns one or more points interpolated along a line. First argument must be a LINESTRING. Second argument is a float8 between 0 and 1 representing the spacing between the points as a fraction of total LineString length. If the third argument is false, at most one point will be constructed (the function will be equivalent to ST_LineInterpolatePoint.)

If the result has zero or one points, it will be returned as a POINT. If it has two or more points, it will be returned as a MULTIPOINT.

@blathers-crl
Copy link

blathers-crl bot commented May 31, 2020

Thank you for updating your pull request.

My owl senses detect your PR is good for review. Please keep an eye out for any test failures in CI.

🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is otan.

Copy link
Contributor

@otan otan left a comment

Choose a reason for hiding this comment

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

glad to see you back! looking good, mostly minor nits.

nit: title does not fit in PR message. can you make it:
geo/geomfn: implement ST_LineInterpolatePoint(s)

},
Info: infoBuilder{
info: builtinInfo,
libraryUsage: usesGEOS,
Copy link
Contributor

Choose a reason for hiding this comment

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

this function does not use an index; please remove canUseIdex: true,


Note If the result has zero or one points, it will be returned as a POINT. If it has two or more points, it will be returned as a MULTIPOINT.`,
libraryUsage: usesGEOS,
canUseIndex: true,
Copy link
Contributor

Choose a reason for hiding this comment

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

this function does not use an index; please remove canUseIdex: true,

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done for all places.

@@ -119,6 +120,7 @@ struct CR_GEOS {
CR_GEOS_Area_r GEOSArea_r;
CR_GEOS_Length_r GEOSLength_r;
CR_GEOS_Centroid_r GEOSGetCentroid_r;
CR_GEOS_Interpolate_r GEOSInterpolateNormalized_r;
Copy link
Contributor

Choose a reason for hiding this comment

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

can you explain why we're using InterpolateNormalized? if this is required, please rename Interpolate_r to InterpolateNormalized_r.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed Geos function which we're using for interpolation. Previously it was GEOSInterpolateNormalized now it is GEOSInterpolate and Updated their names according to GEOSInterpolate.

Initially, I was using GEOSInterpolateNormalized as it was directly satisfying the use-case as it works with fraction directly.
But later realised that It is wrapper function over GEOSInterpolate inside which we are computing LineString's length each time it called.
Which could be inefficient for MULTIPOINT case as It can be done just computing length only once.
And there may be the case in future where we may require to locate a point at a certain distance. For which GEOSInterpolate will be the best option rather somehow using GEOSInterpolateNormalized

@@ -1428,3 +1428,72 @@ ORDER BY id
1 4004 0
2 4326 4326
3 4004 3857

Copy link
Contributor

Choose a reason for hiding this comment

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

subtest geom_linear, maybe?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done!

defProps(),
lineInterpolatePointForRepeatOverload(
false,
`Returns point along the given LineString which is at given fraction of LineString's total length.`,
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: returns a point

INSERT INTO geom_linear VALUES
('Empty LineString', 'LINESTRING EMPTY'),
('LineString anticlockwise covering all the quadrants', 'LINESTRING(1 -1, 2 2, -2 2, -1 -1)'),
('LineString clockwise covering all the quadrants with SRID 4004', 'SRID=4004;LINESTRING(1 -1, -1 -1, -2 2, 2 2)')
Copy link
Contributor

Choose a reason for hiding this comment

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

can you add tests to make sure this behaves as appropriate for POLYGON/POINT/MULTILINESTRING?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since POLYGON/POINT/MULTILINESTRING each of them will produce an error, therefore added separately query for them at the bottom.
Currently, I am unable to figure out how could we add test cases for them by inserting elements in the table.

Similar to this added test case for POLYGON/POINT/MULTILINESTRING,
in unary_operator_test.go too.

}
for _, test := range testCasesForLineInterpolate {
for _, repeat := range []bool{false, true} {
t.Run(fmt.Sprintf("%s for fraction %v where repeat is %t", test.wkb, test.fraction, repeat),
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: fraction %f

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed!
Along with this error message are also changes. As were also using %v for float in error message too.

@blathers-crl blathers-crl bot requested a review from otan June 1, 2020 12:07
@abhishek20123g abhishek20123g changed the title builtin: Implements ST_LineInterpolatePoint and ST_LineInterpolatePoi… geo/geomfn: implement ST_LineInterpolatePoint(s) Jun 1, 2020
@otan
Copy link
Contributor

otan commented Jun 1, 2020

bors r+

@craig
Copy link
Contributor

craig bot commented Jun 1, 2020

Merge conflict (retrying...)

@craig
Copy link
Contributor

craig bot commented Jun 1, 2020

Merge conflict

@otan
Copy link
Contributor

otan commented Jun 1, 2020

fixing the conflict for you, moving the file to linear_reference.go

@abhishek20123g
Copy link
Contributor Author

Thank you for the review 😊

Fixes cockroachdb#48971
Fixes cockroachdb#48972

This PR adds following builtin functions
* ST_LineInterpolatePoint{{geometry, float8}}
* ST_LineInterpolatePoints{{geometry, float8, bool}}

which works for LineString only, allows us to determine one or more
interpolated points in the LineString which at an integral multiple
of given fraction of LineString's total length.

Release note (sql change): This PR implement adds the following built-in functions.
* ST_LineInterpolatePoint{{geometry, float8}}
* ST_LineInterpolatePoints{{geometry, float8, bool}}
@otan
Copy link
Contributor

otan commented Jun 2, 2020

bors r+

@craig
Copy link
Contributor

craig bot commented Jun 2, 2020

Build succeeded

@craig craig bot merged commit cbe7fdc into cockroachdb:master Jun 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
O-community Originated from the community X-blathers-triaged blathers was able to find an owner
Projects
None yet
3 participants