mirror of
https://github.com/imjasonh/staticmaps
synced 2026-07-09 11:16:42 +00:00
return responses that don't include Status and ErrorMessage, instead return an APIError if the API response is not 'OK'
This commit is contained in:
parent
41f9b8b763
commit
aa3b05a35f
6 changed files with 134 additions and 81 deletions
|
|
@ -32,12 +32,15 @@ const (
|
|||
|
||||
// TODO: via_waypoint not documented
|
||||
|
||||
func (c Client) Directions(orig, dest Location, opts *DirectionsOpts) (*DirectionsResponse, error) {
|
||||
var d DirectionsResponse
|
||||
func (c Client) Directions(orig, dest Location, opts *DirectionsOpts) ([]Route, error) {
|
||||
var d directionsResponse
|
||||
if err := c.doDecode(baseURL+directions(orig, dest, opts), &d); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &d, nil
|
||||
if d.Status != StatusOK {
|
||||
return nil, APIError{d.Status, d.ErrorMessage}
|
||||
}
|
||||
return d.Routes, nil
|
||||
}
|
||||
|
||||
func directions(orig, dest Location, opts *DirectionsOpts) string {
|
||||
|
|
@ -89,29 +92,31 @@ func (do *DirectionsOpts) update(p url.Values) {
|
|||
}
|
||||
}
|
||||
|
||||
type DirectionsResponse struct {
|
||||
Status string `json:"status"`
|
||||
ErrorMessage string `json:"error_message"`
|
||||
Routes []struct {
|
||||
Summary string `json:"summary"`
|
||||
Legs []struct {
|
||||
Duration *Duration `json:"duration"`
|
||||
DurationInTraffic *Duration `json:"duration_in_traffic"`
|
||||
Distance *Distance `json:"distance"`
|
||||
ArrivalTime Time `json:"arrival_time"`
|
||||
DepartureTime Time `json:"departure_time"`
|
||||
StartLocation *LatLng `json:"start_location"`
|
||||
EndLocation *LatLng `json:"end_location"`
|
||||
StartAddress string `json:"start_address"`
|
||||
EndAddress string `json:"end_address"`
|
||||
Steps []Step `json:"steps"`
|
||||
} `json:"legs"`
|
||||
Bounds Bounds `json:"bounds"`
|
||||
Copyrights string `json:"copyrights"`
|
||||
OverviewPolyline Polyline `json:"overview_polyline"`
|
||||
Warnings []string `json:"warnings"`
|
||||
WaypointOrder []int `json:"waypoint_order"`
|
||||
} `json:"routes"`
|
||||
type directionsResponse struct {
|
||||
Status string `json:"status"`
|
||||
ErrorMessage string `json:"error_message"`
|
||||
Routes []Route `json:"routes"`
|
||||
}
|
||||
|
||||
type Route struct {
|
||||
Summary string `json:"summary"`
|
||||
Legs []struct {
|
||||
Duration *Duration `json:"duration"`
|
||||
DurationInTraffic *Duration `json:"duration_in_traffic"`
|
||||
Distance *Distance `json:"distance"`
|
||||
ArrivalTime Time `json:"arrival_time"`
|
||||
DepartureTime Time `json:"departure_time"`
|
||||
StartLocation *LatLng `json:"start_location"`
|
||||
EndLocation *LatLng `json:"end_location"`
|
||||
StartAddress string `json:"start_address"`
|
||||
EndAddress string `json:"end_address"`
|
||||
Steps []Step `json:"steps"`
|
||||
} `json:"legs"`
|
||||
Bounds Bounds `json:"bounds"`
|
||||
Copyrights string `json:"copyrights"`
|
||||
OverviewPolyline Polyline `json:"overview_polyline"`
|
||||
Warnings []string `json:"warnings"`
|
||||
WaypointOrder []int `json:"waypoint_order"`
|
||||
}
|
||||
|
||||
type Time struct {
|
||||
|
|
|
|||
17
distance.go
17
distance.go
|
|
@ -6,12 +6,15 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
func (c Client) DistanceMatrix(orig, dest []Location, opts *DistanceMatrixOpts) (*DistanceMatrixResponse, error) {
|
||||
var d DistanceMatrixResponse
|
||||
func (c Client) DistanceMatrix(orig, dest []Location, opts *DistanceMatrixOpts) (*DistanceMatrixResult, error) {
|
||||
var d distanceResponse
|
||||
if err := c.doDecode(baseURL+distancematrix(orig, dest, opts), &d); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &d, nil
|
||||
if d.Status != StatusOK {
|
||||
return nil, APIError{d.Status, ""}
|
||||
}
|
||||
return &d.DistanceMatrixResult, nil
|
||||
}
|
||||
|
||||
func distancematrix(orig, dest []Location, opts *DistanceMatrixOpts) string {
|
||||
|
|
@ -49,8 +52,12 @@ func (o *DistanceMatrixOpts) update(p url.Values) {
|
|||
}
|
||||
}
|
||||
|
||||
type DistanceMatrixResponse struct {
|
||||
Status string `json:"status"`
|
||||
type distanceResponse struct {
|
||||
Status string `json:"status"`
|
||||
DistanceMatrixResult
|
||||
}
|
||||
|
||||
type DistanceMatrixResult struct {
|
||||
OriginAddresses []string `json:"origin_addresses"`
|
||||
DestinationAddresses []string `json:"destination_addresses"`
|
||||
Rows []struct {
|
||||
|
|
|
|||
51
elevation.go
51
elevation.go
|
|
@ -5,36 +5,48 @@ import (
|
|||
"net/url"
|
||||
)
|
||||
|
||||
func (c Client) Elevation(ll []LatLng) (*ElevationResponse, error) {
|
||||
var r ElevationResponse
|
||||
func (c Client) Elevation(ll []LatLng) ([]ElevationResult, error) {
|
||||
var r elevationResponse
|
||||
if err := c.doDecode(baseURL+elevation(ll), &r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &r, nil
|
||||
if r.Status != StatusOK {
|
||||
return nil, APIError{r.Status, ""}
|
||||
}
|
||||
return r.Results, nil
|
||||
}
|
||||
|
||||
func (c Client) ElevationPolyline(p string) (*ElevationResponse, error) {
|
||||
var r ElevationResponse
|
||||
func (c Client) ElevationPolyline(p string) ([]ElevationResult, error) {
|
||||
var r elevationResponse
|
||||
if err := c.doDecode(baseURL+elevationpoly(p), &r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &r, nil
|
||||
if r.Status != StatusOK {
|
||||
return nil, APIError{r.Status, ""}
|
||||
}
|
||||
return r.Results, nil
|
||||
}
|
||||
|
||||
func (c Client) ElevationPath(ll []LatLng, samples int) (*ElevationResponse, error) {
|
||||
var r ElevationResponse
|
||||
func (c Client) ElevationPath(ll []LatLng, samples int) ([]ElevationResult, error) {
|
||||
var r elevationResponse
|
||||
if err := c.doDecode(baseURL+elevationpath(ll, samples), &r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &r, nil
|
||||
if r.Status != StatusOK {
|
||||
return nil, APIError{r.Status, ""}
|
||||
}
|
||||
return r.Results, nil
|
||||
}
|
||||
|
||||
func (c Client) ElevationPathPoly(p string, samples int) (*ElevationResponse, error) {
|
||||
var r ElevationResponse
|
||||
func (c Client) ElevationPathPoly(p string, samples int) ([]ElevationResult, error) {
|
||||
var r elevationResponse
|
||||
if err := c.doDecode(baseURL+elevationpathpoly(p, samples), &r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &r, nil
|
||||
if r.Status != StatusOK {
|
||||
return nil, APIError{r.Status, ""}
|
||||
}
|
||||
return r.Results, nil
|
||||
}
|
||||
|
||||
func elevation(ll []LatLng) string {
|
||||
|
|
@ -63,11 +75,12 @@ func elevationpathpoly(poly string, s int) string {
|
|||
return "elevation/json?" + p.Encode()
|
||||
}
|
||||
|
||||
type ElevationResponse struct {
|
||||
Results []struct {
|
||||
Elevation float64 `json:"elevation"`
|
||||
Location LatLng `json:"location"`
|
||||
Resolution float64 `json:"resolution"`
|
||||
} `json:"results"`
|
||||
Status string `json:"status"`
|
||||
type elevationResponse struct {
|
||||
Results []ElevationResult `json:"results"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
type ElevationResult struct {
|
||||
Elevation float64 `json:"elevation"`
|
||||
Location LatLng `json:"location"`
|
||||
Resolution float64 `json:"resolution"`
|
||||
}
|
||||
|
|
|
|||
57
geocode.go
57
geocode.go
|
|
@ -21,12 +21,15 @@ const (
|
|||
// TODO: enums for https://developers.google.com/maps/documentation/geocoding/#Types
|
||||
)
|
||||
|
||||
func (c Client) Geocode(opts *GeocodeOpts) (*GeocodeResponse, error) {
|
||||
var r GeocodeResponse
|
||||
func (c Client) Geocode(opts *GeocodeOpts) ([]GeocodeResult, error) {
|
||||
var r geocodeResponse
|
||||
if err := c.doDecode(baseURL+geocode(opts), &r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &r, nil
|
||||
if r.Status != StatusOK {
|
||||
return nil, APIError{r.Status, ""}
|
||||
}
|
||||
return r.Results, nil
|
||||
}
|
||||
|
||||
func geocode(opts *GeocodeOpts) string {
|
||||
|
|
@ -79,33 +82,37 @@ func (g *GeocodeOpts) update(p url.Values) {
|
|||
}
|
||||
}
|
||||
|
||||
type GeocodeResponse struct {
|
||||
Results []struct {
|
||||
AddressComponents []struct {
|
||||
LongName string `json:"long_name"`
|
||||
ShortName string `json:"short_name"`
|
||||
Types []string `json:"types"`
|
||||
} `json:"address_components"`
|
||||
PostcodeLocalities []string `json:"postcode_localities"`
|
||||
FormattedAddress string `json:"formatted_address"`
|
||||
Geometry struct {
|
||||
Location LatLng `json:"location"`
|
||||
LocationType string `json:"location_type"`
|
||||
Viewport Bounds `json:"viewport"`
|
||||
Bounds Bounds `json:"bounds"`
|
||||
} `json:"geometry"`
|
||||
Types []string `json:"types"`
|
||||
PartialMatch string `json:"partial_match"`
|
||||
} `json:"results"`
|
||||
Status string `json:"status"`
|
||||
type geocodeResponse struct {
|
||||
Results []GeocodeResult `json:"results"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
type GeocodeResult struct {
|
||||
AddressComponents []struct {
|
||||
LongName string `json:"long_name"`
|
||||
ShortName string `json:"short_name"`
|
||||
Types []string `json:"types"`
|
||||
} `json:"address_components"`
|
||||
PostcodeLocalities []string `json:"postcode_localities"`
|
||||
FormattedAddress string `json:"formatted_address"`
|
||||
Geometry struct {
|
||||
Location LatLng `json:"location"`
|
||||
LocationType string `json:"location_type"`
|
||||
Viewport Bounds `json:"viewport"`
|
||||
Bounds Bounds `json:"bounds"`
|
||||
} `json:"geometry"`
|
||||
Types []string `json:"types"`
|
||||
PartialMatch string `json:"partial_match"`
|
||||
}
|
||||
|
||||
func (c Client) ReverseGeocode(ll LatLng, opts *ReverseGeocodeOpts) (*GeocodeResponse, error) {
|
||||
var r GeocodeResponse
|
||||
func (c Client) ReverseGeocode(ll LatLng, opts *ReverseGeocodeOpts) ([]GeocodeResult, error) {
|
||||
var r geocodeResponse
|
||||
if err := c.doDecode(baseURL+reversegeocode(ll, opts), &r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &r, nil
|
||||
if r.Status != StatusOK {
|
||||
return nil, APIError{r.Status, ""}
|
||||
}
|
||||
return r.Results, nil
|
||||
}
|
||||
|
||||
type ReverseGeocodeOpts struct {
|
||||
|
|
|
|||
14
maps.go
14
maps.go
|
|
@ -57,6 +57,7 @@ func (c Client) doDecode(url string, r interface{}) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// HTTPError indicates an error communicating with the API, and includes the HTTP response returned from the server.
|
||||
type HTTPError struct {
|
||||
Response *http.Response
|
||||
}
|
||||
|
|
@ -65,6 +66,19 @@ func (e HTTPError) Error() string {
|
|||
return fmt.Sprintf("http error %d", e.Response.StatusCode)
|
||||
}
|
||||
|
||||
// APIError indicates a failure response from the API server, even though a successful HTTP response was returned.
|
||||
// Its Status and Message fields can be consulted for more information about the specific error conditions.
|
||||
type APIError struct {
|
||||
Status, Message string
|
||||
}
|
||||
|
||||
func (e APIError) Error() string {
|
||||
if e.Message != "" {
|
||||
return fmt.Sprintf("API error %q: %s", e.Status, e.Message)
|
||||
}
|
||||
return fmt.Sprintf("API Error %q", e.Status)
|
||||
}
|
||||
|
||||
type Location interface {
|
||||
Location() string
|
||||
}
|
||||
|
|
|
|||
19
timezone.go
19
timezone.go
|
|
@ -6,12 +6,15 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
func (c Client) TimeZone(ll LatLng, t time.Time, opts *TimeZoneOpts) (*TimeZoneResponse, error) {
|
||||
var r TimeZoneResponse
|
||||
func (c Client) TimeZone(ll LatLng, t time.Time, opts *TimeZoneOpts) (*TimeZoneResult, error) {
|
||||
var r timeZoneResponse
|
||||
if err := c.doDecode(baseURL+timezone(ll, t, opts), &r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &r, nil
|
||||
if r.Status != StatusOK {
|
||||
return nil, APIError{r.Status, r.ErrorMessage}
|
||||
}
|
||||
return &r.TimeZoneResult, nil
|
||||
}
|
||||
|
||||
func timezone(ll LatLng, t time.Time, opts *TimeZoneOpts) string {
|
||||
|
|
@ -35,19 +38,23 @@ func (t *TimeZoneOpts) update(p url.Values) {
|
|||
}
|
||||
}
|
||||
|
||||
type TimeZoneResponse struct {
|
||||
type timeZoneResponse struct {
|
||||
Status string `json:"status"`
|
||||
ErrorMessage string `json:"error_message"`
|
||||
TimeZoneResult
|
||||
}
|
||||
|
||||
type TimeZoneResult struct {
|
||||
DSTOffset int64 `json:"dstOffset"` // secs offset for DST
|
||||
RawOffset int64 `json:"rawOffset"`
|
||||
TimeZoneID string `json:"timeZoneId"`
|
||||
TimeZoneName string `json:"timeZoneName"`
|
||||
}
|
||||
|
||||
func (r TimeZoneResponse) DSTOffsetDuration() time.Duration {
|
||||
func (r TimeZoneResult) DSTOffsetDuration() time.Duration {
|
||||
return time.Duration(r.DSTOffset) * time.Second
|
||||
}
|
||||
|
||||
func (r TimeZoneResponse) RawOffsetDuration() time.Duration {
|
||||
func (r TimeZoneResult) RawOffsetDuration() time.Duration {
|
||||
return time.Duration(r.RawOffset) * time.Second
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue