#include <OSD_Timer.hxx>
#endif
+#define _DEVDEBUG_
+#include "HYDRO_trace.hxx"
+
IMPLEMENT_STANDARD_HANDLE(HYDROData_Bathymetry, HYDROData_IAltitudeObject)
IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Bathymetry, HYDROData_IAltitudeObject)
+//HYDROData_QuadtreeNode* HYDROData_Bathymetry::myQuadtree = 0;
+std::map<int, HYDROData_QuadtreeNode*> HYDROData_Bathymetry::myQuadtrees;
+
HYDROData_Bathymetry::HYDROData_Bathymetry()
: HYDROData_IAltitudeObject()
{
+ //DEBTRACE("HYDROData_Bathymetry constructor start " << this);
+// if (! myQuadtree)
+// myQuadtree = new HYDROData_QuadtreeNode(0, 30, 5, 0.);
+ //DEBTRACE("HYDROData_Bathymetry constructor end " << this);
}
HYDROData_Bathymetry::~HYDROData_Bathymetry()
{
+ //DEBTRACE("HYDROData_Bathymetry destructor start " << this);
+// if (myQuadtree)
+// delete myQuadtree;
+// Nodes_3D::iterator it = myListOfNodes.begin();
+// for( ; it != myListOfNodes.end(); ++it)
+// delete *it;
+// myListOfNodes.clear();
}
QStringList HYDROData_Bathymetry::DumpToPython( const QString& thePyScriptPath,
return aPoints;
}
+HYDROData_QuadtreeNode* HYDROData_Bathymetry::GetQuadtreeNodes() const
+{
+ TDF_Label aLabel = myLab.FindChild(DataTag_AltitudePoints, false);
+ if (aLabel.IsNull())
+ return 0;
+ int labkey = myLab.Tag();
+ int altkey = aLabel.Tag();
+ //DEBTRACE("GetQuadtreeNodes this labkey altkey "<<this<<" "<<labkey<<" "<<altkey);
+// if (myQuadtree->isEmpty() )
+ if (myQuadtrees.find(labkey) == myQuadtrees.end())
+ {
+ DEBTRACE("GetQuadtreeNodes init " << this << " " << labkey);
+ HYDROData_QuadtreeNode* aQuadtree = new HYDROData_QuadtreeNode(0, 30, 5, 0.);
+ myQuadtrees[labkey] = aQuadtree;
+ TDF_Label aLabel = myLab.FindChild(DataTag_AltitudePoints, false);
+ if (aLabel.IsNull())
+ return 0;
+
+ Handle(TDataStd_RealArray) aCoordsArray;
+ if (!aLabel.FindAttribute(TDataStd_RealArray::GetID(), aCoordsArray))
+ return 0;
+
+ Nodes_3D* aListOfNodes = new Nodes_3D();
+
+ for (int i = aCoordsArray->Lower(), n = aCoordsArray->Upper(); i <= n;)
+ {
+ if (i + 3 > n + 1)
+ break;
+
+ double x = aCoordsArray->Value(i++);
+ double y = aCoordsArray->Value(i++);
+ double z = aCoordsArray->Value(i++);
+ gp_XYZ* aPoint = new gp_XYZ(x, y, z);
+ aListOfNodes->push_back(aPoint);
+ }
+ DEBTRACE(" GetQuadtreeNodes call setNodesAndCompute");
+ aQuadtree->setNodesAndCompute(aListOfNodes);
+ return aQuadtree;
+ }
+ else
+ return myQuadtrees[labkey];
+}
+
void HYDROData_Bathymetry::RemoveAltitudePoints()
{
TDF_Label aLabel = myLab.FindChild( DataTag_AltitudePoints, false );
theResPoint.SetZ( aResVal );
}
-double HYDROData_Bathymetry::GetAltitudeForPoint( const gp_XY& thePoint ) const
+double HYDROData_Bathymetry::GetAltitudeForPoint(const gp_XY& thePoint) const
{
+ DEBTRACE("GetAltitudeForPoint p(" << thePoint.X() << ", " << thePoint.Y() << ")");
double anInvalidAltitude = GetInvalidAltitude();
double aResAltitude = anInvalidAltitude;
-
- AltitudePoints anAltitudePoints = GetAltitudePoints();
- if ( anAltitudePoints.IsEmpty() )
- return aResAltitude;
-
- QPolygonF aBoundingRect;
-
- // Boundary plane
- // [ 0 (top-left) ] [ 1 (top-right) ]
- // thePoint
- // [ 2 (bot-left) ] [ 3 (bot-right) ]
- AltitudePoint aBounds[ 4 ] = { AltitudePoint( -DBL_MAX, -DBL_MAX, anInvalidAltitude ),
- AltitudePoint( DBL_MAX, -DBL_MAX, anInvalidAltitude ),
- AltitudePoint( -DBL_MAX, DBL_MAX, anInvalidAltitude ),
- AltitudePoint( DBL_MAX, DBL_MAX, anInvalidAltitude ) };
-
- AltitudePoints::Iterator anIter( anAltitudePoints );
- for ( ; anIter.More(); anIter.Next() )
- {
- const AltitudePoint& aPoint = anIter.Value();
- double aDeltaX = Abs( aPoint.X() ) - Abs( thePoint.X() );
- double aDeltaY = Abs( aPoint.Y() ) - Abs( thePoint.Y() );
+ HYDROData_QuadtreeNode* aQuadtree = GetQuadtreeNodes();
+ if (!aQuadtree)
+ {
+ DEBTRACE(" no Quadtree");
+ return aResAltitude;
+ }
- if ( ValuesEquals( aDeltaX, 0.0 ) ) // Both left and right sides
+ std::map<double, const gp_XYZ*> dist2nodes;
+ aQuadtree->NodesAround(thePoint, dist2nodes, aQuadtree->getPrecision());
+ while (dist2nodes.size() == 0)
{
- if ( ValuesEquals( aDeltaY, 0.0 ) ) // Both top and bottom sides
- {
- aResAltitude = aPoint.Z();
- return aResAltitude;
- }
- else if ( aDeltaY < 0 ) // top side
- {
- // top border
- if ( ValuesMoreEquals( aPoint.X(), aBounds[ 0 ].X() ) && ValuesMoreEquals( aPoint.Y(), aBounds[ 0 ].Y() ) )
- aBounds[ 0 ] = aPoint;
- if ( ValuesLessEquals( aPoint.X(), aBounds[ 1 ].X() ) && ValuesMoreEquals( aPoint.Y(), aBounds[ 1 ].Y() ) )
- aBounds[ 1 ] = aPoint;
- }
- else
- {
- // bottom border
- if ( ValuesMoreEquals( aPoint.X(), aBounds[ 2 ].X() ) && ValuesLessEquals( aPoint.Y(), aBounds[ 2 ].Y() ) )
- aBounds[ 2 ] = aPoint;
- if ( ValuesLessEquals( aPoint.X(), aBounds[ 3 ].X() ) && ValuesLessEquals( aPoint.Y(), aBounds[ 3 ].Y() ) )
- aBounds[ 3 ] = aPoint;
- }
+ aQuadtree->setPrecision(aQuadtree->getPrecision() *2);
+ DEBTRACE("adjust precision to: " << aQuadtree->getPrecision());
+ aQuadtree->NodesAround(thePoint, dist2nodes, aQuadtree->getPrecision());
}
- else if ( aDeltaX < 0 ) // left side
+ aQuadtree->NodesAround(thePoint, dist2nodes, 5.0);
+ if (dist2nodes.size())
{
- if ( ValuesEquals( aDeltaY, 0.0 ) )
- {
- // Left border
- if ( ValuesMoreEquals( aPoint.X(), aBounds[ 0 ].X() ) && ValuesMoreEquals( aPoint.Y(), aBounds[ 0 ].Y() ) )
- aBounds[ 0 ] = aPoint;
- if ( ValuesMoreEquals( aPoint.X(), aBounds[ 2 ].X() ) && ValuesLessEquals( aPoint.Y(), aBounds[ 2 ].Y() ) )
- aBounds[ 2 ] = aPoint;
- }
- else if ( aDeltaY < 0 )
- {
- // top left corner
- if ( ValuesMoreEquals( aPoint.X(), aBounds[ 0 ].X() ) && ValuesMoreEquals( aPoint.Y(), aBounds[ 0 ].Y() ) )
- aBounds[ 0 ] = aPoint;
- }
- else
- {
- // bottom left corner
- if ( ValuesMoreEquals( aPoint.X(), aBounds[ 2 ].X() ) && ValuesLessEquals( aPoint.Y(), aBounds[ 2 ].Y() ) )
- aBounds[ 2 ] = aPoint;
- }
+ std::map<double, const gp_XYZ*>::const_iterator it = dist2nodes.begin();
+ aResAltitude = it->second->Z();
+ DEBTRACE(" number of points found: " << dist2nodes.size() << " nearest z: " << aResAltitude);
}
- else // right side
+ else
{
- if ( ValuesEquals( aDeltaY, 0.0 ) )
- {
- // Right border
- if ( ValuesLessEquals( aPoint.X(), aBounds[ 1 ].X() ) && ValuesMoreEquals( aPoint.Y(), aBounds[ 1 ].Y() ) )
- aBounds[ 1 ] = aPoint;
- if ( ValuesLessEquals( aPoint.X(), aBounds[ 3 ].X() ) && ValuesLessEquals( aPoint.Y(), aBounds[ 3 ].Y() ) )
- aBounds[ 3 ] = aPoint;
- }
- else if ( aDeltaY < 0 )
- {
- // top right corner
- if ( ValuesLessEquals( aPoint.X(), aBounds[ 1 ].X() ) && ValuesMoreEquals( aPoint.Y(), aBounds[ 1 ].Y() ) )
- aBounds[ 1 ] = aPoint;
- }
- else
- {
- // bottom right corner
- if ( ValuesLessEquals( aPoint.X(), aBounds[ 3 ].X() ) && ValuesLessEquals( aPoint.Y(), aBounds[ 3 ].Y() ) )
- aBounds[ 3 ] = aPoint;
- }
+ DEBTRACE(" number of points found: 0");
}
- // Update bounding rectangle of our global grid
- aBoundingRect << QPointF( aPoint.X(), aPoint.Y() );
- }
-
- const double LIMIT = 1E300;
- if( fabs( aBounds[ 0 ].X() ) > LIMIT || fabs( aBounds[ 0 ].Y() ) > LIMIT ||
- fabs( aBounds[ 1 ].X() ) > LIMIT || fabs( aBounds[ 1 ].Y() ) > LIMIT ||
- fabs( aBounds[ 2 ].X() ) > LIMIT || fabs( aBounds[ 2 ].Y() ) > LIMIT ||
- fabs( aBounds[ 3 ].X() ) > LIMIT || fabs( aBounds[ 3 ].Y() ) > LIMIT )
- return anInvalidAltitude;
-
-
- // Check if requested point is inside of our bounding rectangle
- if ( !aBoundingRect.boundingRect().contains( thePoint.X(), thePoint.Y() ) )
- return aResAltitude;
-
- // Calculate result altitude for point
- AltitudePoint aFirstPoint( aBounds[ 0 ] ), aSecPoint( aBounds[ 1 ] );
-
- // At first we merge top and bottom borders
- if ( aBounds[ 0 ].Y() != aBounds[ 2 ].Y() || aBounds[ 0 ].X() != aBounds[ 2 ].X() )
- interpolateAltitudeForPoints( thePoint, aBounds[ 0 ], aBounds[ 2 ], aFirstPoint, true );
-
- if ( aBounds[ 1 ].Y() != aBounds[ 3 ].Y() || aBounds[ 1 ].X() != aBounds[ 3 ].X() )
- interpolateAltitudeForPoints( thePoint, aBounds[ 1 ], aBounds[ 3 ], aSecPoint, true );
-
- AltitudePoint aResPoint( aFirstPoint );
-
- // At last we merge left and right borders
- if ( aFirstPoint.Y() != aSecPoint.Y() || aFirstPoint.X() != aSecPoint.X() )
- interpolateAltitudeForPoints( thePoint, aFirstPoint, aSecPoint, aResPoint, false );
-
- aResAltitude = aResPoint.Z();
-
return aResAltitude;
+
+
+// AltitudePoints anAltitudePoints = GetAltitudePoints();
+// if ( anAltitudePoints.IsEmpty() )
+// return aResAltitude;
+//
+// QPolygonF aBoundingRect;
+//
+// // Boundary plane
+// // [ 0 (top-left) ] [ 1 (top-right) ]
+// // thePoint
+// // [ 2 (bot-left) ] [ 3 (bot-right) ]
+// AltitudePoint aBounds[ 4 ] = { AltitudePoint( -DBL_MAX, -DBL_MAX, anInvalidAltitude ),
+// AltitudePoint( DBL_MAX, -DBL_MAX, anInvalidAltitude ),
+// AltitudePoint( -DBL_MAX, DBL_MAX, anInvalidAltitude ),
+// AltitudePoint( DBL_MAX, DBL_MAX, anInvalidAltitude ) };
+//
+// AltitudePoints::Iterator anIter( anAltitudePoints );
+// for ( ; anIter.More(); anIter.Next() )
+// {
+// const AltitudePoint& aPoint = anIter.Value();
+//
+// double aDeltaX = Abs( aPoint.X() ) - Abs( thePoint.X() );
+// double aDeltaY = Abs( aPoint.Y() ) - Abs( thePoint.Y() );
+//
+// if ( ValuesEquals( aDeltaX, 0.0 ) ) // Both left and right sides
+// {
+// if ( ValuesEquals( aDeltaY, 0.0 ) ) // Both top and bottom sides
+// {
+// aResAltitude = aPoint.Z();
+// return aResAltitude;
+// }
+// else if ( aDeltaY < 0 ) // top side
+// {
+// // top border
+// if ( ValuesMoreEquals( aPoint.X(), aBounds[ 0 ].X() ) && ValuesMoreEquals( aPoint.Y(), aBounds[ 0 ].Y() ) )
+// aBounds[ 0 ] = aPoint;
+// if ( ValuesLessEquals( aPoint.X(), aBounds[ 1 ].X() ) && ValuesMoreEquals( aPoint.Y(), aBounds[ 1 ].Y() ) )
+// aBounds[ 1 ] = aPoint;
+// }
+// else
+// {
+// // bottom border
+// if ( ValuesMoreEquals( aPoint.X(), aBounds[ 2 ].X() ) && ValuesLessEquals( aPoint.Y(), aBounds[ 2 ].Y() ) )
+// aBounds[ 2 ] = aPoint;
+// if ( ValuesLessEquals( aPoint.X(), aBounds[ 3 ].X() ) && ValuesLessEquals( aPoint.Y(), aBounds[ 3 ].Y() ) )
+// aBounds[ 3 ] = aPoint;
+// }
+// }
+// else if ( aDeltaX < 0 ) // left side
+// {
+// if ( ValuesEquals( aDeltaY, 0.0 ) )
+// {
+// // Left border
+// if ( ValuesMoreEquals( aPoint.X(), aBounds[ 0 ].X() ) && ValuesMoreEquals( aPoint.Y(), aBounds[ 0 ].Y() ) )
+// aBounds[ 0 ] = aPoint;
+// if ( ValuesMoreEquals( aPoint.X(), aBounds[ 2 ].X() ) && ValuesLessEquals( aPoint.Y(), aBounds[ 2 ].Y() ) )
+// aBounds[ 2 ] = aPoint;
+// }
+// else if ( aDeltaY < 0 )
+// {
+// // top left corner
+// if ( ValuesMoreEquals( aPoint.X(), aBounds[ 0 ].X() ) && ValuesMoreEquals( aPoint.Y(), aBounds[ 0 ].Y() ) )
+// aBounds[ 0 ] = aPoint;
+// }
+// else
+// {
+// // bottom left corner
+// if ( ValuesMoreEquals( aPoint.X(), aBounds[ 2 ].X() ) && ValuesLessEquals( aPoint.Y(), aBounds[ 2 ].Y() ) )
+// aBounds[ 2 ] = aPoint;
+// }
+// }
+// else // right side
+// {
+// if ( ValuesEquals( aDeltaY, 0.0 ) )
+// {
+// // Right border
+// if ( ValuesLessEquals( aPoint.X(), aBounds[ 1 ].X() ) && ValuesMoreEquals( aPoint.Y(), aBounds[ 1 ].Y() ) )
+// aBounds[ 1 ] = aPoint;
+// if ( ValuesLessEquals( aPoint.X(), aBounds[ 3 ].X() ) && ValuesLessEquals( aPoint.Y(), aBounds[ 3 ].Y() ) )
+// aBounds[ 3 ] = aPoint;
+// }
+// else if ( aDeltaY < 0 )
+// {
+// // top right corner
+// if ( ValuesLessEquals( aPoint.X(), aBounds[ 1 ].X() ) && ValuesMoreEquals( aPoint.Y(), aBounds[ 1 ].Y() ) )
+// aBounds[ 1 ] = aPoint;
+// }
+// else
+// {
+// // bottom right corner
+// if ( ValuesLessEquals( aPoint.X(), aBounds[ 3 ].X() ) && ValuesLessEquals( aPoint.Y(), aBounds[ 3 ].Y() ) )
+// aBounds[ 3 ] = aPoint;
+// }
+// }
+//
+// // Update bounding rectangle of our global grid
+// aBoundingRect << QPointF( aPoint.X(), aPoint.Y() );
+// }
+//
+// const double LIMIT = 1E300;
+// if( fabs( aBounds[ 0 ].X() ) > LIMIT || fabs( aBounds[ 0 ].Y() ) > LIMIT ||
+// fabs( aBounds[ 1 ].X() ) > LIMIT || fabs( aBounds[ 1 ].Y() ) > LIMIT ||
+// fabs( aBounds[ 2 ].X() ) > LIMIT || fabs( aBounds[ 2 ].Y() ) > LIMIT ||
+// fabs( aBounds[ 3 ].X() ) > LIMIT || fabs( aBounds[ 3 ].Y() ) > LIMIT )
+// return anInvalidAltitude;
+//
+//
+// // Check if requested point is inside of our bounding rectangle
+// if ( !aBoundingRect.boundingRect().contains( thePoint.X(), thePoint.Y() ) )
+// return aResAltitude;
+//
+// // Calculate result altitude for point
+// AltitudePoint aFirstPoint( aBounds[ 0 ] ), aSecPoint( aBounds[ 1 ] );
+//
+// // At first we merge top and bottom borders
+// if ( aBounds[ 0 ].Y() != aBounds[ 2 ].Y() || aBounds[ 0 ].X() != aBounds[ 2 ].X() )
+// interpolateAltitudeForPoints( thePoint, aBounds[ 0 ], aBounds[ 2 ], aFirstPoint, true );
+//
+// if ( aBounds[ 1 ].Y() != aBounds[ 3 ].Y() || aBounds[ 1 ].X() != aBounds[ 3 ].X() )
+// interpolateAltitudeForPoints( thePoint, aBounds[ 1 ], aBounds[ 3 ], aSecPoint, true );
+//
+// AltitudePoint aResPoint( aFirstPoint );
+//
+// // At last we merge left and right borders
+// if ( aFirstPoint.Y() != aSecPoint.Y() || aFirstPoint.X() != aSecPoint.X() )
+// interpolateAltitudeForPoints( thePoint, aFirstPoint, aSecPoint, aResPoint, false );
+//
+// aResAltitude = aResPoint.Z();
+//
+// return aResAltitude;
}
void HYDROData_Bathymetry::SetFilePath( const TCollection_AsciiString& theFilePath )