Select to view content in your preferred language

Dynamically connect a position source

1397
5
Jump to solution
06-29-2021 11:38 AM
ChristopherSwingley
Emerging Contributor

I'm using the 100.8 SDK with Qt 5.14.2 and trying to connect to a variety of GPS units with the serialnmea plugin. The issue I'm having is that the MapView is loading before the Settings can be read, so the user-specified serial port and baud rate aren't set when the PositionSource PluginParameter(s) are begin set up. I would also like to be able to reset the position source when users change the port/baud rate settings so they don't have to restart the program to try out new port/baud settings.

Can someone share some code for dynamically instantiating a MapView and associated LocationDisplay/DefaultLocationDataSource/PositionSource components for connecting GPS location to the map view? I've been able to instantiate a PositionSource with port/baud from Settings, but by the time that happens, my MapView is already instantiated and I can't figure out how to tell the MapView about the newly instantiated PositionSource. I feel like I'm missing something simple, but trial and error isn't getting me anywhere.

0 Kudos
1 Solution

Accepted Solutions
JamesBallard1
Esri Regular Contributor

@ChristopherSwingley  you're on the right track. Any Runtime object can be created programmatically via the ArcGISRuntimeEnvironment.createObject call.

const defaultDataSource = ArcGISRuntimeEnvironment.createObject("DefaultLocationDataSource");

 

https://developers.arcgis.com/qt/qml/api-reference/qml-esri-arcgisruntime-arcgisruntimeenvironment.h...

As for the PositionSource object, that will be one of Qt's objects in QML.

https://doc.qt.io/qt-5/qml-qtpositioning-positionsource.html 

We accept those on the DefaultLocationDataSource object directly:

https://developers.arcgis.com/qt/qml/api-reference/qml-esri-arcgisruntime-defaultlocationdatasource.... 

In order to use a custom QML PositionSource in QML, it may require writing some custom code since that's non-trivial to derive your own type in QML. However if the Qt-provided types provide sufficient logic you can use those directly.

View solution in original post

0 Kudos
5 Replies
JamesBallard1
Esri Regular Contributor

Hi @ChristopherSwingley ,

  We have a few samples that use similar workflows. If your plugin conforms to the QGeoPositionInfoSource class, then we can work directly with it.

You can start, stop and replace the entire data source on the LocationDisplay at any time provided that you stop it before replacing it.

Here is some sample code you can work with:

// take the default
mapView->locationDisplay()->setDataSource(new DefaultLocationDataSource(this));
mapView->locationDisplay()->start();

// then later on, if you want to change it to a custom data source:

mapView->locationDisplay()->stop();

auto* newSource = DefaultLocationDataSource(this);
newSource->setPositionInfoSource(myCustomPositionInfoSource);

mapView->locationDisplay()->setDataSource(newSource);

mapView->locationDisplay()->start();

 

You can replace this as many times as needed until it's configured properly. You can also delay setting any locationDisplay settings at all until you have them configured and ready.

Here are some samples where we show the basic workflows of the LocationDisplay and LocationDataSource.

https://github.com/Esri/arcgis-runtime-samples-qt/tree/main/ArcGISRuntimeSDKQt_CppSamples/Maps/ShowL...

https://github.com/Esri/arcgis-runtime-samples-qt/tree/main/ArcGISRuntimeSDKQt_CppSamples/Maps/Displ...

https://github.com/Esri/arcgis-runtime-samples-qt/tree/main/ArcGISRuntimeSDKQt_CppSamples/Maps/Displ...

 

0 Kudos
ChristopherSwingley
Emerging Contributor

Thanks @JamesBallard1 . I realize in seeing your reply that I completely failed to mention that I'm working in QML, not C++ (with the exception of hacking the serialnmea plugin code). That said, it seems as though most of what you've written can be translated into QML:

mapView.locationDisplay.dataSource = defaultLocationDataSource;
mapView.locationDisplay.start();

// User changes port/baud settings

mapView.locationDisplay.stop();
// instantiate a newPostitionSource with different PluginParameters (?)
// instantiate a newDefaultLocationDataSource using PositionSource
newDefaultLocationDataSource.positionInfoSource = newPositionSource
mapView.locationDisplay.dataSource = newDefaultLocationDataSource;
mapView.locationDisplay.start();

But I am a little fuzzy on how to create a new PositionSource and DefaultLocationDataSource in QML/JavaScript. Would that be using Qt.createComponent()/component.createObject(), or maybe Qt.createQmlObject()?

0 Kudos
JamesBallard1
Esri Regular Contributor

@ChristopherSwingley  you're on the right track. Any Runtime object can be created programmatically via the ArcGISRuntimeEnvironment.createObject call.

const defaultDataSource = ArcGISRuntimeEnvironment.createObject("DefaultLocationDataSource");

 

https://developers.arcgis.com/qt/qml/api-reference/qml-esri-arcgisruntime-arcgisruntimeenvironment.h...

As for the PositionSource object, that will be one of Qt's objects in QML.

https://doc.qt.io/qt-5/qml-qtpositioning-positionsource.html 

We accept those on the DefaultLocationDataSource object directly:

https://developers.arcgis.com/qt/qml/api-reference/qml-esri-arcgisruntime-defaultlocationdatasource.... 

In order to use a custom QML PositionSource in QML, it may require writing some custom code since that's non-trivial to derive your own type in QML. However if the Qt-provided types provide sufficient logic you can use those directly.

0 Kudos
ChristopherSwingley
Emerging Contributor

@JamesBallard1 Thanks. For dynamically creating the QML PositionSource I use the Qt.createComponent/component.createObject, yes? Which presumably means I need to create a new QML file containing a PositionSource { } to pass into Qt.createComponent.

Or maybe changing the PluginParameter(s) on an existing PositionSource (serialnmea in my case) causes it to disconnect and reconnect to a different port, after which I can connect it to the new DefaultLocationDataSource? I feel like I've tried this approach and it didn't work.

0 Kudos
JamesBallard1
Esri Regular Contributor

@ChristopherSwingley  your approach should work just fine. You could also just declare the PositionSource in the same qml file

// for example
PositionSource {
    id: positionSourceSimulated
    nmeaSource: "qrc:///Resources/nmeaSimulation.txt"
}
0 Kudos