mirror of https://github.com/qt/qtdoc.git
138 lines
3.5 KiB
C++
138 lines
3.5 KiB
C++
// Copyright (C) 2023 The Qt Company Ltd.
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
|
|
#include "lightningitemmodel.h"
|
|
#include "laststrikeinfo.h"
|
|
|
|
#include <QGeoPositionInfo>
|
|
|
|
namespace {
|
|
constexpr int HISTORY_SIZE = 1000;
|
|
enum class Role : int {
|
|
Begin = 0,
|
|
Latitude = Begin,
|
|
Longitude,
|
|
Timestamp,
|
|
End
|
|
};
|
|
constexpr auto getRoleName(Role role) {
|
|
switch (role) {
|
|
case Role::Latitude:
|
|
return "latitude";
|
|
case Role::Longitude:
|
|
return "longitude";
|
|
case Role::Timestamp:
|
|
return "timestamp";
|
|
default:
|
|
break;
|
|
}
|
|
return "";
|
|
}
|
|
}
|
|
|
|
LightningItemModel::LightningItemModel(QObject *parent)
|
|
: QAbstractListModel(parent)
|
|
{
|
|
}
|
|
|
|
void LightningItemModel::insertData(const LightningItemData &data)
|
|
{
|
|
if (m_data.size() == HISTORY_SIZE) {
|
|
beginRemoveRows(QModelIndex{}, 0, 0);
|
|
m_data.pop_front();
|
|
endRemoveRows();
|
|
}
|
|
|
|
const int insertRow = m_data.size();
|
|
beginInsertRows(QModelIndex{}, insertRow, insertRow);
|
|
m_data.push_back(data);
|
|
endInsertRows();
|
|
}
|
|
|
|
void LightningItemModel::getNearestStrikeInfo(const QGeoCoordinate &coordinate,
|
|
LastStrikeInfo *nearestStrikeInfo) const
|
|
{
|
|
if (nearestStrikeInfo == nullptr)
|
|
return;
|
|
|
|
LastStrikeInfo strikeInfo;
|
|
|
|
for (auto it = m_data.cbegin(); it != m_data.cend(); ++it)
|
|
{
|
|
const LightningItemData &lightningData = *it;
|
|
|
|
strikeInfo.distance = lightningData.getDistanceTo(coordinate);
|
|
strikeInfo.timestamp = lightningData.timestamp;
|
|
|
|
if (strikeInfo < *nearestStrikeInfo)
|
|
*nearestStrikeInfo = strikeInfo;
|
|
}
|
|
}
|
|
|
|
void LightningItemModel::getLatestStrikeInfo(const QGeoCoordinate &searchCenter,
|
|
double searchRadius,
|
|
LastStrikeInfo *latestStrikeInfo) const
|
|
{
|
|
if (latestStrikeInfo == nullptr)
|
|
return;
|
|
|
|
for (int index = m_data.size() - 1; index >= 0; --index)
|
|
{
|
|
const LightningItemData &lightningData = m_data[index];
|
|
|
|
const double distance = lightningData.getDistanceTo(searchCenter);
|
|
if (distance > searchRadius)
|
|
continue;
|
|
|
|
latestStrikeInfo->distance = distance;
|
|
latestStrikeInfo->timestamp = lightningData.timestamp;
|
|
latestStrikeInfo->direction = lightningData.getDirectionFrom(searchCenter);
|
|
break;
|
|
}
|
|
}
|
|
|
|
int LightningItemModel::rowCount(const QModelIndex &parent) const
|
|
{
|
|
return m_data.size();
|
|
}
|
|
|
|
QVariant LightningItemModel::data(const QModelIndex &index, int role) const
|
|
{
|
|
if (!index.isValid())
|
|
return QVariant{};
|
|
|
|
// child not supported
|
|
if (index.parent().isValid())
|
|
return QVariant{};
|
|
|
|
const int row = index.row();
|
|
|
|
// out of range row
|
|
if ((row < 0) or (m_data.size() <= row))
|
|
return QVariant{};
|
|
|
|
const LightningItemData &data = m_data[row];
|
|
|
|
switch (static_cast<Role>(role)) {
|
|
case Role::Latitude:
|
|
return data.latitude;
|
|
case Role::Longitude:
|
|
return data.longitude;
|
|
case Role::Timestamp:
|
|
return data.timestamp.count();
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// invalid role
|
|
return QVariant{};
|
|
}
|
|
|
|
QHash<int, QByteArray> LightningItemModel::roleNames() const
|
|
{
|
|
QHash<int, QByteArray> roleNames;
|
|
for (int role = static_cast<int>(Role::Begin); role < static_cast<int>(Role::End); ++role)
|
|
roleNames.emplace(role, getRoleName(static_cast<Role>(role)));
|
|
return roleNames;
|
|
}
|