1
0
Fork 0

convert tg_nodes to SGGeod and SGVecd/f

This commit is contained in:
Peter Sadrozinski 2012-11-29 19:24:31 -05:00
parent f157a33d76
commit c0555a1270
17 changed files with 376 additions and 400 deletions

View file

@ -164,7 +164,7 @@ private:
void CalcPointNormals( void );
void CalcTextureCoordinates( void );
// Helpers
SGVec3d calc_normal( double area, Point3D p1, Point3D p2, Point3D p3 );
SGVec3d calc_normal( double area, const SGVec3d& p1, const SGVec3d& p2, const SGVec3d& p3 );
TGPolygon linear_tex_coords( const TGPolygon& tri, const TGTexParams& tp );
TGPolygon area_tex_coords( const TGPolygon& tri );
@ -173,7 +173,7 @@ private:
void AddCustomObjects( void );
// Misc
void calc_normals( point_list& wgs84_nodes, TGSuperPoly& sp );
void calc_normals( std::vector<SGVec3d>& wgs84_nodes, TGSuperPoly& sp );
double calc_tri_area( int_list& triangle_nodes );
// debug
@ -244,11 +244,11 @@ public:
inline TGNodes* get_nodes() { return &nodes; }
// node list in geodetic coords (with fixed elevation)
inline point_list get_geod_nodes() const { return nodes.get_geod_nodes(); }
inline void get_geod_nodes( std::vector<SGGeod>& points ) const { nodes.get_geod_nodes( points ); }
// normal list (for each point) in cart coords (for smooth
// shading)
inline point_list get_point_normals() const { return nodes.get_normals(); }
inline void get_point_normals( std::vector<SGVec3f>& normals ) const { nodes.get_normals( normals ); }
// Debug
void set_debug( std::string path, std::vector<std::string> area_defs, std::vector<std::string> shape_defs );

View file

@ -199,7 +199,7 @@ void TGConstruct::AverageEdgeElevations( void )
elevation = elevation / num_elevations;
/* Find this node, and update it's elevation */
int idx = nodes.find( faces.node );
int idx = nodes.find( faces.node.toSGGeod() );
if (idx != -1) {
TGNode node = nodes.get_node( idx );

View file

@ -54,19 +54,19 @@ bool TGConstruct::ClipLandclassPolys( void ) {
p = Point3D(min.x(), min.y(), -9999.0);
safety_base.add_node( 0, p );
nodes.unique_add( p );
nodes.unique_add( p.toSGGeod() );
p = Point3D(max.x(), min.y(), -9999.0);
safety_base.add_node( 0, p );
nodes.unique_add( p );
nodes.unique_add( p.toSGGeod() );
p = Point3D(max.x(), max.y(), -9999.0);
safety_base.add_node( 0, p );
nodes.unique_add( p );
nodes.unique_add( p.toSGGeod() );
p = Point3D(min.x(), max.y(), -9999.0);
safety_base.add_node( 0, p );
nodes.unique_add( p );
nodes.unique_add( p.toSGGeod() );
// set up land mask, we clip most things to this since it is our
// best representation of land vs. ocean. If we have other less
@ -274,7 +274,7 @@ bool TGConstruct::ClipLandclassPolys( void ) {
for (int con=0; con < poly.contours(); con++) {
for (int node = 0; node < poly.contour_size( con ); node++) {
// ensure we have all nodes...
nodes.unique_add( poly.get_pt( con, node ) );
nodes.unique_add( poly.get_pt( con, node ).toSGGeod() );
}
}
}

View file

@ -52,12 +52,12 @@ void TGConstruct::LoadElevationArray( bool add_nodes ) {
if ( add_nodes ) {
point_list corner_list = array.get_corner_list();
for (unsigned int i=0; i<corner_list.size(); i++) {
nodes.unique_add(corner_list[i]);
nodes.unique_add( corner_list[i].toSGGeod() );
}
point_list fit_list = array.get_fitted_list();
for (unsigned int i=0; i<fit_list.size(); i++) {
nodes.unique_add(fit_list[i]);
nodes.unique_add( fit_list[i].toSGGeod() );
}
}
}
@ -72,13 +72,13 @@ static void calc_gc_course_dist( const Point3D& start, const Point3D& dest,
// calculate spherical distance between two points (lon, lat specified
// in degrees, result returned in meters)
static double distanceSphere( const Point3D p1, const Point3D p2 ) {
Point3D r1( p1.x() * SG_DEGREES_TO_RADIANS,
p1.y() * SG_DEGREES_TO_RADIANS,
p1.z() );
Point3D r2( p2.x() * SG_DEGREES_TO_RADIANS,
p2.y() * SG_DEGREES_TO_RADIANS,
p2.z() );
static double distanceSphere( const SGGeoc& p1, const SGGeod& p2 ) {
Point3D r1( p1.getLongitudeRad(),
p1.getLatitudeRad(),
p1.getRadiusM() );
Point3D r2( p2.getLongitudeRad(),
p2.getLatitudeRad(),
p2.getElevationM() );
double course, dist_m;
calc_gc_course_dist( r1, r2, &course, &dist_m );
@ -94,22 +94,22 @@ void TGConstruct::CalcElevations( void )
TGPolyNodes tri_nodes;
double e1, e2, e3, min;
int n1, n2, n3;
point_list raw_nodes;
Point3D p;
std::vector<SGGeod> raw_nodes;
SGGeoc p;
SG_LOG(SG_GENERAL, SG_ALERT, "fixing node heights");
for (int i = 0; i < (int)nodes.size(); ++i) {
TGNode node = nodes.get_node( i );
Point3D pos = node.GetPosition();
SGGeod pos = node.GetPosition();
if ( !node.GetFixedPosition() ) {
// set elevation as interpolated point from DEM data.
nodes.SetElevation( i, array.altitude_from_grid(pos.x() * 3600.0, pos.y() * 3600.0) );
nodes.SetElevation( i, array.altitude_from_grid(pos.getLongitudeDeg() * 3600.0, pos.getLatitudeDeg() * 3600.0) );
}
}
raw_nodes = nodes.get_geod_nodes();
nodes.get_geod_nodes(raw_nodes);
// now flatten some stuff
for (unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++) {
if ( is_lake_area( (AreaType)area ) ) {
@ -126,11 +126,11 @@ void TGConstruct::CalcElevations( void )
}
n1 = tri_nodes.get_pt( tri, 0 );
e1 = nodes.get_node(n1).GetPosition().z();
e1 = nodes.get_node(n1).GetPosition().getElevationM();
n2 = tri_nodes.get_pt( tri, 1 );
e2 = nodes.get_node(n2).GetPosition().z();
e2 = nodes.get_node(n2).GetPosition().getElevationM();
n3 = tri_nodes.get_pt( tri, 2 );
e3 = nodes.get_node(n3).GetPosition().z();
e3 = nodes.get_node(n3).GetPosition().getElevationM();
min = e1;
if ( e2 < min ) { min = e2; }
@ -159,17 +159,17 @@ void TGConstruct::CalcElevations( void )
n1 = tri_nodes.get_pt( tri, 0 );
e1 = nodes.get_node(n1).GetPosition().z();
e1 = nodes.get_node(n1).GetPosition().getElevationM();
n2 = tri_nodes.get_pt( tri, 1 );
e2 = nodes.get_node(n2).GetPosition().z();
e2 = nodes.get_node(n2).GetPosition().getElevationM();
n3 = tri_nodes.get_pt( tri, 2 );
e3 = nodes.get_node(n3).GetPosition().z();
e3 = nodes.get_node(n3).GetPosition().getElevationM();
min = e1;
p = raw_nodes[n1];
p = SGGeoc::fromGeod( raw_nodes[n1] );
if ( e2 < min ) { min = e2; p = raw_nodes[n2]; }
if ( e3 < min ) { min = e3; p = raw_nodes[n3]; }
if ( e2 < min ) { min = e2; p = SGGeoc::fromGeod( raw_nodes[n2] ); }
if ( e3 < min ) { min = e3; p = SGGeoc::fromGeod( raw_nodes[n3] ); }
double d1 = distanceSphere( p, raw_nodes[n1] );
double d2 = distanceSphere( p, raw_nodes[n2] );
@ -202,17 +202,17 @@ void TGConstruct::CalcElevations( void )
n1 = tri_nodes.get_pt( tri, 0 );
e1 = nodes.get_node(n1).GetPosition().z();
e1 = nodes.get_node(n1).GetPosition().getElevationM();
n2 = tri_nodes.get_pt( tri, 1 );
e2 = nodes.get_node(n2).GetPosition().z();
e2 = nodes.get_node(n2).GetPosition().getElevationM();
n3 = tri_nodes.get_pt( tri, 2 );
e3 = nodes.get_node(n3).GetPosition().z();
e3 = nodes.get_node(n3).GetPosition().getElevationM();
min = e1;
p = raw_nodes[n1];
p = SGGeoc::fromGeod( raw_nodes[n1] );
if ( e2 < min ) { min = e2; p = raw_nodes[n2]; }
if ( e3 < min ) { min = e3; p = raw_nodes[n3]; }
if ( e2 < min ) { min = e2; p = SGGeoc::fromGeod( raw_nodes[n2] ); }
if ( e3 < min ) { min = e3; p = SGGeoc::fromGeod( raw_nodes[n3] ); }
double d1 = distanceSphere( p, raw_nodes[n1] );
double d2 = distanceSphere( p, raw_nodes[n2] );

View file

@ -46,7 +46,7 @@ void TGConstruct::LookupNodesPerVertex( void )
for (int tri=0; tri < tris.contours(); tri++) {
for (int vertex = 0; vertex < tris.contour_size(tri); vertex++) {
idx = nodes.find( tris.get_pt( tri, vertex ) );
idx = nodes.find( tris.get_pt( tri, vertex ).toSGGeod() );
if (idx >= 0) {
tri_nodes.add_node( tri, idx );
} else {
@ -73,7 +73,7 @@ void TGConstruct::LookupFacesPerNode( void )
for (int tri=0; tri < tris.contours(); tri++) {
for (int sub = 0; sub < tris.contour_size(tri); sub++) {
int n = nodes.find( tris.get_pt( tri, sub ) );
int n = nodes.find( tris.get_pt( tri, sub ).toSGGeod() );
nodes.AddFace( n, area, shape, segment, tri );
}
}

View file

@ -32,14 +32,14 @@
//using std::string;
double TGConstruct::calc_tri_area( int_list& triangle_nodes ) {
Point3D p1 = nodes.get_node( triangle_nodes[0] ).GetPosition();
Point3D p2 = nodes.get_node( triangle_nodes[1] ).GetPosition();
Point3D p3 = nodes.get_node( triangle_nodes[2] ).GetPosition();
SGGeod p1 = nodes.get_node( triangle_nodes[0] ).GetPosition();
SGGeod p2 = nodes.get_node( triangle_nodes[1] ).GetPosition();
SGGeod p3 = nodes.get_node( triangle_nodes[2] ).GetPosition();
return triangle_area( p1, p2, p3 );
}
SGVec3d TGConstruct::calc_normal( double area, Point3D p1, Point3D p2, Point3D p3 ) {
SGVec3d TGConstruct::calc_normal( double area, const SGVec3d& p1, const SGVec3d& p2, const SGVec3d& p3 ) {
SGVec3d v1, v2, normal;
// do some sanity checking. With the introduction of landuse
@ -76,7 +76,7 @@ SGVec3d TGConstruct::calc_normal( double area, Point3D p1, Point3D p2, Point3D p
return normal;
}
void TGConstruct::calc_normals( point_list& wgs84_nodes, TGSuperPoly& sp ) {
void TGConstruct::calc_normals( std::vector<SGVec3d>& wgs84_nodes, TGSuperPoly& sp ) {
// for each face in the superpoly, calculate a face normal
SGVec3d normal;
TGPolyNodes tri_nodes = sp.get_tri_idxs();
@ -91,12 +91,11 @@ void TGConstruct::calc_normals( point_list& wgs84_nodes, TGSuperPoly& sp ) {
for (int i=0; i<tri_nodes.contours(); i++) {
face_nodes = tri_nodes.get_contour(i);
Point3D p1 = wgs84_nodes[ face_nodes[0] ];
Point3D p2 = wgs84_nodes[ face_nodes[1] ];
Point3D p3 = wgs84_nodes[ face_nodes[2] ];
SGVec3d p1 = wgs84_nodes[ face_nodes[0] ];
SGVec3d p2 = wgs84_nodes[ face_nodes[1] ];
SGVec3d p3 = wgs84_nodes[ face_nodes[2] ];
area = calc_tri_area( face_nodes );
normal = calc_normal( area, p1, p2, p3 );
face_normals.push_back( Point3D::fromSGVec3( normal ) );
@ -110,7 +109,8 @@ void TGConstruct::calc_normals( point_list& wgs84_nodes, TGSuperPoly& sp ) {
void TGConstruct::CalcFaceNormals( void )
{
// traverse the superpols, and calc normals for each tri within
point_list wgs84_nodes = nodes.get_wgs84_nodes_as_Point3d();
std::vector<SGVec3d> wgs84_nodes;
nodes.get_wgs84_nodes( wgs84_nodes );
for (unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++) {
for (unsigned int shape = 0; shape < polys_clipped.area_size(area); shape++ ) {
@ -127,10 +127,12 @@ void TGConstruct::CalcPointNormals( void )
// traverse triangle structure building the face normal table
SG_LOG(SG_GENERAL, SG_ALERT, "Calculating point normals: 0%");
Point3D normal;
SGVec3d normal;
double face_area;
point_list wgs84_nodes = nodes.get_wgs84_nodes_as_Point3d();
std::vector<SGVec3d> wgs84_nodes;
nodes.get_wgs84_nodes( wgs84_nodes );
unsigned int one_percent = nodes.size() / 100;
unsigned int cur_percent = 1;
@ -140,7 +142,7 @@ void TGConstruct::CalcPointNormals( void )
TGNeighborFaces* neighbor_faces = NULL;
double total_area = 0.0;
Point3D average( 0.0 );
SGVec3d average( 0.0, 0.0, 0.0 );
if ( i == one_percent ) {
SG_LOG(SG_GENERAL, SG_ALERT, "Calculating point normals: " << cur_percent << "%" );
@ -156,7 +158,7 @@ void TGConstruct::CalcPointNormals( void )
unsigned int tri = faces[j].tri;
int_list face_nodes;
normal = polys_clipped.get_face_normal( at, shape, segment, tri );
normal = polys_clipped.get_face_normal( at, shape, segment, tri ).toSGVec3d();
face_nodes = polys_clipped.get_tri_idxs( at, shape, segment ).get_contour( tri ) ;
face_area = polys_clipped.get_face_area( at, shape, segment, tri );
@ -166,11 +168,11 @@ void TGConstruct::CalcPointNormals( void )
}
// if this node exists in the shared edge db, add the faces from the neighbooring tile
neighbor_faces = FindNeighborFaces( node.GetPosition() );
neighbor_faces = FindNeighborFaces( Point3D::fromSGGeod( node.GetPosition() ) );
if ( neighbor_faces ) {
int num_faces = neighbor_faces->face_areas.size();
for ( int j = 0; j < num_faces; j++ ) {
normal = neighbor_faces->face_normals[j];
normal = neighbor_faces->face_normals[j].toSGVec3d();
face_area = neighbor_faces->face_areas[j];
normal *= face_area;
@ -180,6 +182,7 @@ void TGConstruct::CalcPointNormals( void )
}
average /= total_area;
nodes.SetNormal( i, average );
SGVec3f n = SGVec3f( average.x(), average.y(), average.z() );
nodes.SetNormal( i, n );
}
}

View file

@ -155,7 +155,7 @@ void TGConstruct::WriteBtgFile( void )
tri_v.push_back( index );
// add the node's normal
index = normals.unique_add( nodes.GetNormal( index ) );
index = normals.unique_add( Point3D::fromSGVec3( nodes.GetNormal( index ) ) );
tri_n.push_back( index );
Point3D tc = tri_txs.get_pt( k, l );
@ -174,7 +174,8 @@ void TGConstruct::WriteBtgFile( void )
}
}
std::vector< SGVec3d > wgs84_nodes = nodes.get_wgs84_nodes_as_SGVec3d();
std::vector< SGVec3d > wgs84_nodes;
nodes.get_wgs84_nodes( wgs84_nodes );
SGVec3d gbs_center = SGVec3d::fromGeod( bucket.get_center() );
double dist_squared, radius_squared = 0;
for (int i = 0; i < (int)wgs84_nodes.size(); ++i)

View file

@ -177,9 +177,9 @@ bool TGConstruct::load_poly(const string& path) {
poly.add_node( i, p );
if ( poly3d ) {
nodes.unique_add_fixed_elevation( p );
nodes.unique_add_fixed_elevation( p.toSGGeod() );
} else {
nodes.unique_add( p );
nodes.unique_add( p.toSGGeod() );
}
for ( j = 1; j < count - 1; ++j ) {
@ -194,9 +194,9 @@ bool TGConstruct::load_poly(const string& path) {
p.snap( gSnap );
poly.add_node( i, p );
if ( poly3d ) {
nodes.unique_add_fixed_elevation( p );
nodes.unique_add_fixed_elevation( p.toSGGeod() );
} else {
nodes.unique_add( p );
nodes.unique_add( p.toSGGeod() );
}
}
@ -217,9 +217,9 @@ bool TGConstruct::load_poly(const string& path) {
p.snap( gSnap );
poly.add_node( i, p );
if ( poly3d ) {
nodes.unique_add_fixed_elevation( p );
nodes.unique_add_fixed_elevation( p.toSGGeod() );
} else {
nodes.unique_add( p );
nodes.unique_add( p.toSGGeod() );
}
}
}

View file

@ -43,7 +43,7 @@ void TGConstruct::SaveSharedEdgeData( int stage )
switch( stage ) {
case 1:
{
point_list north, south, east, west;
std::vector<SGGeod> north, south, east, west;
int nCount;
nodes.get_geod_edge( bucket, north, south, east, west );
@ -64,28 +64,28 @@ void TGConstruct::SaveSharedEdgeData( int stage )
nCount = north.size();
sgWriteInt( fp, nCount );
for (int i=0; i<nCount; i++) {
sgWritePoint3D( fp, north[i] );
sgWriteGeod( fp, north[i] );
}
// south
nCount = south.size();
sgWriteInt( fp, nCount );
for (int i=0; i<nCount; i++) {
sgWritePoint3D( fp, south[i] );
sgWriteGeod( fp, south[i] );
}
// east
nCount = east.size();
sgWriteInt( fp, nCount );
for (int i=0; i<nCount; i++) {
sgWritePoint3D( fp, east[i] );
sgWriteGeod( fp, east[i] );
}
// west
nCount = west.size();
sgWriteInt( fp, nCount );
for (int i=0; i<nCount; i++) {
sgWritePoint3D( fp, west[i] );
sgWriteGeod( fp, west[i] );
}
gzclose(fp);
@ -113,7 +113,7 @@ void TGConstruct::SaveSharedEdgeData( int stage )
void TGConstruct::WriteNeighborFaces( gzFile& fp, Point3D pt )
{
// find all neighboors of this point
int n = nodes.find( pt );
int n = nodes.find( pt.toSGGeod() );
TGNode node = nodes.get_node( n );
TGFaceList faces = node.GetFaces();
@ -130,19 +130,19 @@ void TGConstruct::WriteNeighborFaces( gzFile& fp, Point3D pt )
int_list face_nodes = polys_clipped.get_tri_idxs( at, shape, segment ).get_contour( tri ) ;
{
Point3D p1 = nodes.get_node( face_nodes[0] ).GetPosition();
Point3D p2 = nodes.get_node( face_nodes[1] ).GetPosition();
Point3D p3 = nodes.get_node( face_nodes[2] ).GetPosition();
SGGeod p1 = nodes.get_node( face_nodes[0] ).GetPosition();
SGGeod p2 = nodes.get_node( face_nodes[1] ).GetPosition();
SGGeod p3 = nodes.get_node( face_nodes[2] ).GetPosition();
Point3D wgs_p1 = nodes.get_node( face_nodes[0] ).GetWgs84AsPoint3D();
Point3D wgs_p2 = nodes.get_node( face_nodes[1] ).GetWgs84AsPoint3D();
Point3D wgs_p3 = nodes.get_node( face_nodes[2] ).GetWgs84AsPoint3D();
SGVec3d wgs_p1 = nodes.get_node( face_nodes[0] ).GetWgs84();
SGVec3d wgs_p2 = nodes.get_node( face_nodes[1] ).GetWgs84();
SGVec3d wgs_p3 = nodes.get_node( face_nodes[2] ).GetWgs84();
double face_area = triangle_area( p1, p2, p3 );
Point3D face_normal = Point3D::fromSGVec3( calc_normal( face_area, wgs_p1, wgs_p2, wgs_p3 ) );
SGVec3d face_normal = calc_normal( face_area, wgs_p1, wgs_p2, wgs_p3 );
sgWriteDouble( fp, face_area );
sgWritePoint3D( fp, face_normal );
sgWritedVec3( fp, face_normal );
}
}
}
@ -193,10 +193,10 @@ void TGConstruct::ReadNeighborFaces( gzFile& fp )
pFaces = AddNeighborFaces( node );
// new face - let's add our elevation first
int idx = nodes.find( node );
int idx = nodes.find( node.toSGGeod() );
if (idx >= 0) {
TGNode local = nodes.get_node( idx );
pFaces->elevations.push_back( local.GetPosition().z() );
pFaces->elevations.push_back( local.GetPosition().getElevationM() );
}
}
@ -222,7 +222,7 @@ void TGConstruct::SaveSharedEdgeDataStage2( void )
{
string dir;
string file;
point_list north, south, east, west;
std::vector<SGGeod> north, south, east, west;
int nCount;
nodes.get_geod_edge( bucket, north, south, east, west );
@ -233,7 +233,6 @@ void TGConstruct::SaveSharedEdgeDataStage2( void )
sgp.append( "dummy" );
sgp.create_dir( 0755 );
// north edge
file = dir + "/" + bucket.gen_index_str() + "_north_edge";
gzFile fp;
@ -247,8 +246,8 @@ void TGConstruct::SaveSharedEdgeDataStage2( void )
sgWriteInt( fp, nCount );
for (int i=0; i<nCount; i++) {
// write the 3d point
sgWritePoint3D( fp, north[i] );
WriteNeighborFaces( fp, north[i] );
sgWriteGeod( fp, north[i] );
WriteNeighborFaces( fp, Point3D::fromSGGeod( north[i] ) );
}
gzclose(fp);
@ -263,8 +262,8 @@ void TGConstruct::SaveSharedEdgeDataStage2( void )
nCount = south.size();
sgWriteInt( fp, nCount );
for (int i=0; i<nCount; i++) {
sgWritePoint3D( fp, south[i] );
WriteNeighborFaces( fp, south[i] );
sgWriteGeod( fp, south[i] );
WriteNeighborFaces( fp, Point3D::fromSGGeod( south[i] ) );
}
gzclose(fp);
@ -279,8 +278,8 @@ void TGConstruct::SaveSharedEdgeDataStage2( void )
nCount = east.size();
sgWriteInt( fp, nCount );
for (int i=0; i<nCount; i++) {
sgWritePoint3D( fp, east[i] );
WriteNeighborFaces( fp, east[i] );
sgWriteGeod( fp, east[i] );
WriteNeighborFaces( fp, Point3D::fromSGGeod( east[i] ) );
}
gzclose(fp);
@ -295,8 +294,8 @@ void TGConstruct::SaveSharedEdgeDataStage2( void )
nCount = west.size();
sgWriteInt( fp, nCount );
for (int i=0; i<nCount; i++) {
sgWritePoint3D( fp, west[i] );
WriteNeighborFaces( fp, west[i] );
sgWriteGeod( fp, west[i] );
WriteNeighborFaces( fp, Point3D::fromSGGeod( west[i] ) );
}
gzclose(fp);
}
@ -497,28 +496,28 @@ void TGConstruct::LoadSharedEdgeData( int stage )
LoadNeighboorEdgeDataStage1( nb, north, south, east, west );
// Add southern nodes from northern tile
for (unsigned int i=0; i<south.size(); i++) {
nodes.unique_add( south[i] );
nodes.unique_add( south[i].toSGGeod() );
}
// Read South Tile and add its northern nodes
sb = sgBucketOffset(clon, clat, 0, -1);
LoadNeighboorEdgeDataStage1( sb, north, south, east, west );
for (unsigned int i=0; i<north.size(); i++) {
nodes.unique_add( north[i] );
nodes.unique_add( north[i].toSGGeod() );
}
// Read East Tile and add its western nodes
eb = sgBucketOffset(clon, clat, 1, 0);
LoadNeighboorEdgeDataStage1( eb, north, south, east, west );
for (unsigned int i=0; i<west.size(); i++) {
nodes.unique_add( west[i] );
nodes.unique_add( west[i].toSGGeod() );
}
// Read West Tile and add its eastern nodes
wb = sgBucketOffset(clon, clat, -1, 0);
LoadNeighboorEdgeDataStage1( wb, north, south, east, west );
for (unsigned int i=0; i<east.size(); i++) {
nodes.unique_add( east[i] );
nodes.unique_add( east[i].toSGGeod() );
}
}
break;

View file

@ -38,7 +38,7 @@
void TGConstruct::TesselatePolys( void )
{
// tesselate the polygons and prepair them for final output
point_list poly_extra;
std::vector<SGGeod> poly_extra;
SGGeod min, max;
for (unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++) {
@ -53,7 +53,7 @@ void TGConstruct::TesselatePolys( void )
TGPolygon poly = polys_clipped.get_poly(area, shape, segment);
poly.get_bounding_box(min, max);
poly_extra = nodes.get_geod_inside( Point3D::fromSGGeod(min), Point3D::fromSGGeod(max) );
nodes.get_geod_inside( min, max, poly_extra );
SG_LOG( SG_CLIPPER, SG_INFO, "Tesselating " << get_area_name( (AreaType)area ) << "(" << area << "): " <<
shape+1 << "-" << segment << " of " << (int)polys_clipped.area_size(area) <<
@ -69,7 +69,7 @@ void TGConstruct::TesselatePolys( void )
for (int k=0; k< tri.contours(); k++) {
for (int l = 0; l < tri.contour_size(k); l++) {
// ensure we have all nodes...
nodes.unique_add( tri.get_pt( k, l ) );
nodes.unique_add( tri.get_pt( k, l ).toSGGeod() );
}
}

View file

@ -103,7 +103,7 @@ void insert_polygon(CDT& cdt,const Polygon_2& polygon)
}
}
TGPolygon polygon_tesselate_alt_with_extra_cgal( TGPolygon &p, const point_list& extra_nodes, bool verbose ) {
TGPolygon polygon_tesselate_alt_with_extra_cgal( TGPolygon &p, const std::vector<SGGeod>& extra_nodes, bool verbose ) {
TGPolygon result;
CDT cdt;
@ -118,10 +118,10 @@ TGPolygon polygon_tesselate_alt_with_extra_cgal( TGPolygon &p, const point_list&
std::vector<Point> points;
points.reserve(extra_nodes.size());
for (unsigned int n = 0; n < extra_nodes.size(); n++) {
points.push_back( Point(extra_nodes[n].x(), extra_nodes[n].y()) );
points.push_back( Point(extra_nodes[n].getLongitudeDeg(), extra_nodes[n].getLatitudeDeg()) );
}
cdt.insert(points.begin(), points.end());
// then insert each polygon as a constraint into the triangulation
for (int c = 0; c < p.contours(); c++) {
point_list contour = p.get_contour( c );
@ -160,6 +160,6 @@ TGPolygon polygon_tesselate_alt_with_extra_cgal( TGPolygon &p, const point_list&
TGPolygon polygon_tesselate_alt_cgal( TGPolygon &p, bool verbose ) {
point_list pl; pl.clear();
std::vector<SGGeod> pl; pl.clear();
return ( polygon_tesselate_alt_with_extra_cgal(p, pl, verbose) );
}

View file

@ -59,6 +59,32 @@ void add_intermediate_nodes( int contour, const Point3D& start,
}
}
void add_intermediate_nodes( int contour, const Point3D& start,
const Point3D& end, std::vector<SGGeod>&tmp_nodes,
TGPolygon *result,
const double bbEpsilon,
const double errEpsilon
)
{
Point3D new_pt;
SG_LOG(SG_GENERAL, SG_BULK, " " << start << " <==> " << end );
bool found_extra = find_intermediate_node( start, end, tmp_nodes, &new_pt, bbEpsilon, errEpsilon );
if ( found_extra ) {
// recurse with two sub segments
// SG_LOG(SG_GENERAL, SG_DEBUG, "dividing " << p0 << " " << nodes[extra_index]
// << " " << p1);
add_intermediate_nodes( contour, start, new_pt, tmp_nodes, result, bbEpsilon, errEpsilon );
result->add_node( contour, new_pt );
SG_LOG(SG_GENERAL, SG_BULK, " adding = " << new_pt);
add_intermediate_nodes( contour, new_pt, end, tmp_nodes, result, bbEpsilon, errEpsilon );
}
}
// Search each segment for additional vertex points that may have been
// created elsewhere that lie on the segment and split it there to
@ -113,12 +139,12 @@ TGPolygon add_tgnodes_to_poly( const TGPolygon& poly,
TGPolygon result; result.erase();
SGGeod min, max;
Point3D p0, p1;
point_list poly_points;
std::vector<SGGeod> poly_points;
poly.get_bounding_box(min, max);
SG_LOG(SG_GENERAL, SG_DEBUG, "add_tgnodes_to_poly : min " << min << " max " << max );
poly_points = nodes->get_geod_inside( Point3D::fromSGGeod(min), Point3D::fromSGGeod(max) );
nodes->get_geod_inside( min, max, poly_points );
for ( int i = 0; i < poly.contours(); ++i ) {
SG_LOG(SG_GENERAL, SG_DEBUG, "contour = " << i);

View file

@ -44,6 +44,14 @@ void add_intermediate_nodes( int contour, const Point3D& start,
);
// TEMP - converting tgnodes to SGGeod/SGVec3d
void add_intermediate_nodes( int contour, const Point3D& start,
const Point3D& end, const std::vector<SGGeod>& tmp_nodes,
TGPolygon *result,
const double bbEpsilon = SG_EPSILON*10,
const double errEpsilon = SG_EPSILON*4
);
// Search each segment for additional vertex points that may have been
// created elsewhere that lie on the segment and split it there to
// avoid "T" intersections.

View file

@ -730,6 +730,126 @@ bool find_intermediate_node( const Point3D& start, const Point3D& end,
return found_node;
}
// temp
bool find_intermediate_node( const Point3D& start, const Point3D& end,
const std::vector<SGGeod>& nodes, Point3D *result,
double bbEpsilon, double errEpsilon
)
{
bool found_node = false;
double m, m1, b, b1, y_err, x_err, y_err_min, x_err_min;
Point3D p0 = start;
Point3D p1 = end;
// cout << " find_intermediate_nodes() " << p0 << " <=> " << p1 << endl;
double xdist = fabs(p0.x() - p1.x());
double ydist = fabs(p0.y() - p1.y());
// cout << "xdist = " << xdist << " ydist = " << ydist << endl;
x_err_min = xdist + 1.0;
y_err_min = ydist + 1.0;
if ( xdist > ydist ) {
// cout << "use y = mx + b" << endl;
// sort these in a sensible order
Point3D p_min, p_max;
if ( p0.x() < p1.x() ) {
p_min = p0;
p_max = p1;
} else {
p_min = p1;
p_max = p0;
}
m = (p_min.y() - p_max.y()) / (p_min.x() - p_max.x());
b = p_max.y() - m * p_max.x();
// cout << "m = " << m << " b = " << b << endl;
for ( int i = 0; i < (int)nodes.size(); ++i ) {
// cout << i << endl;
Point3D current = Point3D::fromSGGeod( nodes[i] );
if ( (current.x() > (p_min.x() + (bbEpsilon)))
&& (current.x() < (p_max.x() - (bbEpsilon))) ) {
// printf( "found a potential candidate %.7f %.7f %.7f\n",
// current.x(), current.y(), current.z() );
y_err = fabs(current.y() - (m * current.x() + b));
// cout << "y_err = " << y_err << endl;
if ( y_err < errEpsilon ) {
// cout << "FOUND EXTRA SEGMENT NODE (Y)" << endl;
// cout << p_min << " < " << current << " < "
// << p_max << endl;
found_node = true;
if ( y_err < y_err_min ) {
*result = current;
y_err_min = y_err;
}
}
}
}
} else {
// cout << "use x = m1 * y + b1" << endl;
// sort these in a sensible order
Point3D p_min, p_max;
if ( p0.y() < p1.y() ) {
p_min = p0;
p_max = p1;
} else {
p_min = p1;
p_max = p0;
}
m1 = (p_min.x() - p_max.x()) / (p_min.y() - p_max.y());
b1 = p_max.x() - m1 * p_max.y();
// cout << " m1 = " << m1 << " b1 = " << b1 << endl;
// printf( " m = %.8f b = %.8f\n", 1/m1, -b1/m1);
// cout << " should = 0 = "
// << fabs(p_min.x() - (m1 * p_min.y() + b1)) << endl;
// cout << " should = 0 = "
// << fabs(p_max.x() - (m1 * p_max.y() + b1)) << endl;
for ( int i = 0; i < (int)nodes.size(); ++i ) {
Point3D current = Point3D::fromSGGeod( nodes[i] );
if ( (current.y() > (p_min.y() + (bbEpsilon)))
&& (current.y() < (p_max.y() - (bbEpsilon))) ) {
// printf( "found a potential candidate %.7f %.7f %.7f\n",
// current.x(), current.y(), current.z() );
x_err = fabs(current.x() - (m1 * current.y() + b1));
// cout << "x_err = " << x_err << endl;
// if ( temp ) {
// cout << " (" << counter << ") x_err = " << x_err << endl;
// }
if ( x_err < errEpsilon ) {
// cout << "FOUND EXTRA SEGMENT NODE (X)" << endl;
// cout << p_min << " < " << current << " < "
// << p_max << endl;
found_node = true;
if ( x_err < x_err_min ) {
*result = current;
x_err_min = x_err;
}
}
}
}
}
return found_node;
}
// Attempt to reduce degeneracies where a subsequent point of a
// polygon lies *on* a previous line segment.

View file

@ -41,11 +41,11 @@
// Calculate the area of a triangle
inline double triangle_area( const Point3D& p1, const Point3D& p2, const Point3D& p3 )
inline double triangle_area( const SGGeod& p1, const SGGeod& p2, const SGGeod& p3 )
{
return fabs(0.5 * ( p1.x() * p2.y() - p2.x() * p1.y() +
p2.x() * p3.y() - p3.x() * p2.y() +
p3.x() * p1.y() - p1.x() * p3.y() ));
return fabs(0.5 * ( p1.getLongitudeDeg() * p2.getLatitudeDeg() - p2.getLongitudeDeg() * p1.getLatitudeDeg() +
p2.getLongitudeDeg() * p3.getLatitudeDeg() - p3.getLongitudeDeg() * p2.getLatitudeDeg() +
p3.getLongitudeDeg() * p1.getLatitudeDeg() - p1.getLongitudeDeg() * p3.getLatitudeDeg() ));
}
@ -53,7 +53,7 @@ inline double triangle_area( const Point3D& p1, const Point3D& p2, const Point3D
// or splitting edges and without regard for holes. Returns a polygon
// with one contour per tesselated triangle.
TGPolygon polygon_tesselate_alt_with_extra_cgal( TGPolygon &p,
const point_list &extra_nodes, bool verbose );
const std::vector<SGGeod>& extra_nodes, bool verbose );
TGPolygon polygon_tesselate_alt_cgal( TGPolygon &p, bool verbose );
@ -93,6 +93,13 @@ bool find_intermediate_node( const Point3D& start, const Point3D& end,
const double errEpsilon = SG_EPSILON*4
);
// TEMP
bool find_intermediate_node( const Point3D& start, const Point3D& end,
const std::vector<SGGeod>& nodes, Point3D *result,
const double bbEpsilon = SG_EPSILON*10,
const double errEpsilon = SG_EPSILON*4
);
// remove any degenerate contours
TGPolygon remove_bad_contours( const TGPolygon &poly );

View file

@ -6,22 +6,22 @@
// compare node's positions (x, then y)
int compare_position(const TGNode& n1, const TGNode& n2)
{
Point3D pos1 = n1.GetPosition();
Point3D pos2 = n2.GetPosition();
SGGeod pos1 = n1.GetPosition();
SGGeod pos2 = n2.GetPosition();
if ( pos1.x() == pos2.x() ) {
return ( pos1.y() < pos2.y() );
if ( pos1.getLongitudeDeg() == pos2.getLongitudeDeg() ) {
return ( pos1.getLatitudeDeg() < pos2.getLatitudeDeg() );
} else {
return ( pos1.x() < pos2.x() );
return ( pos1.getLongitudeDeg() < pos2.getLongitudeDeg() );
}
}
int fuzzy_compare_xposition(const TGNode& n1, const TGNode& n2)
{
Point3D pos1 = n1.GetPosition();
Point3D pos2 = n2.GetPosition();
SGGeod pos1 = n1.GetPosition();
SGGeod pos2 = n2.GetPosition();
if ( fabs(pos1.x() - pos2.x()) < FG_PROXIMITY_EPSILON ) {
if ( fabs(pos1.getLongitudeDeg() - pos2.getLongitudeDeg()) < FG_PROXIMITY_EPSILON ) {
/* if x coords are within vacinity, then pos1 < pos2 */
return 1;
} else {
@ -36,7 +36,7 @@ void TGNodes::SortNodes( void )
}
// Find the index of the specified point (compair to the same
// tolerance as unique_add(). Returns -1 if not found.
int TGNodes::sorted_find( const Point3D& p ) const {
int TGNodes::sorted_find( const SGGeod& p ) const {
TGNode node( p );
const_node_list_iterator lb, ub;
@ -56,9 +56,9 @@ int TGNodes::sorted_find( const Point3D& p ) const {
return -1;
}
int TGNodes::linear_find( const Point3D& p ) const {
int TGNodes::linear_find( const SGGeod& p ) const {
const_node_list_iterator current, last;
Point3D pos;
SGGeod pos;
int counter = 0;
// see if point already exists
@ -76,44 +76,7 @@ int TGNodes::linear_find( const Point3D& p ) const {
return -1;
}
#if 0
void TGNodes::sorted_unique_add( const Point3D& p ) {
# if 0
TGNode node( p );
node.SetFixedPosition( false );
node_list_iterator idx = std::lower_bound( tg_node_list.begin(), tg_node_list.end(), node, compare_position );
tg_node_list.insert( idx, node );
#else
TGNode node( p );
node.SetFixedPosition( false );
node_list_iterator lb, ub, idx;
// first, find the range to search
ub=lower_bound( tg_node_list.begin(), tg_node_list.end(), node, fuzzy_compare_xposition );
lb=upper_bound( tg_node_list.begin(), tg_node_list.end(), node, fuzzy_compare_xposition );
// then do a normal linear search in the range
if ( lb != tg_node_list.end() ) {
for ( ; lb != ub; ++lb ) {
if ( close_enough_2d(p, lb->GetPosition()) ) {
// return std::distance( tg_node_list.begin(), lb );
return;
}
}
}
// we didn't find an existing node - insert new one in correct order
idx = std::lower_bound( lb, ub, node, compare_position );
tg_node_list.insert( idx, node );
// return std::distance( tg_node_list.begin(), idx );
#endif
}
#endif
void TGNodes::linear_unique_add( const Point3D& p ) {
void TGNodes::linear_unique_add( const SGGeod& p ) {
node_list_iterator current, last;
// see if point already exists
@ -134,56 +97,7 @@ void TGNodes::linear_unique_add( const Point3D& p ) {
tg_node_list.push_back( node );
}
#if 0
void TGNodes::sorted_unique_add_fixed_elevation( const Point3D& p ) {
# if 0
TGNode node( p );
node.SetFixedPosition(true);
node_list_iterator idx = std::lower_bound( tg_node_list.begin(), tg_node_list.end(), node, compare_position );
if ( idx != tg_node_list.end() ) {
if ( close_enough_2d( p, idx->GetPosition() ) ) {
SG_LOG(SG_GENERAL, SG_ALERT, "AddFixedLocation: node " << p << " exists at " << std::distance(tg_node_list.begin(), idx) );
idx->SetPosition( p );
idx->SetFixedPosition( true );
} else {
tg_node_list.insert( idx, node );
}
}
#else
TGNode node( p );
node.SetFixedPosition(true);
node_list_iterator lb, ub, idx;
// first, find the range to search
ub=lower_bound( tg_node_list.begin(), tg_node_list.end(), node, fuzzy_compare_xposition );
lb=upper_bound( tg_node_list.begin(), tg_node_list.end(), node, fuzzy_compare_xposition );
// then do a normal linear search in the range
if ( lb != tg_node_list.end() ) {
for ( ; lb != ub; ++lb ) {
if ( close_enough_2d(p, lb->GetPosition()) ) {
lb->SetPosition( p );
lb->SetFixedPosition( true );
// return std::distance( tg_node_list.begin(), lb );
return;
}
}
}
// we didn't find an existing node - insert new one in correct order
idx = std::lower_bound( lb, ub, node, compare_position );
tg_node_list.insert( idx, node );
// return std::distance( tg_node_list.begin(), idx );
#endif
}
#endif
void TGNodes::linear_unique_add_fixed_elevation( const Point3D& p ) {
void TGNodes::linear_unique_add_fixed_elevation( const SGGeod& p ) {
node_list_iterator current, last;
// see if point already exists
@ -207,51 +121,60 @@ void TGNodes::linear_unique_add_fixed_elevation( const Point3D& p ) {
// add to list
tg_node_list.push_back( node );
}
point_list TGNodes::get_geod_nodes( void ) const {
point_list points;
void TGNodes::get_geod_nodes( std::vector<SGGeod>& points ) const {
const_node_list_iterator current, last;
// see if point already exists
current = tg_node_list.begin();
last = tg_node_list.end();
points.clear();
for ( ; current != last; ++current ) {
points.push_back( (*current).GetPosition() );
}
return points;
}
// TODO: if the list is sorted, we should be able to get the range from x=min to x=max,
// then within that range, add each point where y is within ymin, max
// still linear search, but should be less points
point_list TGNodes::get_geod_inside( Point3D min, Point3D max ) const {
point_list points;
const double fgPoint3_Epsilon = 0.000001;
static bool IsWithin( const SGGeod pt, double xmin, double xmax, double ymin, double ymax )
{
return ( (xmin <= pt.getLongitudeDeg()) && (ymin <= pt.getLatitudeDeg()) &&
(xmax >= pt.getLongitudeDeg()) && (ymax >= pt.getLatitudeDeg()) );
}
static bool IsAlmostWithin( const SGGeod pt, const SGGeod& min, const SGGeod& max )
{
// make sure we take epsilon into account
return ( IsWithin(pt,
min.getLongitudeDeg() - fgPoint3_Epsilon,
max.getLongitudeDeg() + fgPoint3_Epsilon,
min.getLatitudeDeg() - fgPoint3_Epsilon,
max.getLatitudeDeg() + fgPoint3_Epsilon ) );
}
void TGNodes::get_geod_inside( const SGGeod& min, const SGGeod& max, std::vector<SGGeod>& points ) const {
const_node_list_iterator current, last;
// see if point already exists
current = tg_node_list.begin();
last = tg_node_list.end();
points.clear();
for ( ; current != last; ++current ) {
Point3D pt = (*current).GetPosition();
SGGeod pt = (*current).GetPosition();
if ( pt.IsAlmostWithin( min, max ) ) {
if ( IsAlmostWithin( pt, min, max ) ) {
points.push_back( pt );
} else {
if ( (pt < max) && (pt > min) ) {
SG_LOG(SG_GENERAL, SG_ALERT, "pt " << pt << " fails IsAlmostWithin, but sholdn't have: min " << min << " max " << max );
}
}
}
return points;
}
void TGNodes::get_geod_edge( SGBucket b, point_list& north, point_list& south, point_list& east, point_list& west ) const {
void TGNodes::get_geod_edge( const SGBucket& b, std::vector<SGGeod>& north, std::vector<SGGeod>& south, std::vector<SGGeod>& east, std::vector<SGGeod>& west ) const {
const_node_list_iterator current, last;
double north_compare = b.get_center_lat() + 0.5 * b.get_height();
double south_compare = b.get_center_lat() - 0.5 * b.get_height();
@ -262,91 +185,60 @@ void TGNodes::get_geod_edge( SGBucket b, point_list& north, point_list& south, p
current = tg_node_list.begin();
last = tg_node_list.end();
north.clear();
south.clear();
east.clear();
west.clear();
for ( ; current != last; ++current ) {
Point3D pt = (*current).GetPosition();
SGGeod pt = (*current).GetPosition();
// may save the same point twice - so we get all the corners
if ( fabs(pt.y() - north_compare) < SG_EPSILON) {
if ( fabs(pt.getLatitudeDeg() - north_compare) < SG_EPSILON) {
north.push_back( pt );
}
if ( fabs(pt.y() - south_compare) < SG_EPSILON) {
if ( fabs(pt.getLatitudeDeg() - south_compare) < SG_EPSILON) {
south.push_back( pt );
}
if ( fabs(pt.x() - east_compare) < SG_EPSILON) {
if ( fabs(pt.getLongitudeDeg() - east_compare) < SG_EPSILON) {
east.push_back( pt );
}
if ( fabs(pt.x() - west_compare) < SG_EPSILON) {
if ( fabs(pt.getLongitudeDeg() - west_compare) < SG_EPSILON) {
west.push_back( pt );
}
}
}
std::vector< SGVec3d > TGNodes::get_wgs84_nodes_as_SGVec3d( void ) const {
void TGNodes::get_wgs84_nodes( std::vector<SGVec3d>& points ) const {
const_node_list_iterator current, last;
std::vector< SGVec3d > points;
current = tg_node_list.begin();
last = tg_node_list.end();
points.clear();
for ( ; current != last; ++current ) {
points.push_back( (*current).GetWgs84AsSGVec3d() );
points.push_back( (*current).GetWgs84() );
}
return points;
}
point_list TGNodes::get_wgs84_nodes_as_Point3d( void ) const {
const_node_list_iterator current, last;
point_list points;
current = tg_node_list.begin();
last = tg_node_list.end();
for ( ; current != last; ++current ) {
points.push_back( (*current).GetWgs84AsPoint3D() );
}
return points;
}
node_list TGNodes::get_fixed_elevation_nodes( void ) const {
node_list fixed_elev;
void TGNodes::get_normals( std::vector<SGVec3f>& normals ) const {
const_node_list_iterator current, last;
// see if point already exists
current = tg_node_list.begin();
last = tg_node_list.end();
normals.clear();
for ( ; current != last; ++current ) {
if ( (*current).GetFixedPosition() ) {
fixed_elev.push_back( (*current) );
}
normals.push_back( (*current).GetNormal() );
}
return fixed_elev;
}
point_list TGNodes::get_normals( void ) const {
point_list points;
const_node_list_iterator current, last;
// see if point already exists
current = tg_node_list.begin();
last = tg_node_list.end();
for ( ; current != last; ++current ) {
points.push_back( (*current).GetNormal() );
}
return points;
}
void TGNodes::Dump( void ) {
for (unsigned int i=0; i<tg_node_list.size(); i++) {
TGNode node = tg_node_list[ i ];
std::string fixed;
if ( node.GetFixedPosition() ) {
fixed = " z is fixed elevation ";
} else {
@ -363,43 +255,15 @@ void TGNodes::Dump( void ) {
}
}
// input from stream
std::istream& operator >> ( std::istream& in, TGNode& n )
{
int i, nCount;
// Load a tgnode
in >> n.position;
n.CalcWgs84();
in >> n.normal;
in >> n.fixed_position;
in >> n.fixed_normal;
in >> nCount;
for (i=0; i<nCount; i++) {
TGFaceLookup face;
in >> face.area;
in >> face.shape;
in >> face.seg;
in >> face.tri;
n.faces.push_back( face );
}
return in;
}
void TGNode::LoadFromGzFile(gzFile& fp)
{
int i, nCount;
// Load a tgnode
sgReadPoint3D( fp, position);
sgReadGeod( fp, position);
CalcWgs84();
sgReadPoint3D( fp, normal );
sgReadVec3( fp, normal );
sgReadInt( fp, (int*)&fixed_position );
sgReadInt( fp, (int*)&fixed_normal );
@ -442,8 +306,8 @@ void TGNode::SaveToGzFile(gzFile& fp)
int i, nCount;
// Save a tgnode
sgWritePoint3D( fp, position );
sgWritePoint3D( fp, normal );
sgWriteGeod( fp, position );
sgWriteVec3( fp, normal );
sgWriteInt( fp, (int)fixed_position );
sgWriteInt( fp, (int)fixed_normal );
@ -457,26 +321,6 @@ void TGNode::SaveToGzFile(gzFile& fp)
}
}
// input from stream
std::istream& operator >> ( std::istream& in, TGNodes& ns )
{
int i, nCount;
// Load sorted flag
in >> ns.sorted;
// Load all tgnodes
in >> nCount;
for (i=0; i<nCount; i++) {
TGNode node;
in >> node;
ns.tg_node_list.push_back( node );
}
return in;
}
void TGNodes::LoadFromGzFile(gzFile& fp)
{
int i, nCount;
@ -526,22 +370,4 @@ void TGNodes::SaveToGzFile(gzFile& fp)
for (i=0; i<nCount; i++) {
tg_node_list[i].SaveToGzFile( fp );
}
}
#if 0
bool TGNodes::LookupFixedElevation( Point3D p, double* z )
{
int index = find( p );
bool found = false;
if (index >= 0) {
TGNode node = tg_node_list[index];
if ( node.GetFixedPosition() ) {
*z = tg_node_list[index].GetPosition().z();
found = true;
}
}
return found;
}
#endif
}

View file

@ -5,18 +5,16 @@
# include <config.h>
#endif
#ifndef __cplusplus
#ifndef __cplusplus
# error This library requires C++
#endif
#endif
#include <cstdlib>
#include <simgear/compiler.h>
#include <simgear/bucket/newbucket.hxx>
#include <simgear/math/sg_types.hxx>
//#include <simgear/math/sg_types.hxx>
#include <simgear/io/lowlevel.hxx>
#include <Geometry/point3d.hxx>
#define FG_PROXIMITY_EPSILON 0.000001
#define FG_COURSE_EPSILON 0.0001
@ -36,12 +34,11 @@ public:
TGNode() {
// constructor for serialization only
}
TGNode( Point3D p ) {
TGNode( SGGeod p ) {
position = p;
normal = Point3D();
CalcWgs84();
fixed_position = false; // no matter what - don't move x, y, or z (likely a hole around an airport generated ny genapts)
fixed_normal = false; // no matter what - don't modify the normal - likely on a normal generated on a shared edge
@ -57,8 +54,7 @@ public:
inline void CalcWgs84()
{
SGGeod geod = SGGeod::fromDegM( position.x(), position.y(), position.z() );
wgs84 = SGVec3d::fromGeod(geod);
wgs84 = SGVec3d::fromGeod(position);
}
inline void AddFace( unsigned int area, unsigned int shape, unsigned int segment, unsigned int tri )
@ -76,10 +72,9 @@ public:
inline bool GetFixedPosition( void ) const { return fixed_position; }
inline void SetFixedNormal( bool fix ) { fixed_normal = fix; }
inline bool GetFixedNormal( void ) const { return fixed_normal; }
inline SGVec3d GetWgs84AsSGVec3d( void ) const { return wgs84; }
inline Point3D GetWgs84AsPoint3D( void ) const { return Point3D::fromSGVec3( wgs84 ); }
inline SGVec3d GetWgs84( void ) const { return wgs84; }
inline void SetPosition( const Point3D& p )
inline void SetPosition( const SGGeod& p )
{
if (!fixed_position) {
position = p;
@ -90,24 +85,23 @@ public:
inline void SetElevation( double z )
{
if (!fixed_position) {
position.setelev( z );
position.setElevationM( z );
CalcWgs84();
}
}
inline Point3D GetPosition( void ) const { return position; }
inline void SetNormal( const Point3D& n ) { normal = n; }
inline Point3D GetNormal( void ) const { return normal; }
inline SGGeod GetPosition( void ) const { return position; }
inline void SetNormal( const SGVec3f& n ) { normal = n; }
inline SGVec3f GetNormal( void ) const { return normal; }
void SaveToGzFile( gzFile& fp );
void LoadFromGzFile( gzFile& fp );
// Friends for serialization
friend std::istream& operator>> ( std::istream&, TGNode& );
friend std::ostream& operator<< ( std::ostream&, const TGNode& );
private:
Point3D position;
Point3D normal;
SGGeod position;
SGVec3f normal;
SGVec3d wgs84;
bool fixed_position;
@ -119,9 +113,7 @@ typedef std::vector < TGNode > node_list;
typedef node_list::iterator node_list_iterator;
typedef node_list::const_iterator const_node_list_iterator;
/* This class handles ALL of the nodes in a tile : 3d nodes in elevation data, 2d nodes generated from landclass, etc) */
class TGNodes {
public:
@ -139,7 +131,7 @@ public:
// Add a point to the point list if it doesn't already exist.
// Returns the index (starting at zero) of the point in the list.
void unique_add( const Point3D& p ) {
void unique_add( const SGGeod& p ) {
if ( !sorted ) {
linear_unique_add( p );
} else {
@ -151,7 +143,7 @@ public:
// Add a point to the point list if it doesn't already exist
// (checking all three dimensions.) Returns the index (starting
// at zero) of the point in the list.
void unique_add_fixed_elevation( const Point3D& p ) {
void unique_add_fixed_elevation( const SGGeod& p ) {
if ( !sorted ) {
linear_unique_add_fixed_elevation( p );
} else {
@ -162,7 +154,7 @@ public:
// Find the index of the specified point (compair to the same
// tolerance as unique_add(). Returns -1 if not found.
int find( const Point3D& p ) const {
int find( const SGGeod& p ) const {
if ( sorted ) {
return sorted_find( p );
} else {
@ -170,33 +162,30 @@ public:
}
}
node_list get_fixed_elevation_nodes( void ) const;
void SortNodes( void );
void SetElevation( int idx, double z ) { tg_node_list[idx].SetElevation( z ); }
Point3D GetNormal( int idx ) const { return tg_node_list[idx].GetNormal(); }
void SetNormal( int idx, Point3D n ) { tg_node_list[idx].SetNormal( n ); }
SGVec3f GetNormal( int idx ) const { return tg_node_list[idx].GetNormal(); }
void SetNormal( int idx, SGVec3f n ) { tg_node_list[idx].SetNormal( n ); }
// return the master node list
inline node_list& get_node_list() { return tg_node_list; }
inline const node_list& get_node_list() const { return tg_node_list; }
// return a point list of geodetic nodes
point_list get_geod_nodes() const;
void get_geod_nodes( std::vector<SGGeod>& points ) const;
// Find all the nodes within a bounding box
point_list get_geod_inside( Point3D min, Point3D max ) const;
void get_geod_inside( const SGGeod& min, const SGGeod& max, std::vector<SGGeod>& points ) const;
// Find a;; the nodes on the tile edges
void get_geod_edge( SGBucket b, point_list& north, point_list& south, point_list& east, point_list& west ) const;
void get_geod_edge( const SGBucket& b, std::vector<SGGeod>& north, std::vector<SGGeod>& south, std::vector<SGGeod>& east, std::vector<SGGeod>& west ) const;
// return a point list of wgs84 nodes
std::vector< SGVec3d > get_wgs84_nodes_as_SGVec3d() const;
point_list get_wgs84_nodes_as_Point3d() const;
void get_wgs84_nodes( std::vector<SGVec3d>& points ) const;
// return a point list of normals
point_list get_normals() const;
void get_normals( std::vector<SGVec3f>& normals ) const;
// return the ith point
inline TGNode get_node( int i ) const { return tg_node_list[i]; }
@ -214,67 +203,64 @@ public:
void LoadFromGzFile( gzFile& fp );
// Friends for serialization
friend std::istream& operator>> ( std::istream&, TGNodes& );
friend std::ostream& operator<< ( std::ostream&, const TGNodes& );
private:
void linear_unique_add( const Point3D& p );
void linear_unique_add_fixed_elevation( const Point3D& p );
void linear_unique_add( const SGGeod& p );
void linear_unique_add_fixed_elevation( const SGGeod& p );
int sorted_find( const Point3D& p ) const;
int linear_find( const Point3D& p ) const;
int sorted_find( const SGGeod& p ) const;
int linear_find( const SGGeod& p ) const;
node_list tg_node_list;
bool sorted;
// return true of the two points are "close enough" as defined by
// FG_PROXIMITY_EPSILON
bool close_enough_2d( const Point3D& p1, const Point3D& p2 ) const;
bool close_enough_2d( const SGGeod& p1, const SGGeod& p2 ) const;
// return true of the two points are "close enough" as defined by
// FG_PROXIMITY_EPSILON
bool close_enough_3d( const Point3D& p1, const Point3D& p2 ) const;
bool close_enough_3d( const SGGeod& p1, const SGGeod& p2 ) const;
// return true of the two points are "close enough" as defined by
// FG_COURSE_EPSILON
bool course_close_enough( const Point3D& p1, const Point3D& p2 );
bool course_close_enough( const SGGeod& p1, const SGGeod& p2 );
};
// return true of the two points are "close enough" as defined by
// FG_PROXIMITY_EPSILON checking just x and y dimensions
inline bool TGNodes::close_enough_2d( const Point3D& p1, const Point3D& p2 )
inline bool TGNodes::close_enough_2d( const SGGeod& p1, const SGGeod& p2 )
const
{
if ( ( fabs(p1.x() - p2.x()) < FG_PROXIMITY_EPSILON ) &&
( fabs(p1.y() - p2.y()) < FG_PROXIMITY_EPSILON ) ) {
if ( ( fabs(p1.getLongitudeDeg() - p2.getLongitudeDeg()) < FG_PROXIMITY_EPSILON ) &&
( fabs(p1.getLatitudeDeg() - p2.getLatitudeDeg()) < FG_PROXIMITY_EPSILON ) ) {
return true;
} else {
return false;
}
}
// return true of the two points are "close enough" as defined by
// FG_PROXIMITY_EPSILON check all three dimensions
inline bool TGNodes::close_enough_3d( const Point3D& p1, const Point3D& p2 )
inline bool TGNodes::close_enough_3d( const SGGeod& p1, const SGGeod& p2 )
const
{
if ( ( fabs(p1.x() - p2.x()) < FG_PROXIMITY_EPSILON ) &&
( fabs(p1.y() - p2.y()) < FG_PROXIMITY_EPSILON ) &&
( fabs(p1.z() - p2.z()) < FG_PROXIMITY_EPSILON ) ) {
if ( ( fabs(p1.getLongitudeDeg() - p2.getLongitudeDeg()) < FG_PROXIMITY_EPSILON ) &&
( fabs(p1.getLatitudeDeg() - p2.getLatitudeDeg()) < FG_PROXIMITY_EPSILON ) &&
( fabs(p1.getElevationM() - p2.getElevationM()) < FG_PROXIMITY_EPSILON ) ) {
return true;
} else {
return false;
}
}
// return true of the two points are "close enough" as defined by
// FG_COURSE_EPSILON
inline bool TGNodes::course_close_enough( const Point3D& p1, const Point3D& p2 )
inline bool TGNodes::course_close_enough( const SGGeod& p1, const SGGeod& p2 )
{
if ( ( fabs(p1.x() - p2.x()) < FG_COURSE_EPSILON ) &&
( fabs(p1.y() - p2.y()) < FG_COURSE_EPSILON ) ) {
if ( ( fabs(p1.getLongitudeDeg() - p2.getLongitudeDeg()) < FG_COURSE_EPSILON ) &&
( fabs(p1.getLatitudeDeg() - p2.getLatitudeDeg()) < FG_COURSE_EPSILON ) ) {
return true;
} else {
return false;