osm

package module
v0.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 8, 2024 License: MIT Imports: 12 Imported by: 49

README

osm CI Go Report Card Go Reference

This package is a general purpose library for reading, writing and working with OpenStreetMap data in Go (golang). It has the ability to:

Made available by the package are the following types:

  • Node
  • Way
  • Relation
  • Changeset
  • Note
  • User

And the following “container” types:

List of sub-package utilities

  • annotate - adds lon/lat, version, changeset and orientation data to way and relation members
  • osmapi - supports all the v0.6 read/data endpoints
  • osmgeojson - OSM to GeoJSON conversion compatible with osmtogeojson
  • osmpbf - stream processing of *.osm.pbf files
  • osmxml - stream processing of *.osm xml files
  • replication - fetch replication state and change files

Concepts

This package refers to the core OSM data types as Objects. The Node, Way, Relation, Changeset, Note and User types implement the osm.Object interface and can be referenced using the osm.ObjectID type. As a result it is possible to have a slice of []osm.Object that contains nodes, changesets and users.

Individual versions of the core OSM Map Data types are referred to as Elements and the set of versions for a give Node, Way or Relation is referred to as a Feature. For example, an osm.ElementID could refer to "Node with id 10 and version 3" and the osm.FeatureID would refer to "all versions of node with id 10." Put another way, features represent a road and how it's changed over time and an element is a specific version of that feature.

A number of helper methods are provided for dealing with features and elements. The idea is to make it easy to work with a Way and its member nodes, for example.

Scanning large data files

For small data it is possible to use the encoding/xml package in the Go standard library to marshal/unmarshal the data. This is typically done using the osm.OSM or osm.Change "container" structs.

For large data the package defines the Scanner interface implemented in both the osmxml and osmpbf sub-packages.

type osm.Scanner interface {
	Scan() bool
	Object() osm.Object
	Err() error
	Close() error
}

This interface is designed to mimic the bufio.Scanner interface found in the Go standard library.

Example usage:

f, err := os.Open("./delaware-latest.osm.pbf")
if err != nil {
	panic(err)
}
defer f.Close()

scanner := osmpbf.New(context.Background(), f, 3)
defer scanner.Close()

for scanner.Scan() {
	o := scanner.Object()
	// do something
}

scanErr := scanner.Err()
if scanErr != nil {
	panic(scanErr)
}

Note: Scanners are not safe for parallel use. One should feed the objects into a channel and have workers read from that.

Working with JSON

This library supports reading and writing OSM JSON. This format is returned by the Overpass API and can be optionally returned by the OSM API.

If performance is important, this library supports third party "encoding/json" replacements such as github.com/json-iterator/go.

They can be enabled with something like this:

import (
  jsoniter "github.com/json-iterator/go"
  "github.com/paulmach/osm"
)

var c = jsoniter.Config{
  EscapeHTML:              true,
  SortMapKeys:             false,
  MarshalFloatWith6Digits: true,
}.Froze()

osm.CustomJSONMarshaler = c
osm.CustomJSONUnmarshaler = c

The above change can have dramatic performance implications, see the benchmarks below on a large OSM Change object.

benchmark                            old ns/op     new ns/op     delta
BenchmarkChange_MarshalJSON-12       604496        461349        -23.68%
BenchmarkChange_UnmarshalJSON-12     1633834       1051630       -35.63%

benchmark                            old allocs    new allocs    delta
BenchmarkChange_MarshalJSON-12       1277          1081          -15.35%
BenchmarkChange_UnmarshalJSON-12     5133          8580          +67.15%

benchmark                            old bytes     new bytes     delta
BenchmarkChange_MarshalJSON-12       180583        162727        -9.89%
BenchmarkChange_UnmarshalJSON-12     287707        317723        +10.43%

CGO and zlib

OSM PBF data comes in blocks, each block is zlib compressed. Decompressing this data takes about 33% of the total read time. DataDog/czlib is used to speed this process. See osmpbf/README.md for more details.

As a result, a C compiler is necessary to install this module. On macOS this may require installing pkg-config using something like brew install pkg-config

CGO can be disabled at build time using the CGO_ENABLED ENV variable. For example, CGO_ENABLED=0 go build. The code will fallback to the stdlib implementation of zlib.

Documentation

Index

Constants

View Source
const (
	Copyright   = "OpenStreetMap and contributors"
	Attribution = "http://www.openstreetmap.org/copyright"
	License     = "http://opendatacommons.org/licenses/odbl/1-0/"
)

These values should be returned if the osm data is actual osm data to give some information about the source and license.

Variables

View Source
var CommitInfoStart = time.Date(2012, 9, 12, 9, 30, 3, 0, time.UTC)

CommitInfoStart is the start time when we know committed at information. Any update.Timestamp >= this date is a committed at time. Anything before this date is the element timestamp.

View Source
var CustomJSONMarshaler interface {
	Marshal(v interface{}) ([]byte, error)
}

CustomJSONMarshaler can be set to have the code use a different json marshaler than the default in the standard library. One use case in enabling `github.com/json-iterator/go` with something like this:

import (
  jsoniter "github.com/json-iterator/go"
  "github.com/paulmach/osm"
)

var c = jsoniter.Config{
  EscapeHTML:              true,
  SortMapKeys:             false,
  MarshalFloatWith6Digits: true,
}.Froze()

osm.CustomJSONMarshaler = c
osm.CustomJSONUnmarshaler = c

Note that any errors encountered during marshaling will be different.

View Source
var CustomJSONUnmarshaler interface {
	Unmarshal(data []byte, v interface{}) error
}

CustomJSONUnmarshaler can be set to have the code use a different json unmarshaler than the default in the standard library. One use case in enabling `github.com/json-iterator/go` with something like this:

import (
  jsoniter "github.com/json-iterator/go"
  "github.com/paulmach/osm"
)

var c = jsoniter.Config{
  EscapeHTML:              true,
  SortMapKeys:             false,
  MarshalFloatWith6Digits: true,
}.Froze()

osm.CustomJSONMarshaler = c
osm.CustomJSONUnmarshaler = c

Note that any errors encountered during unmarshaling will be different.

View Source
var (
	// ErrScannerClosed is returned by scanner.Err() if the scanner is closed
	// and there are no other io or xml errors to report.
	ErrScannerClosed = errors.New("osm: scanner closed by user")
)
View Source
var UninterestingTags = map[string]bool{
	"source":            true,
	"source_ref":        true,
	"source:ref":        true,
	"history":           true,
	"attribution":       true,
	"created_by":        true,
	"tiger:county":      true,
	"tiger:tlid":        true,
	"tiger:upload_uuid": true,
}

UninterestingTags are boring tags. If an element only has these tags it does not usually need to be displayed. For example, if a node with just these tags is part of a way, it probably does not need its own icon along the way.

Functions

This section is empty.

Types

type Action

type Action struct {
	Type ActionType `xml:"type,attr"`
	*OSM `xml:",omitempty"`
	Old  *OSM `xml:"old,omitempty"`
	New  *OSM `xml:"new,omitempty"`
}

Action is an explicit create, modify or delete action with old and new data if applicable. Different properties of this struct will be populated depending on the action.

Create: da.OSM will contain the new element
Modify: da.Old and da.New will contain the old and new elements.
Delete: da.Old and da.New will contain the old and new elements.

func (Action) MarshalXML

func (a Action) MarshalXML(e *xml.Encoder, start xml.StartElement) error

MarshalXML converts a diff action to xml creating the proper structures.

func (*Action) UnmarshalXML

func (a *Action) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML converts xml into a diff action.

type ActionType

type ActionType string

ActionType is a strong type for the different diff actions.

const (
	ActionCreate ActionType = "create"
	ActionModify ActionType = "modify"
	ActionDelete ActionType = "delete"
)

The different types of diff actions.

type Actions

type Actions []Action

Actions is a set of diff actions.

type Bounds

type Bounds struct {
	MinLat float64 `xml:"minlat,attr"`
	MaxLat float64 `xml:"maxlat,attr"`
	MinLon float64 `xml:"minlon,attr"`
	MaxLon float64 `xml:"maxlon,attr"`
}

Bounds are the bounds of osm data as defined in the xml file.

func NewBoundsFromTile

func NewBoundsFromTile(t maptile.Tile) (*Bounds, error)

NewBoundsFromTile creates a bound given an online map tile index.

func (*Bounds) ContainsNode

func (b *Bounds) ContainsNode(n *Node) bool

ContainsNode returns true if the node is within the bound. Uses inclusive intervals, ie. returns true if on the boundary.

func (*Bounds) ObjectID added in v0.1.0

func (b *Bounds) ObjectID() ObjectID

ObjectID returns the bounds type but with 0 id. Since id doesn't make sense. This is here to implement the Object interface since it technically is an osm object type. It also allows bounds to be returned via the osmxml.Scanner.

type Change

type Change struct {
	Version   string `xml:"version,attr,omitempty" json:"version,omitempty"`
	Generator string `xml:"generator,attr,omitempty" json:"generator,omitempty"`

	// to indicate the origin of the data
	Copyright   string `xml:"copyright,attr,omitempty" json:"copyright,omitempty"`
	Attribution string `xml:"attribution,attr,omitempty" json:"attribution,omitempty"`
	License     string `xml:"license,attr,omitempty" json:"license,omitempty"`

	Create *OSM `xml:"create" json:"create,omitempty"`
	Modify *OSM `xml:"modify" json:"modify,omitempty"`
	Delete *OSM `xml:"delete" json:"delete,omitempty"`
}

Change is the structure of a changeset to be uploaded or downloaded from the osm api server. See: http://wiki.openstreetmap.org/wiki/OsmChange

func (*Change) AppendCreate

func (c *Change) AppendCreate(o Object)

AppendCreate will append the object to the Create OSM object.

func (*Change) AppendDelete

func (c *Change) AppendDelete(o Object)

AppendDelete will append the object to the Delete OSM object.

func (*Change) AppendModify

func (c *Change) AppendModify(o Object)

AppendModify will append the object to the Modify OSM object.

func (*Change) HistoryDatasource

func (c *Change) HistoryDatasource() *HistoryDatasource

HistoryDatasource converts the change object to a datasource accessible by feature id. All the creates, modifies and deletes will be added in that order.

func (Change) MarshalXML

func (c Change) MarshalXML(e *xml.Encoder, start xml.StartElement) error

MarshalXML implements the xml.Marshaller method to allow for the correct wrapper/start element case and attr data.

type Changeset

type Changeset struct {
	XMLName       xmlNameJSONTypeCS    `xml:"changeset" json:"type"`
	ID            ChangesetID          `xml:"id,attr" json:"id"`
	User          string               `xml:"user,attr" json:"user,omitempty"`
	UserID        UserID               `xml:"uid,attr" json:"uid,omitempty"`
	CreatedAt     time.Time            `xml:"created_at,attr" json:"created_at"`
	ClosedAt      time.Time            `xml:"closed_at,attr" json:"closed_at"`
	Open          bool                 `xml:"open,attr" json:"open"`
	ChangesCount  int                  `xml:"num_changes,attr,omitempty" json:"num_changes,omitempty"`
	MinLat        float64              `xml:"min_lat,attr" json:"min_lat,omitempty"`
	MaxLat        float64              `xml:"max_lat,attr" json:"max_lat,omitempty"`
	MinLon        float64              `xml:"min_lon,attr" json:"min_lon,omitempty"`
	MaxLon        float64              `xml:"max_lon,attr" json:"max_lon,omitempty"`
	CommentsCount int                  `xml:"comments_count,attr,omitempty" json:"comments_count,omitempty"`
	Tags          Tags                 `xml:"tag" json:"tags,omitempty"`
	Discussion    *ChangesetDiscussion `xml:"discussion,omitempty" json:"discussion,omitempty"`

	Change *Change `xml:"-" json:"change,omitempty"`
}

A Changeset is a set of metadata around a set of osm changes.

func (*Changeset) Bot

func (c *Changeset) Bot() bool

Bot is a helper and returns true if the bot tag is a yes.

func (*Changeset) Bounds

func (c *Changeset) Bounds() *Bounds

Bounds returns the bounds of the changeset as a bounds object.

func (*Changeset) Comment

func (c *Changeset) Comment() string

Comment is a helper and returns the changeset comment from the tag.

func (*Changeset) CreatedBy

func (c *Changeset) CreatedBy() string

CreatedBy is a helper and returns the changeset created by from the tag.

func (*Changeset) Host

func (c *Changeset) Host() string

Host is a helper and returns the changeset host from the tag.

func (*Changeset) ImageryUsed

func (c *Changeset) ImageryUsed() string

ImageryUsed is a helper and returns imagery used for the changeset from the tag.

func (*Changeset) Locale

func (c *Changeset) Locale() string

Locale is a helper and returns the changeset locale from the tag.

func (*Changeset) ObjectID

func (c *Changeset) ObjectID() ObjectID

ObjectID returns the object id of the changeset.

func (*Changeset) Source

func (c *Changeset) Source() string

Source is a helper and returns source for the changeset from the tag.

type ChangesetComment

type ChangesetComment struct {
	User      string    `xml:"user,attr" json:"user"`
	UserID    UserID    `xml:"uid,attr" json:"uid"`
	Timestamp time.Time `xml:"date,attr" json:"date"`
	Text      string    `xml:"text" json:"text"`
}

ChangesetComment is a specific comment in a changeset discussion.

type ChangesetDiscussion

type ChangesetDiscussion struct {
	Comments []*ChangesetComment `xml:"comment" json:"comments"`
}

ChangesetDiscussion is a conversation about a changeset.

func (ChangesetDiscussion) MarshalXML

func (csd ChangesetDiscussion) MarshalXML(e *xml.Encoder, start xml.StartElement) error

MarshalXML implements the xml.Marshaller method to exclude this whole element if the comments are empty.

type ChangesetID

type ChangesetID int64

ChangesetID is the primary key for an osm changeset.

func (ChangesetID) ObjectID

func (id ChangesetID) ObjectID() ObjectID

ObjectID is a helper returning the object id for this changeset id.

type Changesets

type Changesets []*Changeset

Changesets is a collection with some helper functions attached.

func (Changesets) IDs

func (cs Changesets) IDs() []ChangesetID

IDs returns the ids of the changesets in the slice.

type Date

type Date struct {
	time.Time
}

Date is an object to decode the date format used in the osm notes xml api. The format is '2006-01-02 15:04:05 MST'.

func (Date) MarshalJSON

func (d Date) MarshalJSON() ([]byte, error)

MarshalJSON will return null if the date is empty.

func (Date) MarshalXML

func (d Date) MarshalXML(e *xml.Encoder, start xml.StartElement) error

MarshalXML is meant to encode the time.Time into the osm note date formation of '2006-01-02 15:04:05 MST'.

func (*Date) UnmarshalXML

func (d *Date) UnmarshalXML(dec *xml.Decoder, start xml.StartElement) error

UnmarshalXML is meant to decode the osm note date formation of '2006-01-02 15:04:05 MST' into a time.Time object.

type Diff

type Diff struct {
	XMLName    xml.Name   `xml:"osm"`
	Actions    Actions    `xml:"action"`
	Changesets Changesets `xml:"changeset"`
}

Diff represents a difference of osm data with old and new data.

type Element

type Element interface {
	Object

	ElementID() ElementID
	FeatureID() FeatureID
	TagMap() map[string]string
}

An Element represents a Node, Way or Relation.

type ElementID

type ElementID int64

ElementID is a unique key for an osm element. It contains the type, id and version information.

func ParseElementID

func ParseElementID(s string) (ElementID, error)

ParseElementID takes a string and tries to determine the element id from it. The string must be formatted as "type/id:version", the same as the result of the String method.

func (ElementID) FeatureID

func (id ElementID) FeatureID() FeatureID

FeatureID returns the feature id for the element id. i.e removing the version.

func (ElementID) NodeID

func (id ElementID) NodeID() NodeID

NodeID returns the id of this feature as a node id. The function will panic if this element is not of TypeNode.

func (ElementID) ObjectID

func (id ElementID) ObjectID() ObjectID

ObjectID is a helper to convert the id to an object id.

func (ElementID) Ref

func (id ElementID) Ref() int64

Ref return the ID reference for the element. Not unique without the type.

func (ElementID) RelationID

func (id ElementID) RelationID() RelationID

RelationID returns the id of this feature as a relation id. The function will panic if this element is not of TypeRelation.

func (ElementID) String

func (id ElementID) String() string

String returns "type/ref:version" for the element.

func (ElementID) Type

func (id ElementID) Type() Type

Type returns the Type for the element.

func (ElementID) Version

func (id ElementID) Version() int

Version returns the version of the element.

func (ElementID) WayID

func (id ElementID) WayID() WayID

WayID returns the id of this feature as a way id. The function will panic if this element is not of TypeWay.

type ElementIDs

type ElementIDs []ElementID

ElementIDs is a list of element ids with helper functions on top.

func (ElementIDs) Counts

func (ids ElementIDs) Counts() (nodes, ways, relations int)

Counts returns the number of each type of element in the set of ids.

func (ElementIDs) Sort

func (ids ElementIDs) Sort()

Sort will order the ids by type, node, way, relation, changeset, and then id.

type Elements

type Elements []Element

Elements is a collection of the Element type.

func (Elements) ElementIDs

func (es Elements) ElementIDs() ElementIDs

ElementIDs returns a slice of the element ids of the elements.

func (Elements) FeatureIDs

func (es Elements) FeatureIDs() FeatureIDs

FeatureIDs returns a slice of the feature ids of the elements.

func (Elements) Sort

func (es Elements) Sort()

Sort will order the elements by type, node, way, relation, changeset, then id and lastly the version.

type FeatureID

type FeatureID int64

A FeatureID is an identifier for a feature in OSM. It is meant to represent all the versions of a given element.

func ParseFeatureID

func ParseFeatureID(s string) (FeatureID, error)

ParseFeatureID takes a string and tries to determine the feature id from it. The string must be formatted at "type/id", the same as the result of the String method.

func (FeatureID) ElementID

func (id FeatureID) ElementID(v int) ElementID

ElementID is a helper to convert the id to an element id.

func (FeatureID) NodeID

func (id FeatureID) NodeID() NodeID

NodeID returns the id of this feature as a node id. The function will panic if this feature is not of TypeNode..

func (FeatureID) ObjectID

func (id FeatureID) ObjectID(v int) ObjectID

ObjectID is a helper to convert the id to an object id.

func (FeatureID) Ref

func (id FeatureID) Ref() int64

Ref return the ID reference for the feature. Not unique without the type.

func (FeatureID) RelationID

func (id FeatureID) RelationID() RelationID

RelationID returns the id of this feature as a relation id. The function will panic if this feature is not of TypeRelation.

func (FeatureID) String

func (id FeatureID) String() string

String returns "type/ref" for the feature.

func (FeatureID) Type

func (id FeatureID) Type() Type

Type returns the Type of the feature. Returns empty string for invalid type.

func (FeatureID) WayID

func (id FeatureID) WayID() WayID

WayID returns the id of this feature as a way id. The function will panic if this feature is not of TypeWay.

type FeatureIDs

type FeatureIDs []FeatureID

FeatureIDs is a slice of FeatureIDs with some helpers on top.

func (FeatureIDs) Counts

func (ids FeatureIDs) Counts() (nodes, ways, relations int)

Counts returns the number of each type of feature in the set of ids.

func (FeatureIDs) Sort

func (ids FeatureIDs) Sort()

Sort will order the ids by type, node, way, relation, changeset, and then id.

type HistoryDatasource

type HistoryDatasource struct {
	Nodes     map[NodeID]Nodes
	Ways      map[WayID]Ways
	Relations map[RelationID]Relations
}

A HistoryDatasource wraps maps to implement the HistoryDataSource interface.

func (*HistoryDatasource) NodeHistory

func (ds *HistoryDatasource) NodeHistory(ctx context.Context, id NodeID) (Nodes, error)

NodeHistory returns the history for the given id from the map.

func (*HistoryDatasource) NotFound

func (ds *HistoryDatasource) NotFound(err error) bool

NotFound returns true if the error returned is a not found error.

func (*HistoryDatasource) RelationHistory

func (ds *HistoryDatasource) RelationHistory(ctx context.Context, id RelationID) (Relations, error)

RelationHistory returns the history for the given id from the map.

func (*HistoryDatasource) WayHistory

func (ds *HistoryDatasource) WayHistory(ctx context.Context, id WayID) (Ways, error)

WayHistory returns the history for the given id from the map.

type HistoryDatasourcer

type HistoryDatasourcer interface {
	NodeHistory(context.Context, NodeID) (Nodes, error)
	WayHistory(context.Context, WayID) (Ways, error)
	RelationHistory(context.Context, RelationID) (Relations, error)
	NotFound(error) bool
}

A HistoryDatasourcer defines an interface to osm history data.

type Member

type Member struct {
	Type Type   `xml:"type,attr" json:"type"`
	Ref  int64  `xml:"ref,attr" json:"ref"`
	Role string `xml:"role,attr" json:"role"`

	Version     int         `xml:"version,attr,omitempty" json:"version,omitempty"`
	ChangesetID ChangesetID `xml:"changeset,attr,omitempty" json:"changeset,omitempty"`

	// Node location if Type == Node
	// Closest vertex to centroid if Type == Way
	// Empty/invalid if Type == Relation
	Lat float64 `xml:"lat,attr,omitempty" json:"lat,omitempty"`
	Lon float64 `xml:"lon,attr,omitempty" json:"lon,omitempty"`

	// Orientation is the direction of the way around a ring of a multipolygon.
	// Only valid for multipolygon or boundary relations.
	Orientation orb.Orientation `xml:"orientation,attr,omitempty" json:"orientation,omitempty"`

	// Nodes are sometimes included in members of type way to include the lat/lon
	// path of the way. Overpass returns xml like this.
	Nodes WayNodes `xml:"nd" json:"nodes,omitempty"`
}

Member is a member of a relation.

func (Member) ElementID

func (m Member) ElementID() ElementID

ElementID returns the element id of the member.

func (Member) FeatureID

func (m Member) FeatureID() FeatureID

FeatureID returns the feature id of the member.

func (Member) Point

func (m Member) Point() orb.Point

Point returns the orb.Point location for the member. Will be (0, 0) if the relation is not annotated. For way members this location is annotated as the "surface point".

type Members

type Members []Member

Members represents an ordered list of relation members.

func (Members) ElementIDs

func (ms Members) ElementIDs() ElementIDs

ElementIDs returns the a list of element ids for the members.

func (Members) FeatureIDs

func (ms Members) FeatureIDs() FeatureIDs

FeatureIDs returns the a list of feature ids for the members.

func (Members) MarshalJSON

func (ms Members) MarshalJSON() ([]byte, error)

MarshalJSON allows the members to be marshalled as defined by the overpass osmjson. This function is a wrapper to marshal null as [].

type Node

type Node struct {
	XMLName     xmlNameJSONTypeNode `xml:"node" json:"type"`
	ID          NodeID              `xml:"id,attr" json:"id"`
	Lat         float64             `xml:"lat,attr" json:"lat"`
	Lon         float64             `xml:"lon,attr" json:"lon"`
	User        string              `xml:"user,attr" json:"user,omitempty"`
	UserID      UserID              `xml:"uid,attr" json:"uid,omitempty"`
	Visible     bool                `xml:"visible,attr" json:"visible"`
	Version     int                 `xml:"version,attr" json:"version,omitempty"`
	ChangesetID ChangesetID         `xml:"changeset,attr" json:"changeset,omitempty"`
	Timestamp   time.Time           `xml:"timestamp,attr" json:"timestamp"`
	Tags        Tags                `xml:"tag" json:"tags,omitempty"`

	// Committed, is the estimated time this object was committed
	// and made visible in the central OSM database.
	Committed *time.Time `xml:"committed,attr,omitempty" json:"committed,omitempty"`
}

Node is an osm point and allows for marshalling to/from osm xml.

func (*Node) CommittedAt

func (n *Node) CommittedAt() time.Time

CommittedAt returns the best estimate on when this element became was written/committed into the database.

func (*Node) ElementID

func (n *Node) ElementID() ElementID

ElementID returns the element id of the node.

func (*Node) FeatureID

func (n *Node) FeatureID() FeatureID

FeatureID returns the feature id of the node.

func (*Node) ObjectID

func (n *Node) ObjectID() ObjectID

ObjectID returns the object id of the node.

func (*Node) Point

func (n *Node) Point() orb.Point

Point returns the orb.Point location for the node. Will be (0, 0) for "deleted" nodes.

func (*Node) TagMap

func (n *Node) TagMap() map[string]string

TagMap returns the element tags as a key/value map.

type NodeID

type NodeID int64

NodeID corresponds the primary key of a node. The node id + version uniquely identify a node.

func (NodeID) ElementID

func (id NodeID) ElementID(v int) ElementID

ElementID is a helper to convert the id to an element id.

func (NodeID) FeatureID

func (id NodeID) FeatureID() FeatureID

FeatureID is a helper returning the feature id for this node id.

func (NodeID) ObjectID

func (id NodeID) ObjectID(v int) ObjectID

ObjectID is a helper returning the object id for this node id.

type Nodes

type Nodes []*Node

Nodes is a list of nodes with helper functions on top.

func (Nodes) ElementIDs

func (ns Nodes) ElementIDs() ElementIDs

ElementIDs returns the element ids for all the nodes.

func (Nodes) FeatureIDs

func (ns Nodes) FeatureIDs() FeatureIDs

FeatureIDs returns the feature ids for all the nodes.

func (Nodes) IDs

func (ns Nodes) IDs() []NodeID

IDs returns the ids for all the ways.

func (Nodes) SortByIDVersion

func (ns Nodes) SortByIDVersion()

SortByIDVersion will sort the set of nodes first by id and then version in ascending order.

type Note

type Note struct {
	XMLName     xmlNameJSONTypeNote `xml:"note" json:"type"`
	ID          NoteID              `xml:"id" json:"id"`
	Lat         float64             `xml:"lat,attr" json:"lat"`
	Lon         float64             `xml:"lon,attr" json:"lon"`
	URL         string              `xml:"url" json:"url,omitempty"`
	CommentURL  string              `xml:"comment_url" json:"comment_url,omitempty"`
	CloseURL    string              `xml:"close_url" json:"close_url,omitempty"`
	ReopenURL   string              `xml:"reopen_url" json:"reopen_url,omitempty"`
	DateCreated Date                `xml:"date_created" json:"date_created"`
	DateClosed  Date                `xml:"date_closed" json:"date_closed,omitempty"`
	Status      NoteStatus          `xml:"status" json:"status,omitempty"`
	Comments    []*NoteComment      `xml:"comments>comment" json:"comments"`
}

Note is information for other mappers dropped at a map location.

func (*Note) ObjectID

func (n *Note) ObjectID() ObjectID

ObjectID returns the object id of the note.

type NoteComment

type NoteComment struct {
	XMLName xml.Name          `xml:"comment" json:"-"`
	Date    Date              `xml:"date" json:"date"`
	UserID  UserID            `xml:"uid" json:"uid,omitempty"`
	User    string            `xml:"user" json:"user,omitempty"`
	UserURL string            `xml:"user_url" json:"user_url,omitempty"`
	Action  NoteCommentAction `xml:"action" json:"action"`
	Text    string            `xml:"text" json:"text"`
	HTML    string            `xml:"html" json:"html"`
}

NoteComment is a comment on a note.

type NoteCommentAction

type NoteCommentAction string

NoteCommentAction are actions that a note comment took.

var (
	NoteCommentOpened  NoteCommentAction = "opened"
	NoteCommentComment NoteCommentAction = "commented"
	NoteCommentClosed  NoteCommentAction = "closed"
)

The set of comment actions.

type NoteID

type NoteID int64

NoteID is the unique identifier for an osm note.

func (NoteID) ObjectID

func (id NoteID) ObjectID() ObjectID

ObjectID is a helper returning the object id for this note id.

type NoteStatus

type NoteStatus string

NoteStatus is the status of the note.

var (
	NoteOpen   NoteStatus = "open"
	NoteClosed NoteStatus = "closed"
)

A note can be open or closed.

type Notes

type Notes []*Note

Notes is a collection of notes with some helpers attached.

type OSM

type OSM struct {
	// JSON APIs can return version as a string or number, converted to string
	// for consistency.
	Version   string `xml:"version,attr,omitempty"`
	Generator string `xml:"generator,attr,omitempty"`

	// These three attributes are returned by the osm api.
	// The Copyright, Attribution and License constants contain
	// suggested values that match those returned by the official api.
	Copyright   string `xml:"copyright,attr,omitempty"`
	Attribution string `xml:"attribution,attr,omitempty"`
	License     string `xml:"license,attr,omitempty"`

	Bounds    *Bounds   `xml:"bounds,omitempty"`
	Nodes     Nodes     `xml:"node"`
	Ways      Ways      `xml:"way"`
	Relations Relations `xml:"relation"`

	// Changesets will typically not be included with actual data,
	// but all this stuff is technically all under the osm xml
	Changesets Changesets `xml:"changeset"`
	Notes      Notes      `xml:"note"`
	Users      Users      `xml:"user"`
}

OSM represents the core osm data designed to parse http://wiki.openstreetmap.org/wiki/OSM_XML

func (*OSM) Append

func (o *OSM) Append(obj Object)

Append will add the given object to the OSM object.

func (*OSM) ElementIDs

func (o *OSM) ElementIDs() ElementIDs

ElementIDs returns the slice of element ids for all the nodes, ways and relations.

func (*OSM) Elements

func (o *OSM) Elements() Elements

Elements returns all the nodes, ways and relations as a single slice of Elements.

func (*OSM) FeatureIDs

func (o *OSM) FeatureIDs() FeatureIDs

FeatureIDs returns the slice of feature ids for all the nodes, ways and relations.

func (*OSM) HistoryDatasource

func (o *OSM) HistoryDatasource() *HistoryDatasource

HistoryDatasource converts the osm object to a datasource accessible by the feature id.

func (OSM) MarshalJSON

func (o OSM) MarshalJSON() ([]byte, error)

MarshalJSON allows the tags to be marshalled as an object as defined by the overpass osmjson. http://overpass-api.de/output_formats.html#json

func (OSM) MarshalXML

func (o OSM) MarshalXML(e *xml.Encoder, start xml.StartElement) error

MarshalXML implements the xml.Marshaller method to allow for the correct wrapper/start element case and attr data.

func (*OSM) Objects

func (o *OSM) Objects() Objects

Objects returns an array of objects containing any nodes, ways, relations, changesets, notes and users.

func (*OSM) UnmarshalJSON added in v0.6.0

func (o *OSM) UnmarshalJSON(data []byte) error

UnmarshalJSON will decode osm json representation as defined by the overpass osmjson. This format can also by returned by the official OSM API. http://overpass-api.de/output_formats.html#json

type Object

type Object interface {
	ObjectID() ObjectID
	// contains filtered or unexported methods
}

An Object represents a Node, Way, Relation, Changeset, Note or User only.

type ObjectID

type ObjectID int64

ObjectID encodes the type and ref of an osm object, e.g. nodes, ways, relations, changesets, notes and users.

func ParseObjectID

func ParseObjectID(s string) (ObjectID, error)

ParseObjectID takes a string and tries to determine the object id from it. The string must be formatted as "type/id:version", the same as the result of the String method.

func (ObjectID) Ref

func (id ObjectID) Ref() int64

Ref returns the ID reference for the object. Not unique without the type.

func (ObjectID) String

func (id ObjectID) String() string

String returns "type/ref:version" for the object.

func (ObjectID) Type

func (id ObjectID) Type() Type

Type returns the Type of the object.

func (ObjectID) Version

func (id ObjectID) Version() int

Version returns the version of the object. Will return 0 if the object doesn't have versions like users, notes and changesets.

type ObjectIDs

type ObjectIDs []ObjectID

ObjectIDs is a slice of ObjectIDs with some helpers on top.

type Objects

type Objects []Object

Objects is a set of objects with some helpers

func (Objects) ObjectIDs

func (os Objects) ObjectIDs() ObjectIDs

ObjectIDs returns a slice of the object ids of the osm objects.

type Relation

type Relation struct {
	XMLName     xmlNameJSONTypeRel `xml:"relation" json:"type"`
	ID          RelationID         `xml:"id,attr" json:"id"`
	User        string             `xml:"user,attr" json:"user,omitempty"`
	UserID      UserID             `xml:"uid,attr" json:"uid,omitempty"`
	Visible     bool               `xml:"visible,attr" json:"visible"`
	Version     int                `xml:"version,attr" json:"version,omitempty"`
	ChangesetID ChangesetID        `xml:"changeset,attr" json:"changeset,omitempty"`
	Timestamp   time.Time          `xml:"timestamp,attr" json:"timestamp,omitempty"`

	Tags    Tags    `xml:"tag" json:"tags,omitempty"`
	Members Members `xml:"member" json:"members"`

	// Committed, is the estimated time this object was committed
	// and made visible in the central OSM database.
	Committed *time.Time `xml:"committed,attr,omitempty" json:"committed,omitempty"`

	// Updates are changes to the members of this relation independent
	// of an update to the relation itself. The OSM api allows a child
	// to be updated without any changes to the parent.
	Updates Updates `xml:"update,omitempty" json:"updates,omitempty"`

	// Bounds are included by overpass, and maybe others
	Bounds *Bounds `xml:"bounds,omitempty" json:"bounds,omitempty"`
}

Relation is an collection of nodes, ways and other relations with some defining attributes.

func (*Relation) ApplyUpdatesUpTo

func (r *Relation) ApplyUpdatesUpTo(t time.Time) error

ApplyUpdatesUpTo will apply the updates to this object upto and including the given time.

func (*Relation) CommittedAt

func (r *Relation) CommittedAt() time.Time

CommittedAt returns the best estimate on when this element became was written/committed into the database.

func (*Relation) ElementID

func (r *Relation) ElementID() ElementID

ElementID returns the element id of the relation.

func (*Relation) FeatureID

func (r *Relation) FeatureID() FeatureID

FeatureID returns the feature id of the relation.

func (*Relation) ObjectID

func (r *Relation) ObjectID() ObjectID

ObjectID returns the object id of the relation.

func (*Relation) Polygon

func (r *Relation) Polygon() bool

Polygon returns true if the relation is of type multipolygon or boundary.

func (*Relation) TagMap

func (r *Relation) TagMap() map[string]string

TagMap returns the element tags as a key/value map.

type RelationID

type RelationID int64

RelationID is the primary key of a relation. A relation is uniquely identifiable by the id + version.

func (RelationID) ElementID

func (id RelationID) ElementID(v int) ElementID

ElementID is a helper to convert the id to an element id.

func (RelationID) FeatureID

func (id RelationID) FeatureID() FeatureID

FeatureID is a helper returning the feature id for this relation id.

func (RelationID) ObjectID

func (id RelationID) ObjectID(v int) ObjectID

ObjectID is a helper returning the object id for this relation id.

type Relations

type Relations []*Relation

Relations is a list of relations with some helper functions attached.

func (Relations) ElementIDs

func (rs Relations) ElementIDs() ElementIDs

ElementIDs returns the element ids for all the relations.

func (Relations) FeatureIDs

func (rs Relations) FeatureIDs() FeatureIDs

FeatureIDs returns the feature ids for all the relations.

func (Relations) IDs

func (rs Relations) IDs() []RelationID

IDs returns the ids for all the relations.

func (Relations) SortByIDVersion

func (rs Relations) SortByIDVersion()

SortByIDVersion will sort the set of relations first by id and then version in ascending order.

type Scanner

type Scanner interface {
	Scan() bool
	Object() Object
	Err() error
	Close() error
}

A Scanner reads osm data from planet dump files. It is based on the bufio.Scanner, common usage. Scanners are not safe for parallel use. One should feed the objects into their own channel and have workers read from that.

s := scanner.New(r)
defer s.Close()

for s.Next() {
	o := s.Object()
	// do something
}

if s.Err() != nil {
	// scanner did not complete fully
}

type Tag

type Tag struct {
	Key   string `xml:"k,attr"`
	Value string `xml:"v,attr"`
}

Tag is a key+value item attached to osm nodes, ways and relations.

type Tags

type Tags []Tag

Tags is a collection of Tag objects with some helper functions.

func (Tags) AnyInteresting

func (ts Tags) AnyInteresting() bool

AnyInteresting will return true if there is at last one interesting tag.

func (Tags) Find

func (ts Tags) Find(k string) string

Find will return the value for the key. Will return an empty string if not found.

func (Tags) FindTag added in v0.7.1

func (ts Tags) FindTag(k string) *Tag

FindTag will return the Tag for the given key. Can be used to determine if a key exists, even with an empty value. Returns nil if not found.

func (Tags) HasTag added in v0.7.1

func (ts Tags) HasTag(k string) bool

HasTag will return the true if a tag exists for the given key.

func (Tags) Map

func (ts Tags) Map() map[string]string

Map returns the tags as a key/value map.

func (Tags) MarshalJSON

func (ts Tags) MarshalJSON() ([]byte, error)

MarshalJSON allows the tags to be marshalled as a key/value object, as defined by the overpass osmjson.

func (Tags) SortByKeyValue

func (ts Tags) SortByKeyValue()

SortByKeyValue will do an inplace sort of the tags.

func (*Tags) UnmarshalJSON

func (ts *Tags) UnmarshalJSON(data []byte) error

UnmarshalJSON allows the tags to be unmarshalled from a key/value object, as defined by the overpass osmjson.

type Type

type Type string

Type is the type of different osm objects. ie. node, way, relation, changeset, note, user.

const (
	TypeNode      Type = "node"
	TypeWay       Type = "way"
	TypeRelation  Type = "relation"
	TypeChangeset Type = "changeset"
	TypeNote      Type = "note"
	TypeUser      Type = "user"
	TypeBounds    Type = "bounds"
)

Constants for the different object types.

func (Type) FeatureID

func (t Type) FeatureID(ref int64) (FeatureID, error)

FeatureID returns a feature id from the given type.

type Update

type Update struct {
	Index   int `xml:"index,attr" json:"index"`
	Version int `xml:"version,attr" json:"version"`

	// Timestamp is the committed at time if time > CommitInfoStart or the
	// element timestamp if before that date.
	Timestamp time.Time `xml:"timestamp,attr" json:"timestamp"`

	ChangesetID ChangesetID `xml:"changeset,attr,omitempty" json:"changeset,omitempty"`
	Lat         float64     `xml:"lat,attr,omitempty" json:"lat,omitempty"`
	Lon         float64     `xml:"lon,attr,omitempty" json:"lon,omitempty"`
	Reverse     bool        `xml:"reverse,attr,omitempty" json:"reverse,omitempty"`
}

An Update is a change to children of a way or relation. The child type, id, ref and/or role are the same as the child at the given index. Lon/Lat are only updated for nodes.

type UpdateIndexOutOfRangeError

type UpdateIndexOutOfRangeError struct {
	Index int
}

UpdateIndexOutOfRangeError is return when applying an update to an object and the update index is out of range.

func (*UpdateIndexOutOfRangeError) Error

Error returns a string representation of the error.

type Updates

type Updates []Update

Updates are collections of updates.

func (Updates) SortByIndex

func (us Updates) SortByIndex()

SortByIndex will sort the updates by index in ascending order.

func (Updates) SortByTimestamp

func (us Updates) SortByTimestamp()

SortByTimestamp will sort the updates by timestamp in ascending order.

func (Updates) UpTo

func (us Updates) UpTo(t time.Time) Updates

UpTo will return the subset of updates taking place upto and on the given time.

type User

type User struct {
	XMLName     xmlNameJSONTypeUser `xml:"user" json:"type"`
	ID          UserID              `xml:"id,attr" json:"id"`
	Name        string              `xml:"display_name,attr" json:"name"`
	Description string              `xml:"description" json:"description,omitempty"`
	Img         struct {
		Href string `xml:"href,attr" json:"href"`
	} `xml:"img" json:"img"`
	Changesets struct {
		Count int `xml:"count,attr" json:"count"`
	} `xml:"changesets" json:"changesets"`
	Traces struct {
		Count int `xml:"count,attr" json:"count"`
	} `xml:"traces" json:"traces"`
	Home struct {
		Lat  float64 `xml:"lat,attr" json:"lat"`
		Lon  float64 `xml:"lon,attr" json:"lon"`
		Zoom int     `xml:"zoom,attr" json:"zoom"`
	} `xml:"home" json:"home"`
	Languages []string `xml:"languages>lang" json:"languages"`
	Blocks    struct {
		Received struct {
			Count  int `xml:"count,attr" json:"count"`
			Active int `xml:"active,attr" json:"active"`
		} `xml:"received" json:"received"`
	} `xml:"blocks" json:"blocks"`
	Messages struct {
		Received struct {
			Count  int `xml:"count,attr" json:"count"`
			Unread int `xml:"unread,attr" json:"unread"`
		} `xml:"received" json:"received"`
		Sent struct {
			Count int `xml:"count,attr" json:"count"`
		} `xml:"sent" json:"sent"`
	} `xml:"messages" json:"messages"`
	CreatedAt time.Time `xml:"account_created,attr" json:"created_at"`
}

A User is a registered OSM user.

func (*User) ObjectID

func (u *User) ObjectID() ObjectID

ObjectID returns the object id of the user.

type UserID

type UserID int64

UserID is the primary key for a user. This is unique as the display name may change.

func (UserID) ObjectID

func (id UserID) ObjectID() ObjectID

ObjectID is a helper returning the object id for this user id.

type Users

type Users []*User

Users is a collection of users with some helpers attached.

type Way

type Way struct {
	XMLName     xmlNameJSONTypeWay `xml:"way" json:"type"`
	ID          WayID              `xml:"id,attr" json:"id"`
	User        string             `xml:"user,attr" json:"user,omitempty"`
	UserID      UserID             `xml:"uid,attr" json:"uid,omitempty"`
	Visible     bool               `xml:"visible,attr" json:"visible"`
	Version     int                `xml:"version,attr" json:"version,omitempty"`
	ChangesetID ChangesetID        `xml:"changeset,attr" json:"changeset,omitempty"`
	Timestamp   time.Time          `xml:"timestamp,attr" json:"timestamp"`
	Nodes       WayNodes           `xml:"nd" json:"nodes"`
	Tags        Tags               `xml:"tag" json:"tags,omitempty"`

	// Committed, is the estimated time this object was committed
	// and made visible in the central OSM database.
	Committed *time.Time `xml:"committed,attr,omitempty" json:"committed,omitempty"`

	// Updates are changes to the nodes of this way independent
	// of an update to the way itself. The OSM api allows a child
	// to be updated without any changes to the parent.
	Updates Updates `xml:"update,omitempty" json:"updates,omitempty"`

	// Bounds are included by overpass, and maybe others
	Bounds *Bounds `xml:"bounds,omitempty" json:"bounds,omitempty"`
}

Way is an osm way, ie collection of nodes.

func (*Way) ApplyUpdatesUpTo

func (w *Way) ApplyUpdatesUpTo(t time.Time) error

ApplyUpdatesUpTo will apply the updates to this object upto and including the given time.

func (*Way) CommittedAt

func (w *Way) CommittedAt() time.Time

CommittedAt returns the best estimate on when this element became was written/committed into the database.

func (*Way) ElementID

func (w *Way) ElementID() ElementID

ElementID returns the element id of the way.

func (*Way) FeatureID

func (w *Way) FeatureID() FeatureID

FeatureID returns the feature id of the way.

func (*Way) LineString

func (w *Way) LineString() orb.LineString

LineString will convert the annotated nodes into a LineString datatype.

func (*Way) LineStringAt

func (w *Way) LineStringAt(t time.Time) orb.LineString

LineStringAt will return the LineString from the annotated points at the given time. It will apply to the updates upto and including the give time.

func (*Way) ObjectID

func (w *Way) ObjectID() ObjectID

ObjectID returns the object id of the way.

func (*Way) Polygon

func (w *Way) Polygon() bool

Polygon returns true if the way should be considered a closed polygon area. OpenStreetMap doesn't have an intrinsic area data type. The algorithm used here considers a set of heuristics to determine what is most likely an area. The heuristics can be found here, https://wiki.openstreetmap.org/wiki/Overpass_turbo/Polygon_Features and are used by osmtogeojson and overpass turbo.

func (*Way) TagMap

func (w *Way) TagMap() map[string]string

TagMap returns the element tags as a key/value map.

type WayID

type WayID int64

WayID is the primary key of a way. A way is uniquely identifiable by the id + version.

func (WayID) ElementID

func (id WayID) ElementID(v int) ElementID

ElementID is a helper to convert the id to an element id.

func (WayID) FeatureID

func (id WayID) FeatureID() FeatureID

FeatureID is a helper returning the feature id for this way id.

func (WayID) ObjectID

func (id WayID) ObjectID(v int) ObjectID

ObjectID is a helper returning the object id for this way id.

type WayNode

type WayNode struct {
	ID NodeID `xml:"ref,attr,omitempty"`

	// These attributes are populated for concrete versions of ways.
	Version     int         `xml:"version,attr,omitempty"`
	ChangesetID ChangesetID `xml:"changeset,attr,omitempty"`
	Lat         float64     `xml:"lat,attr,omitempty"`
	Lon         float64     `xml:"lon,attr,omitempty"`
}

WayNode is a short node used as part of ways and relations in the osm xml.

func (WayNode) ElementID

func (wn WayNode) ElementID() ElementID

ElementID returns the element id of the way node.

func (WayNode) FeatureID

func (wn WayNode) FeatureID() FeatureID

FeatureID returns the feature id of the way node.

func (WayNode) Point

func (wn WayNode) Point() orb.Point

Point returns the orb.Point location for the way node. Will be (0, 0) if the way is not annotated.

type WayNodes

type WayNodes []WayNode

WayNodes represents a collection of way nodes.

func (WayNodes) Bound added in v0.1.0

func (wn WayNodes) Bound() orb.Bound

Bound computes the orb.Bound for the given way nodes.

func (WayNodes) Bounds

func (wn WayNodes) Bounds() *Bounds

Bounds computes the bounds for the given way nodes.

func (WayNodes) ElementIDs

func (wn WayNodes) ElementIDs() ElementIDs

ElementIDs returns a list of element ids for the way nodes.

func (WayNodes) FeatureIDs

func (wn WayNodes) FeatureIDs() FeatureIDs

FeatureIDs returns a list of feature ids for the way nodes.

func (WayNodes) MarshalJSON

func (wn WayNodes) MarshalJSON() ([]byte, error)

MarshalJSON allows the waynodes to be marshalled as an array of ids, as defined by the overpass osmjson.

func (WayNodes) NodeIDs

func (wn WayNodes) NodeIDs() []NodeID

NodeIDs returns a list of node ids for the way nodes.

func (*WayNodes) UnmarshalJSON

func (wn *WayNodes) UnmarshalJSON(data []byte) error

UnmarshalJSON allows the tags to be unmarshalled from an array of ids, as defined by the overpass osmjson.

type Ways

type Ways []*Way

Ways is a list of osm ways with some helper functions attached.

func (Ways) ElementIDs

func (ws Ways) ElementIDs() ElementIDs

ElementIDs returns the element ids for all the ways.

func (Ways) FeatureIDs

func (ws Ways) FeatureIDs() FeatureIDs

FeatureIDs returns the feature ids for all the ways.

func (Ways) IDs

func (ws Ways) IDs() []WayID

IDs returns the ids for all the ways.

func (Ways) SortByIDVersion

func (ws Ways) SortByIDVersion()

SortByIDVersion will sort the set of ways first by id and then version in ascending order.

Directories

Path Synopsis
shared
Package shared is used by annotate and the internal core.
Package shared is used by annotate and the internal core.
internal
Package osmapi provides an interface to the OSM v0.6 API.
Package osmapi provides an interface to the OSM v0.6 API.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL