Interoperability

Sunday September 20, 17.43.18

A curious interoperability protocol, wherein the address for some weird place in Seoul has been found on an iPhone and must now be entered into the GPS of the taxi. A simple affair, with minimal bumps often enough, particularly because the map on the iPhone shows the address and streets in Korean, which is great for the taxi cab driver, but miserable for the the traveler who can only hope that the locale on the map is actually where he would like to be.

Why do I blog this? This are useful moments to capture, where language, culture, objects, data come into conflict and must work their way around one another. I am told the iPhone isn’t available in South Korea at the time of this photo, so you have this foreign object — one that is probably quite legible as the iPod Touch was spotted around the city — and a baroque assemblage of devices, machines, transaction mechanisms, remote controls, identity stickers, car controls, radios, etc. I would have to contrast this with the notion of seamless perfection and interoperability that is often the image of the future transportation dashboard.
Continue reading Interoperability

GPX to DXF – Drawing GPS Tracks

Sunday March 29, 13.25.20

Lines and arrows and splines point the way. Taken in a parking lot near the beaches at Santa Monica.

It has not been a quiet couple of days here in the Laboratory. Lots of gear and glassware about. Goggles, bunsen burners and all that sort of thing. And the report draft was just finished with Nicolas Nova, which occupied many early mornings. We almost spilled an organic, but toxic material on the draft which cause a collective gasp, but it was pulled out of the way, just in time before irrevocable damage was done. We’re writing with ink and pen these days, which feels so much more angelic and respectful, but are, through incidents like this, reminded that such may have nostalgic integrity, but it is also quite delicate and precious.

In the midst of all that was the need to translate a GPS track from GPX format to DXF. This was harder than I thought it would be, at least after poking around the Google. There are some tools that’ll do format conversions and so forth, but they were way more expensive than I thought was reasonable, seeing as we’re not making precious objects. It’s basically a translation of one connected graph format to another.

Okay, so — it was time to think about making our own tools, which took 10 times less time than the original set of Google searches, mostly because of the recently discovered ancient treasure of a Java library our buddy Tom Carden wrote back in the Precambian of the Age of the Network — somewhere’s around 1996 or some such…

This library provides enough functionality to read a GPX track and draw it on screen. The Processing.org DXF library can spit that drawing from the screen out as a saved DXF. So, that basically solves the problem. The DXF files that come out are flat lines that can then be serviced by other software to do other things. (There also exists this Kabeja library for consuming DXF and creating DOM models, which we’ll save for another day.

My lead toward the Carden code was found here on the Processing.org forums, where I found enough of a simple code snippet to get me out and through the chiseled hole in the brick wall I had hit.

Also to note is the small comment in the small simple bit of code that can cobble together many separate GPX files (tracks from a GPS) into one larger one, which can be quite convenient.

Why do I blog this? Mostly for my own recollection and notes as to how things are done. It’s been enough time in the jungle of small, utility challenges that, when on another project inevitably in the future, some small task I need to perform smells familiar — but, why? One gets the feeling — I’ve had to do this before? What project was it? How did I do it? Playing in the geo/map-making/cartography space has all these little formats and translation steps that are a bit zany to wrangle. Jotting a post with a bit of a reminder helps. Te bigger “why do I blog this?” has to do with using real-world GPS tracks as a basis for constructing other things — the input is movement in the world, an effort to figure out how a map might look that inverted the assumptions about static geographies and fluid movement, so that the ground moved and the things that moved became static. *shrug*


import processing.dxf.*;

// Based on Tom Carden's code and GPX library available at
// http://www.processing.org/hacks/hacks:gpx
// Press "R" and your track gets saved as a DXF file which
// you can use in lots of other things..

import tomc.gpx.*;

GPX gpx;

GPXTrack track;
GPXTrackSeg trackSeg;
String trackName;

double minLat, maxLat;
double minLon, maxLon;
double minEle, maxEle;
boolean record = false;

final static int SEPARATOR = 200;
String filename, filepath;

// I collapse lots of individual GPX files into one larger file
// using the free gpsbabel.
// At the command prompt (the GUI editions don't have enough features
// to do this) you'll do something like this:

/************

/Applications/GPSBabel+-1.3.5/gpsbabel -i gpx -f 20090321.gpx 
-f 20090401.gpx -f 20090402.gpx -f 20090403.gpx 
  -x transform,wpt=trk,del 
  -x radius,distance=5,lat=34.0236,lon=-118.4319,nosort 
  -x transform,trk=wpt,del  
  -o gpx -F foo.gpx

The "-x" filters do a couple of things.
The first -x filter turns the tracks into waypoints to work around
an issue that gpsbabel has with the "radius" filter
The second -x filters the output only to points that are within a
5 mile radius of the specified lat/lon, which is useful if you want
to limit the range of data you draw.
The final -x filter turns the waypoints back into tracks, which is what we want
Finally, we output as GPX formatted data and
write the whole thing to the file called foo.gpx.dxf


*************/

void setup()
{
  // Yep, hardcoded path to the GPX file we'll process
  filepath = "/Users/julian/Desktop/GPS Tracks/foo.gpx";
  // We'll use the name of the file for our DXF output, with the ".dxf" extension added
  filename = (new File(filepath)).getName();
  size(800, 800, P2D);
  gpx = new GPX(this);

  // you can load a file or a URL evidently..
  gpx.parse(filepath);

  // Find scope of track file so we can scale our drawing
  minLat = 2000; minLon = 2000; minEle = 100000;
  maxLon = -1000; maxLat = -1000;

  println("track count "+gpx.getTrackCount());
  for(int j=0; j < gpx.getTrackCount(); j++) {
  track = gpx.getTrack(j);
  println("track size "+track.size());
  for(int k=0; k<track.size(); k++) {
     trackSeg = track.getTrackSeg(k);
     println("track seg size "+trackSeg.size());
  for (int i = 0; i < trackSeg.size(); i++)
  {

    GPXPoint pt = trackSeg.getPoint(i);
    if (pt.lat < minLat)
    {
      minLat = pt.lat;
    }
    if (pt.lon < minLon)
    {
      minLon = pt.lon;
    }
    if (pt.ele  maxLat)
    {
      maxLat = pt.lat;
    }
    if (pt.lon > maxLon)
    {
      maxLon = pt.lon;
    }
    if (pt.ele > maxEle)
    {
      maxEle = pt.ele;
    }
  }
  }
  }
println("Lat: " + minLat + " to " + maxLat);
println("Lon: " + minLon + " to " + maxLon);
println("Ele: " + minEle + " to " + maxEle);
}

boolean hasDrawn = false;

void draw()
{
  if(record == true) {
    beginRaw(DXF, filename+".dxf");
    hasDrawn = false;
  }
  if(hasDrawn == false) {
  background(255);
  //stroke(#FF0000);
  //line(0, SEPARATOR, width, SEPARATOR);

  double distance = 0;

 for(int j=0; j < gpx.getTrackCount(); j++) {
  track = gpx.getTrack(j);
  //println("track size "+track.size());
  for(int k=0; k<track.size(); k++) {
     trackSeg = track.getTrackSeg(k);
     //println("track seg size "+trackSeg.size());
       GPXPoint prevPt = trackSeg.getPoint(0);
      PVector prevPos = GetPosition(prevPt);
      for (int i = 1; i < trackSeg.size(); i++)
      {
       GPXPoint pt = trackSeg.getPoint(i);

    // Show track
    PVector pos = GetPosition(pt);
    stroke(#FF8800);
    line(prevPos.x, prevPos.y, pos.x, pos.y);
    prevPos = pos;
  }
  }
 }
  }
  if(record == true) {
    endRaw();
    record = false; // stop recording to the file
    println("done writing "+filename+".dxf");
  }
  hasDrawn = true;
}

void keyPressed() {
  if (key == 'R' || key == 'r') {
    record = true;
  }
}

PVector GetElevation(int n, GPXPoint pt)
{
  return new PVector(
      map(n, 0, trackSeg.size(), 10, width - 10),
      map((float) pt.ele, (float) minEle, (float) maxEle, SEPARATOR - 10, 10)
  );
}

PVector GetPosition(GPXPoint pt)
{
  return new PVector(
      map((float) pt.lon, (float) minLon, (float) maxLon, 10, width - 10),
      map((float) pt.lat, (float) minLat, (float) maxLat, SEPARATOR + 10, height - 10)
  );
}

GPS 9000

271108_160253

Anticipating the less-than-lovely side of ubiquitous computing scenarios, this photo is the end point of a circuitous GPS navigation FAIL on the way to relatives for Thanksgiving dinner last week. Looks like we’re driving into the river there. After what we went through, it wouldn’t surprise me if the GPS lady sent us right on into the ol’ Housatonic.

We made it unscathed but a bit dizzy from the miscues and miscommunications that were the result of an entangled navigation assemblage of people, roads, cellular telephony and satellite location practices. Along the route from northern New Jersey to somewhere in the woods of Connecticut we ended up departing from what seemed like the correct route along a major highway, but were told to exit by the lady in the GPS box, which I did with a little bit of raised eyebrows from the cohabitants of the car, including myself. I was skeptical initially, thinking that the GPS had been misprogrammed to another set of relatives whose home was somewhere around there. So, there was that, which implied a bit of skepticism tossed at the vehicle’s copilot, which caused some tension, on top of everything else. The GPS lady sent us down a couple of surface streets that constituted a short diversion around and then immediately back onto the same highway, in the same direction, toward the same goal.

This same “bug” (or whatever..) happened again further along, with the GPS lady taking us off route, onto some surface streets to make a long U-turn and then (conveniently and fortuitously) into the parking lot of a Dunkin’ Donuts, which allowed for a bathroom break. GPS lady then told us to get back onto the same highway.

This is either real HAL 9000 style Ubicomp, a test by “the man” to see how much people will blindly listen to their GPS ladies and do ridiculous things, or a case-in-point as to how sucky these things are to begin with. By this point, we were fairly skeptical about the ability of the GPS to navigate, and the conversations turned to things like — maybe the maps need to be updated and questions about Amazon’s return policy. Things like that. Meanwhile, alternative mechanisms were deployed to further entangle the navigation process — iPhones were fingered, alternative routes suggested, questions were raised about the fitness of one biway over another roughly parallel highway, calls were made to discuss alternatives and readjust anticipated arrival times, conversations on phone calls were taken as Gospel directions when they were really questions to the person on the other end (who couldn’t be heard except by the caller — as in “Take a left at the bridge.”, which really was “Take a left at the bridge?” and so a left was taken at the bridge, etc.) Confusion ensued (big time) as navigation became a group activity, which seems entirely a bad idea under even the most pleasant of circumstances. In summary — the same old sort of people-practices that have always gone into navigation and mobility practices, despite the GPS lady and her fancy tricks.

Why do I blog this?Another in a series of observations about the failure of technical instruments like GPS’s were meant to ameliorate, with a bit of cynacism towards the Ubicomp pink pony dream. Despite the dream and vision of fancy-futures, the entanglement of humans and non-humans into a knotted cooperative does not look like the advertising literature and product descriptions.
Continue reading GPS 9000

Manhole Compass

A functionally-decorative manhole cover that emulates the features of a compass rose for those who care not to navigate by dead-reckoning, rather feature or landmark-reckoning. I know these are all over the place, the image of it summoned up a recent conversation about how much built-in navigation cities should provide. The pro-argument being that it helps tourists to get around a city when they don’t have the vernacular, experienced wayfinding abilities of a native or someone who has had time to acclimate and grow accustom to the nuances of what is where. The con-argument is that these sorts of waypoints and navigation aids makes cities over mapped, removing the unexpected encounter that can only happen when you’re lost, or eroding the experience and feeling of becoming “native” and used to a city’s ways on ones own.

GPS Experiment

I can see something in each perspective, although I would generally prefer to leave a little more to chance when navigating a city. This photo is of me in Tokyo, 2005 after I managed to get a Tokyo map uploaded to my Garmin GPS. I had absolutely 0% navi experience in Tokyo and was pretty sure I’d get completely lost, which I did on an occasion or two, but was able to rely on the GPS to get me back on track. (There were no navigation features, just top-down POV and compass.) I’m certain it changed the experience, but there was not a whole lot left to rely upon besides my own wits and my trusty Tokyo City Bilingual Atlas.

Continue reading Manhole Compass

Pre-Columbian Internet Geography

This photograph is my second “Truman Show” moment, near the end of day four of walking the Inca Trail, with this bit of exposed infrastructure along the seam where mountain meets trail. An abrupt reminder that the trail is maintained in the contemporary sense, pretty much exclusively for visitors using it as I was — to have a nice if a bit grueling four day trek through the Andes. (Likely this bit of electrical plumbing ran power and communications between a restaurant/lodge a few kilometers from the final “Sun Gate” milestone.)

The trail was presumed built by order of an Inca back in the day to allow for a proper system of communicating messages as well as goods. It connected all of the villages throughout the Empire, which extended throughout what is now Peru, as well as today’s Bolivia, Ecuador, Chile and Argentina.

It’s often described as a road system, but the Near Future Laboratory can only grok it as a larger system of communication very much like today’s Internet, mostly because of the mechanics of its formal protocols. It was not just something for one to walk along to get from point A to point B. It’s possible to speculate that it was built as a way of adhering social / power relations, creating an assemblage that included royal (the Inca King) control through messaging, maintaining control over borders, dispersing warriors and their power, transporting food, routing vital water along its intricate right-of-way. The protocol allowed for a system of runners operating in relay moving impossibly fast along the trail.

Every four years a race is held, running the trail from kilometer 82 to Machu Picchu, about 45 kilometers total. The current record time? 3 hours and 12 minutes. Today, it’s traveled by at most 500 people a day so that, for the typical 4 day trek, you’re on the trail with 2000 other people. (Only near the beginning at kilometer 82 did it appear to be bustling. Along the way, it was only occasionally that we ran into other people.)

Related:
A Google Earth KML file of the trek, recorded along the way with a GPS device.

Continue reading Pre-Columbian Internet Geography