1
0
Fork 0

Added tgPolygonExpand() to grow / shrink polygons using clipper library.

- used to expand pavement polygons so they overlap slightly (5cm)
  This prevents slivers being formed between pavements when designers
  add their own taxiway shoulders, and try to line them up instead of
  placing the boundary 'under' the taxiway.
- also useed to create the default airport base.  This allows the base
  to follow the taxiways better - allowing concave boundaries, instead
  of the previous convex hull.

Memory leaks squashed.  Fixed several memory leaks reported by valgrind.
- GenApt850 can now run forever (or at least until it segfaults)

Very long linear segments in linear features are now broken up to
avoid triangulation errors

Added back some clipper boolean operations (diff and union).  These can
be used instead of the GPC functions by using tgPolyGonDiffClipper and
tgPolygonUnionClipper.  GPC had crashed in a few airports when clipping
linear features.  Using the clipper routines don't crash.  More investigation
is needed.  It may be something about the polygons being clipped more that
the clipping action itself.  In these problem airports, there are some
linear features extending far from the airport.
( I had thought those issues were fixed :( )

More warning cleanups.
This commit is contained in:
Peter Sadrozinski 2012-01-28 16:45:41 -05:00 committed by Christian Schmitt
parent 00afd0cb17
commit 372cbdf38f
16 changed files with 607 additions and 528 deletions

View file

@ -33,7 +33,7 @@ Airport::Airport( int c, char* def)
{
int numParams;
char* tok;
int x, y;
int ct = 0;
code = c;
@ -59,11 +59,11 @@ Airport::Airport( int c, char* def)
break;
case 1:
x = atoi(tok);
ct = atoi(tok);
break;
case 2:
y = atoi(tok);
// deprecated - ignore
break;
case 3:
@ -79,7 +79,60 @@ Airport::Airport( int c, char* def)
altitude *= SG_FEET_TO_METER;
boundary = NULL;
SG_LOG( SG_GENERAL, SG_DEBUG, "Created airport with icao " << icao << " and description " << description );
SG_LOG( SG_GENERAL, SG_DEBUG, "Created airport with icao " << icao << ", control tower " << ct << ", and description " << description );
}
Airport::~Airport()
{
for (unsigned int i=0; i<features.size(); i++)
{
delete features[i];
}
for (unsigned int i=0; i<helipads.size(); i++)
{
delete helipads[i];
}
for (unsigned int i=0; i<runways.size(); i++)
{
delete runways[i];
}
for (unsigned int i=0; i<waterrunways.size(); i++)
{
delete waterrunways[i];
}
for (unsigned int i=0; i<pavements.size(); i++)
{
delete pavements[i];
}
for (unsigned int i=0; i<lightobjects.size(); i++)
{
delete lightobjects[i];
}
for (unsigned int i=0; i<windsocks.size(); i++)
{
delete windsocks[i];
}
for (unsigned int i=0; i<beacons.size(); i++)
{
delete beacons[i];
}
for (unsigned int i=0; i<signs.size(); i++)
{
delete signs[i];
}
if (boundary)
{
delete boundary;
}
}
// TODO: Add to runway object
@ -322,7 +375,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
superpoly_list line_polys;
texparams_list line_tps;
int i, j, k;
// int i, j, k;
Point3D p;
bool verbose_triangulation = false;
@ -340,13 +393,13 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
// Find the average of all the runway and heliport long / lats
int num_samples = 0;
for (i=0; i<runways.size(); i++)
for (unsigned int i=0; i<runways.size(); i++)
{
apt_lon += runways[i]->GetMidpoint().x();
apt_lat += runways[i]->GetMidpoint().y();
num_samples++;
}
for (i=0; i<helipads.size(); i++)
for (unsigned int i=0; i<helipads.size(); i++)
{
apt_lon += helipads[i]->GetLoc().x();
apt_lat += helipads[i]->GetLoc().y();
@ -364,7 +417,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
// If we are cutting in the linear features, add them first
if (pavements.size())
{
for ( i=0; i<pavements.size(); i++ )
for ( unsigned int i=0; i<pavements.size(); i++ )
{
AddFeatures( pavements[i]->GetFeatures() );
}
@ -376,7 +429,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
// Add the linear features
if (features.size())
{
for ( i=0; i<features.size(); i++ )
for ( unsigned int i=0; i<features.size(); i++ )
{
SG_LOG(SG_GENERAL, SG_INFO, "Build Feature Poly " << i << " of " << features.size() << " : " << features[i]->GetDescription() );
@ -394,7 +447,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
SG_LOG( SG_GENERAL, SG_ALERT, "Finished building Linear Features for " << icao << " at " << ctime(&log_time.tv_sec) );
// Build runways next
for (i=0; i<runways.size(); i++ )
for ( unsigned int i=0; i<runways.size(); i++ )
{
SG_LOG(SG_GENERAL, SG_INFO, "Build Runway " << i << " of " << runways.size());
@ -416,7 +469,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
if (lightobjects.size())
{
for ( i=0; i<lightobjects.size(); i++ )
for ( unsigned int i=0; i<lightobjects.size(); i++ )
{
SG_LOG(SG_GENERAL, SG_INFO, "Build runway light " << i << " of " << lightobjects.size());
@ -427,10 +480,10 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
// Build helipads (use runway poly- and texture list for this)
if (helipads.size())
{
SG_LOG(SG_GENERAL, SG_DEBUG, "Build helipad " << i << " of " << helipads.size());
for (i=0; i<helipads.size(); i++ )
for ( unsigned int i=0; i<helipads.size(); i++ )
{
SG_LOG(SG_GENERAL, SG_INFO, "Build helipad " << i << " of " << helipads.size());
if (boundary)
{
helipads[i]->BuildBtg( altitude, &rwy_polys, &rwy_tps, &rwy_lights, &accum, NULL, NULL );
@ -445,9 +498,9 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
// Build the pavements
if (pavements.size())
{
for ( i=0; i<pavements.size(); i++ )
for ( unsigned int i=0; i<pavements.size(); i++ )
{
SG_LOG(SG_GENERAL, SG_DEBUG, "Build Pavement " << i << " of " << pavements.size() << " : " << pavements[i]->GetDescription());
SG_LOG(SG_GENERAL, SG_INFO, "Build Pavement " << i << " of " << pavements.size() << " : " << pavements[i]->GetDescription());
if (boundary)
{
@ -468,9 +521,9 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
SG_LOG( SG_GENERAL, SG_ALERT, "Finished building pavements for " << icao << " at " << ctime(&log_time.tv_sec) );
// Build runway shoulders here
for (i=0; i<runways.size(); i++ )
for ( unsigned int i=0; i<runways.size(); i++ )
{
SG_LOG(SG_GENERAL, SG_DEBUG, "Build Runway shoulder " << i << " of " << runways.size());
SG_LOG(SG_GENERAL, SG_INFO, "Build Runway shoulder " << i << " of " << runways.size());
if ( runways[i]->GetsShoulder() )
{
@ -481,7 +534,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
// build the base and clearing if there's a boundary
if (boundary)
{
SG_LOG(SG_GENERAL, SG_DEBUG, "Build user defined boundary " );
SG_LOG(SG_GENERAL, SG_INFO, "Build user defined boundary " );
boundary->BuildBtg( altitude, &apt_base, &apt_clearing );
}
@ -508,12 +561,12 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
// build temporary node list from runways...
SG_LOG(SG_GENERAL, SG_INFO, "Build Node List " );
for ( k = 0; k < (int)rwy_polys.size(); ++k )
for ( unsigned int k = 0; k < rwy_polys.size(); ++k )
{
TGPolygon poly = rwy_polys[k].get_poly();
for ( i = 0; i < poly.contours(); ++i )
for ( int i = 0; i < poly.contours(); ++i )
{
for ( j = 0; j < poly.contour_size( i ); ++j )
for ( int j = 0; j < poly.contour_size( i ); ++j )
{
tmp_nodes.unique_add( poly.get_pt(i, j) );
//tmp_nodes.course_add( poly.get_pt(i, j) );
@ -522,12 +575,12 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
}
// and pavements
for ( k = 0; k < (int)pvmt_polys.size(); ++k )
for ( unsigned int k = 0; k < pvmt_polys.size(); ++k )
{
TGPolygon poly = pvmt_polys[k].get_poly();
for ( i = 0; i < poly.contours(); ++i )
for ( int i = 0; i < poly.contours(); ++i )
{
for ( j = 0; j < poly.contour_size( i ); ++j )
for ( int j = 0; j < poly.contour_size( i ); ++j )
{
tmp_nodes.unique_add( poly.get_pt(i, j) );
//tmp_nodes.course_add( poly.get_pt(i, j) );
@ -536,12 +589,12 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
}
// and linear features
for ( k = 0; k < (int)line_polys.size(); ++k )
for ( unsigned int k = 0; k < line_polys.size(); ++k )
{
TGPolygon poly = line_polys[k].get_poly();
for ( i = 0; i < poly.contours(); ++i )
for ( int i = 0; i < poly.contours(); ++i )
{
for ( j = 0; j < poly.contour_size( i ); ++j )
for ( int j = 0; j < poly.contour_size( i ); ++j )
{
tmp_nodes.unique_add( poly.get_pt(i, j) );
//tmp_nodes.course_add( poly.get_pt(i, j) );
@ -550,9 +603,9 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
}
// and the base
for ( i = 0; i < base_poly.contours(); ++i )
for ( int i = 0; i < base_poly.contours(); ++i )
{
for ( j = 0; j < base_poly.contour_size( i ); ++j )
for ( int j = 0; j < base_poly.contour_size( i ); ++j )
{
tmp_nodes.unique_add( base_poly.get_pt(i, j) );
//tmp_nodes.course_add( base_poly.get_pt(i, j) );
@ -561,9 +614,9 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
// the divided base could contain points not found in base_poly,
// so we should add them because the skirt needs them.
for ( i = 0; i < divided_base.contours(); ++i )
for ( int i = 0; i < divided_base.contours(); ++i )
{
for ( j = 0; j < divided_base.contour_size( i ); ++j )
for ( int j = 0; j < divided_base.contour_size( i ); ++j )
{
tmp_nodes.unique_add( divided_base.get_pt(i, j) );
//tmp_nodes.course_add( divided_base.get_pt(i, j) );
@ -574,7 +627,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
SG_LOG( SG_GENERAL, SG_ALERT, "Finished collecting nodes for " << icao << " at " << ctime(&log_time.tv_sec) );
// second pass : runways
for ( k = 0; k < (int)rwy_polys.size(); ++k )
for ( unsigned int k = 0; k < rwy_polys.size(); ++k )
{
TGPolygon poly = rwy_polys[k].get_poly();
poly = add_nodes_to_poly( poly, tmp_nodes );
@ -584,7 +637,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
}
// second pass : and pavements
for ( k = 0; k < (int)pvmt_polys.size(); ++k )
for ( unsigned int k = 0; k < pvmt_polys.size(); ++k )
{
TGPolygon poly = pvmt_polys[k].get_poly();
poly = add_nodes_to_poly( poly, tmp_nodes );
@ -594,7 +647,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
}
// second pass : and lines
for ( k = 0; k < (int)line_polys.size(); ++k )
for ( unsigned int k = 0; k < line_polys.size(); ++k )
{
TGPolygon poly = line_polys[k].get_poly();
poly = add_nodes_to_poly( poly, tmp_nodes );
@ -607,7 +660,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
SG_LOG( SG_GENERAL, SG_ALERT, "Finished adding intermediate nodes for " << icao << " at " << ctime(&log_time.tv_sec) );
// One more pass to try to get rid of other yukky stuff
for ( k = 0; k < (int)rwy_polys.size(); ++k )
for ( unsigned int k = 0; k < rwy_polys.size(); ++k )
{
TGPolygon poly = rwy_polys[k].get_poly();
@ -621,7 +674,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
rwy_polys[k].set_poly( poly );
}
for ( k = 0; k < (int)pvmt_polys.size(); ++k )
for ( unsigned int k = 0; k < pvmt_polys.size(); ++k )
{
TGPolygon poly = pvmt_polys[k].get_poly();
@ -635,7 +688,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
pvmt_polys[k].set_poly( poly );
}
for ( k = 0; k < (int)line_polys.size(); ++k )
for ( unsigned int k = 0; k < line_polys.size(); ++k )
{
TGPolygon poly = line_polys[k].get_poly();
@ -650,7 +703,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
}
gettimeofday(&log_time, NULL);
SG_LOG( SG_GENERAL, SG_ALERT, "Finished cleaning poly for " << icao << " at " << ctime(&log_time.tv_sec) );
SG_LOG( SG_GENERAL, SG_ALERT, "Finished cleaning polys for " << icao << " at " << ctime(&log_time.tv_sec) );
SG_LOG(SG_GENERAL, SG_DEBUG, "add nodes base ");
SG_LOG(SG_GENERAL, SG_DEBUG, " before: " << base_poly);
@ -670,7 +723,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
gettimeofday(&triangulation_start, NULL);
// tesselate the polygons and prepair them for final output
for ( i = 0; i < (int)rwy_polys.size(); ++i )
for ( unsigned int i = 0; i < rwy_polys.size(); ++i )
{
SG_LOG(SG_GENERAL, SG_INFO, "Tesselating runway poly = " << i << " of " << rwy_polys.size() << " : flag = " << rwy_polys[i].get_flag());
@ -695,13 +748,21 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
}
// tesselate the polygons and prepair them for final output
for ( i = 0; i < (int)pvmt_polys.size(); ++i )
for ( unsigned int i = 0; i < pvmt_polys.size(); ++i )
{
SG_LOG(SG_GENERAL, SG_INFO, "Tesselating pavement poly = " << i << " of " << pvmt_polys.size() << " : flag = " << pvmt_polys[i].get_flag());
TGPolygon poly = pvmt_polys[i].get_poly();
#if 0
if ( i == 62 ) {
tgChopNormalPolygon( "/home/pete", "Base", poly, false );
verbose_triangulation = true;
}
#endif
SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << poly.contours() << " total points before = " << poly.total_size());
TGPolygon tri = polygon_tesselate_alt( poly, false );
TGPolygon tri = polygon_tesselate_alt( poly, verbose_triangulation );
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after = " << tri.total_size());
TGPolygon tc;
@ -719,14 +780,21 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
}
// tesselate the polygons and prepair them for final output
for ( i = 0; i < (int)line_polys.size(); ++i )
for ( unsigned int i = 0; i < line_polys.size(); ++i )
{
SG_LOG(SG_GENERAL, SG_INFO, "Tesselating line poly = " << i << " of " << line_polys.size() << " : flag = " << line_polys[i].get_flag());
TGPolygon poly = line_polys[i].get_poly();
#if 0
if ( i == 62 ) {
tgChopNormalPolygon( "/home/pete", "Base", poly, false );
verbose_triangulation = true;
}
#endif
SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << poly.contours() << " total points before = " << poly.total_size());
TGPolygon tri = polygon_tesselate_alt( poly, false );
TGPolygon tri = polygon_tesselate_alt( poly, verbose_triangulation );
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after = " << tri.total_size());
TGPolygon tc;
@ -736,7 +804,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
line_polys[i].set_texcoords( tc );
}
#if 1
#if 0
{
tgChopNormalPolygon( "/home/pete", "Base", base_poly, false );
verbose_triangulation = true;
@ -800,7 +868,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
SG_LOG(SG_GENERAL, SG_DEBUG, "found normal for this airport = " << tmp);
for ( k = 0; k < (int)rwy_polys.size(); ++k )
for ( unsigned int k = 0; k < rwy_polys.size(); ++k )
{
SG_LOG(SG_GENERAL, SG_DEBUG, "tri " << k);
// TGPolygon tri_poly = rwy_tris[k];
@ -810,12 +878,12 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
SG_LOG(SG_GENERAL, SG_DEBUG, "material = " << material);
SG_LOG(SG_GENERAL, SG_DEBUG, "poly size = " << tri_poly.contours());
SG_LOG(SG_GENERAL, SG_DEBUG, "texs size = " << tri_txs.contours());
for ( i = 0; i < tri_poly.contours(); ++i )
for ( int i = 0; i < tri_poly.contours(); ++i )
{
tri_v.clear();
tri_n.clear();
tri_tc.clear();
for ( j = 0; j < tri_poly.contour_size(i); ++j )
for ( int j = 0; j < tri_poly.contour_size(i); ++j )
{
p = tri_poly.get_pt( i, j );
SG_LOG(SG_GENERAL, SG_DEBUG, "adding runway point = " << p);
@ -838,7 +906,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
}
}
for ( k = 0; k < (int)pvmt_polys.size(); ++k )
for ( unsigned int k = 0; k < pvmt_polys.size(); ++k )
{
SG_LOG(SG_GENERAL, SG_DEBUG, "tri " << k);
// TGPolygon tri_poly = rwy_tris[k];
@ -848,12 +916,12 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
SG_LOG(SG_GENERAL, SG_DEBUG, "material = " << material);
SG_LOG(SG_GENERAL, SG_DEBUG, "poly size = " << tri_poly.contours());
SG_LOG(SG_GENERAL, SG_DEBUG, "texs size = " << tri_txs.contours());
for ( i = 0; i < tri_poly.contours(); ++i )
for ( int i = 0; i < tri_poly.contours(); ++i )
{
tri_v.clear();
tri_n.clear();
tri_tc.clear();
for ( j = 0; j < tri_poly.contour_size(i); ++j )
for ( int j = 0; j < tri_poly.contour_size(i); ++j )
{
p = tri_poly.get_pt( i, j );
index = nodes.unique_add( p );
@ -874,7 +942,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
}
}
for ( k = 0; k < (int)line_polys.size(); ++k )
for ( unsigned int k = 0; k < line_polys.size(); ++k )
{
SG_LOG(SG_GENERAL, SG_DEBUG, "tri " << k);
// TGPolygon tri_poly = rwy_tris[k];
@ -884,12 +952,12 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
SG_LOG(SG_GENERAL, SG_DEBUG, "material = " << material);
SG_LOG(SG_GENERAL, SG_DEBUG, "poly size = " << tri_poly.contours());
SG_LOG(SG_GENERAL, SG_DEBUG, "texs size = " << tri_txs.contours());
for ( i = 0; i < tri_poly.contours(); ++i )
for ( int i = 0; i < tri_poly.contours(); ++i )
{
tri_v.clear();
tri_n.clear();
tri_tc.clear();
for ( j = 0; j < tri_poly.contour_size(i); ++j )
for ( int j = 0; j < tri_poly.contour_size(i); ++j )
{
p = tri_poly.get_pt( i, j );
index = nodes.unique_add( p );
@ -914,12 +982,12 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
std::vector< SGVec2f > base_txs;
int_list base_tc;
for ( i = 0; i < base_tris.contours(); ++i )
for ( int i = 0; i < base_tris.contours(); ++i )
{
tri_v.clear();
tri_n.clear();
tri_tc.clear();
for ( j = 0; j < base_tris.contour_size(i); ++j )
for ( int j = 0; j < base_tris.contour_size(i); ++j )
{
p = base_tris.get_pt( i, j );
@ -935,7 +1003,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
tri_materials.push_back( "Grass" );
std::vector < SGGeod > geodNodes;
for ( j = 0; j < nodes.get_node_list().size(); j++ )
for ( unsigned int j = 0; j < nodes.get_node_list().size(); j++ )
{
Point3D node = nodes.get_node_list()[j];
geodNodes.push_back( SGGeod::fromDegM( node.x(), node.y(), node.z() ) );
@ -944,7 +1012,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
base_txs = sgCalcTexCoords( b, geodNodes, tri_v );
base_tc.clear();
for ( j = 0; j < (int)base_txs.size(); ++j )
for ( unsigned int j = 0; j < base_txs.size(); ++j )
{
SGVec2f tc = base_txs[j];
// SG_LOG(SG_GENERAL, SG_DEBUG, "base_tc = " << tc);
@ -958,9 +1026,9 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
// missed. Make sure they are all in the node list so we can
// build a proper skirt.
for ( i = 0; i < divided_base.contours(); ++i )
for ( int i = 0; i < divided_base.contours(); ++i )
{
for ( j = 0; j < divided_base.contour_size( i ); ++j )
for ( int j = 0; j < divided_base.contour_size( i ); ++j )
{
SG_LOG(SG_GENERAL, SG_DEBUG, "adding divided base point " << p);
@ -999,7 +1067,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
SG_LOG(SG_GENERAL, SG_DEBUG, " calculation min/max coordinates of airport area");
Point3D min_deg(9999.0, 9999.0, 0), max_deg(-9999.0, -9999.0, 0);
for ( j = 0; j < (int)nodes.get_node_list().size(); ++j )
for ( unsigned int j = 0; j < nodes.get_node_list().size(); ++j )
{
Point3D p = nodes.get_node_list()[j];
if ( p.lon() < min_deg.lon() )
@ -1025,11 +1093,11 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
SG_LOG(SG_GENERAL, SG_DEBUG, " extend the min/max coordinates of airport area to cover all lights as well : num rwy lights is " << rwy_lights.size() );
for ( i = 0; i < (int)rwy_lights.size(); ++i )
for ( unsigned int i = 0; i < rwy_lights.size(); ++i )
{
SG_LOG(SG_GENERAL, SG_DEBUG, " extend the min/max coordinates of airport area to cover all lights as well : rwy light " << i << "has " << rwy_lights[i].get_poly().get_contour(0).size() << " lights " );
for ( j = 0; j < (int)rwy_lights[i].get_poly().get_contour(0).size(); ++j )
for ( unsigned int j = 0; j < rwy_lights[i].get_poly().get_contour(0).size(); ++j )
{
Point3D p = rwy_lights[i].get_poly().get_contour(0)[j];
if ( p.lon() < min_deg.lon() )
@ -1083,7 +1151,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
SG_LOG(SG_GENERAL, SG_DEBUG, "Computing windsock node elevations");
point_list ws_nodes;
ws_nodes.clear();
for ( i = 0; i < (int)windsocks.size(); ++i )
for ( unsigned int i = 0; i < windsocks.size(); ++i )
{
p = windsocks[i]->GetLoc();
ws_nodes.push_back( p );
@ -1094,7 +1162,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
SG_LOG(SG_GENERAL, SG_DEBUG, "Computing beacon node elevations");
point_list b_nodes;
b_nodes.clear();
for ( i = 0; i < (int)beacons.size(); ++i )
for ( unsigned int i = 0; i < beacons.size(); ++i )
{
p = beacons[i]->GetLoc();
b_nodes.push_back( p );
@ -1106,7 +1174,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
SG_LOG(SG_GENERAL, SG_DEBUG, "Computing taxiway sign node elevations");
point_list ts_nodes;
ts_nodes.clear();
for ( i = 0; i < (int)signs.size(); ++i )
for ( unsigned int i = 0; i < signs.size(); ++i )
{
p = signs[i]->GetLoc();
ts_nodes.push_back( p );
@ -1122,12 +1190,12 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
{
point_list buoy_nodes;
buoy_nodes.clear();
for ( i = 0; i < (int)waterrunways.size(); ++i )
for ( unsigned int i = 0; i < waterrunways.size(); ++i )
{
TGPolygon tmp_nodes;
tmp_nodes.erase();
tmp_nodes = waterrunways[i]->GetNodes();
for (j=0; j< tmp_nodes.contour_size( 0 ); ++j )
for ( int j = 0; j< tmp_nodes.contour_size( 0 ); ++j )
{
buoy_nodes.push_back( tmp_nodes.get_pt( 0, j ) );
}
@ -1143,7 +1211,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
int uindex, lindex;
for ( i = 0; i < divided_base.contours(); ++i )
for ( int i = 0; i < divided_base.contours(); ++i )
{
strip_v.clear();
strip_n.clear();
@ -1175,7 +1243,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
}
// loop through the list
for ( j = 1; j < divided_base.contour_size(i); ++j )
for ( int j = 1; j < divided_base.contour_size(i); ++j )
{
p = divided_base.get_pt( i, j );
uindex = nodes.find( p );
@ -1228,7 +1296,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
strip_materials.push_back( "Grass" );
std::vector < SGGeod > geodNodes;
for ( j = 0; j < nodes.get_node_list().size(); j++ )
for ( unsigned int j = 0; j < nodes.get_node_list().size(); j++ )
{
Point3D node = nodes.get_node_list()[j];
geodNodes.push_back( SGGeod::fromDegM( node.x(), node.y(), node.z() ) );
@ -1237,7 +1305,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
base_txs = sgCalcTexCoords( b, geodNodes, strip_v );
base_tc.clear();
for ( j = 0; j < (int)base_txs.size(); ++j )
for ( unsigned int j = 0; j < base_txs.size(); ++j )
{
SGVec2f tc = base_txs[j];
// SG_LOG(SG_GENERAL, SG_DEBUG, "base_tc = " << tc);
@ -1257,12 +1325,12 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
SG_LOG(SG_GENERAL, SG_DEBUG, "Computing runway/approach lighting elevations");
// pass one, calculate raw elevations from Array
for ( i = 0; i < (int)rwy_lights.size(); ++i )
for ( unsigned int i = 0; i < rwy_lights.size(); ++i )
{
TGTriNodes light_nodes;
light_nodes.clear();
point_list lights_v = rwy_lights[i].get_poly().get_contour(0);
for ( j = 0; j < (int)lights_v.size(); ++j )
for ( unsigned int j = 0; j < lights_v.size(); ++j )
{
p = lights_v[j];
index = light_nodes.simple_add( p );
@ -1285,7 +1353,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
{
max = elevation_map[flag];
}
for ( j = 0; j < (int)geod_light_nodes.size(); ++j )
for ( unsigned int j = 0; j < geod_light_nodes.size(); ++j )
{
if ( geod_light_nodes[j].z() > max )
{
@ -1301,7 +1369,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
// pass two, for each light group check if we need to lift (based
// on flag) and do so, then output next structures.
for ( i = 0; i < (int)rwy_lights.size(); ++i )
for ( unsigned int i = 0; i < rwy_lights.size(); ++i )
{
// tmp_light_list is a parallel structure to rwy_lights
point_list geod_light_nodes = tmp_light_list[i].get_poly().get_contour(0);
@ -1314,7 +1382,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
point_list light_normals = rwy_lights[i].get_normals().get_contour(0);
pt_v.clear();
pt_n.clear();
for ( j = 0; j < (int)geod_light_nodes.size(); ++j )
for ( unsigned int j = 0; j < geod_light_nodes.size(); ++j )
{
p = geod_light_nodes[j];
index = nodes.simple_add( p );
@ -1331,7 +1399,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
// calculate wgs84 mapping of nodes
std::vector< SGVec3d > wgs84_nodes;
for ( i = 0; i < (int)geod_nodes.size(); ++i )
for ( unsigned int i = 0; i < geod_nodes.size(); ++i )
{
SGGeod geod = SGGeod::fromDegM( geod_nodes[i].x(), geod_nodes[i].y(), geod_nodes[i].z() );
SG_LOG(SG_GENERAL, SG_DEBUG, "geod pt = " << geod_nodes[i] );
@ -1340,7 +1408,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
wgs84_nodes.push_back( cart );
}
SGSphered d;
for ( i = 0; i < wgs84_nodes.size(); ++i )
for ( unsigned int i = 0; i < wgs84_nodes.size(); ++i )
{
d.expandBy(wgs84_nodes[ i ]);
}
@ -1361,14 +1429,14 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
string name = icao + ".btg";
std::vector< SGVec3f > normals_3f;
for ( i=0; i < normals.get_node_list().size(); i++ )
for ( unsigned int i = 0; i < normals.get_node_list().size(); i++ )
{
Point3D node = normals.get_node_list()[i];
normals_3f.push_back( node.toSGVec3f() );
}
std::vector< SGVec2f > texcoords_2f;
for ( i=0; i < texcoords.get_node_list().size(); i++ )
for ( unsigned int i = 0; i < texcoords.get_node_list().size(); i++ )
{
Point3D node = texcoords.get_node_list()[i];
texcoords_2f.push_back( node.toSGVec2f() );
@ -1418,7 +1486,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
#endif
// write out windsock references : TODO - save elevation data in the windsock object
for ( i = 0; i < (int)windsock_nodes.size(); ++i )
for ( unsigned int i = 0; i < windsock_nodes.size(); ++i )
{
if ( windsocks[i]->IsLit() )
{
@ -1435,7 +1503,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
}
// write out beacon references
for ( i = 0; i < (int)beacon_nodes.size(); ++i )
for ( unsigned int i = 0; i < beacon_nodes.size(); ++i )
{
write_index_shared( objpath, b, beacon_nodes[i],
"Models/Airport/beacon.xml",
@ -1443,7 +1511,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
}
// write out taxiway signs references
for ( i = 0; i < (int)taxisigns_nodes.size(); ++i )
for ( unsigned int i = 0; i < taxisigns_nodes.size(); ++i )
{
write_object_sign( objpath, b, taxisigns_nodes[i],
signs[i]->GetDefinition(),
@ -1451,14 +1519,13 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
}
// write out water buoys
for ( i = 0; i < (int)water_buoys_nodes.size(); ++i )
for ( unsigned int i = 0; i < water_buoys_nodes.size(); ++i )
{
write_index_shared( objpath, b, water_buoys_nodes[i],
"Models/Airport/water_rw_buoy.xml",
0.0 );
}
string holepath = root + "/AirportArea";
// long int poly_index = poly_index_next();
// write_boundary( holepath, b, hull, poly_index );

View file

@ -18,6 +18,7 @@ class Airport
{
public:
Airport( int c, char* def);
~Airport();
void AddRunway( Runway* runway )
{

View file

@ -175,7 +175,9 @@ TGPolygon gen_wgs84_area( Point3D end1, Point3D end2,
TGPolygon gen_wgs84_rect( double lat, double lon, double heading, double length, double width )
{
TGPolygon result_list;
double ptlat, ptlon, r;
double ptlat = 0.0f;
double ptlon = 0.0f;
double r = 0.0f;
Point3D p;
// starting point is in the middle of the rectangle width, at the beginning - stretch to heading

View file

@ -9,6 +9,18 @@
#include <simgear/debug/logstream.hxx>
// TEMP...
inline Point3D CalculateLinearLocation( Point3D p0, Point3D p1, double t )
{
Point3D result;
double term1 = (1.0f - t);
double term2 = t;
result = (p0 * term1) + (p1 * term2);
return result;
}
inline Point3D CalculateQuadraticLocation( Point3D p0, Point3D cp, Point3D p1, double t )
{
Point3D result;
@ -112,22 +124,22 @@ public:
return (loc - (pt - loc));
}
void SetMarking( int m )
void SetMarking( unsigned int m )
{
mark = m;
}
int GetMarking( )
unsigned int GetMarking( )
{
return mark;
}
void SetLighting( int l )
void SetLighting( unsigned int l )
{
light = l;
}
int GetLighting( )
unsigned int GetLighting( )
{
return light;
}
@ -182,11 +194,11 @@ public:
}
private:
Point3D loc;
Point3D prev_cp;
Point3D next_cp;
int mark;
int light;
Point3D loc;
Point3D prev_cp;
Point3D next_cp;
unsigned int mark;
unsigned int light;
};

View file

@ -60,6 +60,13 @@ ClosedPoly::ClosedPoly( int st, float s, float th, char* desc )
cur_feature = NULL;
}
ClosedPoly::~ClosedPoly()
{
SG_LOG( SG_GENERAL, SG_DEBUG, "Deleting ClosedPoly " << description );
}
void ClosedPoly::AddNode( BezNode* node )
{
// if this is the first node of the contour - create a new contour
@ -468,10 +475,21 @@ void ClosedPoly::Finish()
}
// save memory by deleting unneeded resources
for (unsigned int i=0; i<boundary->size(); i++)
{
delete boundary->at(i);
}
delete boundary;
boundary = NULL;
// and the hole contours
for (unsigned int i=0; i<holes.size(); i++)
{
for (unsigned int j=0; j<holes[i]->size(); j++)
{
delete holes[i]->at(j);
}
}
holes.clear();
}
@ -520,14 +538,15 @@ int ClosedPoly::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list
pre_tess = remove_dups( pre_tess );
pre_tess = reduce_degeneracy( pre_tess );
for (int c=0; c<pre_tess.contours(); c++)
{
for (int pt=0; pt<pre_tess.contour_size(c); pt++)
{
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: contour " << c << " pt " << pt << ": (" << pre_tess.get_pt(c, pt).x() << "," << pre_tess.get_pt(c, pt).y() << ")" );
}
}
//for (int c=0; c<pre_tess.contours(); c++)
//{
// for (int pt=0; pt<pre_tess.contour_size(c); pt++)
// {
// SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: contour " << c << " pt " << pt << ": (" << pre_tess.get_pt(c, pt).x() << "," << pre_tess.get_pt(c, pt).y() << ")" );
// }
//}
// grow pretess by a little bit
pre_tess = tgPolygonExpand( pre_tess, 0.05); // 5cm
TGSuperPoly sp;
TGTexParams tp;
@ -551,9 +570,16 @@ int ClosedPoly::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list
if ( apt_base )
{
ExpandContour( hull, base, 20.0 );
ExpandContour( hull, safe_base, 50.0 );
// ExpandContour( hull, base, 20.0 );
base = tgPolygonExpand( pre_tess, 20.0);
// dump pre_tess and base
//SG_LOG(SG_GENERAL, SG_INFO, "BuildBtg: original poly " << pre_tess );
//SG_LOG(SG_GENERAL, SG_INFO, "BuildBtg: expanded poly " << base );
// ExpandContour( hull, safe_base, 50.0 );
safe_base = tgPolygonExpand( pre_tess, 50.0);
// add this to the airport clearing
*apt_clearing = tgPolygonUnion( safe_base, *apt_clearing);

View file

@ -17,10 +17,7 @@ class ClosedPoly
public:
ClosedPoly( char* desc );
ClosedPoly( int st, float s, float th, char* desc );
~ClosedPoly()
{
SG_LOG( SG_GENERAL, SG_DEBUG, "Deleting ClosedPoly " << description );
}
~ClosedPoly();
inline string GetDescription() { return description; }
void AddNode( BezNode* node );

View file

@ -27,9 +27,9 @@
#endif
// libnewmat includes and defines
#define WANT_STREAM // include.h will get stream fns
#define WANT_MATH // include.h will get math fns
// newmatap.h will get include.h
#define WANT_STREAM // include.h will get stream fns
#define WANT_MATH // include.h will get math fns
// newmatap.h will get include.h
#include <newmat/newmatap.h> // need matrix applications
#include <newmat/newmatio.h> // need matrix output routines
@ -74,7 +74,7 @@ double tgAverageElevation( const string &root, const string_list elev_src,
for ( i = 0; i < points.size(); ++i ) {
if ( points[i].z() < -9000.0 && !found_one ) {
first = points[i];
SG_LOG( SG_GENERAL, SG_DEBUG, "founf first = " << first );
SG_LOG( SG_GENERAL, SG_DEBUG, "found first = " << first );
found_one = true;
}
@ -88,12 +88,11 @@ double tgAverageElevation( const string &root, const string_list elev_src,
i = 0;
bool found_file = false;
while ( !found_file && i < elev_src.size() ) {
string array_path = root + "/" + elev_src[i] + "/" + base
+ "/" + b.gen_index_str();
string array_path = root + "/" + elev_src[i] + "/" + base + "/" + b.gen_index_str();
if ( array.open(array_path) ) {
found_file = true;
SG_LOG( SG_GENERAL, SG_DEBUG, "Using array_path = "
<< array_path );
SG_LOG( SG_GENERAL, SG_DEBUG, "Using array_path = " << array_path );
}
i++;
}
@ -106,10 +105,10 @@ double tgAverageElevation( const string &root, const string_list elev_src,
// data from the nearest neighbor (sort of)
array.remove_voids();
// update all the non-updated elevations that are inside
// this array file
double elev;
done = true;
// update all the non-updated elevations that are inside
// this array file
double elev;
done = true;
for ( i = 0; i < points.size(); ++i ) {
if ( points[i].z() < -9000.0 ) {
done = false;
@ -123,11 +122,11 @@ double tgAverageElevation( const string &root, const string_list elev_src,
}
}
}
array.close();
} else {
done = true;
}
array.close();
} else {
done = true;
}
}
// now find the average height of the queried points
@ -138,8 +137,7 @@ double tgAverageElevation( const string &root, const string_list elev_src,
count++;
}
double average = total / (double) count;
SG_LOG(SG_GENERAL, SG_DEBUG, "Average surface height of point list = "
<< average);
SG_LOG(SG_GENERAL, SG_DEBUG, "Average surface height of point list = " << average);
return average;
}
@ -161,15 +159,15 @@ void tgCalcElevations( const string &root, const string_list elev_src,
// set all elevations to -9999
for ( j = 0; j < Pts.rows(); ++j ) {
for ( i = 0; i < Pts.cols(); ++i ) {
Point3D p = Pts.element(i, j);
p.setz( -9999.0 );
Pts.set(i, j, p);
}
for ( i = 0; i < Pts.cols(); ++i ) {
Point3D p = Pts.element(i, j);
p.setz( -9999.0 );
Pts.set(i, j, p);
}
}
while ( !done ) {
// find first node with -9999 elevation
// find first node with -9999 elevation
Point3D first(0.0);
bool found_one = false;
for ( j = 0; j < Pts.rows(); ++j ) {
@ -182,36 +180,35 @@ void tgCalcElevations( const string &root, const string_list elev_src,
}
}
if ( found_one ) {
SGBucket b( first.x(), first.y() );
string base = b.gen_base_path();
if ( found_one ) {
SGBucket b( first.x(), first.y() );
string base = b.gen_base_path();
// try the various elevation sources
// try the various elevation sources
j = 0;
bool found_file = false;
while ( !found_file && j < (int)elev_src.size() ) {
string array_path = root + "/" + elev_src[j] + "/" + base
+ "/" + b.gen_index_str();
string array_path = root + "/" + elev_src[j] + "/" + base + "/" + b.gen_index_str();
if ( array.open(array_path) ) {
found_file = true;
SG_LOG( SG_GENERAL, SG_DEBUG, "Using array_path = "
<< array_path );
SG_LOG( SG_GENERAL, SG_DEBUG, "Using array_path = " << array_path );
}
j++;
}
}
// this will fill in a zero structure if no array data
// found/opened
array.parse( b );
array.parse( b );
// this will do a hasty job of removing voids by inserting
// data from the nearest neighbor (sort of)
array.remove_voids();
// update all the non-updated elevations that are inside
// this array file
double elev;
done = true;
// update all the non-updated elevations that are inside
// this array file
double elev;
done = true;
for ( j = 0; j < Pts.rows(); ++j ) {
for ( i = 0; i < Pts.cols(); ++i ) {
Point3D p = Pts.element(i,j);
@ -220,20 +217,18 @@ void tgCalcElevations( const string &root, const string_list elev_src,
elev = array.altitude_from_grid( p.x() * 3600.0,
p.y() * 3600.0 );
if ( elev > -9000 ) {
p.setz( elev );
Pts.set(i, j, p);
// cout << "interpolating for " << p << endl;
// cout << p.x() << " " << p.y() << " " << p.z()
// << endl;
p.setz( elev );
Pts.set(i, j, p);
}
}
}
}
array.close();
} else {
done = true;
}
array.close();
} else {
done = true;
}
}
// do some post processing for sanity's sake
@ -249,14 +244,13 @@ void tgCalcElevations( const string &root, const string_list elev_src,
}
}
double grid_average = total / (double) count;
SG_LOG(SG_GENERAL, SG_DEBUG, "Average surface height of matrix = "
<< grid_average);
SG_LOG(SG_GENERAL, SG_DEBUG, "Average surface height of matrix = " << grid_average);
}
// clamp all elevations to the specified range
void tgClampElevations( SimpleMatrix &Pts,
double center_m, double max_clamp_m )
double center_m,
double max_clamp_m )
{
int i, j;

View file

@ -25,7 +25,6 @@ void LinearFeature::ConvertContour( BezContour* src )
int curve_type = CURVE_LINEAR;
Marking* cur_mark = NULL;
Lighting* cur_light = NULL;
int i;
SG_LOG(SG_GENERAL, SG_DEBUG, " LinearFeature::ConvertContour - Creating a contour with " << src->size() << " nodes");
@ -33,7 +32,7 @@ void LinearFeature::ConvertContour( BezContour* src )
points.empty();
// iterate through each bezier node in the contour
for (i=0; i <= src->size()-1; i++)
for (unsigned int i=0; i <= src->size()-1; i++)
{
SG_LOG(SG_GENERAL, SG_DEBUG, " LinearFeature::ConvertContour: Handling Node " << i << "\n\n");
@ -234,12 +233,49 @@ void LinearFeature::ConvertContour( BezContour* src )
}
else
{
nextLoc = nextNode->GetLoc();
// For linear features, sometime long linear lines confuse the tesselator. Add intermediate nodes to keep the rectangles from
// getting too long.
double az1 = 0.0f;
double az2 = 0.0f;
double dist = 0.0f;
// just add the one vertex - linear
points.push_back( curLoc );
// calculate linear distance to determine how many segments we want
Point3D destLoc = nextNode->GetLoc();
geo_inverse_wgs_84( curLoc.y(), curLoc.x(), destLoc.y(), destLoc.x(), &az1, &az2, &dist);
SG_LOG(SG_GENERAL, SG_DEBUG, "adding Linear Anchor node at (" << curLoc.x() << "," << curLoc.y() << ")");
if (dist > 10.0)
{
int num_segs = (dist / 10.0f) + 1;
for (int p=0; p<num_segs; p++)
{
// calculate next location
nextLoc = CalculateLinearLocation( curNode->GetLoc(), nextNode->GetLoc(), (1.0f/num_segs) * (p+1) );
// add the feature vertex
points.push_back( curLoc );
if (p==0)
{
SG_LOG(SG_GENERAL, SG_DEBUG, "adding Linear anchor node at (" << curLoc.x() << "," << curLoc.y() << ")");
}
else
{
SG_LOG(SG_GENERAL, SG_DEBUG, " add linear node at (" << curLoc.x() << "," << curLoc.y() << ")");
}
// now set set prev and cur locations for the next iteration
prevLoc = curLoc;
curLoc = nextLoc;
}
}
else
{
// just add the one vertex - dist is small
points.push_back( curLoc );
SG_LOG(SG_GENERAL, SG_DEBUG, "adding Linear Anchor node at (" << curLoc.x() << "," << curLoc.y() << ")");
}
}
}
@ -264,6 +300,19 @@ void LinearFeature::ConvertContour( BezContour* src )
}
}
LinearFeature::~LinearFeature()
{
for (unsigned int i=0; i<marks.size(); i++)
{
delete marks[i];
}
for (unsigned int i=0; i<lights.size(); i++)
{
delete lights[i];
}
}
Point3D LinearFeature::OffsetPointMiddle( Point3D *prev, Point3D *cur, Point3D *next, double offset_by )
{
double offset_dir;
@ -441,7 +490,6 @@ int LinearFeature::Finish()
double az2;
double last_end_v;
double width = 0;
int i, j;
string material;
double cur_light_dist = 0.0f;
double light_delta = 0;
@ -454,7 +502,7 @@ int LinearFeature::Finish()
ConvertContour( &contour );
// now generate the supoerpoly and texparams lists for markings
for (i=0; i<marks.size(); i++)
for (unsigned int i=0; i<marks.size(); i++)
{
prev_inner = Point3D(0.0f, 0.0f, 0.0f);
prev_outer = Point3D(0.0f, 0.0f, 0.0f);
@ -576,7 +624,7 @@ int LinearFeature::Finish()
}
last_end_v = 0.0f;
for (j = marks[i]->start_idx; j <= marks[i]->end_idx; j++)
for (unsigned int j = marks[i]->start_idx; j <= marks[i]->end_idx; j++)
{
SG_LOG(SG_GENERAL, SG_DEBUG, "LinearFeature::Finish: calculating offsets for mark " << i << " whose start idx is " << marks[i]->start_idx << " and end idx is " << marks[i]->end_idx << " cur idx is " << j );
// for each point on the PointsList, generate a quad from
@ -631,7 +679,7 @@ int LinearFeature::Finish()
}
// now generate the supoerpoly list for lights with constant distance between lights (depending on feature type)
for (i=0; i<lights.size(); i++)
for (unsigned int i=0; i<lights.size(); i++)
{
prev_outer = Point3D(0.0f, 0.0f, 0.0f);
cur_light_dist = 0.0f;
@ -674,7 +722,7 @@ int LinearFeature::Finish()
normals_poly.erase();
sp.erase();
for (j = lights[i]->start_idx; j <= lights[i]->end_idx; j++)
for (unsigned int j = lights[i]->start_idx; j <= lights[i]->end_idx; j++)
{
SG_LOG(SG_GENERAL, SG_DEBUG, "LinearFeature::Finish: calculating offsets for light " << i << " whose start idx is " << lights[i]->start_idx << " and end idx is " << lights[i]->end_idx << " cur idx is " << j );
// for each point on the PointsList, offset by 2 distnaces from the edge, and add a point to the superpoly contour
@ -761,36 +809,37 @@ int LinearFeature::Finish()
SG_LOG(SG_GENERAL, SG_DEBUG, "\nLinearFeature::Finish: No points for linear feature " << description << " light index " << i );
}
}
return 1;
}
int LinearFeature::BuildBtg(float alt_m, superpoly_list* line_polys, texparams_list* line_tps, ClipPolyType* line_accum, superpoly_list* lights )
{
TGPolygon poly;
TGPolygon clipped;
TGPolygon split;
int i;
//TGPolygon split;
SG_LOG(SG_GENERAL, SG_DEBUG, "\nLinearFeature::BuildBtg: " << description);
for (i=0; i<marking_polys.size(); i++)
for ( unsigned int i = 0; i < marking_polys.size(); i++)
{
poly = marking_polys[i].get_poly();
clipped = tgPolygonDiff( poly, *line_accum );
SG_LOG(SG_GENERAL, SG_DEBUG, "LinearFeature::BuildBtg: clipped poly has " << clipped.contours() << " contours");
SG_LOG(SG_GENERAL, SG_DEBUG, "LinearFeature::BuildBtg: clipping poly " << i << " of " << marking_polys.size() );
clipped = tgPolygonDiffClipper( poly, *line_accum );
TGPolygon split = tgPolygonSplitLongEdges( clipped, 400.0 );
SG_LOG(SG_GENERAL, SG_DEBUG, "LinearFeature::BuildBtg: split poly has " << split.contours() << " contours");
// TGPolygon split = tgPolygonSplitLongEdges( clipped, 400.0 );
// SG_LOG(SG_GENERAL, SG_DEBUG, "LinearFeature::BuildBtg: split poly has " << split.contours() << " contours");
marking_polys[i].set_poly( split );
marking_polys[i].set_poly( clipped );
line_polys->push_back( marking_polys[i] );
*line_accum = tgPolygonUnion( poly, *line_accum );
*line_accum = tgPolygonUnionClipper( poly, *line_accum );
line_tps->push_back( marking_tps[i] );
}
SG_LOG(SG_GENERAL, SG_DEBUG, "LinearFeature::BuildBtg: add " << lighting_polys.size() << " light defs");
for (i=0; i<lighting_polys.size(); i++)
for ( unsigned i = 0; i < lighting_polys.size(); i++)
{
SG_LOG(SG_GENERAL, SG_DEBUG, "LinearFeature::BuildBtg: adding light " << i );
lights->push_back( lighting_polys[i] );

View file

@ -45,18 +45,18 @@ using std::string;
struct Marking
{
public:
int type;
int start_idx;
int end_idx;
unsigned int type;
unsigned int start_idx;
unsigned int end_idx;
};
typedef std::vector <Marking*> MarkingList;
struct Lighting
{
public:
int type;
int start_idx;
int end_idx;
unsigned int type;
unsigned int start_idx;
unsigned int end_idx;
};
typedef std::vector <Lighting*> LightingList;
@ -82,6 +82,8 @@ public:
offset = o;
}
~LinearFeature();
inline string GetDescription() { return description; }
void AddNode( BezNode* b )

View file

@ -313,6 +313,8 @@ int main(int argc, char **argv)
parser->Parse();
}
delete parser;
SG_LOG(SG_GENERAL, SG_INFO, "Done");
return 0;

View file

@ -71,14 +71,13 @@ TGArray::TGArray( const string &file ):
// open an Array file (and fitted file if it exists)
bool TGArray::open( const string& file_base ) {
bool success = true;
// open array data file
string array_name = file_base + ".arr.gz";
array_in = new sg_gzifstream( array_name );
if ( ! array_in->is_open() ) {
if ( !array_in->is_open() ) {
SG_LOG(SG_GENERAL, SG_DEBUG, " ps: Cannot open " << array_name );
success = false;
delete array_in;
array_in = NULL;
} else {
SG_LOG(SG_GENERAL, SG_DEBUG, " Opening array data file: " << array_name );
}
@ -92,23 +91,30 @@ bool TGArray::open( const string& file_base ) {
// not be nearly as nice as what the offline terrafit utility
// would have produced.
SG_LOG(SG_GENERAL, SG_DEBUG, " ps: Cannot open " << fitted_name );
delete fitted_in;
fitted_in = NULL;
} else {
SG_LOG(SG_GENERAL, SG_DEBUG, " Opening fitted data file: " << fitted_name );
}
return success;
return (array_in != NULL) ? true : false;
}
// close an Array file
bool
TGArray::close() {
// the sg_gzifstream doesn't seem to have a close()
if (array_in) {
array_in->close();
delete array_in;
array_in = NULL;
}
array_in->close();
fitted_in->close();
delete array_in;
delete fitted_in;
if (fitted_in ) {
fitted_in->close();
delete fitted_in;
fitted_in = NULL;
}
return true;
}
@ -119,52 +125,52 @@ TGArray::close() {
bool
TGArray::parse( SGBucket& b ) {
// Parse/load the array data file
if ( array_in->is_open() ) {
// file open, parse
*array_in >> originx >> originy;
*array_in >> cols >> col_step;
*array_in >> rows >> row_step;
if ( array_in && array_in->is_open() ) {
// file open, parse
*array_in >> originx >> originy;
*array_in >> cols >> col_step;
*array_in >> rows >> row_step;
SG_LOG(SG_GENERAL, SG_DEBUG, " origin = " << originx << " " << originy );
SG_LOG(SG_GENERAL, SG_DEBUG, " cols = " << cols << " rows = " << rows );
SG_LOG(SG_GENERAL, SG_DEBUG, " col_step = " << col_step << " row_step = " << row_step );
SG_LOG(SG_GENERAL, SG_DEBUG, " origin = " << originx << " " << originy );
SG_LOG(SG_GENERAL, SG_DEBUG, " cols = " << cols << " rows = " << rows );
SG_LOG(SG_GENERAL, SG_DEBUG, " col_step = " << col_step << " row_step = " << row_step );
for ( int i = 0; i < cols; i++ ) {
for ( int j = 0; j < rows; j++ ) {
*array_in >> in_data[i][j];
}
}
for ( int i = 0; i < cols; i++ ) {
for ( int j = 0; j < rows; j++ ) {
*array_in >> in_data[i][j];
}
}
SG_LOG(SG_GENERAL, SG_DEBUG, " Done parsing" );
SG_LOG(SG_GENERAL, SG_DEBUG, " Done parsing" );
} else {
// file not open (not found?), fill with zero'd data
// file not open (not found?), fill with zero'd data
originx = ( b.get_center_lon() - 0.5 * b.get_width() ) * 3600.0;
originy = ( b.get_center_lat() - 0.5 * b.get_height() ) * 3600.0;
originx = ( b.get_center_lon() - 0.5 * b.get_width() ) * 3600.0;
originy = ( b.get_center_lat() - 0.5 * b.get_height() ) * 3600.0;
double max_x = ( b.get_center_lon() + 0.5 * b.get_width() ) * 3600.0;
double max_y = ( b.get_center_lat() + 0.5 * b.get_height() ) * 3600.0;
double max_x = ( b.get_center_lon() + 0.5 * b.get_width() ) * 3600.0;
double max_y = ( b.get_center_lat() + 0.5 * b.get_height() ) * 3600.0;
cols = 3;
col_step = (max_x - originx) / (cols - 1);
rows = 3;
row_step = (max_y - originy) / (rows - 1);
cols = 3;
col_step = (max_x - originx) / (cols - 1);
rows = 3;
row_step = (max_y - originy) / (rows - 1);
SG_LOG(SG_GENERAL, SG_DEBUG, " origin = " << originx << " " << originy );
SG_LOG(SG_GENERAL, SG_DEBUG, " cols = " << cols << " rows = " << rows );
SG_LOG(SG_GENERAL, SG_DEBUG, " col_step = " << col_step << " row_step = " << row_step );
SG_LOG(SG_GENERAL, SG_DEBUG, " origin = " << originx << " " << originy );
SG_LOG(SG_GENERAL, SG_DEBUG, " cols = " << cols << " rows = " << rows );
SG_LOG(SG_GENERAL, SG_DEBUG, " col_step = " << col_step << " row_step = " << row_step );
for ( int i = 0; i < cols; i++ ) {
for ( int j = 0; j < rows; j++ ) {
in_data[i][j] = 0;
}
}
for ( int i = 0; i < cols; i++ ) {
for ( int j = 0; j < rows; j++ ) {
in_data[i][j] = 0;
}
}
SG_LOG(SG_GENERAL, SG_DEBUG, " File not open, so using zero'd data" );
SG_LOG(SG_GENERAL, SG_DEBUG, " File not open, so using zero'd data" );
}
// Parse/load the fitted data file
if ( fitted_in->is_open() ) {
if ( fitted_in && fitted_in->is_open() ) {
int fitted_size;
double x, y, z;
*fitted_in >> fitted_size;

View file

@ -40,4 +40,10 @@ TGContourNode::TGContourNode( int n ) {
// Destructor
TGContourNode::~TGContourNode() {
for ( unsigned int i = 0; i < kids.size(); ++i ) {
if ( kids[i] != NULL ) {
delete kids[i];
}
}
}

View file

@ -311,6 +311,9 @@ int polygon_tesselate( const TGPolygon &p,
free(in.pointlist);
free(in.pointattributelist);
free(in.pointmarkerlist);
free(in.segmentlist);
free(in.segmentmarkerlist);
free(in.holelist);
free(in.regionlist);
free(out.pointlist);
free(out.pointattributelist);
@ -634,7 +637,6 @@ static void print_contour_tree( TGContourNode *node, string indent ) {
}
}
// Build the contour "is inside of" tree
static void build_contour_tree( TGContourNode *node,
const TGPolygon &p,
@ -730,7 +732,7 @@ void calc_points_inside( TGPolygon& p ) {
// starters)
int_list avail;
for ( int i = 0; i < p.contours(); ++i ) {
avail.push_back( 1 );
avail.push_back( 1 );
}
// create and initialize the root node
@ -745,6 +747,9 @@ void calc_points_inside( TGPolygon& p ) {
// contour/hole
// cout << " calc_point_inside()\n";
calc_point_inside( ct, p );
// free the memory
delete ct;
}

View file

@ -305,7 +305,6 @@ typedef enum {
POLY_UNION // Union
} clip_op;
#ifdef CLIP_GPC
//
// wrapper functions for gpc polygon clip routines
//
@ -401,95 +400,24 @@ TGPolygon polygon_clip( clip_op poly_op, const TGPolygon& subject,
// free allocated memory
gpc_free_polygon( gpc_subject );
delete gpc_subject;
gpc_free_polygon( gpc_clip );
delete gpc_clip;
gpc_free_polygon( gpc_result );
delete gpc_result;
return result;
}
// Generic clipping routine
TGPolygon polygon_clip( clip_op poly_op, const TGPolygon& subject, const gpc_polygon& clip )
{
TGPolygon result;
gpc_polygon *gpc_subject = new gpc_polygon;
gpc_subject->num_contours = 0;
gpc_subject->contour = NULL;
gpc_subject->hole = NULL;
make_gpc_poly( subject, gpc_subject );
gpc_polygon *gpc_clip = (gpc_polygon*)&clip;
gpc_polygon *gpc_result = new gpc_polygon;
gpc_result->num_contours = 0;
gpc_result->contour = NULL;
gpc_result->hole = NULL;
gpc_op op;
if ( poly_op == POLY_DIFF ) {
op = GPC_DIFF;
} else if ( poly_op == POLY_INT ) {
op = GPC_INT;
} else if ( poly_op == POLY_XOR ) {
op = GPC_XOR;
} else if ( poly_op == POLY_UNION ) {
op = GPC_UNION;
} else {
throw sg_exception("Unknown polygon op, exiting.");
}
gpc_polygon_clip( op, gpc_subject, gpc_clip, gpc_result );
make_tg_poly( gpc_result, &result );
// free allocated memory
gpc_free_polygon( gpc_subject );
gpc_free_polygon( gpc_result );
return result;
}
gpc_polygon polygon_clip_keep_native_fmt( clip_op poly_op, const TGPolygon& subject, const gpc_polygon& clip )
{
gpc_polygon *gpc_subject = new gpc_polygon;
gpc_subject->num_contours = 0;
gpc_subject->contour = NULL;
gpc_subject->hole = NULL;
make_gpc_poly( subject, gpc_subject );
gpc_polygon *gpc_clip = (gpc_polygon*)&clip;
gpc_polygon result;
result.num_contours = 0;
result.contour = NULL;
result.hole = NULL;
gpc_op op;
if ( poly_op == POLY_DIFF ) {
op = GPC_DIFF;
} else if ( poly_op == POLY_INT ) {
op = GPC_INT;
} else if ( poly_op == POLY_XOR ) {
op = GPC_XOR;
} else if ( poly_op == POLY_UNION ) {
op = GPC_UNION;
} else {
throw sg_exception("Unknown polygon op, exiting.");
}
gpc_polygon_clip( op, gpc_subject, gpc_clip, &result );
// free allocated memory
gpc_free_polygon( gpc_subject );
return result;
}
#endif
#ifdef CLIP_CLIPPER
//#define FIXEDPT (10000000000000)
#define FIXEDPT (10000000000000000)
#define FIXED1M ( 90090)
IntPoint MakeClipperPoint( Point3D pt )
{
@ -511,49 +439,60 @@ Point3D MakeTGPoint( IntPoint pt )
return Point3D( x, y, -9999.0f);
}
double MakeClipperDelta( double mDelta )
{
double cDelta = mDelta * ( FIXEDPT / FIXED1M );
// SG_LOG(SG_GENERAL, SG_INFO, "mdelta:" << mDelta << " is " << cDelta );
return( cDelta );
}
void make_clipper_poly( const TGPolygon& in, Polygons *out )
{
Polygon contour;
Point3D p;
int i, j;
if (in.contours())
{
// assume contour 0 is boundary, 1..x are holes
// create the boundary
for (j=0; j<in.contour_size(0); ++j)
for (i=0; i<in.contours(); i++) {
// create a clipper contour
contour.clear();
for (j=0; j<in.contour_size(i); ++j)
{
p = in.get_pt( 0, j );
p = in.get_pt( i, j );
contour.push_back(MakeClipperPoint(p));
}
out->push_back(contour);
// create the holes
for (i=1; i<in.contours(); ++i )
{
contour.clear();
for (j=0; j<in.contour_size(i); ++j)
{
p = in.get_pt( i, j );
contour.push_back(MakeClipperPoint(p));
if ( in.get_hole_flag( i ) )
{
// holes need to be orientation: false
if ( Orientation( contour ) ) {
//SG_LOG(SG_GENERAL, SG_INFO, "Building clipper poly - hole contour needs to be reversed" );
ReversePoints( contour );
}
out->push_back(contour);
}
} else {
// boundaries need to be orientation: true
if ( !Orientation( contour ) ) {
//SG_LOG(SG_GENERAL, SG_INFO, "Building clipper poly - boundary contour needs to be reversed" );
ReversePoints( contour );
}
}
out->push_back(contour);
}
}
void make_tg_poly( const ExPolygons& in, TGPolygon *out )
void make_tg_poly_from_clipper_ex( const ExPolygons& in, TGPolygon *out )
{
int res_contour = 0;
out->erase();
for (int i=0; i<in.size(); i++)
for (unsigned int i=0; i<in.size(); i++)
{
const struct ExPolygon* pg = &in[i];
IntPoint ip;
// Get the boundary contour
for (int j = 0; j < pg->outer.size(); j++)
for (unsigned int j = 0; j < pg->outer.size(); j++)
{
ip = IntPoint( pg->outer[j].X, pg->outer[j].Y );
out->add_node(res_contour, MakeTGPoint(ip));
@ -562,9 +501,9 @@ void make_tg_poly( const ExPolygons& in, TGPolygon *out )
res_contour++;
// then the holes
for (int j = 0; j < pg->holes.size(); j++)
for (unsigned int j = 0; j < pg->holes.size(); j++)
{
for (int k = 0; k < pg->holes[j].size(); k++)
for (unsigned int k = 0; k < pg->holes[j].size(); k++)
{
ip = IntPoint( pg->holes[j].at(k).X, pg->holes[j].at(k).Y );
out->add_node(res_contour, MakeTGPoint(ip));
@ -575,7 +514,34 @@ void make_tg_poly( const ExPolygons& in, TGPolygon *out )
}
}
TGPolygon polygon_clip( clip_op poly_op, const TGPolygon& subject, const TGPolygon& clip )
void make_tg_poly_from_clipper( const Polygons& in, TGPolygon *out )
{
out->erase();
// for each polygon, we need to check the orientation, to set the hole flag...
for (unsigned int i=0; i<in.size(); i++)
{
IntPoint ip;
for (unsigned int j = 0; j < in[i].size(); j++)
{
ip = IntPoint( in[i][j].X, in[i][j].Y );
//SG_LOG(SG_GENERAL, SG_INFO, "Building TG Poly : Add point (" << ip.X << "," << ip.Y << ") to contour " << i );
out->add_node( i, MakeTGPoint(ip) );
}
if ( Orientation( in[i] ) ) {
//SG_LOG(SG_GENERAL, SG_INFO, "Building TG Poly : contour " << i << " is boundary " );
out->set_hole_flag(i, 0);
} else {
//SG_LOG(SG_GENERAL, SG_INFO, "Building TG Poly : contour " << i << " is hole " );
out->set_hole_flag(i, 1);
}
}
}
TGPolygon polygon_clip_clipper( clip_op poly_op, const TGPolygon& subject, const TGPolygon& clip )
{
TGPolygon result;
@ -606,119 +572,42 @@ TGPolygon polygon_clip( clip_op poly_op, const TGPolygon& subject, const TGPolyg
c.AddPolygons(clipper_clip, ptClip);
c.Execute(op, clipper_result, pftEvenOdd, pftEvenOdd);
make_tg_poly( clipper_result, &result );
make_tg_poly_from_clipper_ex( clipper_result, &result );
return result;
}
TGPolygon polygon_clip( clip_op poly_op, const TGPolygon& subject, const Polygons& clipper_clip )
{
TGPolygon result;
Polygons clipper_subject;
make_clipper_poly( subject, &clipper_subject );
ExPolygons clipper_result;
ClipType op;
if ( poly_op == POLY_DIFF ) {
op = ctDifference;
} else if ( poly_op == POLY_INT ) {
op = ctIntersection;
} else if ( poly_op == POLY_XOR ) {
op = ctXor;
} else if ( poly_op == POLY_UNION ) {
op = ctUnion;
} else {
throw sg_exception("Unknown polygon op, exiting.");
}
Clipper c;
c.Clear();
c.AddPolygons(clipper_subject, ptSubject);
c.AddPolygons(clipper_clip, ptClip);
c.Execute(op, clipper_result, pftEvenOdd, pftEvenOdd);
make_tg_poly( clipper_result, &result );
return result;
}
Polygons polygon_clip_keep_native_fmt( clip_op poly_op, const TGPolygon& subject, const Polygons& clipper_clip )
{
Polygons clipper_subject;
make_clipper_poly( subject, &clipper_subject );
ExPolygons clipper_result;
Polygons result;
ClipType op;
if ( poly_op == POLY_DIFF ) {
op = ctDifference;
} else if ( poly_op == POLY_INT ) {
op = ctIntersection;
} else if ( poly_op == POLY_XOR ) {
op = ctXor;
} else if ( poly_op == POLY_UNION ) {
op = ctUnion;
} else {
throw sg_exception("Unknown polygon op, exiting.");
}
Clipper c;
c.Clear();
c.AddPolygons(clipper_subject, ptSubject);
c.AddPolygons(clipper_clip, ptClip);
c.Execute(op, clipper_result, pftEvenOdd, pftEvenOdd);
// copy contours to polygons structure
for (int i=0; i<clipper_result.size(); i++)
{
result.push_back( clipper_result[i].outer );
for (int j=0; j<clipper_result[i].holes.size(); j++)
{
result.push_back( clipper_result[i].holes[j] );
}
}
return result;
}
#endif
// Difference
TGPolygon tgPolygonDiff( const TGPolygon& subject, const TGPolygon& clip ) {
return polygon_clip( POLY_DIFF, subject, clip );
}
#if CLIP_NATIVE
TGPolygon tgPolygonDiff( const TGPolygon& subject, const ClipPolyType& clip ) {
return polygon_clip( POLY_DIFF, subject, clip );
}
#endif
// Intersection
TGPolygon tgPolygonInt( const TGPolygon& subject, const TGPolygon& clip ) {
return polygon_clip( POLY_INT, subject, clip );
}
// Exclusive or
TGPolygon tgPolygonXor( const TGPolygon& subject, const TGPolygon& clip ) {
return polygon_clip( POLY_XOR, subject, clip );
}
// Union
TGPolygon tgPolygonUnion( const TGPolygon& subject, const TGPolygon& clip ) {
return polygon_clip( POLY_UNION, subject, clip );
}
#if CLIP_NATIVE
ClipPolyType tgPolygonUnion( const TGPolygon& subject, const ClipPolyType& clip ) {
return polygon_clip_keep_native_fmt( POLY_UNION, subject, clip );
// CLIPPER
TGPolygon tgPolygonDiffClipper( const TGPolygon& subject, const TGPolygon& clip ) {
return polygon_clip_clipper( POLY_DIFF, subject, clip );
}
#endif
TGPolygon tgPolygonUnionClipper( const TGPolygon& subject, const TGPolygon& clip ) {
return polygon_clip_clipper( POLY_UNION, subject, clip );
}
// canonify the polygon winding, outer contour must be anti-clockwise,
// all inner contours must be clockwise.
@ -869,6 +758,43 @@ TGPolygon tgPolygonStripHoles( const TGPolygon &poly ) {
return result;
}
void PrintClipperPoly( Polygons polys )
{
int nContours = polys.size();
SG_LOG(SG_GENERAL, SG_INFO, "CLIPPER POLY : contours " << nContours );
for (int i = 0; i < nContours; i++) {
int nPoints = polys[i].size();
SG_LOG(SG_GENERAL, SG_INFO, nPoints );
for (int j = 0; j < nPoints; j++) {
SG_LOG(SG_GENERAL, SG_INFO, "(" << polys[i][j].X << "," << polys[i][j].Y << ")" );
}
}
}
TGPolygon tgPolygonExpand(const TGPolygon &poly, double delta)
{
TGPolygon result;
Polygons clipper_src, clipper_dst;
make_clipper_poly( poly, &clipper_src );
//SG_LOG(SG_GENERAL, SG_INFO, "Clipper Source" );
//PrintClipperPoly( clipper_src );
// convert delta from meters to clipper units
OffsetPolygons( clipper_src, clipper_dst, MakeClipperDelta(delta) );
//SG_LOG(SG_GENERAL, SG_INFO, "Clipper Dest" );
//PrintClipperPoly( clipper_dst );
make_tg_poly_from_clipper( clipper_dst, &result );
return result;
}
#if 0
// Wrapper for the fast Polygon Triangulation based on Seidel's

View file

@ -47,9 +47,6 @@
// forward declaration
class TGPolygon;
#define CLIP_GPC
// #define CLIP_CLIPPER
/* Set to 1 to allow keeping accum poly in native clipping lib format
* Although it seems to work on some airports, EHAM is pretty broken
* when turned on
@ -261,10 +258,6 @@ TGPolygon tgPolygon2tristrip( const TGPolygon& poly );
// Difference
TGPolygon tgPolygonDiff( const TGPolygon& subject, const TGPolygon& clip );
#if CLIP_NATIVE
TGPolygon tgPolygonDiff( const TGPolygon& subject, const ClipPolyType& clip );
#endif
// Intersection
TGPolygon tgPolygonInt( const TGPolygon& subject, const TGPolygon& clip );
@ -274,14 +267,21 @@ TGPolygon tgPolygonXor( const TGPolygon& subject, const TGPolygon& clip );
// Union
TGPolygon tgPolygonUnion( const TGPolygon& subject, const TGPolygon& clip );
#if CLIP_NATIVE
ClipPolyType tgPolygonUnion( const TGPolygon& subject, const ClipPolyType& clip );
#endif
// wrapper for clipper clip routines
// Difference
TGPolygon tgPolygonDiffClipper( const TGPolygon& subject, const TGPolygon& clip );
// Union
TGPolygon tgPolygonUnionClipper( const TGPolygon& subject, const TGPolygon& clip );
// Expand / Shrink
TGPolygon tgPolygonExpand(const TGPolygon &poly, double delta);
// Output
std::ostream &operator<<(std::ostream &output, const TGPolygon &poly);
#endif // _POLYGON_HXX

View file

@ -41,6 +41,8 @@ using std:: cout ;
using std:: string ;
using std:: endl ;
#define NOAA_DEBUG (0)
// return the type of the shapefile record
std::string get_shapefile_type(DBFHandle& hDBF, int rec) {
@ -317,54 +319,49 @@ int main( int argc, char **argv ) {
}
int iPart;
#if NOAA_DEBUG
const char *pszPlus;
#endif
for ( i = 0; i < nEntities; i++ ) {
// fetch i-th record (shape)
// fetch i-th record (shape)
SHPObject *psShape;
shape.erase();
shape.erase();
psShape = SHPReadObject( hSHP, i );
SG_LOG( SG_GENERAL, SG_DEBUG, "Processing record = " << i
<< " of " << nEntities
<< " rings = " << psShape->nParts
<< " total vertices = " << psShape->nVertices );
SG_LOG( SG_GENERAL, SG_DEBUG, "Processing record = " << i
<< " of " << nEntities
<< " rings = " << psShape->nParts
<< " total vertices = " << psShape->nVertices );
string area = "Default";
if ( force_area_type.length() == 0 ) {
area = get_shapefile_type(hDBF, i);
SG_LOG( SG_GENERAL, SG_DEBUG, " area type = " << area);
} else {
area = force_area_type;
}
string area = "Default";
if ( force_area_type.length() == 0 ) {
area = get_shapefile_type(hDBF, i);
SG_LOG( SG_GENERAL, SG_DEBUG, " area type = " << area);
} else {
area = force_area_type;
}
SG_LOG( SG_GENERAL, SG_INFO, " record type = "
<< SHPTypeName(psShape->nSHPType) );
SG_LOG( SG_GENERAL, SG_INFO, " bounds = ("
<< psShape->dfXMin << "," << psShape->dfYMin << ") "
<< psShape->dfZMin << "," << psShape->dfMMin
<< " to (" << psShape->dfXMax << "," << psShape->dfYMax << ") "
<< psShape->dfZMax << "," << psShape->dfMMax );
#if 0
printf( "\nShape:%d (%s) nVertices=%d, nParts=%d\n"
" Bounds:(%12.3f,%12.3f, %g, %g)\n"
" to (%12.3f,%12.3f, %g, %g)\n",
i, SHPTypeName(psShape->nSHPType),
psShape->nVertices, psShape->nParts,
psShape->dfXMin, psShape->dfYMin,
psShape->dfZMin, psShape->dfMMin,
psShape->dfXMax, psShape->dfYMax,
psShape->dfZMax, psShape->dfMMax );
#endif
SG_LOG( SG_GENERAL, SG_INFO, " record type = "
<< SHPTypeName(psShape->nSHPType) );
SG_LOG( SG_GENERAL, SG_INFO, " bounds = ("
<< psShape->dfXMin << "," << psShape->dfYMin << ") "
<< psShape->dfZMin << "," << psShape->dfMMin
<< " to (" << psShape->dfXMax << "," << psShape->dfYMax << ") "
<< psShape->dfZMax << "," << psShape->dfMMax );
for ( j = 0, iPart = 1; j < psShape->nVertices; j++ ) {
shape.add_node( iPart - 1, Point3D(psShape->padfX[j], psShape->padfY[j], 0) );
#if NOAA_DEBUG
const char *pszPartType = "";
if ( j == 0 && psShape->nParts > 0 ) {
pszPartType = SHPPartTypeName( psShape->panPartType[0] );
}
}
if( iPart < psShape->nParts
&& psShape->panPartStart[iPart] == j )
@ -374,80 +371,67 @@ int main( int argc, char **argv ) {
pszPlus = "+";
} else {
pszPlus = " ";
}
shape.add_node( iPart - 1,
Point3D(psShape->padfX[j], psShape->padfY[j], 0)
);
#if 0
printf("%d %d %s (%12.3f,%12.3f, %g, %g) %s \n",
iPart, j,
pszPlus,
psShape->padfX[j],
psShape->padfY[j],
psShape->padfZ[j],
psShape->padfM[j],
pszPartType );
#endif
}
#endif
}
SHPDestroyObject( psShape );
// check/set hole status for each contour. negative area
// means counter clockwise winding indicating the ring/contour
// is a hole.
for ( int i = 0; i < shape.contours(); ++i ) {
double area = shape.area_contour( i );
if ( area > 0 ) {
cout << "contour " << i << " = area" << endl;
shape.set_hole_flag( i, false );
} else {
cout << "contour " << i << " = hole" << endl;
shape.set_hole_flag( i, true );
}
}
// check/set hole status for each contour. negative area
// means counter clockwise winding indicating the ring/contour
// is a hole.
for ( int i = 0; i < shape.contours(); ++i ) {
double area = shape.area_contour( i );
if ( area > 0 ) {
cout << "contour " << i << " = area" << endl;
shape.set_hole_flag( i, false );
} else {
cout << "contour " << i << " = hole" << endl;
shape.set_hole_flag( i, true );
}
}
if ( force_area_type.length() > 0 ) {
// interior of polygon is assigned to force_area_type,
// holes are preserved
if ( force_area_type.length() > 0 ) {
// interior of polygon is assigned to force_area_type,
// holes are preserved
area = force_area_type;
tgChopNormalPolygon(work_dir, area, shape, false);
} else if ( is_ocean_area(area) ) {
// interior of polygon is ocean, holes are islands
area = force_area_type;
tgChopNormalPolygon(work_dir, area, shape, false);
} else if ( is_ocean_area(area) ) {
// interior of polygon is ocean, holes are islands
SG_LOG( SG_GENERAL, SG_ALERT, "Ocean area ... SKIPPING!" );
SG_LOG( SG_GENERAL, SG_ALERT, "Ocean area ... SKIPPING!" );
// Ocean data now comes from GSHHS so we want to ignore
// all other ocean data
// tgChopPolygon(work_dir, area, shape, false);
} else if ( is_void_area(area) ) {
// interior is ????
// Ocean data now comes from GSHHS so we want to ignore
// all other ocean data
// tgChopPolygon(work_dir, area, shape, false);
} else if ( is_void_area(area) ) {
// interior is ????
// skip for now
SG_LOG( SG_GENERAL, SG_ALERT, "Void area ... SKIPPING!" );
// skip for now
SG_LOG( SG_GENERAL, SG_ALERT, "Void area ... SKIPPING!" );
if ( shape.contours() > 1 ) {
SG_LOG( SG_GENERAL, SG_ALERT, " Void area with holes!" );
// exit(-1);
}
if ( shape.contours() > 1 ) {
SG_LOG( SG_GENERAL, SG_ALERT, " Void area with holes!" );
// exit(-1);
}
// tgChopPolygon(work_dir, area, shape, false);
} else if ( is_null_area(area) ) {
// interior is ????
// tgChopPolygon(work_dir, area, shape, false);
} else if ( is_null_area(area) ) {
// interior is ????
// skip for now
SG_LOG( SG_GENERAL, SG_ALERT, "Null area ... SKIPPING!" );
// skip for now
SG_LOG( SG_GENERAL, SG_ALERT, "Null area ... SKIPPING!" );
if ( shape.contours() > 1 ) {
SG_LOG( SG_GENERAL, SG_ALERT, " Null area with holes!" );
// exit(-1);
}
if ( shape.contours() > 1 ) {
SG_LOG( SG_GENERAL, SG_ALERT, " Null area with holes!" );
// exit(-1);
}
// tgChopPolygon(work_dir, area, shape, false);
} else {
tgChopNormalPolygon(work_dir, area, shape, false);
}
// tgChopPolygon(work_dir, area, shape, false);
} else {
tgChopNormalPolygon(work_dir, area, shape, false);
}
}
DBFClose( hDBF );