/** * This file is part of OSM2ShareNav * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. * * @version $Revision$ ($Name$) * @author hmueller * Copyright (C) 2007-2010 Harald Mueller */ package net.sharenav.osmToShareNav.model; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; public class Path extends ArrayList<Node> { public Path() { super(2); } public Path(ArrayList<Node> newNodeList) { super(newNodeList); } // create a reversed way public Path(ArrayList<Node> nodeList, boolean reverse) { super(2); //System.out.println("size: " + nodeList.size()); for (int i = nodeList.size()-1; i >= 0; i--) { //System.out.println("Adding node: " + nodeList.get(i)); this.add(nodeList.get(i)); } } public boolean add(Node n) { return super.add(n); } /** * @param i Index of wanted node * @return Node at index i or null if */ public Node getNode(int i) { if (size() == 0) { return null; } else { if (i >= 0 && i < size()) { return get(i); } else { return null; } } } public List<Node> getNodes() { return this; } @Deprecated public boolean isMultiPath() { // if (subPathList != null) { // if (subPathList.size() == 1) { // return false; // } else { // return true; // } // } return false; } @Deprecated public int getPathCount() { return 1; } /** * Replaces node1 with node2 in this path. * @param node1 Node to be replaced * @param node2 Node by which to replace node1. */ public void replace(Node node1, Node node2) { int occur = this.indexOf(node1); while (occur != -1) { this.set(occur, node2); occur = this.indexOf(node1); } } /** replaceNodes lists nodes and by which nodes they have to be replaced. * This method applies this list to this path. * @param replaceNodes Hashmap of pairs of nodes */ public void replace(HashMap<Node, Node> replaceNodes) { for (int i = 0; i < this.size(); i++) { Node newNode = replaceNodes.get(this.get(i)); if (newNode != null) { this.set(i, newNode); } } } /** * @return The number of lines of this path, i.e. nodes - 1. */ public int getLineCount() { if (this.size() == 0) { return 0; } if (this.size() > 1) { return (this.size() - 1); } return 0; } /** * TODO: This returns 0 if size() == 1, this is probably intentional but can causes trouble in some use cases * if it is made to be ..size() >= 1, messages like "no center for searchList for id=24429358 type=1 [ref=45 highway=motorway foot=no name=Tuusulanväylä oneway=yes maxspeed=80 bicycle=no ]" * will appear * @return The number of nodes of this path or 0 if there is no node list. */ public int getNodeCount() { if (this.size() == 0) { return 0; } if (this.size() > 1) { return (this.size()); } return 0; } /** * split this Path at the half subPath elements * @return null if the Path already have one Subpath, * a new Path with the rest after split. */ public Path split() { if (this.size() == 0 || getLineCount() < 2) { return null; } int splitP = this.size() / 2; ArrayList<Node> newNodeList = new ArrayList<Node>(1); int a = 0; for (Iterator<Node> si = this.iterator(); si.hasNext();) { Node t = si.next(); if (a >= splitP) { newNodeList.add(t); if (a > splitP) { si.remove(); } } a++; } newNodeList.trimToSize(); Path newPath = new Path(newNodeList); // Shrink the list to the actual size. trimPath(); return newPath; } public void trimPath() { this.trimToSize(); } /** * @param bound */ public void extendBounds(Bounds bound) { for (Node n:this) { bound.extend(n.lat, n.lon); } } }