fix: 修正雨量瓦片存储的时区
This commit is contained in:
parent
0fd915a2ee
commit
08fa1e8a04
@ -7,6 +7,7 @@ import (
|
|||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
"weatherstation/internal/radar"
|
"weatherstation/internal/radar"
|
||||||
|
"weatherstation/internal/rain"
|
||||||
"weatherstation/internal/server"
|
"weatherstation/internal/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -21,6 +22,11 @@ func main() {
|
|||||||
log.Fatalf("service-radar start error: %v", err)
|
log.Fatalf("service-radar start error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Also start CMPA hourly rain scheduler (StoreToDB=true; tiles/dir/url from env inside package)
|
||||||
|
if err := rain.Start(ctx, rain.Options{StoreToDB: true}); err != nil {
|
||||||
|
log.Fatalf("service-rain (embedded) start error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Keep process alive until signal
|
// Keep process alive until signal
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
log.Println("service-radar shutting down")
|
log.Println("service-radar shutting down")
|
||||||
|
|||||||
@ -121,14 +121,23 @@ func runOnce(ctx context.Context, opts Options, loc *time.Location) error {
|
|||||||
|
|
||||||
func downloadAndStoreTile(ctx context.Context, local time.Time, dateStr, hh, mm string, z, y, x int, opts Options) error {
|
func downloadAndStoreTile(ctx context.Context, local time.Time, dateStr, hh, mm string, z, y, x int, opts Options) error {
|
||||||
url := fmt.Sprintf("https://image.data.cma.cn/tiles/China/CMPA_RT_China_0P01_HOR-PRE_GISJPG_Tiles/%s/%s/%s/%d/%d/%d.bin", dateStr, hh, mm, z, y, x)
|
url := fmt.Sprintf("https://image.data.cma.cn/tiles/China/CMPA_RT_China_0P01_HOR-PRE_GISJPG_Tiles/%s/%s/%s/%d/%d/%d.bin", dateStr, hh, mm, z, y, x)
|
||||||
// skip if exists in DB
|
// skip if exists in DB; dt source configurable (default: local slot time)
|
||||||
|
dtSource := strings.ToLower(getenvDefault("RAIN_DT_SOURCE", "local")) // local|url
|
||||||
|
var product string
|
||||||
|
var dtForKey time.Time
|
||||||
if ref, err := ParseCMPATileURL(url); err == nil {
|
if ref, err := ParseCMPATileURL(url); err == nil {
|
||||||
exists, err := databaseHas(ctx, ref.Product, ref.DT, z, y, x)
|
product = ref.Product
|
||||||
|
if dtSource == "url" {
|
||||||
|
dtForKey = ref.DT
|
||||||
|
} else {
|
||||||
|
dtForKey = local
|
||||||
|
}
|
||||||
|
exists, err := databaseHas(ctx, product, dtForKey, z, y, x)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if exists {
|
if exists {
|
||||||
log.Printf("[rain] skip: already in DB z=%d y=%d x=%d dt(local)=%s url=%s", z, y, x, ref.DT.Format("2006-01-02 15:04"), url)
|
log.Printf("[rain] skip: already in DB z=%d y=%d x=%d dt(%s)=%s url=%s", z, y, x, dtSource, dtForKey.Format("2006-01-02 15:04"), url)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -150,10 +159,30 @@ func downloadAndStoreTile(ctx context.Context, local time.Time, dateStr, hh, mm
|
|||||||
if rerr != nil {
|
if rerr != nil {
|
||||||
return fmt.Errorf("read saved tile: %w", rerr)
|
return fmt.Errorf("read saved tile: %w", rerr)
|
||||||
}
|
}
|
||||||
if err := StoreTileBytes(ctx, url, b); err != nil {
|
// Determine product and dt according to dtSource
|
||||||
|
if product == "" {
|
||||||
|
if ref, e := ParseCMPATileURL(url); e == nil {
|
||||||
|
product = ref.Product
|
||||||
|
if dtSource == "url" {
|
||||||
|
dtForKey = ref.DT
|
||||||
|
} else {
|
||||||
|
dtForKey = local
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if product == "" {
|
||||||
|
return fmt.Errorf("cannot parse product from url for DB store")
|
||||||
|
}
|
||||||
|
if dtForKey.IsZero() {
|
||||||
|
if dtSource == "url" {
|
||||||
|
return fmt.Errorf("dt source=url but failed to parse dt")
|
||||||
|
}
|
||||||
|
dtForKey = local
|
||||||
|
}
|
||||||
|
if err := database.UpsertRainTile(ctx, database.GetDB(), product, dtForKey, z, y, x, 256, 256, b); err != nil {
|
||||||
return fmt.Errorf("store tile db: %w", err)
|
return fmt.Errorf("store tile db: %w", err)
|
||||||
}
|
}
|
||||||
log.Printf("[rain] stored to DB: %s", fname)
|
log.Printf("[rain] stored to DB: %s (dt=%s, source=%s)", fname, dtForKey.Format("2006-01-02 15:04:05"), dtSource)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,8 @@ package rain
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -65,6 +67,15 @@ func StoreTileBytes(ctx context.Context, urlOrPath string, data []byte) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
// 可选:强制 +8 小时(若上游传入的时间已为 UTC 且未转换,可用此开关修正)
|
||||||
|
if strings.EqualFold(strings.TrimSpace(strings.ToLower(os.Getenv("RAIN_FORCE_SHIFT8"))), "1") {
|
||||||
|
ref.DT = ref.DT.Add(8 * time.Hour)
|
||||||
|
}
|
||||||
|
// 可选调试:打印解析出的时间(CST)与 URL
|
||||||
|
if strings.EqualFold(strings.TrimSpace(strings.ToLower(os.Getenv("RAIN_DEBUG"))), "1") {
|
||||||
|
log.Printf("[rain] store tile: url=%s -> product=%s dt(local)=%s z=%d y=%d x=%d",
|
||||||
|
urlOrPath, ref.Product, ref.DT.Format("2006-01-02 15:04:05 -0700"), ref.Z, ref.Y, ref.X)
|
||||||
|
}
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
return database.UpsertRainTile(ctx, db, ref.Product, ref.DT, ref.Z, ref.Y, ref.X, 256, 256, data)
|
return database.UpsertRainTile(ctx, db, ref.Product, ref.DT, ref.Z, ref.Y, ref.X, 256, 256, data)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user