func (g *OpenCageGeocoder) ReverseGeocode(p *Point) (string, error) {
	queryStr, err := opencageReverseGeocodeQueryStr(p)
	if err != nil {
		return "", err
	}
	data, err := g.Request(queryStr)
	if err != nil {
		return "", err
	}
	res := &opencageReverseGeocodeResponse{}
	err = json.Unmarshal(data, res)
	if err != nil {
		return "", err
	}
	if len(res.Results) == 0 {
		return "", opencageZeroResultsError
	}
	return res.Results[0].Formatted, nil
}
ReverseGeocode returns the first most available address that corresponds to the passed in point.
It may also return an error if one occurs during execution.
package geo
import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
)
type OpenCageGeocoder struct{}
type opencageGeocodeResponse struct {
	Results []struct {
		Formatted string `json:"formatted"`
		Geometry  struct {
			Lat float64
			Lng float64
		}
	}
}
type opencageReverseGeocodeResponse struct {
	Results []struct {
		Formatted string `json:"formatted"`
	}
}
var opencageZeroResultsError = errors.New("ZERO_RESULTS")
var opencageGeocodeURL = "http://api.opencagedata.com/geocode/v1/json"
var OpenCageAPIKey = ""
func SetOpenCageGeocodeURL(newGeocodeURL string) {
	opencageGeocodeURL = newGeocodeURL
}
func SetOpenCageAPIKey(newAPIKey string) {
	OpenCageAPIKey = newAPIKey
}
func (g *OpenCageGeocoder) Request(url string) ([]byte, error) {
	client := &http.Client{}
	fullUrl := fmt.Sprintf("%s/%s", opencageGeocodeURL, url)
	req, _ := http.NewRequest("GET", fullUrl, nil)
	resp, requestErr := client.Do(req)
	if requestErr != nil {
		return nil, requestErr
	}
	data, dataReadErr := ioutil.ReadAll(resp.Body)
	if dataReadErr != nil {
		return nil, dataReadErr
	}
	return data, nil
}
func (g *OpenCageGeocoder) Geocode(address string) (*Point, error) {
	queryStr, err := opencageGeocodeQueryStr(address)
	if err != nil {
		return nil, err
	}
	data, err := g.Request(queryStr)
	if err != nil {
		return nil, err
	}
	res := &opencageGeocodeResponse{}
	json.Unmarshal(data, res)
	if len(res.Results) == 0 {
		return nil, opencageZeroResultsError
	}
	lat := res.Results[0].Geometry.Lat
	lng := res.Results[0].Geometry.Lng
	point := &Point{
		lat: lat,
		lng: lng,
	}
	return point, nil
}
func opencageGeocodeQueryStr(address string) (string, error) {
	url_safe_query := url.QueryEscape(address)
	var queryStr = bytes.NewBufferString("?")
	_, err := queryStr.WriteString(fmt.Sprintf("q=%s", url_safe_query))
	if err != nil {
		return "", err
	}
	if OpenCageAPIKey != "" {
		_, err := queryStr.WriteString(fmt.Sprintf("&key=%s", OpenCageAPIKey))
		if err != nil {
			return "", err
		}
	}
	_, err = queryStr.WriteString("&pretty=1")
	if err != nil {
		return "", err
	}
	return queryStr.String(), err
}