// 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())) }
// 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 }