93 lines
2.2 KiB
Go
93 lines
2.2 KiB
Go
package mapbox
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
type Client struct {
|
|
AccessToken string
|
|
HTTPClient *http.Client
|
|
}
|
|
|
|
func New(token string) *Client {
|
|
return &Client{
|
|
AccessToken: token,
|
|
HTTPClient: &http.Client{
|
|
Timeout: 10 * time.Second,
|
|
},
|
|
}
|
|
}
|
|
|
|
type directionsResponse struct {
|
|
Routes []struct {
|
|
Distance float64 `json:"distance"` // meters
|
|
Duration float64 `json:"duration"` // seconds
|
|
} `json:"routes"`
|
|
Code string `json:"code"`
|
|
}
|
|
|
|
// GetDrivingDistance returns distance in kilometers between two points
|
|
func (c *Client) GetDrivingDistance(lat1, lon1, lat2, lon2 float64) (float64, error) {
|
|
// ... (Existing implementation)
|
|
url := fmt.Sprintf("https://api.mapbox.com/directions/v5/mapbox/driving/%f,%f;%f,%f?access_token=%s",
|
|
lon1, lat1, lon2, lat2, c.AccessToken)
|
|
|
|
resp, err := c.HTTPClient.Get(url)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
return 0, fmt.Errorf("mapbox api error: status %d", resp.StatusCode)
|
|
}
|
|
|
|
var result directionsResponse
|
|
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
if len(result.Routes) == 0 {
|
|
return 0, fmt.Errorf("no route found")
|
|
}
|
|
|
|
// Convert meters to km
|
|
return result.Routes[0].Distance / 1000.0, nil
|
|
}
|
|
|
|
type geocodeResponse struct {
|
|
Features []struct {
|
|
Center []float64 `json:"center"` // [lon, lat]
|
|
} `json:"features"`
|
|
}
|
|
|
|
// Geocode returns [lat, lon] for a given address string.
|
|
func (c *Client) Geocode(address string) (float64, float64, error) {
|
|
url := fmt.Sprintf("https://api.mapbox.com/geocoding/v5/mapbox.places/%s.json?access_token=%s&limit=1",
|
|
fmt.Sprintf("%s", address), c.AccessToken) // Need to URL encode properly in prod
|
|
|
|
resp, err := c.HTTPClient.Get(url)
|
|
if err != nil {
|
|
return 0, 0, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
return 0, 0, fmt.Errorf("mapbox geocode error: status %d", resp.StatusCode)
|
|
}
|
|
|
|
var result geocodeResponse
|
|
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
|
return 0, 0, err
|
|
}
|
|
|
|
if len(result.Features) == 0 {
|
|
return 0, 0, fmt.Errorf("address not found")
|
|
}
|
|
|
|
// Mapbox returns [lon, lat]
|
|
return result.Features[0].Center[1], result.Features[0].Center[0], nil
|
|
}
|