nidus-sync/api/compliance.go

110 lines
3.1 KiB
Go
Raw Permalink 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/platform"
"github.com/gorilla/mux"
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) {
vars := mux.Vars(r)
code := vars["public_id"]
2026-02-28 23:17:30 +00:00
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.Quote("lead.site_id").EQ(psql.Quote("site.id")),
2026-03-05 01:24:18 +00:00
),
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 := platform.OrganizationByID(ctx, int(row.OrganizationID))
2026-02-28 23:17:30 +00:00
if err != nil {
http.Error(w, "org err", http.StatusInternalServerError)
return
}
if org == nil {
http.Error(w, "no org", http.StatusBadRequest)
2026-02-28 23:17:30 +00:00
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
}
func writeImage(ctx context.Context, w http.ResponseWriter, org platform.Organization, level uint, lat, lng float64) error {
img, err := platform.ImageAtPoint(ctx, org, level, lat, lng)
2026-03-01 20:33:16 +00:00
if err != nil {
return fmt.Errorf("image at point: %w", err)
}
log.Info().Int("size", len(img.Content)).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.Content)))
_, err = io.Copy(w, bytes.NewBuffer(img.Content))
2026-02-28 23:17:30 +00:00
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
}