Wednesday, 11 July 2012

Pre-process GPS data in Processing





For the last couple of days I've been wrestling with making GPS data from phones etc into a useable form, using data such as :




<trkpt lat="51.5171129"
lon="-0.1776164">
<ele>30.999</ele>
<trkpt lat="31.5171129"
 lon="-0.6776164">
<ele>30.999</ele>
<trkpt lat="59.5171129"
lon="-0.5776164">
<ele>30.999</ele>
<trkpt lat="54.5171129"
lon="-0.5476164">
<ele>30.949</ele>
<time>2012-05-20T12:49:11.961Z</time>


which may not be on new lines, as above, but needs to be. The first useful program I've written uses regex (regular expressions) to get rid of the unwanted stuff and just grab the decimal values, which are printed to a file called gps.txt, which will be used in the program below this to map nicely to a Processing window.




/*
Read in raw GPS and print it as just decimal numbers
 Press any key to save it
 Dare July 2012


 */


PrintWriter output;
String[] lines;
String[] lines2;
String[] gps1;
int index = 0;
String strippedString, whole;
void setup() {
  size(200, 500);
  background(0);
  stroke(255);
  frameRate(12);
  output = createWriter("gps.txt");
  lines = loadStrings("data.txt");
}




void draw() {
  noLoop();
  smooth();
  background(0);
  if (index < lines.length) {
    String[] pieces = split(lines[index], "\n");
    String[] lines2 = new String[lines.length];
    for (int i =0;i<lines.length;i++) {
      lines2[i] =lines[i];
      println(getNumber(lines2[i]));
      String[] gps = new String[lines2.length];
      gps[i]=lines2[i];
      text(getNumber(lines2[i]), 20, 20+i*20);
      output.println(getNumber(lines2[i]) + "");
    }
  }
}






//use regex to get the decimal numbers:
String getNumber(String str) {
  Pattern pattern = Pattern.compile("\\b(\\d+)\\.(\\d+)\\b");


  Matcher matcher = pattern.matcher(str);
  String number = "";
  while (matcher.find ()) {


    number =matcher.group();
  }
  return number;
}




void keyPressed() { // Press a key to save the data


  output.flush(); // Write the remaining data
  output.close(); // Finish the file
  exit(); // Stop the program
}
//end

The second program then gets the longitude and latitude values only (though it could get the elevations as well) finds their minimum and maximum values and then maps them to the window size:


/*get the gps data (once it has been re-formatted in our other program 'convertGPS')
 get the mins and max values ofr longitude and latitude and map to new values
 */

float[] as, lon, lat;
float x, y;
ArrayList thatXPos = new ArrayList(); //array for X lat
ArrayList thatYPos = new ArrayList(); //array for Y long

float lonMax, lonMin, latMax, latMin; //to be our min and max values

void setup() {
  size(600, 400);
  as = float(loadStrings("gps.txt")); /*create thsi file in 'convertGPS.pde */
  background(0);
}


void draw() {
  // background(255);

  ///you might have to adjust start and ends but this seems to work
  for (int i =0;i<as.length-3;i+=3) { //all the latitude every 3rd
    thatXPos.add(as[i]);
  }

  ///you might have to adjust start and ends but this seems to work
  for (int i =1;i<as.length-2;i+=3) { //all the  Y longitude
    thatYPos.add(as[i]);
  }


  int len = thatXPos.size();
  int len2 = thatYPos.size();
  Float[] fa = new Float[len];
  Float[] fa2 = new Float[len2];
  float[] xPosCount = new float[len];
  float[] yPosCount = new float[len2];
  thatXPos.toArray(fa);
  thatYPos.toArray(fa2);


  for (int i =0;i< len; i++) {

    xPosCount[i] = fa[i];
  } 

  for (int i =0;i< len2; i++) {

    yPosCount[i] = fa2[i];
  } 


//apologies for stupid naming! :-S
  lonMax =max(xPosCount); //names are stupid, got head in a twist with lat and long
  lonMin =min(xPosCount); //actually latitude, but doesn't matter as is a name only
  latMax =max(yPosCount); //actually longitude
  latMin =min(yPosCount);


  for (int i = 0; i < len; i++) {

    x =xPosCount[i];
    y =yPosCount[i];

    //use the minimums and maximums to calculate map()
    float x1= map(x, lonMin, lonMax, 40, width-50);
    float y2= map(y, latMin, latMax, 40, height-50);

    fill(255, 0, 0);
    ellipse(x1, y2, 10, 10);
    //print(" *"+x1 + " "+y2);
  }
}
////end

No comments:

Post a Comment