### ----------------------------------------------------
### -- GEOS
### -- Licenses: MIT
### -- Authors: Brian Duggan
### -- File: lib/GEOS/Native.rakumod
### ----------------------------------------------------
### -- Chunk 1 of 4
unit module GEOS::Native;

=begin pod

=head1 NAME

GEOS - Native bindings to the GEOS library

=head1 SYNOPSIS

Read a WKT string and write it as GeoJSON:

    use GEOS::Native;

    my $wkt = "POINT(1 1)";
    my $ctx = GEOS_init_r();
    my $reader = GEOSWKTReader_create_r($ctx);
    my $geom = GEOSWKTReader_read_r($ctx, $reader, $wkt);
    my $geojson-writer = GEOSGeoJSONWriter_create_r($ctx);
    say GEOSGeoJSONWriter_writeGeometry_r($ctx, $geojson-writer, $geom, 1);

    # {
    #  "type": "Point",
    #  "coordinates": [
    #   1.0,
    #   1.0
    #  ]
    # }

Create two squares and calculate their intersection:

    use GEOS::Native;

    my $context = GEOS_init_r();
    my $reader = GEOSWKTReader_create_r($context);
    my $writer = GEOSWKTWriter_create_r($context);

    my $square1 = GEOSWKTReader_read_r($context, $reader, 'POLYGON((0 0, 2 0, 2 2, 0 2, 0 0))');
    my $square2 = GEOSWKTReader_read_r($context, $reader, 'POLYGON((1 1, 3 1, 3 3, 1 3, 1 1))');

    my $intersection = GEOSIntersection_r($context, $square1, $square2);
    say GEOSWKTWriter_write_r($context, $writer, $intersection);
    # POLYGON ((2 2, 2 1, 1 1, 1 2, 2 2))

    for $square1, $square2, $intersection -> $geom {
        GEOSGeom_destroy_r($context, $geom);
    }

    GEOSWKTReader_destroy_r($context, $reader);
    GEOSWKTWriter_destroy_r($context, $writer);

    GEOS_finish_r($context);


=head1 DESCRIPTION

This module provides native bindings to libgeos: https://libgeos.org

The status of this module is EXPERIMENTAL. Everything may change, and some things might not work. Consult the test suite to see what is currently implemented.

The main focus is on the thread-safe functions (ending in `_r`, and requiring a context object).

Note that using the native bindings directly requires careful attention to memory management.

=head1 AUTHOR

Brian Duggan

Claude

=end pod

use NativeCall;

constant GEOS = 'geos_c';

# Opaque types
class GEOSContextHandle is repr('CPointer') is export { }
class GEOSGeometry is repr('CPointer') is export { }
class GEOSPreparedGeometry is repr('CPointer') is export { }
class GEOSWKTReader is repr('CPointer') is export { }
class GEOSWKTWriter is repr('CPointer') is export { }
class GEOSCoordSequence is repr('CPointer') is export { }
class GEOSStrTree is repr('CPointer') is export { }
class GEOSQueryCallback is repr('CPointer') is export { }
class GEOSDistanceCallback is repr('CPointer') is export { }
class GEOSMakeValidParams is repr('CPointer') is export { }
class GEOSTransformXYCallback is repr('CPointer') is export { }
class GEOSTransformXYZCallback is repr('CPointer') is export { }

# Message handler callback type
sub dummy_handler(Str) returns Pointer is export { Pointer }

class X::GEOS::Error is Exception {
    has $.message;
    method message() { "GEOS Error: $!message" }
}

sub GEOSContext_setNoticeHandler_r( GEOSContextHandle, &handler (Str)) returns Pointer is native(GEOS) is export { * }
sub GEOSContext_setErrorHandler_r( GEOSContextHandle, &handler (Str)) returns Pointer is native(GEOS) is export { * }
sub GEOSWKTReader_create_r(GEOSContextHandle) returns GEOSWKTReader is native(GEOS) is export { * }
sub GEOSWKTReader_read_r( GEOSContextHandle, GEOSWKTReader, Str) returns GEOSGeometry is native(GEOS) is export { * }
sub GEOSWKTReader_destroy_r(GEOSContextHandle, GEOSWKTReader) is native(GEOS) is export { * }
sub GEOSWKTWriter_create_r(GEOSContextHandle) returns GEOSWKTWriter is native(GEOS) is export { * }
sub GEOSWKTWriter_write_r( GEOSContextHandle, GEOSWKTWriter, GEOSGeometry) returns Str is native(GEOS) is export { * }
sub GEOSWKTWriter_destroy_r(GEOSContextHandle, GEOSWKTWriter) is native(GEOS) is export { * }

sub GEOSGeom_destroy_r(GEOSContextHandle, GEOSGeometry) is native(GEOS) is export { * }
sub GEOSFree_r(GEOSContextHandle, Pointer) is native(GEOS) is export { * }

enum GEOSGeomTypes is export (
    GEOS_POINT => 0,
    GEOS_LINESTRING => 1,
    GEOS_LINEARRING => 2,
    GEOS_POLYGON => 3,
    GEOS_MULTIPOINT => 4,
    GEOS_MULTILINESTRING => 5,
    GEOS_MULTIPOLYGON => 6,
    GEOS_GEOMETRYCOLLECTION => 7,
    GEOS_CIRCULARSTRING => 8,
    GEOS_COMPOUNDCURVE => 9,
    GEOS_CURVEPOLYGON => 10,
    GEOS_MULTICURVE => 11,
    GEOS_MULTISURFACE => 12,
); 
# /**
# * Well-known binary byte orders used when
# * writing to WKB.
# *
# * \see GEOSWKBWriter_setByteOrder
# */
# enum GEOSWKBByteOrders {
#     /** Big Endian */
#     GEOS_WKB_XDR = 0,
#     /** Little Endian */
#     GEOS_WKB_NDR = 1
# };
enum GEOSWKBByteOrders is export (
    GEOS_WKB_XDR => 0,
    GEOS_WKB_NDR => 1,
); 
# /**
# * Well-known binary flavors to use
# * when writing to WKB. ISO flavour is
# * more standard. Extended flavour supports
# * 3D and SRID embedding. GEOS reads both
# * transparently.
# *
# * \see GEOSWKBWriter_setFlavor
# */
# enum GEOSWKBFlavors {
#     /** Extended */
#     GEOS_WKB_EXTENDED = 1,
#     /** ISO */
#     GEOS_WKB_ISO = 2
# };
enum GEOSWKBFlavors is export (
    GEOS_WKB_EXTENDED => 0,
    GEOS_WKB_ISO => 1,
);

# /**
# * Callback function for use in spatial index search calls. Pass into
# * the query function and handle query results as the index
# * returns them.
# *
# * \see GEOSSTRtree_query
# */
# typedef void (*GEOSQueryCallback)(void *item, void *userdata);
sub GEOSQueryCallback(Pointer, Pointer) is export { * }

# /**
# * Callback function for use in spatial index nearest neighbor calculations.
# * Allows custom distance to be calculated between items in the
# * index. Is passed two items, and sets the calculated distance
# * between the items into the distance pointer. Extra data for the
# * calculation can be passed via the userdata.
# *
# * \param item1 first of the pair of items to calculate distance between
# * \param item2 second of the pair of items to calculate distance between
# * \param distance the distance between the items here
# * \param userdata extra data for the calculation
# *
# * \return 1 if distance calculation succeeds, 0 otherwise
# *
# * \see GEOSSTRtree_nearest_generic
# * \see GEOSSTRtree_iterate
# */
# typedef int (*GEOSDistanceCallback)(
#     const void* item1,
#     const void* item2,
#     double* distance,
#     void* userdata);
sub GEOSDistanceCallback(Pointer, Pointer, num64, Pointer) is export { * }

# 
# /**
# * Callback function for use in GEOSGeom_transformXY.
# * Allows custom function to be applied to x and y values for each coordinate
# * in a geometry.  Z and M values are unchanged by this function.
# * Extra data for the calculation can be passed via the userdata.
# *
# * \param x coordinate value to be updated
# * \param y coordinate value to be updated
# * \param userdata extra data for the calculation
# *
# * \return 1 if calculation succeeded, 0 on failure
# */
# typedef int (*GEOSTransformXYCallback)(
#     double* x,
#     double* y,
#     void* userdata);
sub GEOSTransformXYCallback(Pointer, Pointer, Pointer) is export { * } 
 
# /**
# * Callback function for use in GEOSGeom_transformXYZ.
# * Allows custom function to be applied to x, y and z values for each coordinate
# * in a geometry.  M values are unchanged by this function.
# * Extra data for the calculation can be passed via the userdata.
# *
# * \param x coordinate value to be updated
# * \param y coordinate value to be updated
# * \param z coordinate value to be updated
# * \param userdata extra data for the calculation
# *
# * \return 1 if calculation succeeded, 0 on failure
# */
# typedef int (*GEOSTransformXYZCallback)(
#     double* x,
#     double* y,
#     double* z,
#     void* userdata);
sub GEOSTransformXYZCallback(Pointer, Pointer, Pointer, Pointer) is export { * } 
 
# /* ========== Interruption ========== */
# 
# /**
# * Callback function for use in interruption. The callback will be invoked _before_ checking for
# * interruption, so can be used to request it.
# *
# * \see GEOS_interruptRegisterCallback
# * \see GEOS_interruptRequest
# * \see GEOS_interruptCancel
# */
# typedef void (GEOSInterruptCallback)(void);
sub GEOSInterruptCallback() is export { * } 

# /**
# * Register a function to be called when processing is interrupted.
# * \param cb Callback function to invoke
# * \return the previously configured callback
# * \see GEOSInterruptCallback
# * \since 3.4
# */
# extern GEOSInterruptCallback GEOS_DLL *GEOS_interruptRegisterCallback(
#     GEOSInterruptCallback* cb);
sub GEOS_interruptRegisterCallback(&handler ()) returns Pointer is native(GEOS) is export { * } 

# /**
# * Request safe interruption of operations
# * \since 3.4
# */
# extern void GEOS_DLL GEOS_interruptRequest(void);
sub GEOS_interruptRequest() is native(GEOS) is export { * } 

# /**
# * Cancel a pending interruption request
# * \since 3.4
# */
# extern void GEOS_DLL GEOS_interruptCancel(void);
sub GEOS_interruptCancel() is native(GEOS) is export { * } 

# /* ========== Initialization and Cleanup ========== */
# 
# /**
# * Allocate and initialize a context. Pass this context as the first argument
# * when calling other `*_r` functions. Contexts must only be used from a single
# * thread at a time.
# * \return a new GEOS context.
# *
# * \since 3.5
# */
# extern GEOSContextHandle_t GEOS_DLL GEOS_init_r(void);
sub GEOS_init_r() returns GEOSContextHandle is native(GEOS) is export { * } 

# /**
# * Free the memory associated with a \ref GEOSContextHandle_t
# * when you are finished calling GEOS functions.
# * \param handle to be freed
# *
# * \since 3.5
# */
# extern void GEOS_DLL GEOS_finish_r(GEOSContextHandle_t handle);

sub GEOS_finish_r(GEOSContextHandle) is native(GEOS) is export { * }

# extern GEOSMessageHandler_r GEOS_DLL GEOSContext_setNoticeMessageHandler_r(
#     GEOSContextHandle_t extHandle,
#     GEOSMessageHandler_r nf,
#     void *userData);
sub GEOSContext_setNoticeMessageHandler_r(GEOSContextHandle, &handler (Str), Pointer) returns Pointer is native(GEOS) is export { * }

# extern GEOSMessageHandler_r GEOS_DLL GEOSContext_setErrorMessageHandler_r(
#     GEOSContextHandle_t extHandle,
#     GEOSMessageHandler_r ef,
#     void *userData);
sub GEOSContext_setErrorMessageHandler_r(GEOSContextHandle, &handler (Str), Pointer) returns Pointer is native(GEOS) is export { * } 

# /* ========== Coordinate Sequence functions ========== */
# 
# /** \see GEOSCoordSeq_create */
# extern GEOSCoordSequence GEOS_DLL *GEOSCoordSeq_create_r(
#     GEOSContextHandle_t handle,
#     unsigned int size,
#     unsigned int dims);
sub GEOSCoordSeq_create_r(GEOSContextHandle, uint32, uint32) returns Pointer is native(GEOS) is export { * } 

# /** \see GEOSCoordSeq_copyFromBuffer */
# extern GEOSCoordSequence GEOS_DLL *GEOSCoordSeq_copyFromBuffer_r(
#         GEOSContextHandle_t handle,
#         const double* buf,
#         unsigned int size,
#         int hasZ,
#         int hasM);
sub GEOSCoordSeq_copyFromBuffer_r(GEOSContextHandle, Pointer, uint32, int32, int32) returns Pointer is native(GEOS) is export { * }

# /** \see GEOSCoordSeq_copyFromArrays */
# extern GEOSCoordSequence GEOS_DLL *GEOSCoordSeq_copyFromArrays_r(
#         GEOSContextHandle_t handle,
#         const double* x,
#         const double* y,
#         const double* z,
#         const double* m,
#         unsigned int size);
sub GEOSCoordSeq_copyFromArrays_r(GEOSContextHandle, Pointer, Pointer, Pointer, Pointer, uint32) returns Pointer is native(GEOS) is export { * }

# /** \see GEOSCoordSeq_copyToBuffer */
# extern int GEOS_DLL GEOSCoordSeq_copyToBuffer_r(
#         GEOSContextHandle_t handle,
#         const GEOSCoordSequence* s,
#         double* buf,
#         int hasZ,
#         int hasM);
sub GEOSCoordSeq_copyToBuffer_r(GEOSContextHandle, Pointer, Pointer, int32, int32) returns int32 is native(GEOS) is export { * } 

# /** \see GEOSCoordSeq_copyToArrays */
# extern int GEOS_DLL GEOSCoordSeq_copyToArrays_r(
#         GEOSContextHandle_t handle,
#         const GEOSCoordSequence* s,
#         double* x,
#         double* y,
#         double* z,
#         double* m);
sub GEOSCoordSeq_copyToArrays_r(GEOSContextHandle, Pointer, Pointer, Pointer, Pointer, Pointer) returns int32 is native(GEOS) is export { * } 

# /** \see GEOSCoordSeq_clone */
# extern GEOSCoordSequence GEOS_DLL *GEOSCoordSeq_clone_r(
#     GEOSContextHandle_t handle,
#     const GEOSCoordSequence* s);
sub GEOSCoordSeq_clone_r(GEOSContextHandle, Pointer) returns Pointer is native(GEOS) is export { * } 

# /** \see GEOSCoordSeq_destroy */
# extern void GEOS_DLL GEOSCoordSeq_destroy_r(
#     GEOSContextHandle_t handle,
#     GEOSCoordSequence* s);
sub GEOSCoordSeq_destroy_r(GEOSContextHandle, Pointer) is native(GEOS) is export { * } 

# /** \see GEOSCoordSeq_setX */
# extern int GEOS_DLL GEOSCoordSeq_setX_r(
#     GEOSContextHandle_t handle,
#     GEOSCoordSequence* s, unsigned int idx,
#     double val);
sub GEOSCoordSeq_setX_r(GEOSContextHandle, Pointer, uint32, num64) returns int32 is native(GEOS) is export { * } 

# /** \see GEOSCoordSeq_setY */
# extern int GEOS_DLL GEOSCoordSeq_setY_r(
#     GEOSContextHandle_t handle,
#     GEOSCoordSequence* s, unsigned int idx,
#     double val);
sub GEOSCoordSeq_setY_r(GEOSContextHandle, Pointer, uint32, num64) returns int32 is native(GEOS) is export { * } 

# /** \see GEOSCoordSeq_setZ */
# extern int GEOS_DLL GEOSCoordSeq_setZ_r(
#     GEOSContextHandle_t handle,
#     GEOSCoordSequence* s, unsigned int idx,
#     double val);
sub GEOSCoordSeq_setZ_r(GEOSContextHandle, Pointer, uint32, num64) returns int32 is native(GEOS) is export { * } 

# /** \see GEOSCoordSeq_setXY */
# extern int GEOS_DLL GEOSCoordSeq_setXY_r(
#     GEOSContextHandle_t handle,
#     GEOSCoordSequence* s, unsigned int idx,
#     double x, double y);
sub GEOSCoordSeq_setXY_r(GEOSContextHandle, Pointer, uint32, num64, num64) returns int32 is native(GEOS) is export { * } 

# /** \see GEOSCoordSeq_setXYZ */
# extern int GEOS_DLL GEOSCoordSeq_setXYZ_r(
#     GEOSContextHandle_t handle,
#     GEOSCoordSequence* s, unsigned int idx,
#     double x, double y, double z);
sub GEOSCoordSeq_setXYZ_r(GEOSContextHandle, Pointer, uint32, num64, num64, num64) returns int32 is native(GEOS) is export { * } 

# /** \see GEOSCoordSeq_setOrdinate */
# extern int GEOS_DLL GEOSCoordSeq_setOrdinate_r(
#     GEOSContextHandle_t handle,
#     GEOSCoordSequence* s,
#     unsigned int idx,
#     unsigned int dim, double val);
sub GEOSCoordSeq_setOrdinate_r(GEOSContextHandle, Pointer, uint32, uint32, num64) returns int32 is native(GEOS) is export { * } 

# /** \see GEOSCoordSeq_getX */
# extern int GEOS_DLL GEOSCoordSeq_getX_r(
#     GEOSContextHandle_t handle,
#     const GEOSCoordSequence* s,
#     unsigned int idx, double *val);
sub GEOSCoordSeq_getX_r(GEOSContextHandle, Pointer, uint32, num64 is rw) returns int32 is native(GEOS) is export { * } 

# /** \see GEOSCoordSeq_getY */
# extern int GEOS_DLL GEOSCoordSeq_getY_r(
#     GEOSContextHandle_t handle,
#     const GEOSCoordSequence* s,
#     unsigned int idx, double *val);
sub GEOSCoordSeq_getY_r(GEOSContextHandle, Pointer, uint32, num64 is rw) returns int32 is native(GEOS) is export { * } 

# /** \see GEOSCoordSeq_getZ */
# extern int GEOS_DLL GEOSCoordSeq_getZ_r(
#     GEOSContextHandle_t handle,
#     const GEOSCoordSequence* s,
#     unsigned int idx, double *val);
sub GEOSCoordSeq_getZ_r(GEOSContextHandle, Pointer, uint32, num64 is rw) returns int32 is native(GEOS) is export { * } 

# /** \see GEOSCoordSeq_getXY */
# extern int GEOS_DLL GEOSCoordSeq_getXY_r(
#     GEOSContextHandle_t handle,
#     const GEOSCoordSequence* s,
#     unsigned int idx,
#     double *x, double *y);
sub GEOSCoordSeq_getXY_r(GEOSContextHandle, Pointer, uint32, Pointer, Pointer) returns int32 is native(GEOS) is export { * }

# /** \see GEOSCoordSeq_getXYZ */
# extern int GEOS_DLL GEOSCoordSeq_getXYZ_r(
#     GEOSContextHandle_t handle,
#     const GEOSCoordSequence* s,
#     unsigned int idx,
#     double *x, double *y, double *z);
sub GEOSCoordSeq_getXYZ_r(GEOSContextHandle, Pointer, uint32, Pointer, Pointer, Pointer) returns int32 is native(GEOS) is export { * }

# /** \see GEOSCoordSeq_getOrdinate */
# extern int GEOS_DLL GEOSCoordSeq_getOrdinate_r(
#     GEOSContextHandle_t handle,
#     const GEOSCoordSequence* s,
#     unsigned int idx,
#     unsigned int dim, double *val);
sub GEOSCoordSeq_getOrdinate_r(GEOSContextHandle, Pointer, uint32, uint32, Pointer) returns int32 is native(GEOS) is export { * } 

# /** \see GEOSCoordSeq_getSize */
# extern int GEOS_DLL GEOSCoordSeq_getSize_r(
#     GEOSContextHandle_t handle,
#     const GEOSCoordSequence* s,
#     unsigned int *size);
sub GEOSCoordSeq_getSize_r(GEOSContextHandle, Pointer, uint32 is rw) returns int32 is native(GEOS) is export { * } 

# /** \see GEOSCoordSeq_getDimensions */
# extern int GEOS_DLL GEOSCoordSeq_getDimensions_r(
#     GEOSContextHandle_t handle,
#     const GEOSCoordSequence* s,
#     unsigned int *dims);
sub GEOSCoordSeq_getDimensions_r(GEOSContextHandle, Pointer, Pointer) returns int32 is native(GEOS) is export { * } 

# /** \see GEOSCoordSeq_isCCW */
# extern int GEOS_DLL GEOSCoordSeq_isCCW_r(
#     GEOSContextHandle_t handle,
#     const GEOSCoordSequence* s,
#     char* is_ccw);
sub GEOSCoordSeq_isCCW_r(GEOSContextHandle, Pointer, Str) returns int32 is native(GEOS) is export { * } 

# /* ========= Linear referencing functions ========= */
# 
# /** \see GEOSProject */
# extern double GEOS_DLL GEOSProject_r(
#     GEOSContextHandle_t handle,
#     const GEOSGeometry *line,
#     const GEOSGeometry *point);
sub GEOSProject_r(GEOSContextHandle, GEOSGeometry, GEOSGeometry) returns num64 is native(GEOS) is export { * } 

# /** \see GEOSInterpolate */
# extern GEOSGeometry GEOS_DLL *GEOSInterpolate_r(
#     GEOSContextHandle_t handle,
#     const GEOSGeometry *line,
#     double d);
sub GEOSInterpolate_r(GEOSContextHandle, GEOSGeometry, num64) returns GEOSGeometry is native(GEOS) is export { * } 

# /** \see GEOSProjectNormalized */
# extern double GEOS_DLL GEOSProjectNormalized_r(
#     GEOSContextHandle_t handle,
#     const GEOSGeometry *g,
#     const GEOSGeometry *p);
sub GEOSProjectNormalized_r(GEOSContextHandle, GEOSGeometry, GEOSGeometry) returns num64 is native(GEOS) is export { * } 

# /** \see GEOSInterpolateNormalized */
# extern GEOSGeometry GEOS_DLL *GEOSInterpolateNormalized_r(
#     GEOSContextHandle_t handle,
#     const GEOSGeometry *g,
#     double d);
sub GEOSInterpolateNormalized_r(GEOSContextHandle, GEOSGeometry, num64) returns GEOSGeometry is native(GEOS) is export { * } 

# /* ========== Buffer related functions ========== */
# 
# /** \see GEOSBuffer */
# extern GEOSGeometry GEOS_DLL *GEOSBuffer_r(
#     GEOSContextHandle_t handle,
#     const GEOSGeometry* g,
#     double width, int quadsegs);
sub GEOSBuffer_r(GEOSContextHandle, GEOSGeometry, num64, int32) returns GEOSGeometry is native(GEOS) is export { * } 

# /**
# * Cap styles control the ends of buffered lines.
# * \see GEOSBuffer
# */
# enum GEOSBufCapStyles {
# 
#     /** End is rounded, with end point of original line in the centre of the round cap. */
# 	GEOSBUF_CAP_ROUND = 1,
# 
#     /** End is flat, with end point of original line at the end of the buffer */
# 	GEOSBUF_CAP_FLAT = 2,
# 
#     /** End is flat, with end point of original line in the middle of a square enclosing that point */
# 	GEOSBUF_CAP_SQUARE = 3
# };
enum GEOSBufCapStyles is export (
    GEOSBUF_CAP_ROUND => 1,
    GEOSBUF_CAP_FLAT => 2,
    GEOSBUF_CAP_SQUARE => 3,
); 

# /**
# * Join styles control the buffer shape at bends in a line.
# * \see GEOSBuffer
# */
# enum GEOSBufJoinStyles {
#     /**
#     * Join is rounded, essentially each line is terminated
#     * in a round cap. Form round corner.
#     */
# 	GEOSBUF_JOIN_ROUND = 1,
#     /**
#     * Join is flat, with line between buffer edges,
#     * through the join point. Forms flat corner.
#     */
# 	GEOSBUF_JOIN_MITRE = 2,
#     /**
#     * Join is the point at which the two buffer edges intersect.
#     * Forms sharp corner.
#     */
# 	GEOSBUF_JOIN_BEVEL = 3
# };
enum GEOSBufJoinStyles is export (
    GEOSBUF_JOIN_ROUND => 1,
    GEOSBUF_JOIN_MITRE => 2,
    GEOSBUF_JOIN_BEVEL => 3,
); 

# /** \see GEOSBufferParams_create */
# extern GEOSBufferParams GEOS_DLL *GEOSBufferParams_create_r(
#     GEOSContextHandle_t handle);
sub GEOSBufferParams_create_r(GEOSContextHandle) returns Pointer is native(GEOS) is export { * } 

# /** \see GEOSBufferParams_destroy */
# extern void GEOS_DLL GEOSBufferParams_destroy_r(
#     GEOSContextHandle_t handle,
#     GEOSBufferParams* parms);
sub GEOSBufferParams_destroy_r(GEOSContextHandle, Pointer) is native(GEOS) is export { * } 

# /** \see GEOSBufferParams_setEndCapStyle */
# extern int GEOS_DLL GEOSBufferParams_setEndCapStyle_r(
#     GEOSContextHandle_t handle,
#     GEOSBufferParams* p,
#     int style);
sub GEOSBufferParams_setEndCapStyle_r(GEOSContextHandle, Pointer, int32) returns int32 is native(GEOS) is export { * } 

# /** \see GEOSBufferParams_setJoinStyle */
# extern int GEOS_DLL GEOSBufferParams_setJoinStyle_r(
#     GEOSContextHandle_t handle,
#     GEOSBufferParams* p,
#     int joinStyle);
sub GEOSBufferParams_setJoinStyle_r(GEOSContextHandle, Pointer, int32) returns int32 is native(GEOS) is export { * } 

# /** \see GEOSBufferParams_setMitreLimit */
# extern int GEOS_DLL GEOSBufferParams_setMitreLimit_r(
#     GEOSContextHandle_t handle,
#     GEOSBufferParams* p,
#     double mitreLimit);
sub GEOSBufferParams_setMitreLimit_r(GEOSContextHandle, Pointer, num64) returns int32 is native(GEOS) is export { * } 

# /** \see GEOSBufferParams_setQuadrantSegments */
# extern int GEOS_DLL GEOSBufferParams_setQuadrantSegments_r(
#     GEOSContextHandle_t handle,
#     GEOSBufferParams* p,
#     int quadSegs);
sub GEOSBufferParams_setQuadrantSegments_r(GEOSContextHandle, Pointer, int32) returns int32 is native(GEOS) is export { * } 

# /** \see GEOSBufferParams_setSingleSided */
# extern int GEOS_DLL GEOSBufferParams_setSingleSided_r(
#     GEOSContextHandle_t handle,
#     GEOSBufferParams* p,
#     int singleSided);
sub GEOSBufferParams_setSingleSided_r(GEOSContextHandle, Pointer, int32) returns int32 is native(GEOS) is export { * } 

# /** \see GEOSBufferWithParams */
# extern GEOSGeometry GEOS_DLL *GEOSBufferWithParams_r(
#     GEOSContextHandle_t handle,
#     const GEOSGeometry* g,
#     const GEOSBufferParams* p,
#     double width);
sub GEOSBufferWithParams_r(GEOSContextHandle, GEOSGeometry, Pointer, num64) returns GEOSGeometry is native(GEOS) is export { * } 

# /** \see GEOSBufferWithStyle */
# extern GEOSGeometry GEOS_DLL *GEOSBufferWithStyle_r(
#     GEOSContextHandle_t handle,
# 	const GEOSGeometry* g,
#     double width, int quadsegs, int endCapStyle,
# 	int joinStyle, double mitreLimit);
sub GEOSBufferWithStyle_r(GEOSContextHandle, GEOSGeometry, num64, int32, int32, int32, num64) returns GEOSGeometry is native(GEOS) is export { * } 

# /** \see GEOSDensify */
# extern GEOSGeometry GEOS_DLL *GEOSDensify_r(
#     GEOSContextHandle_t handle,
# 	const GEOSGeometry* g,
#     double tolerance);
sub GEOSDensify_r(GEOSContextHandle, GEOSGeometry, num64) returns GEOSGeometry is native(GEOS) is export { * } 

# /** \see GEOSOffsetCurve */
# extern GEOSGeometry GEOS_DLL *GEOSOffsetCurve_r(
#     GEOSContextHandle_t handle,
# 	const GEOSGeometry* g, double width, int quadsegs,
# 	int joinStyle, double mitreLimit);
sub GEOSOffsetCurve_r(GEOSContextHandle, GEOSGeometry, num64, int32, int32, num64) returns GEOSGeometry is native(GEOS) is export { * } 

# /* ========= Geometry Constructors ========= */
# 
# /** \see GEOSGeom_createPoint */
# extern GEOSGeometry GEOS_DLL *GEOSGeom_createPoint_r(
#     GEOSContextHandle_t handle,
#     GEOSCoordSequence* s);
sub GEOSGeom_createPoint_r(GEOSContextHandle, Pointer) returns GEOSGeometry is native(GEOS) is export { * } 

# /** \see GEOSGeom_createPointFromXY */
# extern GEOSGeometry GEOS_DLL *GEOSGeom_createPointFromXY_r(
#     GEOSContextHandle_t handle,
#     double x, double y);
sub GEOSGeom_createPointFromXY_r(GEOSContextHandle, num64, num64) returns GEOSGeometry is native(GEOS) is export { * } 

# /** \see GEOSGeom_createEmptyPoint */
# extern GEOSGeometry GEOS_DLL *GEOSGeom_createEmptyPoint_r(
#     GEOSContextHandle_t handle);
sub GEOSGeom_createEmptyPoint_r(GEOSContextHandle) returns GEOSGeometry is native(GEOS) is export { * } 

# /** \see GEOSGeom_createLinearRing */
# extern GEOSGeometry GEOS_DLL *GEOSGeom_createLinearRing_r(
#     GEOSContextHandle_t handle,
#     GEOSCoordSequence* s);
sub GEOSGeom_createLinearRing_r(GEOSContextHandle, Pointer) returns GEOSGeometry is native(GEOS) is export { * } 

# /** \see GEOSGeom_createLineString */
# extern GEOSGeometry GEOS_DLL *GEOSGeom_createLineString_r(
#     GEOSContextHandle_t handle,
#     GEOSCoordSequence* s);
sub GEOSGeom_createLineString_r(GEOSContextHandle, Pointer) returns GEOSGeometry is native(GEOS) is export { * } 

# /** \see GEOSGeom_createEmptyLineString */
# extern GEOSGeometry GEOS_DLL *GEOSGeom_createEmptyLineString_r(
#     GEOSContextHandle_t handle);
sub GEOSGeom_createEmptyLineString_r(GEOSContextHandle) returns GEOSGeometry is native(GEOS) is export { * } 

# /** \see GEOSGeom_createEmptyPolygon */
# extern GEOSGeometry GEOS_DLL *GEOSGeom_createEmptyPolygon_r(
#     GEOSContextHandle_t handle);
sub GEOSGeom_createEmptyPolygon_r(GEOSContextHandle) returns GEOSGeometry is native(GEOS) is export { * } 

# /** \see GEOSGeom_createPolygon */
# extern GEOSGeometry GEOS_DLL *GEOSGeom_createPolygon_r(
#     GEOSContextHandle_t handle,
#     GEOSGeometry* shell,
#     GEOSGeometry** holes,
#     unsigned int nholes);
sub GEOSGeom_createPolygon_r(GEOSContextHandle, GEOSGeometry, Pointer, uint32) returns GEOSGeometry is native(GEOS) is export { * } 

# /** \see GEOSGeom_createCollection */
# extern GEOSGeometry GEOS_DLL *GEOSGeom_createCollection_r(
#     GEOSContextHandle_t handle,
#     int type,
#     GEOSGeometry* *geoms,
#     unsigned int ngeoms);
sub GEOSGeom_createCollection_r(GEOSContextHandle, int32, Pointer, uint32) returns GEOSGeometry is native(GEOS) is export { * } 

# /** \see GEOSGeom_releaseCollection */
# extern GEOSGeometry GEOS_DLL ** GEOSGeom_releaseCollection_r(
#     GEOSContextHandle_t handle,
#     GEOSGeometry * collection,
#     unsigned int * ngeoms);
sub GEOSGeom_releaseCollection_r(GEOSContextHandle, GEOSGeometry, Pointer) returns Pointer is native(GEOS) is export { * } 

# /** \see GEOSGeom_createEmptyCollection */
# extern GEOSGeometry GEOS_DLL *GEOSGeom_createEmptyCollection_r(
#     GEOSContextHandle_t handle, int type);
sub GEOSGeom_createEmptyCollection_r(GEOSContextHandle, int32) returns GEOSGeometry is native(GEOS) is export { * } 

# /** \see GEOSGeom_createRectangle */
# extern GEOSGeometry GEOS_DLL *GEOSGeom_createRectangle_r(
#     GEOSContextHandle_t handle,
#     double xmin, double ymin,
#     double xmax, double ymax);
sub GEOSGeom_createRectangle_r(GEOSContextHandle, num64, num64, num64, num64) returns GEOSGeometry is native(GEOS) is export { * } 

# /** \see GEOSGeom_clone */
# extern GEOSGeometry GEOS_DLL *GEOSGeom_clone_r(
#     GEOSContextHandle_t handle,
#     const GEOSGeometry* g);
sub GEOSGeom_clone_r(GEOSContextHandle, GEOSGeometry) returns GEOSGeometry is native(GEOS) is export { * } 

# /** \see GEOSGeom_createCircularString */
# extern GEOSGeometry GEOS_DLL *GEOSGeom_createCircularString_r(
#     GEOSContextHandle_t handle,
#     GEOSCoordSequence* s);
sub GEOSGeom_createCircularString_r(GEOSContextHandle, Pointer) returns GEOSGeometry is native(GEOS) is export { * } 

# /** \see GEOSGeom_createEmptyCircularString */
# extern GEOSGeometry GEOS_DLL *GEOSGeom_createEmptyCircularString_r(
#     GEOSContextHandle_t handle);
sub GEOSGeom_createEmptyCircularString_r(GEOSContextHandle) returns GEOSGeometry is native(GEOS) is export { * } 

# /** \see GEOSGeom_createCompoundCurve */
# extern GEOSGeometry GEOS_DLL *GEOSGeom_createCompoundCurve_r(
#     GEOSContextHandle_t handle,
#     GEOSGeometry** curves,
#     unsigned int ncurves);
sub GEOSGeom_createCompoundCurve_r(GEOSContextHandle, Pointer, uint32) returns GEOSGeometry is native(GEOS) is export { * } 

# /** \see GEOSGeom_createEmptyCompoundCurve */
# extern GEOSGeometry GEOS_DLL *GEOSGeom_createEmptyCompoundCurve_r(
#     GEOSContextHandle_t handle);
sub GEOSGeom_createEmptyCompoundCurve_r(GEOSContextHandle) returns GEOSGeometry is native(GEOS) is export { * } 

# /** \see GEOSGeom_createCurvePolygon */
# extern GEOSGeometry GEOS_DLL *GEOSGeom_createCurvePolygon_r(
#     GEOSContextHandle_t handle,
#     GEOSGeometry* shell,
#     GEOSGeometry** holes,
#     unsigned int nholes);
sub GEOSGeom_createCurvePolygon_r(GEOSContextHandle,