genapts fixes
- remove splinter remaval / merging - remove snap after adding colinear nodes - added zfighting detector - intersects all generated triangles against one another - this fixes ELLX, and to a large extent all 'large' airport self z-fighting. - very small z-fighting still exists at 72 airports. This is down from over 100 before the fix.
This commit is contained in:
parent
968089d322
commit
4f59886aaa
13 changed files with 399 additions and 42 deletions
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include <terragear/tg_polygon.hxx>
|
#include <terragear/tg_polygon.hxx>
|
||||||
#include <terragear/tg_chopper.hxx>
|
#include <terragear/tg_chopper.hxx>
|
||||||
|
#include <terragear/tg_shapefile.hxx>
|
||||||
#include <terragear/tg_unique_geod.hxx>
|
#include <terragear/tg_unique_geod.hxx>
|
||||||
#include <terragear/tg_unique_vec3f.hxx>
|
#include <terragear/tg_unique_vec3f.hxx>
|
||||||
#include <terragear/tg_unique_vec2f.hxx>
|
#include <terragear/tg_unique_vec2f.hxx>
|
||||||
|
@ -233,6 +234,8 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
|
||||||
tglightcontour_list rwy_lights;
|
tglightcontour_list rwy_lights;
|
||||||
|
|
||||||
bool make_shapefiles = false;
|
bool make_shapefiles = false;
|
||||||
|
char debug_root[32];
|
||||||
|
sprintf(debug_root, "./airport_dbg/%s/", icao.c_str() );
|
||||||
|
|
||||||
// parse main airport information
|
// parse main airport information
|
||||||
double apt_lon = 0.0, apt_lat = 0.0;
|
double apt_lon = 0.0, apt_lat = 0.0;
|
||||||
|
@ -311,7 +314,7 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
|
||||||
for ( unsigned int i=0; i<runways.size(); i++ )
|
for ( unsigned int i=0; i<runways.size(); i++ )
|
||||||
{
|
{
|
||||||
TG_LOG(SG_GENERAL, SG_DEBUG, "Build Runway " << i + 1 << " of " << runways.size());
|
TG_LOG(SG_GENERAL, SG_DEBUG, "Build Runway " << i + 1 << " of " << runways.size());
|
||||||
slivers.clear();
|
//slivers.clear();
|
||||||
|
|
||||||
if ( isDebugRunway(i) ) {
|
if ( isDebugRunway(i) ) {
|
||||||
sprintf( shapefile_name, "runway_%d", i );
|
sprintf( shapefile_name, "runway_%d", i );
|
||||||
|
@ -330,7 +333,7 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now try to merge any slivers we found
|
// Now try to merge any slivers we found
|
||||||
tgPolygon::MergeSlivers( rwy_polys, slivers );
|
// tgPolygon::MergeSlivers( rwy_polys, slivers );
|
||||||
}
|
}
|
||||||
|
|
||||||
log_time = time(0);
|
log_time = time(0);
|
||||||
|
@ -354,7 +357,7 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
|
||||||
for ( unsigned int i=0; i<helipads.size(); i++ )
|
for ( unsigned int i=0; i<helipads.size(); i++ )
|
||||||
{
|
{
|
||||||
TG_LOG(SG_GENERAL, SG_DEBUG, "Build helipad " << i + 1 << " of " << helipads.size());
|
TG_LOG(SG_GENERAL, SG_DEBUG, "Build helipad " << i + 1 << " of " << helipads.size());
|
||||||
slivers.clear();
|
//slivers.clear();
|
||||||
|
|
||||||
if (boundary.size())
|
if (boundary.size())
|
||||||
{
|
{
|
||||||
|
@ -366,7 +369,7 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now try to merge any slivers we found
|
// Now try to merge any slivers we found
|
||||||
tgPolygon::MergeSlivers( rwy_polys, slivers );
|
//tgPolygon::MergeSlivers( rwy_polys, slivers );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,7 +380,7 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
|
||||||
for ( unsigned int i=0; i<pavements.size(); i++ )
|
for ( unsigned int i=0; i<pavements.size(); i++ )
|
||||||
{
|
{
|
||||||
TG_LOG(SG_GENERAL, SG_DEBUG, "Build Pavement " << i + 1 << " of " << pavements.size() << " : " << pavements[i]->GetDescription());
|
TG_LOG(SG_GENERAL, SG_DEBUG, "Build Pavement " << i + 1 << " of " << pavements.size() << " : " << pavements[i]->GetDescription());
|
||||||
slivers.clear();
|
//slivers.clear();
|
||||||
|
|
||||||
if ( isDebugPavement(i) ) {
|
if ( isDebugPavement(i) ) {
|
||||||
sprintf( shapefile_name, "pvmnt_%d", i );
|
sprintf( shapefile_name, "pvmnt_%d", i );
|
||||||
|
@ -396,8 +399,8 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now try to merge any slivers we found
|
// Now try to merge any slivers we found
|
||||||
tgPolygon::MergeSlivers( rwy_polys, slivers );
|
//tgPolygon::MergeSlivers( rwy_polys, slivers );
|
||||||
tgPolygon::MergeSlivers( pvmt_polys, slivers );
|
//tgPolygon::MergeSlivers( pvmt_polys, slivers );
|
||||||
}
|
}
|
||||||
|
|
||||||
log_time = time(0);
|
log_time = time(0);
|
||||||
|
@ -411,7 +414,7 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
|
||||||
for ( unsigned int i=0; i<taxiways.size(); i++ )
|
for ( unsigned int i=0; i<taxiways.size(); i++ )
|
||||||
{
|
{
|
||||||
TG_LOG(SG_GENERAL, SG_DEBUG, "Build Taxiway " << i + 1 << " of " << taxiways.size());
|
TG_LOG(SG_GENERAL, SG_DEBUG, "Build Taxiway " << i + 1 << " of " << taxiways.size());
|
||||||
slivers.clear();
|
//slivers.clear();
|
||||||
|
|
||||||
if ( isDebugTaxiway(i) ) {
|
if ( isDebugTaxiway(i) ) {
|
||||||
sprintf( shapefile_name, "taxiway_%d", i );
|
sprintf( shapefile_name, "taxiway_%d", i );
|
||||||
|
@ -430,8 +433,8 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now try to merge any slivers we found
|
// Now try to merge any slivers we found
|
||||||
tgPolygon::MergeSlivers( rwy_polys, slivers );
|
//tgPolygon::MergeSlivers( rwy_polys, slivers );
|
||||||
tgPolygon::MergeSlivers( pvmt_polys, slivers );
|
//tgPolygon::MergeSlivers( pvmt_polys, slivers );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,12 +448,12 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
|
||||||
|
|
||||||
if ( runways[i]->GetsShoulder() )
|
if ( runways[i]->GetsShoulder() )
|
||||||
{
|
{
|
||||||
slivers.clear();
|
//slivers.clear();
|
||||||
runways[i]->BuildShoulder( rwy_polys, slivers, pvmt_accum );
|
runways[i]->BuildShoulder( rwy_polys, slivers, pvmt_accum );
|
||||||
|
|
||||||
// Now try to merge any slivers we found
|
// Now try to merge any slivers we found
|
||||||
tgPolygon::MergeSlivers( rwy_polys, slivers );
|
//tgPolygon::MergeSlivers( rwy_polys, slivers );
|
||||||
tgPolygon::MergeSlivers( pvmt_polys, slivers );
|
//tgPolygon::MergeSlivers( pvmt_polys, slivers );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -465,12 +468,12 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
|
||||||
|
|
||||||
if ( helipads[i]->GetsShoulder() )
|
if ( helipads[i]->GetsShoulder() )
|
||||||
{
|
{
|
||||||
slivers.clear();
|
//slivers.clear();
|
||||||
helipads[i]->BuildShoulder( rwy_polys, slivers, pvmt_accum );
|
helipads[i]->BuildShoulder( rwy_polys, slivers, pvmt_accum );
|
||||||
|
|
||||||
// Now try to merge any slivers we found
|
// Now try to merge any slivers we found
|
||||||
tgPolygon::MergeSlivers( rwy_polys, slivers );
|
//tgPolygon::MergeSlivers( rwy_polys, slivers );
|
||||||
tgPolygon::MergeSlivers( pvmt_polys, slivers );
|
//tgPolygon::MergeSlivers( pvmt_polys, slivers );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -628,14 +631,15 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
|
||||||
TG_LOG( SG_GENERAL, SG_ALERT, "Finished cleaning polys for " << icao << " at " << DebugTimeToString(log_time) );
|
TG_LOG( SG_GENERAL, SG_ALERT, "Finished cleaning polys for " << icao << " at " << DebugTimeToString(log_time) );
|
||||||
|
|
||||||
base_poly = tgPolygon::AddColinearNodes( base_poly, tmp_pvmt_nodes );
|
base_poly = tgPolygon::AddColinearNodes( base_poly, tmp_pvmt_nodes );
|
||||||
base_poly = tgPolygon::Snap( base_poly, gSnap );
|
// base_poly = tgPolygon::Snap( base_poly, gSnap );
|
||||||
|
|
||||||
// Finally find slivers in base
|
// Finally find slivers in base
|
||||||
slivers.clear();
|
//slivers.clear();
|
||||||
tgPolygon::RemoveSlivers( base_poly, slivers );
|
//tgPolygon::RemoveSlivers( base_poly, slivers );
|
||||||
tgPolygon::MergeSlivers( rwy_polys, slivers );
|
//tgPolygon::MergeSlivers( rwy_polys, slivers );
|
||||||
tgPolygon::MergeSlivers( pvmt_polys, slivers );
|
//tgPolygon::MergeSlivers( pvmt_polys, slivers );
|
||||||
|
|
||||||
|
#if 0
|
||||||
// Then snap rwy and pavement to grid (was done right after adding intermediate nodes...)
|
// Then snap rwy and pavement to grid (was done right after adding intermediate nodes...)
|
||||||
for ( unsigned int k = 0; k < rwy_polys.size(); ++k )
|
for ( unsigned int k = 0; k < rwy_polys.size(); ++k )
|
||||||
{
|
{
|
||||||
|
@ -653,10 +657,15 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
|
||||||
poly = tgPolygon::RemoveBadContours( poly );
|
poly = tgPolygon::RemoveBadContours( poly );
|
||||||
pvmt_polys[k] = poly;
|
pvmt_polys[k] = poly;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
cleanup_end.stamp();
|
cleanup_end.stamp();
|
||||||
cleanup_time = cleanup_end - cleanup_start;
|
cleanup_time = cleanup_end - cleanup_start;
|
||||||
|
|
||||||
|
/* before tessellating the base, make sure there are no
|
||||||
|
intersecting contours */
|
||||||
|
base_poly = tgPolygon::Simplify( base_poly );
|
||||||
|
|
||||||
triangulation_start.stamp();
|
triangulation_start.stamp();
|
||||||
|
|
||||||
// tesselate the polygons and prepair them for final output
|
// tesselate the polygons and prepair them for final output
|
||||||
|
@ -669,6 +678,14 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
|
||||||
|
|
||||||
TG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << rwy_polys[i].Contours() << " total points before = " << rwy_polys[i].TotalNodes());
|
TG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << rwy_polys[i].Contours() << " total points before = " << rwy_polys[i].TotalNodes());
|
||||||
rwy_polys[i].Tesselate();
|
rwy_polys[i].Tesselate();
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// dump the triangles for each poly
|
||||||
|
char desc[128];
|
||||||
|
sprintf( desc, "poly_%06d", i );
|
||||||
|
tgShapefile::FromTriangles( rwy_polys[i], debug_root, "rwy_polys", desc );
|
||||||
|
#endif
|
||||||
|
|
||||||
TG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << rwy_polys[i].Triangles());
|
TG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << rwy_polys[i].Triangles());
|
||||||
rwy_polys[i].Texture();
|
rwy_polys[i].Texture();
|
||||||
}
|
}
|
||||||
|
@ -684,6 +701,13 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
|
||||||
|
|
||||||
TG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << pvmt_polys[i].Contours() << " total points before = " << pvmt_polys[i].TotalNodes());
|
TG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << pvmt_polys[i].Contours() << " total points before = " << pvmt_polys[i].TotalNodes());
|
||||||
pvmt_polys[i].Tesselate();
|
pvmt_polys[i].Tesselate();
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
char desc[128];
|
||||||
|
sprintf( desc, "poly_%06d", i );
|
||||||
|
tgShapefile::FromTriangles( pvmt_polys[i], debug_root, "pvmt_polys", desc );
|
||||||
|
#endif
|
||||||
|
|
||||||
TG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << pvmt_polys[i].Triangles());
|
TG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << pvmt_polys[i].Triangles());
|
||||||
pvmt_polys[i].Texture();
|
pvmt_polys[i].Texture();
|
||||||
}
|
}
|
||||||
|
@ -699,17 +723,27 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
|
||||||
|
|
||||||
TG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << line_polys[i].Contours() << " total points before = " << line_polys[i].TotalNodes());
|
TG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << line_polys[i].Contours() << " total points before = " << line_polys[i].TotalNodes());
|
||||||
line_polys[i].Tesselate();
|
line_polys[i].Tesselate();
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
char desc[128];
|
||||||
|
sprintf( desc, "poly_%06d", i );
|
||||||
|
tgShapefile::FromTriangles( line_polys[i], debug_root, "line_polys", desc );
|
||||||
|
#endif
|
||||||
|
|
||||||
TG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << line_polys[i].Triangles());
|
TG_LOG(SG_GENERAL, SG_DEBUG, "triangles after = " << line_polys[i].Triangles());
|
||||||
line_polys[i].Texture();
|
line_polys[i].Texture();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* before tessellating the base, make sure there are no
|
|
||||||
intersecting contours */
|
|
||||||
base_poly = tgPolygon::Simplify( base_poly );
|
|
||||||
|
|
||||||
TG_LOG(SG_GENERAL, SG_INFO, "Tesselating base poly : " << base_poly.Contours() << " contours " );
|
TG_LOG(SG_GENERAL, SG_INFO, "Tesselating base poly : " << base_poly.Contours() << " contours " );
|
||||||
base_poly.Tesselate();
|
base_poly.Tesselate();
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
char desc[128];
|
||||||
|
sprintf( desc, "poly" );
|
||||||
|
tgShapefile::FromTriangles( base_poly, debug_root, "base_poly", desc );
|
||||||
|
#endif
|
||||||
|
|
||||||
TG_LOG(SG_GENERAL, SG_INFO, "Tesselating base poly - done : Triangles = " << base_poly.Triangles());
|
TG_LOG(SG_GENERAL, SG_INFO, "Tesselating base poly - done : Triangles = " << base_poly.Triangles());
|
||||||
// should we texture base here?
|
// should we texture base here?
|
||||||
base_poly.SetTexMethod( TG_TEX_BY_GEODE, b.get_center_lat() );
|
base_poly.SetTexMethod( TG_TEX_BY_GEODE, b.get_center_lat() );
|
||||||
|
@ -726,6 +760,15 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
|
||||||
|
|
||||||
triangulation_time = triangulation_end - triangulation_start;
|
triangulation_time = triangulation_end - triangulation_start;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// CheckZFighting( "post triangulation", debug_root, base_poly, rwy_polys, pvmt_polys );
|
||||||
|
if ( CheckZFightingTriangles( "post triangulation tris", debug_root, base_poly, rwy_polys, pvmt_polys ) ) {
|
||||||
|
char cmd[128];
|
||||||
|
sprintf( cmd, "echo %s >> zfight.txt\n", icao.c_str() );
|
||||||
|
system ( cmd );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// We should now have the runway polygons all generated with their
|
// We should now have the runway polygons all generated with their
|
||||||
// corresponding triangles and texture coordinates, and the
|
// corresponding triangles and texture coordinates, and the
|
||||||
|
@ -1166,3 +1209,142 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
|
||||||
chopper.Add( apt_clearing, "Airport" );
|
chopper.Add( apt_clearing, "Airport" );
|
||||||
chopper.Save( false );
|
chopper.Save( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Airport::CheckZFightingTriangles( const char* prefix, const char* debug_root, const tgPolygon& base_poly, const tgpolygon_list& rwy_polys, const tgpolygon_list& pvmt_polys )
|
||||||
|
{
|
||||||
|
char layer[128];
|
||||||
|
char desc[128];
|
||||||
|
|
||||||
|
sprintf( layer, "zfighting_%s", prefix );
|
||||||
|
double min_area_thresh = 1.0e-10;
|
||||||
|
|
||||||
|
bool zfighting = false;
|
||||||
|
|
||||||
|
if ( rwy_polys.size() ) {
|
||||||
|
for ( unsigned int i = 0; i < rwy_polys.size(); ++i ) {
|
||||||
|
tgPolygon subject = rwy_polys[i];
|
||||||
|
for ( unsigned int j = 0; j < subject.Triangles(); ++j ) {
|
||||||
|
tgTriangle subTri = subject.GetTriangle( j );
|
||||||
|
tgRectangle subBB = subTri.GetBoundingBox();
|
||||||
|
|
||||||
|
for ( unsigned int k = 0; k < pvmt_polys.size(); ++k ) {
|
||||||
|
tgPolygon test = pvmt_polys[k];
|
||||||
|
for ( unsigned int l = 0; l < test.Triangles(); ++l ) {
|
||||||
|
tgTriangle testTri = test.GetTriangle( l );
|
||||||
|
tgRectangle testBB = testTri.GetBoundingBox();
|
||||||
|
|
||||||
|
if ( subBB.intersects( testBB ) ) {
|
||||||
|
// find the intersection
|
||||||
|
tgPolygon intersection = tgTriangle::Intersect( subTri, testTri );
|
||||||
|
|
||||||
|
for ( unsigned int m = 0; m < intersection.Contours(); m++ ) {
|
||||||
|
tgContour intContour = intersection.GetContour( m );
|
||||||
|
if ( (intContour.GetSize() > 2) && (intContour.GetArea() > min_area_thresh) ) {
|
||||||
|
TG_LOG( SG_GENERAL, SG_ALERT, prefix << "Z-FIGHTING between runway poly " << i << " and pavement poly " << k << " contour has " << intContour.GetSize() << " nodes " << " area is " << intContour.GetArea() );
|
||||||
|
sprintf( desc, "rwy_%06d_pvmt_%06d", i, j );
|
||||||
|
tgShapefile::FromContour( intContour, debug_root, layer, desc );
|
||||||
|
zfighting = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// intersect each pavement poly with each pavement, runway, and base poly
|
||||||
|
if ( pvmt_polys.size() ) {
|
||||||
|
for ( unsigned int i = 0; i < pvmt_polys.size(); ++i ) {
|
||||||
|
tgPolygon subject = pvmt_polys[i];
|
||||||
|
for ( unsigned int j = 0; j < subject.Triangles(); ++j ) {
|
||||||
|
tgTriangle subTri = subject.GetTriangle( j );
|
||||||
|
tgRectangle subBB = subTri.GetBoundingBox();
|
||||||
|
|
||||||
|
for ( unsigned int k = 0; k < rwy_polys.size(); ++k ) {
|
||||||
|
tgPolygon test = rwy_polys[k];
|
||||||
|
for ( unsigned int l = 0; l < test.Triangles(); ++l ) {
|
||||||
|
tgTriangle testTri = test.GetTriangle( l );
|
||||||
|
tgRectangle testBB = testTri.GetBoundingBox();
|
||||||
|
|
||||||
|
if ( subBB.intersects( testBB ) ) {
|
||||||
|
// find the intersection
|
||||||
|
tgPolygon intersection = tgTriangle::Intersect( subTri, testTri );
|
||||||
|
|
||||||
|
for ( unsigned int m = 0; m < intersection.Contours(); m++ ) {
|
||||||
|
tgContour intContour = intersection.GetContour( m );
|
||||||
|
if ( (intContour.GetSize() > 2) && (intContour.GetArea() > min_area_thresh) ) {
|
||||||
|
TG_LOG( SG_GENERAL, SG_ALERT, prefix << "Z-FIGHTING between pavement poly " << i << " and runway poly " << k << " contour has " << intContour.GetSize() << " nodes " << " area is " << intContour.GetArea() );
|
||||||
|
sprintf( desc, "pvmt_%06d_rwy_%06d", i, j );
|
||||||
|
tgShapefile::FromContour( intContour, debug_root, layer, desc );
|
||||||
|
zfighting = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// intersect base poly with each runway and pavement poly
|
||||||
|
tgPolygon subject = base_poly;
|
||||||
|
|
||||||
|
for ( unsigned int i = 0; i < subject.Triangles(); ++i ) {
|
||||||
|
tgTriangle subTri = subject.GetTriangle( i );
|
||||||
|
tgRectangle subBB = subTri.GetBoundingBox();
|
||||||
|
|
||||||
|
for ( unsigned int j = 0; j < rwy_polys.size(); ++j ) {
|
||||||
|
tgPolygon test = rwy_polys[j];
|
||||||
|
for ( unsigned int k = 0; k < test.Triangles(); ++k ) {
|
||||||
|
tgTriangle testTri = test.GetTriangle( k );
|
||||||
|
tgRectangle testBB = testTri.GetBoundingBox();
|
||||||
|
|
||||||
|
if ( subBB.intersects( testBB ) ) {
|
||||||
|
// find the intersection
|
||||||
|
tgPolygon intersection = tgTriangle::Intersect( subTri, testTri );
|
||||||
|
|
||||||
|
for ( unsigned int m = 0; m < intersection.Contours(); m++ ) {
|
||||||
|
tgContour intContour = intersection.GetContour( m );
|
||||||
|
if ( (intContour.GetSize() > 2) && (intContour.GetArea() > min_area_thresh) ) {
|
||||||
|
TG_LOG( SG_GENERAL, SG_ALERT, prefix << "Z-FIGHTING between base poly and runway poly " << j << " contour has " << intContour.GetSize() << " nodes " << " area is " << intContour.GetArea() );
|
||||||
|
sprintf( desc, "base_rwy_%06d", j );
|
||||||
|
tgShapefile::FromContour( intContour, debug_root, layer, desc );
|
||||||
|
zfighting = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( unsigned int i = 0; i < subject.Triangles(); ++i ) {
|
||||||
|
tgTriangle subTri = subject.GetTriangle( i );
|
||||||
|
tgRectangle subBB = subTri.GetBoundingBox();
|
||||||
|
|
||||||
|
for ( unsigned int j = 0; j < pvmt_polys.size(); ++j ) {
|
||||||
|
tgPolygon test = pvmt_polys[j];
|
||||||
|
for ( unsigned int k = 0; k < test.Triangles(); ++k ) {
|
||||||
|
tgTriangle testTri = test.GetTriangle( k );
|
||||||
|
tgRectangle testBB = testTri.GetBoundingBox();
|
||||||
|
|
||||||
|
if ( subBB.intersects( testBB ) ) {
|
||||||
|
// find the intersection
|
||||||
|
tgPolygon intersection = tgTriangle::Intersect( subTri, testTri );
|
||||||
|
|
||||||
|
for ( unsigned int m = 0; m < intersection.Contours(); m++ ) {
|
||||||
|
tgContour intContour = intersection.GetContour( m );
|
||||||
|
if ( (intContour.GetSize() > 2) && (intContour.GetArea() > min_area_thresh) ) {
|
||||||
|
TG_LOG( SG_GENERAL, SG_ALERT, prefix << "Z-FIGHTING between base poly and pavement poly " << j << " contour has " << intContour.GetSize() << " nodes " << " area is " << intContour.GetArea() );
|
||||||
|
sprintf( desc, "base_pvmt_%06d", j );
|
||||||
|
tgShapefile::FromContour( intContour, debug_root, layer, desc );
|
||||||
|
zfighting = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return zfighting;
|
||||||
|
}
|
|
@ -131,6 +131,8 @@ public:
|
||||||
bool isDebugFeature ( int i );
|
bool isDebugFeature ( int i );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool CheckZFightingTriangles( const char* prefix, const char* debug_root, const tgPolygon& base_poly, const tgpolygon_list& rwy_polys, const tgpolygon_list& pvmt_polys );
|
||||||
|
|
||||||
int code; // airport, heliport or sea port
|
int code; // airport, heliport or sea port
|
||||||
int altitude; // in meters
|
int altitude; // in meters
|
||||||
std::string icao; // airport code
|
std::string icao; // airport code
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
|
@ -457,21 +458,36 @@ int ClosedPoly::BuildBtg( tgpolygon_list& rwy_polys, tgcontour_list& slivers, tg
|
||||||
|
|
||||||
int ClosedPoly::BuildBtg( tgpolygon_list& rwy_polys, tgcontour_list& slivers, tgAccumulator& accum, std::string& shapefile_name )
|
int ClosedPoly::BuildBtg( tgpolygon_list& rwy_polys, tgcontour_list& slivers, tgAccumulator& accum, std::string& shapefile_name )
|
||||||
{
|
{
|
||||||
|
char layer[128];
|
||||||
|
|
||||||
if ( is_pavement && pre_tess.Contours() )
|
if ( is_pavement && pre_tess.Contours() )
|
||||||
{
|
{
|
||||||
if( shapefile_name.size() ) {
|
if( shapefile_name.size() ) {
|
||||||
tgShapefile::FromPolygon( pre_tess, "./airport_dbg", std::string("preclip"), shapefile_name );
|
sprintf( layer, "%s_preclip", shapefile_name.c_str() );
|
||||||
accum.ToShapefiles( "./airport_dbg", "accum", true );
|
tgShapefile::FromPolygon( pre_tess, "./airport_dbg", layer, std::string("preclip") );
|
||||||
|
|
||||||
|
pre_tess.Tesselate();
|
||||||
|
sprintf( layer, "%s_preclip_tris", shapefile_name.c_str() );
|
||||||
|
tgShapefile::FromTriangles( pre_tess, "./airport_dbg", layer, std::string("preclip") );
|
||||||
|
|
||||||
|
//accum.ToShapefiles( "./airport_dbg", "accum", true );
|
||||||
}
|
}
|
||||||
|
|
||||||
tgPolygon clipped = accum.Diff( pre_tess );
|
tgPolygon clipped = accum.Diff( pre_tess );
|
||||||
if ( clipped.Contours() ) {
|
if ( clipped.Contours() ) {
|
||||||
if( shapefile_name.size() ) {
|
if( shapefile_name.size() ) {
|
||||||
tgShapefile::FromPolygon( clipped, "./airport_dbg", std::string("postclip"), shapefile_name );
|
sprintf( layer, "%s_postclip", shapefile_name.c_str() );
|
||||||
|
tgShapefile::FromPolygon( clipped, "./airport_dbg", layer, std::string("postclip") );
|
||||||
}
|
}
|
||||||
|
|
||||||
tgPolygon::RemoveSlivers( clipped, slivers );
|
// tgPolygon::RemoveSlivers( clipped, slivers );
|
||||||
|
|
||||||
|
if( shapefile_name.size() ) {
|
||||||
|
clipped.Tesselate();
|
||||||
|
sprintf( layer, "%s_postclip_tris", shapefile_name.c_str() );
|
||||||
|
tgShapefile::FromTriangles( clipped, "./airport_dbg", layer, std::string("postclip") );
|
||||||
|
}
|
||||||
|
|
||||||
clipped.SetMaterial( GetMaterial( surface_type ) );
|
clipped.SetMaterial( GetMaterial( surface_type ) );
|
||||||
clipped.SetTexParams( clipped.GetNode(0,0), 5.0, 5.0, texture_heading );
|
clipped.SetTexParams( clipped.GetNode(0,0), 5.0, 5.0, texture_heading );
|
||||||
clipped.SetTexLimits( 0.0, 0.0, 1.0, 1.0 );
|
clipped.SetTexLimits( 0.0, 0.0, 1.0, 1.0 );
|
||||||
|
|
|
@ -146,7 +146,7 @@ void Helipad::BuildBtg( tgpolygon_list& rwy_polys,
|
||||||
|
|
||||||
// Clip the new polygon against what ever has already been created.
|
// Clip the new polygon against what ever has already been created.
|
||||||
tgPolygon clipped = accum.Diff( helipad );
|
tgPolygon clipped = accum.Diff( helipad );
|
||||||
tgPolygon::RemoveSlivers( clipped, slivers );
|
// tgPolygon::RemoveSlivers( clipped, slivers );
|
||||||
|
|
||||||
// Split long edges to create an object that can better flow with
|
// Split long edges to create an object that can better flow with
|
||||||
// the surface terrain
|
// the surface terrain
|
||||||
|
@ -171,7 +171,7 @@ void Helipad::BuildBtg( tgpolygon_list& rwy_polys,
|
||||||
|
|
||||||
tgPolygon outer_poly = tgContour::Diff( outer_area, heli_poly );
|
tgPolygon outer_poly = tgContour::Diff( outer_area, heli_poly );
|
||||||
clipped = accum.Diff( outer_poly );
|
clipped = accum.Diff( outer_poly );
|
||||||
tgPolygon::RemoveSlivers( clipped, slivers );
|
// tgPolygon::RemoveSlivers( clipped, slivers );
|
||||||
|
|
||||||
// Split long edges to create an object that can better flow with
|
// Split long edges to create an object that can better flow with
|
||||||
// the surface terrain
|
// the surface terrain
|
||||||
|
@ -249,7 +249,7 @@ void Helipad::BuildShoulder( tgpolygon_list& rwy_polys,
|
||||||
|
|
||||||
// Clip the new polygon against what ever has already been created.
|
// Clip the new polygon against what ever has already been created.
|
||||||
tgPolygon clipped = accum.Diff( shoulder );
|
tgPolygon clipped = accum.Diff( shoulder );
|
||||||
tgPolygon::RemoveSlivers( clipped, slivers );
|
// tgPolygon::RemoveSlivers( clipped, slivers );
|
||||||
|
|
||||||
// Split long edges to create an object that can better flow with
|
// Split long edges to create an object that can better flow with
|
||||||
// the surface terrain
|
// the surface terrain
|
||||||
|
|
|
@ -313,7 +313,7 @@ void Runway::gen_runway_section( const tgPolygon& runway,
|
||||||
tgShapefile::FromPolygon( clipped, "./airport_dbg", std::string("postclip"), shapefile_name );
|
tgShapefile::FromPolygon( clipped, "./airport_dbg", std::string("postclip"), shapefile_name );
|
||||||
}
|
}
|
||||||
|
|
||||||
tgPolygon::RemoveSlivers( clipped, slivers );
|
//tgPolygon::RemoveSlivers( clipped, slivers );
|
||||||
|
|
||||||
// Split long edges to create an object that can better flow with
|
// Split long edges to create an object that can better flow with
|
||||||
// the surface terrain
|
// the surface terrain
|
||||||
|
@ -451,7 +451,7 @@ void Runway::gen_runway_section( const tgPolygon& runway,
|
||||||
// Clip the new polygon against what ever has already been created.
|
// Clip the new polygon against what ever has already been created.
|
||||||
tgPolygon clipped = accum.Diff( section );
|
tgPolygon clipped = accum.Diff( section );
|
||||||
|
|
||||||
tgPolygon::RemoveSlivers( clipped, slivers );
|
//tgPolygon::RemoveSlivers( clipped, slivers );
|
||||||
|
|
||||||
// Split long edges to create an object that can better flow with
|
// Split long edges to create an object that can better flow with
|
||||||
// the surface terrain
|
// the surface terrain
|
||||||
|
@ -875,7 +875,7 @@ void Runway::BuildShoulder( tgpolygon_list& rwy_polys,
|
||||||
|
|
||||||
// Clip the new polygon against what ever has already been created.
|
// Clip the new polygon against what ever has already been created.
|
||||||
tgPolygon clipped = accum.Diff( shoulder );
|
tgPolygon clipped = accum.Diff( shoulder );
|
||||||
tgPolygon::RemoveSlivers( clipped, slivers );
|
//tgPolygon::RemoveSlivers( clipped, slivers );
|
||||||
|
|
||||||
// Split long edges to create an object that can better flow with
|
// Split long edges to create an object that can better flow with
|
||||||
// the surface terrain
|
// the surface terrain
|
||||||
|
|
|
@ -93,7 +93,7 @@ void TGConstruct::run()
|
||||||
if ( debug_shapes.size() || debug_all ) {
|
if ( debug_shapes.size() || debug_all ) {
|
||||||
sprintf(ds_name, "%s/constructdbg_%s", debug_path.c_str(), bucket.gen_index_str().c_str() );
|
sprintf(ds_name, "%s/constructdbg_%s", debug_path.c_str(), bucket.gen_index_str().c_str() );
|
||||||
} else {
|
} else {
|
||||||
strcpy( ds_name, "" );
|
sprintf(ds_name, "%s/constructdbg_%s", debug_path.c_str(), bucket.gen_index_str().c_str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( stage == 1 ) {
|
if ( stage == 1 ) {
|
||||||
|
|
|
@ -218,6 +218,8 @@ bool TGConstruct::ClipLandclassPolys( void ) {
|
||||||
// finally, what ever is left over goes to ocean
|
// finally, what ever is left over goes to ocean
|
||||||
remains = accum.Diff( safety_base );
|
remains = accum.Diff( safety_base );
|
||||||
|
|
||||||
|
// tgShapefile::FromPolygon( remains, ds_name, "remains", "poly" );
|
||||||
|
|
||||||
if ( debug_all || debug_shapes.size() || debug_areas.size() ) {
|
if ( debug_all || debug_shapes.size() || debug_areas.size() ) {
|
||||||
char layer[32];
|
char layer[32];
|
||||||
char name[32];
|
char name[32];
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "tg_polygon.hxx"
|
#include "tg_polygon.hxx"
|
||||||
#include "tg_misc.hxx"
|
#include "tg_misc.hxx"
|
||||||
|
|
||||||
const double isEqual2D_Epsilon = 0.000001;
|
const double isEqual2D_Epsilon = 0.000000001;
|
||||||
|
|
||||||
#define CLIPPER_FIXEDPT (1000000000000)
|
#define CLIPPER_FIXEDPT (1000000000000)
|
||||||
#define CLIPPER_METERS_PER_DEGREE (111000)
|
#define CLIPPER_METERS_PER_DEGREE (111000)
|
||||||
|
|
|
@ -112,6 +112,29 @@ public:
|
||||||
idx_list.resize( 3, -1 );
|
idx_list.resize( 3, -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tgRectangle GetBoundingBox( void ) const
|
||||||
|
{
|
||||||
|
SGGeod min, max;
|
||||||
|
|
||||||
|
double minx = std::numeric_limits<double>::infinity();
|
||||||
|
double miny = std::numeric_limits<double>::infinity();
|
||||||
|
double maxx = -std::numeric_limits<double>::infinity();
|
||||||
|
double maxy = -std::numeric_limits<double>::infinity();
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < node_list.size(); i++) {
|
||||||
|
SGGeod pt = GetNode(i);
|
||||||
|
if ( pt.getLongitudeDeg() < minx ) { minx = pt.getLongitudeDeg(); }
|
||||||
|
if ( pt.getLongitudeDeg() > maxx ) { maxx = pt.getLongitudeDeg(); }
|
||||||
|
if ( pt.getLatitudeDeg() < miny ) { miny = pt.getLatitudeDeg(); }
|
||||||
|
if ( pt.getLatitudeDeg() > maxy ) { maxy = pt.getLatitudeDeg(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
min = SGGeod::fromDeg( minx, miny );
|
||||||
|
max = SGGeod::fromDeg( maxx, maxy );
|
||||||
|
|
||||||
|
return tgRectangle( min, max );
|
||||||
|
}
|
||||||
|
|
||||||
SGGeod const& GetNode( unsigned int i ) const {
|
SGGeod const& GetNode( unsigned int i ) const {
|
||||||
return node_list[i];
|
return node_list[i];
|
||||||
}
|
}
|
||||||
|
@ -155,6 +178,9 @@ public:
|
||||||
p3.getLongitudeDeg() * p1.getLatitudeDeg() - p1.getLongitudeDeg() * p3.getLatitudeDeg() ));
|
p3.getLongitudeDeg() * p1.getLatitudeDeg() - p1.getLongitudeDeg() * p3.getLatitudeDeg() ));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ClipperLib::Path ToClipper( const tgTriangle& subject );
|
||||||
|
static tgPolygon Intersect( const tgTriangle& subject, const tgTriangle& clip );
|
||||||
|
|
||||||
void SaveToGzFile( gzFile& fp ) const;
|
void SaveToGzFile( gzFile& fp ) const;
|
||||||
void LoadFromGzFile( gzFile& fp );
|
void LoadFromGzFile( gzFile& fp );
|
||||||
|
|
||||||
|
@ -282,6 +308,9 @@ public:
|
||||||
void AddTriangle( const SGGeod& p1, const SGGeod p2, const SGGeod p3 ) {
|
void AddTriangle( const SGGeod& p1, const SGGeod p2, const SGGeod p3 ) {
|
||||||
triangles.push_back( tgTriangle( p1, p2, p3 ) );
|
triangles.push_back( tgTriangle( p1, p2, p3 ) );
|
||||||
}
|
}
|
||||||
|
tgTriangle GetTriangle( unsigned int t ) {
|
||||||
|
return triangles[t];
|
||||||
|
}
|
||||||
|
|
||||||
SGGeod GetTriNode( unsigned int c, unsigned int i ) const {
|
SGGeod GetTriNode( unsigned int c, unsigned int i ) const {
|
||||||
return triangles[c].GetNode( i );
|
return triangles[c].GetNode( i );
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
|
|
||||||
#include "tg_polygon.hxx"
|
#include "tg_polygon.hxx"
|
||||||
|
#include "tg_misc.hxx"
|
||||||
|
|
||||||
static bool clipper_dump = false;
|
static bool clipper_dump = false;
|
||||||
void tgPolygon::SetClipperDump( bool dmp )
|
void tgPolygon::SetClipperDump( bool dmp )
|
||||||
|
@ -197,3 +198,52 @@ tgPolygon tgPolygon::FromClipper( const ClipperLib::Paths& subject )
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClipperLib::Path tgTriangle::ToClipper( const tgTriangle& subject )
|
||||||
|
{
|
||||||
|
ClipperLib::Path contour;
|
||||||
|
|
||||||
|
for ( unsigned int i=0; i<3; i++)
|
||||||
|
{
|
||||||
|
SGGeod p = subject.GetNode( i );
|
||||||
|
contour.push_back( SGGeod_ToClipper(p) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// boundaries need to be orientation: true
|
||||||
|
if ( !Orientation( contour ) ) {
|
||||||
|
//SG_LOG(SG_GENERAL, SG_INFO, "Building clipper contour - boundary contour needs to be reversed" );
|
||||||
|
ReversePath( contour );
|
||||||
|
}
|
||||||
|
|
||||||
|
return contour;
|
||||||
|
}
|
||||||
|
|
||||||
|
tgPolygon tgTriangle::Intersect( const tgTriangle& subject, const tgTriangle& clip )
|
||||||
|
{
|
||||||
|
tgPolygon result;
|
||||||
|
UniqueSGGeodSet all_nodes;
|
||||||
|
|
||||||
|
/* before diff - gather all nodes */
|
||||||
|
for ( unsigned int i = 0; i < 3; ++i ) {
|
||||||
|
all_nodes.add( subject.GetNode(i) );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( unsigned int i = 0; i < 3; ++i ) {
|
||||||
|
all_nodes.add( clip.GetNode(i) );
|
||||||
|
}
|
||||||
|
|
||||||
|
ClipperLib::Path clipper_subject = tgTriangle::ToClipper( subject );
|
||||||
|
ClipperLib::Path clipper_clip = tgTriangle::ToClipper( clip );
|
||||||
|
ClipperLib::Paths clipper_result;
|
||||||
|
|
||||||
|
ClipperLib::Clipper c;
|
||||||
|
c.Clear();
|
||||||
|
c.AddPath(clipper_subject, ClipperLib::ptSubject, true);
|
||||||
|
c.AddPath(clipper_clip, ClipperLib::ptClip, true);
|
||||||
|
c.Execute(ClipperLib::ctIntersection, clipper_result, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd);
|
||||||
|
|
||||||
|
result = tgPolygon::FromClipper( clipper_result );
|
||||||
|
result = tgPolygon::AddColinearNodes( result, all_nodes );
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
|
@ -105,6 +105,9 @@ void tgPolygon::Tesselate( const std::vector<SGGeod>& extra )
|
||||||
|
|
||||||
SG_LOG( SG_GENERAL, SG_DEBUG, "Tess with extra" );
|
SG_LOG( SG_GENERAL, SG_DEBUG, "Tess with extra" );
|
||||||
|
|
||||||
|
// clear any triangles from previous tesselation
|
||||||
|
triangles.clear();
|
||||||
|
|
||||||
// Bail right away if polygon is empty
|
// Bail right away if polygon is empty
|
||||||
if ( contours.size() != 0 ) {
|
if ( contours.size() != 0 ) {
|
||||||
// First, convert the extra points to cgal Points
|
// First, convert the extra points to cgal Points
|
||||||
|
@ -162,6 +165,9 @@ void tgPolygon::Tesselate()
|
||||||
|
|
||||||
SG_LOG( SG_GENERAL, SG_DEBUG, "Tess" );
|
SG_LOG( SG_GENERAL, SG_DEBUG, "Tess" );
|
||||||
|
|
||||||
|
// clear any triangles from previous tesselation
|
||||||
|
triangles.clear();
|
||||||
|
|
||||||
// Bail right away if polygon is empty
|
// Bail right away if polygon is empty
|
||||||
if ( contours.size() != 0 ) {
|
if ( contours.size() != 0 ) {
|
||||||
// insert each polygon as a constraint into the triangulation
|
// insert each polygon as a constraint into the triangulation
|
||||||
|
|
|
@ -65,6 +65,34 @@ void* tgShapefile::OpenLayer( void* ds_id, const char* layer_name ) {
|
||||||
return (void*)layer;
|
return (void*)layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* tgShapefile::OpenLineLayer( void* ds_id, const char* layer_name ) {
|
||||||
|
OGRDataSource* datasource = ( OGRDataSource * )ds_id;
|
||||||
|
OGRLayer* layer;
|
||||||
|
|
||||||
|
OGRSpatialReference srs;
|
||||||
|
srs.SetWellKnownGeogCS("WGS84");
|
||||||
|
|
||||||
|
layer = datasource->GetLayerByName( layer_name );
|
||||||
|
|
||||||
|
if ( !layer ) {
|
||||||
|
layer = datasource->CreateLayer( layer_name, &srs, wkbLineString25D, NULL );
|
||||||
|
|
||||||
|
OGRFieldDefn descriptionField( "ID", OFTString );
|
||||||
|
descriptionField.SetWidth( 128 );
|
||||||
|
|
||||||
|
if( layer->CreateField( &descriptionField ) != OGRERR_NONE ) {
|
||||||
|
SG_LOG( SG_GENERAL, SG_ALERT, "Creation of field 'Description' failed" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !layer ) {
|
||||||
|
SG_LOG( SG_GENERAL, SG_ALERT, "Creation of layer '" << layer_name << "' failed" );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (void*)layer;
|
||||||
|
}
|
||||||
|
|
||||||
void* tgShapefile::CloseDatasource( void* ds_id )
|
void* tgShapefile::CloseDatasource( void* ds_id )
|
||||||
{
|
{
|
||||||
OGRDataSource* datasource = ( OGRDataSource * )ds_id;
|
OGRDataSource* datasource = ( OGRDataSource * )ds_id;
|
||||||
|
@ -172,6 +200,46 @@ void tgShapefile::FromContour( const tgContour& subject, const std::string& data
|
||||||
ds_id = tgShapefile::CloseDatasource( ds_id );
|
ds_id = tgShapefile::CloseDatasource( ds_id );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tgShapefile::FromTriangles( const tgPolygon& subject, const std::string& datasource, const std::string& layer, const std::string& description )
|
||||||
|
{
|
||||||
|
void* ds_id = tgShapefile::OpenDatasource( datasource.c_str() );
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, "tgShapefile::OpenDatasource returned " << (unsigned long)ds_id);
|
||||||
|
|
||||||
|
OGRLayer* l_id = (OGRLayer *)tgShapefile::OpenLineLayer( ds_id, layer.c_str() );
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, "tgShapefile::OpenLayer returned " << (unsigned long)l_id);
|
||||||
|
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, "subject has " << subject.Contours() << " contours ");
|
||||||
|
|
||||||
|
for ( unsigned int i = 0; i < subject.Triangles(); i++ ) {
|
||||||
|
// FIXME: Current we ignore the hole-flag and instead assume
|
||||||
|
// that the first ring is not a hole and the rest
|
||||||
|
// are holes
|
||||||
|
OGRLinearRing ring;
|
||||||
|
for (unsigned int pt = 0; pt < 3; pt++) {
|
||||||
|
OGRPoint point;
|
||||||
|
|
||||||
|
point.setX( subject.GetTriNode(i, pt).getLongitudeDeg() );
|
||||||
|
point.setY( subject.GetTriNode(i, pt).getLatitudeDeg() );
|
||||||
|
point.setZ( 0.0 );
|
||||||
|
ring.addPoint(&point);
|
||||||
|
}
|
||||||
|
ring.closeRings();
|
||||||
|
|
||||||
|
OGRFeature* feature = NULL;
|
||||||
|
feature = new OGRFeature( l_id->GetLayerDefn() );
|
||||||
|
feature->SetField("ID", description.c_str());
|
||||||
|
feature->SetGeometry(&ring);
|
||||||
|
if( l_id->CreateFeature( feature ) != OGRERR_NONE )
|
||||||
|
{
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT, "Failed to create feature in shapefile");
|
||||||
|
}
|
||||||
|
OGRFeature::DestroyFeature(feature);
|
||||||
|
}
|
||||||
|
|
||||||
|
// close after each write
|
||||||
|
ds_id = tgShapefile::CloseDatasource( ds_id );
|
||||||
|
}
|
||||||
|
|
||||||
void tgShapefile::FromPolygon( const tgPolygon& subject, const std::string& datasource, const std::string& layer, const std::string& description )
|
void tgShapefile::FromPolygon( const tgPolygon& subject, const std::string& datasource, const std::string& layer, const std::string& description )
|
||||||
{
|
{
|
||||||
void* ds_id = tgShapefile::OpenDatasource( datasource.c_str() );
|
void* ds_id = tgShapefile::OpenDatasource( datasource.c_str() );
|
||||||
|
|
|
@ -8,6 +8,7 @@ class tgShapefile
|
||||||
public:
|
public:
|
||||||
static void FromContour( const tgContour& subject, const std::string& datasource, const std::string& layer, const std::string& description );
|
static void FromContour( const tgContour& subject, const std::string& datasource, const std::string& layer, const std::string& description );
|
||||||
static void FromPolygon( const tgPolygon& subject, const std::string& datasource, const std::string& layer, const std::string& description );
|
static void FromPolygon( const tgPolygon& subject, const std::string& datasource, const std::string& layer, const std::string& description );
|
||||||
|
static void FromTriangles( const tgPolygon& subject, const std::string& datasource, const std::string& layer, const std::string& description );
|
||||||
static tgPolygon ToPolygon( const void* subject );
|
static tgPolygon ToPolygon( const void* subject );
|
||||||
|
|
||||||
static void FromClipper( const ClipperLib::Paths& subject, const std::string& datasource, const std::string& layer, const std::string& description );
|
static void FromClipper( const ClipperLib::Paths& subject, const std::string& datasource, const std::string& layer, const std::string& description );
|
||||||
|
@ -17,5 +18,6 @@ private:
|
||||||
|
|
||||||
static void* OpenDatasource( const char* datasource_name );
|
static void* OpenDatasource( const char* datasource_name );
|
||||||
static void* OpenLayer( void* ds_id, const char* layer_name );
|
static void* OpenLayer( void* ds_id, const char* layer_name );
|
||||||
|
static void* OpenLineLayer( void* ds_id, const char* layer_name );
|
||||||
static void* CloseDatasource( void* ds_id );
|
static void* CloseDatasource( void* ds_id );
|
||||||
};
|
};
|
Loading…
Add table
Reference in a new issue