stellarium icon indicating copy to clipboard operation
stellarium copied to clipboard

Use QtPositioning for location lookup

Open gzotti opened this issue 10 months ago • 14 comments

Description

Discussed in #4216

Our IP-based location lookup was a nice feature in 2014, but Qt has introduced some while ago the QtPositioning library. This can utilize the OS services for location lookup and may deliver more accurate results.

Operating systems may limit access to these services and require permissions that must be granted or can be denied.

The current implementation first tries to get permission for a high-precision lookup, if that is not granted, a low-precision lookup. If this is not granted, the previous IP-based lookup is executed.

Note that the permission system was only introduced in Qt6.5 or 6.6, so the first versions here will likely not compile in our CI.

For discussion:

  • [ ] Shall we remove the previous IP-based lookup fallback?
  • [ ] We have a contribution that uses its own QGeoPositionInfoSource for recurring position updates as alternative to GPS, but is #ifdeffed to Windows only. It may be also useful on Linux.
  • [ ] If this is difficult on Qt5, we could just exclude it there.

Screenshots (if appropriate):

Type of change

  • [ ] Bug fix (non-breaking change which fixes an issue)
  • [x] New feature (non-breaking change which adds functionality)
  • [ ] Breaking change (fix or feature that would cause existing functionality to change)
  • [x] This change requires a documentation update
  • [ ] Housekeeping

How Has This Been Tested?

Test Configuration:

  • Operating system: Win11 23H2
  • Graphics Card: irrelevant
  • Qt:
  • [x] 6.8.2
  • [x] 6.5
  • [x] 5.15.2 Attn, fallback lookup fails with "TLS initialization failed"! So, our old IP lookup fails with Qt5.

Checklist:

  • [x] My code follows the code style of this project.
  • [x] I have performed a self-review of my own code
  • [x] I have commented my code, particularly in hard-to-understand areas
  • [ ] I have made corresponding changes to the documentation (header file)
  • [ ] I have updated the respective chapter in the Stellarium User Guide
  • [ ] My changes generate no new warnings
  • [ ] I have added tests that prove my fix is effective or that my feature works
  • [ ] New and existing unit tests pass locally with my changes
  • [ ] Any dependent changes have been merged and published in downstream modules

gzotti avatar Mar 17 '25 18:03 gzotti

Hello @gzotti!

Thank you for the suggested improvement.

github-actions[bot] avatar Mar 17 '25 18:03 github-actions[bot]

Great PR! Please pay attention to the following items before merging:

Files matching src/**/*.cpp:

  • [ ] Are possibly unused includes removed?

This is an automatically generated QA checklist based on modified files.

github-actions[bot] avatar Mar 17 '25 18:03 github-actions[bot]

Given that this did not need new buttons or labels, if it works on your platforms, it could maybe even still go into 25.1.

gzotti avatar Mar 17 '25 23:03 gzotti

I do not getting coordinates/location in linux and he switches to use custom time zone when feature is disabled

alex-w avatar Mar 18 '25 03:03 alex-w

I do not getting coordinates/location in linux and he switches to use custom time zone when feature is disabled

The logfile should contain a line "Position received from OS query:...". What does it say? If the location is invalid, this should then fallback to the old version. (TODO, I assumed the reply is meaningful.)

Not sure what you mean by custom timezone. This lookup does not provide place name or timezone. I initialize the location from the current location and change a few data entries. I have left TODO notes where the timezone and light pollution could be put in. The timezone could come from the system clock (Assuming you travel somewhere far away, adjust PC to local time zone and then call this).

gzotti avatar Mar 18 '25 08:03 gzotti

Maybe the logic should be changed: Retrieve both, QtPosition (long/lat/altitude?) and old IP lookup (long/lat/0, timezone, placename, country, ...). Process data like with old solution, just replace long/lat/alt with the new data, This would retrieve at least timezone from IP lookup. The place name retrieved from IP lookup does not make sense when the actual position is tens of km away, so placename from coordinates seems OK to me.

If you then know where to get LP values for coordinates, this can be inserted where indicated by TODO.

gzotti avatar Mar 18 '25 09:03 gzotti

The logfile should contain a line "Position received from OS query:...". What does it say? If the location is invalid, this should then fallback to the old version. (TODO, I assumed the reply is meaningful.)

Nothing...

Not sure what you mean by custom timezone. This lookup does not provide place name or timezone. I initialize the location from the current location and change a few data entries. I have left TODO notes where the timezone and light pollution could be put in. The timezone could come from the system clock (Assuming you travel somewhere far away, adjust PC to local time zone and then call this).

Stellarium after startup: stellarium-008

OK, click "Get location from network": stellarium-009

In the log I see:

[   156.295][DBG ] Doing OS service lookup for location...
[   156.296][DBG ] Doing OS service lookup for location... postRequest 

nothing else :(

OK, click "Get location from network" again, to disable using this feature: stellarium-010

WTF???

alex-w avatar Mar 18 '25 11:03 alex-w

The request is handled asynchronously. The "postRequest" comment indicates request was sent off to the OS, and is expected to trigger positionUpdatedFromOS(). Hm, if the line "Position received from OS query:..." does not appear, something must be wrong with the OS location retrieval.

gzotti avatar Mar 18 '25 13:03 gzotti

Effect switching to using custom time zone can be reproduced in master too :(

alex-w avatar Mar 18 '25 14:03 alex-w

This may be caused by LocationDialog::ipQueryLocation(bool state). Not sure why it has updateTimeZoneControls(!state); -- Since 2019.

gzotti avatar Mar 18 '25 18:03 gzotti

This pull request has conflicts, please resolve those before we can evaluate the pull request.

github-actions[bot] avatar Mar 20 '25 19:03 github-actions[bot]

Conflicts have been resolved. A maintainer will review the pull request shortly.

github-actions[bot] avatar Mar 20 '25 20:03 github-actions[bot]

Shall we remove the previous IP-based lookup fallback?

Definitely no

alex-w avatar Mar 28 '25 18:03 alex-w

I see a problem in that there are two asynchronous methods called. We could call the old IP method if QtPositioning result is bad. But when the QtPositioning message reply does not even appear, should we add some wait timer that fires in this case?

gzotti avatar Mar 28 '25 18:03 gzotti

Debug messages should be more informative for users IMHO

alex-w avatar Jun 20 '25 18:06 alex-w

The big deal: how it need test for all cases of potential troubles?

alex-w avatar Jun 20 '25 18:06 alex-w

I have worked earlier this week on a desktop PC and experienced failures in StelLocationMgr::positionUpdatedFromOS(const QGeoPositionInfo &info), when a serial port was found, but no NMEA device. Now back on my notebook, pressing "Get location from GPS or system device" works again as the NMEA stuff quickly fails with port not found, then QtPositioning takes over. For debugging, we had activated extended debugging with CLI option --verbose.

The QtPositioning addon was contributed on Windows only but should actually work on all platforms where QtPositioning is working properly. I have read there may be separate plugins that may have to be activated in code first on the U*X platforms. I am not there yet.

In the last days I have modified StelLocation in this branch so that it is default-invalid (role='!'), and solved an ultimative lastResortLocation (Paris, unconditional). This alone should help avoiding #4266, you could test that on a fresh install on Linux and Mac please.

gzotti avatar Jun 20 '25 18:06 gzotti

Earlier in March I tried to extend the "location from IP" button. You said it does nothing on Linux. I now tried to remove the Windows-only limit of uwes-ufo QtPositioning extension.

A few more diagnostics show:

[    16.556][DBG ] Neither GPSD nor NMEAhelper. Try OS positionSource, one of
[    16.556][DBG ] QList("nmea", "winrt")
[    16.556][DBG ] Our QGeoPositionInfoSource is : "winrt"
[    16.556][DBG ] Setting up new positionSource...
[    16.572][DBG ] QFlags(0x1|0x2|0x4|0x8|0x10|0x20|0x40|0x80|0x100|0x200|0x400|0x800|0x1000|0x2000|0x4000|0x8000|0x10000|0x20000|0x40000|0x80000|0x100000|0x200000|0x400000|0x800000|0x1000000|0x2000000|0x4000000|0x8000000|0x10000000|0x20000000|0x40000000|0x80000000)
[    16.611][DBG ] Setting up new positionSource...done
[    16.899][DBG ] Location in progress: Long= 16.2599  Lat= 48.1814  Alt 0
[    16.899][DBG ] New location named  "GPS N48 E16"
[    16.899][DBG ] queryOK, resetting GUI

Building on WSL, I get:

[    25.627][DBG ] Neither GPSD nor NMEAhelper. Try OS positionSource, one of
[    25.627][DBG ] QList("geoclue2", "nmea")
[    25.627][DBG ] Our QGeoPositionInfoSource is: "geoclue2"
[    25.627][DBG ] Setting up new positionSource...
[    25.627][DBG ] QFlags()
[    25.627][DBG ] Setting up new positionSource...done

So, it seems the geoclue2 plugin on Ubuntu (WSL) does not behave like the winrt plugin on Windows, which may have been why the location from IP extension did not work on Linux.

(Note that the nmea is Qt's own version, not the NMEALookupHelper Florian had made with me in 2017.)

According to https://doc.qt.io/qt-6/position-plugin-geoclue2.html, the geoclue2 plugin requires installation of sudo apt install libgeoclue-2-0 and required dbus communication. I installed this and libgeoclue-2-dev but it changed nothing. I am not familiar enough with dbus. How to check if if dbus is even running on WSL?

The situation is quite stupid, admittedly. The minimal solution would probably be to fix, in master, just the fallback to lastResortLocation to hit Paris, just to find ourselves in a useful location if all else fails. The "get location from GPS or OS" button may not work on all systems. Or an ifdef OS_WIN orgy in this branch tomorrow. :-(

gzotti avatar Jun 20 '25 23:06 gzotti

Hmm... what about geoclue-2-demo and geoclue-2.0 packages to check on WSL?

alex-w avatar Jun 21 '25 08:06 alex-w

Can you please share any information what to do after installing those? I see /etc/geoclue/geoclue.conf and added an entry for stellarium similar to the firefox entry. Changed nothing.

gzotti avatar Jun 21 '25 08:06 gzotti

Hmpf...

sudo systemctl start geoclue.service
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down

And according to https://wiki.ubuntuusers.de/geoclue/, Mozilla has shut down their WiFi location service. But what to do to start dbus on WSL?

gzotti avatar Jun 21 '25 08:06 gzotti

Can you please share any information what to do after installing those? I see /etc/geoclue/geoclue.conf and added an entry for stellarium similar to the firefox entry. Changed nothing.

I'm not familiar with geoclue and I don't have hardware with incorporated GPS/GLONASS/GALILEO/BAIDU device. I'll try use GPS/GLONASS dongle.

alex-w avatar Jun 21 '25 08:06 alex-w

Ah, then probably the nmea plugin will kick in. It may work, but only for those with GPS/GLONASS hardware. But we already support operation with GPS hardware since 2017...

Alright, sorry, I think I better today deactivate again all new things around QtPositioning for non-Windows for 25.2 and open up further experiments in August, maybe on a fresh Kubuntu installed on a then-ex-Win10 workhorse. My idea was simply to provide a more accurate location when asking for a network location, But for an all-platform solution around QtPositioning, we need a workflow that incorporates the geoclue2 plugin, or that properly detects if something does not work.

gzotti avatar Jun 21 '25 08:06 gzotti

Is it working on Windows?

P.S. Technically I can test it in Linux, macOS and Haiku platforms currently

alex-w avatar Jun 21 '25 09:06 alex-w

Qt on Windows uses the "winrt" QGeoPositionInfoSource and just works. And of course whatever I did in February/March just worked. I have not tested recently what happens if I actively disallow geolocation (no tracking in system settings). But of course it is wise to test capabilities first before querying. Actually, I think the GPS button is now safe for Linux, it just doesn't provide data when geoclue isn't running. I still need to secure the "location from network" checkbox action.

gzotti avatar Jun 21 '25 09:06 gzotti

Why is all this magic with WSL needed? If you need to test on Linux, you can just use a real VM booting real Linux (e.g. a Live CD).

10110111 avatar Jun 21 '25 09:06 10110111

I just have no time to set up everything again today, sorry. Stellarium builds and runs perfectly on WSL, just an optional system service is not available. And there may be other reasons (privacy, firewalls, ...) for QGeoPositionInfoSource not delivering data. So, I will just test whether the QGeoPositionInfoSource delivers data (without test we had the fallback to not even Paris but zero), and catch and fall back to the old path if not.

gzotti avatar Jun 21 '25 09:06 gzotti

Is it fixed issue #4266 in Windows?

alex-w avatar Jun 21 '25 11:06 alex-w

I never had the problem... But I am just restricting the IP lookup to valid- tested sources, and will test with disabled network later to see if I land in Paris or in null island.

gzotti avatar Jun 21 '25 11:06 gzotti

OK, in system panel I can disallow location access to Stellarium. However, I still get a permission. Then the service doesn't deliver. Weird, but I can catch this. So be it...

gzotti avatar Jun 21 '25 11:06 gzotti