-1

I have a std::map< QString, QPolygonF> that contains three QStrings (sensorId) and for each sensor some data as QVector< QPointF>, which are produced continuously and written in a cv::Mat.

In the code block below, I take data from cv::Mat for each sensor and save it in std::map< QString, double> m_Value; and the values are pushed in std::map< QString, QPolygonF> m_Points. I collect data for each sensors only 5 times. Afterwards I send my points to other class in order visualize them with QwtPlot.

std::map<QString, QPolygonF> m_Points
std::map<QString, double>  m_Value;
std::map<QString, int> m_Index;

for(int i= 0; i< 5 ++i)
{
  m_Value[sensorId]= dataMat.at<double>(i);
  m_Points[sensorId].push_back(QPointF((double)m_Index[sensorId], 
  m_Value[sensorId]));
  m_Index[sensorId]++;
}

qDebug()<<" POINTS: " << toolId << m_Points[toolId];
emit updateDataSignal(m_Points); 

With the std::map< QString, int> m_Index; I continue/increase the number of sent points.

The output of the for-loop for only one loop looks like:

POINTS: 
sensor1 QPolygonF(0, pointValue) QPolygonF(1, pointValue) QPolygonF(2, pointValue) QPolygonF(3, pointValue) QPolygonF(4, pointValue)
sensor2 QPolygonF(0, pointValue) QPolygonF(1, pointValue) QPolygonF(2, pointValue) QPolygonF(3, pointValue) QPolygonF(4, pointValue)
sensor3 QPolygonF(0, pointValue) QPolygonF(1, pointValue) QPolygonF(2, pointValue) QPolygonF(3, pointValue) QPolygonF(4, pointValue)

For second loop:

sensor1 QPolygonF(0, pointValue) QPolygonF(1, pointValue) QPolygonF(2, pointValue) QPolygonF(3, pointValue) QPolygonF(4, pointValue) QPolygonF(5, newPointValue) QPolygonF(6, newPointValue) QPolygonF(7, newPointValue) QPolygonF(8, newPointValue) QPolygonF(9, newPointValue)
sensor2 ...
sensor3 ...

After some time I have thousand of points and my Qwtplot slows down by drawing/updating in real-time. Therefore I want to send only e.g. last 5 points from my map.

The output e.g. for sensor 1 should looks like:

first loop:

sensor1 QPolygonF(0, pointValue) QPolygonF(1, pointValue) QPolygonF(2, pointValue) QPolygonF(3, pointValue) QPolygonF(4, pointValue)

second loop:

sensor1 QPolygonF(5, newPointValue) QPolygonF(6, newPointValue) QPolygonF(7, newPointValue) QPolygonF(8, newPointValue) QPolygonF(9, newPointValue)

third loop:

sensor1 QPolygonF(10, newPointValue) QPolygonF(11, newPointValue) QPolygonF(12, newPointValue) QPolygonF(13, newPointValue) QPolygonF(14, newPointValue)
...

Thank you

nasil122002
  • 127
  • 1
  • 3
  • 15
  • Your title is misleading. It seems like you want to show only last `n` elements of the vector `QPolygonF` which `m_Points` contains not the last `n` elements of the `std::map` – Killzone Kid Dec 02 '17 at 18:45

2 Answers2

0

I don't think your example code is right, as you aren't using map for its intended purpose--namely to store key value pairs with O(1) lookup time.

As written, you should be using std::vector instead, and then you can access the last five elements added using the std::vector::end iterator (cplusplus doc link). Depending on your needs, you may need to slice it into a new vector, by using end to get const_iterators to the elements you want and constructing a new vector:

vector<T>::const_iterator last = myVec.end() - 1;
vector<T>::const_iterator first = last - 5;
vector<T> newVec(first, last);

This method is taken from another stack overflow question here: Best way to extract a subvector from a vector?

jaypb
  • 1,544
  • 10
  • 23
  • I am a little bit confused how to adapt your suggestion to my code above. QwtPlot accepts only QPolygonF which is QVector – nasil122002 Dec 02 '17 at 19:06
  • Where does QVector come into it? I do not see that in your code sample anywhere. I'm suggesting you replace std::map with std::vector. – jaypb Dec 07 '17 at 19:29
  • http://doc.qt.io/qt-5/qpolygonf.html#details I use `std::map` to create key-value pair based container. Keys are my sensors (sensorId) and each sensors have different values (m_Value). If I use `std::vector` the container contains either key or value. – nasil122002 Dec 07 '17 at 19:34
0

The answer is simple: don't store more than 5 points. Or, rather, always store exactly 5 most recent points in m_Points. It probably would also help for the locality of reference to have all the data together in a structure. Thus:

class Class : public QObject {
  Q_OBJECT
  std::map<QString, SensorData> m_data;
public:
  struct SensorData {
    QPolygonF points{5};
    qreal value;
    int index;
  };
  void method(const QString &sensorId, const cv::Mat<double> &matrix);
  Q_SIGNAL void updateDataSignal(const QPolygonF &);
};    

void Class::method(const QString &sensorId, const cv::Mat<double> &matrix) {
  auto &data = m_data[sensorId]; // cache the lookup
  for(int i=0; i<data.points.size(); ++i) {
    data.value = matrix.at<double>(i);
    data.points[i] = {(qreal)data.index, data.value};
    data.index++;
  }
  emit updateDataSignal(data.points);
}
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313