Tuesday, September 5, 2017

Simple geolocation in Ubuntu 14 04

Simple geolocation in Ubuntu 14 04


Geolocation means figuring out where a spot on the Earth is.

Usually, its the even more limited question where am I?


GeoClue


The default install of Ubuntu includes GeoClue, a dbus service that checks IP address and GPS data. Since 2012, when I last looked at GeoClue, its changed a bit, and it has more backends available in the Ubuntu Repositories.

 

Privacy

Some commenters on the interwebs have claimed that GeoClue is privacy-intrusive. Its not. It merely tries to figure out your location, which can be handy for various services on your system. It doesnt share or send your location to anybody else.

dbus introspection and d-feet

You would expect that a dbus application like GeoClue would be visible using a dbus introspection tool like d-feet (provided by the d-feet package).

But theres a small twist: D-feet can only see dbus applications that are running. It can only see dbus applications that active, or are inactive daemons.

Its possible (and indeed preferable in many circumstances) to write a dbus application that is not a daemon - it starts at first connection, terminates when complete, and restarts at the next connection. D-feet cannot see these when they are not running.

Back in 2012, GeoClue was an always-on daemon, and always visible to d-feet.
But in 2014 GeoClue is (properly) no longer a daemon, and d-feet wont see GeoClue if its not active.

This simply means we must trigger a connection to GeoClue to make it visible.
Below are two ways to do so: The geoclue-test-gui application, and a Python3 example.




geoclue-test-gui


One easy way to see GeoClue in action, and to make it visible to d-feet, is to use the geoclue-test-gui application (included in the geoclue-examples package)

$ sudo apt-get install geoclue-examples
$ geoclue-test-gui





GeoClue Python3 example


Once GeoClue is visible in d-feet (look in the session tab), you can see the interfaces and try them out.

Heres an example of the GetAddress() and GetLocation() methods using Python3:

>>> import dbus

>>> dest = "org.freedesktop.Geoclue.Master"
>>> path = "/org/freedesktop/Geoclue/Master/client0"
>>> addr_interface = "org.freedesktop.Geoclue.Address"
>>> posn_interface = "org.freedesktop.Geoclue.Position"

>>> bus = dbus.SessionBus()
>>> obj = bus.get_object(dest, path)
>>> addr_iface = dbus.Interface(obj, addr_interface)
>>> posn_iface = dbus.Interface(obj, posn_interface)

>>> addr_iface.GetAddress()
(dbus.Int32(1404823176), # Timestamp
dbus.Dictionary({
dbus.String(locality) : dbus.String(Milwaukee),
dbus.String(country) : dbus.String(United States),
dbus.String(countrycode): dbus.String(US),
dbus.String(region) : dbus.String(Wisconsin),
dbus.String(timezone) : dbus.String(America/Chicago)},
signature=dbus.Signature(ss)),
dbus.Struct( # Accuracy
(dbus.Int32(3),
dbus.Double(0.0),
dbus.Double(0.0)),
signature=None)
)

>>> posn_iface.GetPosition()
(dbus.Int32(3), # Num of fields
dbus.Int32(1404823176), # Timestamp
dbus.Double(43.0389), # Latitude
dbus.Double(-87.9065), # Longitude
dbus.Double(0.0), # Altitude
dbus.Struct((dbus.Int32(3), # Accuracy
dbus.Double(0.0),
dbus.Double(0.0)),
signature=None))

>>> addr_dict = addr_iface.GetAddress()[1]
>>> str(addr_dict[locality])
Milwaukee

>>> posn_iface.GetPosition()[2]
dbus.Double(43.0389)
>>> posn_iface.GetPosition()[3]
dbus.Double(-87.9065)
>>> lat = float(posn_iface.GetPosition()[2])
>>> lon = float(posn_iface.GetPosition()[3])
>>> lat,lon
(43.0389, -87.9065)

Note: Geoclues accuracy codes



Ubuntu GeoIP Service


When you run geoclue-test-gui, you discover that only one backend service is installed with the default install of Ubuntu - the Ubuntu GeoIP service.

The Ubuntu GeoIP service is provided by the geoclue-ubuntu-geoip package, and is included with the default install of Ubuntu 14.04. It simply queries an ubuntu.com server, and parses the XML response.

You can do it yourself, too:

$ wget -q -O - http://geoip.ubuntu.com/lookup

<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Ip>76.142.123.22</Ip>
<Status>OK</Status>
<CountryCode>US</CountryCode>
<CountryCode3>USA</CountryCode3>
<CountryName>United States</CountryName>
<RegionCode>WI</RegionCode>
<RegionName>Wisconsin</RegionName>
<City>Milwaukee</City>
<ZipPostalCode></ZipPostalCode>
<Latitude>43.0389</Latitude>
<Longitude>-87.9065</Longitude>
<AreaCode>414</AreaCode>
<TimeZone>America/Chicago</TimeZone>
</Response>




GeoIP


The default install of Ubuntu 14.04 also includes (the confusingly-named) GeoIP. While it has the prefix Geo, its not a geolocator. Its completely unrelated to the Ubuntu GeoIP service. Instead, GeoIP is a database the IP addresses assigned to each country, provided by the geoip-database package. Knowing the country of origin of a packet or server or connection can be handy.

geoip-database has many bindings, including Python 2.7 (but sadly not Python 3). Easiest is the command line, provided by the additional geoip-bin package.

$ sudo apt-get install geoip-bin
$ geoiplookup 76.45.203.45
GeoIP Country Edition: US, United States




GeocodeGlib


Back in 2012, I compared the two methods of geolocation in Ubuntu: GeoClue and GeocodeGlib. GeocodeGlib was originally intended as a smaller, easier to maintain replacement for GeoClue. But as we have already seen, GeoClue has thrived instead of withering. The only two packages that seem to require GeocodeGlib in 14.04 are gnome-core-devel and gnome-clocks
GeocodeGlib, provided by the libgeocode-glib0 package, is no longer included with a default Ubuntu installation anymore, but it is easily available in the Software Center.

sudo apt-get install gir1.2-geocodeglib-1.0


That is the GTK introspection package for geocodeglib, and it pulls in libgeocode-glib0 as a dependency. The introspection package is necessary.

Useful documentation and code examples are non-existent. My python code sample from 2012 no longer works. Its easy to create a GeocodeGlib.Place() object, and to assign various values to it (town name, postal code, state), but I cant figure out how to get GeocoddeGlib to automatically determine and fill in other properties. So even though it seems maintained, Im not recommending it as a useful geolocation service.

download file now

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.