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
|
||||
Watercourse stream
|
||||
Canal stream
|
||||
Cliff cliff # A cliff face
|
||||
Cliffs cliff # A cliff face
|
||||
Glacier other # Solid ice/snow
|
||||
PackIce other # Water with ice packs
|
||||
PolarIce other
|
||||
|
@ -86,7 +86,9 @@ ShrubGrassCover other # Mixed Shrubland/Grassland
|
|||
SavannaCover other # Savanna
|
||||
Orchard other # Orchard
|
||||
DeciduousForest other # Deciduous Forest
|
||||
DeciduousBroadCover other # Deciduous Forest
|
||||
EvergreenForest other # Evergreen Forest
|
||||
EvergreenBroadCover other # Evergreen Forest
|
||||
MixedForest other # Mixed Forest
|
||||
RainForest other # Rain Forest
|
||||
BarrenCover other # Barren or Sparsely Vegetated
|
||||
|
|
|
@ -67,8 +67,10 @@ int TGConstruct::LoadLandclassPolys( void ) {
|
|||
}
|
||||
|
||||
string lext = p.complete_lower_extension();
|
||||
string lastext = p.extension();
|
||||
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!
|
||||
} else {
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#endif
|
||||
|
||||
#include <cstring>
|
||||
#include <iomanip> //for setprecision
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/io/iostreams/sgstream.hxx>
|
||||
|
@ -120,12 +121,8 @@ bool TGArray::load_cliffs(const string & height_base)
|
|||
continue;
|
||||
}
|
||||
|
||||
string lext = p.complete_lower_extension();
|
||||
if ((lext == "arr") || (lext == "arr.gz") || (lext == "btg.gz") ||
|
||||
(lext == "fit") || (lext == "fit.gz") || (lext == "ind"))
|
||||
{
|
||||
// skipped!
|
||||
} else {
|
||||
string lext = p.lower_extension();
|
||||
if (lext == "cliffs") {
|
||||
gzFile fp = gzopen( p.c_str(), "rb" );
|
||||
unsigned int 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]);
|
||||
break;
|
||||
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
|
||||
dx = xlocal - xindex;
|
||||
dy = ylocal - yindex;
|
||||
|
|
|
@ -11,8 +11,7 @@
|
|||
#include "tg_misc.hxx"
|
||||
|
||||
tgPolygon tgChopper::Clip( const tgPolygon& subject,
|
||||
const std::string& type,
|
||||
SGBucket& b )
|
||||
const std::string& type, SGBucket& b)
|
||||
{
|
||||
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_NW ) );
|
||||
|
||||
result = tgPolygon::Intersect( subject, base );
|
||||
result = tgPolygon::Intersect( subject, base);
|
||||
if ( result.Contours() > 0 ) {
|
||||
if ( subject.GetPreserve3D() ) {
|
||||
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
|
||||
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
|
||||
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
|
||||
{
|
||||
|
@ -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) );
|
||||
|
||||
clipped = tgPolygon::Intersect( subject, clip_row );
|
||||
clipped = tgPolygon::Intersect( subject, clip_row);
|
||||
if ( clipped.TotalNodes() > 0 ) {
|
||||
|
||||
if ( subject.GetPreserve3D() ) {
|
||||
|
@ -205,7 +205,7 @@ void tgChopper::Save( bool DebugShapefiles )
|
|||
long int poly_index = GenerateIndex( path );
|
||||
|
||||
sprintf( poly_ext, "%ld", poly_index );
|
||||
polyfile = polyfile + "." + poly_ext;
|
||||
polyfile = polyfile + "." + poly_ext + "." + extra_extension;
|
||||
|
||||
gzFile fp;
|
||||
if ( (fp = gzopen( polyfile.c_str(), "wb9" )) == NULL ) {
|
||||
|
|
|
@ -11,10 +11,14 @@ class tgChopper
|
|||
public:
|
||||
tgChopper( const std::string& path ) {
|
||||
root_path = path;
|
||||
extra_extension = "";
|
||||
}
|
||||
|
||||
void Add( const tgPolygon& poly, const std::string& type );
|
||||
void Save( bool DebugShapes );
|
||||
void Add_Extension( const std::string& extension) {
|
||||
extra_extension = extension;
|
||||
}
|
||||
|
||||
private:
|
||||
long int GenerateIndex( std::string path );
|
||||
|
@ -25,4 +29,5 @@ private:
|
|||
std::string root_path;
|
||||
bucket_polys_map bp_map;
|
||||
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 t = (crossx*nydif - crossy*nxdif)/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 );
|
||||
p1 = subject.GetNode( 0 );
|
||||
|
||||
if (!subject.GetOpen()) {
|
||||
// add start of segment
|
||||
result.AddNode( p0 );
|
||||
|
||||
// add intermediate points
|
||||
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.SetOpen( subject.GetOpen() );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -879,14 +885,16 @@ tgContour tgContour::AddColinearNodes( const tgContour& subject, bool preserve3d
|
|||
p0 = subject.GetNode( subject.GetSize() - 1 );
|
||||
p1 = subject.GetNode( 0 );
|
||||
|
||||
if(!subject.GetOpen()) {
|
||||
// add start of segment
|
||||
result.AddNode( p0 );
|
||||
|
||||
// add intermediate points
|
||||
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.SetOpen( subject.GetOpen() );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ class tgContour
|
|||
public:
|
||||
tgContour() {
|
||||
hole = false;
|
||||
keep_open = false;
|
||||
}
|
||||
|
||||
void Erase() {
|
||||
|
@ -38,10 +39,19 @@ public:
|
|||
void SetHole( bool h ) {
|
||||
hole = h;
|
||||
}
|
||||
|
||||
bool GetHole( void ) const {
|
||||
return hole;
|
||||
}
|
||||
|
||||
bool GetOpen(void) const {
|
||||
return keep_open;
|
||||
}
|
||||
|
||||
void SetOpen(bool o) {
|
||||
keep_open = o;
|
||||
}
|
||||
|
||||
unsigned int GetSize( void ) const {
|
||||
return node_list.size();
|
||||
}
|
||||
|
@ -138,6 +148,7 @@ public:
|
|||
private:
|
||||
std::vector<SGGeod> node_list;
|
||||
bool hole;
|
||||
bool keep_open; //If non-closed contour, keep open
|
||||
};
|
||||
|
||||
typedef std::vector <tgContour> tgcontour_list;
|
||||
|
|
|
@ -243,6 +243,7 @@ class tgPolygon
|
|||
public:
|
||||
tgPolygon() {
|
||||
preserve3d = false;
|
||||
closed = true;
|
||||
}
|
||||
~tgPolygon() {
|
||||
contours.clear();
|
||||
|
@ -351,6 +352,18 @@ public:
|
|||
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 {
|
||||
return preserve3d;
|
||||
}
|
||||
|
@ -436,6 +449,7 @@ public:
|
|||
// Conversions
|
||||
static ClipperLib::Paths ToClipper( const tgPolygon& 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 );
|
||||
|
||||
// T-Junctions and segment search
|
||||
|
@ -460,6 +474,7 @@ private:
|
|||
bool preserve3d;
|
||||
unsigned int id; // unique polygon id for debug
|
||||
tgTexParams tp;
|
||||
bool closed; // if we treat it as a closed shape
|
||||
};
|
||||
|
||||
#endif // _POLYGON_HXX
|
||||
|
|
|
@ -136,7 +136,8 @@ tgPolygon tgPolygon::Diff( const tgPolygon& subject, tgPolygon& clip )
|
|||
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;
|
||||
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_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;
|
||||
c.Clear();
|
||||
c.AddPaths(clipper_subject, ClipperLib::ptSubject, true);
|
||||
c.AddPaths(clipper_subject, ClipperLib::ptSubject, subject.IsClosed());
|
||||
c.AddPaths(clipper_clip, ClipperLib::ptClip, true);
|
||||
if(subject.IsClosed()) {
|
||||
c.Execute(ClipperLib::ctIntersection, clipper_result, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd);
|
||||
|
||||
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.SetMaterial( subject.GetMaterial() );
|
||||
result.SetTexParams( subject.GetTexParams() );
|
||||
result.SetId( subject.GetId() );
|
||||
|
@ -199,6 +206,17 @@ tgPolygon tgPolygon::FromClipper( const ClipperLib::Paths& subject )
|
|||
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 contour;
|
||||
|
|
Loading…
Add table
Reference in a new issue