1
0
Fork 0

remove_dups() cleanup function would miss 2D dups with different elevations.

- created a new function that will take the higher elevated dup
(as most are ar -9999.0 at initialization.  Use the one with real elevation data)

Fixes UMNB
This commit is contained in:
Peter Sadrozinski 2012-02-05 10:13:15 -05:00 committed by Christian Schmitt
parent 9f96783df6
commit ff352fad28
3 changed files with 149 additions and 2 deletions

View file

@ -669,6 +669,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
poly = remove_bad_contours( poly ); poly = remove_bad_contours( poly );
poly = remove_tiny_contours( poly ); poly = remove_tiny_contours( poly );
poly = remove_spikes( poly ); poly = remove_spikes( poly );
poly = remove_dups( poly );
poly = remove_bad_contours( poly ); poly = remove_bad_contours( poly );
rwy_polys[k].set_poly( poly ); rwy_polys[k].set_poly( poly );
@ -685,6 +686,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
poly = remove_bad_contours( poly ); poly = remove_bad_contours( poly );
poly = remove_tiny_contours( poly ); poly = remove_tiny_contours( poly );
poly = remove_spikes( poly ); poly = remove_spikes( poly );
poly = remove_dups( poly );
poly = remove_bad_contours( poly ); poly = remove_bad_contours( poly );
pvmt_polys[k].set_poly( poly ); pvmt_polys[k].set_poly( poly );
@ -701,6 +703,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
poly = remove_bad_contours( poly ); poly = remove_bad_contours( poly );
poly = remove_tiny_contours( poly ); poly = remove_tiny_contours( poly );
poly = remove_spikes( poly ); poly = remove_spikes( poly );
poly = remove_dups( poly );
poly = remove_bad_contours( poly ); poly = remove_bad_contours( poly );
line_polys[k].set_poly( poly ); line_polys[k].set_poly( poly );
@ -722,6 +725,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
base_poly = remove_bad_contours( base_poly ); base_poly = remove_bad_contours( base_poly );
base_poly = remove_tiny_contours( base_poly ); base_poly = remove_tiny_contours( base_poly );
base_poly = remove_spikes( base_poly ); base_poly = remove_spikes( base_poly );
base_poly = remove_dups( base_poly );
base_poly = remove_bad_contours( base_poly ); base_poly = remove_bad_contours( base_poly );
gettimeofday(&cleanup_end, NULL); gettimeofday(&cleanup_end, NULL);
@ -737,7 +741,15 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
TGPolygon poly = rwy_polys[i].get_poly(); TGPolygon poly = rwy_polys[i].get_poly();
#if 0 #if 0
if ( i == 162 ) { if ( i == 2 ) {
SG_LOG(SG_GENERAL, SG_INFO, "Problem poly before remove_dups: " << poly );
sglog().setLogLevels( SG_GENERAL, SG_BULK );
poly = remove_dups( poly );
sglog().setLogLevels( SG_GENERAL, SG_INFO );
SG_LOG(SG_GENERAL, SG_INFO, "Problem poly after remove_dups(): " << poly );
tgChopNormalPolygon( "/home/pete", "Base", poly, false ); tgChopNormalPolygon( "/home/pete", "Base", poly, false );
verbose_triangulation = true; verbose_triangulation = true;

View file

@ -132,6 +132,9 @@ public:
// Special functions // Special functions
double distance3D(const Point3D& a) const; // distance between double distance3D(const Point3D& a) const; // distance between
double distance3Dsquared(const Point3D& a) const; // distance between ^ 2 double distance3Dsquared(const Point3D& a) const; // distance between ^ 2
bool IsEqual2D(const Point3D& a) const; // equality check in X,Y only
bool HasElevation() const; // does point have elevation data?
}; };
@ -377,6 +380,19 @@ inline SGVec2f Point3D::toSGVec2f(void) const
return SGVec2f(x(), y()); return SGVec2f(x(), y());
} }
inline bool Point3D::IsEqual2D(const Point3D& a) const
{
return
fabs(a.n[PX] - n[PX]) < fgPoint3_Epsilon &&
fabs(a.n[PY] - n[PY]) < fgPoint3_Epsilon;
}
inline bool Point3D::HasElevation() const
{
return fabs( n[PZ] + 9999.0 > fgPoint3_Epsilon );
}
// FRIENDS // FRIENDS
inline Point3D operator - (const Point3D& a) inline Point3D operator - (const Point3D& a)

View file

@ -761,7 +761,7 @@ void calc_points_inside( TGPolygon& p ) {
delete ct; delete ct;
} }
#if 0
// remove duplicate nodes in a polygon should they exist. Returns the // remove duplicate nodes in a polygon should they exist. Returns the
// fixed polygon // fixed polygon
TGPolygon remove_dups( const TGPolygon &poly ) { TGPolygon remove_dups( const TGPolygon &poly ) {
@ -808,7 +808,124 @@ TGPolygon remove_dups( const TGPolygon &poly ) {
return result; return result;
} }
#endif
static point_list remove_contour_dups( const point_list& contour ) {
point_list result;
result.clear();
int iters = 0;
bool found;
unsigned int cur, next;
for ( unsigned int i = 0; i < contour.size(); i++ )
{
result.push_back( contour[i] );
}
SG_LOG(SG_GENERAL, SG_DEBUG, "remove contour dups : original contour has " << result.size() << " points" );
do
{
SG_LOG(SG_GENERAL, SG_DEBUG, "remove_contour_dups: start new iteration");
found = false;
// Step 1 - find a neighboring duplicate point
for ( unsigned int i = 0; i < result.size() && !found; i++ ) {
if (i == result.size()-1 ) {
cur = i;
next = 0;
SG_LOG(SG_GENERAL, SG_DEBUG, " cur is last point: " << cur << ": " << result[cur] << " next is first point: " << next << result[next] );
} else {
cur = i;
next = i+1;
SG_LOG(SG_GENERAL, SG_DEBUG, " cur is: " << cur << ": " << result[cur] << " next is : " << next << result[next] );
}
if ( result[cur].IsEqual2D( result[next] ) ) {
// keep the point with higher Z
if ( result[cur].z() < result[next].z() ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "remove_contour_dups: erasing " << result[cur] );
result.erase( result.begin()+cur );
} else {
SG_LOG(SG_GENERAL, SG_DEBUG, "remove_contour_dups: erasing " << result[next] );
result.erase( result.begin()+next );
}
found = true;
}
}
iters++;
SG_LOG(SG_GENERAL, SG_DEBUG, "remove_contour_dups : after " << iters << "iterations, contour has " << result.size() << " points" );
} while( found );
return result;
}
TGPolygon remove_dups( const TGPolygon& poly )
{
TGPolygon result;
// cout << "remove dups: " << poly << endl;
for ( int i = 0; i < poly.contours(); ++i ) {
point_list contour = poly.get_contour(i);
contour = remove_contour_dups( contour );
result.add_contour( contour, poly.get_hole_flag(i) );
}
return result;
}
#if 0 // fails to remove dupes with different Z
// remove duplicate nodes in a polygon should they exist. Returns the
// fixed polygon
TGPolygon remove_dups( const TGPolygon &poly ) {
TGPolygon result;
point_list contour, new_contour;
result.erase();
TGPolygon tmp = poly;
for ( int i = 0; i < tmp.contours(); ++i ) {
contour = poly.get_contour( i );
// cout << "testing contour " << i << " size = " << contour.size()
// << " hole = " << poly.get_hole_flag( i ) << endl;
bool have_dups = true;
while ( have_dups && contour.size() ) {
have_dups = false;
new_contour.clear();
Point3D last = contour[ contour.size() - 1 ];
for ( int j = 0; j < (int)contour.size(); ++j ) {
// cout << " " << i << " " << j << endl;
Point3D cur = contour[j];
if ( cur == last ) {
have_dups = true;
// cout << "skipping a duplicate point" << endl;
} else {
new_contour.push_back( cur );
last = cur;
}
}
contour = new_contour;
}
// cout << " final size = " << contour.size() << endl;
if ( contour.size() ) {
int flag = poly.get_hole_flag( i );
result.add_contour( contour, flag );
} else {
// too small an area ... add a token point to the contour
// to keep other things happy, but this "bad" contour will
// get nuked later
result.add_node( i, poly.get_pt( i, 0 ) );
}
}
return result;
}
#endif
static inline double static inline double
snap (double value, double grid_size) snap (double value, double grid_size)
@ -1258,6 +1375,8 @@ static point_list remove_contour_spikes( const point_list& contour ) {
result.push_back( contour[i] ); result.push_back( contour[i] );
} }
SG_LOG(SG_GENERAL, SG_DEBUG, "remove contour spikes : original contour has " << result.size() << " points" );
do do
{ {
SG_LOG(SG_GENERAL, SG_DEBUG, "remove_contour_spikes: start new iteration"); SG_LOG(SG_GENERAL, SG_DEBUG, "remove_contour_spikes: start new iteration");