在Qt quick程序中从gpsd获取位置

在Qt quick程序中从gpsd获取位置,qt,gpsd,qtlocation,Qt,Gpsd,Qtlocation,我有一台带有GPS的计算机,它连接到一个串行端口,该端口运行gpsd,配置非常基本。以下是/etc/default/gpsd的内容: START_DAEMON="true" USBAUTO="false" DEVICES="/dev/ttyS0" GPSD_OPTIONS="-n -G" GPSD_SOCKET="/var/run/gpsd.sock" 通过此配置,gpsd可以正常运行,所有gpsd客户端实用程序(例如cgps、gpspipe、gpsmon)都可以从GPS获取数据 我正在尝试使

我有一台带有GPS的计算机,它连接到一个串行端口,该端口运行gpsd,配置非常基本。以下是/etc/default/gpsd的内容:

START_DAEMON="true"
USBAUTO="false"
DEVICES="/dev/ttyS0"
GPSD_OPTIONS="-n -G"
GPSD_SOCKET="/var/run/gpsd.sock"
通过此配置,gpsd可以正常运行,所有gpsd客户端实用程序(例如cgps、gpspipe、gpsmon)都可以从GPS获取数据

我正在尝试使用
PositionSource
元素从Qt QML程序访问GPS数据,该元素具有以下语法,但lat和long显示为NaN,因此无法工作:

    PositionSource {
        id: gpsPos
        updateInterval: 500
        active: true
        nmeaSource: "socket://localhost:2947"

        onPositionChanged: {
            myMap.update( gpsPos.position )
        }
     }
我尝试使用
gpspipe-r | nc-l 6000
将NMEA数据从GPS传输到另一个端口,并指定
NMASource:“socket://localhost:6000
一切正常

如何让Qt直接与gpsd对话?

在使用gps共享、吉普赛、geoclue2、serialnmea和其他方式修改(即从源代码编译、安装、配置、测试等)后,从连接到串行端口的gps访问数据(感谢Pa的所有建议),但都没有结果当gpsd在其他应用程序中完美运行时,我决定通过对QdeCrativePositionSource类进行非常粗略的更改,使Qt支持gpsd,以便在NMasource属性的URL中实现对gpsd方案的支持。通过此更改,gpsd源现在可以定义为
NMasource:gpsd://hostname:2947“
(2947是标准的gpsd端口)

更改后的代码如下所示。我建议在某个时候将其添加到Qt中,但同时,我想我需要派生这个类来在新的QML组件中实现我的更改,但是,作为QML的新手,我不知道如何完成。我想从基于gpsd的组件停止并启动NMEA流可能也是一个好主意关于PositionSource项的
active
属性…我将在某个时候讨论它,但希望您能提供一些关于如何以更优雅的方式进行此操作的建议

void QDeclarativePositionSource::setNmeaSource(const QUrl &nmeaSource)
{
    if ((nmeaSource.scheme() == QLatin1String("socket") ) 
           || (nmeaSource.scheme() == QLatin1String("gpsd"))) {
        if (m_nmeaSocket
                && nmeaSource.host() == m_nmeaSocket->peerName()
                && nmeaSource.port() == m_nmeaSocket->peerPort()) {
            return;
        }

        delete m_nmeaSocket;
        m_nmeaSocket = new QTcpSocket();

        connect(m_nmeaSocket, static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)> (&QAbstractSocket::error),
                this, &QDeclarativePositionSource::socketError);
        connect(m_nmeaSocket, &QTcpSocket::connected,
                this, &QDeclarativePositionSource::socketConnected);

        // If scheme is gpsd, NMEA stream must be initiated by writing a command
        // on the socket (gpsd WATCH_ENABLE | WATCH_NMEA flags)
        // (ref.: gps_sock_stream function in gpsd source file libgps_sock.c)
        if( nmeaSource.scheme() == QLatin1String("gpsd")) {
            m_nmeaSocket->connectToHost(nmeaSource.host(), 
                nmeaSource.port(), 
                QTcpSocket::ReadWrite);
            char const *gpsdInit = "?WATCH={\"enable\":true,\"nmea\":true}";
            m_nmeaSocket->write( gpsdInit, strlen(gpsdInit);
        } else {
            m_nmeaSocket->connectToHost(nmeaSource.host(), nmeaSource.port(), QTcpSocket::ReadOnly);
        }
    } else {
...
void QDeclarativePositionSource::setnmasource(const QUrl&nmasource)
{
if((NMasource.scheme()==QLatin1String(“套接字”))
||(nmasource.scheme()==QLatin1String(“gpsd”)){
如果(m_n)为空
&&nmasource.host()==m\u nmasocket->peerName()
&&NMasource.port()==m\u NMasocket->peerPort()){
返回;
}
删除m_nMasocket;
m_nmasocket=新的QTcpSocket();
连接(m_nMasocket、静态转换(&QAbstractSocket::error),
这是&QDeclarativePositionSource::socketError);
连接(m_NMasocket和QTcpSocket::已连接,
这,&QDecrativePositionSource::socketConnected);
//如果scheme是gpsd,则必须通过编写命令来启动NMEA流
//在插座上(gpsd WATCH_ENABLE | WATCH_NMEA标志)
//(参考:gpsd源文件libgps_sock.c中的gps_sock_流函数)
if(nmasource.scheme()==QLatin1String(“gpsd”)){
m\u NMasocket->connectToHost(NMasource.host(),
NMasource.port(),
QTcpSocket::读写);
char const*gpsdInit=“?WATCH={\'enable\':true,\'nmea\':true}”;
m_nmasocket->write(gpsdInit,strlen(gpsdInit);
}否则{
m_nmasocket->connectToHost(nmasource.host(),nmasource.port(),qtcsocket::ReadOnly);
}
}否则{
...

除非您特别需要gpsd,否则您可以关闭它并使用serialnmea定位插件直接从串行端口读取数据。另外,还有另外两个后端,geoclue2和gipsy,以及IIRC,它们都是包装gpsd的。不,您是对的,我不需要gpsd,谢谢您的建议。我查看了gipsy,发现了很多错误在构建过程中,暂且不提这一点,因为它的支持似乎很少。Geoclue安装在我的安装程序中,Qt应用程序从中获得了基于IP的位置(这很好),但它不能从串行设备或gpsd获取GPS位置。关于如何配置Geoclue以从gpsd或串行设备获取GPS位置,有什么建议吗?如果您不需要多个应用程序来读取,我建议您尝试一下serialnmea后端。至于Geoclue,我从未使用过,但可以快速搜索一下至少在几年前,geoclue和大多数gnome支持的项目一样,已经过时且不受支持。现在有了geoclue2(及其相关的QtPositioning插件),它似乎能够直接从串行数据读取数据,而无需gpsd。