GeoClue2

Michael Leibowitz michael.leibowitz at intel.com
Sun Apr 17 23:35:16 PDT 2011


On Sun, 2011-04-17 at 08:49 -0700, Eckhart Wörner wrote:
> Hi everybody,
> 
> when I first encountered GeoClue some time ago, I immediately liked the idea of
> it. However, I was somehow never really satisfied with its design. Therefore,
> in the last few days I tried to write down my vision of how its D-Bus API
> should look like, and now present it here for discussion. I'll start with the
> problems the old API has in my eyes, and then present a new API that hopefully
> overcomes these problems.

You beat me to the punch.  I was about to write a similar email
discussing a geoclue redesign.  ;)

> I'll call the old API GeoClue and my API GeoClue2 only to differentiate between
> them, not because I think that my API is perfect (it probably isn't). It also
> probably helps my subject getting some attention. ;-)
> 
> 
> == Problems ==
> 
> The GeoClue API is incomplete: GeoClue Position and Velocity provide the
> coordinates of a point (which normally represents a device so close to the
> user's coordinates that we define them to be the user's coordinates) in a
> three-dimensional room (Latitude, Longitude, Altitude), and the first
> derivative (Speed, Direction, Climb). However, we still don't know the
> orientation of the device in this room.
> Why may this information be useful? E.g. a routing application for pedestrians
> can rotate the map it displays according to the heading of the device.
> 
> The GeoClue API defines several providers and puts arbitrary borders between
> them: Latitude, Longitude and Altitude share the same provider, while Speed,
> Direction and Climb share a different provider, however, e.g. an altimeter only
> provides Altitude and Climb.
> 
> The GeoClue API is overly complex in some places: to get latitude, longitude
> and speed, one has to traverse two objects, and then use two different
> providers.
> 
> The GeoClue API exposes too much information to an application that uses it:
> an application that relies on the *type* of the underlying provider clearly
> does something wrong. An application should not decide which provider to use,
> instead GeoClue2 should. An application should not configure providers, a
> dedicated interface should do that.
> 
> The GeoClue API does not differentiate between an application that needs some
> piece of information to work properly, and a piece of information that is
> nice-to-have, but not necessary. E.g. an application for navigation clearly
> needs coordinates to work properly, while a weather applet that works fine
> without coordinates might still use them when they are available.
> 
> Applications may be interested in the last known value for some piece of
> information, even though it is not valid anymore.
> 
> The GeoClue API does not cope well with unexpected application behavior like
> crashes. E.g. AddReference and RemoveReference are just asking for problems.
> 
> The GeoClue API does not play well with D-Bus: Long-running methods will break
> as D-Bus puts a timeout on method calls.

The GeoClue API/design is not terribly efficient.  One ends up with
several round-trips around DBUS for any position information.
Additionally, using DBUS in this way leaks information all over the
place.

Most of the next round of criticism focuses on getting GeoClue more
tightly integrated with positioning mechanisms.  This isn't how it is
presently designed, but as positioning mechanisms in the mobile space
are becoming more advanced and interrelated, having GeoClue be more
entwined with the mechanics of positioning will likely be required.
Actually, I'm mostly focused on positioning, as geocoding/reverse
geocoding are basically just turning around to a web service typically.

The GeoClue design of providers makes it such that making hybrid
positioning methods is difficult if not impossible.  This makes things
like dead-reckoning between position fixes nearly impossible to
implement without enabling each provider below the geoclue level.

The decision making powers and inputs to the Master Provider are too
simple to give optimal results.  The master provider has no concept of
latency or power consumption, providers have no basis to specify them,
and clients have no basis to input their requirements for either.
Furthermore the resources that providers may request are too course
grained and rigid.  For example, a satellite position provider might not
require network access to give information, but having it might enable
assistance that greatly reduces latency or increases accuracy.

The abstraction of providers also hides provider details.  This sounds
like the facts of life and a non-problem, but it actually is a problem.
There are my applications out there that want to display some detailed
status of their position fix but also want to be able to support several
positioning methods.  For example, an application might want to report
the satellites in view if it's getting a GPS signal, but display the
access points it sees for a wifi based position method.  This sounds
contrived, but consider how MeeGo's qt-mobility back-end is currently
written.  It talks to both GeoClue and Gypsy to report satellite data
for GPS fixes as well as supporting non-satellite methods.

> == Proposal ==
> 
> The GeoClue2 service is the only access point to information; there's no
> documented way of communicating with individual providers for information
> retrieval.
> 
> The main interface allows to create objects for individual applications. Any
> object created through the main interface is said to be owned by the
> respective application and should not be used by any other application.
> 
> This is the main interface:
> 
> <node>
>         <interface name="org.freedesktop.Geoclue2">
> 
>                 <method name="CreateProvider">
>                         <arg name="path" type="o" direction="out" />
>                 </method>
> 
>                 <method name="CreateAddressResolver">
>                         <arg name="path" type="o" direction="out" />
>                 </method>
> 
>                 <method name="CreateCoordinatesResolver">
>                         <arg name="path" type="o" direction="out" />
>                 </method>

How do you specify accuracy, latency, or power requirements?  When
creating the objects?  When querying them?

> 
>         </interface>
> </node>
> 
> The CoordinatesResolver is responsible for resolving coordinates to an
> address. It is used by (optionally) first setting the TargetAccuracy and then
> calling Resolve with the coordinates.
> If the resolving succeeds, the Result signal is emitted. If there is a
> permanent error resolving the coordinates, Error is emitted. An error is not
> signalled when it's only temporary. Applications which want a fixed timeout
> have to take care of this for themselves.
> Destroy cancels the ongoing operation and destroys the object; an application
> must be prepared to handle the Result and Error signals after Destroy has been
> called due to the asynchronous nature of D-Bus.
> Destroy is implicitly called when the application that created the resolver
> leaves the bus.
> 
> <node>
>         <interface name="org.freedesktop.Geoclue2.CoordinatesResolver">
> 
>                 <method name="Resolve">
>                         <arg name="latitude" type="d" direction="in" />
>                         <arg name="longitude" type="d" direction="in" />
>                         <arg name="altitude" type="d" direction="in" />
>                         <arg name="targetAccuracy" type="s" direction="in" />
>                 </method>
> 
>                 <signal name="Result">
>                         <arg name="countryCode" type="s" />
>                         <arg name="country" type="s" />
>                         <arg name="region" type="s" />
>                         <arg name="locality" type="s" />
>                         <arg name="area" type="s" />
>                         <arg name="postalCode" type="s" />
>                         <arg name="street" type="s" />
>                 </signal>
> 
>                 <signal name="Error" />
> 
>                 <method name="Destroy" />
> 
>         </interface>
> </node>

I assume street is a freely encoded house number and street?  Also, how
do you disambiguate ambiguous replies?

> 
> The AddressResolver is responsible for resolving an address to coordinates. It
> is used by (optionally) first setting the TargetAccuracy and then calling
> Resolve with the address.
> If the resolving succeeds, the Result signal is emitted. If there is a
> permanent error resolving the address, Error is emitted. An error is not
> signalled when it's only temporary. Applications which want a fixed timeout
> have to take care of this for themselves.
> Destroy cancels the ongoing operation and destroys the object; an application
> must be prepared to handle the Result and Error signals after Destroy has been
> called due to the asynchronous nature of D-Bus.
> Destroy is implicitly called when the application that created the resolver
> leaves the bus.
> 
> <node>
>         <interface name="org.freedesktop.Geoclue2.AddressResolver">
> 
>                 <method name="Resolve">
>                         <arg name="countryCode" type="s" direction="in" />
>                         <arg name="country" type="s" direction="in" />
>                         <arg name="region" type="s" direction="in" />
>                         <arg name="locality" type="s" direction="in" />
>                         <arg name="area" type="s" direction="in" />
>                         <arg name="postalCode" type="s" direction="in" />
>                         <arg name="street" type="s" direction="in" />
>                         <arg name="targetAccuracy" type="s" direction="in" />
>                 </method>
> 
>                 <signal name="Result">
>                         <arg name="Latitude" type="s" />
>                         <arg name="Longitude" type="s" />
>                         <arg name="Altitude" type="s" />
>                 </signal>
> 
>                 <signal name="Error" />
> 
>                 <method name="Destroy" />
> 
>         </interface>
> </node>
> 
> The Provider (yes, I know this is not the best name) is responsible for
> providing information about aspects of the position of the device. These
> include:
> - CountryCode, Country, Region, Locality, Area, PostalCode, Street
> - Latitude, Longitude as WGS84 coordinates
> - Altitude in meters above the reference surface of the WGS84 ellipsoid
> - Heading as the angle between the projection of the main direction of the
> device on a tangential plane and true north, in degrees
> - Elevation as the arc between the main direction of the device and a
> tangential plane, in degrees
> - Bank as the rotation on the plane defined by heading and elevation, in
> degrees
> - Speed and Direction as vector length and vector direction of the first
> derivative of (Latitude, Longitude), in km/h (?) and degrees, respectively
> - Climb as first derivative of Altitude, in m/s
> 
> The above properties are considered as not set if they contain a value that is
> not in the allowed range of values, these ranges are to be defined. If they are
> set, they contain the last valid value. One can check whether the value is
> valid via the corresponding …Valid property.
> 
> An application indicates that it needs one or more properties to function
> correctly by setting ActiveProperties to the corresponding property names.
> 
> An application indicates that one or more properties may enhance the
> application's functionality without being needed to function correctly by
> setting PassiveProperties to the corresponding property names. GeoClue2
> ensures that PassiveProperties is always a superset of ActiveProperties by
> extending PassiveProperties as needed.
> 
> GeoClue2 may try to fill properties that are only in the PassiveProperties set
> at its own discretion; it is suggested that GeoClue2 provides those values iff
> they are in the ActiveProperties of another Provider.
> 
> Communication of changes is done via the standardized PropertiesChanged
> signal.

What if I'm not interested if some of the properties change?  I don't
want to be woken up if the compass changes and I don't care about the
compass.  Might I suggest a more fine-grained approach of specifying
requirements for change notification as well?

> Destroy destroys the object; an application must be prepared to handle the
> PropertiesChanged signal after Destroy has been called due to the asynchronous
> nature of D-Bus.
> Destroy is implicitly called when the application that created the provider
> leaves the bus.
> 
> <node>
>         <interface name="org.freedesktop.Geoclue2.Provider">
> 
>                 <property name="TargetAccuracy" type="s" access="readwrite" />
> 
>                 <property name="ActiveProperties" type="as" access="readwrite" />
>                 <property name="PassiveProperties" type="as" access="readwrite" />
> 
>                 <!-- Aspects of position (and first derivative) in 3d -->
>                 <property name="Latitude" type="d" access="read" />
>                 <property name="Longitude" type="d" access="read" />
>                 <property name="Altitude" type="d" access="read" />
>                 <property name="Heading" type="d" access="read" />
>                 <property name="Elevation" type="d" access="read" />
>                 <property name="Bank" type="d" access="read" />
> 
>                 <property name="Speed" type="d" access="read" />
>                 <property name="Direction" type="d" access="read" />
>                 <property name="Climb" type="d" access="read" />
> 
>                 <property name="CountryCode" type="s" access="read" />
>                 <property name="Country" type="s" access="read" />
>                 <property name="Region" type="s" access="read" />
>                 <property name="Locality" type="s" access="read" />
>                 <property name="Area" type="s" access="read" />
>                 <property name="PostalCode" type="s" access="read" />
>                 <property name="Street" type="s" access="read" />
> 
>                 <property name="LatitudeValid" type="b" access="read" />
>                 <property name="LongitudeValid" type="b" access="read" />
>                 <property name="AltitudeValid" type="b" access="read" />
>                 <property name="HeadingValid" type="b" access="read" />
>                 <property name="ElevationValid" type="b" access="read" />
>                 <property name="BankValid" type="b" access="read" />
> 
>                 <property name="SpeedValid" type="b" access="read" />
>                 <property name="DirectionValid" type="b" access="read" />
>                 <property name="ClimbValid" type="b" access="read" />
> 
>                 <property name="CountryCodeValid" type="b" access="read" />
>                 <property name="CountryValid" type="b" access="read" />
>                 <property name="RegionValid" type="b" access="read" />
>                 <property name="LocalityValid" type="b" access="read" />
>                 <property name="AreaValid" type="b" access="read" />
>                 <property name="PostalCodeValid" type="b" access="read" />
>                 <property name="StreetValid" type="b" access="read" />
> 
>                 <method name="Destroy" />
> 
>                 <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal"
>                         value="true" />
> 
>         </interface>
> </node>

I think that making position providers as plugins or at least defining a
plugin interface should be a goal.  The ability to provide
high-bandwidth data between different providers to support hybrid
positioning information will more or less require this ability in order
for it to be efficient.

> Configuration is separated from the main functionality. It should not be used
> by an application, but only by a configuration tool. The interface is yet to be
> defined.

What is to be configured?

> As said, this API is only a draft for a redesign, and I'd therefore like to
> see tons of comments, criticism, flames, whatever ;-)
> 
> Eckhart

Cheers

-- 
Michael Leibowitz <michael.leibowitz at intel.com>



More information about the GeoClue mailing list