3

I am looking for a solution to connect a GPS-device on a COM-Port in QGIS 3 using Python. The GPS is working in the QGIS 3 GPS Gui as it should. As there are many changes between QGIS 2 and 3 the examples of accessing a GPS device with Python in QGIS 2 ( Connect / Disconnect GPS device via PyQGIS ) are not working for QGIS 3 anymore.

Examples of working code using the different GPS-classes form QGIS 3 are not available.

Using

from qgis.core import *
QgsGpsDetector.availablePorts()

results in a list of the available ports like:

[('internalGPS', 'Interes GPS'), ('localhost:2947:', 'Lokaler GPSD'), ('COM1', 'COM1: Kommunikationsanschluss'), ('COM6', 'COM6: Standardmäßgige Seriell-über-Bluetooth-Verbindung'), ('COM5', 'COM5: Standardmäßgige Seriell-über-Bluetooth-Verbindung'), ('COM4', 'COM4: ')]

By looking at the API at https://qgis.org/pyqgis/3.0/core/Gps/QgsGpsConnection.html the QgsGpsConnection should be the way to go. In QGIS 3 it is not possible to use a string for the port using QgsGpsConnection. It has to be QIODevice. So I tried using

from qgis.core import *
from PyQt5.QtSerialPort import QSerialPort
port = QSerialPort("COM5")
QgsGpsConnection(port)

At this point I am stuck. I used several ways of QgsGpsConnection() like

QgsGpsConnnection.connect(port) 

con = QgsGpsConnection(port)
con.connect()

but I always recieve an TypeError: qgis._core.QgsGpsConnection represents a C++ abstract class and cannot be instantiated .

As I am new to Python in QGIS I do not know how to go on. My goal is to access the XY-Position and the accuracy of the signal.

0
2

My GPS test tool for QGIS 3.4 console. To deactivate select another tool:

class GPS(QgsMapTool):
    def __init__(self, iface):
        self.iface=iface
        self.prj=QgsProject().instance()
        self.canvas = self.iface.mapCanvas() 
        super(GPS, self).__init__(self.canvas)
        try:
            self.gps_active = False
            #transformation
            self.src_crs = QgsCoordinateReferenceSystem("EPSG:4326")
            self.dest_crs = self.prj.crs()
            self.transformation = QgsCoordinateTransform(self.src_crs, self.dest_crs, self.prj)
            self.marker = None
            #gps
            self.gpsCon = None
            self.port ="COM5"
            self.gpsDetector = QgsGpsDetector(self.port)
            self.gpsDetector.detected[QgsGpsConnection].connect(self.connection_succeed)
            self.gpsDetector.detectionFailed.connect(self.connection_failed)
            self.gpsDetector.advance()
        except Exception as e:
            print(e)    

    def deactivate(self):
        try:
            print ('GPS deactivated')
            if self.gpsCon is not None:
                self.gpsCon.close()
            if self.canvas is not None:
                self.canvas.scene().removeItem(self.marker)
            self.gps_active = False
        except Exception as e:
            print(e)

    def connection_succeed(self, connection):
        try:
            print("GPS connected")
            self.gps_active = True
            self.gpsCon = connection
            self.gpsCon.stateChanged.connect(self.status_changed)
            #marker
            self.marker = QgsVertexMarker(self.canvas)
            self.marker.setColor(QColor(255, 0, 0))  # (R,G,B)
            self.marker.setIconSize(10)
            self.marker.setIconType(QgsVertexMarker.ICON_CIRCLE)
            self.marker.setPenWidth(3)
        except Exception as e:
            print(e)

    def connection_failed(self):
        if not self.gps_active:
            print('GPS connection failed')

    def status_changed(self,gpsInfo):
        try:
            if self.gpsCon.status() == 3: #data received
                print('fixMode:', gpsInfo.fixMode)
                print('pdop:', gpsInfo.pdop)
                print('satellitesUsed:', gpsInfo.satellitesUsed)
                print('longitude:',gpsInfo.longitude)
                print('latitude',gpsInfo.latitude)
                print('=====')
                wgs84_pointXY = QgsPointXY(gpsInfo.longitude, gpsInfo.latitude)
                wgs84_point = QgsPoint(wgs84_pointXY)
                wgs84_point.transform(self.transformation)
                x = wgs84_point.x()
                y = wgs84_point.y()
                mapPointXY = QgsPointXY(x, y)
                if gpsInfo.pdop >= 1:  # gps ok
                    self.marker.setColor(QColor(0, 200, 0))
                else:
                    self.marker.setColor(QColor(255, 0, 0))            
                self.marker.setCenter(mapPointXY)
                self.marker.show()
                self.canvas.setCenter(mapPointXY)
        except Exception as e:
            print(e)


tool=GPS(iface)
iface.mapCanvas().setMapTool(tool)
1

Abstract classes can be used only as a base class of other classes. There are three classes inherited from QgsGpsConnection. See the class diagram in the docs: enter image description here

So try to instantiate a QgsNmeaConnection or QgsGpsdConnection or QgsQtLocationConnection.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.