8using namespace Qt::StringLiterals;
14constexpr std::array DESCRIPTORS{
16 .
type = GPSType::trimble,
19 .capabilities = {.recognized =
true, .rtkBase =
true, .surveyIn =
true},
20 .surveyDuration = Duration::ElapsedTime,
21 .configurableSurveyDuration =
true,
24 .
type = GPSType::septentrio,
25 .name =
"Septentrio"_L1,
28 .capabilities = {.recognized =
true, .rtkBase =
true, .surveyIn =
true},
29 .surveyDuration = Duration::ElapsedTime,
32 .
type = GPSType::femto,
33 .name =
"Femtomes"_L1,
35 .capabilities = {.recognized =
true, .rtkBase =
true, .surveyIn =
true},
36 .surveyDuration = Duration::ElapsedTime,
38 .configurableSurveyDuration =
false,
41 .
type = GPSType::ublox,
45 .capabilities = {.recognized =
true, .rtkBase =
true, .surveyIn =
true, .compactObservations =
true},
46 .surveyAccuracy = Accuracy::PositionAccuracy,
47 .surveyDuration = Duration::ElapsedTime,
48 .configurableSurveyDuration =
true,
49 .fixedBaseAccuracy =
true,
52 .
type = GPSType::unicore,
55 .capabilities = {.recognized =
true, .rtkBase =
true, .receiverAveraging =
true},
58 .
type = GPSType::quectel,
61 .capabilities = {.recognized =
true, .rtkBase =
true, .surveyIn =
true, .persistentConfiguration =
true},
62 .surveyAccuracy = Accuracy::ObservationFilter,
63 .surveyDuration = Duration::AcceptedObservations,
64 .configurableSurveyDuration =
true,
65 .restartOnConnect =
true,
66 .surveyMaySavePosition =
true,
69 .
type = GPSType::passive,
70 .name =
"passive NMEA"_L1,
72 .protocol =
"NMEA"_L1,
73 .capabilities = {.recognized =
true, .passive =
true},
78consteval bool registryComplete()
80 for (
int type = 0; type < static_cast<int>(GPSType::automatic); ++type) {
85 for (
const auto& descriptor : DESCRIPTORS) {
91 return DESCRIPTORS.size() ==
static_cast<size_t>(GPSType::automatic);
94static_assert(registryComplete(),
"Each GPSType needs one descriptor with a unique, nonzero manufacturer ID");
105 return entry == DESCRIPTORS.end() ? nullptr : &*entry;
111 return descriptor ? QString(descriptor->name) : QString();
117 if (!descriptor || descriptor->protocol.isEmpty()) {
120 const QString protocol(descriptor->protocol);
121 return type == GPSType::passive ? protocol : QStringLiteral(
"%1 (%2)").arg(
gpsReceiverName(type), protocol);
127 return entry == DESCRIPTORS.end() ? nullptr : &*entry;
133 return GPSType::automatic;
136 return descriptor->type;
149 if (type == GPSType::automatic) {
152 for (
const auto& descriptor : DESCRIPTORS) {
153 const auto& capabilities = descriptor.capabilities;
154 if (!capabilities.rtkBase) {
159 combined.
surveyIn |= capabilities.surveyIn;
171 return descriptor->capabilities;
179 for (
const auto& descriptor : DESCRIPTORS) {
183 presentation.
rtkBase |= descriptor.capabilities.rtkBase;
184 presentation.
surveyIn |= descriptor.capabilities.surveyIn;
187 presentation.
surveyAccuracy |= descriptor.surveyAccuracy != Accuracy::Unavailable;
188 presentation.
surveyDuration |= descriptor.configurableSurveyDuration;
199 presentation.
passive = selected && selected->capabilities.passive;
210 static const QHash<int, GPSReceiverPresentation> presentations = [] {
211 QHash<int, GPSReceiverPresentation> result{
213 for (
const auto& descriptor : DESCRIPTORS) {
214 result.insert(descriptor.manufacturerId, buildPresentation(descriptor.manufacturerId));
219 const auto presentation = presentations.constFind(manufacturer);
220 return presentation != presentations.cend() ? *presentation : unknown;
const GPSReceiverDescriptor * gpsReceiverDescriptorForManufacturer(int manufacturer)
std::span< const GPSReceiverDescriptor > gpsReceiverDescriptors()
QString gpsInputProtocolName(GPSType type)
int gpsReceiverManufacturerForType(GPSType type)
The persisted manufacturer of type, or GPS_AUTOMATIC_MANUFACTURER when it has none.
const GPSReceiverDescriptor * gpsReceiverDescriptor(GPSType type)
GPSReceiverCapabilities gpsReceiverCapabilities(GPSType type)
What type supports, for either role; unknown receiver families support nothing.
QString gpsReceiverName(GPSType type)
The name of type's receiver family as shown to users; empty when no descriptor exists.
std::optional< GPSType > gpsReceiverTypeForManufacturer(int manufacturer)
The family a persisted manufacturer selects, GPSType::automatic for GPS_AUTOMATIC_MANUFACTURER; empty...
const GPSReceiverPresentation & gpsReceiverPresentation(int manufacturer)
constexpr int GPS_AUTOMATIC_MANUFACTURER
Software request support, not a guarantee for every physical receiver model or firmware.
bool persistentConfiguration
Persisted manufacturer IDs are distinct from GPSType values.
bool reportsSurveyDuration
bool automatic
The family is detected when connecting.
bool observationAccuracyFilter
bool acceptedObservationTime
bool surveyMaySavePosition
bool persistentConfiguration