tgconstruct edge matching with existing terrain
This commit is contained in:
parent
c7c8c0be82
commit
47db776404
11 changed files with 436 additions and 33 deletions
|
@ -47,6 +47,7 @@ static void usage( const string name ) {
|
|||
SG_LOG(SG_GENERAL, SG_ALERT, "[ --output-dir=<directory>");
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, " --work-dir=<directory>");
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, " --share-dir=<directory>");
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, " --match-dir=<directory>");
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, " --cover=<path to land-cover raster>");
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, " --tile-id=<id>");
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, " --min-lon=<degrees>");
|
||||
|
@ -63,10 +64,23 @@ static void usage( const string name ) {
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
void RemoveDuplicateBuckets( std::vector<SGBucket>& keep, std::vector<SGBucket>& remove )
|
||||
{
|
||||
for ( unsigned int i=0; i<remove.size(); i++) {
|
||||
for ( unsigned int j=0; j<keep.size(); j++ ) {
|
||||
if ( remove[i] == keep[j] ) {
|
||||
keep.erase( keep.begin()+j );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
string output_dir = ".";
|
||||
string work_dir = ".";
|
||||
string share_dir = "";
|
||||
string match_dir = "";
|
||||
string cover = "";
|
||||
string priorities_file = DEFAULT_PRIORITIES_FILE;
|
||||
string usgs_map_file = DEFAULT_USGS_MAPFILE;
|
||||
|
@ -97,6 +111,8 @@ int main(int argc, char **argv) {
|
|||
work_dir = arg.substr(11);
|
||||
} else if (arg.find("--share-dir=") == 0) {
|
||||
share_dir = arg.substr(12);
|
||||
} else if (arg.find("--match-dir=") == 0) {
|
||||
match_dir = arg.substr(12);
|
||||
} else if (arg.find("--tile-id=") == 0) {
|
||||
tile_id = atol(arg.substr(10).c_str());
|
||||
} else if ( arg.find("--min-lon=") == 0 ) {
|
||||
|
@ -142,6 +158,8 @@ int main(int argc, char **argv) {
|
|||
SG_LOG(SG_GENERAL, SG_ALERT, "Output directory is " << output_dir);
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "Working directory is " << work_dir);
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "Shared directory is " << share_dir);
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "Match directory is " << match_dir);
|
||||
|
||||
if ( tile_id > 0 ) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "Tile id is " << tile_id);
|
||||
} else {
|
||||
|
@ -167,10 +185,13 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
// tile work queue
|
||||
std::vector<SGBucket> matchList;
|
||||
std::vector<SGBucket> bucketList;
|
||||
SGLockedQueue<SGBucket> wq;
|
||||
SGMutex filelock;
|
||||
|
||||
// First generate the workqueue of buckets to construct
|
||||
// First, check if we want to match existing scenery -
|
||||
// if we do, generate a list of buckets outside of the bounding box
|
||||
if (tile_id == -1) {
|
||||
// build all the tiles in an area
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "Building tile(s) within given bounding box");
|
||||
|
@ -184,14 +205,37 @@ int main(int argc, char **argv) {
|
|||
SG_LOG(SG_GENERAL, SG_ALERT, " construction area spans tile boundaries");
|
||||
sgGetBuckets( min, max, bucketList );
|
||||
}
|
||||
if ( match_dir != "" ) {
|
||||
b_min = b_min.sibling(-1,-1);
|
||||
b_max = b_max.sibling(1,1);
|
||||
|
||||
sgGetBuckets( b_min.get_center(), b_max.get_center(), matchList );
|
||||
}
|
||||
} else {
|
||||
// construct the specified tile
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "Building tile " << tile_id);
|
||||
bucketList.push_back( SGBucket( tile_id ) );
|
||||
if ( match_dir != "" ) {
|
||||
SGBucket b_min( SGBucket(tile_id).sibling(-1,-1) );
|
||||
SGBucket b_max( SGBucket(tile_id).sibling( 1, 1) );
|
||||
sgGetBuckets( b_min.get_center(), b_max.get_center(), matchList );
|
||||
}
|
||||
}
|
||||
|
||||
if ( match_dir != "" ) {
|
||||
RemoveDuplicateBuckets( matchList, bucketList );
|
||||
|
||||
// generate the immuatble shared files - when tile matching, we must not
|
||||
// modify shared edges from an immutable file - new tile will collapse
|
||||
// triangles as appropriate.
|
||||
TGConstruct* construct = new TGConstruct( areas, 1, wq, &filelock );
|
||||
//construct->set_cover( cover );
|
||||
construct->set_paths( work_dir, share_dir, match_dir, output_dir, load_dirs );
|
||||
construct->CreateMatchedEdgeFiles( matchList );
|
||||
delete construct;
|
||||
}
|
||||
|
||||
std::vector<TGConstruct *> constructs;
|
||||
SGMutex filelock;
|
||||
|
||||
/* fill the workqueue */
|
||||
for (unsigned int i=0; i<bucketList.size(); i++) {
|
||||
|
@ -202,7 +246,7 @@ int main(int argc, char **argv) {
|
|||
for (int i=0; i<num_threads; i++) {
|
||||
TGConstruct* construct = new TGConstruct( areas, 1, wq, &filelock );
|
||||
//construct->set_cover( cover );
|
||||
construct->set_paths( work_dir, share_dir, output_dir, load_dirs );
|
||||
construct->set_paths( work_dir, share_dir, match_dir, output_dir, load_dirs );
|
||||
construct->set_options( ignoreLandmass, nudge );
|
||||
construct->set_debug( debug_dir, debug_area_defs, debug_shape_defs );
|
||||
constructs.push_back( construct );
|
||||
|
@ -235,7 +279,7 @@ int main(int argc, char **argv) {
|
|||
for (int i=0; i<num_threads; i++) {
|
||||
TGConstruct* construct = new TGConstruct( areas, 2, wq, &filelock );
|
||||
//construct->set_cover( cover );
|
||||
construct->set_paths( work_dir, share_dir, output_dir, load_dirs );
|
||||
construct->set_paths( work_dir, share_dir, match_dir, output_dir, load_dirs );
|
||||
construct->set_options( ignoreLandmass, nudge );
|
||||
construct->set_debug( debug_dir, debug_area_defs, debug_shape_defs );
|
||||
constructs.push_back( construct );
|
||||
|
@ -267,7 +311,7 @@ int main(int argc, char **argv) {
|
|||
for (int i=0; i<num_threads; i++) {
|
||||
TGConstruct* construct = new TGConstruct( areas, 3, wq, &filelock );
|
||||
//construct->set_cover( cover );
|
||||
construct->set_paths( work_dir, share_dir, output_dir, load_dirs );
|
||||
construct->set_paths( work_dir, share_dir, match_dir, output_dir, load_dirs );
|
||||
construct->set_options( ignoreLandmass, nudge );
|
||||
construct->set_debug( debug_dir, debug_area_defs, debug_shape_defs );
|
||||
constructs.push_back( construct );
|
||||
|
|
|
@ -55,9 +55,12 @@ TGConstruct::~TGConstruct() {
|
|||
}
|
||||
|
||||
// TGConstruct: Setup
|
||||
void TGConstruct::set_paths( const std::string work, const std::string share, const std::string output, const std::vector<std::string> load ) {
|
||||
void TGConstruct::set_paths( const std::string work, const std::string share,
|
||||
const std::string match, const std::string output,
|
||||
const std::vector<std::string> load ) {
|
||||
work_base = work;
|
||||
share_base = share;
|
||||
match_base = match;
|
||||
output_base = output;
|
||||
load_dirs = load;
|
||||
}
|
||||
|
@ -93,6 +96,12 @@ void TGConstruct::run()
|
|||
strcpy( ds_name, "" );
|
||||
}
|
||||
|
||||
if ( stage == 1 ) {
|
||||
// Matched edge data is generated from a previous scenery build - do this before we
|
||||
// start the current tile - it can mark edges as immutable
|
||||
LoadMatchedEdgeFiles();
|
||||
}
|
||||
|
||||
if ( stage > 1 ) {
|
||||
LoadFromIntermediateFiles( stage-1 );
|
||||
LoadSharedEdgeData( stage-1 );
|
||||
|
|
|
@ -83,7 +83,8 @@ public:
|
|||
#endif
|
||||
|
||||
// paths
|
||||
void set_paths( const std::string work, const std::string share, const std::string output, const std::vector<std::string> load_dirs );
|
||||
void set_paths( const std::string work, const std::string share, const std::string match,
|
||||
const std::string output, const std::vector<std::string> load_dirs );
|
||||
void set_options( bool ignore_lm, double n );
|
||||
|
||||
// TODO : REMOVE
|
||||
|
@ -98,6 +99,8 @@ public:
|
|||
// Debug
|
||||
void set_debug( std::string path, std::vector<std::string> area_defs, std::vector<std::string> shape_defs );
|
||||
|
||||
void CreateMatchedEdgeFiles( std::vector<SGBucket>& bucketList );
|
||||
|
||||
private:
|
||||
virtual void run();
|
||||
|
||||
|
@ -107,6 +110,10 @@ private:
|
|||
// Load Data
|
||||
void LoadElevationArray( bool add_nodes );
|
||||
int LoadLandclassPolys( void );
|
||||
bool CheckMatchingNode( SGGeod& node, bool road, bool fixed );
|
||||
|
||||
SGGeod GetNearestNodeLatitude( const SGGeod& node, const std::vector<SGGeod>& selection );
|
||||
SGGeod GetNearestNodeLongitude( const SGGeod& node, const std::vector<SGGeod>& selection );
|
||||
|
||||
// Clip Data
|
||||
bool ClipLandclassPolys( void );
|
||||
|
@ -118,8 +125,11 @@ private:
|
|||
// Shared edge Matching
|
||||
void SaveSharedEdgeData( int stage );
|
||||
void LoadSharedEdgeData( int stage );
|
||||
void LoadMatchedEdgeFiles();
|
||||
|
||||
void LoadNeighboorEdgeDataStage1( SGBucket& b, std::vector<SGGeod>& north, std::vector<SGGeod>& south, std::vector<SGGeod>& east, std::vector<SGGeod>& west );
|
||||
void LoadNeighboorMatchDataStage1( SGBucket& b, std::vector<SGGeod>& north, std::vector<SGGeod>& south, std::vector<SGGeod>& east, std::vector<SGGeod>& west );
|
||||
|
||||
void ReadNeighborFaces( gzFile& fp );
|
||||
void WriteNeighborFaces( gzFile& fp, const SGGeod& pt ) const;
|
||||
TGNeighborFaces* AddNeighborFaces( const SGGeod& node );
|
||||
|
@ -164,14 +174,16 @@ private:
|
|||
SGLockedQueue<SGBucket>& workQueue;
|
||||
unsigned int total_tiles;
|
||||
unsigned int stage;
|
||||
std::vector<SGGeod> nm_north, nm_south, nm_east, nm_west;
|
||||
|
||||
// path to land-cover file (if any)
|
||||
std::string cover;
|
||||
|
||||
// paths
|
||||
std::string work_base;
|
||||
std::string output_base;
|
||||
std::string share_base;
|
||||
std::string match_base;
|
||||
std::string output_base;
|
||||
|
||||
std::vector<std::string> load_dirs;
|
||||
|
||||
|
|
|
@ -278,6 +278,7 @@ bool TGConstruct::ClipLandclassPolys( void ) {
|
|||
|
||||
// Now make sure any newly added intersection nodes are added to the tgnodes
|
||||
for (unsigned int area = 0; area < area_defs.size(); area++) {
|
||||
bool isRoad = area_defs.is_road_area( area );
|
||||
for (unsigned int p = 0; p < polys_clipped.area_size(area); p++ ) {
|
||||
tgPolygon& poly = polys_clipped.get_poly( area, p );
|
||||
|
||||
|
@ -286,8 +287,12 @@ bool TGConstruct::ClipLandclassPolys( void ) {
|
|||
for (unsigned int con=0; con < poly.Contours(); con++) {
|
||||
for (unsigned int n = 0; n < poly.ContourSize( con ); n++) {
|
||||
// ensure we have all nodes...
|
||||
TGNode const& node = poly.GetNode( con, n );
|
||||
nodes.unique_add( node );
|
||||
SGGeod node = poly.GetNode( con, n );
|
||||
if ( CheckMatchingNode( node, isRoad, false ) ) {
|
||||
poly.SetNode( con, n, node );
|
||||
} else {
|
||||
poly.DelNode( con, n );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,10 @@ void TGConstruct::LoadElevationArray( bool add_nodes ) {
|
|||
|
||||
std::vector<SGGeod> const& fit_list = array.get_fitted_list();
|
||||
for (unsigned int i=0; i<fit_list.size(); i++) {
|
||||
nodes.unique_add( fit_list[i] );
|
||||
SGGeod node = fit_list[i];
|
||||
if ( CheckMatchingNode( node, false, false ) ) {
|
||||
nodes.unique_add( node );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,23 +84,22 @@ int TGConstruct::LoadLandclassPolys( void ) {
|
|||
poly.LoadFromGzFile( fp );
|
||||
area = area_defs.get_area_priority( poly.GetFlag() );
|
||||
material = area_defs.get_area_name( area );
|
||||
bool isRoad = area_defs.is_road_area( area );
|
||||
|
||||
poly.SetMaterial( material );
|
||||
poly.SetId( cur_poly_id++ );
|
||||
|
||||
if ( poly.Contours() ) {
|
||||
polys_in.add_poly( area, poly );
|
||||
total_polys_read++;
|
||||
|
||||
// add the nodes
|
||||
for (unsigned int j=0; j<poly.Contours(); j++) {
|
||||
for (unsigned int k=0; k<poly.ContourSize(j); k++) {
|
||||
SGGeod const& node = poly.GetNode( j, k );
|
||||
for (int k=poly.ContourSize(j)-1; k>= 0; k--) {
|
||||
SGGeod node = poly.GetNode( j, k );
|
||||
bool isFixed = poly.GetPreserve3D();
|
||||
|
||||
if ( poly.GetPreserve3D() ) {
|
||||
nodes.unique_add_fixed_elevation( node );
|
||||
if ( CheckMatchingNode( node, isRoad, isFixed ) ) {
|
||||
poly.SetNode( j, k, node );
|
||||
} else {
|
||||
nodes.unique_add( node );
|
||||
poly.DelNode( j, k );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -111,6 +110,13 @@ int TGConstruct::LoadLandclassPolys( void ) {
|
|||
|
||||
tgShapefile::FromPolygon( poly, ds_name, layer, material.c_str() );
|
||||
}
|
||||
|
||||
/* make sure we loaded a valid poly */
|
||||
poly = tgPolygon::RemoveBadContours(poly);
|
||||
if ( poly.Contours() ) {
|
||||
polys_in.add_poly( area, poly );
|
||||
total_polys_read++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,3 +130,112 @@ int TGConstruct::LoadLandclassPolys( void ) {
|
|||
|
||||
return total_polys_read;
|
||||
}
|
||||
|
||||
bool TGConstruct::CheckMatchingNode( SGGeod& node, bool road, bool fixed )
|
||||
{
|
||||
bool matched = false;
|
||||
bool added = false;
|
||||
|
||||
if ( fixed ) {
|
||||
node = nodes.unique_add_fixed_elevation( node );
|
||||
added = true;
|
||||
} else {
|
||||
// check mutable edge
|
||||
if ( !nm_north.empty() ) {
|
||||
double north_compare = bucket.get_center_lat() + 0.5 * bucket.get_height();
|
||||
if ( fabs(node.getLatitudeDeg() - north_compare) < SG_EPSILON) {
|
||||
if ( !road ) {
|
||||
// node is on the non_mutable northern border - get closest pt
|
||||
node = GetNearestNodeLongitude( node, nm_north );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " AddNode: constrained on north border from " << node << " to " << node );
|
||||
added = true;
|
||||
} else {
|
||||
matched = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !added && !matched && !nm_south.empty() ) {
|
||||
double south_compare = bucket.get_center_lat() - 0.5 * bucket.get_height();
|
||||
if ( fabs(node.getLatitudeDeg() - south_compare) < SG_EPSILON) {
|
||||
if ( !road ) {
|
||||
// node is on the non_mutable southern border - get closest pt
|
||||
node = GetNearestNodeLongitude( node, nm_south );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " AddNode: constrained on south border from " << node << " to " << node );
|
||||
added = true;
|
||||
} else {
|
||||
matched = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !added && !matched && !nm_east.empty() ) {
|
||||
double east_compare = bucket.get_center_lon() + 0.5 * bucket.get_width();
|
||||
if ( fabs(node.getLongitudeDeg() - east_compare) < SG_EPSILON) {
|
||||
if ( !road ) {
|
||||
// node is on the non_mutable eastern border - get closest pt
|
||||
node = GetNearestNodeLatitude( node, nm_east );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " AddNode: constrained on east border from " << node << " to " << node );
|
||||
added = true;
|
||||
} else {
|
||||
matched = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !added && !matched && !nm_west.empty() ) {
|
||||
double west_compare = bucket.get_center_lon() - 0.5 * bucket.get_width();
|
||||
if ( fabs(node.getLongitudeDeg() - west_compare) < SG_EPSILON) {
|
||||
if ( !road ) {
|
||||
// node is on the non_mutable western border - get closest pt
|
||||
node = GetNearestNodeLatitude( node, nm_west );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " AddNode: constrained on west border from " << node << " to " << node );
|
||||
added = true;
|
||||
} else {
|
||||
matched = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!added && !matched) {
|
||||
node = nodes.unique_add( node );
|
||||
added = true;
|
||||
}
|
||||
|
||||
return added;
|
||||
}
|
||||
|
||||
SGGeod TGConstruct::GetNearestNodeLongitude( const SGGeod& node, const std::vector<SGGeod>& selection )
|
||||
{
|
||||
double min_dist = std::numeric_limits<double>::infinity();
|
||||
double cur_dist;
|
||||
unsigned int min_idx = 0;
|
||||
|
||||
for ( unsigned int i=0; i<selection.size(); i++ ) {
|
||||
cur_dist = fabs( node.getLongitudeDeg() - selection[i].getLongitudeDeg() );
|
||||
if ( cur_dist < min_dist ) {
|
||||
min_dist = cur_dist;
|
||||
min_idx = i;
|
||||
}
|
||||
}
|
||||
|
||||
return selection[min_idx];
|
||||
}
|
||||
|
||||
SGGeod TGConstruct::GetNearestNodeLatitude( const SGGeod& node, const std::vector<SGGeod>& selection )
|
||||
{
|
||||
double min_dist = std::numeric_limits<double>::infinity();
|
||||
double cur_dist;
|
||||
unsigned int min_idx = 0;
|
||||
|
||||
for ( unsigned int i=0; i<selection.size(); i++ ) {
|
||||
cur_dist = fabs( node.getLatitudeDeg() - selection[i].getLatitudeDeg() );
|
||||
if ( cur_dist < min_dist ) {
|
||||
min_dist = cur_dist;
|
||||
min_idx = i;
|
||||
}
|
||||
}
|
||||
|
||||
return selection[min_idx];
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <iomanip>
|
||||
|
||||
#include <simgear/misc/sg_dir.hxx>
|
||||
#include <simgear/io/sg_binobj.hxx>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/io/lowlevel.hxx>
|
||||
|
||||
|
@ -34,6 +35,147 @@
|
|||
|
||||
using std::string;
|
||||
|
||||
void TGConstruct::CreateMatchedEdgeFiles( std::vector<SGBucket>& bucketList )
|
||||
{
|
||||
// todo - add to work queue
|
||||
for ( unsigned int i=0; i<bucketList.size(); i++ ) {
|
||||
SGBucket b = bucketList[i];
|
||||
nodes.clear();
|
||||
|
||||
// load the .btg from the match directory
|
||||
SGPath file = match_base + "/" + b.gen_base_path() + "/" + b.gen_index_str() + ".btg.gz";
|
||||
SGBinObject obj;
|
||||
|
||||
obj.read_bin( file.str() );
|
||||
std::vector<SGVec3d> wgs84_nodes(obj.get_wgs84_nodes() );
|
||||
|
||||
string filepath;
|
||||
std::vector<SGGeod> north, south, east, west;
|
||||
int nCount;
|
||||
|
||||
// read in all of the .btg nodes
|
||||
for ( unsigned int j=0; j<wgs84_nodes.size(); j++ ) {
|
||||
SGGeod pos = SGGeod::fromCart( wgs84_nodes[j] + obj.get_gbs_center() );
|
||||
nodes.unique_add( pos );
|
||||
}
|
||||
|
||||
SG_LOG( SG_GENERAL, SG_DEBUG, "Read " << nodes.size() << " from file " << file.str() );
|
||||
|
||||
nodes.init_spacial_query();
|
||||
nodes.get_geod_edge( b, north, south, east, west );
|
||||
|
||||
filepath = share_base + "/match1/" + b.gen_base_path() + "/" + b.gen_index_str() + "_edges";
|
||||
SGPath file2(filepath);
|
||||
|
||||
lock->lock();
|
||||
|
||||
file2.create_dir( 0755 );
|
||||
|
||||
gzFile fp;
|
||||
if ( (fp = gzopen( filepath.c_str(), "wb9" )) == NULL ) {
|
||||
SG_LOG( SG_GENERAL, SG_INFO, "ERROR: opening " << file.str() << " for writing!" );
|
||||
return;
|
||||
}
|
||||
|
||||
sgClearWriteError();
|
||||
|
||||
// north
|
||||
nCount = north.size();
|
||||
SG_LOG( SG_GENERAL, SG_DEBUG, "write " << north.size() << " northern nodes to file " << filepath.c_str() );
|
||||
sgWriteInt( fp, nCount );
|
||||
for (int i=0; i<nCount; i++) {
|
||||
sgWriteGeod( fp, north[i] );
|
||||
}
|
||||
|
||||
// south
|
||||
nCount = south.size();
|
||||
SG_LOG( SG_GENERAL, SG_DEBUG, "write " << south.size() << " southern nodes to file " << filepath.c_str() );
|
||||
sgWriteInt( fp, nCount );
|
||||
for (int i=0; i<nCount; i++) {
|
||||
sgWriteGeod( fp, south[i] );
|
||||
}
|
||||
|
||||
// east
|
||||
nCount = east.size();
|
||||
SG_LOG( SG_GENERAL, SG_DEBUG, "write " << east.size() << " eastern nodes to file " << filepath.c_str() );
|
||||
sgWriteInt( fp, nCount );
|
||||
for (int i=0; i<nCount; i++) {
|
||||
sgWriteGeod( fp, east[i] );
|
||||
}
|
||||
|
||||
// west
|
||||
nCount = west.size();
|
||||
SG_LOG( SG_GENERAL, SG_DEBUG, "write " << west.size() << " western nodes to file " << filepath.c_str() );
|
||||
sgWriteInt( fp, nCount );
|
||||
for (int i=0; i<nCount; i++) {
|
||||
sgWriteGeod( fp, west[i] );
|
||||
}
|
||||
|
||||
gzclose(fp);
|
||||
|
||||
lock->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void TGConstruct::LoadMatchedEdgeFiles()
|
||||
{
|
||||
// try to load matched edges - on successful load, the edge is marked immutable
|
||||
|
||||
// we need to read just 4 buckets for stage 1 - 1 for each edge
|
||||
std::vector<SGGeod> north, south, east, west;
|
||||
SGBucket nb, sb, eb, wb;
|
||||
|
||||
// Read Northern tile and add its southern nodes
|
||||
nb = bucket.sibling(0, 1);
|
||||
LoadNeighboorMatchDataStage1( nb, north, south, east, west );
|
||||
if ( !south.empty() ) {
|
||||
SG_LOG( SG_GENERAL, SG_DEBUG, "Read " << south.size() << " northern matched nodes " );
|
||||
|
||||
// Add southern nodes from northern tile
|
||||
for (unsigned int i=0; i<south.size(); i++) {
|
||||
nodes.unique_add( south[i] );
|
||||
nm_north.push_back( south[i] );
|
||||
}
|
||||
}
|
||||
|
||||
// Read Southern Tile and add its northern nodes
|
||||
sb = bucket.sibling(0, -1);
|
||||
LoadNeighboorMatchDataStage1( sb, north, south, east, west );
|
||||
if ( !north.empty() ) {
|
||||
SG_LOG( SG_GENERAL, SG_DEBUG, "Read " << north.size() << " southern matched nodes " );
|
||||
|
||||
for (unsigned int i=0; i<north.size(); i++) {
|
||||
nodes.unique_add( north[i] );
|
||||
nm_south.push_back( north[i] );
|
||||
}
|
||||
}
|
||||
|
||||
// Read Eastern Tile and add its western nodes
|
||||
eb = bucket.sibling(1, 0);
|
||||
LoadNeighboorMatchDataStage1( eb, north, south, east, west );
|
||||
SG_LOG( SG_GENERAL, SG_DEBUG, "Read " << west.size() << " eastern matched nodes " );
|
||||
|
||||
if ( !west.empty() ) {
|
||||
for (unsigned int i=0; i<west.size(); i++) {
|
||||
nodes.unique_add( west[i] );
|
||||
nm_east.push_back( west[i] );
|
||||
}
|
||||
}
|
||||
|
||||
// Read Western Tile and add its eastern nodes
|
||||
wb = bucket.sibling(-1, 0);
|
||||
SG_LOG( SG_GENERAL, SG_DEBUG, "Read " << east.size() << " western matched nodes " );
|
||||
|
||||
LoadNeighboorMatchDataStage1( wb, north, south, east, west );
|
||||
if ( !east.empty() ) {
|
||||
for (unsigned int i=0; i<east.size(); i++) {
|
||||
nodes.unique_add( east[i] );
|
||||
nm_west.push_back( east[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TGConstruct::SaveSharedEdgeData( int stage )
|
||||
{
|
||||
switch( stage ) {
|
||||
|
@ -527,6 +669,60 @@ void TGConstruct::LoadNeighboorEdgeDataStage1( SGBucket& b, std::vector<SGGeod>&
|
|||
}
|
||||
}
|
||||
|
||||
void TGConstruct::LoadNeighboorMatchDataStage1( SGBucket& b, std::vector<SGGeod>& north, std::vector<SGGeod>& south, std::vector<SGGeod>& east, std::vector<SGGeod>& west )
|
||||
{
|
||||
string dir;
|
||||
string file;
|
||||
gzFile fp;
|
||||
SGGeod pt;
|
||||
int nCount;
|
||||
|
||||
dir = share_base + "/match1/" + b.gen_base_path();
|
||||
file = dir + "/" + b.gen_index_str() + "_edges";
|
||||
fp = gzopen( file.c_str(), "rb" );
|
||||
|
||||
north.clear();
|
||||
south.clear();
|
||||
east.clear();
|
||||
west.clear();
|
||||
|
||||
if (fp) {
|
||||
// North
|
||||
sgReadInt( fp, &nCount );
|
||||
SG_LOG( SG_CLIPPER, SG_DEBUG, "loading " << nCount << "Points on " << b.gen_index_str() << " north boundary");
|
||||
for (int i=0; i<nCount; i++) {
|
||||
sgReadGeod( fp, pt );
|
||||
north.push_back(pt);
|
||||
}
|
||||
|
||||
// South
|
||||
sgReadInt( fp, &nCount );
|
||||
SG_LOG( SG_CLIPPER, SG_DEBUG, "loading " << nCount << "Points on " << b.gen_index_str() << " south boundary");
|
||||
for (int i=0; i<nCount; i++) {
|
||||
sgReadGeod( fp, pt );
|
||||
south.push_back(pt);
|
||||
}
|
||||
|
||||
// East
|
||||
sgReadInt( fp, &nCount );
|
||||
SG_LOG( SG_CLIPPER, SG_DEBUG, "loading " << nCount << "Points on " << b.gen_index_str() << " east boundary");
|
||||
for (int i=0; i<nCount; i++) {
|
||||
sgReadGeod( fp, pt );
|
||||
east.push_back(pt);
|
||||
}
|
||||
|
||||
// West
|
||||
sgReadInt( fp, &nCount );
|
||||
SG_LOG( SG_CLIPPER, SG_DEBUG, "loading " << nCount << "Points on " << b.gen_index_str() << " west boundary");
|
||||
for (int i=0; i<nCount; i++) {
|
||||
sgReadGeod( fp, pt );
|
||||
west.push_back(pt);
|
||||
}
|
||||
|
||||
gzclose( fp );
|
||||
}
|
||||
}
|
||||
|
||||
void TGConstruct::LoadFromIntermediateFiles( int stage )
|
||||
{
|
||||
string dir;
|
||||
|
|
|
@ -64,6 +64,7 @@ void TGConstruct::TesselatePolys( void )
|
|||
}
|
||||
|
||||
for (unsigned int area = 0; area < area_defs.size(); area++) {
|
||||
bool isRoad = area_defs.is_road_area( area );
|
||||
for (unsigned int p = 0; p < polys_clipped.area_size(area); p++ ) {
|
||||
tgPolygon& poly = polys_clipped.get_poly(area, p );
|
||||
|
||||
|
@ -71,7 +72,13 @@ void TGConstruct::TesselatePolys( void )
|
|||
for (unsigned int k=0; k < poly.Triangles(); k++) {
|
||||
for (int l = 0; l < 3; l++) {
|
||||
// ensure we have all nodes...
|
||||
nodes.unique_add( poly.GetTriNode( k, l ) );
|
||||
SGGeod node = poly.GetTriNode( k, l );
|
||||
if ( CheckMatchingNode( node, isRoad, false ) ) {
|
||||
nodes.unique_add( node );
|
||||
} else {
|
||||
SG_LOG( SG_GENERAL, SG_INFO, "after tesselation, we can't add a node - quit");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,9 @@ public:
|
|||
void SetNode( unsigned int i, SGGeod n ) {
|
||||
node_list[i] = n;
|
||||
}
|
||||
void DelNode( unsigned int i ) {
|
||||
node_list.erase( node_list.begin()+i);
|
||||
}
|
||||
SGGeod GetNode( unsigned int i ) const {
|
||||
return node_list[i];
|
||||
}
|
||||
|
|
|
@ -68,26 +68,32 @@ 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 SGGeod& p ) {
|
||||
SGGeod unique_add( const SGGeod& p ) {
|
||||
TGNode n(p);
|
||||
n.SetFixedPosition(false);
|
||||
tg_node_list.add(n);
|
||||
unsigned idx = tg_node_list.add(n);
|
||||
kd_tree_valid = false;
|
||||
|
||||
return tg_node_list[idx].GetPosition();
|
||||
}
|
||||
|
||||
void unique_add( const TGNode& n ) {
|
||||
tg_node_list.add(n);
|
||||
SGGeod unique_add( const TGNode& n ) {
|
||||
unsigned int idx = tg_node_list.add(n);
|
||||
kd_tree_valid = false;
|
||||
|
||||
return tg_node_list[idx].GetPosition();
|
||||
}
|
||||
|
||||
// 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 SGGeod& p ) {
|
||||
SGGeod unique_add_fixed_elevation( const SGGeod& p ) {
|
||||
TGNode n(p);
|
||||
n.SetFixedPosition(true);
|
||||
tg_node_list.add(n);
|
||||
unsigned int idx = tg_node_list.add(n);
|
||||
kd_tree_valid = false;
|
||||
|
||||
return tg_node_list[idx].GetPosition();
|
||||
}
|
||||
|
||||
// Find the index of the specified point (compair to the same
|
||||
|
|
|
@ -264,6 +264,9 @@ public:
|
|||
|
||||
contours[c].AddNode( n );
|
||||
}
|
||||
void DelNode( unsigned int c, unsigned int n ) {
|
||||
contours[c].DelNode( n );
|
||||
}
|
||||
|
||||
tgRectangle GetBoundingBox( void ) const;
|
||||
|
||||
|
|
Loading…
Reference in a new issue