diff --git a/api/api.go b/api/api.go index aff1bb40..2e0a268c 100644 --- a/api/api.go +++ b/api/api.go @@ -78,6 +78,39 @@ func apiAudioContentPost(w http.ResponseWriter, r *http.Request, u *models.User) w.WriteHeader(http.StatusOK) } +func apiGetDistrict(w http.ResponseWriter, r *http.Request) { + var latStr, lngStr string + err := r.ParseForm() + if err != nil { + render.Render(w, r, errRender(fmt.Errorf("Failed to parse GET form: %w", err))) + return + } else { + latStr = r.FormValue("lat") + lngStr = r.FormValue("lng") + } + lat, err := strconv.ParseFloat(latStr, 64) + if err != nil { + render.Render(w, r, errRender(fmt.Errorf("Failed to parse lat as float: %w", err))) + return + } + lng, err := strconv.ParseFloat(lngStr, 64) + if err != nil { + render.Render(w, r, errRender(fmt.Errorf("Failed to parse lng as float: %w", err))) + return + } + district, err := platform.DistrictForLocation(r.Context(), lng, lat) + if err != nil { + render.Render(w, r, errRender(fmt.Errorf("Failed to get district: %w", err))) + return + } + d := ResponseDistrict{ + Agency: district.Agency.GetOr(""), + } + if err := render.Render(w, r, d); err != nil { + render.Render(w, r, errRender(err)) + } +} + func handleClientIos(w http.ResponseWriter, r *http.Request, u *models.User) { var sinceStr string err := r.ParseForm() diff --git a/api/endpoint.go b/api/endpoint.go index 6a9a3bbe..fd86109f 100644 --- a/api/endpoint.go +++ b/api/endpoint.go @@ -20,6 +20,7 @@ func AddRoutes(r chi.Router) { r.Method("POST", "/image/{uuid}/content", auth.NewEnsureAuth(apiImageContentPost)) // Unauthenticated endpoints + r.Get("/district", apiGetDistrict) r.Get("/webhook/fieldseeker", webhookFieldseeker) r.Post("/webhook/fieldseeker", webhookFieldseeker) } diff --git a/api/types.go b/api/types.go index 9ce61554..b511b456 100644 --- a/api/types.go +++ b/api/types.go @@ -62,6 +62,10 @@ type NoteAudioPayload struct { Version int32 `json:"version"` } +type ResponseDistrict struct { + Agency string `json:"agency"` +} + type ResponseMosquitoSource struct { Access string `json:"access"` Active *bool `json:"active"` @@ -154,6 +158,10 @@ func NewResponseMosquitoInspections(inspections models.FieldseekerMosquitoinspec return results } +func (rd ResponseDistrict) Render(w http.ResponseWriter, r *http.Request) error { + return nil +} + func (rtd ResponseMosquitoSource) Render(w http.ResponseWriter, r *http.Request) error { return nil } diff --git a/platform/district.go b/platform/district.go new file mode 100644 index 00000000..fd3d76c7 --- /dev/null +++ b/platform/district.go @@ -0,0 +1,31 @@ +package platform + +import ( + "context" + "fmt" + + "github.com/Gleipnir-Technology/nidus-sync/db" + "github.com/Gleipnir-Technology/nidus-sync/db/models" + + "github.com/stephenafamo/bob/dialect/psql" + "github.com/stephenafamo/bob/dialect/psql/sm" +) + +func DistrictForLocation(ctx context.Context, lng float64, lat float64) (*models.District, error) { + rows, err := models.Districts.Query( + sm.Where( + psql.F("ST_Contains", psql.Raw("geom_4326"), psql.F("ST_SetSRID", psql.F("ST_MakePoint", psql.Arg(lng), psql.Arg(lat)), psql.Arg(4326))), + ), + ).All(ctx, db.PGInstance.BobDB) + if err != nil { + return nil, fmt.Errorf("failed to query district: %w", err) + } + switch len(rows) { + case 0: + return nil, nil + case 1: + return rows[0], nil + default: + return nil, nil + } +} diff --git a/sync/template/district.html b/sync/template/district.html index a75253cd..c9c6aaec 100644 --- a/sync/template/district.html +++ b/sync/template/district.html @@ -35,6 +35,18 @@ function setDistrictColors(map) { //console.log("using fallback district coloring"); } } + +async function fetchDistrict(lng, lat) { + try { + const url = `/api/district?lat=${lat}&lng=${lng}` + const response = await fetch(url); + const data = await response.json(); + console.log("district", data); + } catch (error) { + console.error('Error fetching geocoding suggestions:', error); + } +} + function onLoad() { console.log("Setting up the map..."); mapboxgl.accessToken = MAPBOX_ACCESS_TOKEN; @@ -118,6 +130,7 @@ function onLoad() { });*/ addressDisplay.show(l); + fetchDistrict(l.geometry.coordinates[0], l.geometry.coordinates[1]); }); } document.addEventListener("DOMContentLoaded", onLoad);