- adding bounding box clip optimization to tgconstruct
- revert some bad ogr-decode changes that caused too angular linear data
This commit is contained in:
parent
5917cb62d1
commit
a7b49565b3
6 changed files with 127 additions and 186 deletions
|
@ -40,8 +40,6 @@
|
|||
#include "tglandclass.hxx"
|
||||
|
||||
#define FIND_SLIVERS (0)
|
||||
#define USE_ACCUMULATOR (1)
|
||||
|
||||
|
||||
// Stage2 shared edge data
|
||||
struct TGNeighborFaces {
|
||||
|
|
|
@ -41,24 +41,14 @@ bool TGConstruct::ClipLandclassPolys( void ) {
|
|||
bool debug_area, debug_shape;
|
||||
static int accum_idx = 0;
|
||||
|
||||
#if !USE_ACCUMULATOR
|
||||
TGPolygon accum;
|
||||
#endif
|
||||
|
||||
// Get clip bounds
|
||||
min.x() = bucket.get_center_lon() - 0.5 * bucket.get_width();
|
||||
min.y() = bucket.get_center_lat() - 0.5 * bucket.get_height();
|
||||
max.x() = bucket.get_center_lon() + 0.5 * bucket.get_width();
|
||||
max.y() = bucket.get_center_lat() + 0.5 * bucket.get_height();
|
||||
|
||||
#if USE_ACCUMULATOR
|
||||
|
||||
tgPolygonInitClipperAccumulator();
|
||||
|
||||
#else
|
||||
accum.erase();
|
||||
#endif
|
||||
|
||||
// set up clipping tile : and remember to add the nodes!
|
||||
safety_base.erase();
|
||||
|
||||
|
@ -146,20 +136,10 @@ bool TGConstruct::ClipLandclassPolys( void ) {
|
|||
sprintf(layer, "pre_clip_accum_%d_%d", accum_idx, polys_in.get_shape( i, j ).id );
|
||||
sprintf(name, "shape_accum %d,%d", i,j);
|
||||
|
||||
#if USE_ACCUMULATOR
|
||||
tgPolygonDumpAccumulator( ds_name, layer, name );
|
||||
#else
|
||||
WriteDebugPoly( layer, name, accum );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if USE_ACCUMULATOR
|
||||
clipped = tgPolygonDiffClipperWithAccumulator( tmp );
|
||||
#else
|
||||
clipped = tgPolygonDiff( tmp, accum );
|
||||
#endif
|
||||
|
||||
|
||||
if ( debug_area || debug_shape ) {
|
||||
char layer[32];
|
||||
|
@ -199,26 +179,19 @@ bool TGConstruct::ClipLandclassPolys( void ) {
|
|||
}
|
||||
}
|
||||
|
||||
#if USE_ACCUMULATOR
|
||||
if ( debug_shape ) {
|
||||
tgPolygonAddToClipperAccumulator( tmp, true );
|
||||
} else {
|
||||
tgPolygonAddToClipperAccumulator( tmp, false );
|
||||
tgPolygonAddToClipperAccumulator( tmp, false );
|
||||
}
|
||||
#else
|
||||
accum = tgPolygonUnion( tmp, accum );
|
||||
#endif
|
||||
|
||||
if ( debug_area || debug_shape ) {
|
||||
char layer[32];
|
||||
char name[32];
|
||||
sprintf(layer, "post_clip_accum_%d_%d", accum_idx, polys_in.get_shape( i, j ).id );
|
||||
sprintf(name, "shape_accum %d,%d", i,j);
|
||||
#if USE_ACCUMULATOR
|
||||
|
||||
tgPolygonDumpAccumulator( ds_name, layer, name );
|
||||
#else
|
||||
WriteDebugPoly( layer, name, accum );
|
||||
#endif
|
||||
}
|
||||
accum_idx++;
|
||||
}
|
||||
|
@ -237,11 +210,7 @@ bool TGConstruct::ClipLandclassPolys( void ) {
|
|||
slivers.clear();
|
||||
|
||||
// finally, what ever is left over goes to ocean
|
||||
#if USE_ACCUMULATOR
|
||||
remains = tgPolygonDiffClipperWithAccumulator( safety_base );
|
||||
#else
|
||||
remains = tgPolygonDiff( safety_base, accum );
|
||||
#endif
|
||||
|
||||
if ( remains.contours() > 0 ) {
|
||||
// cout << "remains contours = " << remains.contours() << endl;
|
||||
|
@ -284,12 +253,8 @@ bool TGConstruct::ClipLandclassPolys( void ) {
|
|||
}
|
||||
}
|
||||
|
||||
#if USE_ACCUMULATOR
|
||||
|
||||
tgPolygonFreeClipperAccumulator();
|
||||
|
||||
#endif
|
||||
|
||||
// Once clipping is complete, intersect the individual segments with their clip masks
|
||||
for (unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++) {
|
||||
for (unsigned int shape = 0; shape < polys_clipped.area_size(area); shape++ ) {
|
||||
|
@ -317,4 +282,4 @@ bool TGConstruct::ClipLandclassPolys( void ) {
|
|||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -176,7 +176,6 @@ void TGConstruct::CalcPointNormals( void )
|
|||
for ( int j = 0; j < num_faces; j++ ) {
|
||||
normal = neighbor_faces->face_normals[j];
|
||||
face_area = neighbor_faces->face_areas[j];
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "\tAdding face area " << face_area << " and normal " << normal << " to node " << node.GetPosition() );
|
||||
|
||||
normal *= face_area;
|
||||
total_area += face_area;
|
||||
|
|
|
@ -639,7 +639,7 @@ makePolygonsTP (const Line &line, double width, poly_list& polys, texparams_list
|
|||
prev_inner = cur_inner;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
|
||||
void
|
||||
makePolygonsTP (const Line &line, double width, poly_list& polys, texparams_list &tps)
|
||||
|
@ -780,7 +780,7 @@ makePolygonsTP (const Line &line, double width, poly_list& polys, texparams_list
|
|||
|
||||
sglog().setLogLevels( SG_ALL, SG_INFO );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Rectangle
|
||||
makeBounds (const TGPolygon &polygon)
|
||||
|
|
|
@ -28,12 +28,19 @@
|
|||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <limits.h>
|
||||
|
||||
#include <simgear/constants.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <Geometry/point3d.hxx>
|
||||
#include <Geometry/poly_support.hxx>
|
||||
#include <simgear/math/sg_geodesy.hxx>
|
||||
#include <simgear/math/SGVec3.hxx>
|
||||
#include <simgear/math/SGMisc.hxx>
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
#include <simgear/math/SGGeometryFwd.hxx>
|
||||
#include <simgear/math/SGBox.hxx>
|
||||
#include <simgear/math/SGIntersect.hxx>
|
||||
#include <simgear/structure/exception.hxx>
|
||||
|
||||
#include <Geometry/trinodes.hxx>
|
||||
|
@ -414,6 +421,19 @@ static Point3D MakeTGPoint( ClipperLib::IntPoint pt )
|
|||
return tg_pt;
|
||||
}
|
||||
|
||||
static SGVec3d MakeSGVec3D( ClipperLib::IntPoint pt )
|
||||
{
|
||||
SGVec3d sgvec;
|
||||
double x, y;
|
||||
|
||||
x = (double)( ((double)pt.X) / (double)FIXEDPT );
|
||||
y = (double)( ((double)pt.Y) / (double)FIXEDPT );
|
||||
|
||||
sgvec = SGVec3d( x, y, 0.0f);
|
||||
|
||||
return sgvec;
|
||||
}
|
||||
|
||||
double MakeClipperDelta( double mDelta )
|
||||
{
|
||||
double cDelta = mDelta * ( FIXEDPT / FIXED1M );
|
||||
|
@ -423,7 +443,7 @@ double MakeClipperDelta( double mDelta )
|
|||
return( cDelta );
|
||||
}
|
||||
|
||||
void make_clipper_poly( const TGPolygon& in, ClipperLib::Polygons *out )
|
||||
static void make_clipper_poly( const TGPolygon& in, ClipperLib::Polygons *out )
|
||||
{
|
||||
ClipperLib::Polygon contour;
|
||||
Point3D p;
|
||||
|
@ -456,41 +476,6 @@ void make_clipper_poly( const TGPolygon& in, ClipperLib::Polygons *out )
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
void make_tg_poly_from_clipper_ex( const ClipperLib::ExPolygons& in, TGPolygon *out )
|
||||
{
|
||||
int res_contour = 0;
|
||||
out->erase();
|
||||
|
||||
for (unsigned int i=0; i<in.size(); i++)
|
||||
{
|
||||
const struct ClipperLib::ExPolygon* pg = &in[i];
|
||||
ClipperLib::IntPoint ip;
|
||||
|
||||
// Get the boundary contour
|
||||
for (unsigned int j = 0; j < pg->outer.size(); j++)
|
||||
{
|
||||
ip = ClipperLib::IntPoint( pg->outer[j].X, pg->outer[j].Y );
|
||||
out->add_node(res_contour, MakeTGPoint(ip));
|
||||
}
|
||||
out->set_hole_flag(res_contour, 0);
|
||||
res_contour++;
|
||||
|
||||
// then the holes
|
||||
for (unsigned int j = 0; j < pg->holes.size(); j++)
|
||||
{
|
||||
for (unsigned int k = 0; k < pg->holes[j].size(); k++)
|
||||
{
|
||||
ip = ClipperLib::IntPoint( pg->holes[j].at(k).X, pg->holes[j].at(k).Y );
|
||||
out->add_node(res_contour, MakeTGPoint(ip));
|
||||
}
|
||||
out->set_hole_flag(res_contour, 1);
|
||||
res_contour++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void make_tg_poly_from_clipper( const ClipperLib::Polygons& in, TGPolygon *out )
|
||||
{
|
||||
out->erase();
|
||||
|
@ -517,40 +502,67 @@ void make_tg_poly_from_clipper( const ClipperLib::Polygons& in, TGPolygon *out )
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
ClipperLib::Polygons clipper_simplify( ClipperLib::ExPolygons &in )
|
||||
|
||||
void get_Clipper_bounding_box( const ClipperLib::Polygons& in, SGVec3d& min, SGVec3d& max )
|
||||
{
|
||||
ClipperLib::Polygons out;
|
||||
ClipperLib::Polygon contour;
|
||||
ClipperLib::IntPoint min_pt, max_pt;
|
||||
|
||||
for (unsigned int i=0; i<in.size(); i++)
|
||||
min_pt.X = min_pt.Y = LONG_LONG_MAX;
|
||||
max_pt.X = max_pt.Y = LONG_LONG_MIN;
|
||||
|
||||
// for each polygon, we need to check the orientation, to set the hole flag...
|
||||
for (unsigned int i=0; i<in.size(); i++)
|
||||
{
|
||||
const struct ClipperLib::ExPolygon* pg = &in[i];
|
||||
|
||||
// first the boundary
|
||||
contour = pg->outer;
|
||||
if ( !Orientation( contour ) ) {
|
||||
ReversePolygon( contour );
|
||||
}
|
||||
out.push_back( contour );
|
||||
|
||||
// then the holes
|
||||
for (unsigned int j = 0; j < pg->holes.size(); j++)
|
||||
for (unsigned int j = 0; j < in[i].size(); j++)
|
||||
{
|
||||
contour = pg->holes[j];
|
||||
if ( Orientation( contour ) ) {
|
||||
ReversePolygon( contour );
|
||||
if ( in[i][j].X < min_pt.X ) {
|
||||
min_pt.X = in[i][j].X;
|
||||
}
|
||||
if ( in[i][j].Y < min_pt.Y ) {
|
||||
min_pt.Y = in[i][j].Y;
|
||||
}
|
||||
|
||||
if ( in[i][j].X > max_pt.X ) {
|
||||
max_pt.X = in[i][j].X;
|
||||
}
|
||||
if ( in[i][j].Y > max_pt.Y ) {
|
||||
max_pt.Y = in[i][j].Y;
|
||||
}
|
||||
out.push_back( contour );
|
||||
}
|
||||
}
|
||||
|
||||
// Now simplify
|
||||
SimplifyPolygons(out);
|
||||
|
||||
return out;
|
||||
min = MakeSGVec3D( min_pt );
|
||||
max = MakeSGVec3D( max_pt );
|
||||
}
|
||||
|
||||
void clipper_to_shapefile( ClipperLib::Polygons polys, char* ds )
|
||||
{
|
||||
ClipperLib::Polygons contour;
|
||||
TGPolygon tgcontour;
|
||||
char layer[32];
|
||||
|
||||
void* ds_id = tgShapefileOpenDatasource( ds );
|
||||
|
||||
for (unsigned int i = 0; i < polys.size(); ++i) {
|
||||
if ( Orientation( polys[i] ) ) {
|
||||
sprintf( layer, "%04d_boundary", i );
|
||||
} else {
|
||||
sprintf( layer, "%04d_hole", i );
|
||||
}
|
||||
|
||||
void* l_id = tgShapefileOpenLayer( ds_id, layer );
|
||||
contour.clear();
|
||||
contour.push_back( polys[i] );
|
||||
|
||||
tgcontour.erase();
|
||||
make_tg_poly_from_clipper( contour, &tgcontour );
|
||||
|
||||
tgShapefileCreateFeature( ds_id, l_id, tgcontour, "contour" );
|
||||
}
|
||||
|
||||
// close after each write
|
||||
ds_id = tgShapefileCloseDatasource( ds_id );
|
||||
}
|
||||
#endif
|
||||
|
||||
TGPolygon polygon_clip_clipper( clip_op poly_op, const TGPolygon& subject, const TGPolygon& clip )
|
||||
{
|
||||
|
@ -614,7 +626,10 @@ TGPolygon tgPolygonUnion( const TGPolygon& subject, const TGPolygon& clip ) {
|
|||
|
||||
|
||||
// Accumulator optimization ( to keep from massive data copies and format changes
|
||||
ClipperLib::Polygons clipper_accumulator;
|
||||
// Start out the accumulator as a list of Polygons - so we can bounding box check
|
||||
// new additions
|
||||
typedef std::vector < ClipperLib::Polygons > ClipperPolysList;
|
||||
ClipperPolysList clipper_accumulator;
|
||||
|
||||
void tgPolygonInitClipperAccumulator( void )
|
||||
{
|
||||
|
@ -632,8 +647,10 @@ void tgPolygonDumpAccumulator( char* ds, char* layer, char* name )
|
|||
void* l_id = tgShapefileOpenLayer( ds_id, layer );
|
||||
TGPolygon accum;
|
||||
|
||||
make_tg_poly_from_clipper( clipper_accumulator, &accum );
|
||||
tgShapefileCreateFeature( ds_id, l_id, accum, name );
|
||||
for (unsigned int i=0; i<clipper_accumulator.size(); i++) {
|
||||
make_tg_poly_from_clipper( clipper_accumulator[i], &accum );
|
||||
tgShapefileCreateFeature( ds_id, l_id, accum, name );
|
||||
}
|
||||
|
||||
// close after each write
|
||||
ds_id = tgShapefileCloseDatasource( ds_id );
|
||||
|
@ -641,95 +658,57 @@ void tgPolygonDumpAccumulator( char* ds, char* layer, char* name )
|
|||
|
||||
void tgPolygonAddToClipperAccumulator( const TGPolygon& subject, bool dump )
|
||||
{
|
||||
std::ofstream subjectFile, clipFile, resultFile;
|
||||
|
||||
ClipperLib::Polygons clipper_subject;
|
||||
make_clipper_poly( subject, &clipper_subject );
|
||||
|
||||
if (dump) {
|
||||
subjectFile.open ("subject.txt");
|
||||
subjectFile << clipper_subject;
|
||||
subjectFile.close();
|
||||
|
||||
clipFile.open ("clip.txt");
|
||||
clipFile << clipper_accumulator;
|
||||
clipFile.close();
|
||||
}
|
||||
|
||||
ClipperLib::Clipper c;
|
||||
c.Clear();
|
||||
c.AddPolygons(clipper_subject, ClipperLib::ptSubject);
|
||||
c.AddPolygons(clipper_accumulator, ClipperLib::ptClip);
|
||||
|
||||
if ( !c.Execute(ClipperLib::ctUnion, clipper_accumulator, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd) ) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "Add to Accumulator returned FALSE" );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (dump) {
|
||||
resultFile.open ("result.txt");
|
||||
resultFile << clipper_accumulator;
|
||||
resultFile.close();
|
||||
}
|
||||
}
|
||||
|
||||
void clipper_to_shapefile( ClipperLib::Polygons polys, char* ds )
|
||||
{
|
||||
ClipperLib::Polygons contour;
|
||||
TGPolygon tgcontour;
|
||||
char layer[32];
|
||||
|
||||
void* ds_id = tgShapefileOpenDatasource( ds );
|
||||
|
||||
for (unsigned int i = 0; i < polys.size(); ++i) {
|
||||
if ( Orientation( polys[i] ) ) {
|
||||
sprintf( layer, "%04d_boundary", i );
|
||||
} else {
|
||||
sprintf( layer, "%04d_hole", i );
|
||||
}
|
||||
|
||||
void* l_id = tgShapefileOpenLayer( ds_id, layer );
|
||||
contour.clear();
|
||||
contour.push_back( polys[i] );
|
||||
|
||||
tgcontour.erase();
|
||||
make_tg_poly_from_clipper( contour, &tgcontour );
|
||||
|
||||
tgShapefileCreateFeature( ds_id, l_id, tgcontour, "contour" );
|
||||
}
|
||||
|
||||
// close after each write
|
||||
ds_id = tgShapefileCloseDatasource( ds_id );
|
||||
clipper_accumulator.push_back( clipper_subject );
|
||||
}
|
||||
|
||||
TGPolygon tgPolygonDiffClipperWithAccumulator( const TGPolygon& subject )
|
||||
{
|
||||
TGPolygon result;
|
||||
SGVec3d min, max, minp, maxp;
|
||||
unsigned int num_hits = 0;
|
||||
|
||||
ClipperLib::Polygons clipper_subject;
|
||||
make_clipper_poly( subject, &clipper_subject );
|
||||
|
||||
ClipperLib::Polygons clipper_result;
|
||||
|
||||
|
||||
// Start with full poly
|
||||
result = subject;
|
||||
result.get_bounding_box(minp, maxp);
|
||||
SGBoxd box1(minp, maxp);
|
||||
|
||||
ClipperLib::Clipper c;
|
||||
c.Clear();
|
||||
c.AddPolygons(clipper_subject, ClipperLib::ptSubject);
|
||||
c.AddPolygons(clipper_accumulator, ClipperLib::ptClip);
|
||||
|
||||
if ( !c.Execute(ClipperLib::ctDifference, clipper_result, ClipperLib::pftNonZero, ClipperLib::pftNonZero) )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "Diff With Accumulator returned FALSE" );
|
||||
exit(-1);
|
||||
c.AddPolygons(clipper_subject, ClipperLib::ptSubject);
|
||||
|
||||
// clip result against all polygons in the accum that intersect our bb
|
||||
for (unsigned int i=0; i < clipper_accumulator.size(); i++) {
|
||||
get_Clipper_bounding_box( clipper_accumulator[i], min, max);
|
||||
SGBoxd box2(min, max);
|
||||
|
||||
if ( intersects( box2, box1 ) )
|
||||
{
|
||||
c.AddPolygons(clipper_accumulator[i], ClipperLib::ptClip);
|
||||
num_hits++;
|
||||
}
|
||||
}
|
||||
|
||||
make_tg_poly_from_clipper( clipper_result, &result );
|
||||
if (num_hits) {
|
||||
ClipperLib::Polygons clipper_result;
|
||||
|
||||
if ( !c.Execute(ClipperLib::ctDifference, clipper_result, ClipperLib::pftNonZero, ClipperLib::pftNonZero) ) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "Diff With Accumulator returned FALSE" );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
make_tg_poly_from_clipper( clipper_result, &result );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// CLIPPER
|
||||
TGPolygon tgPolygonDiffClipper( const TGPolygon& subject, const TGPolygon& clip ) {
|
||||
return polygon_clip_clipper( POLY_DIFF, subject, clip );
|
||||
|
|
|
@ -193,8 +193,8 @@ void processLineStringWithTextureInfo(OGRLineString* poGeometry,
|
|||
double pt_x = 0.0f, pt_y = 0.0f;
|
||||
int i, j, numPoints, numSegs;
|
||||
double max_dist;
|
||||
double min_dist;
|
||||
double cur_dist;
|
||||
// double min_dist;
|
||||
// double cur_dist;
|
||||
|
||||
numPoints = poGeometry->getNumPoints();
|
||||
if (numPoints < 2) {
|
||||
|
@ -203,8 +203,8 @@ void processLineStringWithTextureInfo(OGRLineString* poGeometry,
|
|||
}
|
||||
|
||||
max_dist = (double)width * 10.0f;
|
||||
min_dist = (double)width * 1.5f;
|
||||
cur_dist = 0.0f;
|
||||
// min_dist = (double)width * 1.5f;
|
||||
// cur_dist = 0.0f;
|
||||
|
||||
// because vector data can generate adjacent polys, lets stretch the two enpoints by a little bit
|
||||
p0 = Point3D(poGeometry->getX(0),poGeometry->getY(0),0);
|
||||
|
@ -230,16 +230,16 @@ void processLineStringWithTextureInfo(OGRLineString* poGeometry,
|
|||
geo_direct_wgs_84( p0.y(), p0.x(), heading, dist*(j+1), &pt_y, &pt_x, &az2 );
|
||||
line.addPoint( Point3D( pt_x, pt_y, 0.0f ) );
|
||||
}
|
||||
cur_dist = 0.0f;
|
||||
}
|
||||
else if (dist + cur_dist < max_dist)
|
||||
{
|
||||
cur_dist += dist;
|
||||
// cur_dist = 0.0f;
|
||||
}
|
||||
// else if (dist + cur_dist < max_dist)
|
||||
// {
|
||||
// cur_dist += dist;
|
||||
// }
|
||||
else
|
||||
{
|
||||
line.addPoint( p1 );
|
||||
cur_dist = 0;
|
||||
// cur_dist = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue