Second checkpoint
This commit is contained in:
58
internal/raster/gdal.go
Normal file
58
internal/raster/gdal.go
Normal file
@@ -0,0 +1,58 @@
|
||||
// Package raster converts rasters to Cloud-Optimized GeoTIFFs and reads their
|
||||
// footprints using the GDAL command-line tools (gdal_translate, gdalinfo),
|
||||
// which must be installed in the worker environment.
|
||||
package raster
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// GDALConverter shells out to GDAL.
|
||||
type GDALConverter struct {
|
||||
compression string
|
||||
}
|
||||
|
||||
// NewGDALConverter returns a converter using DEFLATE compression.
|
||||
func NewGDALConverter() *GDALConverter {
|
||||
return &GDALConverter{compression: "DEFLATE"}
|
||||
}
|
||||
|
||||
// ToCOG converts the source raster to a Cloud-Optimized GeoTIFF at dst. The COG
|
||||
// driver builds internal tiling and overviews.
|
||||
func (c *GDALConverter) ToCOG(ctx context.Context, src, dst string) error {
|
||||
cmd := exec.CommandContext(ctx, "gdal_translate",
|
||||
"-of", "COG",
|
||||
"-co", "COMPRESS="+c.compression,
|
||||
src, dst,
|
||||
)
|
||||
var stderr strings.Builder
|
||||
cmd.Stderr = &stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
return fmt.Errorf("gdal_translate: %w: %s", err, strings.TrimSpace(stderr.String()))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Footprint returns the raster's footprint as a GeoJSON polygon in EPSG:4326, or
|
||||
// nil if the raster has no spatial reference.
|
||||
func (c *GDALConverter) Footprint(ctx context.Context, src string) ([]byte, error) {
|
||||
out, err := exec.CommandContext(ctx, "gdalinfo", "-json", src).Output()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("gdalinfo: %w", err)
|
||||
}
|
||||
|
||||
var info struct {
|
||||
Wgs84Extent json.RawMessage `json:"wgs84Extent"`
|
||||
}
|
||||
if err := json.Unmarshal(out, &info); err != nil {
|
||||
return nil, fmt.Errorf("parse gdalinfo: %w", err)
|
||||
}
|
||||
if len(info.Wgs84Extent) == 0 || string(info.Wgs84Extent) == "null" {
|
||||
return nil, nil
|
||||
}
|
||||
return info.Wgs84Extent, nil
|
||||
}
|
||||
Reference in New Issue
Block a user