Go library to access geocoding and reverse geocoding APIs

Overview

GeoService in Go

PkgGoDev Build Status codecov Go Report Card

Code Coverage

codecov.io

A geocoding service developed in Go's way, idiomatic and elegant, not just in golang.

This product is designed to open to any Geocoding service. Based on it,

clients are implemented in ~50 LoC each.

It allows you to switch from one service to another by changing only 1 line, or enjoy all the free quota (requests/sec, day, month...) from them at the same time. Just like this.

package main

import (
	"fmt"
	"os"

	"github.com/codingsince1985/geo-golang"
	"github.com/codingsince1985/geo-golang/arcgis"
	"github.com/codingsince1985/geo-golang/bing"
	"github.com/codingsince1985/geo-golang/chained"
	"github.com/codingsince1985/geo-golang/frenchapigouv"
	"github.com/codingsince1985/geo-golang/geocod"
	"github.com/codingsince1985/geo-golang/google"
	"github.com/codingsince1985/geo-golang/here"
	"github.com/codingsince1985/geo-golang/locationiq"
	"github.com/codingsince1985/geo-golang/mapbox"
	"github.com/codingsince1985/geo-golang/mapquest/nominatim"
	"github.com/codingsince1985/geo-golang/mapquest/open"
	"github.com/codingsince1985/geo-golang/mapzen"
	"github.com/codingsince1985/geo-golang/opencage"
	"github.com/codingsince1985/geo-golang/openstreetmap"
	"github.com/codingsince1985/geo-golang/pickpoint"
	"github.com/codingsince1985/geo-golang/tomtom"
	"github.com/codingsince1985/geo-golang/yandex"
)

const (
	addr         = "Melbourne VIC"
	lat, lng     = -37.813611, 144.963056
	radius       = 50
	zoom         = 18
	addrFR       = "Champs de Mars Paris"
	latFR, lngFR = 48.854395, 2.304770
)

func main() {
	ExampleGeocoder()
}

// ExampleGeocoder demonstrates the different geocoding services
func ExampleGeocoder() {
	fmt.Println("Google Geocoding API")
	try(google.Geocoder(os.Getenv("GOOGLE_API_KEY")))

	fmt.Println("Mapquest Nominatim")
	try(nominatim.Geocoder(os.Getenv("MAPQUEST_NOMINATIM_KEY")))

	fmt.Println("Mapquest Open streetmaps")
	try(open.Geocoder(os.Getenv("MAPQUEST_OPEN_KEY")))

	fmt.Println("OpenCage Data")
	try(opencage.Geocoder(os.Getenv("OPENCAGE_API_KEY")))

	fmt.Println("HERE API")
	try(here.Geocoder(os.Getenv("HERE_APP_ID"), os.Getenv("HERE_APP_CODE"), radius))

	fmt.Println("Bing Geocoding API")
	try(bing.Geocoder(os.Getenv("BING_API_KEY")))

	fmt.Println("Mapbox API")
	try(mapbox.Geocoder(os.Getenv("MAPBOX_API_KEY")))

	fmt.Println("OpenStreetMap")
	try(openstreetmap.Geocoder())

	fmt.Println("PickPoint")
	try(pickpoint.Geocoder(os.Getenv("PICKPOINT_API_KEY")))

	fmt.Println("LocationIQ")
	try(locationiq.Geocoder(os.Getenv("LOCATIONIQ_API_KEY"), zoom))

	fmt.Println("ArcGIS")
	try(arcgis.Geocoder(os.Getenv("ARCGIS_TOKEN")))

	fmt.Println("geocod.io")
	try(geocod.Geocoder(os.Getenv("GEOCOD_API_KEY")))

	fmt.Println("Mapzen")
	try(mapzen.Geocoder(os.Getenv("MAPZEN_API_KEY")))

	fmt.Println("TomTom")
	try(tomtom.Geocoder(os.Getenv("TOMTOM_API_KEY")))

	fmt.Println("Yandex")
	try(yandex.Geocoder(os.Getenv("YANDEX_API_KEY")))

	// To use only with french locations or addresses,
	// or values ​​could be estimated and will be false
	fmt.Println("FrenchAPIGouv")
	tryOnlyFRData(frenchapigouv.Geocoder())

	// Chained geocoder will fallback to subsequent geocoders
	fmt.Println("ChainedAPI[OpenStreetmap -> Google]")
	try(chained.Geocoder(
		openstreetmap.Geocoder(),
		google.Geocoder(os.Getenv("GOOGLE_API_KEY")),
	))
}

func try(geocoder geo.Geocoder) {
	location, _ := geocoder.Geocode(addr)
	if location != nil {
		fmt.Printf("%s location is (%.6f, %.6f)\n", addr, location.Lat, location.Lng)
	} else {
		fmt.Println("got <nil> location")
	}
	address, _ := geocoder.ReverseGeocode(lat, lng)
	if address != nil {
		fmt.Printf("Address of (%.6f,%.6f) is %s\n", lat, lng, address.FormattedAddress)
		fmt.Printf("Detailed address: %#v\n", address)
	} else {
		fmt.Println("got <nil> address")
	}
	fmt.Print("\n")
}

func tryOnlyFRData(geocoder geo.Geocoder) {
	location, _ := geocoder.Geocode(addrFR)
	if location != nil {
		fmt.Printf("%s location is (%.6f, %.6f)\n", addrFR, location.Lat, location.Lng)
	} else {
		fmt.Println("got <nil> location")
	}
	address, _ := geocoder.ReverseGeocode(latFR, lngFR)
	if address != nil {
		fmt.Printf("Address of (%.6f,%.6f) is %s\n", latFR, lngFR, address.FormattedAddress)
		fmt.Printf("Detailed address: %#v\n", address)
	} else {
		fmt.Println("got <nil> address")
	}
	fmt.Print("\n")
}

Result

Google Geocoding API
Melbourne VIC location is (-37.813611, 144.963056)
Address of (-37.813611,144.963056) is 197 Elizabeth St, Melbourne VIC 3000, Australia
Detailed address: &geo.Address{FormattedAddress:"197 Elizabeth St, Melbourne VIC 3000, Australia", Street:"Elizabeth Street", HouseNumber:"197", Suburb:"", Postcode:"3000", State:"Victoria", StateDistrict:"Melbourne City", County:"", Country:"Australia", CountryCode:"AU", City:"Melbourne"}

Mapquest Nominatim
Melbourne VIC location is (-37.814218, 144.963161)
Address of (-37.813611,144.963056) is Melbourne's GPO, Postal Lane, Melbourne, City of Melbourne, Greater Melbourne, Victoria, 3000, Australia
Detailed address: &geo.Address{FormattedAddress:"Melbourne's GPO, Postal Lane, Melbourne, City of Melbourne, Greater Melbourne, Victoria, 3000, Australia", Street:"Postal Lane", HouseNumber:"", Suburb:"Melbourne", Postcode:"3000", State:"Victoria", StateDistrict:"", County:"City of Melbourne", Country:"Australia", CountryCode:"AU", City:"Melbourne"}

Mapquest Open streetmaps
Melbourne VIC location is (-37.814218, 144.963161)
Address of (-37.813611,144.963056) is Elizabeth Street, 3000, Melbourne, Victoria, AU
Detailed address: &geo.Address{FormattedAddress:"Elizabeth Street, 3000, Melbourne, Victoria, AU", Street:"Elizabeth Street", HouseNumber:"", Suburb:"", Postcode:"3000", State:"Victoria", StateDistrict:"", County:"", Country:"", CountryCode:"AU", City:"Melbourne"}

OpenCage Data
Melbourne VIC location is (-37.814217, 144.963161)
Address of (-37.813611,144.963056) is Melbourne's GPO, Postal Lane, Melbourne VIC 3000, Australia
Detailed address: &geo.Address{FormattedAddress:"Melbourne's GPO, Postal Lane, Melbourne VIC 3000, Australia", Street:"Postal Lane", HouseNumber:"", Suburb:"Melbourne (3000)", Postcode:"3000", State:"Victoria", StateDistrict:"", County:"City of Melbourne", Country:"Australia", CountryCode:"AU", City:"Melbourne"}

HERE API
Melbourne VIC location is (-37.817530, 144.967150)
Address of (-37.813611,144.963056) is 197 Elizabeth St, Melbourne VIC 3000, Australia
Detailed address: &geo.Address{FormattedAddress:"197 Elizabeth St, Melbourne VIC 3000, Australia", Street:"Elizabeth St", HouseNumber:"197", Suburb:"", Postcode:"3000", State:"Victoria", StateDistrict:"", County:"", Country:"Australia", CountryCode:"AUS", City:"Melbourne"}

Bing Geocoding API
Melbourne VIC location is (-37.824299, 144.977997)
Address of (-37.813611,144.963056) is Elizabeth St, Melbourne, VIC 3000
Detailed address: &geo.Address{FormattedAddress:"Elizabeth St, Melbourne, VIC 3000", Street:"Elizabeth St", HouseNumber:"", Suburb:"", Postcode:"3000", State:"", StateDistrict:"", County:"", Country:"Australia", CountryCode:"", City:"Melbourne"}

Mapbox API
Melbourne VIC location is (-37.814200, 144.963200)
Address of (-37.813611,144.963056) is Elwood Park Playground, Melbourne, Victoria 3000, Australia
Detailed address: &geo.Address{FormattedAddress:"Elwood Park Playground, Melbourne, Victoria 3000, Australia", Street:"Elwood Park Playground", HouseNumber:"", Suburb:"", Postcode:"3000", State:"Victoria", StateDistrict:"", County:"", Country:"Australia", CountryCode:"AU", City:"Melbourne"}

OpenStreetMap
Melbourne VIC location is (-37.814217, 144.963161)
Address of (-37.813611,144.963056) is Melbourne's GPO, Postal Lane, Chinatown, Melbourne, City of Melbourne, Greater Melbourne, Victoria, 3000, Australia
Detailed address: &geo.Address{FormattedAddress:"Melbourne's GPO, Postal Lane, Chinatown, Melbourne, City of Melbourne, Greater Melbourne, Victoria, 3000, Australia", Street:"Postal Lane", HouseNumber:"", Suburb:"Melbourne", Postcode:"3000", State:"Victoria", StateDistrict:"", County:"", Country:"Australia", CountryCode:"AU", City:"Melbourne"}

PickPoint
Melbourne VIC location is (-37.814217, 144.963161)
Address of (-37.813611,144.963056) is Melbourne's GPO, Postal Lane, Chinatown, Melbourne, City of Melbourne, Greater Melbourne, Victoria, 3000, Australia
Detailed address: &geo.Address{FormattedAddress:"Melbourne's GPO, Postal Lane, Chinatown, Melbourne, City of Melbourne, Greater Melbourne, Victoria, 3000, Australia", Street:"Postal Lane", HouseNumber:"", Suburb:"Melbourne", Postcode:"3000", State:"Victoria", StateDistrict:"", County:"", Country:"Australia", CountryCode:"AU", City:"Melbourne"}

LocationIQ
Melbourne VIC location is (-37.814217, 144.963161)
Address of (-37.813611,144.963056) is Melbourne's GPO, Postal Lane, Chinatown, Melbourne, City of Melbourne, Greater Melbourne, Victoria, 3000, Australia
Detailed address: &geo.Address{FormattedAddress:"Melbourne's GPO, Postal Lane, Chinatown, Melbourne, City of Melbourne, Greater Melbourne, Victoria, 3000, Australia", Street:"Postal Lane", HouseNumber:"", Suburb:"Melbourne", Postcode:"3000", State:"Victoria", StateDistrict:"", County:"", Country:"Australia", CountryCode:"AU", City:"Melbourne"}

ArcGIS
Melbourne VIC location is (-37.817530, 144.967150)
Address of (-37.813611,144.963056) is Melbourne's Gpo
Detailed address: &geo.Address{FormattedAddress:"Melbourne's Gpo", Street:"350 Bourke Street Mall", HouseNumber:"350", Suburb:"", Postcode:"3000", State:"Victoria", StateDistrict:"", County:"", Country:"", CountryCode:"AUS", City:""}

geocod.io
Melbourne VIC location is (28.079357, -80.623618)
got <nil> address

Mapzen
Melbourne VIC location is (45.551136, 11.533929)
Address of (-37.813611,144.963056) is Stop 3: Bourke Street Mall, Bourke Street, Melbourne, Australia
Detailed address: &geo.Address{FormattedAddress:"Stop 3: Bourke Street Mall, Bourke Street, Melbourne, Australia", Street:"", HouseNumber:"", Suburb:"", Postcode:"", State:"Victoria", StateDistrict:"", County:"", Country:"Australia", CountryCode:"AUS", City:""}

TomTom
Melbourne VIC location is (-37.815340, 144.963230)
Address of (-37.813611,144.963056) is Doyles Road, Elaine, West Central Victoria, Victoria, 3334
Detailed address: &geo.Address{FormattedAddress:"Doyles Road, Elaine, West Central Victoria, Victoria, 3334", Street:"Doyles Road", HouseNumber:"", Suburb:"", Postcode:"3334", State:"Victoria", StateDistrict:"", County:"", Country:"Australia", CountryCode:"AU", City:"Elaine"}

Yandex
Melbourne VIC location is (41.926823, 2.254232)
Address of (-37.813611,144.963056) is Victoria, City of Melbourne, Elizabeth Street
Detailed address: &geo.Address{FormattedAddress:"Victoria, City of Melbourne, Elizabeth Street", Street:"Elizabeth Street", HouseNumber:"", Suburb:"", Postcode:"", State:"Victoria", StateDistrict:"", County:"", Country:"Australia", CountryCode:"AU", City:"City of Melbourne"}

FrenchAPIGouv
Champs de Mars Paris location is (2.304770, 48.854395)
Address of (48.854395,2.304770) is 9001, Parc du Champs de Mars, 75007, Paris, Paris, Île-de-France, France
Detailed address: &geo.Address{FormattedAddress:"9001, Parc du Champs de Mars, 75007, Paris, Paris, Île-de-France, France", Street:"Parc du Champs de Mars", HouseNumber:"9001", Suburb:"", Postcode:"75007", State:" Île-de-France", StateDistrict:"", County:" Paris", Country:"France", CountryCode:"FRA", City:"Paris"}

ChainedAPI[OpenStreetmap -> Google]
Melbourne VIC location is (-37.814217, 144.963161)
Address of (-37.813611,144.963056) is Melbourne's GPO, Postal Lane, Chinatown, Melbourne, City of Melbourne, Greater Melbourne, Victoria, 3000, Australia
Detailed address: &geo.Address{FormattedAddress:"Melbourne's GPO, Postal Lane, Chinatown, Melbourne, City of Melbourne, Greater Melbourne, Victoria, 3000, Australia", Street:"Postal Lane", HouseNumber:"", Suburb:"Melbourne", Postcode:"3000", State:"Victoria", StateDistrict:"", County:"", Country:"Australia", CountryCode:"AU", City:"Melbourne"}

License

geo-golang is distributed under the terms of the MIT license. See LICENSE for details.

Issues
  • Change the signature of the functions defined in the `Geocoder` interface

    Change the signature of the functions defined in the `Geocoder` interface

    More often one would like to have an address, returned by reverse geocoding service, as a structure, with separate fields for all the parts an address consists of. Returning a formatted address doesn't cut it most of the times. Also (as a personal opinion of mine and engineers in my team) I find it nice having homogeneous definitions - Geocode returns the Location structure, so why not have a similar signature for ReverseGeocode. Hence I would like to propose (and implement it all over) the following change in the Geocoder interface definitions:

    type Geocoder interface {
    	Geocode(address string) (*Location, error)
    	ReverseGeocode(lat, lng float64) (*Address, error)
    }
    

    with Address being defined in the package geo in a similar manner to the Location one

    // Address is the structured representation of an address, including its flat representation
    type Address struct {
    	FormattedAddress string
    	Street           string
    	HouseNumber      string
    	Suburb           string
    	Postcode         string
    	State            string
    	StateDistrict    string
    	County           string
    	Country          string
    	CountryCode      string
    	City             string
    }
    

    My reasoning for the further proposed changes:

    • Return pointer to the defined structure, so that the caller can check for nil; checking for zero values to deduce ErrNoResult may often go wrong (further no result being returned shouldn't be an error)
    • Add second return value of type error makes is easier to catch errors and propagate them back to the caller, next to a nil, who then should decide how to react
    • The (uniform) address string, currently returned by Address() would be accessible through the FormattedAddress field
    opened by kruftmeister 10
  • Tests should run against mock http responses

    Tests should run against mock http responses

    Testing would be easier to perform and more reliable if the library used mock http responses for geo APIs (e.g. the API's seem to be a little flakey sometimes causing intermittent build failures).

    We could record HTTP requests/responses from the existing tests as the initial mock http responses.

    We could always conditionally run the tests in "integration" mode which would run the mock tests and actual API tests if we still wanted to exercise the live APIs.

    opened by dougnukem 8
  • Add structured address

    Add structured address

    PR to solve issue #29

    It's been a while, but with Christmas, work and family added to the fact I had to sign up for many of the providers, the library supports, look into the documentation of their API, etc...

    To sum up the major changes I made:

    • use context.Context with a timeout instead of time.After with the benefit of cleaning up / releasing resources in case the deadline has been reached
    • moved the structures geo.Location and geo.Address to geocoder.go, where the definition of the interface is placed, since these are part of the interface's contract and also to reduce the LOC in http_geocoder.go
    • no longer using ErrNoResults, this can be now deduced if the returned values are nil, nil; in case an error has been returned by the provider (only few really do so) it's then translated in the second return value
    • moved the examples code from geocoder_test.go to examples/geocoder_example.go to not be mistaken with unit tests, because of language specific conventions

    In case of further questions / concerns, I'll be glad to discuss them.

    Cheers

    opened by kruftmeister 7
  • Fix README.md travis and coveralls badge URL to codingsince1985/geo-golang

    Fix README.md travis and coveralls badge URL to codingsince1985/geo-golang

    • Fix up readme badges to point to the main repo
    opened by dougnukem 7
  • Nil results with no error

    Nil results with no error

    I'm getting some odd results like getting a nil address or location when geocoding or reverse geocoding.

    Geocoding "4000 Blackhawk Plaza Cir, Danville, California 94506, United States": [Here] Geocoded '4000 Blackhawk Plaza Cir, Danville, California 94506, United States' to location: &{37.7999631 -121.9202164} [OpenCage] Failed to geocode address: geocoding error: missing API key [OpenStreetMap] Failed to geocode address: location is nil [Bing] Geocoded '4000 Blackhawk Plaza Cir, Danville, California 94506, United States' to location: &{37.800872802734375 -121.9173355102539} [Google] Geocoded '4000 Blackhawk Plaza Cir, Danville, California 94506, United States' to location: &{37.8006389 -121.919588} [Nominatim] Geocoded '4000 Blackhawk Plaza Cir, Danville, California 94506, United States' to location: &{0 0} [Open] Geocoded '4000 Blackhawk Plaza Cir, Danville, California 94506, United States' to location: &{39.78373 -100.445882} [MapBox] Geocoded '4000 Blackhawk Plaza Cir, Danville, California 94506, United States' to location: &{37.800639 -121.919588} [LocationIQ] Failed to geocode address: location is nil

    Reverse Geocoding "37.8006389,-121.919588": [Google] Failed to reverse geocode location: address is nil [Here] Reverse geocoded location 37.8006389,-121.919588 to 'Danville, CA 94506, United States' [Open] Reverse geocoded location 37.8006389,-121.919588 to 'Blackhawk Plaza Circle, 94506, Blackhawk, CA, US' [MapBox] Reverse geocoded location 37.8006389,-121.919588 to '4000 Blackhawk Plaza Cir, Danville, California 94506, United States' [OpenStreetMap] Reverse geocoded location 37.8006389,-121.919588 to '4014, Blackhawk Plaza Circle, Blackhawk, Contra Costa County, California, 94506, United States of America' [Bing] Reverse geocoded location 37.8006389,-121.919588 to 'Street, Danville, CA 94506' [OpenCage] Failed to reverse geocode location: geocoding error: missing API key [LocationIQ] Reverse geocoded location 37.8006389,-121.919588 to '4014, Blackhawk Plaza Circle, Blackhawk, Contra Costa County, California, 94506, United States of America' [Nominatim] Reverse geocoded location 37.8006389,-121.919588 to 'Blackhawk Plaza Circle, Blackhawk, Contra Costa County, California, 94506, United States of America'

    I'm not sure if I'm doing something wrong or my expectation is incorrect but I would imagine we should get an error if an address or location is nil.

    opened by saheljalal 6
  • Panic in mapquest/open/geocoder.go

    Panic in mapquest/open/geocoder.go

    I have a test that uses lat/long 0,0 and it seems to panic the library.

    panic: runtime error: index out of range

    goroutine 76 [running]: panic(0x39cd00, 0xc4200140f0) /usr/local/Cellar/go/1.7.1/libexec/src/runtime/panic.go:500 +0x1a1 ../vendor/github.com/codingsince1985/geo-golang/mapquest/open.(*geocodeResponse).Address(0xc42043c5c0, 0x50, 0x5cd2e0) ../vendor/github.com/codingsince1985/geo-golang/mapquest/open/geocoder.go:49 +0x18a ../vendor/github.com/codingsince1985/geo-golang.HTTPGeocoder.ReverseGeocode.func1(0x5ce920, 0xc4200156f0, 0x444178, 0x0, 0x0, 0xc42013b3e0) ../vendor/github.com/codingsince1985/geo-golang/http_geocoder.go:71 +0xaa created by ../vendor/github.com/codingsince1985/geo-golang.HTTPGeocoder.ReverseGeocode ../vendor/github.com/codingsince1985/geo-golang/http_geocoder.go:72 +0xb7 exit status 2

    opened by saheljalal 5
  • Cached Geocoder

    Cached Geocoder

    Depends on #17

    • Implements a CachedGeocoder that will cache responses to another Geocoder
      • currently uses in-memory cache https://github.com/patrickmn/go-cache
        • could use a cache interface type later to support other cache implementations
    opened by dougnukem 5
  • Geocoder as an interface to allow for chained and cached types

    Geocoder as an interface to allow for chained and cached types

    Closes https://github.com/codingsince1985/geo-golang/issues/10

    Make the top-level Geocoder type an interface and the HTTP specific one a HTTPGeocoder

    This will be useful for implementing more abstract Geocoder types like Chained fallback ones or cached ones as described here https://github.com/codingsince1985/geo-golang/issues/10

    Also made ResponseObject() be a function that returns new instances (I think there may have been a concurrency issue because the Geocoders were returning the same pointer for every call, so if you made concurrent calls to a Geocoder API it would be decoding to the same response pointer).

    // Geocoder can look up (lat, long) by address and address by (lat, long)
    type Geocoder interface {
        Geocode(address string) (Location, error)
        ReverseGeocode(lat, lng float64) (string, error)
    }
    
    
    // HTTPGeocoder has EndpointBuilder and ResponseParser
    type HTTPGeocoder struct {
        EndpointBuilder
        ResponseParserFactory ResponseParserFactory
    }
    
    opened by dougnukem 5
  • Panic at geo-golang/mapquest/open/geocoder.go:46

    Panic at geo-golang/mapquest/open/geocoder.go:46

    Seeing another panic, not sure if it is tracked or not.

    I think it's this line: func (r *geocodeResponse) Location() geo.Location { return r.Results[0].Locations[0].LatLng }

    panic: runtime error: index out of range

    goroutine 15 [running]: panic(0x3a0bc0, 0xc420016100) /usr/local/Cellar/go/1.7.1/libexec/src/runtime/panic.go:500 +0x1a1 ../codingsince1985/geo-golang/mapquest/open.(*geocodeResponse).Location(0xc4204323a0, 0x6d, 0x5d32e0) /Users/saheljalal/code/go/src/../codingsince1985/geo-golang/mapquest/open/geocoder.go:46 +0x47 ../codingsince1985/geo-golang.HTTPGeocoder.Geocode.func1(0x5d4920, 0xc420017700, 0x448aa8, 0xc42014cbd0, 0x2e, 0xc420302d90) /Users/saheljalal/code/go/src/../codingsince1985/geo-golang/http_geocoder.go:54 +0xbe created by ../codingsince1985/geo-golang.HTTPGeocoder.Geocode /Users/saheljalal/code/go/src/../codingsince1985/geo-golang/http_geocoder.go:55 +0xb6

    opened by saheljalal 4
  • More geocoders/providers

    More geocoders/providers

    +arcgis +gecod +mapzen +tomtom

    opened by kuba-- 3
  • How to find details for an address?

    How to find details for an address?

    I only want to use the lib only to autocomplete adresses. I want to search for "Fred-Grube-Platz 23, 30451 Hannover" and get the "formattedAdress" back. IS that possible? Or is only a conversion from adress to lat/lon possible?

    opened by Linutux 2
  • Package returns abbreviations for city/state instead of full name

    Package returns abbreviations for city/state instead of full name

    Hello,

    By default the package does not include headers related to language, ie Accept-Language

    Using, Accept-Language = en for example will result in the full name of the city/state

    While, Accept-Language = EN for example will result in abbreviation for the city/state

    In my setup I often see the later being returned which results in abbreviations for city/state.

    Can we introduce an optional param to Geocoder to pass in headers when making a request to Nominatim (so that we can control the Accept-Language header)?

    Thank you!

    More about this issue is outlined here: https://github.com/openstreetmap/Nominatim/issues/783

    opened by amehta1128 0
  • Geocode should not return a nil location and a nil error

    Geocode should not return a nil location and a nil error

    I just checked the openstreetmap response parser, and when the returned longitude and latitude are empty, it returns nil for both location and error.

    Returning nil as a valid value when there is no error is undesirable. It means that we have to check the return value, regardless of whether we have a return error or not.

    Instead, it would probably be good to return a sentinel error, such as ErrNoCoordsFound.

    opened by awfm9 0
  • How to include the `_type` property returned by OpenCage in the returned `Address` struct?

    How to include the `_type` property returned by OpenCage in the returned `Address` struct?

    Currently the _type property is not included in the returned Address struct. Any ways to add it?

    opened by teckays 1
  • Geocode should also return accuracy data

    Geocode should also return accuracy data

    Some providers do give certain details about what type of result it is. Having this information (when available) will help validate the results, and can help determine if I need to use another provider as a fallback if the results is not accurate enough.

    opened by ariselseng 2
Releases(v4)
Owner
Jerry Zhao
Jerry Zhao
Go library to access geocoding and reverse geocoding APIs

GeoService in Go Code Coverage A geocoding service developed in Go's way, idiomatic and elegant, not just in golang. This product is designed to open

Jerry Zhao 407 Jul 23, 2021
actionlint is a static checker for GitHub Actions workflow files.

actionlint actionlint is a static checker for GitHub Actions workflow files. Features: Syntax check for workflow files to check unexpected or missing

Linda_pp 296 Jul 23, 2021
EggContractor is a self-hosted contract monitoring web app + CLI client for Egg

EggContractor is a self-hosted contract monitoring web app + CLI client for Egg, Inc.. It allows you to easily monitor all your contract progress, as well as peeking into prospective coops you may want to join.

Z. Wang 21 Jul 20, 2021
Auto-generated Google APIs for Go.

Google APIs Client Library for Go Getting Started $ go get google.golang.org/api/tasks/v1 $ go get google.golang.org/api/moderator/v1 $ go get google.

Google APIs 2.7k Jul 20, 2021
A Facebook Graph API SDK For Go.

A Facebook Graph API SDK In Golang This is a Go package that fully supports the Facebook Graph API with file upload, batch request and marketing API.

Huan Du 978 Jul 17, 2021
QQ、微信(WeChat)、支付宝(AliPay)的Go版本SDK。

QQ、微信(WeChat)、支付宝(AliPay)的Go版本SDK。

Jerry 1.3k Jul 27, 2021
An easy-to-use unofficial SDK for Feishu and Lark Open Platform

go-lark go-lark is an easy-to-use unofficial SDK for Feishu and Lark Open Platform. go-lark implements messaging APIs, with full-fledged supports on b

go-lark-sdk 57 Jul 13, 2021
Go written SDK for Notion.so API

go-notion Go written Notion SDK. Note: The Notion API is in beta phase Supported APIs It supports all APIs for Notion API (as for 2021-05-15). Blocks

Ketion.so 10 Jul 22, 2021
lambda-go-api-proxy makes it easy to port APIs written with Go frameworks such as Gin to AWS Lambda and Amazon API Gateway.

aws-lambda-go-api-proxy makes it easy to run Golang APIs written with frameworks such as Gin with AWS Lambda and Amazon API Gateway.

Amazon Web Services - Labs 508 Jul 14, 2021
Go library for the Spotify Web API

go-spotify Simple Go library for the Spotify Web API Installation go get github.com/rapito/go-spotify/spotify How-to-use Get Requests import "fmt

Robert Peralta 39 Jul 24, 2021
rpCheckup is an AWS resource policy security checkup tool that identifies public, external account access, intra-org account access, and private resources.

rpCheckup - Catch AWS resource policy backdoors like Endgame rpCheckup is an AWS resource policy security checkup tool that identifies public, externa

Gold Fig Labs Inc. 126 Jul 18, 2021
An API client for the Notion API implemented in Golang

An API client for the Notion API implemented in Golang

Anatoly Nosov 186 Jul 19, 2021
Go library for the Stripe API.

Go Stripe The official Stripe Go client library. Installation Make sure your project is using Go Modules (it will have a go.mod file in its root if it

Stripe 1.4k Jul 26, 2021
(Golang) Go bindings for Discord

DiscordGo DiscordGo is a Go package that provides low level bindings to the Discord chat client API. DiscordGo has nearly complete support for all of

null 2.2k Jul 24, 2021