Digikam/GSoC2010/ReverseGeocoding
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. Also, let's say that your photos have coordinates inside metadata and some photos don't have coordinates. All the operations will be made inside Geolocation 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: 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.
Now, 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:
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.
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
Google Maps
- 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
- Marble already has integration for this service
- Address elements returned, if they exist:
- country
- state
- state district
- county
- city
- city district
- street
Geonames.org
- 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.
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
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 |
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. | |
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? | |
General | |
Add correct licensing information to all files | DONE |
Review digikam coding guidelines and apply them to the code | DONE |
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.