diff --git a/osm/osm.go b/osm/osm.go index 2756856..d1c3cd6 100644 --- a/osm/osm.go +++ b/osm/osm.go @@ -12,10 +12,11 @@ import ( ) const ( - liveAPIBaseURL = "http://api-openstreetmap-org-ue6z91hlm5oj.runscope.net/api/0.6" // "http://api.openstreetmap.org/api/0.6" + liveAPIBaseURL = "http://api.openstreetmap.org/api/0.6" devAPIBaseURL = "http://api06.dev.openstreetmap.org/api/0.6" ) +// Client represents an OSM client which is capable of RW operations on the OpenStreetMap type Client struct { username string password string @@ -25,6 +26,7 @@ type Client struct { CurrentUser *User } +// New instantiates a new client and retrieves information about the current user. Set useDevServer to true to change the API URL to the api06.dev.openstreetmap.org server. func New(username, password string, useDevServer bool) (*Client, error) { out := &Client{ username: username, @@ -74,7 +76,7 @@ func (c *Client) do(method, path string, body io.Reader) (io.ReadCloser, error) if res.StatusCode != http.StatusOK { d, e := ioutil.ReadAll(res.Body) if e != nil { - return nil, fmt.Errorf("OSM API responded with status code %d and reading response failed.", res.StatusCode) + return nil, fmt.Errorf("OSM API responded with status code %d and reading response failed", res.StatusCode) } res.Body.Close() @@ -98,6 +100,8 @@ func (c *Client) doParse(method, path string, body io.Reader, output interface{} return nil } +// Wrap is a mostly internal used struct which holds requests to / responses from the API. +// You will get a Wrap object when querying map objects from the API type Wrap struct { XMLName xml.Name `xml:"osm"` User *User `xml:"user,omitempty"` @@ -105,6 +109,7 @@ type Wrap struct { Nodes []*Node `xml:"node,omitempty"` } +// Changeset contains information about a changeset in the API. You need to create a changeset before submitting any changes to the API. type Changeset struct { XMLName xml.Name `xml:"changeset"` ID int64 `xml:"id,attr,omitempty"` @@ -122,6 +127,7 @@ type Changeset struct { Tags []Tag `xml:"tag"` } +// GetMyChangesets retrieves a list of (open) changesets from the API func (c *Client) GetMyChangesets(onlyOpen bool) ([]*Changeset, error) { urlPath := fmt.Sprintf("/changesets?user=%d&open=%s", c.CurrentUser.ID, strconv.FormatBool(onlyOpen)) @@ -129,6 +135,7 @@ func (c *Client) GetMyChangesets(onlyOpen bool) ([]*Changeset, error) { return r.Changesets, c.doParse("GET", urlPath, nil, r) } +// CreateChangeset creates a new changeset func (c *Client) CreateChangeset() (*Changeset, error) { body := bytes.NewBuffer([]byte{}) if err := xml.NewEncoder(body).Encode(Wrap{Changesets: []*Changeset{{}}}); err != nil { @@ -152,6 +159,7 @@ func (c *Client) CreateChangeset() (*Changeset, error) { return cs.Changesets[0], nil } +// SaveChangeset updates or creates a changeset func (c *Client) SaveChangeset(cs *Changeset) error { urlPath := "/changeset/create" @@ -170,12 +178,14 @@ func (c *Client) SaveChangeset(cs *Changeset) error { return err } +// RetrieveMapObjects queries all objects within the passed bounds. You need to ensure the min values are below the max values. func (c *Client) RetrieveMapObjects(minLat, minLon, maxLat, maxLon float64) (*Wrap, error) { urlPath := fmt.Sprintf("/map?bbox=%.7f,%.7f,%.7f,%.7f", minLat, minLon, maxLat, maxLon) res := &Wrap{} return res, c.doParse("GET", urlPath, nil, res) } +// User contains information about an User in the OpenStreetMap type User struct { XMLName xml.Name `xml:"user"` ID int64 `xml:"id,attr"` @@ -185,6 +195,7 @@ type User struct { Description string `xml:"description"` } +// Node represents one node in the OpenStreetMap type Node struct { XMLName xml.Name `xml:"node"` ID int64 `xml:"id,attr,omitempty"` @@ -198,6 +209,7 @@ type Node struct { Tags []Tag `xml:"tag"` } +// SaveNode creates or updates a node with an association to the passed changeset which needs to be open and known to the API. func (c *Client) SaveNode(n *Node, cs *Changeset) error { if n.ID > 0 && n.Version == 0 { return fmt.Errorf("When an ID is set the version must be present") @@ -222,6 +234,7 @@ func (c *Client) SaveNode(n *Node, cs *Changeset) error { return err } +// Tag represents a key-value pair used in all objects inside OpenStreetMap type Tag struct { XMLName xml.Name `xml:"tag"` Key string `xml:"k,attr"`