Index: applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/Lakewalker.java
===================================================================
--- applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/Lakewalker.java	(revision 12588)
+++ applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/Lakewalker.java	(revision 12778)
@@ -16,461 +16,461 @@
 
 public class Lakewalker {
-	protected Collection<Command> commands = new LinkedList<Command>();
-	protected Collection<Way> ways = new ArrayList<Way>();
-	protected boolean cancel;
-	  
-	private int waylen;
-	private int maxnode;
-	private int threshold;
-	private double epsilon;
-	private int resolution;
-	private int tilesize;
-	private String startdir;
-	private String wmslayer;
-	
-	private File workingdir;
-	
-	private int[] dirslat = new int[] {0,1,1,1,0,-1,-1,-1};
-	private int[] dirslon = new int[] {1,1,0,-1,-1,-1,0,1};
-	
-	double start_radius_big = 0.001;
-	double start_radius_small = 0.0002;
-	
-	public Lakewalker(int waylen, int maxnode, int threshold, double epsilon, int resolution, int tilesize, String startdir, String wmslayer, File workingdir){
-		this.waylen = waylen;
-		this.maxnode = maxnode;
-		this.threshold = threshold;
-		this.epsilon = epsilon;
-		this.resolution = resolution;
-		this.tilesize = tilesize;
-		this.startdir = startdir;
-		this.wmslayer = wmslayer;
-		
-		this.workingdir = workingdir;			
-	}
-	
-	/**
-	 *  east = 0
-	 *  northeast = 1
-	 *  north = 2
-	 *  northwest = 3
-	 *  west = 4
-	 *  southwest = 5
-	 *  south = 6
-	 *  southeast = 7  
-	 */
-	private int getDirectionIndex(String direction) throws ArrayIndexOutOfBoundsException{
-		int i=0;
-		if(direction.equals("East") || direction.equals("east")){
-			i = 0;
-		} else if(direction.equals("Northeast") || direction.equals("northeast")){
-			i =  1;
-		} else if(direction.equals("North") || direction.equals("north")){
-			i =  2;
-		} else if(direction.equals("Northwest") || direction.equals("northwest")){
-			i =  3;
-		} else if(direction.equals("West") || direction.equals("west")){
-			i =  4;
-		} else if(direction.equals("Southwest") || direction.equals("southwest")){
-			i =  5;
-		} else if(direction.equals("South") || direction.equals("south")){
-			i =  6;
-		} else if(direction.equals("Southeast") || direction.equals("southeast")){
-			i =  7;
-		} else {
-			throw new ArrayIndexOutOfBoundsException(tr("Direction index '{0}' not found",direction));
-		}
-		return i;
-	}
-	
-	/**
-	 * Do a trace
-	 * 
-	 * @param lat
-	 * @param lon
-	 * @param tl_lon
-	 * @param br_lon
-	 * @param tl_lat
-	 * @param br_lat
-	 */
-	public ArrayList<double[]> trace(double lat, double lon, double tl_lon, double br_lon, double tl_lat, double br_lat) throws LakewalkerException {
-				
-		LakewalkerWMS wms = new LakewalkerWMS(this.resolution, this.tilesize, this.wmslayer, this.workingdir);
-		LakewalkerBBox bbox = new LakewalkerBBox(tl_lat,tl_lon,br_lat,br_lon);
-		
-		Boolean detect_loop = false;
-		
-		ArrayList<double[]> nodelist = new ArrayList<double[]>();
-
-		int[] xy = geo_to_xy(lat,lon,this.resolution); 
-		
-		if(!bbox.contains(lat, lon)){
-			throw new LakewalkerException(tr("The starting location was not within the bbox"));
-		}
-		
-		int v;
-		
-		setStatus(tr("Looking for shoreline..."));
-		
-		while(true){
-			double[] geo = xy_to_geo(xy[0],xy[1],this.resolution);
-			if(bbox.contains(geo[0],geo[1])==false){
-				break;
-			}
-			
-			v = wms.getPixel(xy[0], xy[1]);
-			if(v > this.threshold){
-				break;
-			}
-			
-			int delta_lat = this.dirslat[getDirectionIndex(this.startdir)];
-			int delta_lon = this.dirslon[getDirectionIndex(this.startdir)];
-			
-			xy[0] = xy[0]+delta_lon;
-			xy[1] = xy[1]+delta_lat;
-			
-		}
-		
-		int[] startxy = new int[] {xy[0], xy[1]};
-		double[] startgeo = xy_to_geo(xy[0],xy[1],this.resolution);
-
-		//System.out.printf("Found shore at lat %.4f lon %.4f\n",lat,lon);
-		
-		int last_dir = this.getDirectionIndex(this.startdir);
-		
-		for(int i = 0; i < this.maxnode; i++){
-			
-			// Print a counter
-			if(i % 250 == 0){
-				setStatus(tr("{0} nodes so far...",i));
-				//System.out.println(i+" nodes so far...");
-			}
-			
-			// Some variables we need
-			int d;
-			int test_x=0;
-			int test_y=0;
-			int new_dir = 0;
-			
-			// Loop through all the directions we can go
-			for(d = 1; d <= this.dirslat.length; d++){
-				
-				// Decide which direction we want to look at from this pixel
-				new_dir = (last_dir + d + 4) % 8;
-
-				test_x = xy[0] + this.dirslon[new_dir];
-				test_y = xy[1] + this.dirslat[new_dir];
-				
-				double[] geo = xy_to_geo(test_x,test_y,this.resolution);
-				
-				if(!bbox.contains(geo[0], geo[1])){
-					System.out.println("Outside bbox");
-					break;
-				}
-				
-				v = wms.getPixel(test_x, test_y);
-				if(v > this.threshold){
-					break;
-				}
-				
-				if(d == this.dirslat.length-1){
-					System.out.println("Got stuck");
-					break;
-				}
-			}
-
-			// Remember this direction
-			last_dir = new_dir;
-			
-			// Set the pixel we found as current
-			xy[0] = test_x;
-			xy[1] = test_y;
-			
-			// Break the loop if we managed to get back to our starting point
-			if(xy[0] == startxy[0] && xy[1] == startxy[1]){
-				break;
-			}
-			
-			// Store this node
-			double[] geo = xy_to_geo(xy[0],xy[1],this.resolution);
-			nodelist.add(geo);
-			//System.out.println("Adding node at "+xy[0]+","+xy[1]+" ("+geo[1]+","+geo[0]+")");
-			
-			// Check if we got stuck in a loop 
-	        double start_proximity = Math.pow((geo[0] - startgeo[0]),2) + Math.pow((geo[1] - startgeo[1]),2);
-	        
-			if(detect_loop){
-	            if(start_proximity < Math.pow(start_radius_small,2)){
-	            	System.out.println("Detected loop");
-	                break;
-	            }
-			}else{
-	            if(start_proximity > Math.pow(start_radius_big,2)){
-	                detect_loop = true;
-	            }
-			}			
-		}
-
-		return nodelist;
-	}
-	
-	/**
-	 * Remove duplicate nodes from the list
-	 * 
-	 * @param nodes
-	 * @return
-	 */
-	public ArrayList<double[]> duplicateNodeRemove(ArrayList<double[]> nodes){
-		
-		if(nodes.size() <= 1){
-			return nodes;
-		}
-		
-		double lastnode[] = new double[] {nodes.get(0)[0], nodes.get(0)[1]};
-		
-		for(int i = 1; i < nodes.size(); i++){
-			double[] thisnode = new double[] {nodes.get(i)[0], nodes.get(i)[1]};
-			
-			if(thisnode[0] == lastnode[0] && thisnode[1] == lastnode[1]){
-				// Remove the node
-				nodes.remove(i);
-				
-				// Shift back one index 
-				i = i - 1;
-			}
-			lastnode = thisnode;
-		}
-		
-		return nodes;
-	}
-	
-	/**
-	 * Reduce the number of vertices based on their proximity to each other 
-	 * 
-	 * @param nodes
-	 * @param proximity
-	 * @return
-	 */
-	public ArrayList<double[]> vertexReduce(ArrayList<double[]> nodes, double proximity){
-		
-		// Check if node list is empty
-		if(nodes.size()<=1){
-			return nodes;
-		}
-		
-		double[] test_v = nodes.get(0);
-		ArrayList<double[]> reducednodes = new ArrayList<double[]>();
-		
-		double prox_sq = Math.pow(proximity, 2);
-		
-		for(int v = 0; v < nodes.size(); v++){
-			if(Math.pow(nodes.get(v)[0] - test_v[0],2) + Math.pow(nodes.get(v)[1] - test_v[1],2) > prox_sq){
-				reducednodes.add(nodes.get(v));
-				test_v = nodes.get(v);
-			}
-		}
-		
-		return reducednodes;
-	}
-	
-	public double pointLineDistance(double[] p1, double[] p2, double[] p3){
-		
-		double x0 = p1[0]; 
-		double y0 = p1[1];
-		double x1 = p2[0]; 
-		double y1 = p2[1]; 
-		double x2 = p3[0]; 
-		double y2 = p3[1];
-		
-		if(x2 == x1 && y2 == y1){
-			return Math.sqrt(Math.pow(x1-x0,2) + Math.pow(y1-y0,2));
-		} else {
-			return Math.abs((x2-x1)*(y1-y0) - (x1-x0)*(y2-y1)) / Math.sqrt(Math.pow(x2-x1,2) + Math.pow(y2-y1,2));
-		}
-	}
-	
-	public ArrayList<double[]> douglasPeuckerNR(ArrayList<double[]> nodes, double epsilon){
-		/*
-		command_stack = [(0, len(nodes) - 1)]
-		                 
-		Vector result_stack = new Vector();
+    protected Collection<Command> commands = new LinkedList<Command>();
+    protected Collection<Way> ways = new ArrayList<Way>();
+    protected boolean cancel;
+
+    private int waylen;
+    private int maxnode;
+    private int threshold;
+    private double epsilon;
+    private int resolution;
+    private int tilesize;
+    private String startdir;
+    private String wmslayer;
+
+    private File workingdir;
+
+    private int[] dirslat = new int[] {0,1,1,1,0,-1,-1,-1};
+    private int[] dirslon = new int[] {1,1,0,-1,-1,-1,0,1};
+
+    double start_radius_big = 0.001;
+    double start_radius_small = 0.0002;
+
+    public Lakewalker(int waylen, int maxnode, int threshold, double epsilon, int resolution, int tilesize, String startdir, String wmslayer, File workingdir){
+        this.waylen = waylen;
+        this.maxnode = maxnode;
+        this.threshold = threshold;
+        this.epsilon = epsilon;
+        this.resolution = resolution;
+        this.tilesize = tilesize;
+        this.startdir = startdir;
+        this.wmslayer = wmslayer;
+
+        this.workingdir = workingdir;
+    }
+
+    /**
+     *  east = 0
+     *  northeast = 1
+     *  north = 2
+     *  northwest = 3
+     *  west = 4
+     *  southwest = 5
+     *  south = 6
+     *  southeast = 7
+     */
+    private int getDirectionIndex(String direction) throws ArrayIndexOutOfBoundsException{
+        int i=0;
+        if(direction.equals("East") || direction.equals("east")){
+            i = 0;
+        } else if(direction.equals("Northeast") || direction.equals("northeast")){
+            i =  1;
+        } else if(direction.equals("North") || direction.equals("north")){
+            i =  2;
+        } else if(direction.equals("Northwest") || direction.equals("northwest")){
+            i =  3;
+        } else if(direction.equals("West") || direction.equals("west")){
+            i =  4;
+        } else if(direction.equals("Southwest") || direction.equals("southwest")){
+            i =  5;
+        } else if(direction.equals("South") || direction.equals("south")){
+            i =  6;
+        } else if(direction.equals("Southeast") || direction.equals("southeast")){
+            i =  7;
+        } else {
+            throw new ArrayIndexOutOfBoundsException(tr("Direction index '{0}' not found",direction));
+        }
+        return i;
+    }
+
+    /**
+     * Do a trace
+     *
+     * @param lat
+     * @param lon
+     * @param tl_lon
+     * @param br_lon
+     * @param tl_lat
+     * @param br_lat
+     */
+    public ArrayList<double[]> trace(double lat, double lon, double tl_lon, double br_lon, double tl_lat, double br_lat) throws LakewalkerException {
+
+        LakewalkerWMS wms = new LakewalkerWMS(this.resolution, this.tilesize, this.wmslayer, this.workingdir);
+        LakewalkerBBox bbox = new LakewalkerBBox(tl_lat,tl_lon,br_lat,br_lon);
+
+        Boolean detect_loop = false;
+
+        ArrayList<double[]> nodelist = new ArrayList<double[]>();
+
+        int[] xy = geo_to_xy(lat,lon,this.resolution);
+
+        if(!bbox.contains(lat, lon)){
+            throw new LakewalkerException(tr("The starting location was not within the bbox"));
+        }
+
+        int v;
+
+        setStatus(tr("Looking for shoreline..."));
+
+        while(true){
+            double[] geo = xy_to_geo(xy[0],xy[1],this.resolution);
+            if(bbox.contains(geo[0],geo[1])==false){
+                break;
+            }
+
+            v = wms.getPixel(xy[0], xy[1]);
+            if(v > this.threshold){
+                break;
+            }
+
+            int delta_lat = this.dirslat[getDirectionIndex(this.startdir)];
+            int delta_lon = this.dirslon[getDirectionIndex(this.startdir)];
+
+            xy[0] = xy[0]+delta_lon;
+            xy[1] = xy[1]+delta_lat;
+
+        }
+
+        int[] startxy = new int[] {xy[0], xy[1]};
+        double[] startgeo = xy_to_geo(xy[0],xy[1],this.resolution);
+
+        //System.out.printf("Found shore at lat %.4f lon %.4f\n",lat,lon);
+
+        int last_dir = this.getDirectionIndex(this.startdir);
+
+        for(int i = 0; i < this.maxnode; i++){
+
+            // Print a counter
+            if(i % 250 == 0){
+                setStatus(tr("{0} nodes so far...",i));
+                //System.out.println(i+" nodes so far...");
+            }
+
+            // Some variables we need
+            int d;
+            int test_x=0;
+            int test_y=0;
+            int new_dir = 0;
+
+            // Loop through all the directions we can go
+            for(d = 1; d <= this.dirslat.length; d++){
+
+                // Decide which direction we want to look at from this pixel
+                new_dir = (last_dir + d + 4) % 8;
+
+                test_x = xy[0] + this.dirslon[new_dir];
+                test_y = xy[1] + this.dirslat[new_dir];
+
+                double[] geo = xy_to_geo(test_x,test_y,this.resolution);
+
+                if(!bbox.contains(geo[0], geo[1])){
+                    System.out.println("Outside bbox");
+                    break;
+                }
+
+                v = wms.getPixel(test_x, test_y);
+                if(v > this.threshold){
+                    break;
+                }
+
+                if(d == this.dirslat.length-1){
+                    System.out.println("Got stuck");
+                    break;
+                }
+            }
+
+            // Remember this direction
+            last_dir = new_dir;
+
+            // Set the pixel we found as current
+            xy[0] = test_x;
+            xy[1] = test_y;
+
+            // Break the loop if we managed to get back to our starting point
+            if(xy[0] == startxy[0] && xy[1] == startxy[1]){
+                break;
+            }
+
+            // Store this node
+            double[] geo = xy_to_geo(xy[0],xy[1],this.resolution);
+            nodelist.add(geo);
+            //System.out.println("Adding node at "+xy[0]+","+xy[1]+" ("+geo[1]+","+geo[0]+")");
+
+            // Check if we got stuck in a loop
+            double start_proximity = Math.pow((geo[0] - startgeo[0]),2) + Math.pow((geo[1] - startgeo[1]),2);
+
+            if(detect_loop){
+                if(start_proximity < Math.pow(start_radius_small,2)){
+                    System.out.println("Detected loop");
+                    break;
+                }
+            }else{
+                if(start_proximity > Math.pow(start_radius_big,2)){
+                    detect_loop = true;
+                }
+            }
+        }
+
+        return nodelist;
+    }
+
+    /**
+     * Remove duplicate nodes from the list
+     *
+     * @param nodes
+     * @return
+     */
+    public ArrayList<double[]> duplicateNodeRemove(ArrayList<double[]> nodes){
+
+        if(nodes.size() <= 1){
+            return nodes;
+        }
+
+        double lastnode[] = new double[] {nodes.get(0)[0], nodes.get(0)[1]};
+
+        for(int i = 1; i < nodes.size(); i++){
+            double[] thisnode = new double[] {nodes.get(i)[0], nodes.get(i)[1]};
+
+            if(thisnode[0] == lastnode[0] && thisnode[1] == lastnode[1]){
+                // Remove the node
+                nodes.remove(i);
+
+                // Shift back one index
+                i = i - 1;
+            }
+            lastnode = thisnode;
+        }
+
+        return nodes;
+    }
+
+    /**
+     * Reduce the number of vertices based on their proximity to each other
+     *
+     * @param nodes
+     * @param proximity
+     * @return
+     */
+    public ArrayList<double[]> vertexReduce(ArrayList<double[]> nodes, double proximity){
+
+        // Check if node list is empty
+        if(nodes.size()<=1){
+            return nodes;
+        }
+
+        double[] test_v = nodes.get(0);
+        ArrayList<double[]> reducednodes = new ArrayList<double[]>();
+
+        double prox_sq = Math.pow(proximity, 2);
+
+        for(int v = 0; v < nodes.size(); v++){
+            if(Math.pow(nodes.get(v)[0] - test_v[0],2) + Math.pow(nodes.get(v)[1] - test_v[1],2) > prox_sq){
+                reducednodes.add(nodes.get(v));
+                test_v = nodes.get(v);
+            }
+        }
+
+        return reducednodes;
+    }
+
+    public double pointLineDistance(double[] p1, double[] p2, double[] p3){
+
+        double x0 = p1[0];
+        double y0 = p1[1];
+        double x1 = p2[0];
+        double y1 = p2[1];
+        double x2 = p3[0];
+        double y2 = p3[1];
+
+        if(x2 == x1 && y2 == y1){
+            return Math.sqrt(Math.pow(x1-x0,2) + Math.pow(y1-y0,2));
+        } else {
+            return Math.abs((x2-x1)*(y1-y0) - (x1-x0)*(y2-y1)) / Math.sqrt(Math.pow(x2-x1,2) + Math.pow(y2-y1,2));
+        }
+    }
+
+    public ArrayList<double[]> douglasPeuckerNR(ArrayList<double[]> nodes, double epsilon){
+        /*
+        command_stack = [(0, len(nodes) - 1)]
+
+        Vector result_stack = new Vector();
 
         while(command_stack.size() > 0){
-        	cmd = command_stack.pop();
-        	if(type(cmd) == tuple){
-        		(start, end) = cmd
-        		(node, dist) = dp_findpoint(nodes, start, end)
-        		if(dist > epsilon){
-        			command_stack.append("+")
-        			command_stack.append((start, node))
-        			command_stack.append((node, end))
-        		} else {
-        			result_stack.append((start, end))
-        		}
-        	} elseif(cmd == "+"){
-        		first = result_stack.pop()
-        		second = result_stack.pop()
-        		if(first[-1] == second[0]){
-        			result_stack.append(first + second[1:])
-        			//print "Added %s and %s; result is %s" % (first, second, result_stack[-1])
-        		}else {
-        			error("ERROR: Cannot connect nodestrings!")
-        			#print first
-        			#print second
-        			return;
-        		}
-        	} else {
-        		error("ERROR: Can't understand command \"%s\"" % (cmd,))
-        		return
- 
-		if(len(result_stack) == 1){
-			return [nodes[x] for x in result_stack[0]];
-		} else {
-			error("ERROR: Command stack is empty but result stack has %d nodes!" % len(result_stack));
-			return;
-		}
-        		
-		farthest_node = None
-		farthest_dist = 0
-		first = nodes[0]
-		last = nodes[-1]
-             
-		for(i in xrange(1, len(nodes) - 1){
-			d = point_line_distance(nodes[i], first, last)
-			if(d > farthest_dist){
-				farthest_dist = d
-				farthest_node = i
-     		}
-		}
-		if(farthest_dist > epsilon){
-			seg_a = douglas_peucker(nodes[0:farthest_node+1], epsilon)
-			seg_b = douglas_peucker(nodes[farthest_node:-1], epsilon)
-			//print "Minimized %d nodes to %d + %d nodes" % (len(nodes), len(seg_a), len(seg_b))
-			nodes = seg_a[:-1] + seg_b
-		} else {
-			return [nodes[0], nodes[-1]];
-		}
-		*/
-		return nodes;
-	}
-	
-	public ArrayList<double[]> douglasPeucker(ArrayList<double[]> nodes, double epsilon){
-		
-		// Check if node list is empty
-		if(nodes.size()<=1){
-			return nodes;
-		}
-		
-		int farthest_node = -1;
-		double farthest_dist = 0;
-		double[] first = nodes.get(0);
-		double[] last = nodes.get(nodes.size()-1);
-		
-		ArrayList<double[]> new_nodes = new ArrayList<double[]>();
-		
-		double d = 0;
-		
-		for(int i = 1; i < nodes.size(); i++){
-			d = pointLineDistance(nodes.get(i),first,last);
-			if(d>farthest_dist){
-				farthest_dist = d;
-				farthest_node = i;
-			}
-		}
-		
-		ArrayList<double[]> seg_a = new ArrayList<double[]>();
-		ArrayList<double[]> seg_b = new ArrayList<double[]>();
-		
-		if(farthest_dist > epsilon){
-			seg_a = douglasPeucker(sublist(nodes,0,farthest_node+1),epsilon);
-			seg_b = douglasPeucker(sublist(nodes,farthest_node,nodes.size()-1),epsilon);
-				
-			new_nodes.addAll(seg_a);
-			new_nodes.addAll(seg_b);
-		} else {
-			new_nodes.add(nodes.get(0));
-			new_nodes.add(nodes.get(nodes.size()-1));
-		}
-		return new_nodes;
-	}
-	
-	private ArrayList<double[]> sublist(ArrayList<double[]> l, int i, int f) throws ArrayIndexOutOfBoundsException {
-		ArrayList<double[]> sub = new ArrayList<double[]>();
-		
-		if(f<i || i < 0 || f < 0 || f > l.size()){
-			throw new ArrayIndexOutOfBoundsException();
-		}
-		
-		for(int j = i; j < f; j++){
-			sub.add(l.get(j));
-		}
-		return sub;
-	}
-	
-	public double[] xy_to_geo(int x, int y, double resolution){
-		double[] geo = new double[2];
-	    geo[0] = y / resolution;
-	    geo[1] = x / resolution;
-	    return geo;
-	}
-	
-	public int[] geo_to_xy(double lat, double lon, double resolution){
-		int[] xy = new int[2];
-		
-		xy[0] = (int)Math.floor(lon * resolution + 0.5);
-		xy[1] = (int)Math.floor(lat * resolution + 0.5);
-				
-		return xy;
-	}
-	
-	/*
+            cmd = command_stack.pop();
+            if(type(cmd) == tuple){
+                (start, end) = cmd
+                (node, dist) = dp_findpoint(nodes, start, end)
+                if(dist > epsilon){
+                    command_stack.append("+")
+                    command_stack.append((start, node))
+                    command_stack.append((node, end))
+                } else {
+                    result_stack.append((start, end))
+                }
+            } elseif(cmd == "+"){
+                first = result_stack.pop()
+                second = result_stack.pop()
+                if(first[-1] == second[0]){
+                    result_stack.append(first + second[1:])
+                    //print "Added %s and %s; result is %s" % (first, second, result_stack[-1])
+                }else {
+                    error("ERROR: Cannot connect nodestrings!")
+                    #print first
+                    #print second
+                    return;
+                }
+            } else {
+                error("ERROR: Can't understand command \"%s\"" % (cmd,))
+                return
+
+        if(len(result_stack) == 1){
+            return [nodes[x] for x in result_stack[0]];
+        } else {
+            error("ERROR: Command stack is empty but result stack has %d nodes!" % len(result_stack));
+            return;
+        }
+
+        farthest_node = None
+        farthest_dist = 0
+        first = nodes[0]
+        last = nodes[-1]
+
+        for(i in xrange(1, len(nodes) - 1){
+            d = point_line_distance(nodes[i], first, last)
+            if(d > farthest_dist){
+                farthest_dist = d
+                farthest_node = i
+            }
+        }
+        if(farthest_dist > epsilon){
+            seg_a = douglas_peucker(nodes[0:farthest_node+1], epsilon)
+            seg_b = douglas_peucker(nodes[farthest_node:-1], epsilon)
+            //print "Minimized %d nodes to %d + %d nodes" % (len(nodes), len(seg_a), len(seg_b))
+            nodes = seg_a[:-1] + seg_b
+        } else {
+            return [nodes[0], nodes[-1]];
+        }
+        */
+        return nodes;
+    }
+
+    public ArrayList<double[]> douglasPeucker(ArrayList<double[]> nodes, double epsilon){
+
+        // Check if node list is empty
+        if(nodes.size()<=1){
+            return nodes;
+        }
+
+        int farthest_node = -1;
+        double farthest_dist = 0;
+        double[] first = nodes.get(0);
+        double[] last = nodes.get(nodes.size()-1);
+
+        ArrayList<double[]> new_nodes = new ArrayList<double[]>();
+
+        double d = 0;
+
+        for(int i = 1; i < nodes.size(); i++){
+            d = pointLineDistance(nodes.get(i),first,last);
+            if(d>farthest_dist){
+                farthest_dist = d;
+                farthest_node = i;
+            }
+        }
+
+        ArrayList<double[]> seg_a = new ArrayList<double[]>();
+        ArrayList<double[]> seg_b = new ArrayList<double[]>();
+
+        if(farthest_dist > epsilon){
+            seg_a = douglasPeucker(sublist(nodes,0,farthest_node+1),epsilon);
+            seg_b = douglasPeucker(sublist(nodes,farthest_node,nodes.size()-1),epsilon);
+
+            new_nodes.addAll(seg_a);
+            new_nodes.addAll(seg_b);
+        } else {
+            new_nodes.add(nodes.get(0));
+            new_nodes.add(nodes.get(nodes.size()-1));
+        }
+        return new_nodes;
+    }
+
+    private ArrayList<double[]> sublist(ArrayList<double[]> l, int i, int f) throws ArrayIndexOutOfBoundsException {
+        ArrayList<double[]> sub = new ArrayList<double[]>();
+
+        if(f<i || i < 0 || f < 0 || f > l.size()){
+            throw new ArrayIndexOutOfBoundsException();
+        }
+
+        for(int j = i; j < f; j++){
+            sub.add(l.get(j));
+        }
+        return sub;
+    }
+
+    public double[] xy_to_geo(int x, int y, double resolution){
+        double[] geo = new double[2];
+        geo[0] = y / resolution;
+        geo[1] = x / resolution;
+        return geo;
+    }
+
+    public int[] geo_to_xy(double lat, double lon, double resolution){
+        int[] xy = new int[2];
+
+        xy[0] = (int)Math.floor(lon * resolution + 0.5);
+        xy[1] = (int)Math.floor(lat * resolution + 0.5);
+
+        return xy;
+    }
+
+    /*
      * User has hit the cancel button
-	 */
-	public void cancel() {
-	  cancel = true;
-	}
-		
-	protected void setStatus(String s) {
-	  Main.pleaseWaitDlg.currentAction.setText(s);
-	  Main.pleaseWaitDlg.repaint();
-	}
-	
-	/**
-	 * Class to do checking of whether the point is within our bbox
-	 * 
-	 * @author Jason Reid
-	 */
-	private class LakewalkerBBox {
-		
-		private double top = 90;
-		private double left = -180;
-		private double bottom = -90;
-		private double right = 180;
-		
-		protected LakewalkerBBox(double top, double left, double bottom, double right){
-		  this.left = left;
-		  this.right = right;
-		  this.top = top;
-		  this.bottom = bottom;
-		}
-		
-		protected Boolean contains(double lat, double lon){
-		  if(lat >= this.top || lat <= this.bottom){
-		    return false;
-		  }
-		  if(lon >= this.right || lon <= this.left){
-			  return false;
-		  }
-		  if((this.right - this.left) % 360 == 0){
-		    return true;
-		  }
-		  return (lon - this.left) % 360 <= (this.right - this.left) % 360;
-		}
-	}
-	private void printarr(int[] a){
-		for(int i = 0; i<a.length; i++){
-			System.out.println(i+": "+a[i]);
-		}
-	}
+     */
+    public void cancel() {
+      cancel = true;
+    }
+
+    protected void setStatus(String s) {
+      Main.pleaseWaitDlg.currentAction.setText(s);
+      Main.pleaseWaitDlg.repaint();
+    }
+
+    /**
+     * Class to do checking of whether the point is within our bbox
+     *
+     * @author Jason Reid
+     */
+    private class LakewalkerBBox {
+
+        private double top = 90;
+        private double left = -180;
+        private double bottom = -90;
+        private double right = 180;
+
+        protected LakewalkerBBox(double top, double left, double bottom, double right){
+          this.left = left;
+          this.right = right;
+          this.top = top;
+          this.bottom = bottom;
+        }
+
+        protected Boolean contains(double lat, double lon){
+          if(lat >= this.top || lat <= this.bottom){
+            return false;
+          }
+          if(lon >= this.right || lon <= this.left){
+              return false;
+          }
+          if((this.right - this.left) % 360 == 0){
+            return true;
+          }
+          return (lon - this.left) % 360 <= (this.right - this.left) % 360;
+        }
+    }
+    private void printarr(int[] a){
+        for(int i = 0; i<a.length; i++){
+            System.out.println(i+": "+a[i]);
+        }
+    }
 }
 
Index: applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerAction.java
===================================================================
--- applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerAction.java	(revision 12588)
+++ applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerAction.java	(revision 12778)
@@ -35,5 +35,5 @@
 /**
  * Interface to Darryl Shpak's Lakewalker module
- * 
+ *
  * @author Brent Easton
  */
@@ -45,5 +45,5 @@
   protected Thread executeThread;
   protected boolean cancel;
-  
+
   protected Collection<Command> commands = new LinkedList<Command>();
   protected Collection<Way> ways = new ArrayList<Way>();
@@ -56,5 +56,5 @@
     setEnabled(true);
   }
-  
+
   public void actionPerformed(ActionEvent e) {
     if(Main.map == null || Main.map.mapView == null)
@@ -78,84 +78,84 @@
    */
   private void cleanupCache() {
-	  final long maxCacheAge = System.currentTimeMillis()-Main.pref.getInteger(LakewalkerPreferences.PREF_MAXCACHEAGE, 100)*24*60*60*1000L;
-	  final long maxCacheSize = Main.pref.getInteger(LakewalkerPreferences.PREF_MAXCACHESIZE, 300)*1024*1024;
-
-	  for (String wmsFolder : LakewalkerPreferences.WMSLAYERS) {
-		  String wmsCacheDirName = Main.pref.getPreferencesDir()+"plugins/Lakewalker/"+wmsFolder;
-		  File wmsCacheDir = new File(wmsCacheDirName);
-
-		  if (wmsCacheDir.exists() && wmsCacheDir.isDirectory()) {
-			  File wmsCache[] = wmsCacheDir.listFiles();
-
-			  // sort files by date (most recent first)
-			  Arrays.sort(wmsCache, new Comparator<File>() {
-				  public int compare(File f1, File f2) {
-					  return (int)(f2.lastModified()-f1.lastModified());
-				  }
-			  });
-			  
-			  // delete aged or oversized, keep newest. Once size/age limit was reached delete all older files
-			  long folderSize = 0;
-			  boolean quickdelete = false;
-			  for (File cacheEntry : wmsCache) {
-				  if (!cacheEntry.isFile()) continue;
-				  if (!quickdelete) {
-					  folderSize += cacheEntry.length();
-					  if (folderSize > maxCacheSize) {
-						  quickdelete = true;
-					  } else if (cacheEntry.lastModified() < maxCacheAge) {
-						  quickdelete = true;
-					  }
-				  }
-					  
-				  if (quickdelete) {
-					  cacheEntry.delete();
-				  }
-			  }
-			  
-		  } else {
-			  // create cache directory
-			  if (!wmsCacheDir.mkdirs()) {
-				  JOptionPane.showMessageDialog(Main.parent, tr("Error creating cache directory: {0}", wmsCacheDirName));
-			  }
-		  }
-	  }
-  }
-  
+      final long maxCacheAge = System.currentTimeMillis()-Main.pref.getInteger(LakewalkerPreferences.PREF_MAXCACHEAGE, 100)*24*60*60*1000L;
+      final long maxCacheSize = Main.pref.getInteger(LakewalkerPreferences.PREF_MAXCACHESIZE, 300)*1024*1024;
+
+      for (String wmsFolder : LakewalkerPreferences.WMSLAYERS) {
+          String wmsCacheDirName = Main.pref.getPreferencesDir()+"plugins/Lakewalker/"+wmsFolder;
+          File wmsCacheDir = new File(wmsCacheDirName);
+
+          if (wmsCacheDir.exists() && wmsCacheDir.isDirectory()) {
+              File wmsCache[] = wmsCacheDir.listFiles();
+
+              // sort files by date (most recent first)
+              Arrays.sort(wmsCache, new Comparator<File>() {
+                  public int compare(File f1, File f2) {
+                      return (int)(f2.lastModified()-f1.lastModified());
+                  }
+              });
+
+              // delete aged or oversized, keep newest. Once size/age limit was reached delete all older files
+              long folderSize = 0;
+              boolean quickdelete = false;
+              for (File cacheEntry : wmsCache) {
+                  if (!cacheEntry.isFile()) continue;
+                  if (!quickdelete) {
+                      folderSize += cacheEntry.length();
+                      if (folderSize > maxCacheSize) {
+                          quickdelete = true;
+                      } else if (cacheEntry.lastModified() < maxCacheAge) {
+                          quickdelete = true;
+                      }
+                  }
+
+                  if (quickdelete) {
+                      cacheEntry.delete();
+                  }
+              }
+
+          } else {
+              // create cache directory
+              if (!wmsCacheDir.mkdirs()) {
+                  JOptionPane.showMessageDialog(Main.parent, tr("Error creating cache directory: {0}", wmsCacheDirName));
+              }
+          }
+      }
+  }
+
   protected void lakewalk(Point clickPoint){
-	/**
-	 * Positional data
-	 */
-	final LatLon pos = Main.map.mapView.getLatLon(clickPoint.x, clickPoint.y);
-	final LatLon topLeft = Main.map.mapView.getLatLon(0, 0);
-	final LatLon botRight = Main.map.mapView.getLatLon(Main.map.mapView.getWidth(), Main.map.mapView
-	     .getHeight());	    
-
-	/**
-	 * Cache/working directory location
-	 */
-	final File working_dir = new File(Main.pref.getPreferencesDir(), "plugins/Lakewalker");
-	
-	/*
-	 * Collect options
-	 */
-	final int waylen = Main.pref.getInteger(LakewalkerPreferences.PREF_MAX_SEG, 500);
-	final int maxnode = Main.pref.getInteger(LakewalkerPreferences.PREF_MAX_NODES, 50000);
-	final int threshold = Main.pref.getInteger(LakewalkerPreferences.PREF_THRESHOLD_VALUE, 90);
-	final double epsilon = Main.pref.getDouble(LakewalkerPreferences.PREF_EPSILON, 0.0003);
-	final int resolution = Main.pref.getInteger(LakewalkerPreferences.PREF_LANDSAT_RES, 4000);
-	final int tilesize = Main.pref.getInteger(LakewalkerPreferences.PREF_LANDSAT_SIZE, 2000);
-	final String startdir = Main.pref.get(LakewalkerPreferences.PREF_START_DIR, "east");
-	final String wmslayer = Main.pref.get(LakewalkerPreferences.PREF_WMS, "IR1");
-
-	try {
+    /**
+     * Positional data
+     */
+    final LatLon pos = Main.map.mapView.getLatLon(clickPoint.x, clickPoint.y);
+    final LatLon topLeft = Main.map.mapView.getLatLon(0, 0);
+    final LatLon botRight = Main.map.mapView.getLatLon(Main.map.mapView.getWidth(), Main.map.mapView
+         .getHeight());
+
+    /**
+     * Cache/working directory location
+     */
+    final File working_dir = new File(Main.pref.getPreferencesDir(), "plugins/Lakewalker");
+
+    /*
+     * Collect options
+     */
+    final int waylen = Main.pref.getInteger(LakewalkerPreferences.PREF_MAX_SEG, 500);
+    final int maxnode = Main.pref.getInteger(LakewalkerPreferences.PREF_MAX_NODES, 50000);
+    final int threshold = Main.pref.getInteger(LakewalkerPreferences.PREF_THRESHOLD_VALUE, 90);
+    final double epsilon = Main.pref.getDouble(LakewalkerPreferences.PREF_EPSILON, 0.0003);
+    final int resolution = Main.pref.getInteger(LakewalkerPreferences.PREF_LANDSAT_RES, 4000);
+    final int tilesize = Main.pref.getInteger(LakewalkerPreferences.PREF_LANDSAT_SIZE, 2000);
+    final String startdir = Main.pref.get(LakewalkerPreferences.PREF_START_DIR, "east");
+    final String wmslayer = Main.pref.get(LakewalkerPreferences.PREF_WMS, "IR1");
+
+    try {
         PleaseWaitRunnable lakewalkerTask = new PleaseWaitRunnable(tr("Tracing")){
           @Override protected void realRun() throws SAXException {
-        	  setStatus(tr("checking cache..."));
-        	  cleanupCache();
-        	  processnodelist(pos, topLeft, botRight, waylen,maxnode,threshold,epsilon,resolution,tilesize,startdir,wmslayer,working_dir);
+              setStatus(tr("checking cache..."));
+              cleanupCache();
+              processnodelist(pos, topLeft, botRight, waylen,maxnode,threshold,epsilon,resolution,tilesize,startdir,wmslayer,working_dir);
           }
           @Override protected void finish() {
-            
+
           }
           @Override protected void cancel() {
@@ -168,133 +168,133 @@
       catch (Exception ex) {
         System.out.println("Exception caught: " + ex.getMessage());
-      }      
-  }
-  
+      }
+  }
+
   private void processnodelist(LatLon pos, LatLon topLeft, LatLon botRight, int waylen, int maxnode, int threshold, double epsilon, int resolution, int tilesize, String startdir, String wmslayer, File workingdir){
-	  
-	ArrayList<double[]> nodelist = new ArrayList<double[]>();
-	  
-	Lakewalker lw = new Lakewalker(waylen,maxnode,threshold,epsilon,resolution,tilesize,startdir,wmslayer,workingdir);
-	try {
-		nodelist = lw.trace(pos.lat(),pos.lon(),topLeft.lon(),botRight.lon(),topLeft.lat(),botRight.lat());
-	} catch(LakewalkerException e){
-		System.out.println(e.getError());
-	}
-	
-	System.out.println(nodelist.size()+" nodes generated");
-	
-	/**
-	 * Run the nodelist through a vertex reduction algorithm
-	 */
-	
-	setStatus(tr("Running vertex reduction..."));
-	
-	nodelist = lw.vertexReduce(nodelist, epsilon);
-	
-	//System.out.println("After vertex reduction "+nodelist.size()+" nodes remain.");
-	
-	/**
-	 * And then through douglas-peucker approximation
-	 */
-	
-	setStatus(tr("Running Douglas-Peucker approximation..."));
-	
-	nodelist = lw.douglasPeucker(nodelist, epsilon);
-	
-	//System.out.println("After Douglas-Peucker approximation "+nodelist.size()+" nodes remain.");
-	  
-	/**
-	 * And then through a duplicate node remover
-	 */
-	
-	setStatus(tr("Removing duplicate nodes..."));
-	
-	nodelist = lw.duplicateNodeRemove(nodelist);
-	
-	//System.out.println("After removing duplicate nodes, "+nodelist.size()+" nodes remain.");
-	  
-	
-	// if for some reason (image loading failed, ...) nodelist is empty, no more processing required.
-	if (nodelist.size() == 0) {
-		return;
-	}
-	
-	/**
-	 * Turn the arraylist into osm nodes
-	 */
-	
-	Way way = new Way();
-	Node n = null;
-	Node fn = null;
-	
-	double eastOffset = Main.pref.getDouble(LakewalkerPreferences.PREF_EAST_OFFSET, 0.0);
-	double northOffset = Main.pref.getDouble(LakewalkerPreferences.PREF_NORTH_OFFSET, 0.0);
-	
-	int nodesinway = 0;
-	
-	for(int i = 0; i< nodelist.size(); i++){
-		if (cancel) {
-			return;
-	    }
-		 	
-		try {        	
-		  LatLon ll = new LatLon(nodelist.get(i)[0]+northOffset, nodelist.get(i)[1]+eastOffset);
-		  n = new Node(ll);
-		  if(fn==null){
-		    fn = n;
-		  }
-		  commands.add(new AddCommand(n));
-		  
-		} catch (Exception ex) {		 
-		}	    
-	      
-		way.nodes.add(n);
-		
-		if(nodesinway > Main.pref.getInteger(LakewalkerPreferences.PREF_MAX_SEG, 500)){
-			String waytype = Main.pref.get(LakewalkerPreferences.PREF_WAYTYPE, "water");
-	        
-	        if(!waytype.equals("none")){
-	      	  way.put("natural",waytype);
-	        }
-	        
-	        way.put("created_by", "Dshpak_landsat_lakes");
-	        commands.add(new AddCommand(way));
-	        
-	        way = new Way();
-
-	        way.nodes.add(n);
-	        
-	        nodesinway = 0;
-		}
-		nodesinway++;
-	}
-	
-	
-	String waytype = Main.pref.get(LakewalkerPreferences.PREF_WAYTYPE, "water");
-    
+
+    ArrayList<double[]> nodelist = new ArrayList<double[]>();
+
+    Lakewalker lw = new Lakewalker(waylen,maxnode,threshold,epsilon,resolution,tilesize,startdir,wmslayer,workingdir);
+    try {
+        nodelist = lw.trace(pos.lat(),pos.lon(),topLeft.lon(),botRight.lon(),topLeft.lat(),botRight.lat());
+    } catch(LakewalkerException e){
+        System.out.println(e.getError());
+    }
+
+    System.out.println(nodelist.size()+" nodes generated");
+
+    /**
+     * Run the nodelist through a vertex reduction algorithm
+     */
+
+    setStatus(tr("Running vertex reduction..."));
+
+    nodelist = lw.vertexReduce(nodelist, epsilon);
+
+    //System.out.println("After vertex reduction "+nodelist.size()+" nodes remain.");
+
+    /**
+     * And then through douglas-peucker approximation
+     */
+
+    setStatus(tr("Running Douglas-Peucker approximation..."));
+
+    nodelist = lw.douglasPeucker(nodelist, epsilon);
+
+    //System.out.println("After Douglas-Peucker approximation "+nodelist.size()+" nodes remain.");
+
+    /**
+     * And then through a duplicate node remover
+     */
+
+    setStatus(tr("Removing duplicate nodes..."));
+
+    nodelist = lw.duplicateNodeRemove(nodelist);
+
+    //System.out.println("After removing duplicate nodes, "+nodelist.size()+" nodes remain.");
+
+
+    // if for some reason (image loading failed, ...) nodelist is empty, no more processing required.
+    if (nodelist.size() == 0) {
+        return;
+    }
+
+    /**
+     * Turn the arraylist into osm nodes
+     */
+
+    Way way = new Way();
+    Node n = null;
+    Node fn = null;
+
+    double eastOffset = Main.pref.getDouble(LakewalkerPreferences.PREF_EAST_OFFSET, 0.0);
+    double northOffset = Main.pref.getDouble(LakewalkerPreferences.PREF_NORTH_OFFSET, 0.0);
+
+    int nodesinway = 0;
+
+    for(int i = 0; i< nodelist.size(); i++){
+        if (cancel) {
+            return;
+        }
+
+        try {
+          LatLon ll = new LatLon(nodelist.get(i)[0]+northOffset, nodelist.get(i)[1]+eastOffset);
+          n = new Node(ll);
+          if(fn==null){
+            fn = n;
+          }
+          commands.add(new AddCommand(n));
+
+        } catch (Exception ex) {
+        }
+
+        way.nodes.add(n);
+
+        if(nodesinway > Main.pref.getInteger(LakewalkerPreferences.PREF_MAX_SEG, 500)){
+            String waytype = Main.pref.get(LakewalkerPreferences.PREF_WAYTYPE, "water");
+
+            if(!waytype.equals("none")){
+              way.put("natural",waytype);
+            }
+
+            way.put("created_by", "Dshpak_landsat_lakes");
+            commands.add(new AddCommand(way));
+
+            way = new Way();
+
+            way.nodes.add(n);
+
+            nodesinway = 0;
+        }
+        nodesinway++;
+    }
+
+
+    String waytype = Main.pref.get(LakewalkerPreferences.PREF_WAYTYPE, "water");
+
     if(!waytype.equals("none")){
-  	  way.put("natural",waytype);
-    }
-    
+      way.put("natural",waytype);
+    }
+
     way.put("created_by", "Dshpak_landsat_lakes");
-    
-	way.nodes.add(fn);
-	
-	commands.add(new AddCommand(way));
-	
-	if (!commands.isEmpty()) {
+
+    way.nodes.add(fn);
+
+    commands.add(new AddCommand(way));
+
+    if (!commands.isEmpty()) {
         Main.main.undoRedo.add(new SequenceCommand(tr("Lakewalker trace"), commands));
         Main.ds.setSelected(ways);
     } else {
-  	  System.out.println("Failed");
-    }
-	
-	commands = new LinkedList<Command>();
-	ways = new ArrayList<Way>();
-	
-  }
-  
+      System.out.println("Failed");
+    }
+
+    commands = new LinkedList<Command>();
+    ways = new ArrayList<Way>();
+
+  }
+
   public void cancel() {
-	  cancel = true;
+      cancel = true;
   }
 
@@ -317,6 +317,6 @@
   }
   protected void setStatus(String s) {
-	  Main.pleaseWaitDlg.currentAction.setText(s);
-	  Main.pleaseWaitDlg.repaint();
+      Main.pleaseWaitDlg.currentAction.setText(s);
+      Main.pleaseWaitDlg.repaint();
   }
 }
Index: applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerApp.java
===================================================================
--- applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerApp.java	(revision 12588)
+++ applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerApp.java	(revision 12778)
@@ -5,53 +5,53 @@
 
 public class LakewalkerApp {
-	public static void main(String[] args){
-		double lat = 52.31384;
-		double lon = -79.135;
-		double toplat = 52.3165;
-		double botlat = 52.3041;
-		double leftlon = -79.1442;
-		double rightlon = -79.1093;
-		
-		// ?lat=39.15579999999999&lon=2.9411&zoom=12&layers=B000F000F
-		lat = 39.1422;
-		lon = 2.9102;
-		
-		toplat = 39.2229;
-		botlat = 39.0977;
-		leftlon = 2.8560;
-		rightlon = 3.0462;
-		
-		int waylen = 250;
-		int maxnode = 5000;
-		int threshold = 100;
-		double dp = 0.0003;
-		int tilesize = 2000;
-		int resolution = 4000;
-		String startdir = "East";
-		String wmslayer = "IR2";
-		
-		File working_dir = new File("Lakewalker");
-		
-		ArrayList<double[]> nodelist = null;
-		
-		Lakewalker lw = new Lakewalker(waylen,maxnode,threshold,dp,resolution,tilesize,startdir,wmslayer,working_dir);
-	    try {
-	    	nodelist = lw.trace(lat,lon,leftlon,rightlon,toplat,botlat);
-	    } catch(LakewalkerException e){
-	    	System.out.println(e.getError());
-	    }
-	    
-	    System.out.println(nodelist.size()+" nodes generated");
-	    
-	    nodelist = lw.vertexReduce(nodelist, dp);
-	    
-	    System.out.println("After vertex reduction, "+nodelist.size()+" nodes remain.");
-	    
-	    nodelist = lw.douglasPeucker(nodelist, dp);
-	    
-	    System.out.println("After dp approximation, "+nodelist.size()+" nodes remain.");
-	 
-	    
-	    
-	}
+    public static void main(String[] args){
+        double lat = 52.31384;
+        double lon = -79.135;
+        double toplat = 52.3165;
+        double botlat = 52.3041;
+        double leftlon = -79.1442;
+        double rightlon = -79.1093;
+
+        // ?lat=39.15579999999999&lon=2.9411&zoom=12&layers=B000F000F
+        lat = 39.1422;
+        lon = 2.9102;
+
+        toplat = 39.2229;
+        botlat = 39.0977;
+        leftlon = 2.8560;
+        rightlon = 3.0462;
+
+        int waylen = 250;
+        int maxnode = 5000;
+        int threshold = 100;
+        double dp = 0.0003;
+        int tilesize = 2000;
+        int resolution = 4000;
+        String startdir = "East";
+        String wmslayer = "IR2";
+
+        File working_dir = new File("Lakewalker");
+
+        ArrayList<double[]> nodelist = null;
+
+        Lakewalker lw = new Lakewalker(waylen,maxnode,threshold,dp,resolution,tilesize,startdir,wmslayer,working_dir);
+        try {
+            nodelist = lw.trace(lat,lon,leftlon,rightlon,toplat,botlat);
+        } catch(LakewalkerException e){
+            System.out.println(e.getError());
+        }
+
+        System.out.println(nodelist.size()+" nodes generated");
+
+        nodelist = lw.vertexReduce(nodelist, dp);
+
+        System.out.println("After vertex reduction, "+nodelist.size()+" nodes remain.");
+
+        nodelist = lw.douglasPeucker(nodelist, dp);
+
+        System.out.println("After dp approximation, "+nodelist.size()+" nodes remain.");
+
+
+
+    }
 }
Index: applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerException.java
===================================================================
--- applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerException.java	(revision 12588)
+++ applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerException.java	(revision 12778)
@@ -2,18 +2,18 @@
 
 class LakewalkerException extends Exception {
-	String error;
-	
-	public LakewalkerException(){
-		super();
-		this.error = "An unknown error has occured";
-	}
-	
-	public LakewalkerException(String err){
-		super();
-		this.error = err;
-	}
-	
-	public String getError(){
-	  return this.error;
-	}
+    String error;
+
+    public LakewalkerException(){
+        super();
+        this.error = "An unknown error has occured";
+    }
+
+    public LakewalkerException(String err){
+        super();
+        this.error = err;
+    }
+
+    public String getError(){
+      return this.error;
+    }
 }
Index: applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerPlugin.java
===================================================================
--- applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerPlugin.java	(revision 12588)
+++ applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerPlugin.java	(revision 12778)
@@ -10,5 +10,5 @@
 /**
  * Interface to Darryl Shpak's Lakewalker python module
- * 
+ *
  * @author Brent Easton
  */
@@ -18,5 +18,5 @@
   }
 
-  public PreferenceSetting getPreferenceSetting() 
+  public PreferenceSetting getPreferenceSetting()
   {
     return new LakewalkerPreferences();
Index: applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerReader.java
===================================================================
--- applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerReader.java	(revision 12588)
+++ applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerReader.java	(revision 12778)
@@ -51,9 +51,9 @@
     
     try {
-    	
-	  Node n = null;  // The current node being created
-	  Node tn = null; // The last node of the previous way
+        
+      Node n = null;  // The current node being created
+      Node tn = null; // The last node of the previous way
       Node fn = null; // Node to hold the first node in the trace
-    	
+        
       while ((line = input.readLine()) != null) {
         if (cancel) {
@@ -67,24 +67,24 @@
           
           if(tn==null){
-		      try {        	
-		        LatLon ll = new LatLon(Double.parseDouble(tokens[1])+northOffset, Double.parseDouble(tokens[2])+eastOffset);
-		        n = new Node(ll);
-		        if(fn==null){
-		          fn = n;
-		        }
-		        commands.add(new AddCommand(n));
-		      }
-	          catch (Exception ex) {
-	        	  
-		      }
+              try {         
+                LatLon ll = new LatLon(Double.parseDouble(tokens[1])+northOffset, Double.parseDouble(tokens[2])+eastOffset);
+                n = new Node(ll);
+                if(fn==null){
+                  fn = n;
+                }
+                commands.add(new AddCommand(n));
+              }
+              catch (Exception ex) {
+                  
+              }
           
           } else {
             // If there is a last node, and this node has the same coordinates
             // then we substitute for the previous node
-      		n = tn;
-        	tn = null;       	
+            n = tn;
+            tn = null;          
           }
-	      
-	      way.nodes.add(n);
+          
+          way.nodes.add(n);
           
           break;
@@ -98,5 +98,5 @@
           
           if(!waytype.equals("none")){
-        	  way.put("natural",waytype);
+              way.put("natural",waytype);
           }
           
@@ -106,8 +106,8 @@
           break;
         
-        case 't':      	
-        	way = new Way();
-        	tn = n;
-        	break;
+        case 't':       
+            way = new Way();
+            tn = n;
+            break;
           
         case 'e':
Index: applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerWMS.java
===================================================================
--- applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerWMS.java	(revision 12588)
+++ applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerWMS.java	(revision 12778)
@@ -17,228 +17,228 @@
 
 public class LakewalkerWMS {
-	
-	private BufferedImage image;
-	private int imagex;
-	private int imagey;
-	
-	// Vector to cache images in memory
-	private Vector<BufferedImage> images = new Vector<BufferedImage>();
-	// Hashmap to hold the mapping of cached images 
-	private HashMap<String,Integer> imageindex = new HashMap<String,Integer>();
-	
-	private int resolution;
-	private int tilesize;
-	
-	private String wmslayer;
-	
-	private File working_dir;
-	
-	public LakewalkerWMS(int resolution, int tilesize, String wmslayer, File workdir){
-		this.resolution = resolution;
-		this.tilesize = tilesize;
-		this.working_dir = workdir;
-		this.wmslayer = wmslayer;
-	}
-	
-	public BufferedImage getTile(int x, int y) throws LakewalkerException {
-		String status = getStatus();
-		setStatus(tr("Downloading image tile..."));
-		
-		String layer = "global_mosaic_base";
-		
-		int[] bottom_left_xy = new int[2]; 
-		bottom_left_xy[0] = floor(x,this.tilesize);
-		bottom_left_xy[1] = floor(y,this.tilesize);
-		
-        int[] top_right_xy = new int[2]; 
+
+    private BufferedImage image;
+    private int imagex;
+    private int imagey;
+
+    // Vector to cache images in memory
+    private Vector<BufferedImage> images = new Vector<BufferedImage>();
+    // Hashmap to hold the mapping of cached images
+    private HashMap<String,Integer> imageindex = new HashMap<String,Integer>();
+
+    private int resolution;
+    private int tilesize;
+
+    private String wmslayer;
+
+    private File working_dir;
+
+    public LakewalkerWMS(int resolution, int tilesize, String wmslayer, File workdir){
+        this.resolution = resolution;
+        this.tilesize = tilesize;
+        this.working_dir = workdir;
+        this.wmslayer = wmslayer;
+    }
+
+    public BufferedImage getTile(int x, int y) throws LakewalkerException {
+        String status = getStatus();
+        setStatus(tr("Downloading image tile..."));
+
+        String layer = "global_mosaic_base";
+
+        int[] bottom_left_xy = new int[2];
+        bottom_left_xy[0] = floor(x,this.tilesize);
+        bottom_left_xy[1] = floor(y,this.tilesize);
+
+        int[] top_right_xy = new int[2];
         top_right_xy[0] = (int)bottom_left_xy[0] + this.tilesize;
         top_right_xy[1] = (int)bottom_left_xy[1] + this.tilesize;
-        
+
         double[] topright_geo = xy_to_geo(top_right_xy[0],top_right_xy[1],this.resolution);
         double[] bottomleft_geo = xy_to_geo(bottom_left_xy[0],bottom_left_xy[1],this.resolution);
-                  
-		String filename = this.wmslayer+"/landsat_"+this.resolution+"_"+this.tilesize+
-			"_xy_"+bottom_left_xy[0]+"_"+bottom_left_xy[1]+".png";
-		
-		// The WMS server only understands decimal points using periods, so we need
-		// to convert to a locale that uses that to build the proper URL
+
+        String filename = this.wmslayer+"/landsat_"+this.resolution+"_"+this.tilesize+
+            "_xy_"+bottom_left_xy[0]+"_"+bottom_left_xy[1]+".png";
+
+        // The WMS server only understands decimal points using periods, so we need
+        // to convert to a locale that uses that to build the proper URL
         NumberFormat nf = NumberFormat.getInstance(Locale.ENGLISH);
-		DecimalFormat df = (DecimalFormat)nf;
-		df.applyLocalizedPattern("0.000000");
-		
-		String urlloc = "http://onearth.jpl.nasa.gov/wms.cgi?request=GetMap&layers="+layer+
-			"&styles="+wmslayer+"&srs=EPSG:4326&format=image/png"+
-			"&bbox="+df.format(bottomleft_geo[1])+","+df.format(bottomleft_geo[0])+
-			","+df.format(topright_geo[1])+","+df.format(topright_geo[0])+
-			"&width="+this.tilesize+"&height="+this.tilesize;
-				
+        DecimalFormat df = (DecimalFormat)nf;
+        df.applyLocalizedPattern("0.000000");
+
+        String urlloc = "http://onearth.jpl.nasa.gov/wms.cgi?request=GetMap&layers="+layer+
+            "&styles="+wmslayer+"&srs=EPSG:4326&format=image/png"+
+            "&bbox="+df.format(bottomleft_geo[1])+","+df.format(bottomleft_geo[0])+
+            ","+df.format(topright_geo[1])+","+df.format(topright_geo[0])+
+            "&width="+this.tilesize+"&height="+this.tilesize;
+
         File file = new File(this.working_dir,filename);
-        
+
         // Calculate the hashmap key
-    	String hashkey = Integer.toString(bottom_left_xy[0])+":"+Integer.toString(bottom_left_xy[1]);
-    	
+        String hashkey = Integer.toString(bottom_left_xy[0])+":"+Integer.toString(bottom_left_xy[1]);
+
         // See if this image is already loaded
-        if(this.image != null){  
-        	if(this.imagex != bottom_left_xy[0] || this.imagey != bottom_left_xy[1]){
-        		
-        		// Check if this image exists in the hashmap
-        		if(this.imageindex.containsKey(hashkey)){
-        			// Store which image we have
-        			this.imagex = bottom_left_xy[0];
-        			this.imagey = bottom_left_xy[1];
-        			
-        			// Retrieve from cache
-        			this.image = this.images.get(this.imageindex.get(hashkey));
-        			return this.image;
-        		} else {
-        			this.image = null;
-        		}
-        	} else {
-        		return this.image;
-        	}
-        }
-        
-	    try {	    	
-	    	System.out.println("Looking for image in disk cache: "+filename);
-	    	
-	        // Read from a file
-	        this.image = ImageIO.read(file);
-	    
-	        this.images.add(this.image);
-	        this.imageindex.put(hashkey,this.images.size()-1);
-	        
-	    } catch(FileNotFoundException e){
-	    	System.out.println("Could not find cached image, downloading.");
-	    } catch(IOException e){
-	    	System.out.println(e.getMessage());
-	    } catch(Exception e){
-	    	System.out.println(e.getMessage());
-	    }
-	    
-	    if(this.image == null){
-	    	/**
-	    	 * Try downloading the image
-	    	 */
-		    try {	        	
-	        	System.out.println("Downloading from "+urlloc);
-	        	
-	        	// Read from a URL
-	        	URL url = new URL(urlloc);
-	        	this.image = ImageIO.read(url); // this can return null!
-	        } catch(MalformedURLException e){
-	        	System.out.println(e.getMessage());
-	        } catch(IOException e){
-	        	System.out.println(e.getMessage());
-	        } catch(Exception e){
-	        	System.out.println(e.getMessage());
-		    }
-	        
-	        if (this.image != null) {
-		        this.images.add(this.image);
-		        this.imageindex.put(hashkey,this.images.size()-1);
-		        
-		        this.saveimage(file,this.image);
-	        }
-	    }
-	    
-	    this.imagex = bottom_left_xy[0];
-	    this.imagey = bottom_left_xy[1];
-	    
-	    if(this.image == null){
-	    	throw new LakewalkerException(tr("Could not acquire image"));
-	    }
-		
-	    setStatus(status);
-	    
-		return this.image;
-	}
-	
-	public void saveimage(File file, BufferedImage image){
+        if(this.image != null){
+            if(this.imagex != bottom_left_xy[0] || this.imagey != bottom_left_xy[1]){
+
+                // Check if this image exists in the hashmap
+                if(this.imageindex.containsKey(hashkey)){
+                    // Store which image we have
+                    this.imagex = bottom_left_xy[0];
+                    this.imagey = bottom_left_xy[1];
+
+                    // Retrieve from cache
+                    this.image = this.images.get(this.imageindex.get(hashkey));
+                    return this.image;
+                } else {
+                    this.image = null;
+                }
+            } else {
+                return this.image;
+            }
+        }
+
+        try {
+            System.out.println("Looking for image in disk cache: "+filename);
+
+            // Read from a file
+            this.image = ImageIO.read(file);
+
+            this.images.add(this.image);
+            this.imageindex.put(hashkey,this.images.size()-1);
+
+        } catch(FileNotFoundException e){
+            System.out.println("Could not find cached image, downloading.");
+        } catch(IOException e){
+            System.out.println(e.getMessage());
+        } catch(Exception e){
+            System.out.println(e.getMessage());
+        }
+
+        if(this.image == null){
+            /**
+             * Try downloading the image
+             */
+            try {
+                System.out.println("Downloading from "+urlloc);
+
+                // Read from a URL
+                URL url = new URL(urlloc);
+                this.image = ImageIO.read(url); // this can return null!
+            } catch(MalformedURLException e){
+                System.out.println(e.getMessage());
+            } catch(IOException e){
+                System.out.println(e.getMessage());
+            } catch(Exception e){
+                System.out.println(e.getMessage());
+            }
+
+            if (this.image != null) {
+                this.images.add(this.image);
+                this.imageindex.put(hashkey,this.images.size()-1);
+
+                this.saveimage(file,this.image);
+            }
+        }
+
+        this.imagex = bottom_left_xy[0];
+        this.imagey = bottom_left_xy[1];
+
+        if(this.image == null){
+            throw new LakewalkerException(tr("Could not acquire image"));
+        }
+
+        setStatus(status);
+
+        return this.image;
+    }
+
+    public void saveimage(File file, BufferedImage image){
         /**
          * Save the image to the cache
          */
         try {
-        	ImageIO.write(image, "png", file);
-        	System.out.println("Saved image to cache");
+            ImageIO.write(image, "png", file);
+            System.out.println("Saved image to cache");
         } catch(Exception e){
-        	System.out.println(e.getMessage());
-        }
-	}
-	
-	public int getPixel(int x, int y) throws LakewalkerException{
-
-		// Get the previously shown text
-		
-		
-		BufferedImage image = null;
-
-		try {
-			image = this.getTile(x,y);
-		} catch(LakewalkerException e){
-			System.out.println(e.getError());
-			throw new LakewalkerException(e.getMessage());			
-		}
-	
-		int tx = floor(x,this.tilesize);
-		int ty = floor(y,this.tilesize);
-				
-		int pixel_x = (x-tx);
-		int pixel_y = (this.tilesize-1)-(y-ty);
-					
-		//System.out.println("("+x+","+y+") maps to ("+pixel_x+","+pixel_y+") by ("+tx+", "+ty+")");
-		
-		int rgb = image.getRGB(pixel_x,pixel_y);
-		
-		int pixel;
-		
-		int r = (rgb >> 16) & 0xff;
+            System.out.println(e.getMessage());
+        }
+    }
+
+    public int getPixel(int x, int y) throws LakewalkerException{
+
+        // Get the previously shown text
+
+
+        BufferedImage image = null;
+
+        try {
+            image = this.getTile(x,y);
+        } catch(LakewalkerException e){
+            System.out.println(e.getError());
+            throw new LakewalkerException(e.getMessage());
+        }
+
+        int tx = floor(x,this.tilesize);
+        int ty = floor(y,this.tilesize);
+
+        int pixel_x = (x-tx);
+        int pixel_y = (this.tilesize-1)-(y-ty);
+
+        //System.out.println("("+x+","+y+") maps to ("+pixel_x+","+pixel_y+") by ("+tx+", "+ty+")");
+
+        int rgb = image.getRGB(pixel_x,pixel_y);
+
+        int pixel;
+
+        int r = (rgb >> 16) & 0xff;
         int g = (rgb >>  8) & 0xff;
         int b = (rgb >>  0) & 0xff;
 
         pixel = (int)((0.30 * r) + (0.59 * b) + (0.11 * g));
-                
-		return pixel; 
-	}
-	
-	public int floor(int num, int precision){
-		double dnum = num/(double)precision;
-		BigDecimal val = new BigDecimal(dnum) ;
-		val = val.setScale(0, BigDecimal.ROUND_FLOOR);
-		return val.intValue()*precision;
-	}
-	
-	public double floor(double num) {
-		BigDecimal val = new BigDecimal(num) ;
-		val = val.setScale(0, BigDecimal.ROUND_FLOOR);
-		return val.doubleValue() ;
-	}
-	
-	public double[] xy_to_geo(int x, int y, double resolution){
-		double[] geo = new double[2];
-	    geo[0] = y / resolution;
-	    geo[1] = x / resolution;
-	    return geo;
-	}
-	
-	public int[] geo_to_xy(double lat, double lon, double resolution){
-		int[] xy = new int[2];
-		
-		xy[0] = (int)Math.floor(lon * resolution + 0.5);
-		xy[1] = (int)Math.floor(lat * resolution + 0.5);
-				
-		return xy;
-	}
-	
-	private void printarr(int[] a){
-		for(int i = 0; i<a.length; i++){
-			System.out.println(i+": "+a[i]);
-		}
-	}
-	protected void setStatus(String s) {
-		Main.pleaseWaitDlg.currentAction.setText(s);
-		Main.pleaseWaitDlg.repaint();
-	}
-	protected String getStatus(){
-		return Main.pleaseWaitDlg.currentAction.getText();
-	}
+
+        return pixel;
+    }
+
+    public int floor(int num, int precision){
+        double dnum = num/(double)precision;
+        BigDecimal val = new BigDecimal(dnum) ;
+        val = val.setScale(0, BigDecimal.ROUND_FLOOR);
+        return val.intValue()*precision;
+    }
+
+    public double floor(double num) {
+        BigDecimal val = new BigDecimal(num) ;
+        val = val.setScale(0, BigDecimal.ROUND_FLOOR);
+        return val.doubleValue() ;
+    }
+
+    public double[] xy_to_geo(int x, int y, double resolution){
+        double[] geo = new double[2];
+        geo[0] = y / resolution;
+        geo[1] = x / resolution;
+        return geo;
+    }
+
+    public int[] geo_to_xy(double lat, double lon, double resolution){
+        int[] xy = new int[2];
+
+        xy[0] = (int)Math.floor(lon * resolution + 0.5);
+        xy[1] = (int)Math.floor(lat * resolution + 0.5);
+
+        return xy;
+    }
+
+    private void printarr(int[] a){
+        for(int i = 0; i<a.length; i++){
+            System.out.println(i+": "+a[i]);
+        }
+    }
+    protected void setStatus(String s) {
+        Main.pleaseWaitDlg.currentAction.setText(s);
+        Main.pleaseWaitDlg.repaint();
+    }
+    protected String getStatus(){
+        return Main.pleaseWaitDlg.currentAction.getText();
+    }
 }
Index: applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/StringEnumConfigurer.java
===================================================================
--- applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/StringEnumConfigurer.java	(revision 12588)
+++ applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/StringEnumConfigurer.java	(revision 12778)
@@ -96,9 +96,9 @@
 
   public void setValidValues(String[] s) {
-  	validValues = s;
-  	if (box == null) {
-  	  getControls();
-  	}
-	box.setModel(new DefaultComboBoxModel(validValues));
+    validValues = s;
+    if (box == null) {
+      getControls();
+    }
+    box.setModel(new DefaultComboBoxModel(validValues));
   }
   
