Get mobile device orientation with respect to North

I use QField to document landscape features. In many cases the azimuthal angle (alternatively the bearing) is of relevance.
Also when taking a picture it is usually relevant to know in which direction the picture was taken. I am a user and not a developer, so I ask a bit of patience. In any case I have tried to do my homework.

I will use the term DIRECTION in my question to refer to the angle with respect to the north (From 0 to 359). The term ORIENTATION is most commonly used for Vertical vs. Horizontal image “format”.

I have been searching a lot and reading whatever I could find on this, but I am unable to find a concrete answer to the issue (at least at my knowledge level). Among the things that I have read are:

  1. https://gis.stackexchange.com/questions/376773/direction-of-taken-photo-qfield
    –This one covers extraction of the ORIENTATION from the EXIF data from the picture. However, it should be noted that:
    a. Not all devices/apss store neither the orientation nor the direction in the EXIF data.
    b. If at all, then it is usually the ORIENTATION (Vertical vs. Horizontal) information that is stored.
    c. The discussion focuses on post-processing extraction.

  2. https://gis.stackexchange.com/questions/388378/store-and-use-compass-and-dip-with-qfield
    – This question is much closer related to my question, however the final answer is that is a feature request and there is a link to the request (see Nr. 3 below)

  3. Feature request: geologic compass · Issue #1882 · opengisch/QField · GitHub
    – There is an interesting discussion on the request, but no definite answer. However, from the last entry, I understand that information from a third party app (like Rockd) may be streamed through TCP or UDP sockets and captured by QField. This sounds promissing, but my development/hardware knowledge are not that far reaching, that I could setup something like this.

  4. Enhancement - add expression variable to record Orientation · Issue #3072 · opengisch/QField · GitHub
    – This one also seems to deal with my issue. It appears closed after pointing to QField/src/core/utils/fileutils.cpp at master · opengisch/QField · GitHub
    Yet another discussion points to (which is similar to the previous one).
    QField/src/core/utils/expressioncontextutils.cpp at master · opengisch/QField · GitHub

However, I am uncertain if the GPS Orientation (whatever that means) will return the DIRECTION of say the picture/camera is pointo towards. Also, I can make little out of this code. I need to know how I would call this into an attribute on a layer.
Could it be as simple as using the variable position_orientation or simply orientation in an expression while setting up the QField project?

  1. No more use of the Open Camera app and therefore less image metadata since Android 11 update · Issue #2042 · opengisch/QField · GitHub
    Finally, from the closing comments in this discussion, is this information stored per-default when using the BuiltIn camera? Which would again close the loop to the discussion presented in Nr. 1 above…pffffff

If it turns out that the solution is already there and it is just my lack of knowledge what is preventing me from solving this, I have the feeling that this is a quite common “nice to have” and would be much welcomed to have it clearly treated in the QFIELD Documentation.


Imported from GitHub discussion by @ranleu on 2024-06-03T08:24:09Z

ranleu , you came pretty close to the answer by yourself :slight_smile:

you can use the position_orientation (or gnss_orientation when not locked into the gnss device’s position during ditiziting) in a default value expression to retrieve that value while digitizing.

It should be added to the documentation here (Positioning (GNSS) - QField Ecosystem Documentation).


Imported from GitHub comment by @nirvn on 2024-06-03T08:30:44Z

Thank you for the quick reply. Just for my understanding, is mobile devices magnetometer the source of the orientation for the position_orientation variable?


Imported from GitHub comment by @ranleu on 2024-06-03T09:07:08Z

ranleu , correct.


Imported from GitHub comment by @nirvn on 2024-06-03T09:08:15Z

This just does not work for me. Nothing is displayed.

This just does not work for me. Nothing is displayed. This is on Android with newest QField version and I am using @position_orientation as default in a decimal field. The orientation of my phone is shown correctly in QField, but the field is empty.

Hi @gsommer ,

I just tested with a layer with a decimal and a string using the variable @position_orientation, and it worked correctly for me.

One thing to note is that when using the @position_ variables, you need to activate “Coordinate cursor” to locked.

But with the variables with @gnss_ will always work,

Could you try activating this or using the variable @gnss_orientation?

Hi, thank you for your response.

gnss_position also shows “nan”, which I interpret as not-a-number. The coordinate cursor is locked. It does not make a difference.

I am using a UBLOX ZED-F9P connected with USB and the GNSS Master app as NTRIP client and mock location provider on a galaxy S23 phone with latest Android. As the GNSS does not provide any orientation when not moving, I was assuming that the compass orientation of the phone is read out by QField and used as a value for this variable. The compass orientation certainly is shown on the map as a blue cone. So QField is reading this correctly, but not populating the variable correctly.

OK, I see what happens now. I actually need the coordinate cursor unlocked to make it work. Unlocked meaning the icon is grey like in your screenshot instead of blue. I always thought I needed it blue (locked) to have the cursor move along with the current location, but this actually locks it to the map. This is confusing and I do not really understand why this button is there at all. But I guess my measurements were always wrong before.

But @gnss… also only works when the lock icon is greyed out (unlocked), same as @position…

Thank you for opening my eyes. It is astonishing that it always seemed to work though, but so far I was only testing the new GNSS on a few known points.

I tried it out more and I did everything right before. The only way to make sure that I am recording the correct position and the only way to be able to average out this position is, when the lock button is active (cursor locked message displayed, button color is blue and there is a frame around the circle, the opposite to what you show in the screenshot and when none of the orientation variables have a valid value!). This way the cursor is locked to the current position of the antenna, which I need to record the correct coordinates. But then I cannot record the orientation. This is just opposite to how it should be.

The orientation does not make sense at all, if the cursor is somewhere off the position I want to record, which can only happen, if I do not lock it. It just needs an involuntary tap on the map and I am recording the wrong coordinates without the locking.

At least @gnss_orientation should work when I am locked to the antenna position, if not both. But this is not the case.

@gsommer , your last message contained an important keyword that revealed the issue your facing.

The orientation value attached to the @{gnss,positioning}_orientation variable was wrong for averaged positioning, while non-averaged positioning reading had a proper value. That explains why the issue could not be replicated prior to that crucial detail :slight_smile:

The good news is, it has been addressed and will be fixed in the next QField version (ETA mid December, 2025). In the meantime, you can try the APK attached to the fix pull request on github (Fix averaged position information missing orientation and imu details by nirvn · Pull Request #6793 · opengisch/QField · GitHub) to confirm it is working for you. The APKs will appear in roughly 10 minutes from the time I write this.

Thank you! It works now and I can wait, as long as I know that I just need to avoid averaging for now.

1 Like