CSC400 Code - Smith Walk Project
Contents
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