# WL#14126: Ellipsoidal ST_Buffer of point

ST_Buffer currently only supports computations in Cartesian spatial reference systems (SRSs). This WL extends ST_Buffer to detect that its parameter is in a geographic (ellipsoidal) SRS and to compute the buffer on the ellipsoid. Ellipsoidal buffer is only implemented for points.

Buffers in projected SRSs and SRID 0 will still return the same result as before. If the geometry is a point and the SRID refers to a geographic SRS, the function will now return a value instead of raising an error.

The function ST_Buffer(geometry, distance[, strategy1[, strategy2[, strategy3]]]) returns a geometry representing all points within a specified distance from any point of a geometry using the specified strategies, or the default strategies if none are specified.

## General requirements

- F-1
- The function MUST return NULL if any of its arguments are NULL.
- F-2
- If the geometry argument is not a syntactically well-formed geometry, the function MUST raise ER_GIS_INVALID_DATA during function evaluation.
- F-3
- If the geometry argument is a well-formed geometry in an undefined SRS, the function MUST raise ER_SRS_NOT_FOUND during function evaluation.

## Cartesian buffers

This section is intended to describe the existing behavior for buffer in Cartesian SRSs. It is not intended to change existing behavior.

- F-4a
- If the geometry argument is a well-formed but geometrically invalid geometry in a Cartesian SRS, the function MUST either return a geometry result or raise an error. If a geometry is returned, the value is undefined, i.e. it may be any geometry. The returned value may also be geometrically invalid. The result MUST be in the same SRS as the geometry argument.
- F-4b
- If the geometry argument is a well-formed geometry that is an empty geometry collection (which is currently the only supported empty geometry) in a Cartesian SRS, the function MUST return an empty geometrycollection. (Note: This is nonstandard behavior kept for backward compatibility. SQL/MM specifies that the return value must be NULL.) The result MUST be in the same SRS as the geometry argument.
- F-4c
- If the geometry argument is a well-formed, valid and non-empty geometry in a Cartesian SRS, the distance is positive and the buffer strategies are valid (see req. F-4f), the function MUST return the Cartesian buffer of the geometry. The distance argument MUST be in the SRS distance unit (unspecified if SRID 0). The result MUST be in the same SRS as the geometry argument.
- F-4d
- If the geometry argument is a well-formed, valid and non-empty geometry in a Cartesian SRS
*not*containing any points, linestrings, multipoints or multilinestrings, the distance is negative and the buffer strategies are valid (see req F-4f), the function MUST return the Cartesian buffer of the geometry. The result MUST be in the same SRS as the geometry argument. The result is a geometry that has been shrunk by the specified distance. If the geometry is reduced so much that it disappears, the result becomes an empty geometrycollection. - F-4e
- If the geometry argument is a well-formed, valid and non-empty geometry in a Cartesian SRS containing any points, linestrings, multipoints or multilinestrings, and the distance is negative, the function MUST raise ER_WRONG_ARGUMENTS.
- F-4f
- If the geometry argument is a well-formed geometry in a Cartesian SRS and the buffer strategies are invalid, the function MUST raise ER_WRONG_ARGUMENTS during function evaluation. Invalid buffer strategies occur 1) when two or more strategies of the same type (point, join or end) are specified in the same call to ST_Buffer, 2) when a value that is not a strategy (e.g., an arbitrary binary string or a number) is passed as a strategy argument, 3) when a point strategy is passed and the geometry doesn't contain any points or multipoints, or 4) when an end or join strategy is passed and the geometry doesn't contain any linestrings, polygons, multilinestrings or multipolygons.

## Geographic buffers

- F-5a
- If the geometry argument is a well-formed point in a geographic SRS, the distance argument is not negative and no strategies are specified, the function MUST return the geographic buffer of the point in that SRS. The distance argument MUST be in the SRS distance unit (currently always meters). The result MUST be in the same SRS as the geometry argument.
- F-5b
- If the geometry argument is a well-formed point (points are always geometrically valid) in a geographic SRS and the distance is negative or any strategy (except NULL, see req. F-1) is specified, the function MUST raise ER_WRONG_ARGUMENTS during function evaluation.
- F-5c
- If the geometry argument is a well-formed non-point geometry in a geographic SRS, the function MUST raise ER_NOT_IMPLEMENTED_FOR_GEOGRAPHIC_SRS during function evaluation.
- F-5d
- If the geometry argument is a geometry in a geographic SRS and a longitude value is not in the range (-180,180] (in degrees -- other limits in other units), the function MUST raise ER_GEOMETRY_PARAM_LONGITUDE_OUT_OF_RANGE. (*)
- F-5e
- If the geometry argument is a geometry in a geographic SRS and a latitude value is not in the range [-90,90] (in degrees -- other limits in other units), the function MUST raise ER_GEOMETRY_PARAM_LATITUDE_OUT_OF_RANGE. (*)

(*) The exact limits will deviate slightly because of floating point arithmetics.

- I-1
- No new syntax.
- I-2
- The semantics of interface SQL01 are changed: If the geometry is a point in a geographic SRS, ST_Buffer will return a polygon (or point if the distance is 0). Other calculations will remain as they are today.
- I-3
- No new errors.
- I-4
- No new warnings.

The old implementation of ST_Buffer depends on the deprecated (Cartesian only) old geometry data types. This WL reimplements ST_Buffer from scratch based on the gis::Geometry type hierarchy.

## Item_func_st_buffer

The Item_func_st_buffer class implements the SQL level ST_Buffer function.

The SQL level function interface is tested by an MTR test in mysql-test/suite/gis/t/st_buffer.test.

## gis::buffer and gis::Buffer

The gis::Buffer functor (sql/gis/buffer_functor.{h,cc}) and gis::buffer function (sql/gis/buffer.{h,cc}) implement the interface to the Boost Geometry buffer function. The functor may throw exceptions, while the function is declared nothrow and will wrap the functor in try-catch and translate exceptions to my_error calls.

The function is unit tested by tests in unittest/gunit/gis_buffer-t.cc. These tests handle boundary testing that don't affect the SQL level interface.

## Cleanup

The old function implementation in sql/item_geofunc_buffer.cc and related files is removed by this WL.