Digikam/GSoC2010/ReverseGeocoding

From KDE Community Wiki
Revision as of 19:05, 11 August 2010 by Mghansen256 (talk | contribs) (Add TODO for "Improved Map Search")

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 all his photos geotagged. Of course, you can take them one by one and add geotag them manually. But what happens when you have thousands of photos? The solution comes from the Reverse Geocoding widget (which can be found in Geolocation widget) that does the job for you with just some clicks.

But how will this widget do the job? Well, first you need to set some parameters.Don't worry, you will have to set them only once if you're happy with them.

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

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

The tag tree from the center of the widget will be the place where all the fun will take place. I will make a step-by-step tutorial, to show how to work with it. At first, here is the widget, with the tag tree located in the center:

Let's say you want to add your new geotags as childs of "Places" tag, so you right-click it and a menu appears.

Before I explain what does each menu element, I should tell you how this works: when you select an address element tag from the menu, a control tag(coloured with red) appears as a child of parent tag. This way, when applying the reverse geocoding service, it will know where to add the new geotags. Don't worry about the control tags, because they will not be added as tags to your host application(here digiKam).

Now, let's get back to menu elements. The menu elements gives you the possibility to select what control tags will you want to add. So, you will have country tag, county tag, city tag... or you can click "Add all address elements" and all control tags(each containing a different address element) will be added, sorted by scale(country is bigger than city).

Up there, I clicked the "Add all address elements" menu item and all control tags added properly below the "Places" tag. Now, it's time to retrieve some data. Select you images in the lower-left list (I've selected all) and click "Apply reverse geocoding" button. The data will be added guided by the control tags:

Ok, now you have the intermediate tags(coloured in green). I called them intermediate because they exist as much as Geolocation widget is open. To add them proper to host application and metadata, you must click the "Apply" button. You will notice that the intermediate tags haven't dissapeard. This is good, because they will help you in case you want to geotag some other photos before you close Geolocation widget.


You will also have an option to select whether your tags will be saved in each image XMP metadata. I've chosen only XMP because IPTC doesn't provide support for special characters. To be more precise,IPTC uses ASCII encoding, while XMP uses UTF-8 encoding.

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.

Backends

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
    • town
    • village
    • hamlet
    • street

Geonames.org

geonames.org

  • Provides both reverse geocoding and elevation information
  • It has to services implemented here:
    • "Find nearby place name" which provides:
      • country
      • place name
    • "Find address" is only for USA and retrieves:
      • local administration 2
      • local administration 1
      • place name

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.

Miscellaneous

  • 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

TODO Reverse Geocoding

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? DONE
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
UI
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. DONE
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. DONE
Maybe display an invitation to donate to OSM/geonames?
General
Add correct licensing information to all files DONE
Review digikam coding guidelines and apply them to the code DONE

TODO Improved Map Search

Component Job Status
KMap Switching from Marble to Google Maps does not keep rectangle selection mode
Unknown Size hint of GPS properties tab too wide
Digikam Coordinates/altitude not shown in GPS properties tab sometimes

To be done later:

  • Add an option to set which tags in a hierarchy should be applied to an image. For example, in 'Places/Germany/Monheim', one may not want 'Places' to be a tag for an image. But in 'Holidays/Spain/Barcelona', 'Holidays' may be wanted as a tag.