1
0
Fork 0

Cliffs now appear more or less correctly.

Added cliffs to default_priorities
Ignore cliff files when constructing terrain
Use cliff files when calculating elevations
Set up chopper to allow file extension to be specified
Specify cliff file name when chopping
Allow chopper to chop lines as well as polygons.
This commit is contained in:
James.Hester 2018-10-21 10:07:23 +11:00
parent 005fd6886a
commit d36116d965
9 changed files with 97 additions and 38 deletions

View file

@ -30,7 +30,7 @@ River stream
IntermittentStream stream IntermittentStream stream
Watercourse stream Watercourse stream
Canal stream Canal stream
Cliff cliff # A cliff face Cliffs cliff # A cliff face
Glacier other # Solid ice/snow Glacier other # Solid ice/snow
PackIce other # Water with ice packs PackIce other # Water with ice packs
PolarIce other PolarIce other
@ -86,7 +86,9 @@ ShrubGrassCover other # Mixed Shrubland/Grassland
SavannaCover other # Savanna SavannaCover other # Savanna
Orchard other # Orchard Orchard other # Orchard
DeciduousForest other # Deciduous Forest DeciduousForest other # Deciduous Forest
DeciduousBroadCover other # Deciduous Forest
EvergreenForest other # Evergreen Forest EvergreenForest other # Evergreen Forest
EvergreenBroadCover other # Evergreen Forest
MixedForest other # Mixed Forest MixedForest other # Mixed Forest
RainForest other # Rain Forest RainForest other # Rain Forest
BarrenCover other # Barren or Sparsely Vegetated BarrenCover other # Barren or Sparsely Vegetated

View file

@ -67,8 +67,10 @@ int TGConstruct::LoadLandclassPolys( void ) {
} }
string lext = p.complete_lower_extension(); string lext = p.complete_lower_extension();
string lastext = p.extension();
if ((lext == "arr") || (lext == "arr.gz") || (lext == "btg.gz") || if ((lext == "arr") || (lext == "arr.gz") || (lext == "btg.gz") ||
(lext == "fit") || (lext == "fit.gz") || (lext == "ind")) (lext == "fit") || (lext == "fit.gz") || (lext == "ind") ||
(lastext == "cliffs"))
{ {
// skipped! // skipped!
} else { } else {

View file

@ -24,6 +24,7 @@
#endif #endif
#include <cstring> #include <cstring>
#include <iomanip> //for setprecision
#include <simgear/compiler.h> #include <simgear/compiler.h>
#include <simgear/io/iostreams/sgstream.hxx> #include <simgear/io/iostreams/sgstream.hxx>
@ -120,12 +121,8 @@ bool TGArray::load_cliffs(const string & height_base)
continue; continue;
} }
string lext = p.complete_lower_extension(); string lext = p.lower_extension();
if ((lext == "arr") || (lext == "arr.gz") || (lext == "btg.gz") || if (lext == "cliffs") {
(lext == "fit") || (lext == "fit.gz") || (lext == "ind"))
{
// skipped!
} else {
gzFile fp = gzopen( p.c_str(), "rb" ); gzFile fp = gzopen( p.c_str(), "rb" );
unsigned int count; unsigned int count;
sgReadUInt( fp, &count ); sgReadUInt( fp, &count );
@ -572,7 +569,8 @@ double TGArray::altitude_from_grid( double lon, double lat ) const {
elev = get_array_elev(corners[0][0],corners[0][1]); elev = get_array_elev(corners[0][0],corners[0][1]);
break; break;
case 0: // all points on wrong side, fall through to normal calc case 0: // all points on wrong side, fall through to normal calc
SG_LOG(SG_GENERAL, SG_WARN, "All elevation grid points on wrong side of cliff for " << londeg << "," << latdeg ); SG_LOG(SG_GENERAL, SG_WARN, "All elevation grid points on wrong side of cliff for " << std::setprecision(10) << londeg << "," << latdeg );
SG_LOG(SG_GENERAL, SG_WARN, "Grid points ("<< std::setprecision(9) << lon1 << "," << lat1 << "),("<<lon2<<","<<lat2<<")");
default: // all corners default: // all corners
dx = xlocal - xindex; dx = xlocal - xindex;
dy = ylocal - yindex; dy = ylocal - yindex;

View file

@ -11,8 +11,7 @@
#include "tg_misc.hxx" #include "tg_misc.hxx"
tgPolygon tgChopper::Clip( const tgPolygon& subject, tgPolygon tgChopper::Clip( const tgPolygon& subject,
const std::string& type, const std::string& type, SGBucket& b)
SGBucket& b )
{ {
tgPolygon base, result; tgPolygon base, result;
@ -63,6 +62,7 @@ void tgChopper::ClipRow( const tgPolygon& subject, const double& center_lat, con
} }
} }
void tgChopper::Add( const tgPolygon& subject, const std::string& type) void tgChopper::Add( const tgPolygon& subject, const std::string& type)
{ {
// bail out immediately if polygon is empty // bail out immediately if polygon is empty
@ -205,7 +205,7 @@ void tgChopper::Save( bool DebugShapefiles )
long int poly_index = GenerateIndex( path ); long int poly_index = GenerateIndex( path );
sprintf( poly_ext, "%ld", poly_index ); sprintf( poly_ext, "%ld", poly_index );
polyfile = polyfile + "." + poly_ext; polyfile = polyfile + "." + poly_ext + "." + extra_extension;
gzFile fp; gzFile fp;
if ( (fp = gzopen( polyfile.c_str(), "wb9" )) == NULL ) { if ( (fp = gzopen( polyfile.c_str(), "wb9" )) == NULL ) {

View file

@ -11,10 +11,14 @@ class tgChopper
public: public:
tgChopper( const std::string& path ) { tgChopper( const std::string& path ) {
root_path = path; root_path = path;
extra_extension = "";
} }
void Add( const tgPolygon& poly, const std::string& type ); void Add( const tgPolygon& poly, const std::string& type );
void Save( bool DebugShapes ); void Save( bool DebugShapes );
void Add_Extension( const std::string& extension) {
extra_extension = extension;
}
private: private:
long int GenerateIndex( std::string path ); long int GenerateIndex( std::string path );
@ -25,4 +29,5 @@ private:
std::string root_path; std::string root_path;
bucket_polys_map bp_map; bucket_polys_map bp_map;
SGMutex lock; SGMutex lock;
std::string extra_extension; //add at end of file name
}; };

View file

@ -111,7 +111,11 @@ Then the line segments intersect if 0 <= t,u <= 1.
double crossx = x1-nx1; double crossy = y1-ny1; double crossx = x1-nx1; double crossy = y1-ny1;
double t = (crossx*nydif - crossy*nxdif)/denom; double t = (crossx*nydif - crossy*nxdif)/denom;
double u = -1*(xdif*crossy - ydif*crossx)/denom; double u = -1*(xdif*crossy - ydif*crossx)/denom;
if (t >= 0.0 && t <= 1.0 && u >= 0.0 && u <= 1.0) intersect_ct++; // We consider that an intersection at the edge of the line have
// not crossed
// over, that is, they lie on the same side, so we do not
// include equality in the comparisons
if (t > 0.0 && t < 1.0 && u > 0.0 && u < 1.0) intersect_ct++;
} }
} }
} }
@ -848,14 +852,16 @@ tgContour tgContour::AddColinearNodes( const tgContour& subject, std::vector<SGG
p0 = subject.GetNode( subject.GetSize() - 1 ); p0 = subject.GetNode( subject.GetSize() - 1 );
p1 = subject.GetNode( 0 ); p1 = subject.GetNode( 0 );
if (!subject.GetOpen()) {
// add start of segment // add start of segment
result.AddNode( p0 ); result.AddNode( p0 );
// add intermediate points // add intermediate points
AddIntermediateNodes( p0, p1, nodes, result, SG_EPSILON*10, SG_EPSILON*4 ); AddIntermediateNodes( p0, p1, nodes, result, SG_EPSILON*10, SG_EPSILON*4 );
}
// maintain original hole flag setting // maintain original hole and openness flag setting
result.SetHole( subject.GetHole() ); result.SetHole( subject.GetHole() );
result.SetOpen( subject.GetOpen() );
return result; return result;
} }
@ -879,14 +885,16 @@ tgContour tgContour::AddColinearNodes( const tgContour& subject, bool preserve3d
p0 = subject.GetNode( subject.GetSize() - 1 ); p0 = subject.GetNode( subject.GetSize() - 1 );
p1 = subject.GetNode( 0 ); p1 = subject.GetNode( 0 );
if(!subject.GetOpen()) {
// add start of segment // add start of segment
result.AddNode( p0 ); result.AddNode( p0 );
// add intermediate points // add intermediate points
AddIntermediateNodes( p0, p1, preserve3d, nodes, result, SG_EPSILON*10, SG_EPSILON*4 ); AddIntermediateNodes( p0, p1, preserve3d, nodes, result, SG_EPSILON*10, SG_EPSILON*4 );
}
// maintain original hole flag setting // maintain original hole and open flag settings
result.SetHole( subject.GetHole() ); result.SetHole( subject.GetHole() );
result.SetOpen( subject.GetOpen() );
return result; return result;
} }

View file

@ -29,6 +29,7 @@ class tgContour
public: public:
tgContour() { tgContour() {
hole = false; hole = false;
keep_open = false;
} }
void Erase() { void Erase() {
@ -38,10 +39,19 @@ public:
void SetHole( bool h ) { void SetHole( bool h ) {
hole = h; hole = h;
} }
bool GetHole( void ) const { bool GetHole( void ) const {
return hole; return hole;
} }
bool GetOpen(void) const {
return keep_open;
}
void SetOpen(bool o) {
keep_open = o;
}
unsigned int GetSize( void ) const { unsigned int GetSize( void ) const {
return node_list.size(); return node_list.size();
} }
@ -138,6 +148,7 @@ public:
private: private:
std::vector<SGGeod> node_list; std::vector<SGGeod> node_list;
bool hole; bool hole;
bool keep_open; //If non-closed contour, keep open
}; };
typedef std::vector <tgContour> tgcontour_list; typedef std::vector <tgContour> tgcontour_list;

View file

@ -243,6 +243,7 @@ class tgPolygon
public: public:
tgPolygon() { tgPolygon() {
preserve3d = false; preserve3d = false;
closed = true;
} }
~tgPolygon() { ~tgPolygon() {
contours.clear(); contours.clear();
@ -351,6 +352,18 @@ public:
flag = f; flag = f;
} }
void SetOpen( void ) { //Do not try to close the contours
closed = false;
}
void SetClosed (void) {
closed = true;
}
bool IsClosed( void ) const {
return closed;
}
bool GetPreserve3D( void ) const { bool GetPreserve3D( void ) const {
return preserve3d; return preserve3d;
} }
@ -436,6 +449,7 @@ public:
// Conversions // Conversions
static ClipperLib::Paths ToClipper( const tgPolygon& subject ); static ClipperLib::Paths ToClipper( const tgPolygon& subject );
static tgPolygon FromClipper( const ClipperLib::Paths& subject ); static tgPolygon FromClipper( const ClipperLib::Paths& subject );
static tgPolygon FromClipper( const ClipperLib::PolyTree& subject );
static void ToClipperFile( const tgPolygon& subject, const std::string& path, const std::string& filename ); static void ToClipperFile( const tgPolygon& subject, const std::string& path, const std::string& filename );
// T-Junctions and segment search // T-Junctions and segment search
@ -460,6 +474,7 @@ private:
bool preserve3d; bool preserve3d;
unsigned int id; // unique polygon id for debug unsigned int id; // unique polygon id for debug
tgTexParams tp; tgTexParams tp;
bool closed; // if we treat it as a closed shape
}; };
#endif // _POLYGON_HXX #endif // _POLYGON_HXX

View file

@ -136,6 +136,7 @@ tgPolygon tgPolygon::Diff( const tgPolygon& subject, tgPolygon& clip )
return result; return result;
} }
//Intersect will keep open paths open
tgPolygon tgPolygon::Intersect( const tgPolygon& subject, const tgPolygon& clip) tgPolygon tgPolygon::Intersect( const tgPolygon& subject, const tgPolygon& clip)
{ {
tgPolygon result; tgPolygon result;
@ -156,17 +157,23 @@ tgPolygon tgPolygon::Intersect( const tgPolygon& subject, const tgPolygon& clip
ClipperLib::Paths clipper_subject = tgPolygon::ToClipper( subject ); ClipperLib::Paths clipper_subject = tgPolygon::ToClipper( subject );
ClipperLib::Paths clipper_clip = tgPolygon::ToClipper( clip ); ClipperLib::Paths clipper_clip = tgPolygon::ToClipper( clip );
ClipperLib::Paths clipper_result; ClipperLib::Paths clipper_result; // for closed polygons
ClipperLib::PolyTree clipper_tree_result; //for open polygons
ClipperLib::Clipper c; ClipperLib::Clipper c;
c.Clear(); c.Clear();
c.AddPaths(clipper_subject, ClipperLib::ptSubject, true); c.AddPaths(clipper_subject, ClipperLib::ptSubject, subject.IsClosed());
c.AddPaths(clipper_clip, ClipperLib::ptClip, true); c.AddPaths(clipper_clip, ClipperLib::ptClip, true);
if(subject.IsClosed()) {
c.Execute(ClipperLib::ctIntersection, clipper_result, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd); c.Execute(ClipperLib::ctIntersection, clipper_result, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd);
result = tgPolygon::FromClipper( clipper_result ); result = tgPolygon::FromClipper( clipper_result );
}
else {
c.Execute(ClipperLib::ctIntersection, clipper_tree_result, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd);
result = tgPolygon::FromClipper( clipper_tree_result );
}
result = tgPolygon::AddColinearNodes( result, all_nodes ); result = tgPolygon::AddColinearNodes( result, all_nodes );
result.SetMaterial( subject.GetMaterial() ); result.SetMaterial( subject.GetMaterial() );
result.SetTexParams( subject.GetTexParams() ); result.SetTexParams( subject.GetTexParams() );
result.SetId( subject.GetId() ); result.SetId( subject.GetId() );
@ -199,6 +206,17 @@ tgPolygon tgPolygon::FromClipper( const ClipperLib::Paths& subject )
return result; return result;
} }
// A polytree is returned when an open polygon has been clipped
tgPolygon tgPolygon::FromClipper( const ClipperLib::PolyTree& subject )
{
ClipperLib::Paths path_result;
tgPolygon result;
ClipperLib::PolyTreeToPaths(subject,path_result);
result = FromClipper(path_result);
return result;
}
ClipperLib::Path tgTriangle::ToClipper( const tgTriangle& subject ) ClipperLib::Path tgTriangle::ToClipper( const tgTriangle& subject )
{ {
ClipperLib::Path contour; ClipperLib::Path contour;