Index: /applications/editors/josm/plugins/lakewalker/README
===================================================================
--- /applications/editors/josm/plugins/lakewalker/README	(revision 6909)
+++ /applications/editors/josm/plugins/lakewalker/README	(revision 6910)
@@ -1,9 +1,23 @@
-A JOSM plugin to interface to Darryl Shpak's Lakewalker module
+README FOR Lakewalker
+=======================
 
+The Lakewalker plugin can be used to generate traces of lakes, rivers or shoreline from
+LANDSAT imagery (or theoretically any imagery that is provided on a WMS server).
+
+Currently the plugin features 2 modes of operation: Native and Classic. The classic mode 
+requires the Python lakewalker.py script to be downloaded into the lakewalker directory
+within the JOSM plugin directory.
+
+Common Features:
  - On-screen feedback to Lakewalker progress with cancel
  - Tag ways appropriately
  - limit ways to length
- - Access all lakewalker options via preferences and via ctrl-click pop-up dialog
  - Manage Landsat image cache from Prefs screen
+
+Native Features:
+ - Doesn't require Python
+
+Classic Features:
+ - Access all lakewalker options via preferences
  - Read data in thread
  - ...
Index: /applications/editors/josm/plugins/lakewalker/build.xml
===================================================================
--- /applications/editors/josm/plugins/lakewalker/build.xml	(revision 6909)
+++ /applications/editors/josm/plugins/lakewalker/build.xml	(revision 6910)
@@ -49,6 +49,7 @@
         <attribute name="Plugin-Class" value="org.openstreetmap.josm.plugins.lakewalker.LakewalkerPlugin" />
         <attribute name="Plugin-Description" value="Interface to Lakewalker module" />
-        <attribute name="Plugin-Version" value="0.1"/>
-        <attribute name="Author" value="Brent Easton &lt;b.easton@uws.edu.au>"/>
+        <attribute name="Plugin-Version" value="0.2"/>
+        <attribute name="Author" value="Brent Easton &lt;b.easton@uws.edu.au>, Jason Reid &lt;jrreid@ucalgary.ca>"/>
+		<attribute name="Main-Class" value="org.openstreetmap.josm.plugins.lakewalker.LakewalkerApp"/>
       </manifest>
     </jar>
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 6910)
+++ /applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/Lakewalker.java	(revision 6910)
@@ -0,0 +1,365 @@
+package org.openstreetmap.josm.plugins.lakewalker;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.util.*;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.AddCommand;
+import org.openstreetmap.josm.command.Command;
+import org.openstreetmap.josm.command.SequenceCommand;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.Way;
+
+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("Direction index '"+direction+"' not found");
+		}
+		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); 
+		
+		if(!bbox.contains(lat, lon)){
+			throw new LakewalkerException("The starting location was not within the bbox");
+		}
+		
+		int v;
+		
+		while(true){
+			double[] geo = xy_to_geo(xy[0],xy[1]);
+			if(bbox.contains(geo[0],geo[1])==false){
+				break;
+			}
+			
+			v = wms.getPixel(xy[0], xy[1],0xFF00FF00);
+			if(v < 0){
+				return null;
+			}
+			
+			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]);
+				
+		System.out.println("Found shore at "+startxy[0]+","+startxy[1]);
+		
+		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++){
+			
+			if(i % 250 == 0){
+				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;
+			
+			for(d = 1; d <= this.dirslat.length; d++){
+				
+				new_dir = (last_dir + d + 4) % 8;
+				
+				//System.out.println(last_dir+", "+d+" "+new_dir);
+				
+				test_x = xy[0] + this.dirslon[new_dir];
+				test_y = xy[1] + this.dirslat[new_dir];
+				
+				double[] geo = xy_to_geo(xy[0],xy[1]);
+				
+				if(!bbox.contains(geo[0], geo[1])){
+					System.out.println("Outside bbox");
+					break;
+				}
+				
+				v = wms.getPixel(test_x, test_y,0xFF0000FF);
+				//System.out.println(new_dir+" "+test_x+","+test_y+" "+v);
+				if(v > this.threshold){
+					break;
+				}
+				
+				if(d == this.dirslat.length-1){
+					System.out.println("Got stuck");
+					break;
+				}
+			}
+			
+			//System.out.println("Found empty space");
+			
+			// Remember this direction
+			last_dir = new_dir;
+			xy[0] = test_x;
+			xy[1] = test_y;
+			
+			if(xy[0] == startxy[0] && xy[1] == startxy[1]){
+				break;
+			}
+			
+			double[] geo = xy_to_geo(xy[0],xy[1]);
+			nodelist.add(geo);
+			System.out.println("Adding node at "+xy[0]+","+xy[1]+" ("+geo[1]+","+geo[0]+")");
+			
+	        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;
+	            }
+			}			
+		}
+			
+		// DEBUG
+		File f = new File(this.workingdir,"temp.png");
+		wms.saveimage(f,wms.image2);	
+		
+		return nodelist;
+	}
+	
+	public ArrayList<double[]> vertex_reduce(ArrayList<double[]> nodes, double proximity){
+		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 point_line_distance(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[]> douglas_peucker(ArrayList<double[]> nodes, double epsilon){
+		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 = point_line_distance(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 = douglas_peucker(sublist(nodes,0,farthest_node+1),epsilon);
+			seg_b = douglas_peucker(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;
+	}
+	
+	private double[] xy_to_geo(int x, int y){
+		double[] geo = new double[2];
+	    geo[0] = y / (double)this.resolution;
+	    geo[1] = x / (double)this.resolution;
+	    return geo;
+	}
+	
+	private int[] geo_to_xy(double lat, double lon){
+		int[] xy = new int[2];
+		
+		xy[0] = (int)Math.floor(lon * this.resolution + 0.5);
+		xy[1] = (int)Math.floor(lat * this.resolution + 0.5);
+		
+		System.out.println("("+lon+","+lat+") maps to ("+xy[0]+","+xy[1]+")");
+		
+		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((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 6909)
+++ /applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerAction.java	(revision 6910)
@@ -13,5 +13,8 @@
 import java.io.InputStreamReader;
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
 import java.util.List;
+import java.util.Vector;
 
 import javax.swing.JOptionPane;
@@ -24,4 +27,11 @@
 import org.openstreetmap.josm.gui.PleaseWaitRunnable;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.command.AddCommand;
+import org.openstreetmap.josm.command.Command;
+import org.openstreetmap.josm.command.SequenceCommand;
+
 import org.xml.sax.SAXException;
 
@@ -38,4 +48,8 @@
   protected List<Node> selectedNodes;
   protected Thread executeThread;
+  protected boolean cancel;
+  
+  protected Collection<Command> commands = new LinkedList<Command>();
+  protected Collection<Way> ways = new ArrayList<Way>();
   
   public LakewalkerAction(String name) {
@@ -45,5 +59,5 @@
     setEnabled(true);
   }
-
+  
   public void actionPerformed(ActionEvent e) {
 
@@ -73,72 +87,160 @@
   }
 
-  protected void lakewalk(Point clickPoint) {
-    LatLon pos = Main.map.mapView.getLatLon(clickPoint.x, clickPoint.y);
-
-    /*
-     * Collect options
-     */
-    File working_dir = new File(Main.pref.getPreferencesDir(), "plugins");
-    working_dir = new File(working_dir, "Lakewalker");
-    String target = Main.pref.get(LakewalkerPreferences.PREF_PYTHON) + " lakewalker.py";
-    LatLon topLeft = Main.map.mapView.getLatLon(0, 0);
-    LatLon botRight = Main.map.mapView.getLatLon(Main.map.mapView.getWidth(), Main.map.mapView
-        .getHeight());
-
-    /*
-     * Build command line
-     */
-    target += " --lat=" + pos.lat();
-    target += " --lon=" + pos.lon();
-    target += " --left=" + topLeft.lon();
-    target += " --right=" + botRight.lon();
-    target += " --top=" + topLeft.lat();
-    target += " --bottom=" + botRight.lat();
-    target += " --waylength=" + Main.pref.get(LakewalkerPreferences.PREF_MAX_SEG, "500");
-    target += " --maxnodes=" + Main.pref.get(LakewalkerPreferences.PREF_MAX_NODES, "50000");
-    target += " --threshold=" + Main.pref.get(LakewalkerPreferences.PREF_THRESHOLD, "35");
-    target += " --dp-epsilon=" + Main.pref.get(LakewalkerPreferences.PREF_EPSILON, "0.0003");
-    target += " --landsat-res=" + Main.pref.get(LakewalkerPreferences.PREF_LANDSAT_RES, "4000");
-    target += " --tilesize=" + Main.pref.get(LakewalkerPreferences.PREF_LANDSAT_SIZE, "2000");
-    target += " --startdir=" + Main.pref.get(LakewalkerPreferences.PREF_START_DIR, "east");
-    target += " --wms=" + Main.pref.get(LakewalkerPreferences.PREF_WMS, "IR1");    
-    target += " --josm";
+  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 = Integer.parseInt(Main.pref.get(LakewalkerPreferences.PREF_MAX_SEG, "500"));
+	final int maxnode = Integer.parseInt(Main.pref.get(LakewalkerPreferences.PREF_MAX_NODES, "50000"));
+	final int threshold = Integer.parseInt(Main.pref.get(LakewalkerPreferences.PREF_THRESHOLD, "35"));
+	final double epsilon = Double.parseDouble(Main.pref.get(LakewalkerPreferences.PREF_EPSILON, "0.0003"));
+	final int resolution = Integer.parseInt(Main.pref.get(LakewalkerPreferences.PREF_LANDSAT_RES, "4000"));
+	final int tilesize = Integer.parseInt(Main.pref.get(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 {
+        	  processnodelist(pos, topLeft, botRight, waylen,maxnode,threshold,epsilon,resolution,tilesize,startdir,wmslayer,working_dir);
+          }
+          @Override protected void finish() {
+            
+          }
+          @Override protected void cancel() {
+            cancel();
+          }
+        };
+        Thread executeThread = new Thread(lakewalkerTask);
+        executeThread.start();
+      }
+      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
+	 */
+	
+	nodelist = lw.vertex_reduce(nodelist, epsilon);
+	
+	System.out.println("After vertex reduction "+nodelist.size()+" nodes remain.");
+	
+	/**
+	 * And then through douglas-peucker reduction
+	 */
+	
+	nodelist = lw.douglas_peucker(nodelist, epsilon);
+	
+	System.out.println("After Douglas-Peucker approximation "+nodelist.size()+" nodes remain.");
+	  
+	/**
+	 * Turn the arraylist into osm nodes
+	 */
+	
+	Way way = new Way();
+	Node n = null;
+	Node tn = null;
+	Node fn = null;
+	
+	double eastOffset = 0.0;
+	double northOffset = 0.0;
+	try {
+	  eastOffset = Double.parseDouble(Main.pref.get(LakewalkerPreferences.PREF_EAST_OFFSET, "0.0"));
+	  northOffset = Double.parseDouble(Main.pref.get(LakewalkerPreferences.PREF_NORTH_OFFSET, "0.0"));
+	}
+	catch (Exception e) {
+	  
+	}
+	char option = ' ';
+	
+	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 > Integer.parseInt(Main.pref.get(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++;
+	}
+	
+	commands.add(new AddCommand(way));
+	String waytype = Main.pref.get(LakewalkerPreferences.PREF_WAYTYPE, "water");
     
-
-    try {
-      /*
-       * Start the Lakewalker
-       */
-      Runtime rt = Runtime.getRuntime();
-      System.out.println("dir: " + working_dir + ", target: " + target);
-      final Process p = rt.exec(target, null, working_dir);
-      final BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
-      
-      /*
-       * Start a thread to read the output
-       */
-      final LakewalkerReader reader = new LakewalkerReader();
-      
-      PleaseWaitRunnable lakewalkerTask = new PleaseWaitRunnable(tr("Tracing")){
-        @Override protected void realRun() throws SAXException {
-          reader.read(input);
-        }
-        @Override protected void finish() {
-          
-        }
-        @Override protected void cancel() {
-          reader.cancel();
-          executeThread.interrupt();
-          p.destroy();
-        }
-      };
-      Thread executeThread = new Thread(lakewalkerTask);
-      executeThread.start();
-    }
-    catch (Exception ex) {
-      System.out.println("Exception caught: " + ex.getMessage());
-    }
-
-
+    if(!waytype.equals("none")){
+  	  way.put("natural",waytype);
+    }
+    
+    way.put("created_by", "Dshpak_landsat_lakes");
+    
+	way.nodes.add(fn);
+	
+	
+	if (!commands.isEmpty()) {
+        Main.main.undoRedo.add(new SequenceCommand(tr("Lakewalker trace"), commands));
+        Main.ds.setSelected(ways);
+    } else {
+  	  System.out.println("Failed");
+    }
+  }
+  
+  public void cancel() {
+	  cancel = true;
   }
 
@@ -164,69 +266,4 @@
   public void mouseReleased(MouseEvent e) {
   }
-
-
-  // class DuplicateDialog extends JDialog {
-  // private static final long serialVersionUID = 1L;
-  // protected Box mainPanel;
-  // protected IntConfigurer offset;
-  // protected boolean cancelled;
-  // protected String right;
-  // protected String left;
-  // protected JComboBox moveCombo;
-  //
-  // public DuplicateDialog(String title) {
-  // super();
-  // this.setTitle(title);
-  // this.setModal(true);
-  // initComponents();
-  // }
-  //
-  // protected void initComponents() {
-  // mainPanel = Box.createVerticalBox();
-  // offset = new IntConfigurer("", tr("Offset (metres): "), new Integer(15));
-  // mainPanel.add(offset.getControls());
-  // getContentPane().add(mainPanel);
-  //
-  // right = tr("right/down");
-  // left = tr("left/up");
-  // Box movePanel = Box.createHorizontalBox();
-  // movePanel.add(new JLabel(tr("Create new segments to the ")));
-  // moveCombo = new JComboBox(new String[] {right, left});
-  // movePanel.add(moveCombo);
-  // movePanel.add(new JLabel(tr(" of existing segments.")));
-  // mainPanel.add(movePanel);
-  //
-  // Box buttonPanel = Box.createHorizontalBox();
-  // JButton okButton = new JButton(tr("Ok"));
-  // okButton.addActionListener(new ActionListener() {
-  // public void actionPerformed(ActionEvent e) {
-  // cancelled = false;
-  // setVisible(false);
-  //
-  // }
-  // });
-  // JButton canButton = new JButton(tr("Cancel"));
-  // canButton.addActionListener(new ActionListener() {
-  // public void actionPerformed(ActionEvent e) {
-  // cancelled = true;
-  // setVisible(false);
-  // }
-  // });
-  // buttonPanel.add(okButton);
-  // buttonPanel.add(canButton);
-  // mainPanel.add(buttonPanel);
-  //
-  // pack();
-  // }
-  //
-  // protected int getOffset() {
-  // int off = offset.getIntValue(15);
-  // return right.equals(moveCombo.getSelectedItem()) ? off : -off;
-  // }
-  //
-  // protected boolean isCancelled() {
-  // return cancelled;
-  // }
-  //
-  // }
+  
 }
Index: /applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerActionOld.java
===================================================================
--- /applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerActionOld.java	(revision 6910)
+++ /applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerActionOld.java	(revision 6910)
@@ -0,0 +1,233 @@
+package org.openstreetmap.josm.plugins.lakewalker;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.Cursor;
+import java.awt.Point;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.JOptionPane;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.gui.PleaseWaitRunnable;
+import org.openstreetmap.josm.tools.ImageProvider;
+import org.xml.sax.SAXException;
+
+/**
+ * Interface to Darryl Shpak's Lakewalker module
+ * 
+ * @author Brent Easton
+ */
+class LakewalkerActionOld extends JosmAction implements MouseListener {
+
+  private static final long serialVersionUID = 1L;
+  protected String name;
+  protected Cursor oldCursor;
+  protected List<Node> selectedNodes;
+  protected Thread executeThread;
+  
+  public LakewalkerActionOld(String name) {
+    super(name, "lakewalker-sml", tr("Lake Walker."), KeyEvent.VK_L, KeyEvent.CTRL_MASK
+        | KeyEvent.SHIFT_MASK, true);
+    this.name = name;
+    setEnabled(true);
+  }
+  
+  public void actionPerformed(ActionEvent e) {
+
+    Main.map.mapView.setCursor(oldCursor);
+
+    if (Main.map == null) {
+      JOptionPane.showMessageDialog(Main.parent, tr("No data loaded."));
+      return;
+    }
+
+    selectedNodes = new ArrayList<Node>();
+    for (OsmPrimitive osm : Main.ds.getSelected()) {
+      if (osm instanceof Node) {
+        Node node = (Node) osm;
+        selectedNodes.add(node);
+      }
+    }
+
+    if (selectedNodes.isEmpty()) {
+      oldCursor = Main.map.mapView.getCursor();
+      Main.map.mapView.setCursor(ImageProvider.getCursor("crosshair", "lakewalker-sml"));
+      Main.map.mapView.addMouseListener(this);
+    }
+    else {
+      lakewalk(selectedNodes);
+    }
+  }  
+  
+  protected void lakewalk(Point clickPoint) {
+    LatLon pos = Main.map.mapView.getLatLon(clickPoint.x, clickPoint.y);
+
+    /*
+     * Collect options
+     */
+    File working_dir = new File(Main.pref.getPreferencesDir(), "plugins");
+    working_dir = new File(working_dir, "Lakewalker");
+    String target = Main.pref.get(LakewalkerPreferences.PREF_PYTHON) + " lakewalker.py";
+    LatLon topLeft = Main.map.mapView.getLatLon(0, 0);
+    LatLon botRight = Main.map.mapView.getLatLon(Main.map.mapView.getWidth(), Main.map.mapView
+        .getHeight());
+
+    /*
+     * Build command line
+     */
+    target += " --lat=" + pos.lat();
+    target += " --lon=" + pos.lon();
+    target += " --left=" + topLeft.lon();
+    target += " --right=" + botRight.lon();
+    target += " --top=" + topLeft.lat();
+    target += " --bottom=" + botRight.lat();
+    target += " --waylength=" + Main.pref.get(LakewalkerPreferences.PREF_MAX_SEG, "500");
+    target += " --maxnodes=" + Main.pref.get(LakewalkerPreferences.PREF_MAX_NODES, "50000");
+    target += " --threshold=" + Main.pref.get(LakewalkerPreferences.PREF_THRESHOLD, "35");
+    target += " --dp-epsilon=" + Main.pref.get(LakewalkerPreferences.PREF_EPSILON, "0.0003");
+    target += " --landsat-res=" + Main.pref.get(LakewalkerPreferences.PREF_LANDSAT_RES, "4000");
+    target += " --tilesize=" + Main.pref.get(LakewalkerPreferences.PREF_LANDSAT_SIZE, "2000");
+    target += " --startdir=" + Main.pref.get(LakewalkerPreferences.PREF_START_DIR, "east");
+    target += " --wms=" + Main.pref.get(LakewalkerPreferences.PREF_WMS, "IR1");    
+    target += " --josm";
+    
+
+    try {
+      /*
+       * Start the Lakewalker
+       */
+      Runtime rt = Runtime.getRuntime();
+      System.out.println("dir: " + working_dir + ", target: " + target);
+      final Process p = rt.exec(target, null, working_dir);
+      final BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
+      
+      /*
+       * Start a thread to read the output
+       */
+      final LakewalkerReader reader = new LakewalkerReader();
+      
+      PleaseWaitRunnable lakewalkerTask = new PleaseWaitRunnable(tr("Tracing")){
+        @Override protected void realRun() throws SAXException {
+          reader.read(input);
+        }
+        @Override protected void finish() {
+          
+        }
+        @Override protected void cancel() {
+          reader.cancel();
+          executeThread.interrupt();
+          p.destroy();
+        }
+      };
+      Thread executeThread = new Thread(lakewalkerTask);
+      executeThread.start();
+    }
+    catch (Exception ex) {
+      System.out.println("Exception caught: " + ex.getMessage());
+    }
+
+
+  }
+
+  protected void lakewalk(List nodes) {
+
+  }
+
+  public void mouseClicked(MouseEvent e) {
+    Main.map.mapView.removeMouseListener(this);
+    Main.map.mapView.setCursor(oldCursor);
+    lakewalk(e.getPoint());
+  }
+
+  public void mouseEntered(MouseEvent e) {
+  }
+
+  public void mouseExited(MouseEvent e) {
+  }
+
+  public void mousePressed(MouseEvent e) {
+  }
+
+  public void mouseReleased(MouseEvent e) {
+  }
+
+
+  // class DuplicateDialog extends JDialog {
+  // private static final long serialVersionUID = 1L;
+  // protected Box mainPanel;
+  // protected IntConfigurer offset;
+  // protected boolean cancelled;
+  // protected String right;
+  // protected String left;
+  // protected JComboBox moveCombo;
+  //
+  // public DuplicateDialog(String title) {
+  // super();
+  // this.setTitle(title);
+  // this.setModal(true);
+  // initComponents();
+  // }
+  //
+  // protected void initComponents() {
+  // mainPanel = Box.createVerticalBox();
+  // offset = new IntConfigurer("", tr("Offset (metres): "), new Integer(15));
+  // mainPanel.add(offset.getControls());
+  // getContentPane().add(mainPanel);
+  //
+  // right = tr("right/down");
+  // left = tr("left/up");
+  // Box movePanel = Box.createHorizontalBox();
+  // movePanel.add(new JLabel(tr("Create new segments to the ")));
+  // moveCombo = new JComboBox(new String[] {right, left});
+  // movePanel.add(moveCombo);
+  // movePanel.add(new JLabel(tr(" of existing segments.")));
+  // mainPanel.add(movePanel);
+  //
+  // Box buttonPanel = Box.createHorizontalBox();
+  // JButton okButton = new JButton(tr("Ok"));
+  // okButton.addActionListener(new ActionListener() {
+  // public void actionPerformed(ActionEvent e) {
+  // cancelled = false;
+  // setVisible(false);
+  //
+  // }
+  // });
+  // JButton canButton = new JButton(tr("Cancel"));
+  // canButton.addActionListener(new ActionListener() {
+  // public void actionPerformed(ActionEvent e) {
+  // cancelled = true;
+  // setVisible(false);
+  // }
+  // });
+  // buttonPanel.add(okButton);
+  // buttonPanel.add(canButton);
+  // mainPanel.add(buttonPanel);
+  //
+  // pack();
+  // }
+  //
+  // protected int getOffset() {
+  // int off = offset.getIntValue(15);
+  // return right.equals(moveCombo.getSelectedItem()) ? off : -off;
+  // }
+  //
+  // protected boolean isCancelled() {
+  // return cancelled;
+  // }
+  //
+  // }
+  
+}
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 6910)
+++ /applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerApp.java	(revision 6910)
@@ -0,0 +1,57 @@
+package org.openstreetmap.josm.plugins.lakewalker;
+
+import java.io.File;
+import java.util.*;
+
+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.vertex_reduce(nodelist, dp);
+	    
+	    System.out.println("After vertex reduction, "+nodelist.size()+" nodes remain.");
+	    
+	    nodelist = lw.douglas_peucker(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 6910)
+++ /applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerException.java	(revision 6910)
@@ -0,0 +1,19 @@
+package org.openstreetmap.josm.plugins.lakewalker;
+
+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;
+	}
+}
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 6909)
+++ /applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerPlugin.java	(revision 6910)
@@ -20,7 +20,9 @@
   
   protected String name;
+  protected String name2;
 
   public LakewalkerPlugin() {
     name = tr("Lake Walker");
+    name2 = tr("Lake Walker (Old)");
     JMenu toolsMenu = null;
     for (int i = 0; i < Main.main.menu.getMenuCount() && toolsMenu == null; i++) {
@@ -40,4 +42,5 @@
       toolsMenu.addSeparator();
       toolsMenu.add(new JMenuItem(new LakewalkerAction(name)));
+      toolsMenu.add(new JMenuItem(new LakewalkerActionOld(name2)));
     }
     
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 6910)
+++ /applications/editors/josm/plugins/lakewalker/src/org/openstreetmap/josm/plugins/lakewalker/LakewalkerWMS.java	(revision 6910)
@@ -0,0 +1,201 @@
+package org.openstreetmap.josm.plugins.lakewalker;
+
+import org.openstreetmap.josm.Main;
+import java.awt.Image;
+import javax.imageio.*;
+import java.math.*;
+import java.io.*;
+import java.net.*;
+import java.awt.image.BufferedImage;
+import java.awt.*;
+import java.awt.image.*;
+import java.awt.geom.*;
+
+public class LakewalkerWMS {
+	
+	public LakewalkerWMS(){
+		
+	}
+	
+	private BufferedImage image;
+	private int imagex;
+	private int imagey;
+	
+	public BufferedImage image2 = new BufferedImage(2000, 2000, BufferedImage.TYPE_INT_RGB);
+	
+	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 layer = "global_mosaic_base";
+		
+		int[] bottom_left_xy = new int[2]; 
+		bottom_left_xy[0] = (int)(x / this.tilesize) * this.tilesize;
+		bottom_left_xy[1] = (int)(y / this.tilesize) * 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]);
+        double[] bottomleft_geo = xy_to_geo(bottom_left_xy[0],bottom_left_xy[1]);
+          
+		String filename = this.wmslayer+"/landsat_"+this.resolution+"_"+this.tilesize+
+			"_xy_"+bottom_left_xy[0]+"_"+bottom_left_xy[1]+".png";
+		
+		String urlloc = String.format("http://onearth.jpl.nasa.gov/wms.cgi?request=GetMap&layers="+layer+
+			"&styles="+wmslayer+"&srs=EPSG:4326&format=image/png"+
+			"&bbox=%.6f,%.6f,%.6f,%.6f&width=%d&height=%d",
+			bottomleft_geo[1],bottomleft_geo[0],topright_geo[1],topright_geo[0],
+			this.tilesize,this.tilesize);			
+		
+        File file = new File(this.working_dir,filename);
+        
+        // See if this image is already loaded
+        if(this.image != null){
+        	if(this.imagex != bottom_left_xy[0] || this.imagey != bottom_left_xy[1]){
+        		this.image = null;
+        	} else {
+        		return this.image;
+        	}
+        }
+        
+	    try {	    	
+	    	System.out.println("Looking for image in cache: "+filename);
+	    	
+	        // Read from a file
+	        this.image = ImageIO.read(file);
+	    
+	    } 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);
+	        } catch(MalformedURLException e){
+	        	System.out.println(e.getMessage());
+	        } catch(IOException e){
+	        	System.out.println(e.getMessage());
+	        } catch(Exception e){
+	        	System.out.println(e.getMessage());
+		    }
+	        
+	        this.saveimage(file,this.image);
+	    }
+	    
+	    this.imagex = bottom_left_xy[0];
+	    this.imagey = bottom_left_xy[1];
+	    
+	    if(this.image == null){
+	    	throw new LakewalkerException("Could not acquire image");
+	    }
+		
+		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");
+        } catch(Exception e){
+        	System.out.println(e.getMessage());
+        }
+	}
+	
+	
+	
+	public int getPixel(int x, int y, int pixcol){
+		
+		BufferedImage image = null;
+
+		try {
+			image = this.getTile(x,y);
+		} catch(LakewalkerException e){
+			System.out.println(e.getError());
+			return -1;
+		}
+
+		int tx = (int)(Math.floor(x / this.tilesize) * this.tilesize);
+		int ty = (int)(Math.floor(y / this.tilesize) * this.tilesize);
+		
+		int pixel_x = (x-tx);
+		int pixel_y = (this.tilesize-1)-(y-ty);
+				
+		int rgb = image.getRGB(pixel_x,pixel_y);
+		
+		// DEBUG: set the pixels
+		this.image2.setRGB(pixel_x,pixel_y,pixcol);
+		
+		int pixel;
+		
+		int r = (rgb >> 16) & 0xff;
+        int g = (rgb >>  8) & 0xff;
+        int b = (rgb >>  0) & 0xff;
+
+        //pixel = rgbToGrey(pixel); //(r+g+b)/3; //pixel & 0xff;
+        
+        int pixel2 = (int)((0.212671 * r) + (0.715160 * b) + (0.072169 * b));
+        
+        pixel = (int)((0.30 * r) + (0.59 * b) + (0.11 * g));
+                
+		//System.out.println(pixel_y+","+pixel_x+"  "+r+","+g+","+b+"="+pixel+"("+pixel2+")");
+
+		return pixel; 
+	}
+	
+	private int rgbToGrey(int color) {
+		Color c = new Color(color);
+	    int red = c.getRed();
+	    int green = c.getGreen();
+	    int blue = c.getBlue();
+	    int tot = (red + green + blue) / 3;
+	    return tot;
+	}
+
+	private void printarr(int[] a){
+		for(int i = 0; i<a.length; i++){
+			System.out.println(i+": "+a[i]);
+		}
+	}
+	private double[] xy_to_geo(int x, int y){
+		double[] geo = new double[2];
+	    geo[0] = (double)y / (double)this.resolution;
+	    geo[1] = (double)x / (double)this.resolution;
+	    return geo;
+	}
+	
+	private int[] geo_to_xy(double lat, double lon){
+		int[] xy = new int[2];
+		
+		xy[0] = (int)(Math.floor(lon * this.resolution) + 0.5);
+		xy[1] = (int)(Math.floor(lat * this.resolution) + 0.5);
+		
+		return xy;
+	}
+}
