Difference between revisions of "Digikam/GSoC2010/ReverseGeocoding"

(Add more code links.)
(Update the link to the code.)
Line 42: Line 42:
== Where is the code? ==
== Where is the code? ==
* [http://websvn.kde.org/branches/extragear/graphics/gsoc-geocoding/ gsoc-geocoding]: General place for experiments and small code snippets.
All code can be found in the [http://websvn.kde.org/branches/extragear/graphics/ kipi-plugins/digikam gsoc branch]. Reverse geocoding is implemented in the [http://websvn.kde.org/branches/extragear/graphics/kipi-plugins/gpssync gpssync kipi plugin].
* [http://websvn.kde.org/branches/extragear/graphics/kipi-plugins/gpssync2 GPSSync2]: New version of the GPSSync plugin.
* [http://websvn.kde.org/branches/extragear/graphics/digikam/worldmapwidget2 WorldMapWidget2]: Widget to display the location of images on both Google Maps and Marble. Required by GPSSync2.
* [http://websvn.kde.org/branches/extragear/graphics/libkipi-gsoc-2010/ libkipi-gosc-2010]: Modified version of libkipi to provide access to the new tag properties.
* [http://websvn.kde.org/branches/extragear/graphics/digikam/gsoc-2010/ digikam-gsoc-2010]: GSOC 2010 branch of digikam, used by all of the [[Digikam/GSoC2010|digikam GSOC projects]].
== Backends ==
== Backends ==

Revision as of 18:16, 9 July 2010

Reverse geocoding will be implemented for the new version of the GPSSync plugin as part of GSOC by Gabriel Voicu, mentored by Michael G. Hansen.

Short description

The idea of reverse geocoding is that when the coordinates on earth of an image are known, the application retrieves the associated human readable location: City, street, country, etc. and stores this information in the image. The location names can be stored in the images as new tags, allowing the user to easily search for all pictures he took in a country, city or even street.

Use Cases

Let's say you are a user who wants to have for every photo the location where it was made stored as text in the photo. Also, let's say that you have some photos with coordinates inside metadata and some photos without coordinates. All the operations will be made inside Correlator2 Widget (screenshot below).

Now, before you apply the reverse geocoding service, you need to set some parameters. All parameters will be saved in a config file, so if you are happy with your settings, you have to set them only once.

Firstly, you need to select the service that will provide your data. The choices are: Google Maps, Open Street Map or Geonames.org. You should try each of them, because they provide different results on some areas.

Secondly, you will have to check the address elements provided by the selected service. If the elements exists in the database of the selected service, you may select: Country, State, County, City, District, Street and Street number.

After you select all this, you should select the language, because you may want to have special characters in the retrieved data.

The tree view from the center of the interface gives you the possibility to select a base tag in your tag tree to let the program know where to put the new resulted "location tags". The location tags will reside on the next level below your selected base tag. For example, if you have:

  • My Tags
    • Places
    • Friends

and you select "Places" and your photo coordinates are (53.534325,-2.207343), your tag tree will be:

  • My Tags
    • Places
      • England
        • Manchester
          • M60
    • Friends

By default, the base tag will be the root tag from your tag tree, here "My Tags".

If you selected all your options and you don't want to see them anymore, you can select the "More options/Less options" button to hide all the controls listed above. If you select again the button, all these controls will be restored.

In the Correlator2 Widget, when you move a marker on the map, or when you drag-and-drop a photo on the map, coordinates are automatically added/modified. You can check the "Tag automatically when coordinates are changed" checkbox if you want to automatically geotag your photos when their coordinates are changed. This also allows you to have your photos geocoded automatically while you correlate them to your GPS track files.

You will also have an option to select where inside you photo metadata will reside the address elements. The options are:IPTC, XMP location and XMP keywords. The default value will include all three already selected, so if you don't know what this acronyms mean, you don't have to worry about them.

After setting all these parameters mentioned above, you can click the button that will automatically geotag your photos. The problem is that there isn't one button, but two buttons. The reason for adding an extra button is that you may want to appy reverse geocoding just for the selected images.


Where is the code?

All code can be found in the kipi-plugins/digikam gsoc branch. Reverse geocoding is implemented in the gpssync kipi plugin.


Google Maps

Google Maps V3 API

  • provides both reverse geocoding and elevation information
  • for a given coordinate, returns the next address elements if they exist:
    • country
    • state
    • county
    • city
    • district
    • street
    • street number

OpenStreetMap Nominatim

OSM Nominatim

  • Marble already has integration for this service
  • Address elements returned, if they exist:
    • country
    • state
    • state district
    • county
    • city
    • city district
    • street



  • provides both reverse geocoding and elevation information
  • returned address elements if they exist:
    • country
    • city
    • a list of nearby streets for non-USA
    • nearest street for USA only
    • distance from the the given coordinate to returned address

It seems that retrieving city name might be a problem with Geonames backend, because their "findNearbyPlaceName" service, which I use as backend for reverse geocoding project, provides district,street or place name instead of city name, in large cities. For small cities, the service works fine.

For example, for coordinates lat=51.225,lon=6.77667 the result is:

  • Name: Stadtbezirk 01

instead of:

  • Name: Düsseldorf

Alternatives to "findNearbyPlaceName" would be:

  • "findNearestAddress" service: This service returns all address elements, from country to street and sometimes street number. The problem is that it's for USA only.
  • "cities" service: This returns names of cities inside a bounding box, but the service won't let me select a little box enough to select only one city. Also, results aren't that accurate.
  • "findNearbyPostalCodes" return postal code for a pair of coordinate points and then find city name from that postal code. But for the abovementioned lat=51.225,lon=6.77667 this service returns many postal codes.

Storing information

Inside the image

The textual location descriptions can be stored as tags and in the dedicated location fields provided by XMP and IPTC. However, there are some competing tags which store the same information.

Digikam allows the user to choose whether he wants to have data written to his image files or not. We may want to add a host property to the kipi interface to automatically respect these settings.

In Digikam's database

For now, have a look at the document outlining database changes for the GSOC projects. Possible additions to the existing tags:

  • Coordinates of the tag.
  • Possibly introduce multi-language tags.


  • Terminology: Make sure we use a consistent name for reverse geotagging which is easily understandable to the user.
  • In order to display a tree of tags, we need to add a function to the kipi interface to read the tags from the host application.
  • Use solid to detect whether we have a network connection. If KDE thinks there is no network, warn the user, but always let him override it. Relevant code can be found in KGPG (search for networkUp): keysmanager.cpp

What if the user wants to store his tags as

  • Countries
    • Germany
    • England
  • Cities
    • Cologne
    • London


Job Status
RG backend
Looking at http://wiki.openstreetmap.org/wiki/Nominatim they seem to want us to limit the number of simultaneous connections to 1! DONE
OSM also wants us to include a user agent string, which contains a contact address, possibly [email protected] Maybe you can find out how to set the user agent on KIO::Job? DONE
Investigate what happens on errors, like when the connection to the server fails or the connection times out. How do we react and make sure we report the error to the user?
We should merge requests for the same coordinates. Have a look at the altitude backend again as a guide. Try to make it in a way that when a request has already been sent to the backend, the new request should still be merged in. DONE
Move MakeTagString into a common header file which is included by both the GUI and the test. DONE
Make backend-rg.h independent of gpsreversegeocodingwidget.h DONE
Entering of the tag destination: Think of how the input should be formatted (My Tags/{Country} of similar) and write code that creates the resulting tag names (best done in a test-case outside the UI first, see existing tests directory on how to create tests). DONE
We need to store the settings made in the RG widget UI. Look at the correlation widget to see how it's done. DONE
Finally, we need to decide whether we want to modify the tags in digikam to contain coordinates. Have a look at the database page and think about how it could be done. Try to continue with the following points until a decision is made.
We need to store the tags in the GPSImageItems und the corresponding undo/redo structures. Decide on how to store the tags in the gpsimageitems and in the undo/redo structures, the implement it. We also have to think about where to store whether the user wants XMP/IPTC updated.
Finally, we need to store the tags in the images. There is a function in GPSImageItem that updates the images, and needs to be modified.
Maybe display an invitation to donate to OSM/geonames?
Add correct licensing information to all files DONE
Review digikam coding guidelines and apply them to the code DONE

This page was last edited on 9 July 2010, at 18:16. Content is available under Creative Commons License SA 4.0 unless otherwise noted.