Beispiel #1
0
// move all points of w, use the node with id as reference to do a relative move
func (w *Way) MoveTo(id int64, p *point.Point) error {
	ref := w.Nodes_[id]
	if ref == nil {
		return errors.New(fmt.Sprintf("Node #%d not part of Way #%d\n", id, w.Id()))
	}
	return w.RMoveTo(point.New(ref.Position().Lat-p.Lat, ref.Position().Lon-p.Lon))
}
Beispiel #2
0
// Weighted centroid of all area parts
//
// NOTE - when a relation has node members outside of the way members, this will
//        probably result in a wrong point (bounding box is taken from all nodes,
//        not just way nodes)
func (r *Relation) Centroid() (p *point.Point, err error) {
	if !r.IsAreaRelation() {
		err = errors.New("Not an area relation")
		return
	}

	var seen []*way.Way
	var bb *bbox.BBox
	var lat float64
	var lon float64
	var den float64

	wayList, err := r.WayMembersAsWays()
	if err != nil {
		return
	}
	bb, err = r.BoundingBox()
	if err != nil {
		return
	}
	for _, w := range wayList {
		c := w.Centroid()
		if c == nil {
			err = errors.New(fmt.Sprintf("Way #%d has no centroid?!", w.Id()))
			return
		}

		a := w.Area()
		if a == -1.0 {
			err = errors.New(fmt.Sprintf("Way #%d has no area", w.Id()))
			return
		}

		count := 0
		for _, s := range seen {
			if s.Contains(w.Nodes_[0]) {
				count += 1
			}
		}
		seen = append(seen, w)

		neg := 1.0
		if count%2 == 1 {
			neg = -1.0
		}

		lon += a * neg * (c.Lon - bb.LowerLeft.Lon)
		lat += a * neg * (c.Lat - bb.LowerLeft.Lat)
		den += a * neg
	}

	return point.New(bb.LowerLeft.Lat+lat/den, bb.LowerLeft.Lon+lon/den), nil
}
Beispiel #3
0
func (nl NodeList) BoundingBox() (bb *bbox.BBox, err error) {
	if nl == nil {
		err = errors.New("Empty Nodelist")
		return
	}
	n := []*Node(nl)
	llat := n[0].Position_.Lat
	ulat := n[0].Position_.Lat
	llon := n[0].Position_.Lon
	ulon := n[0].Position_.Lon

	l := len(n)
	for i := 1; i < l; i++ {
		llat = math.Min(llat, n[i].Position_.Lat)
		ulat = math.Max(ulat, n[i].Position_.Lat)
		llon = math.Min(llon, n[i].Position_.Lon)
		ulon = math.Max(ulon, n[i].Position_.Lon)
	}

	return &bbox.BBox{
		LowerLeft:  point.New(llat, llon),
		UpperRight: point.New(ulat, ulon),
	}, nil
}
Beispiel #4
0
func (w *Way) Centroid() *point.Point {
	if !w.Closed() {
		return nil
	}

	var cx, cy, a float64
	l := len(w.Nodes_) - 1
	for i := 0; i < l; i++ {
		ap := w.Nodes_[i].Position_.Lon*w.Nodes_[i+1].Position_.Lat - w.Nodes_[i+1].Position_.Lon*w.Nodes_[i].Position_.Lat
		cx += (w.Nodes_[i].Position_.Lon + w.Nodes_[i+1].Position_.Lon) * ap
		cy += (w.Nodes_[i].Position_.Lat + w.Nodes_[i+1].Position_.Lat) * ap
		a += ap
	}
	cx = 2 * cx / (6 * a)
	cy = 2 * cy / (6 * a)
	return point.New(cy, cx)
}
Beispiel #5
0
// implements the osm.Parser interface
func (p *Pbf) Parse() (o *osm.OSM, err error) {
	d := osmpbf.NewDecoder(p.r)

	err = d.Start(runtime.GOMAXPROCS(-1))
	if err != nil {
		return
	}

	o = osm.NewOSM()
	var v interface{}
	for {
		if v, err = d.Decode(); err == io.EOF {
			err = nil
			break
		} else if err != nil {
			return
		} else {
			switch v := v.(type) {
			case *osmpbf.Node:
				var t tags.Tags
				if v.Tags != nil && len(v.Tags) != 0 {
					t = tags.Tags(v.Tags)
				}
				o.Nodes[v.ID] = &node.Node{
					Id_:        v.ID,
					User_:      user.New(int64(v.Info.Uid), v.Info.User),
					Position_:  point.New(v.Lat, v.Lon),
					Timestamp_: v.Info.Timestamp,
					Changeset_: v.Info.Changeset,
					Version_:   int64(v.Info.Version),
					Visible_:   v.Info.Visible,
					Tags_:      &t,
				}
			case *osmpbf.Way:
				var t tags.Tags
				if v.Tags != nil && len(v.Tags) != 0 {
					t = tags.Tags(v.Tags)
				}
				w := &way.Way{
					Id_:        v.ID,
					User_:      user.New(int64(v.Info.Uid), v.Info.User),
					Timestamp_: v.Info.Timestamp,
					Changeset_: v.Info.Changeset,
					Version_:   int64(v.Info.Version),
					Visible_:   v.Info.Visible,
					Tags_:      &t,
				}
				var nd []*node.Node
				for _, id := range v.NodeIDs {
					n := o.Nodes[id]
					if n == nil {
						err = errors.New(fmt.Sprintf("Missing node #%d in way #%d", id, v.ID))
						o = nil
						return
					}
					nd = append(nd, n)
				}
				w.Nodes_ = nd
				o.Ways[v.ID] = w
			case *osmpbf.Relation:
				var t tags.Tags
				if v.Tags != nil && len(v.Tags) != 0 {
					t = tags.Tags(v.Tags)
				}
				r := &relation.Relation{
					Id_:        v.ID,
					User_:      user.New(int64(v.Info.Uid), v.Info.User),
					Timestamp_: v.Info.Timestamp,
					Changeset_: v.Info.Changeset,
					Version_:   int64(v.Info.Version),
					Visible_:   v.Info.Visible,
					Tags_:      &t,
				}
				var members []*relation.Member
				for _, m := range v.Members {
					member := &relation.Member{Role: m.Role, Id_: m.ID}
					switch m.Type {
					case osmpbf.NodeType:
						member.Type_ = item.TypeNode
						member.Ref = o.GetNode(m.ID)
					case osmpbf.WayType:
						member.Type_ = item.TypeWay
						member.Ref = o.GetWay(m.ID)
					case osmpbf.RelationType:
						member.Type_ = item.TypeRelation
						member.Ref = o.GetRelation(m.ID)
					}
					if member.Ref == nil {
						err = errors.New(fmt.Sprintf("Missing member #%d (%s) in way #%d", m.ID, member.Type(), v.ID))
						o = nil
						return
					}
					members = append(members, member)
				}
				r.Members_ = members
				o.Relations[v.ID] = r
			default:
				log.Printf("ERROR: unknown type %T\n", v)
			}
		}
	}
	return
}
Beispiel #6
0
func (x *DotOSM) parseItem(line string) (i item.Item, err error) {
	prefix, closed, m := x.parseLine(line)

	var ts time.Time
	if m["timestamp"] != "" {
		ts, err = time.Parse(time.RFC3339, m["timestamp"])
		if err != nil {
			err = errors.New(fmt.Sprintf("Failed to parse timestamp '%s': %s\n", m["timestamp"], err))
			return
		}
	}
	switch prefix {
	case "<node":
		n := &node.Node{
			Id_:        str2int64(m["id"]),
			User_:      user.New(str2int64(m["uid"]), m["user"]),
			Position_:  point.New(str2float64(m["lat"]), str2float64(m["lon"])),
			Timestamp_: ts,
			Version_:   str2int64(m["version"]),
			Changeset_: str2int64(m["changeset"]),
			Visible_:   str2bool(m["visible"]),
		}
		if !closed {
			n.Tags_ = x.parseTags("node")
		}
		// fmt.Printf("NODE=%q\n", n)
		return n, nil

	case "<way":
		if closed {
			err = errors.New(fmt.Sprintf("Way %s has no nodes\n", m["id"]))
			return
		}

		w := &way.Way{
			Id_:        str2int64(m["id"]),
			User_:      user.New(str2int64(m["uid"]), m["user"]),
			Timestamp_: ts,
			Version_:   str2int64(m["version"]),
			Changeset_: str2int64(m["changeset"]),
			Visible_:   str2bool(m["visible"]),
		}
		var t *tags.Tags
		var nd []*node.Node
		t, nd, err = x.parseWay(str2int64(m["id"]))
		if err != nil {
			return
		}
		w.Tags_ = t
		w.Nodes_ = nd

		// fmt.Printf("WAY=%q\n", w)
		return w, nil

	case "<relation":
		if closed {
			err = errors.New(fmt.Sprintf("Relation %s has no members\n", m["id"]))
			return
		}

		rel := &relation.Relation{
			Id_:        str2int64(m["id"]),
			User_:      user.New(str2int64(m["uid"]), m["user"]),
			Timestamp_: ts,
			Version_:   str2int64(m["version"]),
			Changeset_: str2int64(m["changeset"]),
			Visible_:   str2bool(m["visible"]),
		}
		members, tags := x.parseRelation(str2int64(m["id"]))
		rel.Members_ = members
		rel.Tags_ = tags

		// fmt.Printf("RELATION=%q\n", rel)
		return rel, nil

	case "<osm":
		// fmt.Printf("OSM=%q\n", m)
	case "</osm>":
		// fmt.Printf("/OSM\n")
	case "<bounds":
		// fmt.Printf("BOUNDS=%q\n", m)
	default:
		// fmt.Printf("OTHER=%q\n", m)
	}
	return &xmlItem{t: item.TypeUnknown}, nil
}