Skip to content

Commit

Permalink
Merge pull request #10 from Dewberry/merge-upstream-slawler
Browse files Browse the repository at this point in the history
Merge upstream slawler
  • Loading branch information
slawler authored Feb 6, 2024
2 parents 47f077b + 0a31f34 commit 7b4b23c
Show file tree
Hide file tree
Showing 22 changed files with 1,085 additions and 483 deletions.
30 changes: 30 additions & 0 deletions README
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
-------------
About
-------------

The gdal.go package provides a go wrapper for GDAL, the Geospatial Data Abstraction Library. More information about GDAL can be found at http://www.gdal.org

-------------
Installation
-------------

1) go get github.com/lukeroth/gdal
2) Set the GDAL library and include directories to the appropriate locations.
3) go build

-------------
Compatibility
-------------

This software has been tested most recently on Ubuntu 18.10, GDAL version 2.3.2.

-------------
Examples
-------------

-------------
Status (3/08/2019)
-------------

The majority of GDAL functionality exposed by the C API is available, as well as much of the OGR API.
Most functionality is not covered by tests or benchmarks.
92 changes: 52 additions & 40 deletions algorithms.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ package gdal
/*
#include "go_gdal.h"
#include "gdal_version.h"
#cgo linux pkg-config: gdal
#cgo darwin pkg-config: gdal
#cgo windows LDFLAGS: -Lc:/gdal/release-1600-x64/lib -lgdal_i
#cgo windows CFLAGS: -IC:/gdal/release-1600-x64/include
*/
import "C"
import (
Expand Down Expand Up @@ -95,13 +90,13 @@ func (src RasterBand) ComputeProximity(
}
opts[length] = (*C.char)(unsafe.Pointer(nil))

return C.GDALComputeProximity(
return CPLErr(C.GDALComputeProximity(
src.cval,
dest.cval,
(**C.char)(unsafe.Pointer(&opts[0])),
C.goGDALProgressFuncProxyB(),
unsafe.Pointer(arg),
).Err()
)).Err()
}

// Fill selected raster regions by interpolation from the edges
Expand All @@ -125,7 +120,7 @@ func (src RasterBand) FillNoData(
}
opts[length] = (*C.char)(unsafe.Pointer(nil))

return C.GDALFillNodata(
return CPLErr(C.GDALFillNodata(
src.cval,
mask.cval,
C.double(distance),
Expand All @@ -134,7 +129,7 @@ func (src RasterBand) FillNoData(
(**C.char)(unsafe.Pointer(&opts[0])),
C.goGDALProgressFuncProxyB(),
unsafe.Pointer(arg),
).Err()
)).Err()
}

// Create polygon coverage from raster data using an integer buffer
Expand All @@ -158,15 +153,15 @@ func (src RasterBand) Polygonize(
}
opts[length] = (*C.char)(unsafe.Pointer(nil))

return C.GDALPolygonize(
return CPLErr(C.GDALPolygonize(
src.cval,
mask.cval,
layer.cval,
C.int(fieldIndex),
(**C.char)(unsafe.Pointer(&opts[0])),
C.goGDALProgressFuncProxyB(),
unsafe.Pointer(arg),
).Err()
)).Err()
}

// Create polygon coverage from raster data using a floating point buffer
Expand All @@ -190,15 +185,15 @@ func (src RasterBand) FPolygonize(
}
opts[length] = (*C.char)(unsafe.Pointer(nil))

return C.GDALFPolygonize(
return CPLErr(C.GDALFPolygonize(
src.cval,
mask.cval,
layer.cval,
C.int(fieldIndex),
(**C.char)(unsafe.Pointer(&opts[0])),
C.goGDALProgressFuncProxyB(),
unsafe.Pointer(arg),
).Err()
)).Err()
}

// Removes small raster polygons
Expand All @@ -221,7 +216,7 @@ func (src RasterBand) SieveFilter(
}
opts[length] = (*C.char)(unsafe.Pointer(nil))

return C.GDALSieveFilter(
return CPLErr(C.GDALSieveFilter(
src.cval,
mask.cval,
dest.cval,
Expand All @@ -230,7 +225,7 @@ func (src RasterBand) SieveFilter(
(**C.char)(unsafe.Pointer(&opts[0])),
C.goGDALProgressFuncProxyB(),
unsafe.Pointer(arg),
).Err()
)).Err()
}

/* --------------------------------------------- */
Expand Down Expand Up @@ -306,7 +301,6 @@ func (src RasterBand) SieveFilter(
// GridAlgorithm represents Grid Algorithm code
type GridAlgorithm int

//
const (
GA_InverseDistancetoAPower = GridAlgorithm(C.GGA_InverseDistanceToAPower)
GA_MovingAverage = GridAlgorithm(C.GGA_MovingAverage)
Expand All @@ -323,6 +317,8 @@ const (

// GridLinearOptions: Linear method control options.
type GridLinearOptions struct {
// SizeOfStructure: Added in GDAL 3.6 to detect potential ABI issues. Should be set to sizeof(GDALGridLinearOptions)
SizeOfStructure uintptr
// Radius: in case the point to be interpolated does not fit into a triangle of the Delaunay triangulation,
// use that maximum distance to search a nearest neighbour, or use nodata otherwise. If set to -1, the search
// distance is infinite. If set to 0, nodata value will be always used.
Expand All @@ -333,6 +329,8 @@ type GridLinearOptions struct {

// GridInverseDistanceToAPowerOptions: Inverse distance to a power method control options.
type GridInverseDistanceToAPowerOptions struct {
// SizeOfStructure: Added in GDAL 3.6 to detect potential ABI issues. Should be set to sizeof(GridInverseDistanceToAPowerOptions)
SizeOfStructure uintptr
// Power: Weighting power
Power float64
// Smoothing: Smoothing parameter
Expand Down Expand Up @@ -361,6 +359,8 @@ type GridInverseDistanceToAPowerOptions struct {
// GridInverseDistanceToAPowerNearestNeighborOptions: Inverse distance to a power, with nearest neighbour search,
// control options
type GridInverseDistanceToAPowerNearestNeighborOptions struct {
// SizeOfStructure: Added in GDAL 3.6 to detect potential ABI issues. Should be set to sizeof(GridInverseDistanceToAPowerNearestNeighborOptions)
SizeOfStructure uintptr
// Power: Weighting power
Power float64
// Radius: The radius of search circle
Expand All @@ -380,6 +380,8 @@ type GridInverseDistanceToAPowerNearestNeighborOptions struct {

// GridMovingAverageOptions: Moving average method control options
type GridMovingAverageOptions struct {
// SizeOfStructure: Added in GDAL 3.6 to detect potential ABI issues. Should be set to sizeof(GridMovingAverageOptions)
SizeOfStructure uintptr
// Radius1: The first radius (X axis if rotation angle is 0) of search ellipse.
Radius1 float64
// Radius2: The second radius (Y axis if rotation angle is 0) of search ellipse.
Expand All @@ -395,6 +397,8 @@ type GridMovingAverageOptions struct {

// GridNearestNeighborOptions: Nearest neighbor method control options.
type GridNearestNeighborOptions struct {
// SizeOfStructure: Added in GDAL 3.6 to detect potential ABI issues. Should be set to sizeof(GridNearestNeighborOptions)
SizeOfStructure uintptr
// Radius1: The first radius (X axis if rotation angle is 0) of search ellipse.
Radius1 float64
// Radius2: The second radius (Y axis if rotation angle is 0) of search ellipse.
Expand All @@ -407,6 +411,8 @@ type GridNearestNeighborOptions struct {

// GridDataMetricsOptions: Data metrics method control options
type GridDataMetricsOptions struct {
// SizeOfStructure: Added in GDAL 3.6 to detect potential ABI issues. Should be set to sizeof(GridDataMetricsOptions)
SizeOfStructure uintptr
// Radius1: The first radius (X axis if rotation angle is 0) of search ellipse.
Radius1 float64
// Radius2: The second radius (Y axis if rotation angle is 0) of search ellipse.
Expand Down Expand Up @@ -447,6 +453,7 @@ func GridCreate(
return nil, errInvalidOptionsTypeWasPassed
}
poptions = unsafe.Pointer(&C.GDALGridInverseDistanceToAPowerOptions{
nSizeOfStructure: C.size_t(unsafe.Sizeof(soptions)),
dfPower: C.double(soptions.Power),
dfSmoothing: C.double(soptions.Smoothing),
dfAnisotropyRatio: C.double(soptions.AnisotropyRatio),
Expand All @@ -464,35 +471,38 @@ func GridCreate(
return nil, errInvalidOptionsTypeWasPassed
}
poptions = unsafe.Pointer(&C.GDALGridInverseDistanceToAPowerNearestNeighborOptions{
dfPower: C.double(soptions.Power),
dfRadius: C.double(soptions.Radius),
dfSmoothing: C.double(soptions.Smoothing),
nMaxPoints: C.uint(soptions.MaxPoints),
nMinPoints: C.uint(soptions.MinPoints),
dfNoDataValue: C.double(soptions.NoDataValue),
nSizeOfStructure: C.size_t(unsafe.Sizeof(soptions)),
dfPower: C.double(soptions.Power),
dfRadius: C.double(soptions.Radius),
dfSmoothing: C.double(soptions.Smoothing),
nMaxPoints: C.uint(soptions.MaxPoints),
nMinPoints: C.uint(soptions.MinPoints),
dfNoDataValue: C.double(soptions.NoDataValue),
})
case GA_MovingAverage:
soptions, ok := options.(GridMovingAverageOptions)
if !ok {
return nil, errInvalidOptionsTypeWasPassed
}
poptions = unsafe.Pointer(&C.GDALGridMovingAverageOptions{
dfRadius1: C.double(soptions.Radius1),
dfRadius2: C.double(soptions.Radius2),
dfAngle: C.double(soptions.Angle),
nMinPoints: C.uint(soptions.MinPoints),
dfNoDataValue: C.double(soptions.NoDataValue),
nSizeOfStructure: C.size_t(unsafe.Sizeof(soptions)),
dfRadius1: C.double(soptions.Radius1),
dfRadius2: C.double(soptions.Radius2),
dfAngle: C.double(soptions.Angle),
nMinPoints: C.uint(soptions.MinPoints),
dfNoDataValue: C.double(soptions.NoDataValue),
})
case GA_NearestNeighbor:
soptions, ok := options.(GridNearestNeighborOptions)
if !ok {
return nil, errInvalidOptionsTypeWasPassed
}
poptions = unsafe.Pointer(&C.GDALGridNearestNeighborOptions{
dfRadius1: C.double(soptions.Radius1),
dfRadius2: C.double(soptions.Radius2),
dfAngle: C.double(soptions.Angle),
dfNoDataValue: C.double(soptions.NoDataValue),
nSizeOfStructure: C.size_t(unsafe.Sizeof(soptions)),
dfRadius1: C.double(soptions.Radius1),
dfRadius2: C.double(soptions.Radius2),
dfAngle: C.double(soptions.Angle),
dfNoDataValue: C.double(soptions.NoDataValue),
})
case GA_MetricMinimum, GA_MetricMaximum, GA_MetricCount, GA_MetricRange,
GA_MetricAverageDistance, GA_MetricAverageDistancePts:
Expand All @@ -501,26 +511,28 @@ func GridCreate(
return nil, errInvalidOptionsTypeWasPassed
}
poptions = unsafe.Pointer(&C.GDALGridDataMetricsOptions{
dfRadius1: C.double(soptions.Radius1),
dfRadius2: C.double(soptions.Radius2),
dfAngle: C.double(soptions.Angle),
nMinPoints: C.uint(soptions.MinPoints),
dfNoDataValue: C.double(soptions.NoDataValue),
nSizeOfStructure: C.size_t(unsafe.Sizeof(soptions)),
dfRadius1: C.double(soptions.Radius1),
dfRadius2: C.double(soptions.Radius2),
dfAngle: C.double(soptions.Angle),
nMinPoints: C.uint(soptions.MinPoints),
dfNoDataValue: C.double(soptions.NoDataValue),
})
case GA_Linear:
soptions, ok := options.(GridLinearOptions)
if !ok {
return nil, errInvalidOptionsTypeWasPassed
}
poptions = unsafe.Pointer(&C.GDALGridLinearOptions{
dfRadius: C.double(soptions.Radius),
dfNoDataValue: C.double(soptions.NoDataValue),
nSizeOfStructure: C.size_t(unsafe.Sizeof(soptions)),
dfRadius: C.double(soptions.Radius),
dfNoDataValue: C.double(soptions.NoDataValue),
})
}

buffer := make([]float64, nX*nY)
arg := &goGDALProgressFuncProxyArgs{progress, data}
err := C.GDALGridCreate(
err := CPLErr(C.GDALGridCreate(
C.GDALGridAlgorithm(algorithm),
poptions,
C.uint(uint(len(x))),
Expand All @@ -537,7 +549,7 @@ func GridCreate(
unsafe.Pointer(&buffer[0]),
C.goGDALProgressFuncProxyB(),
unsafe.Pointer(arg),
).Err()
)).Err()
return buffer, err
}

Expand Down
9 changes: 9 additions & 0 deletions c_darwin_amd64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// +build darwin,amd64

package gdal

/*
#cgo pkg-config: gdal
#cgo LDFLAGS: -Wl,-undefined,dynamic_lookup
*/
import "C"
9 changes: 9 additions & 0 deletions c_darwin_arm64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// +build darwin,arm64

package gdal

/*
#cgo pkg-config: gdal
#cgo LDFLAGS: -Wl,-undefined,dynamic_lookup
*/
import "C"
8 changes: 8 additions & 0 deletions c_linux_amd64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// +build linux,amd64

package gdal

/*
#cgo pkg-config: gdal
*/
import "C"
8 changes: 8 additions & 0 deletions c_linux_arm64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// +build linux,arm64

package gdal

/*
#cgo pkg-config: gdal
*/
import "C"
9 changes: 9 additions & 0 deletions c_windows_amd64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// +build windows,amd64

package gdal

/*
#cgo windows LDFLAGS: -Lc:/gdal/release-1600-x64/lib -lgdal_i
#cgo windows CFLAGS: -IC:/gdal/release-1600-x64/include
*/
import "C"
9 changes: 5 additions & 4 deletions doc.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
/*
Package gdal provides a wrapper for GDAL, the Geospatial Data Abstraction Library. This C/C++ library provides access to a large number of geospatial raster data formats. It also contains a wrapper for the related OGR Simple Feature Library which provides similar functionality for vector formats.
Limitations
# Limitations
Some less oftenly used functions are not yet implemented. The majoriry of these involve style tables, asynchronous I/O, and GCPs.
The documentation is fairly limited, but the functionality fairly closely matches that of the C++ api.
This wrapper has most recently been tested on Windows7, using the MinGW32_x64 compiler and GDAL version 1.11.
Usage
# Usage
A simple program to create a georeferenced blank 256x256 GeoTIFF:
package main
import (
"fmt"
"flag"
gdal "github.com/lukeroth/gdal"
gdal "github.com/lukeroth/gdal "
)
func main() {
Expand Down Expand Up @@ -46,7 +47,7 @@ A simple program to create a georeferenced blank 256x256 GeoTIFF:
raster := dataset.RasterBand(1)
raster.IO(gdal.Write, 0, 0, 256, 256, buffer, 256, 256, 0, 0)
}
More examples can be found in the ./examples subdirectory.
More examples can be found in the ./examples subdirectory.
*/
package gdal
5 changes: 4 additions & 1 deletion examples/translate/translate.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ func main() {
log.Fatal(err)
}

outputDs := gdal.GDALTranslate(outputFile, ds, options)
outputDs, err := gdal.Translate(outputFile, ds, options)
if err != nil {
log.Fatal(err)
}

defer outputDs.Close()

Expand Down
Loading

0 comments on commit 7b4b23c

Please sign in to comment.