64 lines
1.5 KiB
Go
64 lines
1.5 KiB
Go
package database
|
|
|
|
import (
|
|
"context"
|
|
"crypto/md5"
|
|
"database/sql"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"math"
|
|
"time"
|
|
)
|
|
|
|
// UpsertRadarTile stores a radar tile into table `radar_tiles`.
|
|
// Assumes the table exists with schema compatible to columns used below.
|
|
func UpsertRadarTile(ctx context.Context, db *sql.DB, product string, dt time.Time, z, y, x int, width, height int, data []byte) error {
|
|
if width == 0 {
|
|
width = 256
|
|
}
|
|
if height == 0 {
|
|
height = 256
|
|
}
|
|
step := 360.0 / math.Pow(2, float64(z))
|
|
west := -180.0 + float64(x)*step
|
|
south := -90.0 + float64(y)*step
|
|
east := west + step
|
|
north := south + step
|
|
res := step / float64(width)
|
|
|
|
sum := md5.Sum(data)
|
|
md5hex := hex.EncodeToString(sum[:])
|
|
|
|
q := `
|
|
INSERT INTO radar_tiles (
|
|
product, dt, z, y, x, width, height,
|
|
west, south, east, north, res_deg,
|
|
data, checksum_md5
|
|
) VALUES (
|
|
$1,$2,$3,$4,$5,$6,$7,
|
|
$8,$9,$10,$11,$12,
|
|
$13,$14
|
|
)
|
|
ON CONFLICT (product, dt, z, y, x)
|
|
DO UPDATE SET
|
|
width = EXCLUDED.width,
|
|
height = EXCLUDED.height,
|
|
west = EXCLUDED.west,
|
|
south = EXCLUDED.south,
|
|
east = EXCLUDED.east,
|
|
north = EXCLUDED.north,
|
|
res_deg = EXCLUDED.res_deg,
|
|
data = EXCLUDED.data,
|
|
checksum_md5 = EXCLUDED.checksum_md5`
|
|
|
|
_, err := db.ExecContext(ctx, q,
|
|
product, dt, z, y, x, width, height,
|
|
west, south, east, north, res,
|
|
data, md5hex,
|
|
)
|
|
if err != nil {
|
|
return fmt.Errorf("upsert radar tile (%s %s z=%d y=%d x=%d): %w", product, dt.Format(time.RFC3339), z, y, x, err)
|
|
}
|
|
return nil
|
|
}
|