So this should be an easy enough problem to solve but I am having trouble with a project I have been working on for some time. This bit of code is from a larger project but it is where I am getting hung up. I can tell the while loop is incrementing through my data-set as I would expect but I am not resulting in a video as I would expect. I end up with a video in which all the frames are empty even though places[g].draw exports a picture of the map I would expect.
I am new to processing and coding really so if there is any other information I should provide please let me know. I have been working on this project for a while and feel like I am close, I just need this last step.
Any help appreciated. Thanks to everyone who participates on this forum.
public void draw(){ int i = 1; int d = 1; int gap; background(000); image(mapImage, 0, 0);
//while i is smaller than the number of lines in my dataset while (i < (numLines-2)){
//gap is equal to the number of days between one record and the next gap = Math.round(places[i].days) - Math.round(places[i-1].days);
//if the day placeholder changed from one record to the next than draw a dot for every lat long in dataset //from the beginning of the data-set to the current record and export as frame, repeat for the number of days //that elapsed from the last record (gap) if (gap != 0) { while (0 < gap) { for (int g = 0; g < i; g++){ places[g].draw(); } mm.addFrame(); System.out.println("gap izz " + gap + " days izz: " + Math.round(places[i].days) + " i izz: " + i); gap--; } i++; } else { i++; } mm.finish(); noLoop(); } }
I have been trying to create a video mapping location data tagged with dates. I have the dataset such that it is in order by date and I am trying to write a loop that will iterate down my text file:
check to see if the next date < than the current one
if it is count the number of days difference between the two
draw the point associated with that date and all previous ones as a map
send that drawing as a frame to a video file by the number days difference calculated in step 2 (to reflect that a number of days passed with no event)
I feel that my code is almost complete but I wrote a nested loop to do this and it has been giving me trouble. The code I wrote follows with the troublesome bits highlighted yellow. Any suggestions?
PImage mapImage; //column numbers in data file (cleanT.tsv) static final int UID = 0; static final int Y = 1; static final int X = 2; static final int LATITUDE = 3; static final int LONGITUDE = 4; static final int DATE = 5; static final int OCCURANCE = 6; static final int DAYS = 7;
Date days;//initialize days date float spanDays; //initialize in to hold number of days from first tea party to most recent
int totalCount; //total number of meetings Place[] places; int placeCount;//number of places loaded
//min, max boundary of all points float minX, maxX; float minY, maxY; float mapX1, mapY1; float mapX2, mapY2;
//initialize beginDate and endDate String beginDate; String endDate; int totLines;
public void setup(){ size(1039, 725, P3D); mapImage = loadImage("ContiguousUS_albers.png");//load image of us exported from ArcGIS mapX1 = 65; mapX2 = width - mapX1; mapY1 = 87; mapY2 = height - mapY1; totLines = readData(); System.out.println(totLines); mm = new MovieMaker(this,width,height,"Tparties8.mov",30,MovieMaker.H263,MovieMaker.LOSSLESS); }
public int readData(){ String[] lines = loadStrings("cleanTcontigUSb.tsv"); totlLines = lines.length; parseInfo(lines[0], totLines);//read the header line places = new Place[totalCount]; System.out.println(lines.length); for(int i = 1; i < lines.length; i++){ places[placeCount] = parsePlace(lines[i]); placeCount++; } return totlLines;}
void parseInfo(String line, int totlLines){ // Date days; //intitialize Date object to use in getting milli since epoch float beginMilli; //initialize integer to place number of milliseconds in loop float endMilli; DateFormat formatter; formatter = new SimpleDateFormat("MM/dd/yyyy"); //fomatter to use in the loop to parse the string date to a date object
int uid = int(pieces[UID]); float y = float(pieces[Y]); float x = float(pieces[X]); String dateString = pieces[DATE]; int occurance = int(pieces[OCCURANCE]); float days = float(pieces[DAYS]); return new Place(uid, x , y, dateString, occurance, days); }
public void draw(){ int i = 1; int d = 1; float gap; background(000); image(mapImage, 0, 0); while (i < totlLines){ gap = places[i+1].days - places[i].days; if (gap >= 1) { while (0 < gap) { for (int g = 0; g < i; g++){ places[i].draw(); } mm.addFrame(); gap--; } i++; } else { i++; { mm.finish(); }
I have been trying to write a sketch that will increment over a dataset and progressively map events so that I can stitch them together. Before I do that I am trying to read through a csv and convert date strings to Date objects so that I can store the dates as a uniform number (like number of days since some set time). This will allow me to read the begin date of the file and the end date and help me increment through the data. Having read through some documentation on JavaScript date handling libraries I am a bit frustrated as I cant seem to make what seems like it should be easy work.
Here is my code, it is long but the important part is just the small bit that is highlighted. If anybody has any suggestions I would be immensely grateful.
//split the row into pieces allong each comma String[] firstLine = split(lines[1], '\t'); scrubQuotes(firstLine); //remove extra whitespace on either side of each column firstLine = trim(firstLine); String beginDate = firstLine[DATE];
//split the row into pieces allong each comma String[] endLine = split(lines[(lines.length-1)], '\t'); scrubQuotes(endLine); //remove extra whitespace on either side of each column endLine = trim(endLine); String endDate = endLine[DATE];
//set min and max values arbitrarily high float minX = 1; float maxX = -1; float minY = 1; float maxY = -1;
//set up an array for the cleaned data String[] cleaned = new String[lines.length]; //number of cleaned entries found int placeCount = 0;
//Start at row 1 because the first row is the column titles. for (int row = 1; row < lines.length; row++){ //split the row into pieces allong each comma String[] data = split(lines[row], '\t'); scrubQuotes(data); //remove extra whitespace on either side of each column data = trim(data); // here is where I am trying to parse date[DATE] (a text string) into a date object so that I can store the //dates value as a number of continuous days since ?epoch? later on when I print to a text file. cant seem to //make it work though it seems like it should be easy. I hate the way javascript handles dates. Really //frustrating. I would be enormously grateful for any help anyone could confer. DateFormat formatter ; Date days; try {
formatter = new SimpleDateFormat("MM/dd/yyyy"); days = formatter.parse(data[DATE]); } catch (ParseException e)
//exclude meetings in non-contiguous US States (hawaii/alaska) float longitude = Float.parseFloat(data[LONGITUDE]); if (longitude < -127) continue;
float lat = float(data[LATITUDE]); float lon = float(data[LONGITUDE]);
//write to a file called "cleanT.tsv" in the sketch folder PrintWriter tsv = createWriter("cleanTcontigUSb.tsv");
//use the first line to specify the number of data points in the file, //allong with the minimum and maximum lat and long using //# to make the line as different from the other ones. tsv.println("#" + placeCount + "," + minX + "," + maxX + "," + minY + "," + maxY + "," + beginDate + "," + endDate);
for (int i = 0; i < placeCount; i++) { tsv.println(cleaned[i]); }
tsv.flush(); tsv.close();
println("Finished."); exit(); }
// Parse quotes from CSV or TSV data. Quotes areound a column are common, //and actual double quotes (") are specified by two double quotes("") void scrubQuotes(String[] array){ for (int i = 0; i < array.length; i++){ if (array[i].length() > 2){ //Remove quotes from start and end if present if(array[i].startsWith("\"") && array[i].endsWith("\"")){ array[i] = array[i].substring(1, array[i].length() - 1); } } array[i] = array[i].replaceAll("\"\"", "\""); } } String fixCapitals(String title) { char[] text = title.toCharArray(); //If set to true, the next letter will nbe capitalized. boolean capitalizeNext = true; for (int i = 0; i < text.length; i++) { if(Character.isSpace(text[i])) { capitalizeNext = true; } else if (capitalizeNext) { text[i] = Character.toUpperCase(text[i]); capitalizeNext = false; } else { text[i] = Character.toLowerCase(text[i]); } } return new String(text); }
//column numbers in data file (cleanT.tsv)
static final int UID = 0;
static final int Y = 1;
static final int X = 2;
static final int LATITUDE = 3;
static final int LONGITUDE = 4;
static final int DATE = 5;
static final int OCCURANCE = 6;
int totalCount; //total number of meetings
Place[] places;
int placeCount;//number of places loaded
//min, max boundary of all points
float minX, maxX;
float minY, maxY;
public void setup(){
readData();
}
void readData(){
String[] lines = loadStrings("cleanT.tsv");
parseInfo(lines[0]);//read the header line
places = new Place[totalCount];
for(int i = 1; i < lines.length; i++){
places[placeCount] = parsePlace(lines[i]); //keeps getting hung up here (ArrayIndexOutOfBoundsException:948)
placeCount++;
}
}
void parseInfo(String line){
String infoString = line.substring(2); //remove the #
String[] infoPieces = split(infoString, ',');
totalCount = int(infoPieces[0]);
minX = float(infoPieces[1]);
maxX = float(infoPieces[2]);
minY = float(infoPieces[3]);
maxY = float(infoPieces[4]);
}
Place parsePlace(String line){
String pieces[] = split(line,TAB);
int uid = int(pieces[UID]);
float y = float(pieces[Y]);
float x = float(pieces[X]);
String date = pieces[DATE];
int occurance = int(pieces[OCCURANCE]);
return new Place(uid, x , y, date, occurance);
}
//This code is essentially copied right out of Visualizing Data the O'Reilly processing book. I am just trying to implement it //with my own data and I keep getting hung up when trying to load the data. Anybody have any suggestions as to what //might be going on here? I have highlighted where it gets hung up