2026-01-29 23:55:41 +00:00
package rmo
2026-01-09 19:43:19 +00:00
import (
"fmt"
"net/http"
"strconv"
"github.com/Gleipnir-Technology/nidus-sync/h3utils"
"github.com/rs/zerolog/log"
"github.com/uber/h3-go/v4"
)
type GeospatialData struct {
Cell h3 . Cell
GeometryQuery string
Populated bool
}
func geospatialFromForm ( r * http . Request ) ( GeospatialData , error ) {
lat := r . FormValue ( "latitude" )
lng := r . FormValue ( "longitude" )
accuracy_type := r . FormValue ( "latlng-accuracy-type" )
accuracy_value := r . FormValue ( "latlng-accuracy-value" )
if lat == "" || lng == "" {
return GeospatialData { Populated : false } , nil
}
latitude , err := strconv . ParseFloat ( lat , 64 )
if err != nil {
return GeospatialData { Populated : false } , fmt . Errorf ( "Failed to create parse latitude: %v" , err )
}
longitude , err := strconv . ParseFloat ( lng , 64 )
if err != nil {
return GeospatialData { Populated : false } , fmt . Errorf ( "Failed to create parse longitude: %v" , err )
}
var resolution int
switch accuracy_type {
// These accuracy_type strings come from the Mapbox Geocoding API definition and
// are far from scientific
case "rooftop" :
resolution = 14
case "parcel" :
resolution = 13
case "point" :
resolution = 13
case "interpolated" :
resolution = 12
case "approximate" :
resolution = 11
case "intersection" :
resolution = 10
// This is a special indicator that we got our location from the browser measurements
case "meters" :
2026-02-06 15:41:21 +00:00
case "browser" :
2026-01-09 19:43:19 +00:00
accuracy_in_meters , err := strconv . ParseFloat ( accuracy_value , 64 )
if err != nil {
return GeospatialData { Populated : false } , fmt . Errorf ( "Failed to parse '%s' as an accuracy in meters: %v" , accuracy_value , err )
}
resolution = h3utils . MeterAccuracyToH3Resolution ( accuracy_in_meters )
default :
log . Warn ( ) . Str ( "accuracy-type" , accuracy_type ) . Msg ( "unrecognized accuracy type, this indicates either a weird client or misbehaving web page. Defaulting to resolution 13" )
resolution = 13
}
cell , err := h3utils . GetCell ( longitude , latitude , resolution )
return GeospatialData {
Cell : cell ,
2026-03-08 02:43:00 +00:00
GeometryQuery : fmt . Sprintf ( "ST_Point(%f, %f, 4326)" , longitude , latitude ) ,
2026-01-09 19:43:19 +00:00
Populated : true ,
} , nil
}