Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ set(MM_SRCS
ios/iosutils.cpp
position/providers/abstractpositionprovider.cpp
position/providers/internalpositionprovider.cpp
position/providers/networkpositionprovider.cpp
position/providers/positionprovidersmodel.cpp
position/providers/simulatedpositionprovider.cpp
position/providers/nmeaparser.cpp
position/tracking/abstracttrackingbackend.cpp
position/tracking/internaltrackingbackend.cpp
position/tracking/positiontrackinghighlight.cpp
Expand Down Expand Up @@ -122,8 +124,10 @@ set(MM_HDRS
ios/iosutils.h
position/providers/abstractpositionprovider.h
position/providers/internalpositionprovider.h
position/providers/networkpositionprovider.h
position/providers/positionprovidersmodel.h
position/providers/simulatedpositionprovider.h
position/providers/nmeaparser.h
position/tracking/abstracttrackingbackend.h
position/tracking/internaltrackingbackend.h
position/tracking/positiontrackinghighlight.h
Expand Down
8 changes: 5 additions & 3 deletions app/appsettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ QVariantList AppSettings::savedPositionProviders() const
QStringList provider;
provider << settings.value( "providerName" ).toString();
provider << settings.value( "providerAddress" ).toString();
provider << settings.value( "providerType" ).toString();
providers.push_back( provider );
}

Expand All @@ -238,15 +239,16 @@ void AppSettings::savePositionProviders( const QVariantList &providers )
{
QVariantList provider = providers[i].toList();

if ( provider.length() < 2 )
if ( provider.length() < 3 )
{
CoreUtils::log( QStringLiteral( "AppSettings" ), QStringLiteral( "Tried to save provider without sufficient data" ) );
continue;
}
settings.setArrayIndex( i );

settings.setValue( "providerName", providers[i].toList()[0] );
settings.setValue( "providerAddress", providers[i].toList()[1] );
settings.setValue( "providerName", provider[0] );
settings.setValue( "providerAddress", provider[1] );
settings.setValue( "providerType", provider[2] );
}
settings.endArray();
}
Expand Down
73 changes: 43 additions & 30 deletions app/position/positionkit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "position/providers/internalpositionprovider.h"
#include "position/providers/simulatedpositionprovider.h"
#include "providers/networkpositionprovider.h"
#ifdef ANDROID
#include "position/providers/androidpositionprovider.h"
#include <android/log.h>
Expand Down Expand Up @@ -122,53 +123,59 @@ AbstractPositionProvider *PositionKit::constructProvider( const QString &type, c
{
QString providerType( type );

// currently the only external provider is bluetooth, so manually set internal provider for platforms that
// do not support reading bluetooth serial
// set internal provider for platforms that do not support reading bluetooth serial
#ifndef HAVE_BLUETOOTH
providerType = QStringLiteral( "internal" );
#endif

if ( providerType == QStringLiteral( "external" ) )
if ( providerType == QStringLiteral( "external_bt" ) )
{
#ifdef HAVE_BLUETOOTH
AbstractPositionProvider *provider = new BluetoothPositionProvider( id, name, *mPositionTransformer );
QQmlEngine::setObjectOwnership( provider, QQmlEngine::CppOwnership );
return provider;
#endif
}
else // type == internal

if ( providerType == QStringLiteral( "external_ip" ) )
{
if ( id == QStringLiteral( "simulated" ) )
{
AbstractPositionProvider *provider = new SimulatedPositionProvider( *mPositionTransformer );
QQmlEngine::setObjectOwnership( provider, QQmlEngine::CppOwnership );
return provider;
}
AbstractPositionProvider *provider = new NetworkPositionProvider( id, name, *mPositionTransformer );
QQmlEngine::setObjectOwnership( provider, QQmlEngine::CppOwnership );
return provider;
}

// type == internal
if ( id == QStringLiteral( "simulated" ) )
{
AbstractPositionProvider *provider = new SimulatedPositionProvider( *mPositionTransformer );
QQmlEngine::setObjectOwnership( provider, QQmlEngine::CppOwnership );
return provider;
}
#ifdef ANDROID
if ( id == QStringLiteral( "android_fused" ) || id == QStringLiteral( "android_gps" ) )
if ( id == QStringLiteral( "android_fused" ) || id == QStringLiteral( "android_gps" ) )
{
const bool fused = ( id == QStringLiteral( "android_fused" ) );
if ( fused && !AndroidPositionProvider::isFusedAvailable() )
{
const bool fused = ( id == QStringLiteral( "android_fused" ) );
if ( fused && !AndroidPositionProvider::isFusedAvailable() )
{
// TODO: inform user + use AndroidPositionProvider::fusedErrorString() output?
// TODO: inform user + use AndroidPositionProvider::fusedErrorString() output?

// fallback to the default - at this point the Qt Positioning implementation
AbstractPositionProvider *provider = new InternalPositionProvider( *mPositionTransformer );
QQmlEngine::setObjectOwnership( provider, QQmlEngine::CppOwnership );
return provider;
}
__android_log_print( ANDROID_LOG_INFO, "CPP", "MAKE PROVIDER %d", fused );
AbstractPositionProvider *provider = new AndroidPositionProvider( fused, *mPositionTransformer );
QQmlEngine::setObjectOwnership( provider, QQmlEngine::CppOwnership );
return provider;
}
#endif
else // id == devicegps
{
// fallback to the default - at this point the Qt Positioning implementation
AbstractPositionProvider *provider = new InternalPositionProvider( *mPositionTransformer );
QQmlEngine::setObjectOwnership( provider, QQmlEngine::CppOwnership );
return provider;
}
__android_log_print( ANDROID_LOG_INFO, "CPP", "MAKE PROVIDER %d", fused );
AbstractPositionProvider *provider = new AndroidPositionProvider( fused, *mPositionTransformer );
QQmlEngine::setObjectOwnership( provider, QQmlEngine::CppOwnership );
return provider;
}
#endif

// id == devicegps
{
AbstractPositionProvider *provider = new InternalPositionProvider( *mPositionTransformer );
QQmlEngine::setObjectOwnership( provider, QQmlEngine::CppOwnership );
return provider;
}
}

Expand Down Expand Up @@ -201,8 +208,10 @@ AbstractPositionProvider *PositionKit::constructActiveProvider( AppSettings *app
}
else
{
// find name of the active provider
// find name & type of the active provider
QString providerName;
// Migration from single external provider to multiple currently, missing type == bluetooth provider
QString providerType = QStringLiteral( "external_bt" );
QVariantList providers = appsettings->savedPositionProviders();

for ( const auto &provider : providers )
Expand All @@ -217,10 +226,14 @@ AbstractPositionProvider *PositionKit::constructActiveProvider( AppSettings *app
if ( providerData[1] == providerId )
{
providerName = providerData[0].toString();
if ( !providerData.at( 2 ).isNull() )
{
providerType = providerData[2].toString();
}
}
}

return constructProvider( QStringLiteral( "external" ), providerId, providerName );
return constructProvider( providerType, providerId, providerName );
}
}

Expand Down
5 changes: 5 additions & 0 deletions app/position/positiontransformer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ GeoPosition PositionTransformer::processBluetoothPosition( GeoPosition geoPositi
return geoPosition;
}

GeoPosition PositionTransformer::processNetworkPosition( const GeoPosition &geoPosition )
{
return processBluetoothPosition( geoPosition );
}

GeoPosition PositionTransformer::processAndroidPosition( GeoPosition geoPosition )
{
if ( geoPosition.elevation != std::numeric_limits<double>::quiet_NaN() )
Expand Down
8 changes: 8 additions & 0 deletions app/position/positiontransformer.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ class PositionTransformer : QObject
*/
GeoPosition processBluetoothPosition( GeoPosition geoPosition );

/**
* Transform the elevation if the user sets custom vertical CRS. The elevation gets recalculated to ellipsoid elevation
* and then back to orthometric based on specified CRS.
* \note This method should be used only with NetworkPositionProvider to mitigate unnecessary transformations
* \return Copy of passed geoPosition with processed elevation and elevation separation.
*/
GeoPosition processNetworkPosition( const GeoPosition &geoPosition );

/**
* Transform the elevation from EPSG:4979 (WGS84 (EPSG:4326) + ellipsoidal height) to specified geoid model
* (by default EPSG:9707 (WGS84 + EGM96))
Expand Down
15 changes: 2 additions & 13 deletions app/position/providers/bluetoothpositionprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,8 @@
#include <QPermissions>
#endif

NmeaParser::NmeaParser() : QgsNmeaConnection( new QBluetoothSocket() )
{
}

QgsGpsInformation NmeaParser::parseNmeaString( const QString &nmeaString )
{
mStringBuffer = nmeaString;
processStringBuffer();
return mLastGPSInformation;
}

BluetoothPositionProvider::BluetoothPositionProvider( const QString &addr, const QString &name, PositionTransformer &positionTransformer, QObject *parent )
: AbstractPositionProvider( addr, QStringLiteral( "external" ), name, positionTransformer, parent )
: AbstractPositionProvider( addr, QStringLiteral( "external_bt" ), name, positionTransformer, parent )
, mTargetAddress( addr )
{
mSocket = std::unique_ptr<QBluetoothSocket>( new QBluetoothSocket( QBluetoothServiceInfo::RfcommProtocol ) );
Expand Down Expand Up @@ -214,6 +203,6 @@ void BluetoothPositionProvider::positionUpdateReceived()
GeoPosition positionData = GeoPosition::fromQgsGpsInformation( data );
GeoPosition transformedPosition = mPositionTransformer->processBluetoothPosition( positionData );

emit positionChanged( positionData );
emit positionChanged( transformedPosition );
}
}
21 changes: 2 additions & 19 deletions app/position/providers/bluetoothpositionprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,12 @@
#ifndef BLUETOOTHPOSITIONPROVIDER_H
#define BLUETOOTHPOSITIONPROVIDER_H

#include "abstractpositionprovider.h"

#include "qgsnmeaconnection.h"

#include <QBluetoothSocket>
#include <QBluetoothLocalDevice>
#include <QTimer>

/**
* NmeaParser is a big hack how to reuse QGIS NmeaConnection function in order to (a) keep ownership of bluetooth
* socket, (b) do not have multiple unique_ptrs holding the same pointer and to avoid some possible crashes.
*
* Note: This way of reusing makes the parser highly dependent on QgsNmeaConnection class and any change inside the class
* can lead to misbehavior's. See implementation of QgsNmeaConnection and QgsGpsConnection for more details.
*/
class NmeaParser : public QgsNmeaConnection
{
public:
NmeaParser();

// Takes nmea string and returns gps position
QgsGpsInformation parseNmeaString( const QString &nmeaString );
};
#include "abstractpositionprovider.h"
#include "nmeaparser.h"

/**
* BluetoothPositionProvider initiates connection to bluetooth device
Expand Down
Loading
Loading