golang地理编码与反向地理编码API集成插件库geo-golang的使用
Golang地理编码与反向地理编码API集成插件库geo-golang的使用
geo-golang是一个Go语言开发的地理编码服务库,提供了优雅且符合Go语言习惯的API,支持多种地理编码服务提供商。
功能特性
- 支持多种地理编码服务提供商
- 只需修改一行代码即可切换不同服务
- 可以同时使用多个服务的免费配额
- 每个服务提供商的客户端实现仅需约50行代码
支持的提供商
- Google Maps
- MapQuest (Nominatim Search/Open Geocoding)
- OpenCage
- HERE (Geocoder API/Geocoding and Search API)
- Bing
- Mapbox
- OpenStreetMap
- PickPoint
- LocationIQ
- ArcGIS
- geocodio
- Mapzen
- TomTom
- Yandex.Maps
- French API Gouv
- Baidu Map
使用示例
下面是一个完整的示例代码,展示如何使用geo-golang进行地理编码和反向地理编码:
package main
import (
"fmt"
"os"
"github.com/codingsince1985/geo-golang"
"github.com/codingsince1985/geo-golang/arcgis"
"github.com/codingsince1985/geo-golang/baidu"
"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演示了不同的地理编码服务
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("Baidu Geocoding API")
try(baidu.Geocoder(os.Getenv("BAIDU_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")))
// 仅适用于法国位置或地址
fmt.Println("FrenchAPIGouv")
tryOnlyFRData(frenchapigouv.Geocoder())
// 链式地理编码器会回退到后续的地理编码器
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")
}
示例输出
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"}
Baidu Geocoding API
Melbourne VIC location is (31.227015, 121.456967)
Address of (-37.813611,144.963056) is 341 Little Bourke Street, Melbourne, Victoria, Australia
Detailed address: &geo.Address{FormattedAddress:"341 Little Bourke Street, Melbourne, Victoria, Australia", Street:"Little Bourke Street", HouseNumber:"341", Suburb:"", Postcode:"", State:"Victoria", StateCode:"", StateDistrict:"", County:"", Country:"Australia", CountryCode:"AUS", 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"}
许可证
geo-golang根据MIT许可证分发。
更多关于golang地理编码与反向地理编码API集成插件库geo-golang的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang地理编码与反向地理编码API集成插件库geo-golang的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
geo-golang地理编码与反向地理编码库使用指南
geo-golang是一个优秀的Go语言地理编码(Geocoding)和反向地理编码(Reverse Geocoding)库,支持多种地理编码服务提供商。下面我将详细介绍它的使用方法。
安装
go get github.com/codingsince1985/geo-golang
支持的提供商
geo-golang支持以下地理编码服务:
- Google Maps
- OpenStreetMap/Nominatim
- Mapbox
- HERE Maps
- Bing Maps
- MapQuest
- OpenCage
- TomTom
- Geocodio
- ArcGIS
- Pelias
基本用法
1. 地理编码(地址转坐标)
package main
import (
"fmt"
"github.com/codingsince1985/geo-golang"
)
func main() {
// 使用OpenStreetMap/Nominatim服务
geocoder := geo.GeocoderNominatim()
// 地理编码 - 地址转坐标
location, err := geocoder.Geocode("1600 Amphitheatre Parkway, Mountain View, CA")
if err != nil {
fmt.Println("Geocoding error:", err)
return
}
fmt.Printf("Latitude: %f, Longitude: %f\n", location.Lat, location.Lng)
}
2. 反向地理编码(坐标转地址)
func reverseGeocoding() {
// 使用Google Maps服务(需要API key)
// geocoder := geo.GeocoderGoogle("YOUR_GOOGLE_API_KEY")
// 使用免费的OpenStreetMap服务
geocoder := geo.GeocoderNominatim()
// 反向地理编码 - 坐标转地址
address, err := geocoder.ReverseGeocode(37.4224764, -122.0842499)
if err != nil {
fmt.Println("Reverse geocoding error:", err)
return
}
fmt.Println("Full address:", address.FormattedAddress)
fmt.Println("Street:", address.Street)
fmt.Println("House Number:", address.HouseNumber)
fmt.Println("Postcode:", address.Postcode)
fmt.Println("City:", address.City)
fmt.Println("State:", address.State)
fmt.Println("Country:", address.Country)
fmt.Println("Country Code:", address.CountryCode)
}
高级用法
1. 使用不同提供商
func differentProviders() {
// Google Maps
googleGeocoder := geo.GeocoderGoogle("YOUR_GOOGLE_API_KEY")
// Mapbox
mapboxGeocoder := geo.GeocoderMapbox("YOUR_MAPBOX_ACCESS_TOKEN")
// HERE Maps
hereGeocoder := geo.GeocoderHERE("YOUR_HERE_APP_ID", "YOUR_HERE_APP_CODE")
// 使用示例
location, _ := googleGeocoder.Geocode("Statue of Liberty")
fmt.Println("Google:", location)
location, _ = mapboxGeocoder.Geocode("Eiffel Tower")
fmt.Println("Mapbox:", location)
}
2. 设置超时和用户代理
func withOptions() {
// 创建自定义HTTP客户端
client := &http.Client{
Timeout: time.Second * 10,
}
// 设置用户代理(某些服务如Nominatim要求)
options := geo.Options{
HTTPClient: client,
UserAgent: "MyGeocodingApp/1.0",
}
geocoder := geo.GeocoderNominatimWithOptions(options)
address, err := geocoder.ReverseGeocode(40.7128, -74.0060)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("New York City address:", address)
}
3. 批量地理编码
func batchGeocoding() {
geocoder := geo.GeocoderNominatim()
addresses := []string{
"Eiffel Tower, Paris",
"Statue of Liberty, New York",
"Great Wall of China",
}
for _, addr := range addresses {
location, err := geocoder.Geocode(addr)
if err != nil {
fmt.Printf("Failed to geocode %s: %v\n", addr, err)
continue
}
fmt.Printf("%s is at (%.6f, %.6f)\n", addr, location.Lat, location.Lng)
}
}
注意事项
- API限制:大多数地理编码服务都有请求限制,特别是免费服务
- API密钥:Google Maps、Mapbox等服务需要API密钥
- 用户代理:使用Nominatim等服务时需要设置有效的用户代理
- 缓存:考虑实现缓存机制以减少API调用
- 错误处理:始终处理可能出现的错误
性能优化建议
- 对于大量请求,考虑使用支持批量请求的服务
- 实现本地缓存以避免重复查询相同地址
- 对于生产环境,考虑使用付费服务以获得更高的配额和更好的稳定性
geo-golang库提供了简单一致的接口来访问各种地理编码服务,使得在Go应用中集成地理编码功能变得非常方便。根据你的需求选择合适的服务提供商,并注意遵守各服务的使用条款。