Dynamically update "error" until the resulting tile data scales within
a lower and upper bounds.
This commit is contained in:
parent
773d67b823
commit
b18c82c33b
5 changed files with 105 additions and 15 deletions
|
@ -26,6 +26,7 @@
|
||||||
#include <dirent.h> // for directory reading
|
#include <dirent.h> // for directory reading
|
||||||
|
|
||||||
#include <Bucket/newbucket.hxx>
|
#include <Bucket/newbucket.hxx>
|
||||||
|
#include <Include/fg_constants.h>
|
||||||
|
|
||||||
#include <Debug/logstream.hxx>
|
#include <Debug/logstream.hxx>
|
||||||
#include <Array/array.hxx>
|
#include <Array/array.hxx>
|
||||||
|
@ -46,15 +47,18 @@ int load_dem(const string& work_base, FGBucket& b, FGArray& array) {
|
||||||
|
|
||||||
if ( ! array.open(dem_path) ) {
|
if ( ! array.open(dem_path) ) {
|
||||||
cout << "ERROR: cannot open " << dem_path << endl;
|
cout << "ERROR: cannot open " << dem_path << endl;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
array.parse();
|
array.parse( b );
|
||||||
array.fit( 200 );
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fit dem nodes, return number of fitted nodes
|
||||||
|
int fit_dem(FGArray& array, int error) {
|
||||||
|
return array.fit( error );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// do actual scan of directory and loading of files
|
// do actual scan of directory and loading of files
|
||||||
int actual_load_polys( const string& dir, FGBucket& b, FGClipper& clipper ) {
|
int actual_load_polys( const string& dir, FGBucket& b, FGClipper& clipper ) {
|
||||||
|
@ -165,17 +169,65 @@ void construct_tile( const string& work_base, const string& output_base,
|
||||||
{
|
{
|
||||||
cout << "Construct tile, bucket = " << b << endl;
|
cout << "Construct tile, bucket = " << b << endl;
|
||||||
|
|
||||||
|
// fit with ever increasing error tolerance until we produce <=
|
||||||
|
// 80% of max nodes. We should really have the sim end handle
|
||||||
|
// arbitrarily complex tiles.
|
||||||
|
|
||||||
|
const int min_nodes = 50;
|
||||||
|
const int max_nodes = (int)(MAX_NODES * 0.8);
|
||||||
|
|
||||||
|
bool acceptable = false;
|
||||||
|
double error = 200.0;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
// load and fit grid of elevation data
|
// load and fit grid of elevation data
|
||||||
FGArray array;
|
FGArray array;
|
||||||
load_dem( work_base, b, array );
|
load_dem( work_base, b, array );
|
||||||
|
|
||||||
// load and clip 2d polygon data
|
|
||||||
FGClipper clipper;
|
|
||||||
load_polys( work_base, b, clipper );
|
|
||||||
|
|
||||||
// triangulate the data for each polygon
|
|
||||||
FGTriangle t;
|
FGTriangle t;
|
||||||
do_triangulate( array, clipper, t );
|
|
||||||
|
while ( ! acceptable ) {
|
||||||
|
// fit the data
|
||||||
|
array.fit( error );
|
||||||
|
|
||||||
|
// load and clip 2d polygon data
|
||||||
|
FGClipper clipper;
|
||||||
|
load_polys( work_base, b, clipper );
|
||||||
|
|
||||||
|
// triangulate the data for each polygon
|
||||||
|
do_triangulate( array, clipper, t );
|
||||||
|
|
||||||
|
acceptable = true;
|
||||||
|
|
||||||
|
count = t.get_out_nodes_size();
|
||||||
|
|
||||||
|
if ( (count < min_nodes) && (error >= 25.0) ) {
|
||||||
|
// reduce error tolerance until number of points exceeds the
|
||||||
|
// minimum threshold
|
||||||
|
cout << "produced too few nodes ..." << endl;
|
||||||
|
|
||||||
|
acceptable = false;
|
||||||
|
|
||||||
|
error /= 1.5;
|
||||||
|
cout << "Setting error to " << error << " and retrying fit."
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (count > max_nodes) && (error <= 1000.0) ) {
|
||||||
|
// increase error tolerance until number of points drops below
|
||||||
|
// the maximum threshold
|
||||||
|
cout << "produced too many nodes ..." << endl;
|
||||||
|
|
||||||
|
acceptable = false;
|
||||||
|
|
||||||
|
error *= 1.5;
|
||||||
|
cout << "Setting error to " << error << " and retrying fit."
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "finished fit with error = " << error << " node count = "
|
||||||
|
<< count << endl;
|
||||||
|
|
||||||
// generate the output
|
// generate the output
|
||||||
FGGenOutput output;
|
FGGenOutput output;
|
||||||
|
@ -207,15 +259,16 @@ main(int argc, char **argv) {
|
||||||
// lon = -90.757128; lat = 46.790212; // WI32
|
// lon = -90.757128; lat = 46.790212; // WI32
|
||||||
// lon = -122.220717; lat = 37.721291; // KOAK
|
// lon = -122.220717; lat = 37.721291; // KOAK
|
||||||
// lon = -111.721477; lat = 40.215641; // KPVU
|
// lon = -111.721477; lat = 40.215641; // KPVU
|
||||||
lon = -122.309313; lat = 47.448982; // KSEA
|
// lon = -122.309313; lat = 47.448982; // KSEA
|
||||||
|
lon = -148.798131; lat = 63.645099; // AK06 (Danali, AK)
|
||||||
|
|
||||||
double min_x = lon - 1;
|
double min_x = lon - 3;
|
||||||
double min_y = lat - 1;
|
double min_y = lat - 1;
|
||||||
FGBucket b_min( min_x, min_y );
|
FGBucket b_min( min_x, min_y );
|
||||||
FGBucket b_max( lon + 1, lat + 1 );
|
FGBucket b_max( lon + 3, lat + 1 );
|
||||||
|
|
||||||
FGBucket b_omit(550314L);
|
FGBucket b_omit(550314L);
|
||||||
// FGBucket b(942698L);
|
// FGBucket b(517745L);
|
||||||
// FGBucket b(-146.248360, 61.133950);
|
// FGBucket b(-146.248360, 61.133950);
|
||||||
// construct_tile( work_base, output_base, b );
|
// construct_tile( work_base, output_base, b );
|
||||||
// exit(0);
|
// exit(0);
|
||||||
|
@ -245,6 +298,10 @@ main(int argc, char **argv) {
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.18 1999/04/05 02:16:51 curt
|
||||||
|
// Dynamically update "error" until the resulting tile data scales within
|
||||||
|
// a lower and upper bounds.
|
||||||
|
//
|
||||||
// Revision 1.17 1999/04/03 05:22:57 curt
|
// Revision 1.17 1999/04/03 05:22:57 curt
|
||||||
// Found a bug in dividing and adding unique verticle segments which could
|
// Found a bug in dividing and adding unique verticle segments which could
|
||||||
// cause the triangulator to end up in an infinite loop. Basically the code
|
// cause the triangulator to end up in an infinite loop. Basically the code
|
||||||
|
|
|
@ -44,6 +44,9 @@ FGTriangle::build( const point_list& corner_list,
|
||||||
FGTriPoly poly;
|
FGTriPoly poly;
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
|
in_nodes.clear();
|
||||||
|
trisegs.clear();
|
||||||
|
|
||||||
// Point3D junkp;
|
// Point3D junkp;
|
||||||
// int junkc = 0;
|
// int junkc = 0;
|
||||||
// char junkn[256];
|
// char junkn[256];
|
||||||
|
@ -70,6 +73,8 @@ FGTriangle::build( const point_list& corner_list,
|
||||||
cout << "prepairing node list and polygons" << endl;
|
cout << "prepairing node list and polygons" << endl;
|
||||||
|
|
||||||
for ( int i = 0; i < FG_MAX_AREA_TYPES; ++i ) {
|
for ( int i = 0; i < FG_MAX_AREA_TYPES; ++i ) {
|
||||||
|
polylist[i].clear();
|
||||||
|
|
||||||
// cout << "area type = " << i << endl;
|
// cout << "area type = " << i << endl;
|
||||||
current = gpc_polys.polys[i].begin();
|
current = gpc_polys.polys[i].begin();
|
||||||
last = gpc_polys.polys[i].end();
|
last = gpc_polys.polys[i].end();
|
||||||
|
@ -328,7 +333,7 @@ int FGTriangle::run_triangulate() {
|
||||||
vorout.normlist = (REAL *) NULL; // Needed only if -v switch used.
|
vorout.normlist = (REAL *) NULL; // Needed only if -v switch used.
|
||||||
|
|
||||||
// TEMPORARY
|
// TEMPORARY
|
||||||
write_out_data(&in);
|
// write_out_data(&in);
|
||||||
|
|
||||||
// Triangulate the points. Switches are chosen to read and write
|
// Triangulate the points. Switches are chosen to read and write
|
||||||
// a PSLG (p), preserve the convex hull (c), number everything
|
// a PSLG (p), preserve the convex hull (c), number everything
|
||||||
|
@ -343,12 +348,13 @@ int FGTriangle::run_triangulate() {
|
||||||
triangulate(tri_options.c_str(), &in, &out, &vorout);
|
triangulate(tri_options.c_str(), &in, &out, &vorout);
|
||||||
|
|
||||||
// TEMPORARY
|
// TEMPORARY
|
||||||
// write_out_data(&out);
|
write_out_data(&out);
|
||||||
|
|
||||||
// now copy the results back into the corresponding FGTriangle
|
// now copy the results back into the corresponding FGTriangle
|
||||||
// structures
|
// structures
|
||||||
|
|
||||||
// nodes
|
// nodes
|
||||||
|
out_nodes.clear();
|
||||||
for ( int i = 0; i < out.numberofpoints; i++ ) {
|
for ( int i = 0; i < out.numberofpoints; i++ ) {
|
||||||
Point3D p( out.pointlist[2*i], out.pointlist[2*i + 1], 0.0 );
|
Point3D p( out.pointlist[2*i], out.pointlist[2*i + 1], 0.0 );
|
||||||
// cout << "point = " << p << endl;
|
// cout << "point = " << p << endl;
|
||||||
|
@ -356,6 +362,7 @@ int FGTriangle::run_triangulate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// triangles
|
// triangles
|
||||||
|
elelist.clear();
|
||||||
int n1, n2, n3;
|
int n1, n2, n3;
|
||||||
double attribute;
|
double attribute;
|
||||||
for ( int i = 0; i < out.numberoftriangles; i++ ) {
|
for ( int i = 0; i < out.numberoftriangles; i++ ) {
|
||||||
|
@ -398,6 +405,10 @@ int FGTriangle::run_triangulate() {
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.16 1999/04/05 02:17:11 curt
|
||||||
|
// Dynamically update "error" until the resulting tile data scales within
|
||||||
|
// a lower and upper bounds.
|
||||||
|
//
|
||||||
// Revision 1.15 1999/04/03 05:22:58 curt
|
// Revision 1.15 1999/04/03 05:22:58 curt
|
||||||
// Found a bug in dividing and adding unique verticle segments which could
|
// Found a bug in dividing and adding unique verticle segments which could
|
||||||
// cause the triangulator to end up in an infinite loop. Basically the code
|
// cause the triangulator to end up in an infinite loop. Basically the code
|
||||||
|
|
|
@ -84,6 +84,7 @@ public:
|
||||||
int run_triangulate();
|
int run_triangulate();
|
||||||
|
|
||||||
inline FGTriNodes get_out_nodes() const { return out_nodes; }
|
inline FGTriNodes get_out_nodes() const { return out_nodes; }
|
||||||
|
inline size_t get_out_nodes_size() const { return out_nodes.size(); }
|
||||||
inline triele_list get_elelist() const { return elelist; }
|
inline triele_list get_elelist() const { return elelist; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -92,6 +93,10 @@ public:
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.11 1999/04/05 02:17:12 curt
|
||||||
|
// Dynamically update "error" until the resulting tile data scales within
|
||||||
|
// a lower and upper bounds.
|
||||||
|
//
|
||||||
// Revision 1.10 1999/03/29 13:11:08 curt
|
// Revision 1.10 1999/03/29 13:11:08 curt
|
||||||
// Shuffled stl type names a bit.
|
// Shuffled stl type names a bit.
|
||||||
// Began adding support for tri-fanning (or maybe other arrangments too.)
|
// Began adding support for tri-fanning (or maybe other arrangments too.)
|
||||||
|
|
|
@ -62,6 +62,9 @@ public:
|
||||||
FGTriNodes( void );
|
FGTriNodes( void );
|
||||||
~FGTriNodes( void );
|
~FGTriNodes( void );
|
||||||
|
|
||||||
|
// delete all the data out of node_list
|
||||||
|
inline void clear() { node_list.clear(); }
|
||||||
|
|
||||||
// Add a point to the point list if it doesn't already exist.
|
// Add a point to the point list if it doesn't already exist.
|
||||||
// Returns the index (starting at zero) of the point in the list.
|
// Returns the index (starting at zero) of the point in the list.
|
||||||
int unique_add( const Point3D& p );
|
int unique_add( const Point3D& p );
|
||||||
|
@ -79,6 +82,9 @@ public:
|
||||||
|
|
||||||
// return the ith point
|
// return the ith point
|
||||||
inline Point3D get_node( int i ) const { return node_list[i]; }
|
inline Point3D get_node( int i ) const { return node_list[i]; }
|
||||||
|
|
||||||
|
// return the size of the node list
|
||||||
|
inline size_t size() const { return node_list.size(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,6 +118,10 @@ inline bool FGTriNodes::course_close_enough( const Point3D& p1,
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.8 1999/04/05 02:17:13 curt
|
||||||
|
// Dynamically update "error" until the resulting tile data scales within
|
||||||
|
// a lower and upper bounds.
|
||||||
|
//
|
||||||
// Revision 1.7 1999/03/29 13:11:10 curt
|
// Revision 1.7 1999/03/29 13:11:10 curt
|
||||||
// Shuffled stl type names a bit.
|
// Shuffled stl type names a bit.
|
||||||
// Began adding support for tri-fanning (or maybe other arrangments too.)
|
// Began adding support for tri-fanning (or maybe other arrangments too.)
|
||||||
|
|
|
@ -93,6 +93,9 @@ public:
|
||||||
FGTriSegments( void );
|
FGTriSegments( void );
|
||||||
~FGTriSegments( void );
|
~FGTriSegments( void );
|
||||||
|
|
||||||
|
// delete all the data out of seg_list
|
||||||
|
inline void clear() { seg_list.clear(); }
|
||||||
|
|
||||||
// Add a segment to the segment list if it doesn't already exist.
|
// Add a segment to the segment list if it doesn't already exist.
|
||||||
// Returns the index (starting at zero) of the segment in the
|
// Returns the index (starting at zero) of the segment in the
|
||||||
// list.
|
// list.
|
||||||
|
@ -115,6 +118,10 @@ public:
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.4 1999/04/05 02:17:14 curt
|
||||||
|
// Dynamically update "error" until the resulting tile data scales within
|
||||||
|
// a lower and upper bounds.
|
||||||
|
//
|
||||||
// Revision 1.3 1999/03/27 05:30:18 curt
|
// Revision 1.3 1999/03/27 05:30:18 curt
|
||||||
// Handle corner nodes separately from the rest of the fitted nodes.
|
// Handle corner nodes separately from the rest of the fitted nodes.
|
||||||
// Add fitted nodes in after corners and polygon nodes since the fitted nodes
|
// Add fitted nodes in after corners and polygon nodes since the fitted nodes
|
||||||
|
|
Loading…
Add table
Reference in a new issue