CSC400 Code - Smith Walk Project

From CSclasswiki
Jump to: navigation, search

extractCoord.php

Fetches a file with coordinates from the database, and linearly interpolates the time at each point.

<?php
  // extractCoord.php
  // Elizabeth Do and Aigerim Karabekova
  // 220a-aa, 220a-aa
  // November 4, 2010
  // Obtains KML data from database

  // Modified by Aigerim Karabekova
  // Feb 13, 2011

  include 'accessinfo.php';
date_default_timezone_set('America/New_York');
  $database = "220a_project";

// Extract an array of ids from the URL
//$id = $_REQUEST['id'];
//$id_arr = explode(",", $id);

$id_arr = array("783");

//--- connect to mysql server ---
  $link = mysql_connect( $hostName, $userName, $password );
  if ( ! $link ) 
    die( "Could not connect to server: " . $mysql_error() );

//--- select database ---
  $db = mysql_select_db( $database, $link );
  if ( ! $db ) 
    die( "Could not connect to database " . $database . ": "
         . mysql_error() );

  $filename = "coordinates.txt";

  if(file_exists($filename)){
    unlink($filename);
  }

  $fg = fopen($filename, 'a') or die("Can't open file");


//--- get KML data using id from kmldata table ---
foreach($id_arr as $id){

  $id = mysql_real_escape_string($id);

  $query = sprintf( "SELECT `data` FROM `kmldata` WHERE `tripId`=$id" );

  $result = mysql_query( $query, $link );

  if ( ! $result ) 
    printf( "Unsuccessful query \n" );

  $row = mysql_fetch_row($result);

  $newId = coord($row[0]);

  fwrite($fg, "id=$id"."\n".$newId);
}

  fclose($fg);
  chmod($filename, 0766);

//--- close database ---
mysql_close( $link );


function coord($kml){
  $kmlArray = explode("\n", $kml);
  $coorXY = "";

  // An array to store timestamps 
  $timeCount = array();

  // 2D arrays of coordinates
  $x = array(); 
  $y = array();
  $recordCoords = false;
  $timeCounter = 0;

  // loop through each line in kml and extract coordinates

  for($i=0; $i < count($kmlArray); $i++){

    $timeStart = strPos($kmlArray[$i], "<time>");

    if ($timeStart !== False){

      $timeCount[] = strtotime(trim(substr($kmlArray[$i], strpos($kmlArray[$i], ":")-2, 8)));

      $i += 1; //move to next line

      $posStart = strpos($kmlArray[$i], "<coordinates>");

      if ($posStart !== False){
	$i+=1;
	while(strpos($kmlArray[$i], "</coordinates>") === False){
	  $coords = explode(",", $kmlArray[$i]);

	  if($coords[0] !== "</coordinates>" && $coords[0]!=="<coordinates>"){

	    if (preg_match("/[-+]?[0-9]*\.?[0-9]+/", trim($coords[0]), $matches)) {
	      $x[$timeCounter][] = $matches[0];
	      $dummy =  $matches[0];

	    }

	    if (preg_match("/[-+]?[0-9]*\.?[0-9]+/", trim($coords[1]), $matches)) {
	      $y[$timeCounter][] = $matches[0];
	    }
	  }
	  $i+=1;
	}
	$timeCounter += 1;
      }
    }
  }

  for ($i=0; $i < $timeCounter; $i++){
    $arrlength = sizeof($x[$i]);

    $interval = ($timeCount[$i+1]-$timeCount[$i])/($arrlength-1);

    for ($k=0; $k < $arrlength; $k++){
      $time = $interval*$k + $timeCount[$i];     
      $date = date(DATE_RSS, $time);
      $coorXY .= $x[$i][$k].','.$y[$i][$k].','.$date."\n";
    }
  }
  return $coorXY;
}
?>

Output:

id=783
-72.69459750750001,42.34444296000000,Sun, 13 Feb 2011 07:50:00 -0500
-72.69435600000000,42.34400928333333,Sun, 13 Feb 2011 07:52:13 -0500
-72.69431068333333,42.34405935000000,Sun, 13 Feb 2011 07:54:26 -0500
-72.69446536666666,42.34410188333333,Sun, 13 Feb 2011 07:56:40 -0500
-72.69409073333333,42.34385796666667,Sun, 13 Feb 2011 07:58:53 -0500
-72.69392793333333,42.34376685000000,Sun, 13 Feb 2011 08:01:06 -0500
-72.69364926666667,42.34365636666666,Sun, 13 Feb 2011 08:03:20 -0500
-72.69293845000000,42.34334739999999,Sun, 13 Feb 2011 08:05:33 -0500
-72.69270220000000,42.34304800000000,Sun, 13 Feb 2011 08:07:46 -0500
-72.69264033333334,42.34287956666667,Sun, 13 Feb 2011 08:10:00 -0500
-72.69265161666668,42.34280600000000,Sun, 13 Feb 2011 08:10:00 -0500
-72.69287370000001,42.34265043333333,Sun, 13 Feb 2011 08:13:04 -0500
-72.69309221666667,42.34251263333334,Sun, 13 Feb 2011 08:16:09 -0500
-72.69328463333333,42.34241403333333,Sun, 13 Feb 2011 08:19:13 -0500
-72.69342835000000,42.34232905000000,Sun, 13 Feb 2011 08:22:18 -0500
-72.69359670000000,42.34220988333334,Sun, 13 Feb 2011 08:25:23 -0500
-72.69377464999999,42.34210050000000,Sun, 13 Feb 2011 08:28:27 -0500
-72.69396520000001,42.34200168333333,Sun, 13 Feb 2011 08:31:32 -0500
-72.69419445000000,42.34190578333333,Sun, 13 Feb 2011 08:34:36 -0500
-72.69439651666667,42.34189388333332,Sun, 13 Feb 2011 08:37:41 -0500
-72.69453363333334,42.34204025000000,Sun, 13 Feb 2011 08:40:46 -0500
-72.69470221666667,42.34222191666666,Sun, 13 Feb 2011 08:43:50 -0500
-72.69501901666666,42.34270666666666,Sun, 13 Feb 2011 08:46:55 -0500
-72.69512208333333,42.34282508333334,Sun, 13 Feb 2011 08:50:00 -0500

Trace.java

This class stores information about traces from the database.

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.Date;

/**
 *  Sorts coordinate, time, color in one data
 *  object.
 * 
 *  @author Lindsey Gregor
 *  @version 20 February 2011
 */
public class Trace {
    /** Holds the track id number */
    int trackId;
	
    /** Holds the user id number for the trace */
    int userId;
    
    /** Holds the coordinate data in form of [x,y,t] */
    double[][] coord;
    
    /** Holds the pointer to which coordinate to use */
    int pointer;
    
    /** Holds the date of the trace */
    Date date;

    /** Constructor */
    Trace(File coords, int trackId, int userId){
    	// Initialize all of the fields
        this.trackId = trackId;
        this.userId = userId;
        this.coord = extractCoords(coords);
        this.pointer = 0;
    }

    /**
     *	Takes a file and extracts the coordinates in
     *	it.  Returns them in an array.
     *
     * 	@param File coords  The file to extract
     *	@return int[][] of coordinates
     */
    //String[][] extractCoords(File coords) {
    private double[][] extractCoords(File coords) {
    	// Declare a set size for now
    	double[][] coord1 = new double[24][3];
    	try {
    		BufferedReader input = new BufferedReader(new FileReader(coords));
    		String line = null;
    		int index = 0;
    		while ((line = input.readLine()) != null){
    			String tmp[] = line.split(",");
    			for (int i=0; i<tmp.length; i++) {
    				coord1[index][i] = Double.parseDouble(tmp[i]);
    			}
    			index++;
    		}
    	} catch (Exception ex){
    		System.out.println("Error when reading file "+ coords + " " + ex.getMessage());
    	}
    	return coord1;
    }
    
    /**
     *  Gets the coordinate array.
     * 
     *  @return the entire coordinate array
     */
    public double[][] getCoords() {
    	return this.coord;
    }
    
    /**
     *  Gets the coordinate triplet at pointer if it exists.  If
     *  not, returns null.
     *
     *  @return the coordinate triplet at the pointer
     */
    public double[] getCoordinate() {
    	if (this.pointer<this.coord.length) {
    		return this.coord[this.pointer];
    	} else {
    		return null;
    	}
    }
    
    public int getTrackId() {
    	return this.trackId;
    }
    
    /** 
     *  Increments the pointer.  Checks to make sure 
     *  there exists a coordinate point at the new 
     *  pointer index
     *  
     *  @return true if pointer index exists
     *  @return false if pointer index does not exist
     */
    public boolean increment() {
    	this.pointer++;
    	// Check to see if there exists more points in trace
    	if (this.pointer<(this.coord).length) {
    		return true;
    	} else {
    		return false;
    	}
    }
}

Modified Trace.java

This class stores information about traces from the database. Now has a getCoordinateArray() method which returns the current coordinate triplet and track ID in a double array [x, y, t, trackId].

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.Date;

/**
 *  Sorts coordinate, time, color in one data
 * 	object.
 * 
 *	@author Lindsey Gregor
 *	@version 20 February 2011
 */
public class Trace {
	/** Holds the track id number */
	int trackId;
	
	/** Holds the user id number for the trace */
    int userId;
    
    /** Holds the coordinate data in form of [x,y,t] */
    double[][] coord;
    
    /** Holds the pointer to which coordinate to use */
    int pointer;
    
    /** Holds the date of the trace */
    Date date;

    Trace(File coords, int trackId, int userId){
    	// Initialize all of the fields
        this.trackId = trackId;
        this.userId = userId;
        this.coord = extractCoords(coords);
        this.pointer = 0;
    }

    /**
     *	Takes a file and extracts the coordinates in
     *	it.  Returns them in an array.
     *
     * 	@param File coords  The file to extract
     *	@return int[][] of coordinates
     */
    //String[][] extractCoords(File coords) {
    private double[][] extractCoords(File coords) {
    	// Declare a set size for now
    	double[][] coord1 = new double[24][3];
    	try {
    		BufferedReader input = new BufferedReader(new FileReader(coords));
    		String line = null;
    		int index = 0;
    		while ((line = input.readLine()) != null){
    			String tmp[] = line.split(",");
    			for (int i=0; i<tmp.length; i++) {
    				coord1[index][i] = Double.parseDouble(tmp[i]);
    			}
    			index++;
    		}
    	} catch (Exception ex){
    		System.out.println("Error when reading file "
    				+ coords + " " + ex.getMessage());
    	}
    	return coord1;
    }
    
    /**
     * 	Gets the coordinate array.
     * 
     *  @return The entire coordinate array
     */
    public double[][] getCoords() {
    	return this.coord;
    }
    
    /**
     * 	Gets the coordinate triplet at pointer if it
     *  exists.  If not, returns null.
     *  
     *  @return The coordinate triplet at the pointer
     */
    public double[] getCoordinate() {
    	if (this.pointer<this.coord.length) {
    		return this.coord[this.pointer];
    	} else {
    		return null;
    	}
    }
    
    /**
     *  Gets the track id number of this Trace.
     *  
     *  @return The track id number of the trace
     */
    public int getTrackId() {
    	return this.trackId;
    }
    
    /**
     * Sets up the array of doubles to be added to a discrete
     * event queue.
     *
     * @return The double array [x,y,t,trackId]
     */
    public double[] getCoordinateArray() {
    	if (this.pointer<this.coord.length) {
    		double[] arr = new double[4];
    		int i = 0;
    		while (i < this.coord[this.pointer].length) {
    			arr[i] = this.coord[this.pointer][i];
    			i++;
    		}
    		arr[3] = this.trackId;
    		return arr;
    	} else {
    		return null;
    	}
    }
    
    /** 
     * 	Increments the pointer.  Checks to make sure 
     *  there exists a coordinate point at the new 
     *  pointer index
     *  
     *   @return true if pointer index exists
     *   @return false if pointer index does not exist
     */
    public boolean increment() {
    	this.pointer++;
    	// Check to see if there exists more points in trace
    	if (this.pointer<(this.coord).length) {
    		return true;
    	} else {
    		return false;
    	}
    }
}

DiscreteEventQueue.java

This class implements a discrete event queue.

import java.util.LinkedList;

/**
 *  This class implements a discrete event
 *  queue for Trace elements.
 *
 *  @author  Lindsey Gregor
 *  @version 19 February 2011
 */
public class DiscreteEventQueue {
    /** LinkedList to be implemented as a queue */
    LinkedList<double[]> queue;

    /** Check queue status */
    public boolean isEmpty() {
	return (queue.size() == 0);
    }
    
    /** Constructor */
    public DiscreteEventQueue() {
    	queue = new LinkedList<double[]>();
    }
    
    /**
     *  Adds a Trace coordinate triplet to the queue.
     *  
     *  @param data The coordinate to add
     *  @return true if added successfully
     *  @return false if not added
     */
    public boolean offer(double[] data) {
    	return queue.offer(data);
    }
    
    /**
     *  Removes the first Trace coordinate triplet 
     *  from the queue.
     *  
     *  @return the first element in the queue
     */
    public double[] poll() {
    	return queue.poll();
    }

    /** Sorts the entire discrete event queue */
    public void fullSort() {
    	// Not yet added
    }
    
    /** 
     * 	Sorts the discrete event queue after a 
     * 	new point is added.
     */
    public void sort() {
    	// Create the lists to hold the traces smaller and larger
    	// than the last one in the discrete event queue
    	LinkedList<double[]> larger = new LinkedList<double[]>();
    	LinkedList<double[]> smaller = new LinkedList<double[]>();
    	
    	// Sort the queue
    	for (int i=0; i<queue.size()-1; i++) {
    		double[] temp = queue.get(i);
    		if (temp[2] > queue.getLast()[2]) {
    			larger.offer(temp);
    		} else {
    			smaller.offer(temp);
    		}
    	}
    	
    	// Create new queue to replace old one
    	LinkedList<double[]> newQueue = new LinkedList<double[]>();
    	for (int i=0; i<smaller.size(); i++) {
    		newQueue.offer(smaller.poll());
    	}
    	newQueue.offer(queue.getLast());
    	for (int i=0; i<larger.size(); i++) {
    		newQueue.offer(larger.poll());
    	}
    	queue = newQueue;
    }
}

Modified DiscreteEventQueue.java

This class implements a discrete event queue. This class now has a peek() method.

import java.util.LinkedList;

/**
 *  This class implements a discrete event
 *  queue for Trace elements.
 *
 *   @author  Lindsey Gregor
 *  @version 19 February 2011
 */
public class DiscreteEventQueue {
	/** LinkedList to be implemented as a queue */
	LinkedList<double[]> queue;

    /** Check queue status */
    public boolean isEmpty() {
		return (queue.size() == 0);
    }
    
    /** Constructor */
    public DiscreteEventQueue() {
    	queue = new LinkedList<double[]>();
    }
    
    /**
     *  Adds a Trace coordinate triplet to the queue.
     *  
     *  @param data The coordinate to add
     *  @return true if added successfully
     *  @return false if not added
     */
    public boolean offer(double[] data) {
    	return queue.offer(data);
    }
    
    /**
     *  Removes the first Trace coordinate triplet 
     *  from the queue.
     *  
     *  @return the first element in the queue
     */
    public double[] poll() {
    	return queue.poll();
    }
    
    /**
     *  Looks at the first element of the queue 
     *  but does not remove it.
     *  
     *  @return the first element in the queue
     */
    public double[] peek() {
    	return queue.peek();
    }

    /** Sorts the entire discrete event queue */
    public void fullSort() {
    	// Not yet added
    }
    
    /** 
     * 	Sorts the discrete event queue after a 
     * 	new point is added.
     */
    public void sort() {
    	// Create the lists to hold the traces smaller and larger
    	// than the last one in the discrete event queue
    	LinkedList<double[]> larger = new LinkedList<double[]>();
    	LinkedList<double[]> smaller = new LinkedList<double[]>();
    	
    	// Sort the queue
    	for (int i=0; i<queue.size()-1; i++) {
    		double[] temp = queue.get(i);
    		if (temp[2] > queue.getLast()[2]) {
    			larger.offer(temp);
    		} else {
    			smaller.offer(temp);
    		}
    	}
    	
    	// Create new queue to replace old one
    	LinkedList<double[]> newQueue = new LinkedList<double[]>();
    	for (int i=0; i<smaller.size(); i++) {
    		newQueue.offer(smaller.poll());
    	}
    	if (!queue.isEmpty()) {
            newQueue.offer(queue.getLast());
    	}
    	for (int i=0; i<larger.size(); i++) {
    		newQueue.offer(larger.poll());
    	}
    	queue = newQueue;
    }
}

Testing the Discrete Event Simulator

Below are test files and sample outputs generated when testing the discrete event simulator classes.

Sample Output 1 for Discrete Event Simulation

Here is sample output from a test class testing both the Trace class and DiscreteEventQueue class. The test program ran the simulation from two .txt files containing 24 coordinate triplets where time is represented in Unix time. The output is given as x y t trackId.

-72.6945975075	        42.34444296      	1287905400	2	
-72.694356	        42.34400928333333	1287905520	2	
-72.69431068333333	42.34405935      	1287905640	2	
-72.69446536666666	42.34410188333333	1287905760	2	
-72.69409073333333	42.34385796666667	1287905880	2	
-72.69392793333333	42.34376685      	1287906000	2	
-72.69364926666667	42.34365636666666	1287906120	2	
-72.69293845	        42.34334739999999	1287906240	2	
-72.6927022	        42.343048         	1287906360	2	
-72.69264033333334	42.34287956666667	1287906480	2	
-72.69265161666668	42.342806         	1287906600	2	
-72.6928737	        42.34265043333333	1287906720	2	
-72.69309221666667	42.34251263333334	1287906840	2	
-72.69328463333333	42.34241403333333	1287906960	2	
-72.6945975075         	42.34444296      	1287907000	1	
-72.69342835	        42.34232905      	1287907080	2	
-72.694356        	42.34400928333333	1287907180	1	
-72.6935967      	42.34220988333334	1287907200	2	
-72.69431068333333	42.34405935      	1287907240	1	
-72.69446536666666	42.34410188333333	1287907300	1	
-72.69377465     	42.3421005        	1287907320	2	
-72.69409073333333	42.34385796666667	1287907360	1	
-72.69392793333333	42.34376685      	1287907420	1	
-72.69396520000001	42.34200168333333	1287907440	2	
-72.69364926666667	42.34365636666666	1287907480	1	
-72.69293845     	42.34334739999999	1287907540	1	
-72.69419445     	42.34190578333333	1287907560	2	
-72.6927022      	42.343048         	1287907600	1	
-72.69264033333334	42.34287956666667	1287907660	1	
-72.69439651666667	42.34189388333332	1287907680	2	
-72.69265161666668	42.342806         	1287907720	1	
-72.6928737      	42.34265043333333	1287907780	1	
-72.69453363333334	42.34204025      	1287907800	2	
-72.69309221666667	42.34251263333334	1287907840	1	
-72.69328463333333	42.34241403333333	1287907900	1	
-72.69470221666667	42.34222191666666	1287907920	2	
-72.69342835     	42.34232905      	1287907960	1	
-72.6935967      	42.34220988333334	1287908020	1	
-72.69501901666666	42.34270666666666	1287908040	2	
-72.69377465     	42.3421005        	1287908080	1	
-72.69396520000001	42.34200168333333	1287908140	1	
-72.69512208333333	42.34282508333334	1287908160	2	

Test Class for Trace and DiscreteEventQueue

This is a simple test class for Trace.java and DiscreteEventQueue.java. It runs a discrete event simulation on two tracks stored in .txt files containing 24 coordinate triplets with time in Unix time. The elements in the text file are separated by commas with a new line denoting the next coordinate triplet. Sample output from this program can be found here.

import java.io.File;

/**
 * 	Tests the discrete event queue.
 * 
 * 	@author Lindsey Gregor
 *	@version 23 Febraury 2011
 */
public class TestDEQ {
	/** How much the time is changing by in each step */
	private static final int DELTAT = 90;
	
	/** What time to start at */
	private static final int STARTTIME = 1287905000;
	
	public static void main(String args[]) {		
		Trace trace1 = new Trace(new File("test1.txt"),1,1);
		Trace trace2 = new Trace(new File("test2.txt"),2,2);
		
		DiscreteEventQueue queue = new DiscreteEventQueue();
		
		// First sets of coordinates
		queue.offer(trace1.getCoordinateArray());
		trace1.increment();
		
		queue.offer(trace2.getCoordinateArray());
		trace2.increment();
		
		queue.sort();
		
		// Time element which starts at STARTTIME and 
		// increments by DELTAT
		int time = STARTTIME;
		while (!queue.isEmpty()) {
			System.out.println();
			System.out.print("Time: "+time+"\t");
			while ((!queue.isEmpty())&&((int)queue.peek()[2] <= time)) {
				double[] current = queue.poll();
				// Print out the polled element of the queue
				for (int i=0; i<4; i++) {
					if ((i==2)||(i==3)) {
						System.out.print((int)current[i]+"\t");
					} else {
						System.out.print(current[i]+"\t");
					}
				}
				if (current[3] == 1) {
					if (trace1.getCoordinate() != null){
						queue.offer(trace1.getCoordinateArray());
						trace1.increment();
					}
				} else {
					if (trace2.getCoordinate() != null){
						queue.offer(trace2.getCoordinateArray());
						trace2.increment();
					}
				}
				queue.sort();
			}
			time += DELTAT;
		}
	}  // End main()
	
}  // End TestDEQ

Sample Output 2 for Discrete Event Simulation

Here is sample output from a test class testing both the Trace class and DiscreteEventQueue class. The test program ran the simulation from two .txt files containing 24 coordinate triplets where time is represented in Unix time. Elements in the discrete event queue are not polled off unless the clock matches that of the coordinate's time stamp. The output is given as time [x y t trackId]. The test class for this output can be found here.

Time: 1287905000	
Time: 1287905090	
Time: 1287905180	
Time: 1287905270	
Time: 1287905360	
Time: 1287905450	-72.6945975075		42.34444296		1287905400	2	
Time: 1287905540	-72.694356		42.34400928333333	1287905520	2	
Time: 1287905630	
Time: 1287905720	-72.69431068333333	42.34405935		1287905640	2	
Time: 1287905810	-72.69446536666666	42.34410188333333	1287905760	2	
Time: 1287905900	-72.69409073333333	42.34385796666667	1287905880	2	
Time: 1287905990	
Time: 1287906080	-72.69392793333333	42.34376685		1287906000	2	
Time: 1287906170	-72.69364926666667	42.34365636666666	1287906120	2	
Time: 1287906260	-72.69293845		42.34334739999999	1287906240	2	
Time: 1287906350	
Time: 1287906440	-72.6927022		42.343048		1287906360	2	
Time: 1287906530	-72.69264033333334	42.34287956666667	1287906480	2	
Time: 1287906620	-72.69265161666668	42.342806		1287906600	2	
Time: 1287906710	
Time: 1287906800	-72.6928737		42.34265043333333	1287906720	2	
Time: 1287906890	-72.69309221666667	42.34251263333334	1287906840	2	
Time: 1287906980	-72.69328463333333	42.34241403333333	1287906960	2	
Time: 1287907070	-72.6945975075		42.34444296		1287907000	1	
Time: 1287907160	-72.69342835		42.34232905		1287907080	2	
Time: 1287907250	-72.694356		42.34400928333333	1287907180	1	
			-72.6935967		42.34220988333334	1287907200	2	
			-72.69431068333333	42.34405935		1287907240	1	
Time: 1287907340	-72.69446536666666	42.34410188333333	1287907300	1	
			-72.69377465		42.3421005		1287907320	2	
Time: 1287907430	-72.69409073333333	42.34385796666667	1287907360	1	
			-72.69392793333333	42.34376685		1287907420	1	
Time: 1287907520	-72.69396520000001	42.34200168333333	1287907440	2	
			-72.69364926666667	42.34365636666666	1287907480	1	
Time: 1287907610	-72.69293845		42.34334739999999	1287907540	1	
			-72.69419445		42.34190578333333	1287907560	2	
			-72.6927022		42.343048		1287907600	1	
Time: 1287907700	-72.69264033333334	42.34287956666667	1287907660	1	
			-72.69439651666667	42.34189388333332	1287907680	2	
Time: 1287907790	-72.69265161666668	42.342806		1287907720	1	
			-72.6928737		42.34265043333333	1287907780	1	
Time: 1287907880	-72.69453363333334	42.34204025		1287907800	2	
			-72.69309221666667	42.34251263333334	1287907840	1	
Time: 1287907970	-72.69328463333333	42.34241403333333	1287907900	1	
			-72.69470221666667	42.34222191666666	1287907920	2	
			-72.69342835		42.34232905		1287907960	1	
Time: 1287908060	-72.6935967		42.34220988333334	1287908020	1	
			-72.69501901666666	42.34270666666666	1287908040	2	
Time: 1287908150	-72.69377465		42.3421005		1287908080	1	
			-72.69396520000001	42.34200168333333	1287908140	1	
Time: 1287908240	-72.69512208333333	42.34282508333334	1287908160	2	
			-72.69419445		42.34190578333333	1287908200	1	
Time: 1287908330	-72.69439651666667	42.34189388333332	1287908260	1	
			-72.69453363333334	42.34204025		1287908320	1	
Time: 1287908420	-72.69470221666667	42.34222191666666	1287908380	1	
Time: 1287908510	-72.69501901666666	42.34270666666666	1287908440	1	
			-72.69512208333333	42.34282508333334	1287908500	1