1
0
Fork 0

- adding bounding box clip optimization to tgconstruct

- revert some bad ogr-decode changes that caused too angular linear data
This commit is contained in:
2012-10-13 00:18:15 -04:00
parent 5917cb62d1
commit a7b49565b3
6 changed files with 127 additions and 186 deletions

View file

@ -40,8 +40,6 @@
#include "tglandclass.hxx"
#define FIND_SLIVERS (0)
#define USE_ACCUMULATOR (1)
// Stage2 shared edge data
struct TGNeighborFaces {

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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)

View file

@ -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 );

View file

@ -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;
}
}