Skip to content

Commit

Permalink
Use a stub implementation of MakeValid when not supported by GEOS
Browse files Browse the repository at this point in the history
  • Loading branch information
peterstace committed Nov 18, 2021
1 parent 88cd41b commit c8e5fa0
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 1 deletion.
15 changes: 15 additions & 0 deletions geos/entrypoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@ package geos
#cgo LDFLAGS: -lgeos_c
#cgo CFLAGS: -Wall
#include "geos_c.h"
#define MAKE_VALID_MIN_VERSION "3.8.0"
#define MAKE_VALID_MISSING ( \
GEOS_VERSION_MAJOR < 3 || \
(GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR < 8) \
)
#if MAKE_VALID_MISSING
// This stub implementation also fails
GEOSGeometry *GEOSMakeValid_r(GEOSContextHandle_t handle, const GEOSGeometry* g) { return NULL; }
#endif
*/
import "C"

Expand Down Expand Up @@ -316,6 +327,10 @@ func SymmetricDifference(a, b geom.Geometry, opts ...geom.ConstructorOption) (ge
// invalid geometry. If the input geometry is valid, then it is returned
// unaltered.
func MakeValid(g geom.Geometry, opts ...geom.ConstructorOption) (geom.Geometry, error) {
if C.MAKE_VALID_MISSING != 0 {
return geom.Geometry{}, unsupportedGEOSVersionError{
C.MAKE_VALID_MIN_VERSION, "MakeValid"}
}
result, err := unaryOpG(g, opts, func(ctx C.GEOSContextHandle_t, g *C.GEOSGeometry) *C.GEOSGeometry {
return C.GEOSMakeValid_r(ctx, g)
})
Expand Down
3 changes: 3 additions & 0 deletions geos/entrypoints_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,9 @@ func TestMakeValid(t *testing.T) {
t.Run(strconv.Itoa(i), func(t *testing.T) {
in := geomFromWKT(t, tt.input, geom.DisableAllValidations)
gotGeom, err := MakeValid(in)
if _, ok := err.(unsupportedGEOSVersionError); ok {
t.Skip(err)
}
expectNoErr(t, err)
wantGeom := geomFromWKT(t, tt.wantOutput)
expectGeomEq(t, gotGeom, wantGeom)
Expand Down
20 changes: 20 additions & 0 deletions geos/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,29 @@ package geos

import "fmt"

// #include "geos_c.h"
import "C"

func wrap(err error, format string, args ...interface{}) error {
if err == nil {
return nil
}
return fmt.Errorf(format+": %w", append(args, err)...)
}

var currentGEOSVersion = fmt.Sprintf(
"%d.%d.%d",
C.GEOS_VERSION_MAJOR,
C.GEOS_VERSION_MINOR,
C.GEOS_VERSION_PATCH,
)

type unsupportedGEOSVersionError struct {
requiredGEOSVersion string
operation string
}

func (e unsupportedGEOSVersionError) Error() string {
return fmt.Sprintf("%s is unsupported in GEOS %s, requires at least GEOS %s",
e.operation, currentGEOSVersion, e.requiredGEOSVersion)
}
2 changes: 1 addition & 1 deletion geos/handle.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ char *marshal(GEOSContextHandle_t handle, const GEOSGeometry *g, size_t *size, c
GEOSGeometry const *noop(GEOSContextHandle_t handle, const GEOSGeometry *g) {
return g;
}
*/
import "C"

Expand Down Expand Up @@ -62,6 +61,7 @@ func newHandle() (*handle, error) {
h.release()
return nil, errors.New("malloc failed")
}
C.memset((unsafe.Pointer)(h.errBuf), 0, 1024)

h.context = C.sf_init(unsafe.Pointer(h.errBuf))
if h.context == nil {
Expand Down

0 comments on commit c8e5fa0

Please sign in to comment.