func (g *GoogleGeo) ReverseGeocodeDetailed(p *Point) (*GoogleReverseGeocodeResponse, error) {
	queryStr, err := g.reverseGeocodeQueryStr(p)
	if err != nil {
		return nil, err
	}
	data, err := g.request(queryStr)
	if err != nil {
		return nil, err
	}
	res := &GoogleReverseGeocodeResponse{}
	if err := json.Unmarshal(data, res); err != nil {
		return nil, err
	}
	if len(res.Results) == 0 {
		return nil, errGoogleZeroResults
	}
	return res, nil
}
ReverseGeocodeDetailed geocodes the pointer to a Point struct and returns detailed address information.
package geolocate
import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"time"
)
type GoogleGeo struct {
	client *http.Client
	apiKey string
	region string
}
func NewGoogleGeo(apiKey string) *GoogleGeo {
	return &GoogleGeo{
		client: &http.Client{Timeout: time.Second * 10},
		apiKey: apiKey,
	}
}
type googleGeocodeResponse struct {
	Results []struct {
		FormattedAddress string `json:"formatted_address"`
		Geometry         struct {
			Location struct {
				Lat float64
				Lng float64
			}
			LocationType string `json:"location_type"`
		}
	}
}
type GoogleReverseGeocodeResponse struct {
	Results []reverseGeocodeResult
}
type reverseGeocodeResult struct {
	AddressComponents []reverseGeocodeAddressComponent `json:"address_components"`
	FormattedAddress  string                           `json:"formatted_address"`
	Types             []string                         `json:"types"`
}
type reverseGeocodeAddressComponent struct {
	LongName  string   `json:"long_name"`
	ShortName string   `json:"short_name"`
	Types     []string `json:"types"`
}
var errGoogleZeroResults = errors.New("ZERO_RESULTS")
func (g *GoogleGeo) SetGoogleAPIKey(newAPIKey string) {
	g.apiKey = newAPIKey
}
func (g *GoogleGeo) GeocodeWithRegion(address, region string) (*Point, error) {
	return g.geocode(address, region)
}
func (g *GoogleGeo) Geocode(address string) (*Point, error) {
	return g.geocode(address, "")
}
func (g *GoogleGeo) geocode(address, region string) (*Point, error) {
	queryStr, err := g.geocodeQueryStr(address, region)
	if err != nil {
		return nil, err
	}
	data, err := g.request(queryStr)
	if err != nil {
		return nil, err
	}
	res := &googleGeocodeResponse{}
	if err := json.Unmarshal(data, res); err != nil {
		return nil, err
	}
	if len(res.Results) == 0 {
		return nil, errGoogleZeroResults
	}
	lat := res.Results[0].Geometry.Location.Lat
	lng := res.Results[0].Geometry.Location.Lng
	loc := res.Results[0].Geometry.LocationType
	point := &Point{
		Address:      res.Results[0].FormattedAddress,
		Lat:          lat,
		Lng:          lng,
		LocationType: loc,
	}
	return point, nil
}
func (g *GoogleGeo) ReverseGeocode(p *Point) (string, error) {
	res, err := g.ReverseGeocodeDetailed(p)
	if err != nil {
		return "", err
	}
	return res.Results[0].FormattedAddress, err
}