These add a --min-angle options to fgfs-tools-client,
and make the E00 support a lot more robust.
This commit is contained in:
parent
1190702047
commit
528c12a682
9 changed files with 1013 additions and 406 deletions
|
@ -175,8 +175,8 @@ long int get_next_task( const string& host, int port, long int last_tile ) {
|
|||
// successfully
|
||||
bool construct_tile( const SGBucket& b,
|
||||
const string& result_file,
|
||||
const string &cover ) {
|
||||
double angle = 10.0;
|
||||
const string &cover,
|
||||
float angle ) {
|
||||
bool still_trying = true;
|
||||
|
||||
while ( still_trying ) {
|
||||
|
@ -216,6 +216,9 @@ bool construct_tile( const SGBucket& b,
|
|||
angle = 5.0;
|
||||
still_trying = true;
|
||||
} else if ( angle > 4.0 ) {
|
||||
angle = 1.0;
|
||||
still_trying = true;
|
||||
} else if ( angle > 0.0 ) {
|
||||
angle = 0.0;
|
||||
still_trying = true;
|
||||
}
|
||||
|
@ -257,6 +260,7 @@ int main(int argc, char *argv[]) {
|
|||
string cover;
|
||||
string host = "127.0.0.1";
|
||||
int port=4001;
|
||||
float angle = 10.0;
|
||||
|
||||
//
|
||||
// Parse the command-line arguments.
|
||||
|
@ -277,6 +281,8 @@ int main(int argc, char *argv[]) {
|
|||
rude = true;
|
||||
} else if (arg.find("--cover=") == 0) {
|
||||
cover = arg.substr(8);
|
||||
} else if (arg.find("--min-angle=") == 0) {
|
||||
angle = atof(arg.substr(12).c_str());
|
||||
} else if (arg.find("--") == 0) {
|
||||
usage(argv[0]);
|
||||
} else {
|
||||
|
@ -315,7 +321,7 @@ int main(int argc, char *argv[]) {
|
|||
check_master_switch();
|
||||
|
||||
while ( (tile = get_next_task( host, port, last_tile )) >= 0 ) {
|
||||
result = construct_tile( SGBucket(tile), result_file, cover );
|
||||
result = construct_tile( SGBucket(tile), result_file, cover, angle );
|
||||
if ( result ) {
|
||||
last_tile = tile;
|
||||
} else {
|
||||
|
|
|
@ -70,6 +70,7 @@ inline static void init ()
|
|||
set_area("Reservoir", ReservoirArea);
|
||||
set_area("Reservoir Intermittent", IntReservoirArea);
|
||||
set_area("IntermittentReservoir", IntReservoirArea);
|
||||
set_area("Freeway", FreewayArea);
|
||||
set_area("Road", RoadArea);
|
||||
set_area("Railroad", RailroadArea);
|
||||
set_area("Stream", StreamArea);
|
||||
|
|
|
@ -44,6 +44,7 @@ enum AreaType {
|
|||
IntLakeArea,
|
||||
ReservoirArea,
|
||||
IntReservoirArea,
|
||||
FreewayArea,
|
||||
RoadArea,
|
||||
RailroadArea,
|
||||
StreamArea,
|
||||
|
|
|
@ -5,6 +5,8 @@ libe00_a_SOURCES = e00.cxx e00.hxx
|
|||
noinst_PROGRAMS = teste00
|
||||
|
||||
teste00_SOURCES = teste00.cxx
|
||||
teste00_LDADD = libe00.a
|
||||
|
||||
teste00_LDADD = libe00.a -lsgmisc -lz
|
||||
|
||||
INCLUDES += \
|
||||
-I$(top_srcdir)/src \
|
||||
-I$(top_srcdir)/src/Lib
|
||||
|
|
|
@ -39,22 +39,25 @@ append (string &s, double f)
|
|||
}
|
||||
|
||||
static void
|
||||
skipWhitespace (istream &input)
|
||||
skipNewlines (istream &input)
|
||||
{
|
||||
char c;
|
||||
input.get(c);
|
||||
while (isspace(c)) {
|
||||
// while (isspace(c)) {
|
||||
// input.get(c);
|
||||
// }
|
||||
while (c == '\n' || c == '\r') {
|
||||
input.get(c);
|
||||
}
|
||||
input.putback(c);
|
||||
}
|
||||
|
||||
static void
|
||||
readStringItem (istream &input, string &line, int width)
|
||||
readItem (istream &input, string &line, int width)
|
||||
{
|
||||
char c;
|
||||
|
||||
skipWhitespace(input);
|
||||
skipNewlines(input);
|
||||
line.resize(0);
|
||||
|
||||
for (int i = 0; i < width; i++) {
|
||||
|
@ -89,6 +92,43 @@ checkZeros (istream &input)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
expect (istream &input, int i)
|
||||
{
|
||||
int in;
|
||||
input >> in;
|
||||
if (in != i) {
|
||||
string message = "Expected ";
|
||||
append(message, i);
|
||||
throw E00Exception(message.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
expect (istream &input, double f)
|
||||
{
|
||||
double in;
|
||||
input >> in;
|
||||
if (in != f) {
|
||||
string message = "Expected ";
|
||||
append(message, f);
|
||||
throw E00Exception(message.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
expect (istream &input, const char *s)
|
||||
{
|
||||
string in;
|
||||
input >> in;
|
||||
if (in != s) {
|
||||
string message = "Expected ";
|
||||
message += s;
|
||||
throw E00Exception(message.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of E00
|
||||
|
@ -105,136 +145,6 @@ 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
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
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 ( i = 0; i < (int)arc_section.size(); i++) {
|
||||
const e00ARC &arc = arc_section[i];
|
||||
if (!arc.inPolygon) {
|
||||
output << "<line>" << endl;
|
||||
for ( 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 ( i = 1; i < (int)pal_section.size(); i++) {
|
||||
const e00PAL &pal = pal_section[i];
|
||||
output << "<polygon>" << endl;
|
||||
for ( 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 ( k = arc.numberOfCoordinates - 1; k >= 0; k--) {
|
||||
writeVertex(output, arc.coordinates[k].x, arc.coordinates[k].y);
|
||||
}
|
||||
} else {
|
||||
for ( 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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -255,6 +165,7 @@ E00::readE00 (istream &input)
|
|||
|
||||
*_input >> token;
|
||||
|
||||
cerr << "Reading " << token << " section" << endl;
|
||||
if (token == "ARC") {
|
||||
readARC();
|
||||
} else if (token == "CNT") {
|
||||
|
@ -273,6 +184,14 @@ E00::readE00 (istream &input)
|
|||
readTOL();
|
||||
} else if (token == "IFO") {
|
||||
readIFO();
|
||||
} else if (token == "TX6") {
|
||||
readTX6();
|
||||
} else if (token == "TX7") {
|
||||
readTX7();
|
||||
} else if (token == "RXP") {
|
||||
readRXP();
|
||||
} else if (token == "RPL") {
|
||||
readRPL();
|
||||
} else if (token == "EOS") {
|
||||
postProcess();
|
||||
return;
|
||||
|
@ -283,6 +202,7 @@ E00::readE00 (istream &input)
|
|||
}
|
||||
|
||||
throw E00Exception("File ended without EOS line");
|
||||
_input = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -292,8 +212,8 @@ E00::readE00 (istream &input)
|
|||
void
|
||||
E00::readHeader ()
|
||||
{
|
||||
expect("EXP");
|
||||
expect(0);
|
||||
expect(*_input, "EXP");
|
||||
expect(*_input, 0);
|
||||
*_input >> pathName;
|
||||
}
|
||||
|
||||
|
@ -304,14 +224,12 @@ E00::readHeader ()
|
|||
void
|
||||
E00::readARC ()
|
||||
{
|
||||
e00ARC arc;
|
||||
e00Coord coord;
|
||||
ARC arc;
|
||||
Coord coord;
|
||||
|
||||
checkPrecision(*_input);
|
||||
|
||||
*_input >> arc.coverageNum;
|
||||
while (arc.coverageNum != -1) {
|
||||
arc.inPolygon = false;
|
||||
*_input >> arc.coverageId;
|
||||
*_input >> arc.fromNode;
|
||||
*_input >> arc.toNode;
|
||||
|
@ -324,6 +242,7 @@ E00::readARC ()
|
|||
*_input >> coord.y;
|
||||
arc.coordinates.push_back(coord);
|
||||
}
|
||||
arc.in_polygon = false; // we'll check later
|
||||
arc_section.push_back(arc);
|
||||
*_input >> arc.coverageNum;
|
||||
}
|
||||
|
@ -338,14 +257,16 @@ E00::readARC ()
|
|||
void
|
||||
E00::readCNT ()
|
||||
{
|
||||
e00CNT cnt;
|
||||
int numLabels;
|
||||
int label;
|
||||
|
||||
checkPrecision(*_input);
|
||||
|
||||
*_input >> cnt.numLabels;
|
||||
*_input >> numLabels;
|
||||
|
||||
while (cnt.numLabels != -1) {
|
||||
while (numLabels != -1) {
|
||||
CNT cnt;
|
||||
cnt.numLabels = numLabels;
|
||||
*_input >> cnt.centroid.x;
|
||||
*_input >> cnt.centroid.y;
|
||||
for (int i = 0; i < cnt.numLabels; i++) {
|
||||
|
@ -353,7 +274,7 @@ E00::readCNT ()
|
|||
cnt.labels.push_back(label);
|
||||
}
|
||||
cnt_section.push_back(cnt);
|
||||
*_input >> cnt.numLabels;
|
||||
*_input >> numLabels;
|
||||
}
|
||||
|
||||
checkZeros(*_input);
|
||||
|
@ -363,7 +284,7 @@ E00::readCNT ()
|
|||
void
|
||||
E00::readLAB ()
|
||||
{
|
||||
e00LAB lab;
|
||||
LAB lab;
|
||||
|
||||
checkPrecision(*_input);
|
||||
*_input >> lab.coverageId;
|
||||
|
@ -387,7 +308,7 @@ E00::readLAB ()
|
|||
void
|
||||
E00::readLOG ()
|
||||
{
|
||||
e00LOG log;
|
||||
LOG log;
|
||||
string line;
|
||||
|
||||
checkPrecision(*_input);
|
||||
|
@ -409,8 +330,9 @@ E00::readLOG ()
|
|||
void
|
||||
E00::readPAL ()
|
||||
{
|
||||
e00PAL pal;
|
||||
e00PAL::ARC arc;
|
||||
PAL pal;
|
||||
PAL::ARCref arc;
|
||||
int count = 1;
|
||||
|
||||
checkPrecision(*_input);
|
||||
*_input >> pal.numArcs;
|
||||
|
@ -422,6 +344,19 @@ E00::readPAL ()
|
|||
pal.arcs.resize(0);
|
||||
for (int i = 0; i < pal.numArcs; i++) {
|
||||
*_input >> arc.arcNum;
|
||||
if (count > 1) {
|
||||
if (arc.arcNum > 0)
|
||||
_getARC(arc.arcNum).in_polygon = true;
|
||||
else
|
||||
_getARC(0-arc.arcNum).in_polygon = true;
|
||||
}
|
||||
int num = (arc.arcNum < 0 ? 0 - arc.arcNum : arc.arcNum);
|
||||
if (num != 0 &&
|
||||
getARC(num).leftPolygon != count &&
|
||||
getARC(num).rightPolygon != count) {
|
||||
cerr << "Polygon " << count << " includes arc " << num
|
||||
<< " which doesn't reference it" << endl;
|
||||
}
|
||||
*_input >> arc.nodeNum;
|
||||
*_input >> arc.polygonNum;
|
||||
pal.arcs.push_back(arc);
|
||||
|
@ -429,6 +364,7 @@ E00::readPAL ()
|
|||
|
||||
pal_section.push_back(pal);
|
||||
*_input >> pal.numArcs;
|
||||
count++;
|
||||
}
|
||||
|
||||
checkZeros(*_input);
|
||||
|
@ -438,7 +374,7 @@ E00::readPAL ()
|
|||
void
|
||||
E00::readPRJ ()
|
||||
{
|
||||
e00PRJ prj;
|
||||
PRJ prj;
|
||||
string line;
|
||||
|
||||
checkPrecision(*_input);
|
||||
|
@ -472,7 +408,7 @@ E00::readSIN ()
|
|||
void
|
||||
E00::readTOL ()
|
||||
{
|
||||
e00TOL tol;
|
||||
TOL tol;
|
||||
|
||||
checkPrecision(*_input);
|
||||
*_input >> tol.type;
|
||||
|
@ -487,20 +423,68 @@ E00::readTOL ()
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
E00::readTX6 ()
|
||||
{
|
||||
string dummy;
|
||||
*_input >> dummy;
|
||||
// FIXME: will fail if "JABBERWOCKY" appears
|
||||
// in the text annotation itself
|
||||
while (dummy != "JABBERWOCKY")
|
||||
*_input >> dummy;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
E00::readTX7 ()
|
||||
{
|
||||
string dummy;
|
||||
*_input >> dummy;
|
||||
// FIXME: will fail if "JABBERWOCKY" appears
|
||||
// in the text annotation itself
|
||||
while (dummy != "JABBERWOCKY")
|
||||
*_input >> dummy;
|
||||
}
|
||||
|
||||
void
|
||||
E00::readRXP ()
|
||||
{
|
||||
string dummy;
|
||||
*_input >> dummy;
|
||||
// FIXME: will fail if "JABBERWOCKY" appears
|
||||
// in the text annotation itself
|
||||
while (dummy != "JABBERWOCKY")
|
||||
*_input >> dummy;
|
||||
}
|
||||
|
||||
void
|
||||
E00::readRPL ()
|
||||
{
|
||||
string dummy;
|
||||
*_input >> dummy;
|
||||
// FIXME: will fail if "JABBERWOCKY" appears
|
||||
// in the text annotation itself
|
||||
while (dummy != "JABBERWOCKY")
|
||||
*_input >> dummy;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
E00::readIFO ()
|
||||
{
|
||||
e00IFO ifo;
|
||||
e00IFO::ItemDef def;
|
||||
e00IFO::Entry entry;
|
||||
string line;
|
||||
string line = "";
|
||||
int intval;
|
||||
double realval;
|
||||
|
||||
checkPrecision(*_input);
|
||||
|
||||
*_input >> ifo.fileName;
|
||||
while (ifo.fileName.find("EOI") != 0) {
|
||||
while (line == "")
|
||||
*_input >> line;
|
||||
while (line != string("EOI")) {
|
||||
|
||||
IFO ifo;
|
||||
IFO::Entry entry;
|
||||
ifo.fileName = line;
|
||||
|
||||
// 'XX' may be absent
|
||||
*_input >> ifo.isArcInfo;
|
||||
|
@ -517,19 +501,21 @@ E00::readIFO ()
|
|||
// Read the item definitions
|
||||
ifo.defs.resize(0);
|
||||
for (int i = 0; i < ifo.numItems; i++) {
|
||||
IFO::ItemDef def;
|
||||
|
||||
*_input >> def.itemName;
|
||||
*_input >> def.itemWidth;
|
||||
expect(-1);
|
||||
expect(*_input, -1);
|
||||
*_input >> def.itemStartPos;
|
||||
expect(-1);
|
||||
expect(*_input, -1);
|
||||
def.itemStartPos -= 4;
|
||||
def.itemStartPos /= 10;
|
||||
*_input >> def.itemOutputFormat[0];
|
||||
*_input >> def.itemOutputFormat[1];
|
||||
*_input >> def.itemType;
|
||||
expect(-1);
|
||||
expect(-1);
|
||||
expect(-1);
|
||||
expect(*_input, -1);
|
||||
expect(*_input, -1);
|
||||
expect(*_input, -1);
|
||||
*_input >> def.seqId;
|
||||
ifo.defs.push_back(def);
|
||||
getline(*_input, line);
|
||||
|
@ -542,18 +528,51 @@ E00::readIFO ()
|
|||
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);
|
||||
|
||||
if (type == "10-1") { // date
|
||||
readItem(*_input, line, 8);
|
||||
}
|
||||
|
||||
else if (type == "20-1") { // character field
|
||||
readItem(*_input, line, ifo.defs[j].itemOutputFormat[0]);
|
||||
}
|
||||
|
||||
else if (type == "30-1") { // fixed-width integer
|
||||
readItem(*_input, line, ifo.defs[j].itemOutputFormat[0]);
|
||||
}
|
||||
|
||||
else if (type == "40-1") { // single-precision float
|
||||
readItem(*_input, line, 14);
|
||||
}
|
||||
|
||||
else if (type == "50-1") { // integer
|
||||
if (ifo.defs[j].itemWidth == 2) {
|
||||
readItem(*_input, line, 6);
|
||||
} else if (ifo.defs[j].itemWidth == 4) {
|
||||
readItem(*_input, line, 11);
|
||||
} else {
|
||||
cerr << "Unexpected width " << ifo.defs[j].itemWidth
|
||||
<< " for item of type 50-1" << endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
else if (type == "60-1") { // real number
|
||||
if (ifo.defs[j].itemWidth == 4) {
|
||||
readItem(*_input, line, 14);
|
||||
} else if (ifo.defs[j].itemWidth == 8) {
|
||||
readItem(*_input, line, 24);
|
||||
} else {
|
||||
cerr << "Unexpected width " << ifo.defs[j].itemWidth
|
||||
<< " for item of type 60-1" << endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
else { // assume integer
|
||||
cerr << "Unknown IFO item type " << type
|
||||
<< " assuming integer" << endl;
|
||||
exit(1);
|
||||
}
|
||||
entry.push_back(line);
|
||||
}
|
||||
|
@ -561,7 +580,9 @@ E00::readIFO ()
|
|||
}
|
||||
|
||||
ifo_section.push_back(ifo);
|
||||
*_input >> ifo.fileName;
|
||||
line = "";
|
||||
while (line == "")
|
||||
*_input >> line;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -580,31 +601,59 @@ E00::readUnknown ()
|
|||
void
|
||||
E00::postProcess ()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Other access methods.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const E00::IFO *
|
||||
E00::getIFO (const string &fileName) const
|
||||
{
|
||||
for (int i = 0; i < ifo_section.size(); i++) {
|
||||
if (ifo_section[i].fileName == fileName)
|
||||
return &(ifo_section[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const string *
|
||||
E00::getIFOItem (const string &fileName, int entry,
|
||||
const string &itemName) const
|
||||
{
|
||||
const IFO * ifo = getIFO(fileName);
|
||||
if (ifo == 0)
|
||||
return 0;
|
||||
|
||||
int pos = -1;
|
||||
for (int i = 0; i < ifo->defs.size(); i++) {
|
||||
if (ifo->defs[i].itemName == itemName)
|
||||
pos = i;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
if (pos == -1)
|
||||
return 0;
|
||||
|
||||
return &(ifo->entries[entry-1][pos]);
|
||||
}
|
||||
|
||||
const string *
|
||||
E00::getIFOItemType (const string &fileName, const string &itemName) const
|
||||
{
|
||||
const IFO * ifo = getIFO(fileName);
|
||||
if (ifo == 0)
|
||||
return 0;
|
||||
|
||||
int pos = -1;
|
||||
for (int i = 0; i < ifo->defs.size(); i++) {
|
||||
if (ifo->defs[i].itemName == itemName)
|
||||
return &(ifo->defs[i].itemType);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// end of e00.cxx
|
||||
|
|
|
@ -1,145 +1,170 @@
|
|||
// e00.hxx - declarations for E00 file processing.
|
||||
|
||||
#ifndef __E00_HXX
|
||||
#define __E00_HXX 1
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include STL_STRING
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
FG_USING_STD(vector);
|
||||
FG_USING_STD(map);
|
||||
FG_USING_STD(string);
|
||||
FG_USING_STD(istream);
|
||||
FG_USING_STD(ostream);
|
||||
using std::vector;
|
||||
using std::string;
|
||||
using std::istream;
|
||||
|
||||
struct E00Exception
|
||||
|
||||
// An exception reading an E00 file.
|
||||
|
||||
class E00Exception
|
||||
{
|
||||
E00Exception (const char * msg) : message(msg) {}
|
||||
string message;
|
||||
public:
|
||||
E00Exception (const string &message) : _message(message) {}
|
||||
virtual const string &getMessage () const { return _message; }
|
||||
private:
|
||||
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:
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Data structures for internal use.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// A coordinate in two-dimensional space.
|
||||
|
||||
struct Coord
|
||||
{
|
||||
virtual ~Coord () {}
|
||||
double x;
|
||||
double y;
|
||||
};
|
||||
|
||||
|
||||
// Arc co-ordinates and topology.
|
||||
|
||||
struct ARC
|
||||
{
|
||||
virtual ~ARC () {}
|
||||
int coverageNum;
|
||||
int coverageId;
|
||||
int fromNode;
|
||||
int toNode;
|
||||
int leftPolygon;
|
||||
int rightPolygon;
|
||||
int numberOfCoordinates;
|
||||
vector<Coord> coordinates;
|
||||
bool in_polygon;
|
||||
};
|
||||
|
||||
|
||||
// Polygon Centroid Coordinates
|
||||
|
||||
struct CNT
|
||||
{
|
||||
virtual ~CNT () {}
|
||||
int numLabels;
|
||||
Coord centroid;
|
||||
vector<int> labels;
|
||||
};
|
||||
|
||||
|
||||
// Label Point Coordinates and Topology
|
||||
|
||||
struct LAB
|
||||
{
|
||||
virtual ~LAB () {}
|
||||
int coverageId;
|
||||
int enclosingPolygon;
|
||||
Coord coord;
|
||||
Coord box1; // obsolete
|
||||
Coord box2; // obsolete
|
||||
};
|
||||
|
||||
|
||||
// Coverage History
|
||||
|
||||
struct LOG
|
||||
{
|
||||
virtual ~LOG () {}
|
||||
vector<string> lines;
|
||||
};
|
||||
|
||||
|
||||
// Polygon Topology
|
||||
|
||||
struct PAL
|
||||
{
|
||||
virtual ~PAL () {}
|
||||
struct ARCref
|
||||
{
|
||||
int arcNum;
|
||||
int nodeNum;
|
||||
int polygonNum;
|
||||
};
|
||||
int numArcs;
|
||||
Coord min;
|
||||
Coord max;
|
||||
vector<ARCref> arcs;
|
||||
};
|
||||
|
||||
|
||||
// Projection Parameters
|
||||
|
||||
struct PRJ
|
||||
{
|
||||
virtual ~PRJ () {}
|
||||
vector<string> lines;
|
||||
};
|
||||
|
||||
|
||||
// Tolerance Type
|
||||
|
||||
struct TOL
|
||||
{
|
||||
virtual ~TOL () {}
|
||||
int type;
|
||||
int status;
|
||||
double value;
|
||||
};
|
||||
|
||||
|
||||
// Info Files
|
||||
|
||||
struct IFO
|
||||
{
|
||||
virtual ~IFO () {}
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
E00 ();
|
||||
virtual ~E00 ();
|
||||
|
||||
|
@ -147,35 +172,37 @@ public:
|
|||
|
||||
virtual string getPathName () const { return pathName; }
|
||||
|
||||
virtual int nPoints () const;
|
||||
virtual int nLines () const;
|
||||
virtual int nPolygons () const;
|
||||
virtual int nPoints () const { return lab_section.size(); }
|
||||
virtual int nLines () const { return arc_section.size(); }
|
||||
virtual int nPolygons () const { return pal_section.size(); }
|
||||
virtual int nInfoFiles () const { return ifo_section.size(); }
|
||||
|
||||
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;
|
||||
virtual const ARC &getARC (int i) const { return arc_section[i-1]; }
|
||||
virtual const LAB &getLAB (int i) const { return lab_section[i-1]; }
|
||||
virtual const PAL &getPAL (int i) const { return pal_section[i-1]; }
|
||||
virtual const IFO &getIFO (int i) const { return ifo_section[i-1]; }
|
||||
virtual const IFO * getIFO (const string &name) const;
|
||||
virtual const string * getIFOItem (const string &fileName, int entry,
|
||||
const string &itemName) const;
|
||||
virtual const string * getIFOItemType (const string &fileName,
|
||||
const string &itemName) const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
vector<const e00ARC *> pointArcs;
|
||||
vector<const e00ARC *> lineArcs;
|
||||
virtual ARC &_getARC (int i) { return arc_section[i-1]; }
|
||||
|
||||
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;
|
||||
vector<ARC> arc_section;
|
||||
vector<CNT> cnt_section;
|
||||
vector<LAB> lab_section;
|
||||
vector<LOG> log_section;
|
||||
vector<PAL> pal_section;
|
||||
vector<PRJ> prj_section;
|
||||
vector<TOL> tol_section;
|
||||
vector<IFO> ifo_section;
|
||||
|
||||
istream * _input;
|
||||
|
||||
void expect (int i);
|
||||
void expect (double f);
|
||||
void expect (const char * s);
|
||||
mutable istream * _input;
|
||||
|
||||
void postProcess ();
|
||||
|
||||
|
@ -188,6 +215,15 @@ private:
|
|||
void readPRJ ();
|
||||
void readSIN ();
|
||||
void readTOL ();
|
||||
void readTX6 ();
|
||||
void readTX7 ();
|
||||
void readRXP ();
|
||||
void readRPL ();
|
||||
void readIFO ();
|
||||
void readUnknown ();
|
||||
|
||||
};
|
||||
|
||||
#endif __E00_HXX
|
||||
|
||||
// end of e00.hxx
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
// teste00.cxx - test the E00 parsing routines and dump some results.
|
||||
|
||||
#include <fstream>
|
||||
#include <simgear/misc/fgstream.hxx>
|
||||
#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]);
|
||||
fg_gzifstream input(av[i]);
|
||||
E00 data;
|
||||
try {
|
||||
data.readE00(input);
|
||||
} catch (E00Exception &e) {
|
||||
cerr << "Reading " << av[i] << " failed with exception "
|
||||
<< e.message << endl;
|
||||
<< e.getMessage() << endl;
|
||||
exit(1);
|
||||
}
|
||||
cerr << "Read " << av[i] << " successfully" << endl;
|
||||
|
@ -23,8 +22,39 @@ int main (int ac, const char ** av)
|
|||
cerr << "Read " << data.nPolygons() << " polygon(s)" << endl;
|
||||
cerr << " (including enclosing polygon)" << endl;
|
||||
|
||||
data.write(cout);
|
||||
for (int i = 1; i <= data.nInfoFiles(); i++) {
|
||||
const E00::IFO &ifo = data.getIFO(i);
|
||||
cout << "IFO file: " << ifo.fileName << endl;
|
||||
for (int j = 0; j < ifo.numItems; j++) {
|
||||
cout << " " << ifo.defs[j].itemName << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// for (int i = 2; i <= data.nPolygons(); i++) {
|
||||
// const E00::PAL &pal = data.getPAL(i);
|
||||
// for (int j = 0; j < pal.numArcs; j++) {
|
||||
// int arcNum = pal.arcs[j].arcNum;
|
||||
// if (arcNum == 0) {
|
||||
// cout << endl;
|
||||
// } else if (arcNum < 0) {
|
||||
// const E00::ARC &arc = data.getARC(0-arcNum);
|
||||
// for (int k = arc.numberOfCoordinates - 1; k >= 0; k--) {
|
||||
// cout << arc.coordinates[k].x << '\t'
|
||||
// << arc.coordinates[k].y << endl;
|
||||
// }
|
||||
// } else {
|
||||
// const E00::ARC &arc = data.getARC(arcNum);
|
||||
// for (int k = 0; k < arc.numberOfCoordinates; k++) {
|
||||
// cout << arc.coordinates[k].x << '\t'
|
||||
// << arc.coordinates[k].y << endl;
|
||||
// }
|
||||
// }
|
||||
// cout << endl;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// end of teste00.cxx
|
||||
|
|
|
@ -6,6 +6,6 @@ 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
|
||||
-lsgdebug -lsgbucket -lsgmisc -lsgmath -lsgio -lz -lgpc
|
||||
|
||||
INCLUDES += -I$(top_srcdir)/src/Lib
|
||||
|
|
|
@ -27,12 +27,16 @@
|
|||
#include <simgear/constants.h>
|
||||
#include <simgear/math/sg_geodesy.hxx>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/misc/fgstream.hxx>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
using std::string;
|
||||
using std::ifstream;
|
||||
FG_USING_STD(cerr);
|
||||
FG_USING_STD(cout);
|
||||
FG_USING_STD(string);
|
||||
FG_USING_STD(vector);
|
||||
|
||||
#include <Polygon/index.hxx>
|
||||
#include <Polygon/names.hxx>
|
||||
|
@ -44,7 +48,14 @@ using std::ifstream;
|
|||
# include <Win32/mkdir.hpp>
|
||||
#endif
|
||||
|
||||
static inline double ANGLE (double a)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Utility stuff.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline double
|
||||
ANGLE (double a)
|
||||
{
|
||||
while (a < 0.0)
|
||||
a += 360.0;
|
||||
|
@ -54,69 +65,192 @@ static inline double ANGLE (double a)
|
|||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, const char **argv)
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Areas.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* A rectangle (such as a bounding box).
|
||||
*/
|
||||
struct Rectangle
|
||||
{
|
||||
Rectangle () : minX(0.0), minY(0.0), maxX(0.0), maxY(0.0) {}
|
||||
Rectangle (double _minX, double _minY, double _maxX, double _maxY)
|
||||
: minX(_minX), minY(_minY), maxX(_maxX), maxY(_maxY) {}
|
||||
double minX;
|
||||
double minY;
|
||||
double maxX;
|
||||
double maxY;
|
||||
bool isInside (double x, double y) const
|
||||
{
|
||||
return (x >= minX && x <= maxX && y >= minY && y <= maxY);
|
||||
}
|
||||
bool isOverlapping (const Rectangle &rect) const
|
||||
{
|
||||
return (isInside(rect.minX, rect.minY) ||
|
||||
isInside(rect.minX, rect.maxY) ||
|
||||
isInside(rect.maxX, rect.minY) ||
|
||||
isInside(rect.maxX, rect.maxY));
|
||||
}
|
||||
};
|
||||
|
||||
// Enable logging.
|
||||
fglog().setLogLevels( FG_ALL, FG_DEBUG );
|
||||
static ostream &
|
||||
operator<< (ostream &output, const Rectangle &rect) {
|
||||
output << '(' << rect.minX << ',' << rect.minY << "),("
|
||||
<< rect.maxX << ',' << rect.maxY << ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a bounding box for a single ARC.
|
||||
*/
|
||||
static Rectangle
|
||||
makeBounds (const E00::ARC &arc)
|
||||
{
|
||||
Rectangle bounds;
|
||||
for (int i = 0; i < arc.numberOfCoordinates; i++) {
|
||||
double x = arc.coordinates[i].x;
|
||||
double y = arc.coordinates[i].y;
|
||||
if (i == 0) {
|
||||
bounds.minX = bounds.maxX = x;
|
||||
bounds.minY = bounds.maxY = y;
|
||||
} else {
|
||||
if (x < bounds.minX) bounds.minX = x;
|
||||
if (y < bounds.minY) bounds.minY = y;
|
||||
if (x > bounds.maxX) bounds.maxX = x;
|
||||
if (y > bounds.maxY) bounds.maxY = y;
|
||||
}
|
||||
}
|
||||
return bounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a bounding box for a polygon.
|
||||
*/
|
||||
static Rectangle
|
||||
makeBounds (const E00::PAL &pal)
|
||||
{
|
||||
return Rectangle(pal.min.x, pal.min.y, pal.max.x, pal.max.y);
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Processing methods.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* An attribute pattern.
|
||||
*/
|
||||
struct Attribute
|
||||
{
|
||||
string file;
|
||||
string item;
|
||||
string value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check whether an attribute pattern matches a shape.
|
||||
*/
|
||||
static bool
|
||||
checkAttribute (const E00 &data, int index, const Attribute &att)
|
||||
{
|
||||
const string * type = data.getIFOItemType(att.file, att.item);
|
||||
if (type == 0)
|
||||
return false;
|
||||
const string * value = data.getIFOItem(att.file, index, att.item);
|
||||
if (value == 0)
|
||||
return false;
|
||||
|
||||
if (*type == "10-1") { // date
|
||||
return (*value == att.value);
|
||||
}
|
||||
|
||||
// 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);
|
||||
else if (*type == "20-1") { // string
|
||||
return (*value == att.value);
|
||||
}
|
||||
|
||||
// Grab command-line arguments.
|
||||
ifstream input(argv[1]);
|
||||
if ( !input.good() ) {
|
||||
FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << argv[1]);
|
||||
exit(-1);
|
||||
else if (*type == "30-1" || *type == "50-1") { // integer
|
||||
int val1 = atoi(value->c_str());
|
||||
int val2 = atoi(att.value.c_str());
|
||||
return (val1 == val2);
|
||||
}
|
||||
|
||||
int width = atoi(argv[2]);
|
||||
if (width <= 0) {
|
||||
FG_LOG(FG_GENERAL, FG_ALERT, "Bad width specified " << argv[2]);
|
||||
exit(-1);
|
||||
else if (*type == "40-1" || *type == "60-1") { // float
|
||||
float val1 = atof(value->c_str());
|
||||
float val2 = atof(att.value.c_str());
|
||||
return (val1 == val2);
|
||||
}
|
||||
|
||||
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);
|
||||
else {
|
||||
cerr << "Unknown IFO field type " << *type << endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Initialize the persistant polygon counter.
|
||||
string counter_file = work_dir + "/../poly_counter";
|
||||
poly_index_init( counter_file );
|
||||
return (*value == att.value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create polygons out of points.
|
||||
*/
|
||||
static void
|
||||
processPoints (const E00 &data, const Rectangle &bounds,
|
||||
AreaType areaType, const string &workDir, int width)
|
||||
{
|
||||
cerr << "Points not yet supported" << endl;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create polygons out of all loose line segments.
|
||||
*/
|
||||
static void
|
||||
processLines (const E00 &data, const Rectangle &bounds,
|
||||
AreaType areaType, const string &workDir, int width,
|
||||
const vector<Attribute> &aat_list)
|
||||
{
|
||||
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;
|
||||
cout << "Processing " << nLines << " lines." << endl;
|
||||
for (int i = 1; i <= nLines; i++) {
|
||||
const E00::ARC &arc = data.getARC(i);
|
||||
Rectangle arcBounds = makeBounds(arc);
|
||||
if (!bounds.isOverlapping(arcBounds)) {
|
||||
cout << "Arc " << i << " outside of area; skipping" << endl;
|
||||
cout << "Arc bounds: " << arcBounds << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If any arc attributes were specified,
|
||||
// make sure at least one of them is
|
||||
// present.
|
||||
if (aat_list.size() > 0) {
|
||||
bool status = false;
|
||||
for (int j = 0; j < aat_list.size(); j++) {
|
||||
if (checkAttribute(data, i, aat_list[j])) {
|
||||
status = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!status) {
|
||||
cout << "Skipping line " << i << " (failed attribute tests)" << endl;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Make the line into a polygon.
|
||||
cout << "Line has " << arc.numberOfCoordinates << " coordinates" << endl;
|
||||
for (int j = 0; j < arc.numberOfCoordinates - 1; j++) {
|
||||
double lon1 = arc.coordinates[j].x;
|
||||
double lat1 = arc.coordinates[j].y;
|
||||
double lon2 = arc.coordinates[j+1].x;
|
||||
double lat2 = arc.coordinates[j+1].y;
|
||||
double angle1, angle2, dist;
|
||||
geo_inverse_wgs_84(0, lat1, lon1, lat2, lon2, &angle1, &angle2, &dist);
|
||||
cout << "angle1 = " << angle1 << endl;
|
||||
|
@ -152,10 +286,358 @@ main (int argc, const char **argv)
|
|||
shape.add_node(0, Point3D(x, y, 0));
|
||||
|
||||
// Split into tiles
|
||||
split_polygon(work_dir, area_type, shape);
|
||||
split_polygon(workDir, areaType, shape);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Import all polygons.
|
||||
*/
|
||||
static void
|
||||
processPolygons (const E00 &data, const Rectangle &bounds,
|
||||
AreaType areaType, const string &workDir,
|
||||
const vector<Attribute> pat_list)
|
||||
{
|
||||
FGPolygon shape;
|
||||
|
||||
int nPolygons = data.nPolygons();
|
||||
cout << "Processing " << nPolygons << " polygons" << endl;
|
||||
|
||||
for (int i = 2; i <= nPolygons; i++) {
|
||||
|
||||
// Test whether the polygon matches
|
||||
// at least one of the attributes
|
||||
// provided.
|
||||
if (pat_list.size() > 0) {
|
||||
bool status = false;
|
||||
for (int j = 0; j < pat_list.size(); j++) {
|
||||
if (checkAttribute(data, i, pat_list[j])) {
|
||||
status = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!status) {
|
||||
cout << "Skipping polygon " << i << " (failed attribute tests)"
|
||||
<< endl;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
int contour = 0;
|
||||
const E00::PAL &pal = data.getPAL(i);
|
||||
Rectangle palBounds = makeBounds(pal);
|
||||
if (!bounds.isOverlapping(palBounds)) {
|
||||
cout << "Polygon " << i << " outside of area, skipping" << endl;
|
||||
cout << "Polygon boundary is " << palBounds << endl;
|
||||
continue;
|
||||
}
|
||||
shape.erase();
|
||||
for (int j = 0; j < pal.numArcs; j++) {
|
||||
int arcNum = pal.arcs[j].arcNum;
|
||||
// Starting a hole
|
||||
if (arcNum == 0) {
|
||||
contour++;
|
||||
point_list contour;
|
||||
contour.clear();
|
||||
shape.add_contour(contour, 1);
|
||||
} else if (arcNum < 0) {
|
||||
const E00::ARC &arc = data.getARC(0-arcNum);
|
||||
for (int k = arc.numberOfCoordinates - 1; k >= 0; k--)
|
||||
shape.add_node(contour, Point3D(arc.coordinates[k].x,
|
||||
arc.coordinates[k].y,
|
||||
0.0));
|
||||
} else {
|
||||
const E00::ARC &arc = data.getARC(arcNum);
|
||||
for (int k = 0; k < arc.numberOfCoordinates; k++)
|
||||
shape.add_node(contour, Point3D(arc.coordinates[k].x,
|
||||
arc.coordinates[k].y,
|
||||
0.0));
|
||||
}
|
||||
}
|
||||
split_polygon(workDir, areaType, shape);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Main program.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* Print the command-line usage and exit.
|
||||
*/
|
||||
static void
|
||||
usage (const char * prog)
|
||||
{
|
||||
cerr << "Usage: " << prog << " [opts] e00file ..." << endl;
|
||||
cerr << "Options:" << endl;
|
||||
cerr << "--points=yes|no (default: no)" << endl;
|
||||
cerr << "--lines=yes|no (default: yes)" << endl;
|
||||
cerr << "--polygons=yes|no (default: yes)" << endl;
|
||||
cerr << "--min-lon=<longitude> (default: -180.0)" << endl;
|
||||
cerr << "--min-lat=<latitude> (default: -90.0)" << endl;
|
||||
cerr << "--max-lon=<longitude> (default: 180.0)" << endl;
|
||||
cerr << "--max-lat=<latitude> (default: 90.0)" << endl;
|
||||
cerr << "--area=<area_type> (default: Default)" << endl;
|
||||
cerr << "--point-width=<meters> (default: 500)" << endl;
|
||||
cerr << "--line-width=<meters> (default: 50)" << endl;
|
||||
cerr << "--work-dir=<dir> (default: .)" << endl;
|
||||
cerr << "--aat=<infofile>:<item>:<value> (may be repeated)" << endl;
|
||||
cerr << "--pat=<infofile>:<item>:<value> (may be repeated)" << endl;
|
||||
exit(2);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse an attribute value specification from the command line.
|
||||
*/
|
||||
static void
|
||||
parseAttribute (const char * prog, string arg, Attribute &att)
|
||||
{
|
||||
int pos1 = arg.find(':');
|
||||
int pos2 = arg.rfind(':');
|
||||
if (pos1 == -1 || pos2 == -1 || pos2 <= pos1) {
|
||||
cerr << "Bad attribute specification: " << arg << endl;
|
||||
usage(prog);
|
||||
}
|
||||
|
||||
att.file = arg.substr(0, pos1);
|
||||
att.item = arg.substr(pos1 + 1, pos2 - (pos1 + 1));
|
||||
att.value = arg.substr(pos2+1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Main entry point.
|
||||
*/
|
||||
int
|
||||
main (int argc, const char **argv)
|
||||
{
|
||||
vector<Attribute> aat_list;
|
||||
vector<Attribute> pat_list;
|
||||
|
||||
// Enable logging.
|
||||
fglog().setLogLevels( FG_ALL, FG_DEBUG );
|
||||
|
||||
|
||||
// Default values
|
||||
Rectangle bounds(-180.0, -90.0, 180.0, 90.0);
|
||||
AreaType areaType = DefaultArea;
|
||||
int pointWidth = 500;
|
||||
int lineWidth = 50;
|
||||
string workDir = ".";
|
||||
bool usePoints = false;
|
||||
bool useLines = true;
|
||||
bool usePolygons = true;
|
||||
|
||||
// Command-line options
|
||||
int argPos = 1;
|
||||
while (argPos < argc) {
|
||||
string arg = argv[argPos];
|
||||
|
||||
cout << "Trying argument " << arg << endl;
|
||||
|
||||
if (arg.find("--points=") == 0) {
|
||||
if (arg.substr(9) == "yes")
|
||||
usePoints = true;
|
||||
else if (arg.substr(9) == "no")
|
||||
usePoints = false;
|
||||
else {
|
||||
cerr << "--points option needs 'yes' or 'no'" << endl;
|
||||
usage(argv[0]);
|
||||
}
|
||||
argPos++;
|
||||
}
|
||||
|
||||
else if (arg.find("--lines=") == 0) {
|
||||
if (arg.substr(9) == "yes")
|
||||
useLines = true;
|
||||
else if (arg.substr(9) == "no")
|
||||
useLines = false;
|
||||
else {
|
||||
cerr << "--lines option needs 'yes' or 'no'" << endl;
|
||||
usage(argv[0]);
|
||||
}
|
||||
argPos++;
|
||||
}
|
||||
|
||||
else if (arg.find("--polygons=") == 0) {
|
||||
if (arg.substr(9) == "yes")
|
||||
usePolygons = true;
|
||||
else if (arg.substr(9) == "no")
|
||||
usePolygons = false;
|
||||
else {
|
||||
cerr << "--polygons option needs 'yes' or 'no'" << endl;
|
||||
usage(argv[0]);
|
||||
}
|
||||
argPos++;
|
||||
}
|
||||
|
||||
else if (arg.find("--min-lon=") == 0) {
|
||||
bounds.minX = atof(arg.substr(10).c_str());
|
||||
argPos++;
|
||||
}
|
||||
|
||||
else if (arg.find("--min-lat=") == 0) {
|
||||
bounds.minY = atof(arg.substr(10).c_str());
|
||||
argPos++;
|
||||
}
|
||||
|
||||
else if (arg.find("--max-lon=") == 0) {
|
||||
bounds.maxX = atof(arg.substr(10).c_str());
|
||||
argPos++;
|
||||
}
|
||||
|
||||
else if (arg.find("--max-lat=") == 0) {
|
||||
bounds.maxY = atof(arg.substr(10).c_str());
|
||||
argPos++;
|
||||
}
|
||||
|
||||
else if (arg.find("--area=") == 0) {
|
||||
areaType = get_area_type(arg.substr(7).c_str());
|
||||
argPos++;
|
||||
}
|
||||
|
||||
else if (arg.find("--point-width=") == 0) {
|
||||
pointWidth = atoi(arg.substr(14).c_str());
|
||||
argPos++;
|
||||
}
|
||||
|
||||
else if (arg.find("--line-width=") == 0) {
|
||||
lineWidth = atoi(arg.substr(13).c_str());
|
||||
argPos++;
|
||||
}
|
||||
|
||||
else if (arg.find("--work-dir=") == 0) {
|
||||
workDir = arg.substr(11);
|
||||
argPos++;
|
||||
}
|
||||
|
||||
else if (arg.find("--aat=") == 0) {
|
||||
Attribute att;
|
||||
parseAttribute(argv[0], arg.substr(6), att);
|
||||
aat_list.push_back(att);
|
||||
cout << "Added polygon constraint for " << att.file << ": "
|
||||
<< att.item << '=' << att.value << endl;
|
||||
argPos++;
|
||||
}
|
||||
|
||||
else if (arg.find("--pat=") == 0) {
|
||||
Attribute att;
|
||||
parseAttribute(argv[0], arg.substr(6), att);
|
||||
pat_list.push_back(att);
|
||||
cout << "Added polygon constraint for " << att.file << ": "
|
||||
<< att.item << '=' << att.value << endl;
|
||||
argPos++;
|
||||
}
|
||||
|
||||
else if (arg == "--") {
|
||||
argPos++;
|
||||
break;
|
||||
}
|
||||
|
||||
else if (arg.find("-") == 0) {
|
||||
cerr << "Unrecognized option: " << arg << endl;
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for files to process
|
||||
if (argPos >= argc) {
|
||||
cerr << "No e00 files specified!!" << endl;
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
cout << "Bounds are " << bounds << endl;
|
||||
cout << "Area type is " << get_area_name(areaType) << endl;;
|
||||
cout << "Working directory is " << workDir << endl;
|
||||
if (usePoints)
|
||||
cout << "Using points with width " << pointWidth << " meters" << endl;
|
||||
else
|
||||
cout << "Ignoring point coverage" << endl;
|
||||
if (useLines)
|
||||
cout << "Using lines with width " << lineWidth << " meters" << endl;
|
||||
else
|
||||
cout << "Ignoring line coverage" << endl;
|
||||
if (usePolygons)
|
||||
cout << "Using polygons" << endl;
|
||||
else
|
||||
cout << "Ignoring polygon coverage" << endl;
|
||||
if (useLines && aat_list.size() > 0) {
|
||||
cout << "Lines must match at least one of the following:" << endl;
|
||||
for (int i = 0; i < aat_list.size(); i++) {
|
||||
cout << aat_list[i].file << ' ' << aat_list[i].item << ' '
|
||||
<< aat_list[i].value << endl;
|
||||
}
|
||||
}
|
||||
if (usePolygons && pat_list.size() > 0) {
|
||||
cout << "Polygons must match at least one of the following:" << endl;
|
||||
for (int i = 0; i < pat_list.size(); i++) {
|
||||
cout << pat_list[i].file << ' ' << pat_list[i].item << ' '
|
||||
<< pat_list[i].value << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the destination
|
||||
// directory exists.
|
||||
#ifdef _MSC_VER
|
||||
fg_mkdir(workDir.c_str());
|
||||
#else
|
||||
string command = "mkdir -p " + workDir;
|
||||
system(command.c_str());
|
||||
#endif
|
||||
|
||||
// Process all of the e00 files
|
||||
// on the command line.
|
||||
while (argPos < argc) {
|
||||
|
||||
cout << "Processing " << argv[argPos] << endl;
|
||||
|
||||
// Grab command-line arguments.
|
||||
fg_gzifstream input(argv[argPos]);
|
||||
if ( !input.good() ) {
|
||||
FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << argv[argPos]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// Read the E00 file.
|
||||
|
||||
E00 data;
|
||||
try {
|
||||
data.readE00(input);
|
||||
} catch (E00Exception &e) {
|
||||
FG_LOG(FG_GENERAL, FG_ALERT, "Reading " << argv[argPos]
|
||||
<< " failed with exception " << e.getMessage());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Initialize the persistant polygon counter.
|
||||
string counter_file = workDir + "/../poly_counter";
|
||||
poly_index_init( counter_file );
|
||||
|
||||
if (usePoints)
|
||||
processPoints(data, bounds, areaType, workDir, pointWidth);
|
||||
|
||||
if (useLines)
|
||||
processLines(data, bounds, areaType, workDir, lineWidth, aat_list);
|
||||
|
||||
if (usePolygons)
|
||||
processPolygons(data, bounds, areaType, workDir, pat_list);
|
||||
|
||||
cout << "Done processing " << argv[argPos] << endl;
|
||||
argPos++;
|
||||
}
|
||||
|
||||
cout << "Done all processing." << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue