Using Windows GPS Location Service in a Python Script
Asked Answered
B

4

16

I have been doing some research and can't find any information on the topic. I am running a Windows 10 version that has a GPS feature for apps to use, this can be enabled or disabled by the user. I want to know how to access and use it through a python script, assuming it is even possible.

Note: I don't want any solution to get the location through an IP geolocation service. Much like using the gps service of a mobile device in android apps.

Preferably python3 libs and modules.

Brutus answered 6/6, 2017 at 22:14 Comment(1)
Only one application can access GPS data at the same time. Location API and GPS data is different. Location API use external connection but GPS work localy. I haven't any win10 device include a GPS sensor. Mean far to bid an example.Mazda
I
6

On one hand, from the Microsoft Location API documentation you will find, LocationDisp.DispLatLongReport object which has these properties:

  • Altitude
  • AltitudeError
  • ErrorRadius
  • Latitude
  • Longitude
  • Timestamp

And on the other hand by using Python pywin32 module (or ctype module), you will get access to the Windows API (or any Windows DLL), so finally you could get the Lat & Long as you want.

If you need help, to use the pywin32 module you may take a look here.

Instate answered 9/6, 2017 at 15:56 Comment(2)
How about some concrete examplesBrutus
I haven't any win10 device include a GPS sensorInstate
S
6

This may be a late response, but I have recently wanted (mostly out of curiosity) to achieve this same thing b/c my company just purchased GPS-Enabled Microsoft Surface Go tablets (running win10) to take out into the field. I wanted to create a small app that records where you are and gives you relevant data on your surroundings based on information from our own database.

The answer came with a bit of digging, and I really wanted to use pywin32 to access the Location API, but this endeavor fizzled out quickly, as there is no information on the subject and working with .dlls is not my cup of tea. (If anyone has a working example of that, please share!) I am guessing that since hardly any Windows 10 devices are equipped with GPS, there has been little to no reason to accomplish the task, especially using python...

But the answer soon came in this thread about using PowerShell commands to access the Location API. I don't have much experience with PowerShell/shelling commands with another language but I knew this could be the right path. There is a lot of information out there about using the subprocess module of python, and I should mention there are security concerns as well.

Anyways, here is a quick snippet of code that will grab your location (I have verified something very similar to this works with our GPS-Enabled Microsoft Surface Go to get accuracy to 3 meters) - the only thing (as there is always something) is that the CPU tends to be faster than the GPS, and will default to your IP/MAC address or even the wildly inaccurate cellular triangulation to get your position as fast as possible (hmm facepalm from 2016 perhaps?). Therefore there are wait commands, and I implemented an accuracy builder (this can be removed to search for a required accuracy) to make sure it searches for fine accuracy before accepting coarser values because I had issues with it grabbing cellular location too quickly, even when GPS could get me 3-meter accuracy in the same spot! If anyone is interested in this, please test/tinker and let me know if it works or not. There are undoubtedly issues that will arise with a workaround like this, so beware.

Disclaimer: I am not a computer science major nor know as much as most programmers. I am a self-taught engineer, so just know that this was written by one. If you do have insights into my code, lay it on me! I'm always learning.

import subprocess as sp
import re
import time

wt = 5 # Wait time -- I purposefully make it wait before the shell command
accuracy = 3 #Starting desired accuracy is fine and builds at x1.5 per loop

while True:
    time.sleep(wt)
    pshellcomm = ['powershell']
    pshellcomm.append('add-type -assemblyname system.device; '\
                      '$loc = new-object system.device.location.geocoordinatewatcher;'\
                      '$loc.start(); '\
                      'while(($loc.status -ne "Ready") -and ($loc.permission -ne "Denied")) '\
                      '{start-sleep -milliseconds 100}; '\
                      '$acc = %d; '\
                      'while($loc.position.location.horizontalaccuracy -gt $acc) '\
                      '{start-sleep -milliseconds 100; $acc = [math]::Round($acc*1.5)}; '\
                      '$loc.position.location.latitude; '\
                      '$loc.position.location.longitude; '\
                      '$loc.position.location.horizontalaccuracy; '\
                      '$loc.stop()' %(accuracy))

    #Remove >>> $acc = [math]::Round($acc*1.5) <<< to remove accuracy builder
    #Once removed, try setting accuracy = 10, 20, 50, 100, 1000 to see if that affects the results
    #Note: This code will hang if your desired accuracy is too fine for your device
    #Note: This code will hang if you interact with the Command Prompt AT ALL 
    #Try pressing ESC or CTRL-C once if you interacted with the CMD,
    #this might allow the process to continue

    p = sp.Popen(pshellcomm, stdin = sp.PIPE, stdout = sp.PIPE, stderr = sp.STDOUT, text=True)
    (out, err) = p.communicate()
    out = re.split('\n', out)

    lat = float(out[0])
    long = float(out[1])
    radius = int(out[2])

    print(lat, long, radius)
Stern answered 13/5, 2020 at 3:10 Comment(0)
S
3

Install winsdk with pip install winsdk

Then use this code (source):

import asyncio
import winsdk.windows.devices.geolocation as wdg


async def getCoords():
    locator = wdg.Geolocator()
    pos = await locator.get_geoposition_async()
    return [pos.coordinate.latitude, pos.coordinate.longitude]


def getLoc():
    try:
        return asyncio.run(getCoords())
    except PermissionError:
        print("ERROR: You need to allow applications to access you location in Windows settings")


print(getLoc())

It makes use of Windows.Devices.Geolocation Namespace.

Synonymy answered 20/9, 2022 at 9:42 Comment(0)
A
0
import winsdk.windows.devices.geolocation as wdg


async def getCoords():
    locator = wdg.Geolocator()
    pos = await locator.get_geoposition_async()
    return [pos.coordinate.latitude, po`enter code here`s.coordinate.longitude]
Altheta answered 25/9, 2022 at 12:38 Comment(2)
This is nothing but a poor copy/paste of (a section of) another answer.Permalloy
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From ReviewAngwantibo

© 2022 - 2024 — McMap. All rights reserved.