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:
parent
005fd6886a
commit
d36116d965
9 changed files with 97 additions and 38 deletions
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
@ -22,7 +21,7 @@ tgPolygon tgChopper::Clip( const tgPolygon& subject,
|
||||||
base.AddNode( 0, b.get_corner( SG_BUCKET_NE ) );
|
base.AddNode( 0, b.get_corner( SG_BUCKET_NE ) );
|
||||||
base.AddNode( 0, b.get_corner( SG_BUCKET_NW ) );
|
base.AddNode( 0, b.get_corner( SG_BUCKET_NW ) );
|
||||||
|
|
||||||
result = tgPolygon::Intersect( subject, base );
|
result = tgPolygon::Intersect( subject, base);
|
||||||
if ( result.Contours() > 0 ) {
|
if ( result.Contours() > 0 ) {
|
||||||
if ( subject.GetPreserve3D() ) {
|
if ( subject.GetPreserve3D() ) {
|
||||||
result.InheritElevations( subject );
|
result.InheritElevations( subject );
|
||||||
|
@ -63,7 +62,8 @@ 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
|
||||||
if ( subject.Contours() == 0 )
|
if ( subject.Contours() == 0 )
|
||||||
|
@ -90,7 +90,7 @@ void tgChopper::Add( const tgPolygon& subject, const std::string& type )
|
||||||
// We just have a single row - no need to intersect first
|
// We just have a single row - no need to intersect first
|
||||||
SG_LOG( SG_GENERAL, SG_DEBUG, " UN_CLIPPED row - center lat is " << b_min.get_center_lat() );
|
SG_LOG( SG_GENERAL, SG_DEBUG, " UN_CLIPPED row - center lat is " << b_min.get_center_lat() );
|
||||||
|
|
||||||
ClipRow( subject, b_min.get_center_lat(), type );
|
ClipRow( subject, b_min.get_center_lat(), type);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -117,7 +117,7 @@ void tgChopper::Add( const tgPolygon& subject, const std::string& type )
|
||||||
clip_row.AddNode( 0, SGGeod::fromDeg( 180.0, clip_top) );
|
clip_row.AddNode( 0, SGGeod::fromDeg( 180.0, clip_top) );
|
||||||
clip_row.AddNode( 0, SGGeod::fromDeg(-180.0, clip_top) );
|
clip_row.AddNode( 0, SGGeod::fromDeg(-180.0, clip_top) );
|
||||||
|
|
||||||
clipped = tgPolygon::Intersect( subject, clip_row );
|
clipped = tgPolygon::Intersect( subject, clip_row);
|
||||||
if ( clipped.TotalNodes() > 0 ) {
|
if ( clipped.TotalNodes() > 0 ) {
|
||||||
|
|
||||||
if ( subject.GetPreserve3D() ) {
|
if ( subject.GetPreserve3D() ) {
|
||||||
|
@ -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 ) {
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -136,7 +136,8 @@ tgPolygon tgPolygon::Diff( const tgPolygon& subject, tgPolygon& clip )
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
tgPolygon tgPolygon::Intersect( const tgPolygon& subject, const tgPolygon& clip )
|
//Intersect will keep open paths open
|
||||||
|
tgPolygon tgPolygon::Intersect( const tgPolygon& subject, const tgPolygon& clip)
|
||||||
{
|
{
|
||||||
tgPolygon result;
|
tgPolygon result;
|
||||||
UniqueSGGeodSet all_nodes;
|
UniqueSGGeodSet all_nodes;
|
||||||
|
@ -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;
|
||||||
|
|
Loading…
Add table
Reference in a new issue