-
Notifications
You must be signed in to change notification settings - Fork 0
/
wikipedia.go
98 lines (90 loc) · 2.54 KB
/
wikipedia.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package geonames
import (
"context"
"fmt"
"net/url"
"strconv"
)
type wikipediaResponse struct {
Geonames []struct {
Summary string `json:"summary"`
Elevation int `json:"elevation"`
GeoNameID int `json:"geoNameId,omitempty"`
Lng float64 `json:"lng"`
CountryCode string `json:"countryCode"`
Rank int `json:"rank"`
Lang string `json:"lang"`
Title string `json:"title"`
Lat float64 `json:"lat"`
WikipediaURL string `json:"wikipediaUrl"`
Feature string `json:"feature,omitempty"`
} `json:"geonames"`
}
// Geoname represents a name for a place retrieved from Wikipedia.
type Geoname struct {
Summary string
Elevation int
GeoNameID int
Feature string
Position Position
CountryCode string
Rank int
Language string
Title string
URL string
}
// GetPlace retrives geo coordinates for given place name and country code.
func (c Client) GetPlace(ctx context.Context, name, country string, maxResults int) ([]Geoname, error) {
if maxResults < 1 {
return nil, fmt.Errorf("invalid max results: %d", maxResults)
}
url, err := c.buildWikiURL(name, country, maxResults)
if err != nil {
return nil, err
}
var wr wikipediaResponse
if err := c.get(ctx, url, &wr); err != nil {
return nil, err
}
var geonames []Geoname
for _, g := range wr.Geonames {
geoname := Geoname{
Summary: g.Summary,
Elevation: g.Elevation,
GeoNameID: g.GeoNameID,
Feature: g.Feature,
Position: Position{
Lat: g.Lat,
Lng: g.Lng,
},
CountryCode: g.CountryCode,
Rank: g.Rank,
Language: g.Lang,
Title: g.Title,
URL: g.WikipediaURL,
}
geonames = append(geonames, geoname)
}
return geonames, nil
}
func (c Client) buildWikiURL(place, country string, maxResults int) (string, error) {
params := url.Values{
"q": []string{place},
"title": []string{place},
"countryCode": []string{country},
"maxRows": []string{strconv.Itoa(maxResults)},
"username": []string{c.UserName},
}
baseWiki := fmt.Sprintf("%s/wikipediaSearchJSON", c.BaseURL)
u, err := url.Parse(baseWiki)
if err != nil {
return "", fmt.Errorf("parsing wikipedia base url: %w", err)
}
u.RawQuery = params.Encode()
return u.String(), nil
}
// GetPlace takes place name, country and max results and returns
// a list of names associated with the place.
func GetPlace(name, country string, maxResults int) ([]Geoname, error) {
return ClientFromEnv.GetPlace(context.Background(), name, country, maxResults)
}