diff --git a/src/Lib/e00/Makefile.am b/src/Lib/e00/Makefile.am
new file mode 100644
index 00000000..25e97f1e
--- /dev/null
+++ b/src/Lib/e00/Makefile.am
@@ -0,0 +1,10 @@
+noinst_LIBRARIES = libe00.a
+
+libe00_a_SOURCES = e00.cxx e00.hxx
+
+noinst_PROGRAMS = teste00
+
+teste00_SOURCES = teste00.cxx
+teste00_LDADD = libe00.a
+
+
diff --git a/src/Lib/e00/e00.cxx b/src/Lib/e00/e00.cxx
new file mode 100644
index 00000000..98abd804
--- /dev/null
+++ b/src/Lib/e00/e00.cxx
@@ -0,0 +1,608 @@
+// e00.cxx: implementation of ArcInfo (e00) reader.
+
+#include "e00.hxx"
+
+#include <vector>
+#include <map>
+#include <string>
+#include <iostream>
+#include <cctype>
+
+#include <stdio.h>
+
+using std::vector;
+using std::map;
+using std::string;
+using std::istream;
+using std::cerr;
+using std::endl;
+
+
+////////////////////////////////////////////////////////////////////////
+// Static helper functions.
+////////////////////////////////////////////////////////////////////////
+
+static void
+append (string &s, int i)
+{
+  char buf[128];
+  sprintf(buf, "%d", i);
+  s += buf;
+}
+
+static void
+append (string &s, double f)
+{
+  char buf[128];
+  sprintf(buf, "%f", f);
+  s += buf;
+}
+
+static void
+skipWhitespace (istream &input)
+{
+  char c;
+  input.get(c);
+  while (isspace(c)) {
+    input.get(c);
+  }
+  input.putback(c);
+}
+
+static void
+readStringItem (istream &input, string &line, int width)
+{
+  char c;
+  
+  skipWhitespace(input);
+  line.resize(0);
+  
+  for (int i = 0; i < width; i++) {
+    input.get(c);
+    if (c == '\n' || c == '\r')	// premature termination
+      return;
+    else
+      line += c;
+  }
+}
+
+static void
+checkPrecision (istream &input)
+{
+  int i;
+
+  input >> i;
+  if (i != 2 && i != 3)
+    throw E00Exception("Unknown precision");
+}
+
+static void
+checkZeros (istream &input)
+{
+  int i, j;
+
+  for (i = 0; i < 6; i++) {
+    input >> j;
+    if (j != 0)
+      throw E00Exception("Expected -1 followed by six zeros");
+  }
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+// Implementation of E00
+////////////////////////////////////////////////////////////////////////
+
+
+E00::E00 ()
+{
+}
+
+
+E00::~E00 ()
+{
+}
+
+
+void
+E00::expect (int i)
+{
+  int in;
+  *_input >> in;
+  if (in != i) {
+    string message = "Expected ";
+    append(message, i);
+    throw E00Exception(message.c_str());
+  }
+}
+
+void
+E00::expect (double f)
+{
+  double in;
+  *_input >> in;
+  if (in != f) {
+    string message = "Expected ";
+    append(message, f);
+    throw E00Exception(message.c_str());
+  }
+}
+
+void
+E00::expect (const char * s)
+{
+  string in;
+  *_input >> in;
+  if (in != s) {
+    string message = "Expected ";
+    message += s;
+    throw E00Exception(message.c_str());
+  }
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+// XML output.
+////////////////////////////////////////////////////////////////////////
+
+static void
+writeVertex (ostream &output, double x, double y)
+{
+  output << "<v x=\"" << x << "\" y=\"" << y << "\"/>" << endl;
+}
+
+void
+E00::write (ostream &output) const
+{
+  output << "<?xml version=\"1.0\"?>" << endl << endl;
+  output << "<GIS>" << endl << endl;
+
+  if (arc_section.size() == 0) {
+    for (int i = 0; i < (int)lab_section.size(); i++) {
+      output << "<point>" << endl;
+      writeVertex(output, lab_section[i].coord.x, lab_section[i].coord.y);
+      output << "</point>" << endl << endl;
+    }
+  }
+
+  for (int i = 0; i < (int)arc_section.size(); i++) {
+    const e00ARC &arc = arc_section[i];
+    if (!arc.inPolygon) {
+      output << "<line>" << endl;
+      for (int j = 0; j < (int)arc.coordinates.size(); j++) {
+	writeVertex(output, arc.coordinates[j].x, arc.coordinates[j].y);
+      }
+      output << "</line>" << endl << endl;;
+    }
+  }
+
+				// NB: skip enclosing poly
+  for (int i = 1; i < (int)pal_section.size(); i++) {
+    const e00PAL &pal = pal_section[i];
+    output << "<polygon>" << endl;
+    for (int j = 0; j < pal.numArcs; j++) {
+      bool isReversed = false;
+      int arcNum = pal.arcs[j].arcNum;
+      if (arcNum < 0) {
+	arcNum = 0 - arcNum;
+	isReversed = true;
+      }
+      const e00ARC &arc = arc_section[arcNum];
+      output << "<arc coverage=\"" << arc.coverageId << "\">" << endl;
+      if (isReversed) {
+	for (int k = arc.numberOfCoordinates - 1; k >= 0; k--) {
+	  writeVertex(output, arc.coordinates[k].x, arc.coordinates[k].y);
+	}
+      } else {
+	for (int k = 0; k < arc.numberOfCoordinates; k++) {
+	  writeVertex(output, arc.coordinates[k].x, arc.coordinates[k].y);
+	}
+      }
+      output << "</arc>" << endl;
+    }
+    output << "</polygon>" << endl << endl;
+  }
+
+  output << "</GIS>" << endl;
+}
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////
+// Public query methods.
+////////////////////////////////////////////////////////////////////////
+
+int
+E00::nPoints () const
+{
+  return lab_section.size();
+}
+
+int
+E00::nLines () const
+{
+  return lineArcs.size();
+}
+
+int
+E00::nPolygons () const
+{
+  return pal_section.size();
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+// Reader.
+////////////////////////////////////////////////////////////////////////
+
+void
+E00::readE00 (istream &input)
+{
+  string token;
+
+  _input = &input;
+
+  readHeader();
+
+  while (!_input->eof()) {
+
+    *_input >> token;
+
+    if (token == "ARC") {
+      readARC();
+    } else if (token == "CNT") {
+      readCNT();
+    } else if (token == "LAB") {
+      readLAB();
+    } else if (token == "LOG") {
+      readLOG();
+    } else if (token == "PAL") {
+      readPAL();
+    } else if (token == "PRJ") {
+      readPRJ();
+    } else if (token == "SIN") {
+      readSIN();
+    } else if (token == "TOL") {
+      readTOL();
+    } else if (token == "IFO") {
+      readIFO();
+    } else if (token == "EOS") {
+      postProcess();
+      return;
+    } else {
+      cerr << "Skipping unknown section type " << token << endl;
+      readUnknown();
+    }
+  }
+
+  throw E00Exception("File ended without EOS line");
+}
+
+
+/**
+ * Read the header of an E00 file.
+ */
+void
+E00::readHeader ()
+{
+  expect("EXP");
+  expect(0);
+  *_input >> pathName;
+}
+
+
+/**
+ * Read the ARC section of an E00 file.
+ */
+void
+E00::readARC ()
+{
+  e00ARC arc;
+  e00Coord coord;
+
+  checkPrecision(*_input);
+
+  *_input >> arc.coverageNum;
+  while (arc.coverageNum != -1) {
+    arc.inPolygon = false;
+    *_input >> arc.coverageId;
+    *_input >> arc.fromNode;
+    *_input >> arc.toNode;
+    *_input >> arc.leftPolygon;
+    *_input >> arc.rightPolygon;
+    *_input >> arc.numberOfCoordinates;
+    arc.coordinates.resize(0);
+    for (int i = 0; i < arc.numberOfCoordinates; i++) {
+      *_input >> coord.x;
+      *_input >> coord.y;
+      arc.coordinates.push_back(coord);
+    }
+    arc_section.push_back(arc);
+    *_input >> arc.coverageNum;
+  }
+
+  checkZeros(*_input);
+}
+
+
+/**
+ * Read the CNT section of an E00 file.
+ */
+void
+E00::readCNT ()
+{
+  e00CNT cnt;
+  int label;
+
+  checkPrecision(*_input);
+
+  *_input >> cnt.numLabels;
+
+  while (cnt.numLabels != -1) {
+    *_input >> cnt.centroid.x;
+    *_input >> cnt.centroid.y;
+    for (int i = 0; i < cnt.numLabels; i++) {
+      *_input >> label;
+      cnt.labels.push_back(label);
+    }
+    cnt_section.push_back(cnt);
+    *_input >> cnt.numLabels;
+  }
+
+  checkZeros(*_input);
+}
+
+
+void
+E00::readLAB ()
+{
+  e00LAB lab;
+
+  checkPrecision(*_input);
+  *_input >> lab.coverageId;
+  *_input >> lab.enclosingPolygon;
+  *_input >> lab.coord.x;
+  *_input >> lab.coord.y;
+  while (lab.coverageId != -1) {
+    *_input >> lab.box1.x;	// obsolete
+    *_input >> lab.box1.y;	// obsolete
+    *_input >> lab.box2.x;	// obsolete
+    *_input >> lab.box2.y;	// obsolete
+    lab_section.push_back(lab);
+    *_input >> lab.coverageId;
+    *_input >> lab.enclosingPolygon;
+    *_input >> lab.coord.x;
+    *_input >> lab.coord.y;
+  }
+}
+
+
+void
+E00::readLOG ()
+{
+  e00LOG log;
+  string line;
+
+  checkPrecision(*_input);
+  getline(*_input, line);
+  while (line.find("EOL") != 0) {
+
+    if (line[0] == '~') {
+      log_section.push_back(log);
+      log.lines.resize(0);
+    } else {
+      log.lines.push_back(line);
+    }
+
+    getline(*_input, line);
+  }
+}
+
+
+void
+E00::readPAL ()
+{
+  e00PAL pal;
+  e00PAL::ARC arc;
+
+  checkPrecision(*_input);
+  *_input >> pal.numArcs;
+  while (pal.numArcs != -1) {
+    *_input >> pal.min.x;
+    *_input >> pal.min.y;
+    *_input >> pal.max.x;
+    *_input >> pal.max.y;
+    pal.arcs.resize(0);
+    for (int i = 0; i < pal.numArcs; i++) {
+      *_input >> arc.arcNum;
+      *_input >> arc.nodeNum;
+      *_input >> arc.polygonNum;
+      pal.arcs.push_back(arc);
+    }
+
+    pal_section.push_back(pal);
+    *_input >> pal.numArcs;
+  }
+
+  checkZeros(*_input);
+}
+
+
+void
+E00::readPRJ ()
+{
+  e00PRJ prj;
+  string line;
+
+  checkPrecision(*_input);
+  getline(*_input, line);
+  while (line.find("EOP") != 0) {
+
+    if (line[0] == '~') {
+      prj_section.push_back(prj);
+      prj.lines.resize(0);
+    } else {
+      prj.lines.push_back(line);
+    }
+
+    getline(*_input, line);
+  }
+}
+
+
+void
+E00::readSIN ()
+{
+  string line;
+  checkPrecision(*_input);
+  getline(*_input, line);
+  while (line.find("EOX") != 0) {
+    getline(*_input, line);
+  }
+}
+
+
+void
+E00::readTOL ()
+{
+  e00TOL tol;
+
+  checkPrecision(*_input);
+  *_input >> tol.type;
+  while (tol.type != -1) {
+    *_input >> tol.status;
+    *_input >> tol.value;
+    tol_section.push_back(tol);
+    *_input >> tol.type;
+  }
+
+  checkZeros(*_input);
+}
+
+
+void
+E00::readIFO ()
+{
+  e00IFO ifo;
+  e00IFO::ItemDef def;
+  e00IFO::Entry entry;
+  string line;
+  int intval;
+  double realval;
+
+  checkPrecision(*_input);
+
+  *_input >> ifo.fileName;
+  while (ifo.fileName.find("EOI") != 0) {
+
+				// 'XX' may be absent
+    *_input >> ifo.isArcInfo;
+    if (ifo.isArcInfo == "XX") {
+      *_input >> ifo.numItems;
+    } else {
+      ifo.numItems = atoi(ifo.isArcInfo.c_str());
+      ifo.isArcInfo = "";
+    }
+    *_input >> ifo.altNumItems;
+    *_input >> ifo.dataRecordLength;
+    *_input >> ifo.numDataRecords;
+
+				// Read the item definitions
+    ifo.defs.resize(0);
+    for (int i = 0; i < ifo.numItems; i++) {
+      *_input >> def.itemName;
+      *_input >> def.itemWidth;
+      expect(-1);
+      *_input >> def.itemStartPos;
+      expect(-1);
+      def.itemStartPos -= 4;
+      def.itemStartPos /= 10;
+      *_input >> def.itemOutputFormat[0];
+      *_input >> def.itemOutputFormat[1];
+      *_input >> def.itemType;
+      expect(-1);
+      expect(-1);
+      expect(-1);
+      *_input >> def.seqId;
+      ifo.defs.push_back(def);
+      getline(*_input, line);
+    }
+
+				// Read the data records
+    ifo.entries.resize(0);
+    for (int i = 0; i < ifo.numDataRecords; i++) {
+      entry.resize(0);
+      for (int j = 0; j < ifo.numItems; j++) {
+	line.resize(0);
+	string &type = ifo.defs[j].itemType;
+	if (type == "20-1") {	// character field
+	  readStringItem(*_input, line, ifo.defs[j].itemOutputFormat[0]);
+	} else if (type == "50-1") { // integer
+	  *_input >> intval;
+	  append(line, intval);
+	} else if (type == "60-1") { // real number
+	  *_input >> realval;
+	  append(line, realval);
+	} else {		// assume integer
+	  cerr << "Unknown IFO item type '30-1': assuming integer" << endl;
+	  *_input >> intval;
+	  append(line, intval);
+	}
+	entry.push_back(line);
+      }
+      ifo.entries.push_back(entry);
+    }
+
+    ifo_section.push_back(ifo);
+    *_input >> ifo.fileName;
+  }
+}
+
+
+void
+E00::readUnknown ()
+{
+  string line;
+  getline(*_input, line);
+  while (line.find("EOX") != 0) {
+    getline(*_input, line);
+  }
+}
+
+
+void
+E00::postProcess ()
+{
+
+				// Flag the arcs so that we know what is
+				// and isn't part of a polygon.
+  for (int i = 0; i < (int)pal_section.size(); i++) {
+    e00PAL &pal = pal_section[i];
+    for (int j = 0; j < (int)pal.arcs.size(); j++) {
+      int arcNum = pal.arcs[j].arcNum;
+      if (arcNum >= (int)arc_section.size()) {
+	cerr << "Polygon includes non-existent arc " << arcNum << endl;
+      } else {
+	arc_section[arcNum].inPolygon = true;
+      }
+    }
+  }
+
+				// Now, check which arcs aren't flagged
+				// and assign them to the appropriate
+				// lists.
+  for (int i = 0; i < (int)arc_section.size(); i++) {
+    e00ARC &arc = arc_section[i];
+    if (!arc.inPolygon) {
+	lineArcs.push_back(&arc);
+    }
+  }
+
+}
+
+// end of e00.cxx
diff --git a/src/Lib/e00/e00.hxx b/src/Lib/e00/e00.hxx
new file mode 100644
index 00000000..07f2f757
--- /dev/null
+++ b/src/Lib/e00/e00.hxx
@@ -0,0 +1,190 @@
+#include <vector>
+#include <map>
+#include <string>
+#include <iostream>
+
+using std::vector;
+using std::map;
+using std::string;
+using std::istream;
+
+struct E00Exception
+{
+  E00Exception (const char * msg) : message(msg) {}
+  string message;
+};
+
+
+// A coordinate in two-dimensional space.
+
+struct e00Coord
+{
+  double x;
+  double y;
+};
+
+
+// Arc Coordinates and Topology
+
+struct e00ARC
+{
+  bool inPolygon;
+  int coverageNum;
+  int coverageId;
+  int fromNode;
+  int toNode;
+  int leftPolygon;
+  int rightPolygon;
+  int numberOfCoordinates;
+  vector<e00Coord> coordinates;
+};
+
+
+// Polygon Centroid Coordinates
+
+struct e00CNT
+{
+  int numLabels;
+  e00Coord centroid;
+  vector<int> labels;
+};
+
+
+// Label Point Coordinates and Topology
+
+struct e00LAB
+{
+  int coverageId;
+  int enclosingPolygon;
+  e00Coord coord;
+  e00Coord box1;		// obsolete
+  e00Coord box2;		// obsolete
+};
+
+
+// Coverage History
+
+struct e00LOG
+{
+  vector<string> lines;
+};
+
+
+// Polygon Topology
+
+struct e00PAL
+{
+  struct ARC
+  {
+    int arcNum;
+    int nodeNum;
+    int polygonNum;
+  };
+  int numArcs;
+  e00Coord min;
+  e00Coord max;
+  vector<ARC> arcs;
+};
+
+
+// Projection Parameters
+
+struct e00PRJ
+{
+  vector<string> lines;
+};
+
+
+// Tolerance Type
+
+struct e00TOL
+{
+  int type;
+  int status;
+  double value;
+};
+
+
+// Info Files
+
+struct e00IFO
+{
+  struct ItemDef 
+  {
+    string itemName;
+    int itemWidth;		// followed by -1
+    int itemStartPos;		// followed by 4-1
+    int itemOutputFormat[2];
+    string itemType;
+    // -1
+    // -1-1
+    string seqId;
+  };
+  typedef vector<string> Entry;
+  string fileName;
+  string isArcInfo;
+  int numItems;
+  int altNumItems;
+  int dataRecordLength;
+  int numDataRecords;
+  vector<ItemDef> defs;
+  vector<Entry> entries;
+};
+
+
+// ARCInfo file
+
+class E00 {
+public:
+
+  E00 ();
+  virtual ~E00 ();
+
+  virtual void readE00 (istream &input);
+
+  virtual string getPathName () const { return pathName; }
+
+  virtual int nPoints () const;
+  virtual int nLines () const;
+  virtual int nPolygons () const;
+
+  virtual const e00ARC * getPoint (int i) const { return pointArcs[i]; }
+  virtual const e00ARC * getLine (int i) const { return lineArcs[i]; }
+
+  virtual void write (ostream &output) const;
+
+private:
+
+  vector<const e00ARC *> pointArcs;
+  vector<const e00ARC *> lineArcs;
+
+  string pathName;
+  vector<e00ARC> arc_section;
+  vector<e00CNT> cnt_section;
+  vector<e00LAB> lab_section;
+  vector<e00LOG> log_section;
+  vector<e00PAL> pal_section;
+  vector<e00PRJ> prj_section;
+  vector<e00TOL> tol_section;
+  vector<e00IFO> ifo_section;
+
+  istream * _input;
+
+  void expect (int i);
+  void expect (double f);
+  void expect (const char * s);
+
+  void postProcess ();
+
+  void readHeader ();
+  void readARC ();
+  void readCNT ();
+  void readLAB ();
+  void readLOG ();
+  void readPAL ();
+  void readPRJ ();
+  void readSIN ();
+  void readTOL ();
+  void readIFO ();
+  void readUnknown ();
+};
diff --git a/src/Lib/e00/teste00.cxx b/src/Lib/e00/teste00.cxx
new file mode 100644
index 00000000..af13d7a4
--- /dev/null
+++ b/src/Lib/e00/teste00.cxx
@@ -0,0 +1,30 @@
+
+#include <fstream>
+#include "e00.hxx"
+
+using std::ifstream;
+
+int main (int ac, const char ** av)
+{
+  for (int i = 1; i < ac; i++) {
+    cerr << "Reading " << av[i] << endl;
+    ifstream input(av[i]);
+    E00 data;
+    try {
+      data.readE00(input);
+    } catch (E00Exception &e) {
+      cerr << "Reading " << av[i] << " failed with exception "
+	   << e.message << endl;
+      exit(1);
+    }
+    cerr << "Read " << av[i] << " successfully" << endl;
+    cerr << "Read " << data.nPoints() << " point(s)" << endl;
+    cerr << "Read " << data.nLines() << " line segment(s)" << endl;
+    cerr << "Read " << data.nPolygons() << " polygon(s)" << endl;
+    cerr << " (including enclosing polygon)" << endl;
+
+    data.write(cout);
+  } 
+
+  return 0;
+}
diff --git a/src/Prep/E00Lines/Makefile.am b/src/Prep/E00Lines/Makefile.am
new file mode 100644
index 00000000..09e7e34a
--- /dev/null
+++ b/src/Prep/E00Lines/Makefile.am
@@ -0,0 +1,11 @@
+bin_PROGRAMS = e00lines
+
+e00lines_SOURCES = main.cxx
+
+e00lines_LDADD = \
+	$(top_builddir)/src/Lib/Polygon/libPolygon.a \
+	$(top_builddir)/src/Lib/poly2tri/libpoly2tri.a \
+	$(top_builddir)/src/Lib/e00/libe00.a \
+	-lsgdebug -lsgbucket -lsgmisc -lsgmath -lz -lgpc
+
+INCLUDES += -I$(top_srcdir)/src/Lib
diff --git a/src/Prep/E00Lines/main.cxx b/src/Prep/E00Lines/main.cxx
new file mode 100644
index 00000000..c9550384
--- /dev/null
+++ b/src/Prep/E00Lines/main.cxx
@@ -0,0 +1,162 @@
+// main.cxx -- generate lines from E00 files.
+//
+// Written by David Megginson, started October 2000.  Based on
+// code by Curtis Olson.
+//
+// Copyright (C) 2000  David Megginson  - david@megginson.com
+// Copyright (C) 1999  Curtis L. Olson  - curt@flightgear.org
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+ 
+
+#include <simgear/compiler.h>
+#include <simgear/constants.h>
+#include <simgear/math/sg_geodesy.hxx>
+#include <simgear/debug/logstream.hxx>
+
+#include <string>
+#include <fstream>
+
+using std::string;
+using std::ifstream;
+
+#include <Polygon/index.hxx>
+#include <Polygon/names.hxx>
+#include <Polygon/polygon.hxx>
+#include <Polygon/split.hxx>
+#include <e00/e00.hxx>
+
+#ifdef _MSC_VER
+#  include <Win32/mkdir.hpp>
+#endif
+
+static inline double ANGLE (double a)
+{
+  while (a < 0.0)
+    a += 360.0;
+  while (a >= 360.0)
+    a -= 360.0;
+  return a;
+}
+
+
+int
+main (int argc, const char **argv)
+{
+
+				// Enable logging.
+  fglog().setLogLevels( FG_ALL, FG_DEBUG );
+  
+				// Check usage.
+  if ( argc != 5 ) {
+    FG_LOG( FG_GENERAL, FG_ALERT, "Usage: " << argv[0] 
+	    << " <e00_line_file> <width_meters> <area_type> <work_dir>" );
+    exit(-1);
+  }
+
+				// Grab command-line arguments.
+  ifstream input(argv[1]);
+  if ( !input.good() ) {
+    FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << argv[1]);
+    exit(-1);
+  }
+
+  int width = atoi(argv[2]);
+  if (width <= 0) {
+    FG_LOG(FG_GENERAL, FG_ALERT, "Bad width specified " << argv[2]);
+    exit(-1);
+  }
+
+  AreaType area_type = get_area_type(argv[3]);
+
+  string work_dir = argv[4];
+#ifdef _MSC_VER
+  fg_mkdir(work_dir.c_str());
+#else
+  string command = "mkdir -p " + work_dir;
+  system(command.c_str());
+#endif
+
+				// Read the E00 file.
+  E00 data;
+  try {
+    data.readE00(input);
+  } catch (E00Exception &e) {
+    FG_LOG(FG_GENERAL, FG_ALERT, "Reading " << argv[1]
+	   << " failed with exception " << e.message);
+    exit(1);
+  }
+
+				// Initialize the persistant polygon counter.
+  string counter_file = work_dir + "/../poly_counter";
+  poly_index_init( counter_file );
+
+  FGPolygon shape;
+
+				// Iterate through the lines.
+  int nLines = data.nLines();
+  for (int i = 0; i < nLines; i++) {
+    const e00ARC * line = data.getLine(i);
+    cout << "Line has " << line->numberOfCoordinates << " coordinates" << endl;
+    for (int j = 0; j < line->numberOfCoordinates - 1; j++) {
+      double lon1 = line->coordinates[j].x;
+      double lat1 = line->coordinates[j].y;
+      double lon2 = line->coordinates[j+1].x;
+      double lat2 = line->coordinates[j+1].y;
+      double angle1, angle2, dist;
+      geo_inverse_wgs_84(0, lat1, lon1, lat2, lon2, &angle1, &angle2, &dist);
+      cout << "angle1 = " << angle1 << endl;
+      cout << "angle2 = " << angle2 << endl;
+      cout << "dist = " << dist << endl;
+      shape.erase();
+
+      double x, y, az;
+
+				// Corner 1
+      geo_direct_wgs_84(0, lat1, lon1, ANGLE(angle1+90), width/2, &y, &x, &az);
+      cout << x << '\t' << y << endl;
+      shape.add_node(0, Point3D(x, y, 0));
+
+				// Corner 2
+      geo_direct_wgs_84(0, lat1, lon1, ANGLE(angle1-90), width/2, &y, &x, &az);
+      cout << x << '\t' << y << endl;
+      shape.add_node(0, Point3D(x, y, 0));
+
+				// Corner 3
+      geo_direct_wgs_84(0, lat2, lon2, ANGLE(angle2+90), width/2, &y, &x, &az);
+      cout << x << '\t' << y << endl;
+      shape.add_node(0, Point3D(x, y, 0));
+
+				// Corner 4
+      geo_direct_wgs_84(0, lat2, lon2, ANGLE(angle2-90), width/2, &y, &x, &az);
+      cout << x << '\t' << y << endl;
+      shape.add_node(0, Point3D(x, y, 0));
+
+				// Corner 1, again
+      geo_direct_wgs_84(0, lat1, lon1, ANGLE(angle1+90), width/2, &y, &x, &az);
+      cout << x << '\t' << y << endl;
+      shape.add_node(0, Point3D(x, y, 0));
+
+				// Split into tiles
+      split_polygon(work_dir, area_type, shape);
+    }
+  }
+
+  return 0;
+}
+
+