nidus-sync/api/compliance.go

110 lines
3.2 KiB
Go
Raw Normal View History

2026-02-28 23:17:30 +00:00
package api
import (
"bytes"
2026-02-28 23:40:21 +00:00
"context"
2026-03-05 01:24:18 +00:00
"encoding/json"
2026-02-28 23:17:30 +00:00
"fmt"
"io"
"net/http"
2026-03-05 01:24:18 +00:00
"github.com/Gleipnir-Technology/bob"
"github.com/Gleipnir-Technology/bob/dialect/psql"
"github.com/Gleipnir-Technology/bob/dialect/psql/sm"
2026-02-28 23:17:30 +00:00
"github.com/Gleipnir-Technology/nidus-sync/db"
"github.com/Gleipnir-Technology/nidus-sync/db/models"
2026-03-05 01:24:18 +00:00
//"github.com/Gleipnir-Technology/nidus-sync/platform"
2026-02-28 23:17:30 +00:00
"github.com/Gleipnir-Technology/nidus-sync/platform/imagetile"
"github.com/go-chi/chi/v5"
2026-03-05 01:24:18 +00:00
"github.com/paulmach/orb/geojson"
2026-02-28 23:17:30 +00:00
"github.com/rs/zerolog/log"
2026-03-05 01:24:18 +00:00
"github.com/stephenafamo/scan"
2026-02-28 23:17:30 +00:00
)
func getComplianceRequestImagePool(w http.ResponseWriter, r *http.Request) {
code := chi.URLParam(r, "public_id")
if code == "" {
http.Error(w, "empty public_id", http.StatusBadRequest)
return
}
ctx := r.Context()
2026-03-05 01:24:18 +00:00
/*
comp, err := models.ComplianceReportRequests.Query(
models.Preload.ComplianceReportRequest.Lead(),
models.SelectWhere.ComplianceReportRequests.PublicID.EQ(code),
).One(ctx, db.PGInstance.BobDB)
if err != nil {
http.Error(w, "no comp", http.StatusInternalServerError)
return
}
2026-02-28 23:17:30 +00:00
2026-03-05 01:24:18 +00:00
lead := comp.R.Lead
site := lead.R.Site
*/
type _Row struct {
Envelope string `db:"parcel_envelope"`
OrganizationID int32 `db:"organization_id"`
}
row, err := bob.One(ctx, db.PGInstance.BobDB, psql.Select(
sm.Columns(
"ST_AsGeoJSON(ST_Envelope(parcel.geometry)) AS parcel_envelope",
"organization.id AS organization_id",
),
sm.From("compliance_report_request"),
sm.InnerJoin("lead").OnEQ(
psql.Quote("compliance_report_request.lead_id"),
psql.Quote("organization.id"),
),
sm.InnerJoin("organization").OnEQ(
psql.Quote("lead.organization_id"),
psql.Quote("organization.id"),
),
sm.InnerJoin("site").On(
psql.And(
psql.Quote("lead.site_id").EQ(psql.Quote("site.id")),
psql.Quote("lead.site_version").EQ(psql.Quote("site.version")),
),
),
sm.InnerJoin("parcel").OnEQ(
psql.Quote("site.parcel_id"),
psql.Quote("parcel.id"),
),
sm.Where(psql.Quote("compliance_report_request").EQ(psql.Arg(code))),
), scan.StructMapper[_Row]())
org, err := models.FindOrganization(ctx, db.PGInstance.BobDB, row.OrganizationID)
2026-02-28 23:17:30 +00:00
if err != nil {
http.Error(w, "no org", http.StatusInternalServerError)
return
}
2026-03-05 01:24:18 +00:00
var polygon geojson.Polygon
err = json.Unmarshal([]byte(row.Envelope), &polygon)
2026-02-28 23:17:30 +00:00
if err != nil {
2026-03-05 01:24:18 +00:00
log.Error().Err(err).Msg("unmarshal json")
http.Error(w, "unmarshal envelope json", http.StatusInternalServerError)
2026-02-28 23:17:30 +00:00
return
}
2026-03-05 01:24:18 +00:00
ring := polygon[0]
2026-02-28 23:17:30 +00:00
p := ring[0]
err = writeImage(ctx, w, org, 19, p[1], p[0])
2026-03-01 20:33:16 +00:00
if err != nil {
log.Error().Err(err).Msg("write image")
http.Error(w, "failed to write image", http.StatusInternalServerError)
return
}
2026-02-28 23:40:21 +00:00
}
2026-03-01 20:33:16 +00:00
func writeImage(ctx context.Context, w http.ResponseWriter, org *models.Organization, level uint, lat, lng float64) error {
img, err := imagetile.ImageAtPoint(ctx, org, level, lat, lng)
if err != nil {
return fmt.Errorf("image at point: %w", err)
}
log.Info().Int("size", len(img)).Msg("image")
2026-02-28 23:17:30 +00:00
w.Header().Set("Content-Type", "image/png")
w.Header().Set("Content-Length", fmt.Sprintf("%d", len(img)))
_, err = io.Copy(w, bytes.NewBuffer(img))
if err != nil {
2026-03-01 20:33:16 +00:00
return fmt.Errorf("copy bytes: %w", err)
2026-02-28 23:17:30 +00:00
}
2026-03-01 20:33:16 +00:00
return nil
2026-02-28 23:17:30 +00:00
}