Skip to content

Commit

Permalink
Merge branch 'main' into gcp
Browse files Browse the repository at this point in the history
  • Loading branch information
pericles-tpt committed Sep 29, 2023
2 parents aa78e3f + 4a1ba9d commit 66d34b3
Show file tree
Hide file tree
Showing 2 changed files with 188 additions and 20 deletions.
59 changes: 47 additions & 12 deletions godal.go
Original file line number Diff line number Diff line change
Expand Up @@ -891,7 +891,7 @@ func (ds *Dataset) SetNoData(nd float64, opts ...SetNoDataOption) error {
return cgc.close()
}

// SetScale sets the band's scale and offset
// SetScaleOffset sets the band's scale and offset
func (ds *Dataset) SetScaleOffset(scale, offset float64, opts ...SetScaleOffsetOption) error {
setterOpts := &setScaleOffsetOpts{}
for _, opt := range opts {
Expand Down Expand Up @@ -3849,7 +3849,8 @@ func (ds *Dataset) Grid(destPath string, switches []string, opts ...GridOption)
return &Dataset{majorObject{C.GDALMajorObjectH(dsRet)}}, nil
}

// Grid runs the library version of nearblack.
// Nearblack runs the library version of nearblack
//
// See the nearblack doc page to determine the valid flags/opts that can be set in switches.
//
// Example switches :
Expand All @@ -3862,7 +3863,7 @@ func (ds *Dataset) Grid(destPath string, switches []string, opts ...GridOption)
//
// NOTE: Some switches are NOT compatible with this binding, as a `nullptr` is passed to a later call to
// `GDALNearblackOptionsNew()` (as the 2nd argument). Those switches are: "-o", "-q", "-quiet"
func (ds *Dataset) Nearblack(destPath string, destDs *Dataset, switches []string, opts ...NearblackOption) (*Dataset, error) {
func (ds *Dataset) Nearblack(dstDS string, switches []string, opts ...NearblackOption) (*Dataset, error) {
nearBlackOpts := nearBlackOpts{}
for _, opt := range opts {
opt.setNearblackOpt(&nearBlackOpts)
Expand All @@ -3871,21 +3872,55 @@ func (ds *Dataset) Nearblack(destPath string, destDs *Dataset, switches []string
cswitches := sliceToCStringArray(switches)
defer cswitches.free()

dest := unsafe.Pointer(C.CString(destPath))
dest := unsafe.Pointer(C.CString(dstDS))
defer C.free(dest)

cgc := createCGOContext(nil, nearBlackOpts.errorHandler)
defer C.free(unsafe.Pointer(dest))

var dsRet C.GDALDatasetH
if destDs != nil {
dsRet = C.godalNearblack(cgc.cPointer(), (*C.char)(dest), destDs.handle(), ds.handle(), cswitches.cPointer())
} else {
dsRet = C.godalNearblack(cgc.cPointer(), (*C.char)(dest), nil, ds.handle(), cswitches.cPointer())
ret, err := C.godalNearblack(cgc.cPointer(), (*C.char)(dest), nil, ds.handle(), cswitches.cPointer())
if err = cgc.close(); err != nil {
return nil, err
}

return &Dataset{majorObject{C.GDALMajorObjectH(ret)}}, nil
}

// NearblackInto writes the provided `sourceDs` into the Dataset that this method was called on, and
// runs the library version of nearblack.
//
// See the nearblack doc page to determine the valid flags/opts that can be set in switches.
//
// Example switches :
//
// []string{"-white", "-near", "10"}
//
// Creation options and driver may be set in the switches slice with
//
// switches:=[]string{"-co","TILED=YES","-of","GTiff"}
//
// NOTE: Some switches are NOT compatible with this binding, as a `nullptr` is passed to a later call to
// `GDALNearblackOptionsNew()` (as the 2nd argument). Those switches are: "-o", "-q", "-quiet"
func (ds *Dataset) NearblackInto(sourceDs *Dataset, switches []string, opts ...NearblackOption) error {
nearBlackOpts := nearBlackOpts{}
for _, opt := range opts {
opt.setNearblackOpt(&nearBlackOpts)
}

cswitches := sliceToCStringArray(switches)
defer cswitches.free()

cgc := createCGOContext(nil, nearBlackOpts.errorHandler)

var srcDsHandle C.GDALDatasetH = nil
if sourceDs != nil {
srcDsHandle = sourceDs.handle()
}
_ = C.godalNearblack(cgc.cPointer(), nil, ds.handle(), srcDsHandle, cswitches.cPointer())
if err := cgc.close(); err != nil {
return nil, err
return err
}

return &Dataset{majorObject{C.GDALMajorObjectH(dsRet)}}, nil
return nil
}

// GCP mirrors the structure of the GDAL_GCP type
Expand Down
149 changes: 141 additions & 8 deletions godal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4253,7 +4253,8 @@ func TestGridInvalidSwitch(t *testing.T) {
t.Error(err)
return
}

_, err = vrtDs.Grid("/vsimem/test.tiff", []string{"-invalidswitch"})
assert.Error(t, err)
ehc := eh()
_, err = vrtDs.Grid("/vsimem/test.tiff", []string{"-invalidswitch"}, ErrLogger(ehc.ErrorHandler))
assert.Error(t, err)
Expand All @@ -4270,11 +4271,13 @@ func TestNearblackBlack(t *testing.T) {
t.Error(err)
return
}
defer vrtDs.Close()
geom, err := NewGeometryFromWKT("POLYGON((0 0 0, 0 1 0, 1 1 255, 1 0 255))", nil)
if err != nil {
t.Error(err)
return
}
defer geom.Close()
_, err = vrtDs.CreateLayer("grid", nil, GTPolygon)
if err != nil {
t.Error(err)
Expand Down Expand Up @@ -4309,10 +4312,9 @@ func TestNearblackBlack(t *testing.T) {
gridDs.Read(0, 0, originalColors, outXSize, outYSize)

// 2. Put the Dataset generated above, through the `Nearblack` function, to set pixels near BLACK to BLACK
nbDs := &Dataset{}
argsNbString := "-near 10 -nb 0"
fname2 := "/vsimem/test1.tiff"
nbDs, err = gridDs.Nearblack(fname2, nbDs, strings.Split(argsNbString, " "))
nbDs, err := gridDs.Nearblack(fname2, strings.Split(argsNbString, " "))
if err != nil {
t.Error(err)
return
Expand Down Expand Up @@ -4341,11 +4343,13 @@ func TestNearblackWhite(t *testing.T) {
t.Error(err)
return
}
defer vrtDs.Close()
geom, err := NewGeometryFromWKT("POLYGON((0 0 255, 0 1 255, 1 1 0, 1 0 0))", nil)
if err != nil {
t.Error(err)
return
}
defer geom.Close()
_, err = vrtDs.CreateLayer("grid", nil, GTPolygon)
if err != nil {
t.Error(err)
Expand Down Expand Up @@ -4380,10 +4384,9 @@ func TestNearblackWhite(t *testing.T) {
gridDs.Read(0, 0, originalColors, outXSize, outYSize)

// 2. Put the Dataset generated above, through the `Nearblack` function, to set pixels near WHITE to WHITE
nbDs := &Dataset{}
argsNbString := "-near 10 -nb 0 -white"
fname2 := "/vsimem/test1.tiff"
nbDs, err = gridDs.Nearblack(fname2, nbDs, strings.Split(argsNbString, " "))
nbDs, err := gridDs.Nearblack(fname2, strings.Split(argsNbString, " "))
if err != nil {
t.Error(err)
return
Expand Down Expand Up @@ -4417,15 +4420,145 @@ func TestNearblackInvalidSwitch(t *testing.T) {
defer vrtDs.Close()

// 2. Put the Dataset generated above, through the `Nearblack`
nbDs := &Dataset{}
fname2 := "/vsimem/test1.tiff"

_, err = vrtDs.Nearblack(fname2, []string{"-invalidswitch"})
assert.Error(t, err)
ehc := eh()
_, err = vrtDs.Nearblack(fname2, []string{"-invalidswitch"}, ErrLogger(ehc.ErrorHandler))
assert.Error(t, err)

defer func() { _ = VSIUnlink(fname2) }()
}

func TestNearblackBlackInto(t *testing.T) {
// 1. Create an image, linearly interpolated, from black (on the left) to white (on the right), using `Grid()`
var (
outXSize = 256
outYSize = 256
)
vrtDs, err := CreateVector(Memory, "")
if err != nil {
t.Error(err)
return
}
defer vrtDs.Close()
geom, err := NewGeometryFromWKT("POLYGON((0 0 0, 0 1 0, 1 1 255, 1 0 255))", nil)
if err != nil {
t.Error(err)
return
}
defer geom.Close()
_, err = vrtDs.CreateLayer("grid", nil, GTPolygon)
if err != nil {
t.Error(err)
return
}
_, err = vrtDs.Layers()[0].NewFeature(geom)
if err != nil {
t.Error(err)
return
}
// As of GDAL v3.6, `GDALGrid` will swap `yMin` and `yMax` if `yMin` < `yMax`. In order to make the output of
// earlier GDAL versions (< 3.6) consistent with this, we're setting `yMin` > `yMax`.
yMin := 1
yMax := 0
argsString := fmt.Sprintf("-a linear -txe 0 1 -tye %d %d -outsize %d %d -ot Byte", yMin, yMax, outXSize, outYSize)
fname := "/vsimem/test.tiff"
gridDs, err := vrtDs.Grid(fname, strings.Split(argsString, " "))
if err != nil {
// Handles QHull error differently here, as it's a compatibility issue not a gridding error
isQhullError := strings.HasSuffix(err.Error(), "without QHull support")
if isQhullError {
t.Log(`Skipping test, GDAL was built without "Delaunay triangulation" support which is required for the "Linear" gridding algorithm`)
return
} else {
t.Error(err)
return
}
}
defer func() { _ = VSIUnlink(fname) }()
defer gridDs.Close()
originalColors := make([]byte, outXSize*outYSize)
gridDs.Read(0, 0, originalColors, outXSize, outYSize)

// 2. Put the Dataset generated above, through the `Nearblack` function, to set pixels near BLACK to BLACK
nbDs, err := Create(Memory, "nbDs", 1, Byte, outXSize, outYSize)
if err != nil {
t.Error(err)
return
}
defer nbDs.Close()
argsNbString := "-near 10 -nb 0"
err = nbDs.NearblackInto(gridDs, strings.Split(argsNbString, " "))
if err != nil {
t.Error(err)
return
}
nearblackColors := make([]byte, outXSize*outYSize)
nbDs.Read(0, 0, nearblackColors, outXSize, outYSize)

// 3. Test on all rows that pixels where abs(0 - pixelValue) <= 10, are set to black (0)
for i := 0; i < outYSize; i++ {
startIndex := i * outXSize
assert.Equal(t, []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, originalColors[startIndex:startIndex+13])
assert.Equal(t, []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12}, nearblackColors[startIndex:startIndex+13])
}
}

func TestNearblackIntoInvalidSwitch(t *testing.T) {
// 1. Create a linearly interpolated image that goes from white -> black, using `Grid()`
var (
outXSize = 256
outYSize = 256
)
fname := "/vsimem/test.tiff"
vrtDs, err := Create(Memory, fname, 1, Byte, outXSize, outYSize)
if err != nil {
t.Error(err)
return
}
defer func() { _ = VSIUnlink(fname) }()
defer vrtDs.Close()

// 2. Put the Dataset generated above, through the `Nearblack`
nbDs, err := Create(Memory, "nbDs", 1, Byte, outXSize, outYSize)
if err != nil {
t.Error(err)
return
}
defer nbDs.Close()
err = nbDs.NearblackInto(vrtDs, []string{"-invalidswitch"})
assert.Error(t, err)
ehc := eh()
_, err = vrtDs.Nearblack(fname2, nbDs, []string{"-invalidswitch"}, ErrLogger(ehc.ErrorHandler))
err = nbDs.NearblackInto(vrtDs, []string{"-invalidswitch"}, ErrLogger(ehc.ErrorHandler))
assert.Error(t, err)
}

_, err = vrtDs.Nearblack(fname2, nbDs, []string{"-invalidswitch"})
func TestNearblackIntoNoSrcDs(t *testing.T) {
// 1. Create a linearly interpolated image that goes from white -> black, using `Grid()`
var (
outXSize = 256
outYSize = 256
)
fname := "/vsimem/test.tiff"
vrtDs, err := Create(Memory, fname, 1, Byte, outXSize, outYSize)
if err != nil {
t.Error(err)
return
}
defer func() { _ = VSIUnlink(fname) }()
defer vrtDs.Close()

// 2. Put the Dataset generated above, through the `Nearblack`
nbDs, err := Create(Memory, "nbDs", 1, Byte, outXSize, outYSize)
if err != nil {
t.Error(err)
return
}
defer nbDs.Close()
ehc := eh()
err = nbDs.NearblackInto(nil, []string{}, ErrLogger(ehc.ErrorHandler))
assert.Error(t, err)
}

Expand Down

0 comments on commit 66d34b3

Please sign in to comment.