2026-04-05 21:57:30 +00:00
|
|
|
package resource
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"net/http"
|
2026-04-06 16:53:26 +00:00
|
|
|
|
|
|
|
|
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
|
|
|
|
ngeocode "github.com/Gleipnir-Technology/nidus-sync/platform/geocode"
|
|
|
|
|
"github.com/Gleipnir-Technology/nidus-sync/platform/types"
|
|
|
|
|
"github.com/gorilla/mux"
|
2026-04-05 21:57:30 +00:00
|
|
|
//"github.com/rs/zerolog/log"
|
2026-04-06 16:53:26 +00:00
|
|
|
"github.com/uber/h3-go/v4"
|
2026-04-05 21:57:30 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type geocodeR struct {
|
|
|
|
|
router *router
|
|
|
|
|
}
|
2026-04-06 16:53:26 +00:00
|
|
|
type geocode struct {
|
|
|
|
|
Address types.Address `json:"address"`
|
|
|
|
|
Cell h3.Cell `json:"cell"`
|
|
|
|
|
Location types.Location `json:"location"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func newGeocode(g *ngeocode.GeocodeResult) *geocode {
|
|
|
|
|
return &geocode{
|
|
|
|
|
Address: g.Address,
|
|
|
|
|
Cell: g.Cell,
|
|
|
|
|
Location: g.Location,
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-04-05 21:57:30 +00:00
|
|
|
|
|
|
|
|
type geocodeSuggestion struct {
|
|
|
|
|
Detail string `json:"detail"`
|
2026-04-06 16:53:26 +00:00
|
|
|
GID string `json:"gid"`
|
2026-04-05 21:57:30 +00:00
|
|
|
Locality string `json:"locality"`
|
2026-04-06 16:53:26 +00:00
|
|
|
Type string `json:"type"`
|
2026-04-05 21:57:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Geocode(r *router) *geocodeR {
|
|
|
|
|
return &geocodeR{
|
|
|
|
|
router: r,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-06 16:53:26 +00:00
|
|
|
func (res *geocodeR) ByGID(ctx context.Context, r *http.Request, query QueryParams) (*geocode, *nhttp.ErrorWithStatus) {
|
|
|
|
|
vars := mux.Vars(r)
|
|
|
|
|
gid := vars["id"]
|
|
|
|
|
if gid == "" {
|
|
|
|
|
return nil, nhttp.NewBadRequest("no id")
|
|
|
|
|
}
|
|
|
|
|
g, err := ngeocode.ByGID(ctx, gid)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, nhttp.NewError("bygid: %w", err)
|
|
|
|
|
}
|
|
|
|
|
return newGeocode(g), nil
|
|
|
|
|
}
|
|
|
|
|
func (res *geocodeR) Reverse(ctx context.Context, r *http.Request, location types.Location) (*geocode, *nhttp.ErrorWithStatus) {
|
|
|
|
|
g, err := ngeocode.ReverseGeocode(ctx, location)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, nhttp.NewError("reverse: %w", err)
|
|
|
|
|
}
|
|
|
|
|
return newGeocode(g), nil
|
|
|
|
|
}
|
2026-04-05 21:57:30 +00:00
|
|
|
func (res *geocodeR) SuggestionList(ctx context.Context, r *http.Request, query QueryParams) ([]*geocodeSuggestion, *nhttp.ErrorWithStatus) {
|
|
|
|
|
if query.Query == nil {
|
|
|
|
|
return nil, nhttp.NewBadRequest("you must include a query")
|
|
|
|
|
}
|
2026-04-06 16:53:26 +00:00
|
|
|
completions, err := ngeocode.Autocomplete(ctx, nil, *query.Query)
|
2026-04-05 21:57:30 +00:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, nhttp.NewError("geocode: %w", err)
|
|
|
|
|
}
|
|
|
|
|
result := make([]*geocodeSuggestion, len(completions))
|
|
|
|
|
for i, c := range completions {
|
|
|
|
|
result[i] = &geocodeSuggestion{
|
|
|
|
|
Detail: c.Detail,
|
2026-04-06 16:53:26 +00:00
|
|
|
GID: c.GID,
|
2026-04-05 21:57:30 +00:00
|
|
|
Locality: c.Locality,
|
2026-04-06 16:53:26 +00:00
|
|
|
Type: c.Layer,
|
2026-04-05 21:57:30 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result, nil
|
|
|
|
|
}
|