Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
+801
@@ -0,0 +1,801 @@
|
||||
|
||||
/*
|
||||
** -----------------------------------------------------------------------------------------------
|
||||
**
|
||||
** @RDE_HEADER@
|
||||
** Implementation of fan of sight
|
||||
** $Id$
|
||||
** $HeadURL : svn ://192.168.133.21/TDS/branches/product/devel/trunk/Lts/Viewer/SituationMap/Rubberbands/rubberband.cpp $
|
||||
** $Author : ehrlicher $
|
||||
**
|
||||
** -----------------------------------------------------------------------------------------------
|
||||
**
|
||||
** Hardware - Environment : Intel - PC
|
||||
** Software - Environment : Windows 7, Qt 5.x.ArcGISRuntimeQt 100.2
|
||||
**
|
||||
** Language ........ : C++ 11
|
||||
**
|
||||
** -----------------------------------------------------------------------------------------------
|
||||
**
|
||||
** Autor ........... : Nikolaus Hanekamp, SEDG, Tel. 2906
|
||||
** Jörg Turla, SPDG, Tel. 3132
|
||||
**
|
||||
** -----------------------------------------------------------------------------------------------
|
||||
**
|
||||
** Notices ......... :
|
||||
**
|
||||
** 01.02.2005, NH : Urversion
|
||||
** 15.05.2018, JT : adapting GeISiR source to SituationMap
|
||||
**
|
||||
** -----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "sight_fan_impl.h"
|
||||
|
||||
#include <GraphicalObjects/graphical_object_path.h>
|
||||
|
||||
#include <Map/bounding_box.h>
|
||||
#include <Map/coord_translation_functor.h>
|
||||
|
||||
#include <MapImpl/layer_factory_impl.h>
|
||||
#include <MapImpl/map_impl.h>
|
||||
#include <ElevationMap/elevation_map_manager.h>
|
||||
|
||||
#include <MathUtils/math_const.h>
|
||||
|
||||
#include <arcgis/Surface.h>
|
||||
|
||||
#include <QtCore/QSharedPointer>
|
||||
#include <QtCore/QVector>
|
||||
#include <QTimer>
|
||||
#include <chrono>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
// class SightFanImpl::Internal;
|
||||
|
||||
|
||||
enum SightMode { VISIBLE = 0, INVISIBLE, UNDEFINED, START };
|
||||
|
||||
|
||||
class SightEntry
|
||||
{
|
||||
public:
|
||||
|
||||
SightEntry() : _dist(0.0), _mode(START) {;}
|
||||
SightEntry(double dist, SightMode mode) : _dist(dist), _mode(mode) {;}
|
||||
|
||||
~SightEntry() = default;
|
||||
|
||||
double & dist() { return _dist; }
|
||||
SightMode & mode() { return _mode; }
|
||||
|
||||
double dist() const { return _dist; }
|
||||
SightMode mode() const { return _mode; }
|
||||
|
||||
private:
|
||||
|
||||
double _dist;
|
||||
SightMode _mode;
|
||||
|
||||
}; // SightEntry
|
||||
|
||||
|
||||
|
||||
class SightBeam : public Referenced
|
||||
{
|
||||
public:
|
||||
|
||||
explicit SightBeam(int beamId, const QPointF &directionB, const QPointF &directionE)
|
||||
: _beamId(beamId)
|
||||
, _directionBeg(directionB)
|
||||
, _directionEnd(directionE)
|
||||
, _sightEntryVec()
|
||||
, _graphicalQuadVec() {;}
|
||||
|
||||
SightBeam() = delete;
|
||||
~SightBeam() = default;
|
||||
|
||||
QPointF direction() const
|
||||
{
|
||||
auto normalize = [](const QPointF &v) -> QPointF
|
||||
{
|
||||
double l = sqrt(v.x()*v.x() + v.y()*v.y());
|
||||
return v / l;
|
||||
};
|
||||
|
||||
return normalize(QPointF((_directionBeg + _directionEnd)*0.5));
|
||||
} // QPointF direction()
|
||||
|
||||
|
||||
void add(const SightEntry &sightE)
|
||||
{
|
||||
_sightEntryVec.push_back(sightE);
|
||||
} // void add( const SightEntry &sightE)
|
||||
|
||||
void clear() { _sightEntryVec.clear(); }
|
||||
|
||||
// void draw(const QPointF &beamCenter, osg::Matrixd mat, QColor colors[]); // todo: Farbtabelle
|
||||
|
||||
void updateGraphic( MapImpl *mapImpl, AbstractMapObjectImpl *meMapObj, SightFanImpl::Internal * sightFanInternal );
|
||||
|
||||
int _beamId;
|
||||
|
||||
protected:
|
||||
|
||||
QPointF _directionBeg; // Einheitsvektoren die den Beam begrenzen
|
||||
QPointF _directionEnd;
|
||||
|
||||
using SightEntryVec = QVector<SightEntry>;
|
||||
|
||||
SightEntryVec _sightEntryVec;
|
||||
|
||||
QVector<QSharedPointer<GraphicalObjectPath>> _graphicalQuadVec;
|
||||
|
||||
}; /* SightBeam */
|
||||
|
||||
|
||||
class SightFanImpl::Internal
|
||||
{
|
||||
public:
|
||||
|
||||
using SightBeamVec = std::vector<RefPointer<SightBeam>> ;
|
||||
|
||||
QString m_layerName;
|
||||
std::shared_ptr<ElevationMapManager> m_eMapManager;
|
||||
QPointF m_center;
|
||||
double m_centHat;
|
||||
double m_objHat;
|
||||
double m_radius;
|
||||
double m_innerRadius;
|
||||
double m_startAngle;
|
||||
double m_dAngle;
|
||||
unsigned int m_nrFans;
|
||||
|
||||
double m_alpha;
|
||||
|
||||
QRectF m_location; // Lage des SightFans in Kartenkoordinaten
|
||||
|
||||
SightBeamVec m_sightBeamVec;
|
||||
|
||||
QColor m_colors[3]; // 0 : visibleCol, 1 : invisibleCol, 2 : undefinedCol
|
||||
|
||||
QColor m_fanColorVec[2][4];
|
||||
|
||||
float m_fanMult; // Farbabsenkung jedes 2. Beams < 1.0 !
|
||||
|
||||
MapImpl *m_mapImpl;
|
||||
Esri::ArcGISRuntime::Surface *m_surface;
|
||||
|
||||
LOGGER_T m_logger; ///< Interface of the Logging-Facility
|
||||
|
||||
Internal()
|
||||
: m_layerName()
|
||||
, m_center()
|
||||
, m_centHat(1.8)
|
||||
, m_objHat(0.5)
|
||||
, m_radius(0.0)
|
||||
, m_innerRadius(0.0)
|
||||
, m_startAngle(0.0)
|
||||
, m_dAngle(2.0*MathConst::pi/180)
|
||||
, m_nrFans(180)
|
||||
, m_alpha(0.8)
|
||||
, m_fanMult(0.75)
|
||||
, m_mapImpl(nullptr)
|
||||
, m_surface(nullptr)
|
||||
, m_logger(getLogger("SightFanImpl"))
|
||||
{;}
|
||||
|
||||
|
||||
void setFanColorMap( double brightness, double bias, double alpha)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
double r = (m_colors[i].redF() * brightness) + bias;
|
||||
double g = (m_colors[i].greenF() * brightness) + bias;
|
||||
double b = (m_colors[i].blueF() * brightness) + bias;
|
||||
double a = m_colors[i].alphaF() * alpha;
|
||||
|
||||
m_fanColorVec[0][i] = QColor::fromRgbF(r,g,b,a);
|
||||
m_fanColorVec[1][i] = QColor::fromRgbF(r*m_fanMult,g*m_fanMult,b*m_fanMult,a);
|
||||
|
||||
}
|
||||
m_fanColorVec[0][3] = m_fanColorVec[0][2];
|
||||
m_fanColorVec[1][3] = m_fanColorVec[1][2];
|
||||
} // void setFanColorMap()
|
||||
|
||||
|
||||
}; // SightFanImpl::Internal
|
||||
|
||||
|
||||
SightFanImpl::SightFanImpl( const QString &debugInfo )
|
||||
: SightFan()
|
||||
, QObject()
|
||||
, AbstractMapObjectImpl(debugInfo)
|
||||
, m_internal(new Internal())
|
||||
, m_moveDelayTimer(new QTimer(this))
|
||||
|
||||
{
|
||||
initColors();
|
||||
m_internal->setFanColorMap(1, 0, 1);
|
||||
m_moveDelayTimer->setSingleShot(true);
|
||||
m_moveDelayTimer->setInterval(250ms);
|
||||
connect(m_moveDelayTimer, &QTimer::timeout, this, &SightFanImpl::delayedMove);
|
||||
} // SightFanImpl::SightFanImpl
|
||||
|
||||
|
||||
SightFanImpl::~SightFanImpl()
|
||||
{
|
||||
delete m_internal;
|
||||
} // SightFanImpl::~SightFanImpl()
|
||||
|
||||
|
||||
void SightFanImpl::initColors()
|
||||
{
|
||||
m_internal->m_fanMult = 0.75;
|
||||
m_internal->m_colors[0] = QColor(0, 255, 0, 180);
|
||||
m_internal->m_colors[1] = QColor(255, 0, 0, 180);
|
||||
m_internal->m_colors[2] = QColor(0, 0, 255, 180);
|
||||
} // void SightFanImpl::initColors()
|
||||
|
||||
|
||||
void SightFanImpl::setFanColor( const QColor &visible, const QColor &invisible, const QColor &undefined)
|
||||
{
|
||||
m_internal->m_colors[0] = visible;
|
||||
m_internal->m_colors[1] = invisible;
|
||||
m_internal->m_colors[2] = undefined;
|
||||
} // void SightFanImpl::setFanColor( const QColor &visible, const QColor &invisible, const QColor &undefined)
|
||||
|
||||
|
||||
void SightFanImpl::setFanColorMark( float colMult)
|
||||
{
|
||||
if( colMult > 1.0)
|
||||
colMult = 1.0;
|
||||
if( colMult < 0.0)
|
||||
colMult = 0.0;
|
||||
|
||||
m_internal->m_fanMult = colMult;
|
||||
} // void SightFanImpl::setFanColorMark( float colMult)
|
||||
|
||||
|
||||
void SightFanImpl::setCenter(const QPointF ¢er) { m_internal->m_center = center; }
|
||||
void SightFanImpl::setCenter(const Point3D ¢er) { m_internal->m_center = center.toPointF();
|
||||
m_internal->m_centHat = center.z(); }
|
||||
|
||||
void SightFanImpl::setCenter(const QPointF ¢er, double centerHat) { m_internal->m_center = center;
|
||||
m_internal->m_centHat = centerHat; }
|
||||
|
||||
void SightFanImpl::setCenterHat(double centerHat) { m_internal->m_centHat = centerHat; }
|
||||
void SightFanImpl::setObjectHat(double objHat) { m_internal->m_objHat = objHat; }
|
||||
|
||||
void SightFanImpl::setRadius(double radius) { m_internal->m_radius = radius; }
|
||||
void SightFanImpl::setInnerRadius(double radius) { m_internal->m_innerRadius = radius; }
|
||||
void SightFanImpl::setStartAngle(double startAngle) { m_internal->m_startAngle = startAngle; }
|
||||
void SightFanImpl::setdeltaAngle(double dAngle) { m_internal->m_dAngle = dAngle; }
|
||||
void SightFanImpl::setNoOfFans(double noFans) { m_internal->m_nrFans = noFans; }
|
||||
|
||||
|
||||
void SightFanImpl::setAlpha(double alpha)
|
||||
{
|
||||
if (alpha < 0.0) alpha = 0.0;
|
||||
if (alpha > 1.0) alpha = 1.0;
|
||||
|
||||
m_internal->m_alpha = alpha;
|
||||
} // void SightFanImpl::setAlpha(double alpha)
|
||||
|
||||
|
||||
QPointF SightFanImpl::center() const { return m_internal->m_center; }
|
||||
double SightFanImpl::centerHat() const { return m_internal->m_centHat; }
|
||||
double SightFanImpl::objectHat() const { return m_internal->m_objHat; }
|
||||
double SightFanImpl::innerRadius() const { return m_internal->m_innerRadius; }
|
||||
double SightFanImpl::radius() const { return m_internal->m_radius; }
|
||||
double SightFanImpl::startAngle() const { return m_internal->m_startAngle; }
|
||||
double SightFanImpl::dAngle() const { return m_internal->m_dAngle; }
|
||||
double SightFanImpl::alpha() const { return m_internal->m_alpha; }
|
||||
unsigned int SightFanImpl::noOfFans() const { return m_internal->m_nrFans; }
|
||||
|
||||
bool SightFanImpl::init(MapImpl *mapImpl, const QString &logicalLayerName)
|
||||
{
|
||||
if (mapImpl)
|
||||
{
|
||||
m_internal->m_mapImpl = mapImpl;
|
||||
m_internal->m_layerName = logicalLayerName;
|
||||
m_internal->m_eMapManager = mapImpl->getElevationMapManager();
|
||||
|
||||
if (!m_internal->m_eMapManager)
|
||||
{
|
||||
ERROR_LOG(m_internal->m_logger) << LOGFUNCTION << " failure, no ElevationMapManager";
|
||||
return false;
|
||||
}
|
||||
if (!AbstractMapObjectImpl::init(mapImpl, logicalLayerName))
|
||||
{
|
||||
ERROR_LOG(m_internal->m_logger) << LOGFUNCTION << " failure, AbstractMapObjectImpl::init failed";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
ERROR_LOG(m_internal->m_logger) << LOGFUNCTION << " init SightFanImpl failed";
|
||||
return false;
|
||||
} // bool SightFanImpl::init(MapImpl *mapImpl, const QString &logicalLayerName)
|
||||
|
||||
|
||||
void SightFanImpl::boundingBox(BoundingBox &bbox) const
|
||||
{
|
||||
bbox.reset();
|
||||
|
||||
CoordTranslationFunctor * coordTransFunc = m_internal->m_mapImpl->coordTranslationFunctor();
|
||||
|
||||
if (coordTransFunc)
|
||||
{
|
||||
const QPointF ¢erMap = coordTransFunc->geographicToMap(m_internal->m_center);
|
||||
double diameter = 2 * m_internal->m_radius;
|
||||
|
||||
bbox = BoundingBox( BoundingBox::ExtentType::Sim, Point3D::fromQPointF(centerMap), diameter, diameter );
|
||||
}
|
||||
} // void SightFanImpl::boundingBox(BoundingBox &bbox) const
|
||||
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
|
||||
void SightFanImpl::initFan( const Point3D ¢er
|
||||
, double objHat
|
||||
, double radius
|
||||
, double innerRadius
|
||||
, double startAngle
|
||||
, double dAngle
|
||||
, unsigned int nrFans
|
||||
, double alpha )
|
||||
{
|
||||
initFan( center.toPointF(), center.z(), objHat, radius, innerRadius, startAngle, dAngle, nrFans, alpha );
|
||||
} // void SightFanImpl::init(...)
|
||||
|
||||
|
||||
void SightFanImpl::initFan( const QPointF ¢er
|
||||
, double centHat
|
||||
, double objHat
|
||||
, double radius
|
||||
, double innerRadius
|
||||
, double startAngle
|
||||
, double dAngle
|
||||
, unsigned int nrFans
|
||||
, double alpha )
|
||||
{
|
||||
if (!m_internal->m_mapImpl)
|
||||
{
|
||||
ERROR_LOG(m_internal->m_logger) << LOGFUNCTION << " no mapImpl";
|
||||
return;
|
||||
}
|
||||
|
||||
if (alpha < 0.0) alpha = 0.0;
|
||||
if (alpha > 1.0) alpha = 1.0;
|
||||
|
||||
m_internal->m_center = center;
|
||||
m_internal->m_centHat = centHat;
|
||||
m_internal->m_objHat = objHat;
|
||||
m_internal->m_radius = radius;
|
||||
m_internal->m_innerRadius = innerRadius;
|
||||
m_internal->m_startAngle = startAngle;
|
||||
m_internal->m_dAngle = (dAngle < 0) ? -dAngle : dAngle;
|
||||
m_internal->m_nrFans = nrFans;
|
||||
m_internal->m_alpha = alpha;
|
||||
|
||||
QPointF offc(m_internal->m_radius, -m_internal->m_radius);
|
||||
m_internal->m_location = QRectF(m_internal->m_center - offc, m_internal->m_center + offc);
|
||||
|
||||
if ((m_internal->m_nrFans*m_internal->m_dAngle) > (MathConst::pi*2.0))
|
||||
{
|
||||
m_internal->m_nrFans = floor((MathConst::pi*2.0) / m_internal->m_dAngle + 0.5); // To avoid error with floor; 30.3.2006 JT
|
||||
}
|
||||
|
||||
calculateSightBeamVec();
|
||||
|
||||
} /* SightFan::SightFan */
|
||||
|
||||
|
||||
void SightFanImpl::calculateSightBeamVec()
|
||||
{
|
||||
m_internal->m_sightBeamVec.clear();
|
||||
|
||||
double dAlfa = (m_internal->m_dAngle / 2.0) + 0.00025; // 0.00025 wegen Überlappung, auf antialiazed Systemen nicht nötig
|
||||
|
||||
for (unsigned int i = 0; i < m_internal->m_nrFans; i++)
|
||||
{
|
||||
double alfa = m_internal->m_startAngle + m_internal->m_dAngle * i;
|
||||
double alfaBeg = alfa - dAlfa;
|
||||
double alfaEnd = alfa + dAlfa;
|
||||
|
||||
RefPointer<SightBeam> sBeam = RefPointer<SightBeam>(new SightBeam(i, QPointF(cos(alfaBeg), sin(alfaBeg)), QPointF(cos(alfaEnd), sin(alfaEnd))));
|
||||
calculateSightBeam(*(sBeam.get()));
|
||||
m_internal->m_sightBeamVec.push_back(sBeam);
|
||||
}
|
||||
} // void SightFanImpl::calculateSightBeamVev()
|
||||
|
||||
|
||||
void SightFanImpl::move(const QPointF ¢er, double centHat, double objHat)
|
||||
{
|
||||
|
||||
m_internal->m_centHat = centHat;
|
||||
m_internal->m_objHat = objHat;
|
||||
move(center);
|
||||
} // void SightFanImpl::move(ElevationMap &eMap, QPointF ¢er, double centHat, double objHat)
|
||||
|
||||
|
||||
void SightFanImpl::move(const QPointF & center)
|
||||
{
|
||||
m_moveDelayedCenter = center;
|
||||
m_moveDelayTimer->start();
|
||||
|
||||
}
|
||||
|
||||
void SightFanImpl::show()
|
||||
{
|
||||
move( m_internal->m_center );
|
||||
} // void SightFanImpl::show
|
||||
|
||||
|
||||
bool SightFanImpl::updateViewImplPre()
|
||||
{
|
||||
return true;
|
||||
} // bool SightFanImpl::updateViewImplPre()
|
||||
|
||||
|
||||
bool SightFanImpl::updateViewImpl()
|
||||
{
|
||||
show();
|
||||
return true;
|
||||
} // bool SightFanImpl::updateViewImpl()
|
||||
|
||||
|
||||
bool SightFanImpl::updateViewImplPost()
|
||||
{
|
||||
return true;
|
||||
} // bool SightFanImpl::updateViewImplPost()
|
||||
|
||||
|
||||
inline QPointF mittelBreitenRechnung(const QPointF &start, const QPointF &direction, double distance)
|
||||
{
|
||||
// ---------------------------------------------------------------
|
||||
// Vec2d mittelBreitenRechnung( Vec2d start, Vec2d direction, double distance )
|
||||
|
||||
// Berechnet näherungsweise die Koordinate der Endposition eines
|
||||
// Beams gemäß der ersten Aufgabe der Besteckrechnung durch das
|
||||
// Verfahren der Mittelbreite.
|
||||
// Siehe http://astrosail.de/de/static/tutorial/best3.php?cat=42
|
||||
|
||||
// Start ist die Anfangskoordinate im Bogenmaß, direction der
|
||||
// normierte Richtungsvektor, distance die Entfernung in Metern.
|
||||
// ---------------------------------------------------------------
|
||||
double cosKurs = direction.y();
|
||||
double sinKurs = direction.x();
|
||||
double distanceBogen = distance / MathConst::EarthRadius;
|
||||
double lat = distanceBogen * cosKurs + start.y();
|
||||
double mittelbreite = (start.y() + lat) * 0.5;
|
||||
double lon = distanceBogen * sinKurs / cos(mittelbreite) + start.x();
|
||||
return {lon, lat};
|
||||
}
|
||||
|
||||
inline QPointF endOfBeam( const QPointF &start, const QPointF &direction, double distance )
|
||||
{
|
||||
return mittelBreitenRechnung(start,direction,distance);
|
||||
}
|
||||
|
||||
|
||||
void SightFanImpl::calculateSightBeam(SightBeam &sBeam)
|
||||
{
|
||||
const QPointF &direction = sBeam.direction();
|
||||
const QPointF &end = endOfBeam(m_internal->m_center, direction, m_internal->m_radius);
|
||||
|
||||
LOSVector losProfile;
|
||||
m_internal->m_eMapManager->LOSProfile(m_internal->m_center, end, losProfile);
|
||||
calculateSightBeam(losProfile, sBeam);
|
||||
sBeam.updateGraphic(m_internal->m_mapImpl, this, m_internal);
|
||||
} // void SightFanImpl::calculateSightBeam(ElevationMap &eMap, SightBeam &sBeam)
|
||||
|
||||
|
||||
void SightFanImpl::calculateSightBeam( const LOSVector &losProfile, SightBeam &sBeam )
|
||||
{
|
||||
sBeam.clear();
|
||||
|
||||
if (losProfile.empty()) // Startpunkt undefiniert oder ausserhalb der Karte
|
||||
{
|
||||
sBeam.add( SightEntry(m_internal->m_innerRadius, START) );
|
||||
sBeam.add( SightEntry(m_internal->m_radius, UNDEFINED) );
|
||||
return;
|
||||
}
|
||||
|
||||
LOSVector::const_iterator itr = losProfile.begin();
|
||||
double centerHeight = itr->height() + m_internal->m_centHat;
|
||||
|
||||
double d1 = 0.0;
|
||||
double height1 = itr->height();
|
||||
|
||||
// überspringen bis _innerRadius erreicht ist !
|
||||
while(++itr != losProfile.end())
|
||||
{
|
||||
double d2 = itr->dist(); // *EarthRadius;
|
||||
double height2 = itr->height();
|
||||
if (d2 >= m_internal->m_innerRadius)
|
||||
{
|
||||
height1 = height1 + (m_internal->m_innerRadius - d1) * ( height2 - height1)/(d2 - d1);
|
||||
d1 = m_internal->m_innerRadius;
|
||||
--itr;
|
||||
break;
|
||||
}
|
||||
d1 = d2;
|
||||
height1 = height2;
|
||||
}
|
||||
|
||||
// bool visible = true;
|
||||
SightMode mode = START;
|
||||
|
||||
double curM = (height1 - centerHeight ) / d1; // bestimmende Steigung
|
||||
|
||||
sBeam.add(SightEntry( d1, START));
|
||||
|
||||
if (itr != losProfile.end())
|
||||
{
|
||||
while (++itr != losProfile.end())
|
||||
{
|
||||
double d2 = itr->dist(); // *EarthRadius;
|
||||
double height2 = itr->height();
|
||||
|
||||
if (std::isnan(height2)) // Undefined
|
||||
{
|
||||
if (mode != START)
|
||||
{
|
||||
sBeam.add(SightEntry(d1, mode));
|
||||
}
|
||||
mode = UNDEFINED;
|
||||
break;
|
||||
}
|
||||
|
||||
double hObj = (height2 + m_internal->m_objHat - centerHeight );
|
||||
double objM = hObj / d2; // Steigung bezogen auf Objekte( Objekte verdecken nicht !)
|
||||
|
||||
SightMode newMode = ((objM >= curM)) ? VISIBLE : INVISIBLE;
|
||||
|
||||
if(newMode != mode)
|
||||
{
|
||||
if ((mode != START) && (d2 != d1))
|
||||
{
|
||||
// Korrekturwert für Distanz berechnen, unter Berücksichtigung der Objekthoehe !!
|
||||
double localM = (height2 - height1) /(d2 -d1);
|
||||
// localM == curM kann nicht auftreten, da newMode != mode
|
||||
double dCorr = (hObj - (curM * d2)) / (localM - curM);
|
||||
|
||||
if (dCorr < 0.0)
|
||||
dCorr = 0.0;
|
||||
dCorr = d2 - dCorr;
|
||||
if (dCorr < d1)
|
||||
dCorr = d1;
|
||||
|
||||
sBeam.add( SightEntry( dCorr, mode) );
|
||||
}
|
||||
mode = newMode;
|
||||
}
|
||||
|
||||
double terrM = (height2 - centerHeight) / d2; // Steigung bezogen auf Gelaende
|
||||
if (terrM >= curM)
|
||||
{
|
||||
curM = terrM; // neue bestimmende Steigung
|
||||
}
|
||||
|
||||
height1 = height2;
|
||||
d1 = d2;
|
||||
} /* while */
|
||||
}
|
||||
sBeam.add( SightEntry(m_internal->m_radius, mode) );
|
||||
}
|
||||
/*!
|
||||
* \brief SightFanImpl::delayedMove
|
||||
* \param center
|
||||
* \details Delays the move call to prevent crash of map beacause of the heavy load while moving
|
||||
*/
|
||||
void SightFanImpl::delayedMove()
|
||||
{
|
||||
m_internal->m_center = m_moveDelayedCenter;
|
||||
|
||||
m_internal->setFanColorMap(1, 0, 1);
|
||||
|
||||
QPointF offc(m_internal->m_radius, -m_internal->m_radius);
|
||||
m_internal->m_location = QRectF(m_internal->m_center - offc, m_internal->m_center + offc);
|
||||
|
||||
if (m_internal->m_nrFans == m_internal->m_sightBeamVec.size())
|
||||
{
|
||||
for (RefPointer<SightBeam> sBeam : qAsConst(m_internal->m_sightBeamVec))
|
||||
{
|
||||
calculateSightBeam(*sBeam.get());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
calculateSightBeamVec();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SightBeam::updateGraphic(MapImpl *mapImpl, AbstractMapObjectImpl *meMapObj, SightFanImpl::Internal *sightFanInternal)
|
||||
{
|
||||
if (!mapImpl || !meMapObj || !sightFanInternal)
|
||||
return;
|
||||
|
||||
if (_sightEntryVec.size() <= 1)
|
||||
return;
|
||||
|
||||
Esri::ArcGISRuntime::GraphicsOverlay *graphicLayer = sightFanInternal->m_mapImpl->getGraphicsLayer(sightFanInternal->m_layerName);
|
||||
if (!graphicLayer)
|
||||
{
|
||||
ERROR_LOG(sightFanInternal->m_logger) << LOGFUNCTION << " Creating graphic overlayer \'" << sightFanInternal->m_layerName << "\' failed. Can't render sight fan";
|
||||
return;
|
||||
}
|
||||
|
||||
// _sightEntryVec[0] is SightMode::START
|
||||
|
||||
// resize _graphicalQuadVec according _sightEntryVec
|
||||
// (_sightEntryVec.size() <= 1 is chexck above)
|
||||
const int newGraphicalSize = _sightEntryVec.size() - 1;
|
||||
_graphicalQuadVec.resize(newGraphicalSize);
|
||||
|
||||
CoordTranslationFunctor *geoToMap = sightFanInternal->m_mapImpl->coordTranslationFunctor();
|
||||
|
||||
int quadNo = 0;
|
||||
SightEntryVec::iterator itr = _sightEntryVec.begin();
|
||||
|
||||
const QPointF ¢er = sightFanInternal->m_center;
|
||||
QPointF v0 = endOfBeam(center, _directionBeg, itr->dist());
|
||||
QPointF v1 = endOfBeam(center, _directionEnd, itr->dist());
|
||||
|
||||
if (geoToMap)
|
||||
{
|
||||
v0 = geoToMap->geographicToMap(v0);
|
||||
v1 = geoToMap->geographicToMap(v1);
|
||||
}
|
||||
|
||||
PositionCont locationVec;
|
||||
|
||||
// skip first, we know mode==SightMode::START
|
||||
while (++itr != _sightEntryVec.end())
|
||||
{
|
||||
// GraphicalObjectPath already created :
|
||||
QSharedPointer<GraphicalObjectPath> &spGopRef = _graphicalQuadVec[quadNo];
|
||||
if (!spGopRef)
|
||||
{
|
||||
GraphicalObjectPath * grQuad = new GraphicalObjectPath( GraphicalObjectPathType::Polygon
|
||||
, mapImpl->getEsriGeoView()
|
||||
, graphicLayer
|
||||
, QStringLiteral("FanOfSight-Beam-%1").arg(_beamId)
|
||||
, meMapObj->uniqueMapId() );
|
||||
grQuad->setPickable(false);
|
||||
grQuad->rLineStyle().setLinePattern(LinePattern::Null);
|
||||
grQuad->rFillStyle().setFillPattern(FillPattern::Solid);
|
||||
|
||||
// write to _graphicalQuadVec
|
||||
spGopRef = QSharedPointer<GraphicalObjectPath>(grQuad);
|
||||
}
|
||||
// : GraphicalObjectPath already created
|
||||
|
||||
GraphicalObjectPath * grQuad = _graphicalQuadVec[quadNo].data();
|
||||
Q_ASSERT_X(grQuad, "SightBeam", "GraphicalObjectPath invalid");
|
||||
|
||||
SightMode mode = itr->mode();
|
||||
double dist = itr->dist();
|
||||
QColor quadColor = sightFanInternal->m_fanColorVec[_beamId % 2][int(mode)];
|
||||
|
||||
quadColor.setAlphaF( quadColor.alphaF()*sightFanInternal->m_alpha );
|
||||
|
||||
grQuad->rFillStyle().setFillColor(quadColor);
|
||||
|
||||
QPointF v2 = endOfBeam(center, _directionBeg, dist);
|
||||
QPointF v3 = endOfBeam(center, _directionEnd, dist);
|
||||
|
||||
if (geoToMap)
|
||||
{
|
||||
v2 = geoToMap->geographicToMap(v2);
|
||||
v3 = geoToMap->geographicToMap(v3);
|
||||
}
|
||||
|
||||
locationVec.clear();
|
||||
locationVec << Point3D::fromQPointF(v0);
|
||||
locationVec << Point3D::fromQPointF(v1);
|
||||
locationVec << Point3D::fromQPointF(v2);
|
||||
locationVec << Point3D::fromQPointF(v3);
|
||||
|
||||
grQuad->setPositions(locationVec);
|
||||
|
||||
grQuad->updateView();
|
||||
|
||||
v0 = v3;
|
||||
v1 = v2;
|
||||
|
||||
++quadNo;
|
||||
} /* while */
|
||||
|
||||
} // void SightBeam::updateGraphic(MapImpl *mapImpl, AbstractMapObjectImpl *meMapObj, SightFanImpl::Internal *sightFanInternal)
|
||||
|
||||
|
||||
#ifdef NEVER
|
||||
bool SightFan::draw( const AbstractView * const view, osg::Matrixd mat,
|
||||
float alpha, float brightness, float bias, MapObject::RenderState rstate ) // todo: Farbtabelle
|
||||
{
|
||||
if ((rstate & _renderState) == 0) return false;
|
||||
|
||||
if( !( _location.intersects( view->rectBound()) )) return false; // isCulled
|
||||
|
||||
|
||||
ColorVec colors[2][4];
|
||||
for( int i = 0; i < 3; i++)
|
||||
{
|
||||
colors[0][i] = (_colors[i] * brightness) + bias;
|
||||
colors[1][i] = colors[0][i] * _fanMult;
|
||||
colors[0][i].alpha = alpha * _colors[i].alpha;
|
||||
colors[1][i].alpha = alpha * _colors[i].alpha;
|
||||
}
|
||||
colors[0][3] = colors[0][2];
|
||||
colors[1][3] = colors[1][2];
|
||||
|
||||
GLint shadeModel;
|
||||
|
||||
glGetIntegerv( GL_SHADE_MODEL, &shadeModel );
|
||||
glShadeModel(GL_FLAT);
|
||||
glEnable( GL_BLEND);
|
||||
|
||||
int n = 0;
|
||||
for( SightBeamVec::iterator itr = _sightBeamVec.begin(); itr != _sightBeamVec.end(); ++itr)
|
||||
{
|
||||
(*itr).get()->draw( _center, mat, colors[(++n)%2]);
|
||||
}
|
||||
|
||||
glDisable( GL_BLEND);
|
||||
glShadeModel(shadeModel);
|
||||
return true;
|
||||
} /* SightFan::draw */
|
||||
|
||||
|
||||
|
||||
void SightBeam::draw( Vec2d center, osg::Matrixd mat, ColorVec colors[]) // todo: Farbtabelle !?
|
||||
{
|
||||
float z = 0;
|
||||
|
||||
if( _sightEntryVec.size() <= 1) return;
|
||||
|
||||
SightEntryVec::iterator itr = _sightEntryVec.begin();
|
||||
|
||||
Vec2d v0 = endOfBeam( center, _directionBeg, (*itr).dist() );
|
||||
Vec2d v1 = endOfBeam( center, _directionEnd, (*itr).dist() );
|
||||
|
||||
osg::Vec3d _v0 = mat.preMult( osg::Vec3d( v0[0], v0[1], 0.0 ));
|
||||
osg::Vec3d _v1 = mat.preMult( osg::Vec3d( v1[0], v1[1], 0.0 ));
|
||||
|
||||
glBegin( GL_QUAD_STRIP);
|
||||
{
|
||||
glVertex3f( _v0.x(), _v0.y(), z);
|
||||
glVertex3f( _v1.x(), _v1.y(), z);
|
||||
|
||||
|
||||
while( ++itr != _sightEntryVec.end() )
|
||||
{
|
||||
SightMode mode = (*itr).mode();
|
||||
glColor4f( colors[mode].red, colors[mode].green, colors[mode].blue, colors[mode].alpha);
|
||||
|
||||
v0 = endOfBeam( center, _directionBeg, (*itr).dist() );
|
||||
v1 = endOfBeam( center, _directionEnd, (*itr).dist() );
|
||||
|
||||
_v0 = mat.preMult( osg::Vec3d( v0[0], v0[1], 0.0 ));
|
||||
_v1 = mat.preMult( osg::Vec3d( v1[0], v1[1], 0.0 ));
|
||||
|
||||
glVertex3f( _v0.x(), _v0.y(), z);
|
||||
glVertex3f( _v1.x(), _v1.y(), z);
|
||||
} /* while */
|
||||
}
|
||||
glEnd();
|
||||
} /* SightBeam::draw */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
} // SituationMap
|
||||
|
||||
|
||||
Reference in new issue
Block a user