1
0
Fork 0

Initial revision.

This commit is contained in:
curt 2000-11-22 22:17:58 +00:00
parent a115f756c7
commit 8a82c389ec
6 changed files with 1011 additions and 0 deletions

10
src/Lib/e00/Makefile.am Normal file
View file

@ -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

608
src/Lib/e00/e00.cxx Normal file
View file

@ -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

190
src/Lib/e00/e00.hxx Normal file
View file

@ -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 ();
};

30
src/Lib/e00/teste00.cxx Normal file
View file

@ -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;
}

View file

@ -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

162
src/Prep/E00Lines/main.cxx Normal file
View file

@ -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;
}