Match districts on pool reports too

This commit is contained in:
Eli Ribble 2026-02-10 15:09:57 +00:00
parent 5802fe4fd3
commit c74fff6da9
No known key found for this signature in database
4 changed files with 55 additions and 43 deletions

View file

@ -1,6 +1,8 @@
package rmo
import (
"context"
"fmt"
"net/http"
"github.com/Gleipnir-Technology/bob/dialect/psql/sm"
@ -8,7 +10,9 @@ import (
"github.com/Gleipnir-Technology/nidus-sync/db"
"github.com/Gleipnir-Technology/nidus-sync/db/models"
"github.com/Gleipnir-Technology/nidus-sync/html"
"github.com/Gleipnir-Technology/nidus-sync/platform"
"github.com/go-chi/chi/v5"
"github.com/rs/zerolog/log"
)
type ContentDistrict struct {
@ -53,6 +57,39 @@ func getDistrictList(w http.ResponseWriter, r *http.Request) {
)
}
func matchDistrict(ctx context.Context, longitude, latitude *float64, images []ImageUpload) (*int32, error) {
var err error
var org *models.Organization
for _, image := range images {
if image.Exif.GPS == nil {
continue
}
_, org, err = platform.DistrictForLocation(ctx, image.Exif.GPS.Longitude, image.Exif.GPS.Latitude)
if err != nil {
log.Warn().Err(err).Msg("Failed to get district for location")
continue
}
if org != nil {
return &org.ID, nil
}
}
if longitude == nil || latitude == nil {
log.Debug().Msg("No location from images, no latlng for the report itself, cannot match")
return nil, nil
}
_, org, err = platform.DistrictForLocation(ctx, *longitude, *latitude)
if err != nil {
log.Warn().Err(err).Msg("Failed to get district for location")
return nil, fmt.Errorf("Failed to get district for location: %w", err)
}
if org == nil {
log.Debug().Err(err).Float64("lng", *longitude).Float64("lat", *latitude).Msg("No district match by report location")
return nil, nil
}
log.Debug().Err(err).Int32("org_id", org.ID).Float64("lng", *longitude).Float64("lat", *latitude).Msg("Found district match by report location")
return &org.ID, nil
}
func newContentDistrict(d *models.Organization) *ContentDistrict {
if d == nil {
return nil

View file

@ -160,15 +160,13 @@ func postNuisance(w http.ResponseWriter, r *http.Request) {
}
var organization_id *int32
var h3cell h3.Cell
if latlng.Latitude != nil && latlng.Longitude != nil {
organization_id, err = matchDistrict(ctx, *latlng.Longitude, *latlng.Latitude, uploads)
if err != nil {
log.Warn().Err(err).Msg("Failed to match district")
}
h3cell, err = h3utils.GetCell(*latlng.Longitude, *latlng.Latitude, 15)
if err != nil {
respondError(w, "Failedt o get h3 cell", err, http.StatusInternalServerError)
}
organization_id, err = matchDistrict(ctx, latlng.Longitude, latlng.Latitude, uploads)
if err != nil {
log.Warn().Err(err).Msg("Failed to match district")
}
h3cell, err = h3utils.GetCell(*latlng.Longitude, *latlng.Latitude, 15)
if err != nil {
respondError(w, "Failedt o get h3 cell", err, http.StatusInternalServerError)
}
setter := models.PublicreportNuisanceSetter{
@ -212,14 +210,20 @@ func postNuisance(w http.ResponseWriter, r *http.Request) {
respondError(w, "Failed to create database record", err, http.StatusInternalServerError)
return
}
if latlng.Latitude != nil && latlng.Longitude != nil {
geospatial, err := geospatialFromForm(r)
if err != nil {
respondError(w, "Failed to handle geospatial data", err, http.StatusInternalServerError)
return
}
if geospatial.Populated {
_, err = psql.Update(
um.Table("publicreport.nuisance"),
um.SetCol("location").To(fmt.Sprintf("ST_GeometryFromText('Point(%f %f)')", *latlng.Longitude, *latlng.Latitude)),
um.SetCol("h3cell").ToArg(geospatial.Cell),
um.SetCol("location").To(geospatial.GeometryQuery),
um.Where(psql.Quote("id").EQ(psql.Arg(nuisance.ID))),
).Exec(ctx, txn)
if err != nil {
respondError(w, "Failed to insert publicreport", err, http.StatusInternalServerError)
respondError(w, "Failed to insert publicreport.nuisance geospatial", err, http.StatusInternalServerError)
return
}
}

View file

@ -1,7 +1,6 @@
package rmo
import (
"context"
"fmt"
"net/http"
"strconv"
@ -16,7 +15,6 @@ import (
"github.com/Gleipnir-Technology/nidus-sync/db/models"
"github.com/Gleipnir-Technology/nidus-sync/h3utils"
"github.com/Gleipnir-Technology/nidus-sync/html"
"github.com/Gleipnir-Technology/nidus-sync/platform"
"github.com/Gleipnir-Technology/nidus-sync/platform/report"
"github.com/aarondl/opt/omit"
"github.com/aarondl/opt/omitnull"
@ -92,33 +90,6 @@ func getRegisterNotificationsComplete(w http.ResponseWriter, r *http.Request) {
},
)
}
func matchDistrict(ctx context.Context, longitude, latitude float64, images []ImageUpload) (*int32, error) {
for _, image := range images {
if image.Exif.GPS == nil {
continue
}
_, org, err := platform.DistrictForLocation(ctx, image.Exif.GPS.Longitude, image.Exif.GPS.Latitude)
if err != nil {
log.Warn().Err(err).Msg("Failed to get district for location")
continue
}
if org != nil {
return &org.ID, nil
}
}
_, org, err := platform.DistrictForLocation(ctx, longitude, latitude)
if err != nil {
log.Warn().Err(err).Msg("Failed to get district for location")
return nil, fmt.Errorf("Failed to get district for location: %w", err)
}
if org == nil {
log.Debug().Err(err).Float64("lng", longitude).Float64("lat", latitude).Msg("No district match by report location")
return nil, nil
}
log.Debug().Err(err).Int32("org_id", org.ID).Float64("lng", longitude).Float64("lat", latitude).Msg("Found district match by report location")
return &org.ID, nil
}
func postQuick(w http.ResponseWriter, r *http.Request) {
err := r.ParseMultipartForm(32 << 10) // 32 MB buffer
if err != nil {
@ -170,7 +141,7 @@ func postQuick(w http.ResponseWriter, r *http.Request) {
return
}
organization_id, err := matchDistrict(ctx, longitude, latitude, uploads)
organization_id, err := matchDistrict(ctx, &longitude, &latitude, uploads)
if err != nil {
log.Warn().Err(err).Msg("Failed to match district")
}

View file

@ -152,7 +152,7 @@ func postWater(w http.ResponseWriter, r *http.Request) {
um.Where(psql.Quote("id").EQ(psql.Arg(pool.ID))),
).Exec(ctx, tx)
if err != nil {
respondError(w, "Failed to insert publicreport.pool", err, http.StatusInternalServerError)
respondError(w, "Failed to update publicreport.pool geospatial", err, http.StatusInternalServerError)
return
}
}