Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
+102
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* MouseMoveOverlay
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#include "mouse_move_overlay.h"
|
||||
|
||||
// Own
|
||||
#include <MapImpl/map_impl.h>
|
||||
|
||||
// ESRI
|
||||
#include <arcgis/Map.h>
|
||||
#include <arcgis/CoordinateConversion.h>
|
||||
#include <arcgis/GeometryEngine.h>
|
||||
|
||||
// Qt
|
||||
#include <QDebug>
|
||||
#include <QGraphicsSceneHoverEvent>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
class MouseMoveOverlay::Private
|
||||
{
|
||||
public:
|
||||
Private() = default;
|
||||
~Private() = default;
|
||||
|
||||
// ESRI data:
|
||||
EsriRuntimeQt::Map *m_map = nullptr;
|
||||
|
||||
// OWN data:
|
||||
SituationMap::MapImpl *m_mapImpl = nullptr;
|
||||
|
||||
}; // class MouseMoveOverlay::Private
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
MouseMoveOverlay::MouseMoveOverlay(MapImpl *mapImpl)
|
||||
: QGraphicsItem()
|
||||
, d(new Private)
|
||||
{
|
||||
qDebug() << LOGFUNCTION;
|
||||
|
||||
// object to be called:
|
||||
d->m_mapImpl = mapImpl;
|
||||
|
||||
if (d->m_mapImpl)
|
||||
d->m_map = d->m_mapImpl->getEsriMap();
|
||||
|
||||
setAcceptHoverEvents(true);
|
||||
}
|
||||
|
||||
MouseMoveOverlay::~MouseMoveOverlay()
|
||||
{
|
||||
qDebug() << LOGFUNCTION;
|
||||
delete d;
|
||||
}
|
||||
|
||||
QRectF MouseMoveOverlay::boundingRect() const
|
||||
{
|
||||
if (d->m_map)
|
||||
return QRect(0, 0, d->m_map->width(), d->m_map->height());
|
||||
return QRect(); // fallback
|
||||
}
|
||||
|
||||
void MouseMoveOverlay::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
// No need to paint
|
||||
Q_UNUSED(painter)
|
||||
Q_UNUSED(option)
|
||||
Q_UNUSED(widget)
|
||||
}
|
||||
|
||||
|
||||
void MouseMoveOverlay::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
// qDebug() << LOGFUNCTION;
|
||||
|
||||
if (d->m_map)
|
||||
{
|
||||
if (!d->m_map->isReady())
|
||||
return;
|
||||
|
||||
QPointF scenePoint = event->scenePos();
|
||||
int scenePointX = scenePoint.x();
|
||||
int scenePointY = scenePoint.y();
|
||||
if (scenePointX < 0 || scenePointY < 0)
|
||||
return;
|
||||
|
||||
d->m_mapImpl->onHandleMouseMove(scenePointX, scenePointY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace SituationMap
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* MouseMoveOverlay
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QGraphicsItem>
|
||||
|
||||
namespace EsriRuntimeQt
|
||||
{
|
||||
class MapGraphicsView;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
class MapImpl;
|
||||
|
||||
class MouseMoveOverlay : public QGraphicsItem
|
||||
{
|
||||
// Q_OBJECT
|
||||
public:
|
||||
|
||||
explicit MouseMoveOverlay(MapImpl *mapImpl);
|
||||
virtual ~MouseMoveOverlay();
|
||||
|
||||
signals:
|
||||
// void mousePositionChanged(const QPointF& screenPos, QPointF& mapPos);
|
||||
// void mousePositionChanged();
|
||||
|
||||
protected:
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
|
||||
|
||||
private :
|
||||
|
||||
MouseMoveOverlay(const MouseMoveOverlay &other) = delete;
|
||||
MouseMoveOverlay &operator=(const MouseMoveOverlay &other) = delete;
|
||||
|
||||
class Private;
|
||||
/**
|
||||
* The private d-pointer to not break BC when changing internals of this class
|
||||
*/
|
||||
Private *d = nullptr;
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // namespace SituationMap
|
||||
|
||||
|
||||
+268
@@ -0,0 +1,268 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Class MovementTrack
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
// Own
|
||||
#include "movement_track.h"
|
||||
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
|
||||
// Qt
|
||||
#include <QVector>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
int MovementTrack::m_count = 0;
|
||||
|
||||
MovementTrack::MovementTrack(int trackId)
|
||||
// : m_logger(getLogger("MovementTrack", trackId))
|
||||
: m_logger(getLogger("MovementTrack"))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " trackId/participantId=" << trackId
|
||||
<< " m_count=" << m_count;
|
||||
++m_count;
|
||||
|
||||
m_trackId = trackId;
|
||||
m_active = true;
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " m_trackId=" << m_trackId << " m_count=" << m_count;
|
||||
}
|
||||
|
||||
MovementTrack::~MovementTrack()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " m_trackId=" << m_trackId << " m_count=" << m_count;
|
||||
--m_count;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " m_trackId=" << m_trackId << " m_count=" << m_count;
|
||||
}
|
||||
|
||||
void MovementTrack::setActive(bool active)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START " << " active=" << active << " m_count=" << m_count;
|
||||
m_active = active;
|
||||
}
|
||||
|
||||
bool MovementTrack::addPosition(const COORD_T &newPosition,
|
||||
qint64 currentTimeMsec, double minDistance, int maxNumberOfPositions)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " currentTimeMsec=" << currentTimeMsec
|
||||
<< " newPosition=" << newPosition
|
||||
<< " #ofCoords=" << m_cont.size();
|
||||
bool success = false;
|
||||
|
||||
// Very first access?
|
||||
if (m_cont.isEmpty())
|
||||
{
|
||||
m_cont.insert(currentTimeMsec, newPosition);
|
||||
success = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Avoid identical values:
|
||||
const COORD_T &lastPosition = m_cont.last();
|
||||
|
||||
// isEmpty already checked:
|
||||
if (lastPosition != newPosition)
|
||||
{
|
||||
const double distance = LtsCoordTrans::distance(lastPosition.x(), lastPosition.y(),
|
||||
newPosition.x(), newPosition.y());
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " distance " << distance;
|
||||
|
||||
if (distance > minDistance)
|
||||
{
|
||||
m_cont.insert(currentTimeMsec, newPosition);
|
||||
success = true;
|
||||
}
|
||||
} // if (lastPosition != newPosition)
|
||||
}
|
||||
|
||||
if (!m_cont.isEmpty() &&
|
||||
(m_cont.size() > maxNumberOfPositions) && (maxNumberOfPositions > 0))
|
||||
{
|
||||
// see QTBUG-59373
|
||||
m_cont.erase(m_cont.begin());
|
||||
}
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END " << "success=" << success << " #ofCoords=" << m_cont.size();
|
||||
return success;
|
||||
}
|
||||
|
||||
bool MovementTrack::removeEntriesNewer(qint64 currentTimeMsec)
|
||||
{
|
||||
// TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " m_active=" << m_active << " m_count=" << m_count;
|
||||
|
||||
bool modified = false;
|
||||
QMapIterator<KEY_T, COORD_T> mapIt(m_cont);
|
||||
mapIt.toBack();
|
||||
|
||||
while (mapIt.hasPrevious())
|
||||
{
|
||||
mapIt.previous();
|
||||
if (mapIt.key() > currentTimeMsec)
|
||||
{
|
||||
m_cont.remove(mapIt.key());
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
break;
|
||||
} // while
|
||||
|
||||
// TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " m_active=" << m_active << " m_count=" << m_count << " modified=" << modified;
|
||||
return modified;
|
||||
}
|
||||
|
||||
bool MovementTrack::removeEntriesOlder(qint64 currentTimeMsec, qint64 maxAgeMsec)
|
||||
{
|
||||
// TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " m_active=" << m_active << " m_count=" << m_count << " currentTimeMsec=" << currentTimeMsec << " maxAgeMsec=" << maxAgeMsec;
|
||||
|
||||
bool modified = false;
|
||||
auto it = m_cont.begin();
|
||||
while (it != m_cont.end())
|
||||
{
|
||||
const KEY_T &ageMsec = currentTimeMsec - it.key();
|
||||
if (ageMsec > maxAgeMsec)
|
||||
{
|
||||
it = m_cont.erase(it);
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
++it;
|
||||
} // while
|
||||
|
||||
// TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " m_active=" << m_active << " m_count=" << m_count << " modified=" << modified;
|
||||
return modified;
|
||||
}
|
||||
|
||||
QVector<MovementTrack::COORD_T> MovementTrack::getTrack() const
|
||||
{
|
||||
QVector<MovementTrack::COORD_T> ret;
|
||||
ret.reserve(m_cont.size());
|
||||
for (const auto &pos : m_cont)
|
||||
ret.push_back(pos);
|
||||
return ret;
|
||||
}
|
||||
|
||||
QVector<MovementTrack::COORD_T> MovementTrack::getVisibleTrack(qint64 currentTimeMsec,
|
||||
qint64 maxAgeMsec,
|
||||
qint64 maxViewAgeMsec)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " m_trackId=" << m_trackId << " currentTimeMsec=" << currentTimeMsec << " maxAgeMsec=" << maxAgeMsec << " maxViewAgeMsec=" << maxViewAgeMsec;
|
||||
|
||||
|
||||
removeEntriesOlder(currentTimeMsec, maxAgeMsec);
|
||||
|
||||
// Auch wenn keine neuen Positionen eingegangen sind,
|
||||
// hat sich die Spur evtl. wegen der modifizierten Zeit 'currentTimeMsec'
|
||||
// geändert:
|
||||
// uebertragen in validCoords
|
||||
|
||||
QVector<MovementTrack::COORD_T> validCoords;
|
||||
validCoords.reserve(m_cont.size());
|
||||
for (auto it = m_cont.cbegin(); it != m_cont.cend(); ++it)
|
||||
{
|
||||
const KEY_T &ageMsec = currentTimeMsec - it.key();
|
||||
if (ageMsec > maxViewAgeMsec && maxViewAgeMsec > 0)
|
||||
continue;
|
||||
|
||||
if (ageMsec < 0)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " age is negative!!! - "
|
||||
<< " currentTimeMsec=" << currentTimeMsec
|
||||
<< " m_trackId=" << m_trackId
|
||||
<< " ageMsec=" << ageMsec
|
||||
<< " - "
|
||||
<< " size = " << m_cont.size()
|
||||
<< ", dis = " << std::distance(m_cont.cbegin(), it);
|
||||
if (ageMsec < -1500)
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION << " age is negative!!! - "
|
||||
<< " currentTimeMsec=" << currentTimeMsec
|
||||
<< " m_trackId=" << m_trackId
|
||||
<< " ageMsec=" << ageMsec
|
||||
<< " - "
|
||||
<< " size = " << m_cont.size()
|
||||
<< ", dis = " << std::distance(m_cont.cbegin(), it);
|
||||
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " m_trackId=" << m_trackId << " ageMsec=" << ageMsec << " coord=" << it.value();
|
||||
validCoords.push_back(it.value());
|
||||
} // for
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " validCoords.size()/m_cont.size(): " << validCoords.size() << " / " << m_cont.size();
|
||||
|
||||
return validCoords;
|
||||
}
|
||||
|
||||
QSharedPointer<MovementTrack> MovementTrack::read(const QJsonObject &json)
|
||||
{
|
||||
if (!json.contains(QLatin1String("trackId")))
|
||||
return nullptr;
|
||||
|
||||
int trackId = -1;
|
||||
if (json.contains(QLatin1String("trackId")))
|
||||
trackId = json[QLatin1String("trackId")].toInt();
|
||||
|
||||
if (trackId < 0)
|
||||
return nullptr;
|
||||
|
||||
QSharedPointer<MovementTrack> mt =
|
||||
QSharedPointer<MovementTrack>(new MovementTrack(trackId));
|
||||
|
||||
// active
|
||||
if (json.contains(QLatin1String("active")))
|
||||
mt->setActive(json[QLatin1String("active")].toBool());
|
||||
|
||||
// coordinates
|
||||
QJsonArray jArray = json[QLatin1String("coordinates")].toArray();
|
||||
for (int idx = 0; idx < jArray.size(); ++idx)
|
||||
{
|
||||
const QJsonObject &objTemp = jArray[idx].toObject();
|
||||
const KEY_T &timeMsec = objTemp[QLatin1String("pointInTimeMsec")].toDouble(); // toDouble!!!
|
||||
|
||||
Point3D p3D;
|
||||
p3D.rx() = objTemp[QLatin1String("loc_x_lon")].toDouble();
|
||||
p3D.ry() = objTemp[QLatin1String("loc_y_lat")].toDouble();
|
||||
if (json.contains(QLatin1String("loc_z")))
|
||||
p3D.rz() = objTemp[QLatin1String("loc_z")].toDouble();
|
||||
mt->addPosition(p3D, timeMsec, 0, 0);
|
||||
} // for
|
||||
|
||||
return mt;
|
||||
}
|
||||
|
||||
QJsonObject MovementTrack::toJsonObject() const
|
||||
{
|
||||
QJsonObject json;
|
||||
|
||||
json[QLatin1String("trackId")] = m_trackId;
|
||||
json[QLatin1String("active")] = m_active;
|
||||
|
||||
QJsonArray jArray;
|
||||
QMapIterator<KEY_T, COORD_T> it(m_cont);
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
const KEY_T &key = it.key();
|
||||
const COORD_T &coord = it.value();
|
||||
|
||||
QJsonObject jsonCoord;
|
||||
jsonCoord[QLatin1String("loc_x_lon")] = coord.x();
|
||||
jsonCoord[QLatin1String("loc_y_lat")] = coord.y();
|
||||
jsonCoord[QLatin1String("loc_z")] = coord.z();
|
||||
jsonCoord[QLatin1String("pointInTimeMsec")] = key;
|
||||
jArray.append(jsonCoord);
|
||||
}
|
||||
json[QLatin1String("coordinates")] = jArray;
|
||||
return json;
|
||||
}
|
||||
|
||||
|
||||
} // namespace SituationMap
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Class MovementTrack
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
// Own
|
||||
#include <Map/point3D.h>
|
||||
#include <Common/situation_map_logging.h>
|
||||
#include <situation_map_export.h>
|
||||
|
||||
|
||||
// Qt
|
||||
#include <QMap>
|
||||
#include <QSharedPointer>
|
||||
|
||||
|
||||
class QJsonObject;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
class SITUATIONMAP_EXPORT MovementTrack
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
using KEY_T = qint64; // msec
|
||||
using COORD_T = Point3D; // lon, lat
|
||||
using CONT_T = QMap<KEY_T, COORD_T>; // ordered by time [msec]
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
explicit MovementTrack(int trackId);
|
||||
|
||||
/// Destructor
|
||||
virtual ~MovementTrack();
|
||||
|
||||
int trackId() const { return m_trackId; }
|
||||
int size() const { return m_cont.size(); }
|
||||
void clear() { m_cont.clear(); }
|
||||
|
||||
void setActive(bool active);
|
||||
bool isActive() const { return m_active; }
|
||||
|
||||
bool addPosition(const COORD_T &newPosition,
|
||||
qint64 currentTimeMsec, double minDistance, int maxNumberOfPositions);
|
||||
|
||||
const COORD_T lastPosition() const
|
||||
{
|
||||
if (this->m_cont.empty())
|
||||
return COORD_T();
|
||||
return this->m_cont.last();
|
||||
}
|
||||
|
||||
bool removeEntriesOlder(qint64 currentTimeMsec, qint64 maxAgeMsec);
|
||||
bool removeEntriesNewer(qint64 currentTimeMsec);
|
||||
|
||||
QVector<COORD_T> getTrack() const;
|
||||
QVector<COORD_T> getVisibleTrack(qint64 currentTimeMsec, qint64 maxAgeMsec, qint64 maxViewAgeMsec);
|
||||
|
||||
|
||||
static QSharedPointer<MovementTrack> read(const QJsonObject &json);
|
||||
QJsonObject toJsonObject() const;
|
||||
|
||||
protected:
|
||||
static int m_count;
|
||||
int m_trackId; // UniqueMapId
|
||||
bool m_active;
|
||||
|
||||
CONT_T m_cont;
|
||||
|
||||
|
||||
private:
|
||||
LOGGER_T m_logger; ///< Interface to the Logging-Facility
|
||||
};
|
||||
|
||||
} // namespace SituationMap
|
||||
+338
@@ -0,0 +1,338 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Class MovementTrackManager
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
|
||||
// Own
|
||||
#include "movement_track_manager.h"
|
||||
|
||||
|
||||
// Qt
|
||||
#include <QVector>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
MovementTrackManager::MovementTrackManager(QObject *parent)
|
||||
: BaseClass(parent)
|
||||
, m_logger(getLogger("MovementTrackManager"))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
init();
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
MovementTrackManager::~MovementTrackManager()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " size=" << m_cont.size();
|
||||
m_cont.clear();
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END ";
|
||||
}
|
||||
|
||||
void MovementTrackManager::init()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_cont.clear();
|
||||
m_currentTimeMsec = 0;
|
||||
m_maxNumberOfTracks = 10;
|
||||
m_maxNumberOfPointsPerTrack = 600; // 600
|
||||
|
||||
// min sec msec
|
||||
m_maxAgeMsec = 30 * 60 * 1000; // (30Min * 60 * 1000= 1 800 000sec)
|
||||
m_maxViewAgeMsec = 30 * 60 * 1000; // (30Min * 60 * 1000= 1 800 000sec)
|
||||
|
||||
m_minDistance = 2; // 2 Meter
|
||||
|
||||
// just for testing:
|
||||
// m_maxNumberOfTracks = 3;
|
||||
// m_maxAgeMsec = 6000 * 60 * 1000;
|
||||
// m_maxViewAgeMsec = 6000 * 60 * 1000;
|
||||
// m_maxNumberOfPointsPerTrack = 10;
|
||||
// m_minDistance = 0;
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
QSet<int> MovementTrackManager::setCurrentTimeMsec(qint64 timeMsec)
|
||||
{
|
||||
// TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " timeMsec=" << timeMsec;
|
||||
|
||||
QSet<int> modifiedMapObjects;
|
||||
|
||||
if (m_currentTimeMsec == timeMsec)
|
||||
return modifiedMapObjects;
|
||||
|
||||
// forward or backward?
|
||||
bool forward = timeMsec > m_currentTimeMsec;
|
||||
m_currentTimeMsec = timeMsec;
|
||||
|
||||
|
||||
QVectorIterator<DATA_T> vecIt(m_cont);
|
||||
while (vecIt.hasNext())
|
||||
{
|
||||
DATA_T item = vecIt.next();
|
||||
|
||||
if (!item)
|
||||
continue;
|
||||
|
||||
bool mod;
|
||||
if (forward)
|
||||
mod = item->removeEntriesOlder(timeMsec, m_maxAgeMsec);
|
||||
else
|
||||
mod = item->removeEntriesNewer(timeMsec); // set time backward -> remove all entries whose time is too new
|
||||
|
||||
if (mod)
|
||||
{
|
||||
int trackId = item->trackId();
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " Track changes, simId/trackId=" << trackId
|
||||
<< " (m_maxAgeMsec=" << m_maxAgeMsec << ")"
|
||||
<< " (m_maxViewAgeMsec=" << m_maxViewAgeMsec << ")";
|
||||
modifiedMapObjects.insert(trackId);
|
||||
}
|
||||
} // while
|
||||
|
||||
// TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " timeMsec=" << timeMsec << " modifiedMapObjects=" << modifiedMapObjects.size();
|
||||
return modifiedMapObjects;
|
||||
}
|
||||
|
||||
|
||||
bool MovementTrackManager::addTrack(int trackId)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " size=" << m_cont.size() << " trackId=" << trackId;
|
||||
|
||||
if (hasTrack(trackId))
|
||||
return false;
|
||||
|
||||
m_cont.push_back(DATA_T(new MovementTrack(trackId)));
|
||||
|
||||
if (!m_cont.isEmpty() && (m_cont.size() > m_maxNumberOfTracks))
|
||||
{
|
||||
const int trackIdSave = m_cont.first()->trackId();
|
||||
m_cont.pop_front();
|
||||
emit trackRemoved(trackIdSave);
|
||||
}
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END " << " size=" << m_cont.size() << " trackId=" << trackId;
|
||||
return true;
|
||||
}
|
||||
|
||||
MovementTrackManager::DATA_T MovementTrackManager::getTrack(int trackId) const
|
||||
{
|
||||
QVectorIterator<DATA_T> vecIt(m_cont);
|
||||
while (vecIt.hasNext())
|
||||
{
|
||||
DATA_T item = vecIt.next();
|
||||
|
||||
if (item && item->trackId() == trackId)
|
||||
return item;
|
||||
} // while
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void MovementTrackManager::removeTrack(int trackId)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " size=" << m_cont.size() << " trackId=" << trackId;
|
||||
|
||||
for (int idx = m_cont.size() - 1; idx >= 0; --idx)
|
||||
{
|
||||
const DATA_T &item = m_cont.at(idx);
|
||||
if (item && item->trackId() == trackId)
|
||||
{
|
||||
m_cont.removeAt(idx);
|
||||
emit trackRemoved(trackId);
|
||||
}
|
||||
} // for
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " size=" << m_cont.size() << " trackId=" << trackId;
|
||||
}
|
||||
|
||||
void MovementTrackManager::activateTrack(int trackId)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " size=" << m_cont.size() << " trackId=" << trackId;
|
||||
|
||||
// Eintrag finden
|
||||
DATA_T track = getTrack(trackId);
|
||||
|
||||
if (track)
|
||||
{
|
||||
if (!track->isActive())
|
||||
{
|
||||
track->setActive(true);
|
||||
emit trackActivityChanged(trackId, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
addTrack(trackId); // new Track -> active
|
||||
emit trackActivityChanged(trackId, true);
|
||||
}
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " size=" << m_cont.size() << " trackId=" << trackId;
|
||||
}
|
||||
|
||||
void MovementTrackManager::deactivateTrack(int trackId)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " size=" << m_cont.size() << " trackId=" << trackId;
|
||||
|
||||
// 1. find track and save:
|
||||
DATA_T savedTrack = getTrack(trackId);
|
||||
if (!savedTrack)
|
||||
return;
|
||||
|
||||
if (!savedTrack->isActive()) // is already deactivated
|
||||
return;
|
||||
|
||||
// 2. remove track:
|
||||
for (int idx = m_cont.size() - 1; idx >= 0; --idx)
|
||||
{
|
||||
const DATA_T &item = m_cont.at(idx);
|
||||
if (item && item->trackId() == trackId)
|
||||
m_cont.removeAt(idx);
|
||||
} // for
|
||||
|
||||
// 3. re-add savedTrack:
|
||||
savedTrack->setActive(false);
|
||||
m_cont.push_front(savedTrack); // front -> remove candidate / Guez: was push_back!?
|
||||
|
||||
emit trackActivityChanged(trackId, false);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " size=" << m_cont.size() << " trackId=" << trackId;
|
||||
}
|
||||
|
||||
bool MovementTrackManager::addPosition(int trackId, const MovementTrack::COORD_T &coord, qint64 timeMsec)
|
||||
{
|
||||
DATA_T track = getTrack(trackId);
|
||||
if (track.isNull())
|
||||
return false;
|
||||
return track->addPosition(coord, timeMsec, m_minDistance, m_maxNumberOfPointsPerTrack);
|
||||
}
|
||||
|
||||
PositionCont MovementTrackManager::activeAndVisibleTrack(int trackId) const
|
||||
{
|
||||
DATA_T track = getTrack(trackId);
|
||||
if (!track || !track->isActive())
|
||||
return PositionCont();
|
||||
|
||||
return track->getVisibleTrack(m_currentTimeMsec, m_maxAgeMsec, m_maxViewAgeMsec);
|
||||
}
|
||||
|
||||
void MovementTrackManager::emit_activeSimIdsChanged(const QVector<int32_t> &activeSimIds)
|
||||
{
|
||||
emit activeSimIdsChanged(activeSimIds);
|
||||
}
|
||||
|
||||
bool MovementTrackManager::read(const QJsonObject &json)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
this->init();
|
||||
|
||||
if (json.contains(QLatin1String("currentTimeMsec")))
|
||||
this->setCurrentTimeMsec(json[QLatin1String("currentTimeMsec")].toDouble()); // qint64 -> toDouble
|
||||
if (json.contains(QLatin1String("maxAgeMsec")))
|
||||
this->setMaxAgeMsec(json[QLatin1String("maxAgeMsec")].toDouble()); // qint64 -> toDouble
|
||||
if (json.contains(QLatin1String("maxViewAgeMsec")))
|
||||
this->setMaxViewAgeMsec(json[QLatin1String("maxViewAgeMsec")].toDouble()); // qint64 -> toDouble
|
||||
|
||||
if (json.contains(QLatin1String("minDistance")))
|
||||
this->setMinDistance(json[QLatin1String("minDistance")].toInt());
|
||||
if (json.contains(QLatin1String("maxNumberOfTracks")))
|
||||
this->setMaxNumberOfTracks(json[QLatin1String("maxNumberOfTracks")].toInt());
|
||||
if (json.contains(QLatin1String("maxNumberOfPointsPerTrack")))
|
||||
this->setMaxNumberOfPointsPerTrack(json[QLatin1String("maxNumberOfPointsPerTrack")].toInt());
|
||||
|
||||
|
||||
// coords
|
||||
const QJsonArray &jArray = json[QLatin1String("movementTracks")].toArray();
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " movementTrack QJsonArray size=" << jArray.size();
|
||||
|
||||
for (int idx = 0; idx < jArray.size(); ++idx)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " movementTrack QJsonArray, idx=" << idx;
|
||||
|
||||
const QJsonObject &objTemp = jArray[idx].toObject();
|
||||
const QSharedPointer<MovementTrack> &mt = MovementTrack::read(objTemp);
|
||||
if (!mt)
|
||||
continue;
|
||||
if (mt->trackId() >= 0)
|
||||
m_cont.append(mt);
|
||||
|
||||
} // for
|
||||
|
||||
// send signals for all tracks:
|
||||
for (const QSharedPointer<MovementTrack> &mt : qAsConst(m_cont))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " emit trackActivityChanged,"
|
||||
<< " mt->trackId()=" << mt->trackId()
|
||||
<< " mt->isActive()=" << mt->isActive();
|
||||
emit trackActivityChanged(mt->trackId(), mt->isActive());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QJsonObject MovementTrackManager::toJsonObject() const
|
||||
{
|
||||
QJsonObject json;
|
||||
|
||||
json[QLatin1String("currentTimeMsec")] = m_currentTimeMsec;
|
||||
json[QLatin1String("maxAgeMsec")] = m_maxAgeMsec;
|
||||
json[QLatin1String("maxViewAgeMsec")] = m_maxViewAgeMsec;
|
||||
json[QLatin1String("minDistance")] = m_minDistance;
|
||||
json[QLatin1String("maxNumberOfTracks")] = m_maxNumberOfTracks;
|
||||
json[QLatin1String("maxNumberOfPointsPerTrack")] = m_maxNumberOfPointsPerTrack;
|
||||
|
||||
QJsonArray jArray;
|
||||
for (const auto &item : m_cont)
|
||||
{
|
||||
if (!item)
|
||||
continue;
|
||||
QJsonObject objTemp = item->toJsonObject();
|
||||
jArray.append(objTemp);
|
||||
}
|
||||
json[QLatin1String("movementTracks")] = jArray;
|
||||
return json;
|
||||
}
|
||||
|
||||
QByteArray MovementTrackManager::toJson() const
|
||||
{
|
||||
// final - toJson
|
||||
QJsonDocument jDoc(toJsonObject());
|
||||
return jDoc.toJson();
|
||||
}
|
||||
|
||||
QVector<int> MovementTrackManager::activeTrackIds() const
|
||||
{
|
||||
QVector<int> trackIds;
|
||||
trackIds.reserve(m_cont.size());
|
||||
|
||||
for (const auto &item : m_cont)
|
||||
{
|
||||
if (item && item->isActive())
|
||||
trackIds.append(item->trackId());
|
||||
}
|
||||
return trackIds;
|
||||
}
|
||||
|
||||
QVector<int> MovementTrackManager::deactiveTrackIds() const
|
||||
{
|
||||
QVector<int> deactiveTrackIds;
|
||||
deactiveTrackIds.reserve(m_cont.size());
|
||||
|
||||
for (const auto &item : m_cont)
|
||||
{
|
||||
if (item && !item->isActive())
|
||||
deactiveTrackIds.append(item->trackId());
|
||||
}
|
||||
return deactiveTrackIds;
|
||||
}
|
||||
|
||||
} // namespace GDW_CTC
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Class MovementTrackManager
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
// Own
|
||||
#include "movement_track.h"
|
||||
#include <Map/situation_map_types.h>
|
||||
|
||||
|
||||
// Qt
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
#include <QSharedPointer>
|
||||
#include <QVector>
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
class SITUATIONMAP_EXPORT MovementTrackManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using COORD_T = MovementTrack::COORD_T;
|
||||
using BaseClass = QObject;
|
||||
|
||||
/// Constructor
|
||||
explicit MovementTrackManager(QObject *parent = nullptr);
|
||||
|
||||
/// Destructor
|
||||
virtual ~MovementTrackManager();
|
||||
|
||||
void init();
|
||||
|
||||
qint64 currentTimeMsec() { return m_currentTimeMsec; }
|
||||
QSet<int> setCurrentTimeMsec(qint64 timeMsec);
|
||||
|
||||
qint64 maxAgeMsec() { return m_maxAgeMsec; }
|
||||
void setMaxAgeMsec(qint64 timeMsec) { m_maxAgeMsec = timeMsec; }
|
||||
|
||||
qint64 maxViewAgeMsec() { return m_maxViewAgeMsec; }
|
||||
void setMaxViewAgeMsec(qint64 maxViewAgeMsec) { m_maxViewAgeMsec = maxViewAgeMsec; }
|
||||
|
||||
int maxNumberOfTracks() const { return m_maxNumberOfTracks; }
|
||||
void setMaxNumberOfTracks(int maxNumberOfTracks) { m_maxNumberOfTracks = maxNumberOfTracks; }
|
||||
|
||||
int maxNumberOfPointsPerTrack() const { return m_maxNumberOfPointsPerTrack; }
|
||||
void setMaxNumberOfPointsPerTrack(int maxPoints) { m_maxNumberOfPointsPerTrack = maxPoints; }
|
||||
|
||||
int minDistance() const { return m_minDistance; }
|
||||
void setMinDistance(int minDistance) { m_minDistance = minDistance; }
|
||||
|
||||
|
||||
|
||||
bool addPosition(int trackId, const COORD_T &coord, qint64 timeMsec); // if track exists
|
||||
void removeTrack(int trackId);
|
||||
|
||||
void activateTrack(int trackId);
|
||||
void deactivateTrack(int trackId);
|
||||
|
||||
bool hasTrack(int trackId) const { return getTrack(trackId); }
|
||||
int size() const { return m_cont.size(); }
|
||||
|
||||
QVector<int> activeTrackIds() const;
|
||||
QVector<int> deactiveTrackIds() const;
|
||||
PositionCont activeAndVisibleTrack(int trackId) const;
|
||||
|
||||
void emit_activeSimIdsChanged(const QVector<int32_t> &activeSimIds);
|
||||
|
||||
bool read(const QJsonObject &json);
|
||||
QJsonObject toJsonObject() const;
|
||||
QByteArray toJson() const;
|
||||
|
||||
|
||||
Q_SIGNALS:
|
||||
void trackActivityChanged(int trackId, bool active);
|
||||
void trackRemoved(int trackId);
|
||||
|
||||
void activeSimIdsChanged(const QVector<int32_t> &activeSimIds);
|
||||
|
||||
private:
|
||||
bool addTrack(int trackId);
|
||||
|
||||
using DATA_T = QSharedPointer<MovementTrack>;
|
||||
using CONT_T = QVector<DATA_T>;
|
||||
|
||||
DATA_T getTrack(int trackId) const;
|
||||
|
||||
|
||||
protected:
|
||||
CONT_T m_cont;
|
||||
|
||||
qint64 m_currentTimeMsec;
|
||||
qint64 m_maxAgeMsec;
|
||||
qint64 m_maxViewAgeMsec;
|
||||
int m_minDistance;
|
||||
int m_maxNumberOfTracks;
|
||||
int m_maxNumberOfPointsPerTrack;
|
||||
|
||||
|
||||
private:
|
||||
LOGGER_T m_logger; ///< Interface to the Logging-Facility
|
||||
};
|
||||
|
||||
} // namespace SituationMap
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* TerrainProfileDialog/ Höhendialog
|
||||
* $Id: zwmsui_TerrainProfileDialog.cpp 21168 2014-10-27 07:35:54Z ehrlicher $
|
||||
* $HeadURL: svn://slssvn/TDS/branches/product/devel/vor_cleanup_zw_zs/ZW/ZWMS/ZWMSUI/zwmsui_TerrainProfileDialog.cpp $
|
||||
* $Author: ehrlicher $
|
||||
*/
|
||||
|
||||
#include "terrain_profile_dialog.h"
|
||||
#include "ui_terrain_profile_dialog.h"
|
||||
|
||||
//#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
#include <Map/map.h>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
TerrainProfileDialog::TerrainProfileDialog(QWidget *parent, LtsWidgets::ButtonCombination buttonCombination)
|
||||
: LtsWidgets::LtsDialog(parent, buttonCombination)
|
||||
, m_ui(new Ui::TerrainProfile)
|
||||
, m_logger(getLogger("TerrainProfileDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
connect(m_ui->heightPlotWidget, &LtsHeightPlotWidget::mousePositionChanged, this, &TerrainProfileDialog::onUpdatePosition);
|
||||
|
||||
// SIGNAL-SIGNAL um die Informationen nach aussen zu tragen
|
||||
connect(m_ui->heightPlotWidget, &LtsHeightPlotWidget::mousePositionChanged, this, &TerrainProfileDialog::mousePositionChanged);
|
||||
connect(m_ui->heightPlotWidget, &LtsHeightPlotWidget::startLineOfSight, this, &TerrainProfileDialog::startLineOfSight);
|
||||
connect(m_ui->heightPlotWidget, &LtsHeightPlotWidget::stopLineOfSight, this, &TerrainProfileDialog::stopLineOfSight);
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Start_Terrain_Profil"));
|
||||
}
|
||||
|
||||
TerrainProfileDialog::~TerrainProfileDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void TerrainProfileDialog::setMap(Map *map)
|
||||
{
|
||||
m_map = map;
|
||||
}
|
||||
|
||||
void TerrainProfileDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, QString(), false, tr("Terrain Profile"));
|
||||
}
|
||||
|
||||
void TerrainProfileDialog::setData(const QVector<heightData> &data)
|
||||
{
|
||||
m_ui->heightPlotWidget->setData(data);
|
||||
}
|
||||
|
||||
void TerrainProfileDialog::setMarks(const QVector<QPointF> &data)
|
||||
{
|
||||
m_ui->heightPlotWidget->setMarks(data);
|
||||
}
|
||||
|
||||
void TerrainProfileDialog::setMarkerPen(const QPen &pen)
|
||||
{
|
||||
m_ui->heightPlotWidget->setMarkerPen(pen);
|
||||
}
|
||||
|
||||
void TerrainProfileDialog::onUpdatePosition(const QPointF &position, double curHeight, double mouseHeight)
|
||||
{
|
||||
QString str; // = LtsCoordTrans::UtmCoordinate::fromGeographic(position).mgrs();
|
||||
if (m_map)
|
||||
str = m_map->mapToMgrsString(position);
|
||||
|
||||
m_ui->lblPosition->setText(str);
|
||||
m_ui->lblHeight->setText(QString::number(curHeight, 'f', 2));
|
||||
m_ui->lblHeightCursor->setText(QString::number(mouseHeight, 'f', 2));
|
||||
}
|
||||
|
||||
} // namespace SituationMap
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* TerrainProfileDialog/ Höhendialog
|
||||
* $Id: zwmsui_TerrainProfileDialog.h 4471 2010-06-15 06:56:51Z ehrlicher $
|
||||
* $HeadURL: svn://slssvn/TDS/branches/product/devel/vor_cleanup_zw_zs/ZW/ZWMS/ZWMSUI/zwmsui_TerrainProfileDialog.h $
|
||||
* $Author: ehrlicher $
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <Common/situation_map_logging.h>
|
||||
#include <situation_map_export.h>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class TerrainProfile;
|
||||
}
|
||||
|
||||
namespace QtCore
|
||||
{
|
||||
class QList;
|
||||
class QPair;
|
||||
class QPointF;
|
||||
}
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
class Map;
|
||||
|
||||
class SITUATIONMAP_EXPORT TerrainProfileDialog final : public LtsWidgets::LtsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using heightData = QPair<QPointF, double>;
|
||||
|
||||
public:
|
||||
explicit TerrainProfileDialog(QWidget *parent = nullptr, LtsWidgets::ButtonCombination buttonCombination = LtsWidgets::ButtonCombination::CloseOnly);
|
||||
~TerrainProfileDialog();
|
||||
void setMap(Map *map);
|
||||
|
||||
void setData(const QVector<heightData> &data);
|
||||
void setMarks(const QVector<QPointF> &data);
|
||||
void setMarkerPen(const QPen &pen);
|
||||
void retranslate() override;
|
||||
|
||||
signals:
|
||||
void mousePositionChanged(const QPointF &curPoint);
|
||||
void startLineOfSight(const QPointF &startPoint);
|
||||
void stopLineOfSight();
|
||||
|
||||
protected slots:
|
||||
void onUpdatePosition(const QPointF &position, double curHeight, double mouseHeight);
|
||||
|
||||
private:
|
||||
Ui::TerrainProfile *m_ui;
|
||||
Map *m_map = nullptr;
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
} // namespace SituationMap
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TerrainProfile</class>
|
||||
<widget class="QWidget" name="TerrainProfile">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>500</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Terrain Profile</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Position:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblPosition">
|
||||
<property name="text">
|
||||
<string notr="true">XXXXX YYYYY</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>17</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Height:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblHeight">
|
||||
<property name="text">
|
||||
<string notr="true">xxxx m</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>17</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Cursor height:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblHeightCursor">
|
||||
<property name="text">
|
||||
<string notr="true">xxxx m</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LtsHeightPlotWidget" name="heightPlotWidget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsHeightPlotWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsWidgets/lts_height_plot_widget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
Reference in new issue
Block a user