Files
gis/internal/landscape/fakeio_test.go

76 lines
1.9 KiB
Go

package landscape
import (
"context"
"fmt"
"sync"
"gis/internal/raster"
)
// fakeIO keeps rasters in memory keyed by path.
type fakeIO struct {
mu sync.Mutex
files map[string]*fakeRaster
}
type fakeRaster struct {
grid raster.Grid
data []float64 // row-major
}
func newFakeIO() *fakeIO { return &fakeIO{files: map[string]*fakeRaster{}} }
func (f *fakeIO) put(path string, g raster.Grid, data []float64) {
f.files[path] = &fakeRaster{grid: g, data: data}
}
type fakeReader struct{ r *fakeRaster }
func (r *fakeReader) Grid() raster.Grid { return r.r.grid }
func (r *fakeReader) NoData() (float64, bool) { return -9999, true }
func (r *fakeReader) Close() error { return nil }
func (r *fakeReader) ReadFloat64(w raster.Window, dst []float64) error {
for y := 0; y < w.Height; y++ {
copy(dst[y*w.Width:(y+1)*w.Width], r.r.data[(w.Y+y)*r.r.grid.Width+w.X:(w.Y+y)*r.r.grid.Width+w.X+w.Width])
}
return nil
}
type fakeWriter struct {
f *fakeIO
r *fakeRaster
}
func (w *fakeWriter) WriteInt16(win raster.Window, src []int16) error {
w.f.mu.Lock()
defer w.f.mu.Unlock()
for y := 0; y < win.Height; y++ {
for x := 0; x < win.Width; x++ {
w.r.data[(win.Y+y)*w.r.grid.Width+win.X+x] = float64(src[y*win.Width+x])
}
}
return nil
}
func (w *fakeWriter) Close() error { return nil }
func (f *fakeIO) Open(_ context.Context, path string) (raster.Reader, error) {
f.mu.Lock()
defer f.mu.Unlock()
r, ok := f.files[path]
if !ok {
return nil, fmt.Errorf("fake: %s not found", path)
}
return &fakeReader{r: r}, nil
}
func (f *fakeIO) Create(_ context.Context, path string, g raster.Grid, _ raster.WriterOptions) (raster.Writer, error) {
f.mu.Lock()
defer f.mu.Unlock()
r := &fakeRaster{grid: g, data: make([]float64, g.Width*g.Height)}
f.files[path] = r
return &fakeWriter{f: f, r: r}, nil
}
func (f *fakeIO) SameGrid(a, b raster.Grid) bool { return a == b }