WL#7929: GIS: Implement ST_Buffer and ST_Distance with Boost.Geometry

Status: Complete   —   Priority: Medium

Replace the current Buffer/ST_Buffer implementation with BG when BG supports buffer.

Replace remaining st_distance() implementation which uses old GIS algorithm with
BG algorithms.
F-1: ST_Buffer MUST return NULL if any of its arguments is NULL, or if the
geometry argument is an invalid GEOMETRY byte string.
In case of an invalid GEOMETRY byte string, ER_GIS_INVALID_DATA should be reported;

And it MUST not return NULL if all arguments are
valid and the geometry is not empty.

F-2: ST_Buffer receives a geometry and a distance value(of double type) as the
1st and 2nd parameter respectively, and returns a GEOMETRY byte string which is
a polygon or multipolygon and which is the buffer of the geometry.

F-3: Given a geometry collection, its buffer should be computed this way:
Firstly its components' buffers are computed, then the [multi]polygons are 
merged into the final multipolygon.

F-4: The distance argument for ST_Buffer can be positive or zero, and if the
geometry is a polygon or multipolygon, it can also be negative, i.e. the polygon
or multipolygon is eroded/deflated to a specified distance as result. 

If the distance is zero, the geometry MUST be returned as is without any
computation done; 

If the distance is negative but the geometry is not a polygon or multipolygon, 
the ST_Buffer MUST report ER_WRONG_ARGUMENTS error and return NULL.

If the geometry is empty, ST_Buffer should return the empty geometry as result.

F-5: If a negative distance value is specified for a [multi]polygon and the
resulting eroded/deflated [multi]polygon is gone, an empty geometry is returned.
ST_Buffer MUST never return a [multi]point or [multi]linestring in any case.

F-6: ST_Buffer allows specifying strategies optionally using
ST_Buffer_Strategy() function, in order to compute the buffer in various ways.
ST_Buffer MUST return NULL if any of the option arguments is invalid or NULL.

Available strategy categories and strategy options in each category(bracketed) are: 
	point strategies(point round, point square)
	join strategy(join round, join miter)
	end strategy(end round, end flat)

F-7: ST_Buffer_Strategy function accepts one or two arguments and returns one
strategy option as a byte string with the strategy setting encoded. It MUST
return NULL if any argument is NULL, or any of the arguments is not valid;
it MUST not return NULL if all arguments are valid.

F-8: The first argument of ST_Buffer_Strategy MUST be one of these strategy
options in strings(case insensitive): "point_circle", "point_square",
"join_round", "join_miter", "end_round", "end_flat", otherwise
ER_WRONG_ARGUMENTS is raised and NULL returned.

F-9: If the 1st argument for ST_Buffer_Strategy is one these strategy options:
"point_circle", "join_round", "end_round", and "join_miter", ST_Buffer_Strategy
requires a 2nd argument called 'points_per_circle' which must be a positive 
numeric value.

In case of lack of arguments or argument range mismatch, ER_WRONG_ARGUMENTS 
is raised and NULL returned.

F-10: If the 1st argument for ST_Buffer_Strategy is one of these strategy
options: "point_square" and "end_flat", no more arguments can be specified to
ST_Buffer_Strategy otherwise it returns NULL and reports ER_WRONG_ARGUMENTS.

F-11: Each category of strategy applies to certain types of geometries, if a
strategy option of a strategy category is specified to a geometry that it can't
be applied to, ST_Buffer MUST report ER_WRONG_ARGUMENTS error and return NULL.
	point strategy: applies to [multi]point
	join strategy: applies to [multi]linestring, [multi]polygon
	end strategy: applies to [multi]linestring

F-12: the user may optionally specify any of the three strategy categories by 
calling ST_Buffer_Strategy. Each strategy category must be specified at most once, 
otherwise ER_WRONG_ARGUMENTS is reported and NULL is returned. 
But different strategy categories may be mixed and provided to ST_Buffer in any

F-13: If no strategy option is specified into ST_Buffer for a category, its
system wide global fixed default option is used. 
The default options for each category are defined as:

point strategies --- "point_circle" with 'points_per_circle' = 32;
join strategy --- "join_round" with 'points_per_circle' = 32;
end strategy --- "end_round" with 'points_per_circle' = 32.

F-14: The SRID of the geometry argument of ST_Buffer must be 0, because only cartessian coordinate system is supported by boost::geometry::buffer currently.

F-15: ST_Buffer's 3rd and more arguments must be valid buffer strategy values produced by valid ST_Buffer_Strategy calls, otherwise ER_WRONG_ARGUMENTS should be reported.

F-16: Replace the remaining ST_distance code which used old GIS algorithm with
Boost Geometry. The syntax of st_distance MUST NOT change.

Changes to the interface specification:

I-1: No new files.

I-2: New syntax: 

1. One new function:

          = ST_Buffer_Strategy( [, ])
2. One function with extended interface (0 to 3 optional arguments)
          = ST_Buffer(,  [, [,
[,] ] ])

Here the  is the  returned by the ST_Buffer_Strategy()
function call.

The old interface of ST_Buffer still works because the change of the ST_Buffer
interface is adding 3 optional strategy arguments, when non added, ST_Buffer is
used like before, however the behavior in this case may not be exactly the same
as the old GIS algorithm, this is determined by the BG algorithm and our default

Note that the removal of ST_GIS_DEBUG is NOT an interface change because this
function is only used internally and is only effective in debug builds, and it's
not publicly known and not documented. 

I-3: No new commands.

I-4: No new tools.

I-5: No impact on existing functionality.