Exemplo n.º 1
0
Arquivo: way.go Projeto: vetinari/osm
// Opens a closed way (i.e. a way where the last node has the
// same id as the first one) at the node with the given id. A
// new node is inserted where the way is open. This new node
// will be the end of the current way -> the first node will
// not necessarily stay the first node
func (w *Way) OpenAt(id int64) (nn *node.Node, err error) {
	if !w.Closed() {
		return nil, errors.New("Cannot open non-closed way")
	}
	var i int
	var nd *node.Node
	last := len(w.Nodes_) - 1
	for i, nd = range w.Nodes_ {
		if nd.Id_ != id {
			continue
		}

		w.modified = true
		nn = node.New(nd.Position_)
		nn.Tags_ = nd.Tags_

		if i == 0 {
			w.Nodes_[last] = nn
			return nn, nil
		}

		nb, nl := w.Nodes_[:i], w.Nodes_[i:]
		nl = append(nl, nb...)
		w.Nodes_ = append(nl, nn)

		return nn, nil
	}

	return nil, errors.New(fmt.Sprintf("Node #%d not a member of way #%d", id, w.Id()))
}
Exemplo n.º 2
0
Arquivo: way.go Projeto: vetinari/osm
// Splits a way and returns all resulting ways. For a closed way at least two
// node ids must be given. A resulting way must contain at least two nodes.
func (w *Way) Split(ids ...int64) (ws []*Way, err error) {
	var orig []*node.Node
	for _, n := range w.Nodes_ {
		orig = append(orig, n)
	}

	if w.Closed() {
		if len(ids) < 2 {
			err = errors.New("Not enough arguments to split a closed way")
			return
		}
		var id0 int64
		id0, ids = ids[0], ids[1:]
		_, err = w.OpenAt(id0)
		if err != nil {
			w.Nodes_ = orig
			return
		}
	}

	min_len := 2*len(ids) + 1
	if min_len > len(w.Nodes_) {
		w.Nodes_ = orig
		err = errors.New("Way has too few nodes to split")
		return
	}

	ws = []*Way{w}
	cur_w := w
	for _, id := range ids {
		// the node with the id "id" will be the last node of the current
		// way, a new node with the same position is inserted at the
		// beginning of the new way
		var nid int64
		nid, err = cur_w.NextNodeId(id)
		if err != nil {
			w.Nodes_ = orig
			ws = EmptyWays()
			err = errors.New(fmt.Sprintf("Node #%d not a member of way #%d", nid, w.Id()))
			return
		}
		for i, n := range cur_w.Nodes_ {
			if n.Id_ == nid {
				if i == 0 || i == len(cur_w.Nodes_)-1 {
					w.Nodes_ = orig
					ws = EmptyWays()
					err = errors.New("Cannot split way at first or last node")
					return
				}
				if i == 1 {
					w.Nodes_ = orig
					ws = EmptyWays()
					err = errors.New("Cannot split into a way with one node")
					return
				}

				nn := node.New(n.Position_)
				nn.Tags_ = n.Tags_
				nl := []*node.Node{nn}
				for _, nd := range cur_w.Nodes_[i:] {
					nl = append(nl, nd)
				}
				cur_w.Nodes_ = cur_w.Nodes_[0:i]
				var new_w *Way
				new_w, err = New(nl)
				if err != nil {
					w.Nodes_ = orig
					ws = EmptyWays()
					return
				}
				new_w.Tags_ = cur_w.Tags_
				ws = append(ws, new_w)
				cur_w = new_w
			}
		}
	}
	w.modified = true
	return ws, nil
}